PageSourceSearch

https://www.lamiachampagne.com/wp-content/plugins/pixelyoursite-pro/dist/scripts/public.js?ver=12.4.0.2

js lamiachampagne.com collected 2026-10-10 00:43:26 UTC 332,991 bytes, 7,498 lines download raw bytes

1/* global pysOptions */
2
3! function ($, options) {
4    if (options.debug) {
5        console.log('PYS:', options);
6    }
7
8    var uniqueId = {};
9
10    var firstVisit = false;
11
12    var isTrackEventForGA = [];
13
14    var isAdsLoad = false;
15
16    let gtm_variables = {};
17    let gtm_datalayername = "dynamicVariable";
18    var domain = '';
19    if(options.hasOwnProperty("track_cookie_for_subdomains") && options.track_cookie_for_subdomains) {
20        domain = getRootDomain(true);
21    }
22
23    /**
24     * Resolve parameter value based on mode (static or dynamic)
25     *
26     * @param {Object|string} param - Parameter object with { value, selector } or string value
27     * @returns {string|null} - Resolved value
28     */
29    function resolveParamValue(param) {
30        // Handle old format (string)
31        if (typeof param === 'string') {
32            return param;
33        }
34        // Handle new format (object with value and selector)
35        if (typeof param === 'object' && param !== null) {
36            // STATIC MODE: selector is empty or not present
37            if ((!param.dynamic || param.dynamic == false) || (!param.selector || param.selector.trim() === "")) {
38                if (param.input_type === "float" || param.input_type === "int") {
39                    param.value = extractNumericValue(param.value, param.input_type === "int");
40                }
41                return param.value ?? param;
42            }
43
44            // DYNAMIC MODE: selector is present
45            try {
46                const el = document.querySelector(param.selector);
47                if (!el) {
48                    return null;
49                }
50                value = (
51                    el.value ||                           // Input fields
52                    el.innerText ||                       // Text content
53                    el.textContent ||                     // Alternative text content
54                    el.getAttribute("content") ||         // Meta tags
55                    el.getAttribute("data-value") ||      // Data attributes
56                    null
57                );
58                if (param.input_type === "float" || param.input_type === "int") {
59                    value = extractNumericValue(value, param.input_type === "int");
60                }
61                // Try to extract value from element in order of priority
62                return value;
63            } catch (e) {
64
65                return null;
66            }
67        }
68
69        if (typeof param === 'number'){
70            return param;
71        }
72
73        if (Array.isArray(param)) {
74            return param;
75        }
76
77        return null;
78    }
79
80    function extractNumericValue(value, isInt=false) {
81        if (value === null || value === undefined) {
82            return null;
83        }
84        if (isInt) {
85            return parseInt(value);
86        }
87        return parseFloat(value);
88    }
89
90    var loadTags = [];
91
92    var dummyPinterest = function () {
93
94        /**
95         * Public API
96         */
97        return {
98            tag: function() {
99                return "pinterest";
100            },
101            isEnabled: function () {},
102
103            disable: function () {},
104
105            loadPixel: function () {},
106
107            fireEvent: function (name, data) {
108                return false;
109            },
110
111            onAdSenseEvent: function (event) {},
112
113            onClickEvent: function (params) {},
114
115            onWatchVideo: function (params) {},
116
117            onCommentEvent: function (event) {},
118
119            onFormEvent: function (params) {},
120
121            onDownloadEvent: function (params) {},
122
123
124
125            onWooAddToCartOnButtonEvent: function (product_id) {},
126
127            onWooAddToCartOnSingleEvent: function (product_id, qty, product_type, is_external, $form) {},
128
129            onWooRemoveFromCartEvent: function (cart_item_hash) {},
130
131            onWooAffiliateEvent: function (product_id) {},
132
133            onWooPayPalEvent: function (event) {},
134
135            onEddAddToCartOnButtonEvent: function (download_id, price_index, qty) {},
136
137            onEddRemoveFromCartEvent: function (item) {},
138
139            onPageScroll: function (event) {},
140            onTime: function (event) {
141
142            },
143
144        }
145
146    }();
147
148    var dummyBing = function () {
149
150        /**
151         * Public API
152         */
153        return {
154            tag: function() {
155                return "bing";
156            },
157            isEnabled: function () {},
158
159            disable: function () {},
160
161            loadPixel: function () {},
162
163            fireEvent: function (name, data) {
164                return false;
165            },
166
167            onAdSenseEvent: function (event) {},
168
169            onClickEvent: function (params) {},
170
171            onWatchVideo: function (params) {},
172
173            onCommentEvent: function (event) {},
174
175            onFormEvent: function (params) {},
176
177            onDownloadEvent: function (params) {},
178
179
180            onWooAddToCartOnButtonEvent: function (product_id) {},
181
182            onWooAddToCartOnSingleEvent: function (product_id, qty, product_type, is_external, $form) {},
183
184            onWooRemoveFromCartEvent: function (cart_item_hash) {},
185
186            onWooAffiliateEvent: function (product_id) {},
187
188            onWooPayPalEvent: function (event) {},
189
190            onEddAddToCartOnButtonEvent: function (download_id, price_index, qty) {},
191
192            onEddRemoveFromCartEvent: function (item) {},
193            onPageScroll: function (event) {},
194            onTime: function (event) {
195
196            },
197        }
198
199    }();
200
201	var dummyReddit = function () {
202		/**
203		 * Public API
204		 */
205		return {
206			tag: function () {
207				return "reddit";
208			},
209			isEnabled: function () {
210			},
211
212			disable: function () {
213			},
214
215			loadPixel: function () {
216			},
217
218			fireEvent: function ( name, data ) {
219				return false;
220			},
221
222			onAdSenseEvent: function ( event ) {
223			},
224
225			onClickEvent: function ( params ) {
226			},
227
228			onWatchVideo: function ( params ) {
229			},
230
231			onCommentEvent: function ( event ) {
232			},
233
234			onFormEvent: function ( params ) {
235			},
236
237			onDownloadEvent: function ( params ) {
238			},
239
240			onWooAddToCartOnButtonEvent: function ( product_id ) {
241			},
242
243			onWooAddToCartOnSingleEvent: function ( product_id, qty, product_type, is_external, $form ) {
244			},
245
246			onWooRemoveFromCartEvent: function ( cart_item_hash ) {
247			},
248
249			onWooAffiliateEvent: function ( product_id ) {
250			},
251
252			onWooPayPalEvent: function ( event ) {
253			},
254
255			onEddAddToCartOnButtonEvent: function ( download_id, price_index, qty ) {
256			},
257
258			onEddRemoveFromCartEvent: function ( item ) {
259			},
260
261			onPageScroll: function ( event ) {
262			},
263
264			onTime: function ( event ) {
265			},
266		}
267	}();
268
269    var Utils = function (options) {
270
271
272        var Pinterest = dummyPinterest;
273
274        var Bing = dummyBing;
275
276	    var Reddit = dummyReddit;
277
278        var gtag_loaded = false;
279
280        var gtm_loaded = false;
281
282        let isNewSession = checkSession();
283
284        let dataLayerName = 'dataLayerPYS';
285
286        let GTMdataLayerName = 'dataLayer';
287
288
289        function loadPixels() {
290
291            if (!options.gdpr.all_disabled_by_api) {
292                if (!options.gdpr.tiktok_disabled_by_api) {
293                    TikTok.loadPixel();
294                }
295
296                if (!options.gdpr.facebook_disabled_by_api) {
297                    Facebook.loadPixel();
298                }
299
300                if (!options.gdpr.analytics_disabled_by_api) {
301                    Analytics.loadPixel();
302                }
303
304                if (!options.gdpr.google_ads_disabled_by_api) {
305                    GAds.loadPixel();
306                }
307
308                if (!options.gdpr.analytics_disabled_by_api) {
309                    GTM.loadPixel();
310                }
311
312                if (!options.gdpr.pinterest_disabled_by_api) {
313                    Pinterest.loadPixel();
314                }
315
316                if (!options.gdpr.bing_disabled_by_api) {
317                    Bing.loadPixel();
318                }
319
320	            if (!options.gdpr.reddit_disabled_by_api) {
321		            Reddit.loadPixel();
322	            }
323
324            }
325            if (options.gdpr.consent_magic_integration_enabled && typeof CS_Data !== "undefined") {
326                if (typeof CS_Data.cs_google_analytics_consent_mode !== "undefined" && CS_Data.cs_google_analytics_consent_mode == 1) {
327                    Analytics.loadPixel();
328                }
329                if (typeof CS_Data.cs_google_ads_consent_mode !== "undefined" && CS_Data.cs_google_ads_consent_mode == 1 ) {
330                    GAds.loadPixel();
331                }
332            }
333        }
334
335        /**
336         * WATCHVIDEO UTILS
337         */
338
339        function isJSApiAttrEnabled(url) {
340            return url.indexOf('enablejsapi') > -1;
341        }
342
343        function isOriginAttrEnabled(url) {
344            return url.indexOf('origin') > -1;
345        }
346
347        // Returns key/value pairs of percentages: number of seconds to achieve
348        function getVideoCompletionMarks(duration) {
349
350            var marks = {};
351            var points = [0, 10, 50, 90, 100];
352
353            for (var i = 0; i < points.length; i++) {
354
355                var _point = points[i];
356                var _mark = _point + '%';
357                var _time = duration * _point / 100;
358
359                if (_point === 100) {
360                    _time = _time - 1;
361                }
362
363                // 10% => 123
364                marks[_mark] = Math.floor(_time);
365
366            }
367
368            return marks;
369
370        }
371
372        // Determine if the element is a YouTube video or not
373        function tagIsYouTubeVideo(tag) {
374            var src = tag.src || '';
375            return src.indexOf('youtube.com/embed/') > -1 || src.indexOf('youtube.com/v/') > -1;
376        }
377
378        function tagIsYouTubeAsyncVideo(tag) {
379            if(tag.src && tag.src.indexOf("data:image") !== -1) return false; // video is loaded
380            var keys = Object.keys(tag.dataset);
381            for(var i = 0;i<keys.length;i++) {
382                if(keys[i].toLowerCase().indexOf("src") > -1) {
383                    var src = tag.dataset[keys[i]];
384                    return src.indexOf('youtube.com/embed/') > -1 || src.indexOf('youtube.com/v/') > -1;
385                }
386            }
387            return false; //not find src
388        }
389
390        // Turn embed objects into iframe objects and ensure they have the right parameters
391        function normalizeYouTubeIframe(tag) {
392
393            var loc = window.location;
394            var a = document.createElement('a');
395            a.href = tag.src;
396            a.hostname = 'www.youtube.com';
397            a.protocol = loc.protocol;
398            var tmpPathname = a.pathname.charAt(0) === '/' ? a.pathname : '/' + a.pathname; // IE10 shim
399
400            if (!isJSApiAttrEnabled(a.search)) {
401                a.search = (a.search.length > 0 ? a.search + '&' : '') + 'enablejsapi=1';
402            }
403
404            // for security reasons, YouTube wants an origin parameter set that matches our hostname
405            if (!isOriginAttrEnabled(a.search) && loc.hostname.indexOf('localhost') === -1) {
406
407                var port = loc.port ? ':' + loc.port : '';
408                var origin = loc.protocol + '%2F%2F' + loc.hostname + port;
409
410                a.search = a.search + '&origin=' + origin;
411
412            }
413
414            if (tag.type === 'application/x-shockwave-flash') {
415
416                var newIframe = document.createElement('iframe');
417                newIframe.height = tag.height;
418                newIframe.width = tag.width;
419                tmpPathname = tmpPathname.replace('/v/', '/embed/');
420
421                tag.parentNode.parentNode.replaceChild(newIframe, tag.parentNode);
422
423                tag = newIframe;
424
425            }
426
427            a.pathname = tmpPathname;
428
429            if (tag.src !== a.href + a.hash) {
430                tag.src = a.href + a.hash;
431            }
432
433            return tag;
434
435        }
436
437        // Add event handlers for events emitted by the YouTube API
438        function addYouTubeEvents(iframe) {
439
440            var player = YT.get(iframe.id);
441            if (!player) {
442                player = new YT.Player(iframe, {});
443            }
444
445            if (typeof iframe.pauseFlag === 'undefined') {
446
447                iframe.pauseFlag = false;
448                player.addEventListener('onStateChange', function (evt) {
449                    onYouTubePlayerStateChange(evt, iframe);
450                });
451
452            }
453
454        }
455
456        function addDynYouTubeVideos(el) {
457            // We only bind to iFrames with a YouTube URL with the enablejsapi=1 and
458            // origin=<<hostname>> parameters
459            if (el.tagName === 'IFRAME'
460                && tagIsYouTubeVideo(el)
461                && isJSApiAttrEnabled(el.src)
462                && isOriginAttrEnabled(el.src))
463            {
464                addYouTubeEvents(el);
465            }
466        }
467
468        // Event handler for events emitted from the YouTube API
469        function onYouTubePlayerStateChange(evt, iframe) {
470
471            var stateIndex = evt.data;
472            var player = evt.target;
473            var targetVideoUrl = player.getVideoUrl();
474            var targetVideoId = targetVideoUrl.match(/[?&]v=([^&#]*)/)[1]; // Extract the ID
475            var playerState = player.getPlayerState();
476            var marks = getVideoCompletionMarks(player.getDuration());
477
478            iframe.playTracker = iframe.playTracker || {};
479
480            if (playerState === YT.PlayerState.PLAYING && !iframe.timer) {
481
482                clearInterval(iframe.timer);
483
484                // check every second to see if we've hit any of our percentage viewed marks
485                iframe.timer = setInterval(function () {
486                    checkYouTubeCompletion(player, marks, iframe.videoId);
487                }, 1000);
488
489            } else {
490
491                clearInterval(iframe.timer);
492                iframe.timer = false;
493
494            }
495
496            // playlist edge-case handler
497            if (stateIndex === YT.PlayerState.PLAYING) {
498                iframe.playTracker[targetVideoId] = true;
499                iframe.videoId = targetVideoId;
500                iframe.pauseFlag = false;
501            }
502
503            if (!iframe.playTracker[iframe.videoId]) {
504                return false; // this video hasn't started yet, so this is spam
505            }
506
507            if (stateIndex === YT.PlayerState.PAUSED) {
508
509                if (!iframe.pauseFlag) {
510                    iframe.pauseFlag = true;
511                } else {
512                    return false; // we don't want to fire consecutive pause events
513                }
514
515            }
516
517        }
518
519        // Trigger event if YouTube video mark was reached
520        function checkYouTubeCompletion(player, marks, videoId) {
521
522            var currentTime = player.getCurrentTime();
523
524            player[videoId] = player[videoId] || {};
525
526            for (var key in marks) {
527
528                if (marks[key] <= currentTime && !player[videoId][key]) {
529                    player[videoId][key] = true;
530
531                    var data = player.getVideoData();
532
533                    if (key === '0%') {
534                        key = 'play';
535                    }
536
537                    var params = {
538                        video_type: 'youtube',
539                        video_id: videoId,
540                        video_title: data.title,
541                    };
542
543                    let disable_watch_video = [];
544
545                    //Custom
546                    if ( options.triggerEventTypes.hasOwnProperty( "video_view" ) ) {
547                        Object.entries( options.triggerEventTypes.video_view ).forEach( function ( [ trigger_id, triggers ] ) {
548                            triggers.forEach( function ( trigger ) {
549                                if ( trigger.type === 'youtube' && trigger.rule === videoId ) {
550
551                                    let pixels = Object.keys( options.triggerEvents[ trigger_id ] );
552                                    for ( let i = 0; i < pixels.length; i++ ) {
553                                        let event = Utils.clone( options.triggerEvents[ trigger_id ][ pixels[ i ] ] );
554
555                                        if ( trigger.disable_watch_video ) {
556                                            disable_watch_video.push( pixels[ i ] );
557                                        }
558
559                                        if ( currentTime >= marks[ trigger.value ] ) {
560											if (pixels[i] !== 'reddit') {
561												event.params["progress"] = key;
562												Utils.copyProperties( params, event.params );
563											}
564
565                                            if ( event.fired !== true ) {
566                                                if ( Utils.isEventInTimeWindow( event.name, event, 'dyn_' + pixels[ i ] + '_' + trigger_id ) ) {
567                                                    event = Utils.getFormFilledData( event );
568                                                    getPixelBySlag( pixels[ i ] ).fireEvent( event.name, event );
569                                                    options.triggerEvents[ trigger_id ][ pixels[ i ] ].fired = true;
570                                                }
571                                            }
572                                        }
573                                    }
574                                }
575                            } )
576                        } )
577                    }
578
579                    // Auto
580                    if( options.automatic.enable_video
581                        && options.automatic.enable_youtube
582                        && options.dynamicEvents.hasOwnProperty("automatic_event_video")
583                    ) {
584                        var pixels = Object.keys(options.dynamicEvents.automatic_event_video);
585
586                        for (var i = 0; i < pixels.length; i++) {
587                            if ( disable_watch_video.includes( pixels[ i ] ) ) {
588                                continue;
589                            }
590                            var event = Utils.clone(options.dynamicEvents.automatic_event_video[pixels[i]]);
591
592							if ( pixels[ i ] !== 'reddit' ) {
593								event.params[ "progress" ] = key;
594								Utils.copyProperties(params, event.params)
595							}
596
597                            if ( pixels[i] === 'tiktok' || pixels[i] === 'reddit' ) {
598                                var time_trigger = event.automatic_event_video_trigger;
599                                if ( currentTime >= marks[time_trigger] && event.fired !== true ) {
600                                    getPixelBySlag(pixels[i]).onWatchVideo(event);
601
602                                    //tiktok and reddit watch video fire once
603                                    options.dynamicEvents.automatic_event_video[pixels[i]].fired = true;
604                                }
605                            } else {
606                                Utils.copyProperties(Utils.getRequestParam
606s(), event.params);
607                                getPixelBySlag(pixels[i]).onWatchVideo(event);
608                            }
609                        }
610                    }
611
612                    if(key == "play") {
613
614                        $.each(options.triggerEventTypes, function (triggerType, events) {
615                            $.each(events, function (eventId, triggers) {
616                                switch (triggerType) {
617                                    case 'video_play':
618                                        Utils.fireTriggerEvent(eventId);
619                                        break;
620                                }
621
622                            });
623                        });
624                    }
625
626                }
627
628            }
629
630        }
631
632        // Determine if the element is a Vimeo video or not
633        function tagIsVimeoVideo(tag) {
634            var src = tag.src || '';
635            return src.indexOf('player.vimeo.com/video/') > -1;
636        }
637
638        function tagIsAsincVimeoVideo(tag) {
639            if(tag.src) return false; // video is loaded
640            var keys = Object.keys(tag.dataset);
641            for(var i = 0;i<keys.length;i++) {
642                if(keys[i].toLowerCase().indexOf("src") > -1) {
643                    var src = tag.dataset[keys[i]];
644                    return src.indexOf('player.vimeo.com/video/') > -1;
645                }
646            }
647            return false; //not find src
648        }
649
650        function attachVimeoPlayerToTag(tag) {
651            var player = new Vimeo.Player(tag);
652
653            player.getDuration().then(function (pl,seconds) {
654                pl.pysMarks = getVideoCompletionMarks(seconds);
655            }.bind(null,player));
656
657            player.getVideoTitle().then(function (pl,title) {
658                pl.pysVideoTitle = title;
659            }.bind(null,player));
660
661            player.getVideoId().then(function (pl,id) {
662                pl.pysVideoId = id;
663            }.bind(null,player));
664
665            player.pysCompletedMarks = {};
666
667            player.on('play', function () {
668
669                if (this.pysTimer) {
670                    return;
671                }
672
673                clearInterval(this.pysTimer);
674
675                var player = this;
676
677                this.pysTimer = setInterval(function () {
678                    checkVimeoCompletion(player);
679                }, 1000);
680
681            });
682
683            player.on('pause', function () {
684                clearInterval(this.pysTimer);
685                this.pysTimer = false;
686            });
687
688            player.on('ended', function () {
689                clearInterval(this.pysTimer);
690                this.pysTimer = false;
691            });
692        }
693
694        // Trigger event if Vimeo video mark was reached
695        function checkVimeoCompletion(player) {
696
697            player.getCurrentTime().then(function (seconds) {
698
699                for (var key in player.pysMarks) {
700
701                    if (player.pysMarks[key] <= seconds && !player.pysCompletedMarks[key]) {
702
703                        player.pysCompletedMarks[key] = true;
704
705                        if (key === '0%') {
706                            key = 'play';
707                        }
708
709                        var params = {
710                            video_type: 'vimeo',
711                            video_id: player.pysVideoId,
712                            video_title: player.pysVideoTitle,
713                        };
714
715                        let disable_watch_video = [];
716
717                        //Custom
718                        if ( options.triggerEventTypes.hasOwnProperty( "video_view" ) ) {
719                            Object.entries( options.triggerEventTypes.video_view ).forEach( function ( [ trigger_id, triggers ] ) {
720                                triggers.forEach( function ( trigger ) {
721                                    if ( trigger.type === 'vimeo' && trigger.rule == player.pysVideoId ) {
722                                        let pixels = Object.keys( options.triggerEvents[ trigger_id ] );
723                                        for ( let i = 0; i < pixels.length; i++ ) {
724                                            let event = Utils.clone( options.triggerEvents[ trigger_id ][ pixels[ i ] ] );
725
726                                            if ( trigger.disable_watch_video ) {
727                                                disable_watch_video.push( pixels[ i ] );
728                                            }
729
730                                            if ( seconds >= player.pysMarks[ trigger.value ] ) {
731												if ( pixels[ i ] !== 'reddit' ) {
732													event.params[ "progress" ] = key;
733													Utils.copyProperties( params, event.params );
734                                                }
735
736                                                if ( event.fired !== true ) {
737                                                    if ( Utils.isEventInTimeWindow( event.name, event, 'dyn_' + pixels[ i ] + '_' + trigger_id ) ) {
738                                                        event = Utils.getFormFilledData( event );
739                                                        getPixelBySlag( pixels[ i ] ).fireEvent( event.name, event );
740                                                        options.triggerEvents[ trigger_id ][ pixels[ i ] ].fired = true;
741                                                    }
742                                                }
743                                            }
744                                        }
745                                    }
746                                } )
747                            } )
748                        }
749
750                        // Auto
751                        if(options.automatic.enable_video
752                            && options.automatic.enable_vimeo
753                            && options.dynamicEvents.hasOwnProperty("automatic_event_video")
754                        ) {
755                            var pixels = Object.keys(options.dynamicEvents.automatic_event_video);
756
757                            for (var i = 0; i < pixels.length; i++) {
758                                if ( disable_watch_video.includes( pixels[ i ] ) ) {
759                                    continue;
760                                }
761
762                                var event = Utils.clone(options.dynamicEvents.automatic_event_video[pixels[i]]);
763
764								if ( pixels[i] !== 'reddit' ) {
765									event.params["progress"] = key;
766									Utils.copyProperties(params, event.params);
767								}
768
769                                if ( pixels[i] === 'tiktok' || pixels[i] === 'reddit' ) {
770                                    var time_trigger = event.automatic_event_video_trigger;
771                                    if ( seconds >= player.pysMarks[time_trigger] && event.fired !== true ) {
772                                        getPixelBySlag(pixels[i]).onWatchVideo(event);
773
774                                        //tiktok and reddit watch video fire once
775                                        options.dynamicEvents.automatic_event_video[pixels[i]].fired = true;
776                                    }
777                                } else {
778                                    Utils.copyProperties(Utils.getRequestParam
778s(), event.params);
779                                    getPixelBySlag(pixels[i]).onWatchVideo(event);
780                                }
781                            }
782                        }
783
784                        if(key == "play") {
785                            $.each(options.triggerEventTypes, function (triggerType, events) {
786                                $.each(events, function (eventId, triggers) {
787                                    switch (triggerType) {
788                                        case 'video_play':
789                                            Utils.fireTriggerEvent(eventId);
790                                            break;
791                                    }
792
793                                });
794                            });
795                        }
796                    }
797
798                }
799
800            });
801
802        }
803
804        /**
805         * COOKIES UTILS
806         */
807
808        var utmTerms = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_content' ,'utm_term'];
809        var utmId = ['fbadid', 'gadid', 'padid', 'bingid'];
810        var requestParams = [];
811
812
813        function getDomain(url) {
814
815            url = url.replace(/(https?:\/\/)?(www.)?/i, '');
816
817            if (url.indexOf('/') !== -1) {
818                return url.split('/')[0];
819            }
820
821            return url;
822        }
823
824        function checkSession() {
825
826            if( Cookies.get('pys_start_session') === undefined ||
827                Cookies.get('pys_session_limit') === undefined) {
828                firstVisit = true;
829                return true
830            }
831            return false
832
833        }
834
835        function getTrafficSource() {
836
837            try {
838
839                let referrer = document.referrer.toString(),
840                    source;
841
842                let direct = referrer.length === 0;
843                let internal = direct ? false : referrer.indexOf(options.siteUrl) === 0;
844                let external = !direct && !internal;
845
846                if (external === false) {
847                    source = 'direct';
848                } else {
849                    source = referrer;
850                }
851
852                if (source !== 'direct') {
853                    // leave only domain (Issue #70)
854                    return getDomain(source);
855                } else {
856                    return source;
857                }
858
859            } catch (e) {
860                console.error(e);
861                return 'direct';
862            }
863
864        }
865
866        /**
867         * Return query variables object with where property name is query variable
868         * and property value is query variable value.
869         */
870        function getQueryVars() {
871
872            try {
873
874                var result = {},
875                    tmp = [];
876
877                window.location.search
878                    .substr(1)
879                    .split("&")
880                    .forEach(function (item) {
881
882                        tmp = item.split('=');
883
884                        if (tmp.length > 1) {
885                            result[tmp[0]] = tmp[1];
886                        }
887
888                    });
889
890                return result;
891
892            } catch (e) {
893                console.error(e);
894                return {};
895            }
896
897        }
898
899        function getLandingPageValue() {
900            let name = "pys_landing_page"
901            if(options.visit_data_model === "last_visit") {
902                name = "last_pys_landing_page"
903            }
904            if(Cookies.get(name) && Cookies.get(name) !== "undefined") {
905                return Cookies.get(name);
906            }
907            else if(options.hasOwnProperty("tracking_analytics") && options.tracking_analytics.TrafficLanding){
908                return options.tracking_analytics.TrafficLanding;
909            } else{
910                return "";
911            }
912        }
913        function getTrafficSourceValue() {
914            let name = "pysTrafficSource"
915            if(options.visit_data_model === "last_visit") {
916                name = "last_pysTrafficSource"
917            }
918            if(Cookies.get(name) && Cookies.get(name) !== "undefined") {
919                return Cookies.get(name);
920            }
921            else if(options.hasOwnProperty("tracking_analytics") && options.tracking_analytics.TrafficSource){
922                return options.tracking_analytics.TrafficSource;
923            } else{
924                return "";
925            }
926        }
927
928        /**
929         * Handle alternative GCLID parameter for Safari compatibility
930         * Creates _gcl_aw cookie when alternative parameter is detected and _gcl_aw doesn't exist
931         */
932        function handleAlternativeGclid() {
933            // Check if alternative GCLID is enabled
934            if (!options.GATags || !options.GATags.gclid_alternative_enabled || !options.GATags.gclid_alternative_param) {
935                return;
936            }
937
938            // GDPR consent checks - stop if any consent filter blocks it
939            if (options.gdpr.all_disabled_by_api) {
940                return;
941            }
942            if (options.gdpr.analytics_disabled_by_api) {
943                return;
944            }
945            if (options.cookie.disabled_all_cookie) {
946                return;
947            }
948            if (options.cookie.disabled_google_alternative_id) {
949                return;
950            }
951
952            const alternativeParam = options.GATags.gclid_alternative_param;
953            const queryVars = getQueryVars();
954            
955            // Check if alternative parameter exists in URL
956            if (queryVars[alternativeParam]) {
957                const gclidValue = queryVars[alternativeParam];
958                
959                // Only create _gcl_aw cookie if it doesn't exist
960                if (!Cookies.get('_gcl_aw')) {
961                    // Create _gcl_aw cookie with the alternative parameter value in Google's format
962                    // Format: GCL.{timestamp}.{gclid_value}
963                    const timestamp = Math.floor(Date.now() / 1000);
964                    const cookieValue = 'GCL.' + timestamp + '.' + gclidValue;
965                    
966                    // Set cookie for 90 days (Google's standard)
967                    const expires = new Date();
968                    expires.setTime(expires.getTime() + (90 * 24 * 60 * 60 * 1000));
969                    
970                    Cookies.set('_gcl_aw', cookieValue, { 
971                        expires: expires, 
972                        path: '/', 
973                        domain: domain 
974                    });
975                    
976                    if (options.debug) {
977                        console.log('PYS: Created _gcl_aw cookie from alternative parameter:', alternativeParam, '=', gclidValue);
978                    }
979                }
980            }
981        }
982
983        function getUTMId(useLast = false) {
984            try {
985                let cookiePrefix = 'pys_'
986                let terms = [];
987                if (useLast) {
988                    cookiePrefix = 'last_pys_'
989                }
990                $.each(utmId, function (index, name) {
991                    if (Cookies.get(cookiePrefix + name)) {
992                        terms[name] = Cookies.get(cookiePrefix + name)
993                    }
994                    else if(options.hasOwnProperty("tracking_analytics") && options.tracking_analytics.TrafficUtmsId[name]) {
995                        terms[name] = filterEmails(options.tracking_analytics.TrafficUtmsId[name])
996                    }
997                });
998                return terms;
999            } catch (e) {
1000                console.error(e);
1001                return [];
1002            }
1003        }
1004        /**
1005         * Return UTM terms from request query variables or from cookies.
1006         */
1007        function getUTMs(useLast = false) {
1008
1009            try {
1010                let cookiePrefix = 'pys_'
1011                if(useLast) {
1012                    cookiePrefix = 'last_pys_'
1013                }
1014                let terms = [];
1015                $.each(utmTerms, function (index, name) {
1016                    if (Cookies.get(cookiePrefix + name)) {
1017                        let value = Cookies.get(cookiePrefix + name);
1018                        terms[name] = filterEmails(value); // do not allow email in request params (Issue #70)
1019                    }
1020                    else if(options.hasOwnProperty("tracking_analytics") && options.tracking_analytics.TrafficUtms[name]) {
1021                        terms[name] = filterEmails(options.tracking_analytics.TrafficUtms[name])
1022                    }
1023                });
1024
1025                return terms;
1026
1027            } catch (e) {
1028                console.error(e);
1029                return [];
1030            }
1031
1032        }
1033
1034        function getDateTime() {
1035            var dateTime = new Array();
1036            var date = new Date(),
1037                days = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'],
1038                months = ['January', 'February', 'March', 'April', 'May', 'June',
1039                    'July', 'August', 'September', 'October', 'November', 'December'
1040                ],
1041                hours = ['00-01', '01-02', '02-03', '03-04', '04-05', '05-06', '06-07', '07-08',
1042                    '08-09', '09-10', '10-11', '11-12', '12-13', '13-14', '14-15', '15-16', '16-17',
1043                    '17-18', '18-19', '19-20', '20-21', '21-22', '22-23', '23-24'
1044                ];
1045            dateTime.push(hours[date.getHours()]);
1046            dateTime.push(days[date.getDay()]);
1047            dateTime.push(months[date.getMonth()]);
1048            return dateTime;
1049        }
1050
1051        function filterEmails(value) {
1052            return Utils.validateEmail(value) ? undefined : value;
1053        }
1054
1055        /**
1056         * PUBLIC API
1057         */
1058        return {
1059
1060            PRODUCT_SIMPLE : 0,
1061            PRODUCT_VARIABLE : 1,
1062            PRODUCT_BUNDLE : 2,
1063            PRODUCT_GROUPED : 3,
1064            utmTerms : utmTerms,
1065            utmId : utmId,
1066            isNewSession: checkSession(),
1067            setHidePixelCookie: function(){
1068                let refresh_after_consent = false;
1069                if ( !firstVisit && options.gdpr.consent_magic_integration_enabled && window.CS_Data !== undefined && window.CS_Data.cs_refresh_after_consent) {
1070                    refresh_after_consent = true;
1071                }
1072                if( !refresh_after_consent && !firstVisit) return false;
1073
1074                const url_parts = window.location.href;
1075                const url_params = new URLSearchParams(window.location.search);
1076                const matchingPixels = ["facebook", "ga", "gtm", "google_ads", "bing", "pinterest", "tiktok", "reddit"];
1077                $.each(matchingPixels, function (index, slug) {
1078                    var module = getPixelBySlag(slug);
1079                    if (module && module.isEnabled()) {
1080                        const fullUrl = window.location.href;
1081                        $.each(module.getHidePixel(), function (index, hide_info) {
1082                            for (const item of hide_info.hide_tag_contain) {
1083                                if (item && fullUrl.includes(item)) {
1084                                    let hideTagTimeInMilliseconds = hide_info.hide_tag_time * 60 * 60 * 1000;
1085                                    let expiresTime = new Date().getTime() + hideTagTimeInMilliseconds;
1086                                    Cookies.set('hide_tag_' + hide_info.pixel, true, { expires: new Date(expiresTime), path: '/' });
1087                                    break;
1088                                }
1089                            }
1090                        });
1091                    }
1092
1093                });
1094            },
1095            hideMatchingPixel: function(pixelValue, slug) {
1096                if(Cookies.get('hide_tag_'+pixelValue))
1097                {
1098                    return true;
1099                }
1100                return false;
1101            },
1102            validateEmail: function (email) {
1103                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,}))$/;
1104                return re.test(email);
1105            },
1106            fireEventForAllPixel:function(functionName,events){
1107                if (events.hasOwnProperty(Facebook.tag()))
1108                    Facebook[functionName](events[Facebook.tag()]);
1109                if (events.hasOwnProperty(Analytics.tag()))
1110                    Analytics[functionName](events[Analytics.tag()]);
1111                if (events.hasOwnProperty(GAds.tag()))
1112                    GAds[functionName](events[GAds.tag()]);
1113                if (events.hasOwnProperty(Pinterest.tag()))
1114                    Pinterest[functionName](events[Pinterest.tag()]);
1115                if (events.hasOwnProperty(Bing.tag()))
1116                    Bing[functionName](events[Bing.tag()]);
1117                if (events.hasOwnProperty(TikTok.tag()))
1118                    TikTok[functionName](events[TikTok.tag()]);
1119	            if (events.hasOwnProperty(Reddit.tag()))
1120		            Reddit[functionName](events[Reddit.tag()]);
1121
1122                if (events.hasOwnProperty(GTM.tag()))
1123                    GTM[functionName](events[GTM.tag()]);
1124            },
1125
1126            getQueryValue:function (name){
1127                return getQueryVars()[name];
1128            },
1129
1130            filterEmails: function (value) {
1131                return filterEmails(value);
1132            },
1133
1134            setupPinterestObject: function () {
1135                Pinterest = window.pys.Pinterest || Pinterest;
1136                return Pinterest;
1137            },
1138
1139            setupBingObject: function () {
1140                Bing = window.pys.Bing || Bing;
1141                return Bing;
1142            },
1143
1144	        setupRedditObject: function () {
1145		        Reddit = window.pys.Reddit || Reddit;
1146		        return Reddit;
1147	        },
1148
1149            // Clone all object members to another and return it
1150            copyProperties: function (from, to) {
1151                for (var key in from) {
1152                    if("function" == typeof from[key]) {
1153                        continue;
1154                    }
1155                    to[key] = from[key];
1156                }
1157                return to;
1158            },
1159
1160            /**
1161             * Generate unique ID
1162             */
1163            generateUniqueId : function (event) {
1164                if(event.eventID.length == 0 ||
1165                    (!event.isVariationTrigger &&
1166                        (event.type == "static" && options.ajaxForServerStaticEvent ||
1167                        event.type !== "static" && options.ajaxForServerEvent)
1168                    )
1169                ) {
1170                    let idKey = event.hasOwnProperty('custom_event_post_id') ? event.custom_event_post_id : event.e_id;
1171                    if (!uniqueId.hasOwnProperty(idKey)) {
1172                        uniqueId[idKey] = pys_generate_token();
1173                    }
1174                    return uniqueId[idKey];
1175                }
1176                else if(event.eventID.length !== 0)
1177                {
1178                    return event.eventID;
1179                }
1180            },
1181
1182            // Flatten object for sendBeacon compatibility
1183            flattenObject: function (obj, prefix = '', res = {}) {
1184                for (const [key, value] of Object.entries(obj)) {
1185                    const prefixedKey = prefix
1186                        ? (Array.isArray(obj) ? `${prefix}[${key}]` : `${prefix}[${key}]`)
1187                        : key;
1188                    if (value !== null && typeof value === 'object' && !(value instanceof File)) {
1189                        this.flattenObject(value, prefixedKey, res);
1190                    } else {
1191                        res[prefixedKey] = value;
1192                    }
1193                }
1194                return res;
1195            },
1196
1197            sendServerAjaxRequest: function ( url, data ) {
1198                // Check if we should use REST API for TikTok or Facebook
1199                if (data.action === 'pys_tiktok_api_event' && window.pysTikTokRest) {
1200                    // Use TikTok REST API
1201                    this.sendRestAPIRequest(data, 'tiktok');
1202                    return;
1203                }
1204
1205                if (data.action === 'pys_api_event' && data.pixel === 'facebook' && window.pysFacebookRest) {
1206                    // Use Facebook REST API
1207                    this.sendRestAPIRequest(data, 'facebook');
1208                    return;
1209                }
1210
1211                // Check if sendBeacon is enabled and supported
1212                if (options.useSendBeacon && navigator.sendBeacon) {
1213                    try {
1214                        // Flatten the data object for sendBeacon compatibility
1215                        const flattenedData = this.flattenObject(data);
1216                        const formData = new URLSearchParams();
1217
1218                        // Convert flattened data to URLSearchParams
1219                        for (const [key, value] of Object.entries(flattenedData)) {
1220                            if (value !== null && value !== undefined) {
1221                                formData.append(key, value);
1222                            }
1223                        }
1224
1225                        // Try to send using sendBeacon
1226                        const success = navigator.sendBeacon(url, formData);
1227                        if (success) {
1228                            return; // Successfully sent via sendBeacon
1229                        }
1230                    } catch (e) {
1231                        // If sendBeacon fails, fall back to jQuery.ajax
1232                        if (options.debug) {
1233                            console.log('PYS: sendBeacon failed, falling back to jQuery.ajax:', e);
1234                        }
1235                    }
1236                }
1237
1238                // Fallback to jQuery.ajax
1239                jQuery.ajax( {
1240                    type: 'POST',
1241                    url: url,
1242                    data: data,
1243                    headers: {
1244                        'Cache-Control': 'no-cache'
1245                    },
1246                    success: function () {
1247                    },
1248                } );
1249            },
1250
1251            // Send event via REST API (unified function for TikTok, Facebook, and other platforms)
1252            // Replaces the old sendTikTokRestAPIRequest and sendFacebookRestAPIRequest functions
1253            sendRestAPIRequest: function (data, platform) {
1254                let restApiUrl;
1255
1256                // Get platform-specific REST API configuration
1257                switch (platform) {
1258                    case 'tiktok':
1259                        restApiUrl = window.pysTikTokRest ? window.pysTikTokRest.restApiUrl : '/wp-json/pys-tiktok/v1/event';
1260                        break;
1261                    case 'facebook':
1262                        restApiUrl = window.pysFacebookRest ? window.pysFacebookRest.restApiUrl : '/wp-json/pys-facebook/v1/event';
1263                        break;
1264                    case 'pinterest':
1265                        restApiUrl = window.pysPinterestRest ? window.pysPinterestRest.restApiUrl : '/wp-json/pys-pinterest/v1/event';
1266                        break;
1267                    default:
1268                        console.error('PYS: Unknown platform for REST API:', platform);
1269                        this.sendAjaxFallback(data);
1270                        return;
1271                }
1272
1273                // Prepare data for REST API
1274                const restApiData = {
1275                    event: data.event,
1276                    event_slug: data.event_slug,
1277                    data: JSON.stringify(data.data || {}),
1278                    ids: JSON.stringify(data.ids || []),
1279                    eventID: data.event_id || data.eventID || '',
1280                    woo_order: data.woo_order || '0',
1281                    edd_order: data.edd_order || '0'
1282                };
1283
1284                // Try to send using sendBeacon first (if enabled)
1285                if (options.useSendBeacon && navigator.sendBeacon) {
1286                    try {
1287                        const formData = new URLSearchParams();
1288                        for (const [key, value] of Object.entries(restApiData)) {
1289                            formData.append(key, value);
1290                        }
1291
1292                        if (navigator.sendBeacon(restApiUrl, formData)) {
1293                            return;
1294                        }
1295                    } catch (e) {
1296                        // sendBeacon failed, continue to fetch
1297                    }
1298                }
1299
1300                // Try to send using fetch with REST API
1301                if (window.fetch) {
1302                    const headers = {
1303                        'Content-Type': 'application/json'
1304                    };
1305
1306                    fetch(restApiUrl, {
1307                        method: 'POST',
1308                        headers: headers,
1309                        body: JSON.stringify(restApiData)
1310                    })
1311                    .then(response => {
1312                        if (!response.ok) {
1313                            throw new Error(platform + ' REST API request failed: ' + response.status);
1314                        }
1315                    })
1316                    .catch(error => {
1317                        // Fallback to AJAX if REST API fails
1318                        if (options.debug) {
1319                            console.log('PYS: ' + platform + ' REST API failed, falling back to AJAX:', error);
1320                        }
1321                        this.sendAjaxFallback(data);
1322                    });
1323                } else {
1324                    // Fallback to AJAX if fetch is not supported
1325                    this.sendAjaxFallback(data);
1326                }
1327            },
1328
1329
1330
1331            // Fallback AJAX method
1332            sendAjaxFallback: function (data) {
1333                jQuery.ajax({
1334                    type: 'POST',
1335                    url: options.ajaxUrl,
1336                    data: data,
1337                    headers: {
1338                        'Cache-Control': 'no-cache'
1339                    },
1340                    success: function () {
1341                    },
1342                });
1343            },
1344
1345            clone: function(obj) {
1346                var copy;
1347
1348                // Handle the 3 simple types, and null or undefined
1349                if (null == obj || "object" != typeof obj) return obj;
1350
1351                // Handle Date
1352                if (obj instanceof Date) {
1353                    copy = new Date();
1354                    copy.setTime(obj.getTime());
1355                    return copy;
1356                }
1357
1358                // Handle Array
1359                if (obj instanceof Array) {
1360                    copy = [];
1361                    for (var i = 0, len = obj.length; i < len; i++) {
1362                        if("function" == typeof obj[i]) {
1363                            continue;
1364                        }
1365                        copy[i] = Utils.clone(obj[i]);
1366                    }
1367                    return copy;
1368                }
1369
1370                // Handle Object
1371                if (obj instanceof Object) {
1372                    copy = {};
1373                    for (var attr in obj) {
1374                        if (obj.hasOwnProperty(attr)) {
1375                            if("function" == typeof obj[attr]) {
1376                                continue;
1377                            }
1378                            copy[attr] = Utils.clone(obj[attr]);
1379                        }
1380                    }
1381                    return copy;
1382                }
1383
1384                return obj;
1385            },
1386
1387            // Returns array of elements with given tag name
1388            getTagsAsArray: function (tag) {
1389                return [].slice.call(document.getElementsByTagName(tag));
1390            },
1391
1392
1393            initializeVideoAPIs: function (options) {
1394                let trigger_has_video_YT, trigger_has_video_Vimeo = false;
1395                if (options.hasOwnProperty('automatic') && options.automatic.enable_video) {
1396                    if ( options.triggerEventTypes.hasOwnProperty( "video_view" ) ) {
1397                        Object.entries( options.triggerEventTypes.video_view ).forEach( function ( [ trigger_id, triggers ] ) {
1398                            triggers.forEach( function ( trigger ) {
1399                                if (trigger.type === 'youtube') {
1400                                    trigger_has_video_YT = true;
1401                                }
1402                                if(trigger.type === 'vimeo'){
1403                                    trigger_has_video_Vimeo = true;
1404                                }
1405                            });
1406                        });
1407                    }
1408                    if (
1409                        options.hasOwnProperty('enable_automatic_events') &&
1410                        options.enable_automatic_events
1411                    ) {
1412                        if (options.automatic.enable_youtube || trigger_has_video_YT) {
1413                            Utils.initYouTubeAPI();
1414                        }
1415                        if (options.automatic.enable_vimeo || trigger_has_video_Vimeo) {
1416                            Utils.initVimeoAPI();
1417                        }
1418                    }
1419                }
1420            },
1421            /**
1422             * Load and initialize YouTube API
1423             *
1424             * @link: https://developers.google.com/youtube/iframe_api_reference
1425             */
1426            initYouTubeAPI: function () {
1427
1428                // maybe load YouTube JS API
1429                if (typeof window.YT === 'undefined') {
1430                    var tag = document.createElement('script');
1431                    tag.src = '//www.youtube.com/iframe_api';
1432                    var firstScriptTag = document.getElementsByTagName('script')[0];
1433                    firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
1434                }
1435
1436                // initialize when API is ready
1437                if ( typeof window.onYouTubeIframeAPIReady !== 'function' ) {
1438
1439                    window.onYouTubeIframeAPIReady = function () {
1440
1441                        // collect all possible YouTube tags
1442                        var potentialVideos = Utils.getTagsAsArray( 'iframe' ).concat( 
1442Utils.getTagsAsArray( 'embed' ) );
1443
1444                        // turn videos into trackable videos with events
1445                        for ( var i = 0; i < potentialVideos.length; i++ ) {
1446                            var video = potentialVideos[ i ];
1447                            if ( tagIsYouTubeVideo( video ) ) {
1448                                var iframe = normalizeYouTubeIframe( video );
1449                                addYouTubeEvents( iframe );
1450                            } else if ( tagIsYouTubeAsyncVideo( video ) ){
1451                                video.addEventListener( "load", function ( evt ) {
1452                                    var iframe = normalizeYouTubeIframe( evt.currentTarget );
1453                                    addYouTubeEvents( iframe );
1454                                } );
1455                            }
1456                        }
1457
1458                        var targets = document.querySelectorAll( '.elementor-widget-video .elementor-wrapper' );
1459
1460                        const config = {
1461                            attributes: false,
1462                            childList: true,
1463                            subtree: true
1464                        };
1465
1466                        const callback = function ( mutationsList, observer ) {
1467                            for ( let mutation of mutationsList ) {
1468                                if ( mutation.type === 'childList' ) {
1469                                    for ( var m = 0; m < mutation.addedNodes.length; m++ ) {
1470                                        addDynYouTubeVideos( mutation.addedNodes[ m ] );
1471                                    }
1472                                }
1473                            }
1474                        };
1475                        // observe elementator widget-video and add event when it add iframe
1476                        for ( var i = 0; i < targets.length; i++ ) {
1477                            const observer = new MutationObserver( callback );
1478                            observer.observe( targets[ i ], config );//maybe remove before add
1479                        }
1480                    }
1481                }
1482            },
1483
1484            /**
1485             * Load and initialize Vimeo API
1486             *
1487             * @link: https://github.com/vimeo/player.js
1488             */
1489            initVimeoAPI: function () {
1490
1491
1492                $(document).ready(function () {
1493
1494                    var potentialVideos = Utils.getTagsAsArray('iframe').concat(Utils.getTagsAsArray('embed'));
1495
1496                    for (var i = 0; i < potentialVideos.length; i++) {
1497                        var tag = potentialVideos[i];
1498                        if (tagIsVimeoVideo(tag)) {
1499                            var nextElementHasClass = $(tag).closest('.elementor-widget-video').find('.elementor-custom-embed-image-overlay');
1500                            if(nextElementHasClass.length > 0) {
1501                                tag.addEventListener("load", function() {
1502                                    attachVimeoPlayerToTag(this);
1503                                });
1504                            }
1505                            else {
1506                                attachVimeoPlayerToTag(tag);
1507                            }
1508
1509
1510                        } else {
1511                            if (tagIsAsincVimeoVideo(tag)) {
1512                                tag.addEventListener("load", function(evt) {
1513                                    attachVimeoPlayerToTag(evt.currentTarget);
1514                                });
1515                            }
1516                        }
1517                    }
1518
1519                });
1520
1521            },
1522
1523            manageCookies: function () {
1524                // Handle alternative GCLID parameter for Safari compatibility
1525                handleAlternativeGclid();
1526                
1527                if (options.gdpr.cookiebot_integration_enabled && typeof Cookiebot !== 'undefined') {
1528                    if (Cookiebot.consented === false && !Cookiebot.consent['marketing'] && !Cookiebot.consent['statistics']) {
1529                        return;
1530                    }
1531                }
1532
1533                let cm_consent_not_expressed = false;
1534                if ( options.gdpr.consent_magic_integration_enabled && window.CS_Data !== undefined && window.CS_Data.cs_refresh_after_consent == 1 ) {
1535                    if ( Cookies.get( 'cs_viewed_cookie_policy' ) === undefined ) {
1536                        cm_consent_not_expressed = true;
1537                    }
1538                }
1539
1540                if( !cm_consent_not_expressed && isNewSession && !options.cookie.disabled_all_cookie && !options.cookie.disabled_start_session_cookie) {
1541                    let duration = options.last_visit_duration * 60000
1542                    var now = new Date();
1543                    now.setTime(now.getTime() + duration);
1544                    Cookies.set('pys_session_limit', true,{ expires: now, path: '/',domain: domain })
1545                    Cookies.set('pys_start_session', true,{ path: '/',domain: domain });
1546                    Utils.setHidePixelCookie();
1547                }
1548
1549                if (!Cookies.get('pbid') && Facebook.isEnabled() && options.ajaxForServerEvent) {
1550                    jQuery.ajax({
1551                        url: options.ajaxUrl,
1552                        dataType: 'json',
1553                        data: {
1554                            action: 'pys_get_pbid'
1555                        },
1556                        success: function (res) {
1557                            if (res.data && res.data.pbid != false && options.send_external_id) {
1558                                if(!(options.cookie.disabled_all_cookie || options.cookie.externalID_disabled_by_api)){
1559                                    var expires = parseInt(options.external_id_expire || 180);
1560                                    Cookies.set('pbid', res.data.pbid, { expires: expires,path: '/',domain: domain });
1561                                }
1562
1563                                if(options.hasOwnProperty('facebook')) {
1564                                    options.facebook.advancedMatching = {
1565                                        ...options.facebook.advancedMatching,  // распыляем текущие значения advancedMatching
1566                                        external_id: res.data.pbid
1567                                    };
1568                                }
1569                            }
1570                        }
1571                    });
1572                } else if (Cookies.get('pbid') && Facebook.isEnabled()){
1573                    if(options.hasOwnProperty('facebook')) {
1574                        options.facebook.advancedMatching = {
1575                            ...options.facebook.advancedMatching,
1576                            external_id: Cookies.get('pbid')
1577                        };
1578                    }
1579                }
1580                let expires = parseInt(options.cookie_duration); //  days
1581                let queryVars = getQueryVars();
1582                let landing = window.location.href.split('?')[0];
1583                try {
1584                    // save data for first visit
1585                    if(Cookies.get('pys_first_visit') === undefined && (!options.cookie.disabled_all_cookie)) {
1586
1587                        if(!options.cookie.disabled_first_visit_cookie)
1588                        {
1589                            Cookies.set('pys_first_visit', true, { expires: expires, path: '/',domain: domain });
1590                        }
1591                        else {
1592                            Cookies.remove('pys_first_visit', { path: '/',domain: domain } )
1593                        }
1594
1595                        if(!options.cookie.disabled_trafficsource_cookie)
1596                        {
1597                            Cookies.set('pysTrafficSource', getTrafficSource(), { expires: expires,path: '/',domain: domain });
1598                        }
1599                        else {
1600                            Cookies.remove('pysTrafficSource', { path: '/',domain: domain })
1601                        }
1602
1603                        if(!options.cookie.disabled_landing_page_cookie && options.enable_lading_page_param)
1604                        {
1605                            Cookies.set('pys_landing_page',landing,{ expires: expires,path: '/',domain: domain });
1606                        }
1607                        else {
1608                            Cookies.remove('pys_landing_page', { path: '/',domain: domain })
1609                        }
1610
1611                        if(!options.cookie.disabled_utmTerms_cookie)
1612                        {
1613                            $.each(utmTerms, function (index, name) {
1614                                if (queryVars.hasOwnProperty(name)) {
1615                                    Cookies.set('pys_' + name, queryVars[name], { expires: expires,path: '/',domain: domain });
1616                                } else {
1617                                    Cookies.remove('pys_' + name, { path: '/',domain: domain })
1618                                }
1619                            });
1620                        }
1621                        else {
1622                            $.each(utmTerms, function (index, name) {
1623                                Cookies.remove('pys_' + name, { path: '/',domain: domain })
1624                            });
1625                        }
1626
1627                        if(!options.cookie.disabled_utmId_cookie)
1628                        {
1629                            $.each(utmId,function(index,name) {
1630                                if (queryVars.hasOwnProperty(name)) {
1631                                    Cookies.set('pys_' + name, queryVars[name], { expires: expires,path: '/',domain: domain });
1632                                } else {
1633                                    Cookies.remove('pys_' + name, { path: '/',domain: domain })
1634                                }
1635                            })
1636                        }
1637                        else {
1638                            $.each(utmId, function (index, name) {
1639                                Cookies.remove('pys_' + name, { path: '/',domain: domain })
1640                            });
1641                        }
1642
1643                    }
1644                    // save data for last visit if it new session
1645                    if(isNewSession && (!options.cookie.disabled_all_cookie)) {
1646                        if(!options.cookie.disabled_trafficsource_cookie)
1647                        {
1648                            Cookies.set('last_pysTrafficSource', getTrafficSource(), { expires: expires,path: '/',domain: domain });
1649                        }
1650                        else {
1651                            Cookies.remove('last_pysTrafficSource', { path: '/',domain: domain })
1652                        }
1653
1654                        if(!options.cookie.disabled_landing_page_cookie && options.enable_lading_page_param)
1655                        {
1656                            Cookies.set('last_pys_landing_page',landing,{ expires: expires,path: '/',domain: domain });
1657                        }
1658                        else {
1659                            Cookies.remove('last_pys_landing_page', { path: '/',domain: domain })
1660                        }
1661
1662                        if(!options.cookie.disabled_utmTerms_cookie)
1663                        {
1664                            $.each(utmTerms, function (index, name) {
1665                                if (queryVars.hasOwnProperty(name)) {
1666                                    Cookies.set('last_pys_' + name, queryVars[name], { expires: expires,path: '/',domain: domain });
1667                                }
1668                            });
1669                        }
1670                        else {
1671                            $.each(utmTerms, function (index, name) {
1672                                Cookies.remove('last_pys_' + name, { path: '/',domain: domain })
1673                            });
1674                        }
1675
1676                        if(!options.cookie.disabled_utmId_cookie)
1677                        {
1678                            $.each(utmId,function(index,name) {
1679                                if (queryVars.hasOwnProperty(name)) {
1680                                    Cookies.set('last_pys_' + name, queryVars[name], { expires: expires,path: '/',domain: domain });
1681                                }
1682                            })
1683                        }
1684                        else {
1685                            $.each(utmId, function (index, name) {
1686                                Cookies.remove('last_pys_' + name, { path: '/',domain: domain })
1687                            });
1688                        }
1689
1690                    }
1691                    if(options.cookie.disabled_start_session_cookie) {
1692                        Cookies.remove('pys_start_session', { path: '/',domain: domain })
1693                        Cookies.remove('pys_session_limit', { path: '/',domain: domain })
1694                    }
1695                    if(options.cookie.disabled_all_cookie)
1696                    {
1697                        Cookies.remove('pys_first_visit', { path: '/',domain: domain })
1698                        Cookies.remove('pysTrafficSource', { path: '/',domain: domain })
1699                        Cookies.remove('pys_landing_page', { path: '/',domain: domain })
1700                        Cookies.remove('last_pys_landing_page', { path: '/',domain: domain })
1701                        Cookies.remove('last_pysTrafficSource', { path: '/',domain: domain })
1702                        Cookies.remove('pys_start_session', { path: '/',domain: domain })
1703                        Cookies.remove('pys_session_limit', { path: '/',domain: domain })
1704                        $.each(Utils.utmTerms, function (index, name) {
1705                            Cookies.remove('pys_' + name, { path: '/',domain: domain })
1706                        });
1707                        $.each(Utils.utmId,function(index,name) {
1708                            Cookies.remove('pys_' + name, { path: '/',domain: domain })
1709                        })
1710                        $.each(Utils.utmTerms, function (index, name) {
1711                            Cookies.remove('last_pys_' + name, { path: '/',domain: domain })
1712                        });
1713                        $.each(Utils.utmId,function(index,name) {
1714                            Cookies.remove('last_pys_' + name, { path: '/',domain: domain })
1715                        });
1716                    }
1717                } catch (e) {
1718                    console.error(e);
1719                }
1720            },
1721
1722            initializeRequestParams: function () {
1723
1724                if (options.trackTrafficSource) {
1725                    requestParams.traffic_source = getTrafficSourceValue();
1726                }
1727
1728                if (options.trackUTMs) {
1729
1730                    var utms = getUTMs(options.visit_data_model === "last_visit");
1731
1732                    $.each(utmTerms, function (index, term) {
1733                        if (term in utms) {
1734                            requestParams[term] = utms[term];
1735                        }
1736                    });
1737
1738                }
1739
1740
1741                var dateTime = getDateTime();
1742                if(options.enable_event_time_param) {
1743                    requestParams.event_hour = dateTime[0];
1744                }
1745
1746                if(options.enable_event_day_param) {
1747                    requestParams.event_day = dateTime[1];
1748                }
1749                if(options.enable_event_month_param) {
1750                    requestParams.event_month = dateTime[2];
1751                }
1752
1753                if(options.enable_lading_page_param){
1754                    requestParams.landing_page = getLandingPageValue();
1755                }
1756            },
1757
1758            getRequestParams: function () {
1759                return requestParams;
1760            },
1761
1762            /**
1763             * DOWNLOAD DOCS
1764             */
1765
1766            getLinkExtension: function (link) {
1767
1768                // Remove anchor, query string and everything before last slash
1769                link = link.substring(0, (link.indexOf("#") === -1) ? link.length : link.indexOf("#"));
1770                link = link.substring(0, (link.indexOf("?") === -1) ? link.length : link.indexOf("?"));
1771                link = link.substring(link.lastIndexOf("/") + 1, link.length);
1772
1773                // If there's a period left in the URL, then there's a extension
1774                if (link.length > 0 && link.indexOf('.') !== -1) {
1775                    link = link.substring(link.lastIndexOf(".") + 1); // Remove everything but what's after the first period
1776                    return link;
1777                } else {
1778                    return "";
1779                }
1780            },
1781
1782            getLinkFilename: function (link) {
1783
1784                // Remove anchor, query string and everything before last slash
1785                link = link.substring(0, (link.indexOf("#") === -1) ? link.length : link.indexOf("#"));
1786                link = link.substring(0, (link.indexOf("?") === -1) ? link.length : link.indexOf("?"));
1787                link = link.substring(link.lastIndexOf("/") + 1, link.length);
1788
1789                // If there's a period left in the URL, then there's a extension
1790                if (link.length > 0 && link.indexOf('.') !== -1) {
1791                    return link;
1792                } else {
1793                    return "";
1794                }
1795            },
1796
1797            /**
1798             * CUSTOM EVENTS
1799             */
1800
1801            setupMouseOverClickEvents: function (eventId, triggers) {
1802
1803                // Non-default binding used to avoid situations when some code in external js
1804                // stopping events propagation, eg. returns false, and our handler will never called
1805                document.addEventListener('mouseover', function(event) {
1806                    var matchedElements = Array.from(document.querySelectorAll(triggers));
1807                    var clickedElement = event.target;
1808                    var closestMatch = clickedElement.closest(triggers);
1809                    if (matchedElements.includes(clickedElement) || closestMatch){
1810                        if (event.target.classList.contains('pys-mouse-over-' + eventId)) {
1811                            return true;
1812                        } else {
1813                            event.target.classList.add('pys-mouse-over-' + eventId);
1814                        }
1815
1816                        Utils.fireTriggerEvent(eventId);
1817                    }
1818                });
1819
1820
1821            },
1822
1823            setupFormFieldEvents: function (eventId, triggers) {
1824                triggers.forEach(function(trigger) {
1825                    let eventType = 'input';
1826
1827                    if (['checkbox', 'radio', 'select'].includes(trigger.type)) {
1828                        eventType = 'change';
1829                    } else if (['text', 'email', 'tel'].includes(trigger.type)) {
1830                        eventType = 'blur';
1831                    }
1832
1833                    const form = document.querySelector(trigger.form);
1834                    if (!form) return;
1835
1836                    const field = form.querySelector(trigger.field); // ищем поле ТОЛЬКО внутри формы
1837                    if (!field) return;
1838
1839                    field.addEventListener(eventType, function (event) {
1840                        Utils.fireTriggerEvent(eventId);
1841                    }, true);
1842                });
1843            },
1844
1845            setupCSSClickEvents: function (eventId, triggers) {
1846                // Non-default binding used to avoid situations when some code in external js
1847                // stopping events propagation, eg. returns false, and our handler will never called
1848                // add event to document to support dyn class
1849                document.addEventListener('click', function(event) {
1850                    let matchedElements = Array.from(document.querySelectorAll(triggers)),
1851                        clickedElement = event.target,
1852                        closestMatch = clickedElement.closest(triggers);
1853
1854                    if (matchedElements.includes(clickedElement) || closestMatch){
1855                        Utils.fireTriggerEvent(eventId);
1856                    }
1857                }, true);
1858            },
1859
1860            setupURLClickEvents: function () {
1861
1862                if( !options.triggerEventTypes.hasOwnProperty('url_click') ) {
1863                    return;
1864                }
1865                // Non-default binding used to avoid situations when some code in external js
1866                // stopping events propagation, eg. returns false, and our handler will never called
1867                document.addEventListener('click', function(event) {
1868                    let anchor = event.target.closest('a');
1869
1870                    if (anchor) {
1871                        var url = anchor.getAttribute('href');
1872                        if (url) {
1873                            Object.entries(options.triggerEventTypes.url_click).forEac
1873h(function ([eventId, triggers]) {
1874                                triggers.forEach(function (trigger) {
1875                                    if (Utils.compareUrl(url, trigger.value, trigger.rule)) {
1876                                        Utils.fireTriggerEvent(eventId);
1877                                    }
1878                                });
1879                            });
1880                        }
1881                    }
1882                }, true);
1883
1884            },
1885
1886            removeUrlDomain(url) {
1887                if(url.indexOf("/#") > -1) {
1888                    url = url.substring(0, url.indexOf("/#"));
1889                }
1890                return url.replace('http://','')
1891                    .replace('https://','')
1892                    .replace('www.','')
1893                    .trim()
1894                    .replace(/^\/+/g, '')
1895
1896            },
1897
1898            compareUrl: function(base,url,rule){
1899
1900                if(url == "*" || url == '') return true;
1901
1902                base = Utils.removeUrlDomain(base)
1903                url = Utils.removeUrlDomain(url)
1904
1905                if(rule == 'match') {
1906                    return url == base;
1907                } else {
1908                    return base.indexOf(url) !== -1
1909                }
1910
1911            },
1912
1913            setupScrollPosEvents: function (eventId, triggers) {
1914
1915                var scrollPosThresholds = {},
1916                    docHeight = $(document).height() - $(window).height();
1917
1918                // convert % to absolute positions
1919                $.each(triggers, function (index, scrollPos) {
1920
1921                    // convert % to pixels
1922                    scrollPos = docHeight * scrollPos / 100;
1923                    scrollPos = Math.round(scrollPos);
1924
1925                    scrollPosThresholds[scrollPos] = eventId;
1926
1927                });
1928
1929                $(document).on("scroll",function () {
1930
1931                    var scrollPos = $(window).scrollTop();
1932
1933                    $.each(scrollPosThresholds, function (threshold, eventId) {
1934
1935                        // position has not reached yes
1936                        if (scrollPos <= threshold) {
1937                            return true;
1938                        }
1939
1940                        // fire event only once
1941                        if (eventId === null) {
1942                            return true;
1943                        } else {
1944                            scrollPosThresholds[threshold] = null;
1945                        }
1946
1947                        Utils.fireTriggerEvent(eventId);
1948
1949                    });
1950
1951                });
1952
1953            },
1954            setupCommentEvents : function (eventId,triggers) {
1955                $('form.comment-form').on("submit",function () {
1956                    Utils.fireTriggerEvent(eventId);
1957                });
1958            },
1959
1960            setupEmailLinkEvents: function ( events ) {
1961
1962                $( document ).on( 'click', 'a', function ( event ) {
1963                    let anchor = event.target.closest('a');
1964
1965                    if (anchor) {
1966                        let url = anchor.getAttribute('href');
1967                        if (url && (url.startsWith('mailto:') || url.startsWith('tel:'))) {
1968
1969                            let sendEventIds = [],
1970                                disabled_for_pixels = [],
1971                                disabled_email_action = false;
1972
1973                            $.each(events, function (eventId, trigger_group) {
1974                                url = url.replace('mailto:', '').replace('tel:', '');
1975                                trigger_group.forEach(function (triggers) {
1976                                    triggers.rules.forEach(function (trigger) {
1977                                        if (Utils.compareUrl(url, trigger.value, trigger.rule)) {
1978                                            sendEventIds.push(eventId);
1979                                            if (triggers.hasOwnProperty('disabled_email_link') && triggers.disabled_email_link) {
1980                                                disabled_email_action = true;
1981                                                if (options.triggerEvents.hasOwnProperty(eventId)) {
1982                                                    disabled_for_pixels.push(...Object.keys(options.triggerEvents[eventId]));
1983                                                }
1984                                            }
1985                                        }
1986                                    });
1987                                })
1988                            })
1989
1990                            if (sendEventIds.length > 0) {
1991                                sendEventIds.forEach(function (sendEventId) {
1992                                    Utils.fireTriggerEvent(sendEventId);
1993                                })
1994                            }
1995                            setupEmailLinks(disabled_for_pixels);
1996                        }
1997                    }
1998                } )
1999            },
2000
2001            /**
2002             * Events
2003             */
2004
2005            isEventInTimeWindow: function (eventName, event, prefix) {
2006
2007                if(event.hasOwnProperty("hasTimeWindow") && event.hasTimeWindow) {
2008                    var cookieName = prefix+"_"+eventName;
2009                    var now = new Date().getTime();
2010
2011                    if(Cookies.get(cookieName) !== undefined) {
2012
2013                        var lastTimeFire = Cookies.get(cookieName);
2014                        var fireTime = event.timeWindow * 60*60*1000;
2015
2016                        if( now - lastTimeFire > fireTime) {
2017                            Cookies.set(cookieName,now, { expires: event.timeWindow / 24.0, path: '/'} );
2018                        } else {
2019                            return false;
2020                        }
2021                    } else {
2022                        Cookies.set(cookieName,now, { expires: event.timeWindow / 24.0, path: '/'} );
2023                    }
2024                }
2025                return true
2026            },
2027
2028            fireTriggerEvent: function (eventId) {
2029
2030                if (!options.triggerEvents.hasOwnProperty(eventId)) {
2031                    return;
2032                }
2033
2034                var event = {};
2035                var events = options.triggerEvents[eventId];
2036
2037                if (events.hasOwnProperty('facebook')) {
2038                    event = events.facebook;
2039                    if(Utils.isEventInTimeWindow(event.name,event,"dyn_facebook_"+eventId)) {
2040                        event = Utils.getFormFilledData(event);
2041                        Facebook.fireEvent(event.name, event);
2042                    }
2043                }
2044
2045                if (events.hasOwnProperty('ga')) {
2046                    event = events.ga;
2047                    if(Utils.isEventInTimeWindow(event.name,event,"dyn_ga_"+eventId)) {
2048                        event = Utils.getFormFilledData(event);
2049                        Analytics.fireEvent(event.name, event);
2050                    }
2051                }
2052
2053                if (events.hasOwnProperty('google_ads')) {
2054                    event = events.google_ads;
2055                    if(Utils.isEventInTimeWindow(event.name,event,"dyn_google_ads_"+eventId)) {
2056                        event = Utils.getFormFilledData(event);
2057                        GAds.fireEvent(event.name, event);
2058                    }
2059                }
2060
2061                if (events.hasOwnProperty('pinterest')) {
2062                    event = events.pinterest;
2063                    if(Utils.isEventInTimeWindow(event.name,event,"dyn_pinterest_"+eventId)) {
2064                        event = Utils.getFormFilledData(event);
2065                        Pinterest.fireEvent(event.name, event);;
2066                    }
2067                }
2068
2069                if (events.hasOwnProperty('bing')) {
2070                    event = events.bing;
2071                    if(Utils.isEventInTimeWindow(event.name,event,"dyn_bing_"+eventId)) {
2072                        event = Utils.getFormFilledData(event);
2073                        Bing.fireEvent(event.name, event);;
2074                    }
2075                }
2076                if (events.hasOwnProperty('tiktok')) {
2077                    event = events.tiktok;
2078                    if(Utils.isEventInTimeWindow(event.name,event,"dyn_tiktok_"+eventId)) {
2079                        event = Utils.getFormFilledData(event);
2080                        TikTok.fireEvent(event.name, event);
2081                    }
2082                }
2083	            if (events.hasOwnProperty('reddit')) {
2084		            event = events.reddit;
2085		            if(Utils.isEventInTimeWindow(event.name,event,"dyn_reddit_"+eventId)) {
2086			            event = Utils.getFormFilledData(event);
2087			            Reddit.fireEvent(event.name, event);
2088		            }
2089	            }
2090
2091
2092                if (events.hasOwnProperty('gtm')) {
2093                    event = events.gtm;
2094                    if(Utils.isEventInTimeWindow(event.name,event,"dyn_gtm_"+eventId)) {
2095                        event = Utils.getFormFilledData(event);
2096                        GTM.fireEvent(event.name, event);
2097                    }
2098                }
2099
2100
2101            },
2102
2103            isFirstPurchaseFire: function ($eventName,orderId,pixel) {
2104
2105                if(Cookies.get("pys_"+$eventName+"_order_id_"+pixel) == orderId) {
2106                    return false;
2107                } else {
2108                    Cookies.set("pys_"+$eventName+"_order_id_"+pixel, orderId, { expires: 1,path: '/' });
2109                }
2110                return true;
2111            },
2112
2113            fireStaticEvents: function (pixel, timeout = 0) {
2114
2115                if (options.staticEvents.hasOwnProperty(pixel)) {
2116
2117                    $.each(options.staticEvents[pixel], function (eventId, events) {
2118
2119                        //skip purchase event if this order was fired
2120                        if( options.woo.hasOwnProperty('woo_purchase_on_transaction') &&
2121                            options.woo.woo_purchase_on_transaction &&
2122                            (eventId === "woo_purchase" || eventId === "woo_purchase_category") ) {
2123                            if(!Utils.isFirstPurchaseFire(eventId,events[0].woo_order,pixel)) {
2124                                return;
2125                            }
2126                        }
2127
2128                        if( options.edd.hasOwnProperty('edd_purchase_on_transaction') &&
2129                            options.edd.edd_purchase_on_transaction &&
2130                            (eventId === "edd_purchase" || eventId === "edd_purchase_category") ) {
2131                            if(!Utils.isFirstPurchaseFire(eventId,events[0].edd_order,pixel)) {
2132                                return;
2133                            }
2134                        }
2135
2136
2137                        $.each(events, function (index, event) {
2138
2139                            event.fired = event.fired || false;
2140
2141                            if (!event.fired && Utils.isEventInTimeWindow(event.name,event,'static_' + pixel+"_")) {
2142                                event = Utils.getFormFilledData(event);
2143
2144                                var fired = false;
2145
2146                                // fire event
2147                                if ( pixel === 'tiktok' ) {
2148                                    setTimeout(function() {
2149                                        getPixelBySlag(pixel).fireEvent(event.name, event);
2150                                    }, timeout * 500);
2151                                    timeout++;
2152                                } else {
2153                                    getPixelBySlag(pixel).fireEvent(event.name, event);
2154                                }
2155
2156                                // prevent event double event firing
2157                                event.fired = fired;
2158                            }
2159                        });
2160                    });
2161                }
2162            },
2163
2164            /**
2165             * Load tag's JS
2166             *
2167             * @link: https://developers.google.com/analytics/devguides/collection/gtagjs/
2168             * @link: https://developers.google.com/analytics/devguides/collection/gtagjs/custom-dim
2168s-mets
2169             */
2170            loadGoogleTag: function (id) {
2171
2172                if (!gtag_loaded) {
2173                    let dataLayerName = this.dataLayerName;
2174                    if(options.hasOwnProperty('GATags')){
2175                        switch (options.GATags.ga_datalayer_type) {
2176                            case 'default':
2177                                dataLayerName = 'dataLayerPYS';
2178                                break;
2179                            case 'custom':
2180                                dataLayerName = options.GATags.ga_datalayer_name;
2181                                break;
2182                            default:
2183                                dataLayerName = 'dataLayer';
2184                        }
2185                    }
2186                    this.dataLayerName = dataLayerName;
2187                    (function (window, document, src) {
2188                        var a = document.createElement('script'),
2189                            m = document.getElementsByTagName('script')[0];
2190                        a.async = 1;
2191                        a.src = src;
2192                        m.parentNode.insertBefore(a, m);
2193                    })(window, document, '//www.googletagmanager.com/gtag/js?id=' + id+'&l='+this.dataLayerName);
2194
2195                    window[dataLayerName] = window[dataLayerName] || [];
2196                    window.gtag = window.gtag || function gtag() {
2197                        window[dataLayerName].push(arguments);
2198                    };
2199
2200                    if ( options.google_consent_mode ) {
2201                        let data = {};
2202                        data[ 'analytics_storage' ] = options.gdpr.analytics_storage.enabled ? options.gdpr.analytics_storage.value : 'granted';
2203                        data[ 'ad_storage' ] = options.gdpr.ad_storage.enabled ? options.gdpr.ad_storage.value : 'granted';
2204                        data[ 'ad_user_data' ] = options.gdpr.ad_user_data.enabled ? options.gdpr.ad_user_data.value : 'granted';
2205                        data[ 'ad_personalization' ] = options.gdpr.ad_personalization.enabled ? options.gdpr.ad_personalization.value : 'granted';
2206
2207                        this.loadDefaultConsent( 'consent', 'default', data );
2208                    }
2209
2210                    gtag('js', new Date());
2211                    gtag_loaded = true;
2212
2213                }
2214
2215            },
2216
2217            loadDefaultConsent: function() {
2218                window[ this.dataLayerName ].push( arguments );
2219            },
2220
2221            loadGTMScript: function (id = '') {
2222                const domain = options.gtm.gtm_container_domain ?? 'www.googletagmanager.com';
2223                const loader = options.gtm.gtm_container_identifier ?? 'gtm';
2224                const gtm_auth = options.gtm.gtm_auth ?? ''; // Set this if needed
2225                const gtm_preview = options.gtm.gtm_preview ?? ''; // Set this if needed
2226                const datalayer_name = options.gtm.gtm_dataLayer_name ?? 'dataLayer';
2227
2228                window[ datalayer_name ] = window[ datalayer_name ] || [];
2229                window.gtag = window.gtag || function gtag() {
2230                    window[ datalayer_name ].push( arguments );
2231                };
2232
2233                if ( options.google_consent_mode ) {
2234                    let data = {};
2235                    data[ 'analytics_storage' ] = options.gdpr.analytics_storage.enabled ? options.gdpr.analytics_storage.value : 'granted';
2236                    data[ 'ad_storage' ] = options.gdpr.ad_storage.enabled ? options.gdpr.ad_storage.value : 'granted';
2237                    data[ 'ad_user_data' ] = options.gdpr.ad_user_data.enabled ? options.gdpr.ad_user_data.value : 'granted';
2238                    data[ 'ad_personalization' ] = options.gdpr.ad_personalization.enabled ? options.gdpr.ad_personalization.value : 'granted';
2239
2240                    this.GTMdataLayerName = datalayer_name;
2241                    this.loadDefaultGTMConsent( 'consent', 'default', data );
2242                }
2243
2244                (function(w, d, s, l, i) {
2245                    w[l] = w[l] || [];
2246                    w[l].push({ 'gtm.start': new Date().getTime(), event: 'gtm.js' });
2247                    const f = d.getElementsByTagName(s)[0];
2248                    const j = d.createElement(s);
2249                    const dl = l !== 'dataLayer' ? '&l=' + l : '';
2250                    j.async = true;
2251                    j.src = 'https://' + domain + '/' + loader + '.js?id=' + i + dl;
2252                    if (gtm_auth && gtm_preview) {
2253                        j.src += '&gtm_auth=' + gtm_auth + '&gtm_preview=' + gtm_preview + '&gtm_cookies_win=x';
2254                    }
2255                    f.parentNode.insertBefore(j, f);
2256                })(window, document, 'script', datalayer_name, id);
2257
2258            },
2259
2260            loadDefaultGTMConsent: function() {
2261                window[ this.GTMdataLayerName ].push( arguments );
2262            },
2263
2264            /**
2265             * GDPR
2266             */
2267
2268            loadPixels: function () {
2269
2270                if (options.gdpr.ajax_enabled && !options.gdpr.consent_magic_integration_enabled) {
2271
2272                    // retrieves actual PYS GDPR filters values which allow to avoid cache issues
2273                    $.get({
2274                        url: options.ajaxUrl,
2275                        dataType: 'json',
2276                        data: {
2277                            action: 'pys_get_gdpr_filters_values'
2278                        },
2279                        success: function (res) {
2280
2281                            if (res.success) {
2282
2283                                options.gdpr.all_disabled_by_api = res.data.all_disabled_by_api;
2284                                options.gdpr.facebook_disabled_by_api = res.data.facebook_disabled_by_api;
2285                                options.gdpr.tiktok_disabled_by_api = res.data.tiktok_disabled_by_api;
2286                                options.gdpr.analytics_disabled_by_api = res.data.analytics_disabled_by_api;
2287                                options.gdpr.google_ads_disabled_by_api = res.data.google_ads_disabled_by_api;
2288                                options.gdpr.pinterest_disabled_by_api = res.data.pinterest_disabled_by_api;
2289                                options.gdpr.bing_disabled_by_api = res.data.bing_disabled_by_api;
2290                                options.gdpr.reddit_disabled_by_api = res.data.reddit_disabled_by_api;
2291
2292                                options.cookie.externalID_disabled_by_api = res.data.externalID_disabled_by_api;
2293                                options.cookie.disabled_all_cookie = res.data.disabled_all_cookie;
2294                                options.cookie.disabled_advanced_form_data_cookie = res.data.disabled_advanced_form_data_cookie;
2295                                options.cookie.disabled_landing_page_cookie = res.data.disabled_landing_page_cookie || !options.enable_lading_page_param;
2296                                options.cookie.disabled_first_visit_cookie = res.data.disabled_first_visit_cookie;
2297                                options.cookie.disabled_trafficsource_cookie = res.data.disabled_trafficsource_cookie;
2298                                options.cookie.disabled_utmTerms_cookie = res.data.disabled_utmTerms_cookie;
2299                                options.cookie.disabled_utmId_cookie = res.data.disabled_utmId_cookie;
2300                            }
2301                            loadPixels();
2302
2303                        }
2304                    });
2305
2306                } else {
2307                    loadPixels();
2308                }
2309
2310            },
2311
2312            consentGiven: function (pixel) {
2313
2314                /**
2315                 * Cookiebot
2316                 */
2317                if (options.gdpr.cookiebot_integration_enabled && typeof Cookiebot !== 'undefined') {
2318
2319                    var cookiebot_consent_category = options.gdpr['cookiebot_' + pixel + '_consent_category'];
2320
2321                    if (options.gdpr[pixel + '_prior_consent_enabled']) {
2322                        if (Cookiebot.consented === true || Cookiebot.consent[cookiebot_consent_category]) {
2323                            return true;
2324                        }
2325                    } else {
2326                        if (Cookiebot.consent[cookiebot_consent_category]) {
2327                            return true;
2328                        }
2329                    }
2330                    return false;
2331
2332                }
2333
2334                /**
2335                 * Cookie Notice
2336                 */
2337                if (options.gdpr.cookie_notice_integration_enabled && typeof cnArgs !== 'undefined') {
2338
2339                    var cn_cookie = Cookies.get(cnArgs.cookieName);
2340
2341                    if (options.gdpr[pixel + '_prior_consent_enabled']) {
2342                        if (typeof cn_cookie === 'undefined' || cn_cookie === 'true') {
2343                            return true;
2344                        }
2345                    } else {
2346                        if (cn_cookie === 'true') {
2347                            return true;
2348                        }
2349                    }
2350
2351                    return false;
2352
2353                }
2354
2355                /**
2356                 * Cookie Law Info
2357                 */
2358
2359                if (options.gdpr.cookie_law_info_integration_enabled) {
2360                    var cli_cookie = Cookies.get('cookieyes-consent') ?? Cookies.get('wt_consent') ?? Cookies.get('viewed_cookie_policy');
2361                    if (options.gdpr[pixel + '_prior_consent_enabled']) {
2362                        if (typeof cli_cookie === 'undefined') return true;
2363                        if (
2364                            cli_cookie &&
2365                            (cli_cookie === Cookies.get('cookieyes-consent') || cli_cookie === Cookies.get('wt_consent'))
2366                        ) {
2367                            if (getCookieYes('analytics') === 'yes') {
2368                                return true;
2369                            }
2370                        } else if (cli_cookie && cli_cookie === Cookies.get('viewed_cookie_policy')) {
2371                            if (Cookies.get('viewed_cookie_policy') === 'yes') {
2372                                return true;
2373                            }
2374                        }
2375                    } else {
2376                        if (
2377                            cli_cookie &&
2378                            (cli_cookie === Cookies.get('cookieyes-consent') || cli_cookie === Cookies.get('wt_consent'))
2379                        ) {
2380                            if (getCookieYes('analytics') === 'yes') {
2381                                return true;
2382                            }
2383                        } else if (cli_cookie && cli_cookie === Cookies.get('viewed_cookie_policy')) {
2384                            if (Cookies.get('viewed_cookie_policy') === 'yes') {
2385                                return true;
2386                            }
2387                        }
2388                    }
2389                    return false;
2390                }
2391
2392                /**
2393                 * ConsentMagic
2394                 */
2395                if (options.gdpr.consent_magic_integration_enabled && typeof CS_Data !== "undefined" ) {
2396
2397                    let test_prefix = CS_Data.test_prefix;
2398                    if (
2399                        ( ( typeof CS_Data.cs_google_consent_mode_enabled !== "undefined" && CS_Data.cs_google_consent_mode_enabled == 1 ) && ( pixel == 'analytics' || pixel == 'google_ads' ) )
2400                        || ( typeof CS_Data.cs_meta_ldu_mode !== "undefined" && CS_Data.cs_meta_ldu_mode && pixel == 'facebook' )
2401                        || ( typeof CS_Data.cs_reddit_ldu_mode !== "undefined" && CS_Data.cs_reddit_ldu_mode && pixel == 'reddit' )
2402                        || ( typeof CS_Data.cs_bing_consent_mode !== "undefined" && CS_Data.cs_bing_consent_mode.ad_storage.enabled && pixel == 'bing' )
2403                    ) {
2404                        if ( CS_Data.cs_cache_enabled == 0 || ( CS_Data.cs_cache_enabled == 1 && window.CS_Cache && window.CS_Cache.check_status ) ) {
2405                            return true;
2406                        } else {
2407                            return false;
2408                        }
2409                    }
2410
2411                    if( pixel == 'facebook' && ( CS_Data.cs_script_cat.facebook == 0 || CS_Data.cs_script_cat.facebook == CS_Data.cs_necessary_cat_id ) ) {
2412                        return true;
2413                    } else if( pixel == 'bing' && ( CS_Data.cs_script_cat.bing == 0 || CS_Data.cs_script_cat.bing == CS_Data.cs_necessary_cat_id ) ) {
2414                        return true;
2415                    } else if( pixel == 'analytics' && ( CS_Data.cs_script_cat.analytics == 0 || CS_Data.cs_script_cat.analytics == CS_Data.cs_necessary_cat_id ) ) {
2416                        return true;
2417                    } else if( pixel == 'google_ads' && ( CS_Data.cs_script_cat.gads == 0 || CS_Data.cs_script_cat.gads == CS_Data.cs_necessary_cat_id ) ) {
2418                        return true;
2419                    } else if( pixel == 'pinterest' && ( CS_Data.cs_script_cat.pinterest == 0 || CS_Data.cs_script_cat.pinterest == CS_Data.cs_necessary_cat_id ) ) {
2420                        return true;
2421                    } else if( pixel == 'tiktok' && ( CS_Data.cs_script_cat.tiktok == 0 || CS_Data.cs_script_cat.tiktok == CS_Data.cs_necessary_cat_id ) ) {
2422                        return true;
2423                    } else if( pixel == 'reddit' && ( CS_Data.cs_script_cat?.reddit == 0 || CS_Data.cs_script_cat?.reddit == CS_Data.cs_necessary_cat_id ) ) {
2424		                return true;
2425	                }
2426
2427                    let substring = "cs_enabled_cookie_term",
2428                        theCookies = document.cookie.split( ';' );
2429
2430                    for ( let i = 1; i <= theCookies.length; i++ ) {
2431                        if ( theCookies[ i - 1 ].indexOf( substring ) !== -1 ) {
2432                            let categoryCookie = theCookies[ i - 1 ].replace( 'cs_enabled_cookie_term' + test_prefix + '_', '' );
2433                            categoryCookie = Number( categoryCookie.replace( /\D+/g, "" ) );
2434                            let cs_cookie_val = Cookies.get( 'cs_enabled_cookie_term' + test_prefix + '_' + categoryCookie );
2435
2436                            if ( categoryCookie === CS_Data.cs_script_cat.facebook && pixel == 'facebook' ) {
2437                                return cs_cookie_val == 'yes';
2438                            } else if ( categoryCookie === CS_Data.cs_script_cat.bing && pixel == 'bing' ) {
2439                                return cs_cookie_val == 'yes';
2440                            } else if ( categoryCookie === CS_Data.cs_script_cat.analytics && pixel == 'analytics' ) {
2441                                return cs_cookie_val == 'yes';
2442                            } else if ( categoryCookie === CS_Data.cs_script_cat.gads && pixel == 'google_ads' ) {
2443                                return cs_cookie_val == 'yes';
2444                            } else if ( categoryCookie === CS_Data.cs_script_cat.pinterest && pixel == 'pinterest' ) {
2445                                return cs_cookie_val == 'yes';
2446                            } else if ( categoryCookie === CS_Data.cs_script_cat.tiktok && pixel == 'tiktok' ) {
2447                                return cs_cookie_val == 'yes';
2448                            } else if ( categoryCookie === CS_Data.cs_script_cat?.reddit && pixel == 'reddit' ) {
2449	                            return cs_cookie_val == 'yes';
2450                            }
2451                        }
2452                    }
2453
2454                    return false;
2455                }
2456
2457
2458                /**
2459                 * Real Cookie Banner
2460                 */
2461                if (options.gdpr.real_cookie_banner_integration_enabled) {
2462                    var consentApi = window.consentApi;
2463                    if (consentApi) {
2464                        switch (pixel) {
2465                            case "analytics":
2466                                return consentApi.consentSync("http", "_ga", "*").cookieOptIn;
2467                            case "facebook":
2468                                return consentApi.consentSync("http", "_fbp", "*").cookieOptIn;
2469                            case "pinterest":
2470  
2470                              return consentApi.consentSync("http", "_pinterest_sess", ".pinterest.com").cookieOptIn;
2471                            case "bing":
2472                                return consentApi.consentSync("http", "_uetsid", "*").cookieOptIn;
2473                            case "google_ads":
2474                                return consentApi.consentSync("http", "1P_JAR", ".google.com").cookieOptIn;
2475                            case 'tiktok':
2476                                return consentApi.consentSync("http", "tt_webid_v2", ".tiktok.com").cookieOptIn;
2477                            default:
2478                                return true;
2479                        }
2480                    }
2481                }
2482
2483                return true;
2484
2485            },
2486
2487            setupGdprCallbacks: function () {
2488
2489                let isConcent = false;
2490
2491                /**
2492                 * Cookiebot
2493                 */
2494                if ( options.gdpr.cookiebot_integration_enabled && typeof Cookiebot !== 'undefined' ) {
2495                    isConcent = true;
2496                    window.addEventListener( "CookiebotOnConsentReady", function () {
2497
2498                        let consent = {
2499                            facebook: true,
2500                            ga: true,
2501                            google_ads: true,
2502                            tiktok: true,
2503                            bing: true,
2504                            pinterest: true,
2505                            gtm: true,
2506                        };
2507                        Utils.initializeVideoAPIs( options );
2508
2509                        Utils.manageCookies();
2510                        if ( Cookiebot.consent.marketing ) {
2511                            Facebook.loadPixel();
2512                            Bing.loadPixel();
2513                            Pinterest.loadPixel();
2514                            GAds.loadPixel();
2515                            TikTok.loadPixel();
2516
2517                            consent.facebook = true;
2518                            consent.bing = true;
2519                            consent.google_ads = true;
2520                            consent.pinterest = true;
2521                            consent.tiktok = true;
2522                        }
2523                        if ( Cookiebot.consent.statistics ) {
2524                            Analytics.loadPixel();
2525
2526                            consent.ga = true;
2527                            consent.gtm = true;
2528                        }
2529                        if ( !Cookiebot.consent.marketing ) {
2530                            Facebook.disable();
2531                            Pinterest.disable();
2532                            Bing.disable()
2533                            GAds.disable();
2534                            TikTok.disable();
2535
2536                            consent.facebook = false;
2537                            consent.bing = false;
2538                            consent.google_ads = false;
2539                            consent.pinterest = false;
2540                            consent.tiktok = false;
2541                        }
2542                        if ( !Cookiebot.consent.statistics ) {
2543                            Analytics.disable();
2544
2545                            consent.ga = false;
2546                            consent.gtm = false;
2547                        }
2548
2549                        Utils.setupGDPRData( consent );
2550                    } );
2551                }
2552
2553                /**
2554                 * Cookie Notice
2555                 */
2556                if ( options.gdpr.cookie_notice_integration_enabled ) {
2557                    isConcent = true;
2558                    $( document ).onFirst( 'click', '.cn-set-cookie', function () {
2559
2560                        let consent = {};
2561
2562                        if ( $( this ).data( 'cookie-set' ) === 'accept' ) {
2563
2564                            Utils.initializeVideoAPIs( options );
2565
2566                            Facebook.loadPixel();
2567                            Analytics.loadPixel();
2568                            GAds.loadPixel();
2569                            Pinterest.loadPixel();
2570                            Bing.loadPixel();
2571                            TikTok.loadPixel();
2572
2573                            consent = {
2574                                facebook: true,
2575                                ga: true,
2576                                google_ads: true,
2577                                tiktok: true,
2578                                bing: true,
2579                                pinterest: true,
2580                                gtm: true,
2581                            };
2582                        } else {
2583                            Facebook.disable();
2584                            Analytics.disable();
2585                            GAds.disable();
2586                            Pinterest.disable();
2587                            Bing.disable();
2588                            TikTok.disable();
2589
2590                            consent = {
2591                                facebook: false,
2592                                ga: false,
2593                                google_ads: false,
2594                                tiktok: false,
2595                                bing: false,
2596                                pinterest: false,
2597                                gtm: false,
2598                            };
2599                        }
2600                        Utils.setupGDPRData( consent );
2601
2602                    } );
2603
2604                    $( document ).onFirst( 'click', '.cn-revoke-cookie', function () {
2605                        Facebook.disable();
2606                        Analytics.disable();
2607                        GAds.disable();
2608                        Pinterest.disable();
2609                        Bing.disable();
2610                        TikTok.disable();
2611
2612                        let consent = {
2613                            facebook: false,
2614                            ga: false,
2615                            google_ads: false,
2616                            tiktok: false,
2617                            bing: false,
2618                            pinterest: false,
2619                            gtm: false,
2620                        };
2621                        Utils.setupGDPRData( consent );
2622
2623                    } );
2624                }
2625
2626                /**
2627                 * Cookie Law Info
2628                 */
2629                if ( options.gdpr.cookie_law_info_integration_enabled ) {
2630                    isConcent = true;
2631                    $( document ).onFirst( 'click', '#wt-cli-accept-all-btn,#cookie_action_close_header, .cky-btn-accept', function () {
2632                        Utils.initializeVideoAPIs( options );
2633                        setTimeout( function () {
2634                            let cli_cookie = Cookies.get( 'cookieyes-consent' ) ?? Cookies.get( 'wt_consent' ) ?? Cookies.get( 'viewed_cookie_policy' );
2635                            if ( typeof cli_cookie !== 'undefined' ) {
2636                                if (
2637                                    cli_cookie &&
2638                                    (cli_cookie === Cookies.get('cookieyes-consent') || cli_cookie === Cookies.get('wt_consent'))
2639                                ) {
2640                                    if (getCookieYes('analytics') === 'yes') {
2641                                        Utils.manageCookies();
2642                                    }
2643                                } else if ( cli_cookie === Cookies.get( 'viewed_cookie_policy' ) && cli_cookie == 'yes' ) {
2644                                    Utils.manageCookies();
2645                                }
2646                            }
2647                        }, 1000 )
2648                        Facebook.loadPixel();
2649                        Analytics.loadPixel();
2650                        GAds.loadPixel();
2651                        Pinterest.loadPixel();
2652                        Bing.loadPixel();
2653                        TikTok.loadPixel();
2654
2655                        let consent = {
2656                            facebook: true,
2657                            ga: true,
2658                            google_ads: true,
2659                            tiktok: true,
2660                            bing: true,
2661                            pinterest: true,
2662                            gtm: true,
2663                        };
2664                        Utils.setupGDPRData( consent );
2665                    } );
2666
2667                    $( document ).onFirst( 'click', '#cookie_action_close_header_reject, .cky-btn-reject', function () {
2668                        Facebook.disable();
2669                        Analytics.disable();
2670                        GAds.disable();
2671                        Pinterest.disable();
2672                        Bing.disable();
2673                        TikTok.disable();
2674
2675                        let consent = {
2676                            facebook: false,
2677                            ga: false,
2678                            google_ads: false,
2679                            tiktok: false,
2680                            bing: false,
2681                            pinterest: false,
2682                            gtm: false,
2683                        };
2684                        Utils.setupGDPRData( consent );
2685                    } );
2686                }
2687
2688                /**
2689                 * ConsentMagic
2690                 */
2691                if ( options.gdpr.consent_magic_integration_enabled && typeof CS_Data !== "undefined" ) {
2692                    isConcent = true;
2693                    let test_prefix = CS_Data.test_prefix,
2694                        cs_refresh_after_consent = false,
2695                        substring = "cs_enabled_cookie_term";
2696
2697                    if ( CS_Data.cs_refresh_after_consent == 1 ) {
2698                        cs_refresh_after_consent = CS_Data.cs_refresh_after_consent;
2699                    }
2700
2701                    let consent_actions = function () {
2702                        let theCookies = document.cookie.split( ';' );
2703
2704                        let consent = {
2705                            facebook: true,
2706                            ga: true,
2707                            google_ads: true,
2708                            tiktok: true,
2709                            bing: true,
2710                            pinterest: true,
2711                            gtm: true,
2712	                        reddit: true,
2713                        };
2714
2715                        for ( let i = 1; i <= theCookies.length; i++ ) {
2716                            if ( theCookies[ i - 1 ].indexOf( substring ) !== -1 ) {
2717                                let categoryCookie = theCookies[ i - 1 ].replace( 'cs_enabled_cookie_term' + test_prefix + '_', '' );
2718                                categoryCookie = Number( categoryCookie.replace( /\D+/g, "" ) );
2719                                let cs_cookie_val = Cookies.get( 'cs_enabled_cookie_term' + test_prefix + '_' + categoryCookie );
2720                                if ( cs_cookie_val == 'yes' ) {
2721
2722                                    Utils.initializeVideoAPIs( options );
2723
2724                                    if ( ( categoryCookie === CS_Data.cs_script_cat.facebook ) || ( typeof CS_Data.cs_meta_ldu_mode !== "undefined" && CS_Data.cs_meta_ldu_mode ) ) {
2725                                        Facebook.loadPixel();
2726                                    }
2727
2728                                    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 ) ) {
2729                                        Bing.loadPixel();
2730                                    }
2731
2732                                    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 ) ) {
2733                                        Analytics.loadPixel();
2734                                    }
2735                                    if ( categoryCookie === CS_Data.cs_script_cat.gads || ( typeof CS_Data.cs_google_ads_consent_mode !== "undefined" && CS_Data.cs_google_ads_consent_mode == 1 ) ) {
2736                                        GAds.loadPixel();
2737                                    }
2738
2739                                    if ( categoryCookie === CS_Data.cs_script_cat.pinterest ) {
2740                                        Pinterest.loadPixel();
2741                                    }
2742
2743                                    if ( categoryCookie === CS_Data.cs_script_cat.tiktok ) {
2744                                        TikTok.loadPixel();
2745                                    }
2746
2747	                                if ( ( categoryCookie === CS_Data.cs_script_cat.reddit ) || ( typeof CS_Data.cs_reddit_ldu_mode !== "undefined" && CS_Data.cs_reddit_ldu_mode ) ) {
2748		                                Reddit.loadPixel();
2749	                                }
2750                                } else {
2751                                    if ( ( categoryCookie === CS_Data.cs_script_cat.facebook ) && ( typeof CS_Data.cs_meta_ldu_mode == "undefined" || !CS_Data.cs_meta_ldu_mode ) ) {
2752                                        Facebook.disable();
2753                                        consent.facebook = false;
2754                                    }
2755
2756                                    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 ) ) {
2757                                        Bing.disable();
2758                                        consent.bing = false;
2759                                    }
2760
2761                                    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 ) ) {
2762                                        Analytics.disable();
2763                                        consent.ga = false;
2764                                        consent.gtm = false;
2765                                    }
2766
2767                                    if ( categoryCookie === CS_Data.cs_script_cat.gads && ( typeof CS_Data.cs_google_ads_consent_mode == "undefined" || CS_Data.cs_google_ads_consent_mode == 0 ) ) {
2768                                        GAds.disable();
2769                                        consent.google_ads = false;
2770                                    }
2771
2772                                    if ( categoryCookie === CS_Data.cs_script_cat.pinterest ) {
2773                                        Pinterest.disable();
2774                                        consent.pinterest = false;
2775                                    }
2776
2777                                    if ( categoryCookie === CS_Data.cs_script_cat.tiktok ) {
2778                                        TikTok.disable();
2779                                        consent.tiktok = false;
2780                                    }
2781
2782	                                if ( ( categoryCookie === CS_Data.cs_script_cat.reddit ) && ( typeof CS_Data.cs_reddit_ldu_mode == "undefined" || !CS_Data.cs_reddit_ldu_mode ) ) {
2783		                                Reddit.disable();
2784		                                consent.reddit = false;
2785	                                }
2786                                }
2787                                if ( Cookies.get( 'cs_enabled_advanced_matching' ) == 'yes' ) {
2788                                    Facebook.loadPixel();
2789                                }
2790                            }
2791                        }
2792
2793                        Utils.setupGDPRData( consent );
2794                    }
2795
2796                    if ( !cs_refresh_after_consent ) {
2797                        consent_actions();
2798
2799                        $( document ).on( 'click', '.cs_action_btn', function ( e ) {
2800                            e.preventDefault();
2801
2802                            let consent = {
2803                                facebook: true,
2804                                ga: true,
2805                                google_ads: true,
2806                                tiktok: true,
2807                                bing: true,
2808                                pinterest: true,
2809                                gtm: true,
2810	                            reddit: true,
2811                            };
2812
2813                            let elm = $( this ),
2814                                button_action = elm.attr( 'data-cs_action' );
2815
2816                            if ( button_action === 'allow_all' ) {
2817
2818                                Utils.initializeVideoAPIs( options );
2819
2820                                Facebook.loadPixel();
2821                                Bing.loadPixel();
2822                                Analytics.loadPixel();
2823                                GAds.loadPixel();
2824                                Pinterest.loadPixel();
2825                                TikTok.loadPixel();
2826								Reddit.loadPixel();
2827
2828                                consent.facebook = true;
2829                                consent.bing = true;
2830                                consent.ga = true;
2831                                consent.google_ads = true;
2832                                consent.pinterest = true;
2833                                consent.tiktok = true;
2834								consent.reddit = true;
2835                                consent.gtm = true;
2836
2837                                Utils.setupGDPRData( consent );
2838
2839                            } else if ( button_action === 'disable_all' ) {
2840
2841                                if (typeof CS_Data.cs_meta_ldu_mode == "undefined" || CS_Data.cs_meta_ldu_mode == 0 ) {
2842                                    Facebook.disable();
2843                                    consent.facebook = false;
2844                                }
2845
2846                                if (typeof CS_Data.cs_bing_consent_mode == "undefined" || CS_Data.cs_bing_consent_mode.ad_storage.enabled == 0 ) {
2847                                    Bing.disable();
2848                                    consent.bing = false;
2849                                }
2850
2851                                if ( typeof CS_Data.cs_google_analytics_consent_mode == "undefined" || CS_Data.cs_google_analytics_consent_mode == 0 ) {
2852                                    Analytics.disable();
2853                                    consent.ga = false;
2854                                    consent.gtm = false;
2855                                }
2856
2857                                if ( typeof CS_Data.cs_google_ads_consent_mode == "undefined" || CS_Data.cs_google_ads_consent_mode == 0 ) {
2858                                    GAds.disable();
2859                                    consent.google_ads = false;
2860                                }
2861
2862	                            if ( typeof CS_Data.cs_reddit_ldu_mode == "undefined" || CS_Data.cs_reddit_ldu_mode == 0 ) {
2863		                            Reddit.disable();
2864		                            consent.reddit = false;
2865	                            }
2866
2867                                Pinterest.disable();
2868                                TikTok.disable();
2869
2870                                consent.pinterest = false;
2871                                consent.tiktok = false;
2872
2873                                Utils.setupGDPRData( consent );
2874                            } else if ( button_action === 'cs_confirm' ) {
2875                                consent_actions();
2876                            }
2877                        } );
2878                    }
2879                }
2880
2881                /**
2882                 * Real Cookie Banner
2883                 */
2884                if ( options.gdpr.real_cookie_banner_integration_enabled ) {
2885                    isConcent = true;
2886                    let consentApi = window.consentApi;
2887                    if ( consentApi ) {
2888                        consentApi.consent( "http", "_ga", "*" )
2889                            .then( Analytics.loadPixel.bind( Analytics ), Analytics.disable.bind( Analytics ) );
2890                        consentApi.consent( "http", "1P_JAR", ".google.com" )
2891                            .then( GAds.loadPixel.bind( GAds ), GAds.disable.bind( GAds ) );
2892                        consentApi.consent( "http", "_fbp", "*" )
2893                            .then( Facebook.loadPixel.bind( Facebook ), Facebook.disable.bind( Facebook ) );
2894                        consentApi.consent( "http", "_pinterest_sess", ".pinterest.com" )
2895                            .then( Pinterest.loadPixel.bind( Pinterest ), Pinterest.disable.bind( Pinterest ) );
2896                        consentApi.consent( "http", "_uetsid", "*" )
2897                            .then( Bing.loadPixel.bind( Bing ), Bing.disable.bind( Bing ) );
2898                        consentApi.consent( "http", "tt_webid_v2", ".tiktok.com" )
2899                            .then( TikTok.loadPixel.bind( TikTok ), TikTok.disable.bind( TikTok ) );
2900
2901                        let consent = {
2902                            facebook: true,
2903                            ga: true,
2904                            google_ads: true,
2905                            tiktok: true,
2906                            bing: true,
2907                            pinterest: true,
2908           
2908                 gtm: true,
2909                        };
2910
2911                        if (!consentApi.consentSync("http", "_ga", "*").cookieOptIn) {
2912                            consent.ga = false;
2913                            consent.gtm = false;
2914                        }
2915                        if (!consentApi.consentSync("http", "_fbp", "*").cookieOptIn) {
2916                            consent.facebook = false;
2917                        }
2918                        if (!consentApi.consentSync("http", "_pinterest_sess", ".pinterest.com").cookieOptIn) {
2919                            consent.pinterest = false;
2920                        }
2921                        if (!consentApi.consentSync("http", "_uetsid", "*").cookieOptIn) {
2922                            consent.bing = false;
2923                        }
2924                        if (!consentApi.consentSync("http", "1P_JAR", ".google.com").cookieOptIn) {
2925                            consent.google_ads = false;
2926                        }
2927                        if (!consentApi.consentSync("http", "tt_webid_v2", ".tiktok.com").cookieOptIn) {
2928                            consent.tiktok = false;
2929                        }
2930                        Utils.setupGDPRData( consent );
2931
2932                        // load WatchVideo event APIs for Auto
2933                        /**
2934                         * Real Cookie Banner.
2935                         */
2936                        if ( options.hasOwnProperty( 'automatic' ) && options.automatic.enable_video && options.automatic.enable_youtube ) {
2937                            consentApi.consent( "http", "CONSENT", ".youtube.com" ).then( Utils.initYouTubeAPI );
2938                        }
2939
2940                        if ( options.hasOwnProperty( 'automatic' ) && options.automatic.enable_video && options.automatic.enable_vimeo ) {
2941                            consentApi.consent( "http", "player", ".vimeo.com" ).then( Utils.initVimeoAPI );
2942                        }
2943                    }
2944                }
2945
2946                if ( !isConcent ) {
2947                    Utils.initializeVideoAPIs( options );
2948                }
2949            },
2950
2951            setupGDPRData: function ( consent ) {
2952                consent = window.btoa( JSON.stringify( consent ) );
2953                Cookies.set( 'pys_consent', consent, { expires: 365, path: '/', domain: domain } );
2954            },
2955
2956            /**
2957             * Enrich
2958             */
2959            isCheckoutPage: function () {
2960                return $('body').hasClass('woocommerce-checkout') || document.querySelector('.woocommerce-checkout') ||
2961                    $('body').hasClass('edd-checkout');
2962            },
2963            addCheckoutFields : function() {
2964                var utm = "";
2965                var utms = getUTMs()
2966                $.each(utmTerms, function (index, name) {
2967                    if(index > 0) {
2968                        utm+="|";
2969                    }
2970                    utm+=name+":"+utms[name];
2971                });
2972                var utmIdList = "";
2973                var utmsIds = getUTMId()
2974                $.each(utmId, function (index, name) {
2975                    if(index > 0) {
2976                        utmIdList+="|";
2977                    }
2978                    utmIdList+=name+":"+utmsIds[name];
2979                });
2980                var utmIdListLast = "";
2981                var utmsIdsLast = getUTMId(true)
2982                $.each(utmId, function (index, name) {
2983                    if(index > 0) {
2984                        utmIdListLast+="|";
2985                    }
2986                    utmIdListLast+=name+":"+utmsIdsLast[name];
2987                });
2988
2989
2990                var utmLast = "";
2991                var utmsLast = getUTMs(true)
2992                $.each(utmTerms, function (index, name) {
2993                    if(index > 0) {
2994                        utmLast+="|";
2995                    }
2996                    utmLast+=name+":"+utmsLast[name];
2997                });
2998
2999                var dateTime = getDateTime();
3000                var landing = Cookies.get('pys_landing_page');
3001                var lastLanding = Cookies.get('last_pys_landing_page');
3002                var trafic = Cookies.get('pysTrafficSource');
3003                var lastTrafic = Cookies.get('last_pysTrafficSource');
3004
3005                var $form = null;
3006                if($('body').hasClass('woocommerce-checkout')) {
3007                    $form = $("form.woocommerce-checkout");
3008                } else {
3009                    $form = $("#edd_purchase_form");
3010                }
3011                var inputs = {'pys_utm':utm,
3012                    'pys_utm_id':utmIdList,
3013                    'pys_browser_time':dateTime.join("|"),
3014                    'pys_landing':landing,
3015                    'pys_source':trafic,
3016                    'pys_order_type': $(".wcf-optin-form").length > 0 ? "wcf-optin" : "normal",
3017
3018                    'last_pys_landing':lastLanding,
3019                    'last_pys_source':lastTrafic,
3020                    'last_pys_utm':utmLast,
3021                    'last_pys_utm_id':utmIdListLast,
3022                }
3023
3024                Object.keys(inputs).forEach(function(key,index) {
3025                    $form.append("<input type='hidden' name='"+key+"' value='"+inputs[key]+"' /> ");
3026                });
3027
3028
3029            },
3030
3031            /**
3032             * Advanced From Data
3033             */
3034            saveAdvancedFormData: function ( email, phone, firstName, lastName, override = true ) {
3035
3036                if ( !options.cookie.disabled_advanced_form_data_cookie ) {
3037                    let data = Utils.getAdvancedFormData();
3038                    // Ensure data["address"] is an object
3039
3040                    if ( email != null ) {
3041                        if ( !override ) {
3042                            if ( typeof data[ "email" ] === 'undefined' || !data[ "email" ] ) {
3043                                data[ "email" ] = email;
3044                            }
3045                        } else {
3046                            data[ "email" ] = email;
3047                        }
3048
3049                        if ( typeof data[ "emails" ] === 'object' ) {
3050                            if ( override ) {
3051                                data[ "emails" ] = [ email, ...Object.values( data[ "emails" ] ) ];
3052                            } else {
3053                                data[ "emails" ] = [ ...Object.values( data[ "emails" ] ), email ];
3054                            }
3055                        } else {
3056                            data[ "emails" ] = [ email ];
3057                        }
3058                        data[ "emails" ] = [ ...new Set( data[ "emails" ] ) ];
3059                        data[ "emails" ] = data[ "emails" ].slice( 0, 3 );
3060                    }
3061
3062                    if ( phone != null ) {
3063                        if ( !override ) {
3064                            if ( typeof data[ "phone" ] === 'undefined' || !data[ "phone" ] ) {
3065                                data[ "phone" ] = phone;
3066                            }
3067                        } else {
3068                            data[ "phone" ] = phone;
3069                        }
3070
3071                        if ( typeof data[ "phones" ] === 'object' ) {
3072                            if ( override ) {
3073                                data[ "phones" ] = [ phone, ...Object.values( data[ "phones" ] ) ];
3074                            } else {
3075                                data[ "phones" ] = [ ...Object.values( data[ "phones" ] ), phone ];
3076                            }
3077                        } else {
3078                            data[ "phones" ] = [ phone ];
3079                        }
3080                        data[ "phones" ] = [ ...new Set( data[ "phones" ] ) ];
3081                        data[ "phones" ] = data[ "phones" ].slice( 0, 3 );
3082                    }
3083
3084                    if ( firstName != null ) {
3085                        if ( !override ) {
3086                            if ( typeof data[ "first_name" ] === 'undefined' || !data[ "first_name" ] ) {
3087                                data[ "first_name" ] = firstName;
3088                            }
3089                        } else {
3090                            data[ "first_name" ] = firstName;
3091                        }
3092
3093                        if ( typeof data[ "fns" ] === 'object' ) {
3094                            if ( override ) {
3095                                data[ "fns" ] = [ firstName, ...Object.values( data[ "fns" ] ) ];
3096                            } else {
3097                                data[ "fns" ] = [ ...Object.values( data[ "fns" ] ), firstName ];
3098                            }
3099                        } else {
3100                            data[ "fns" ] = [ firstName ];
3101                        }
3102                        data[ "fns" ] = [ ...new Set( data[ "fns" ] ) ];
3103                        data[ "fns" ] = data[ "fns" ].slice( 0, 2 );
3104                    }
3105
3106                    if ( lastName != null ) {
3107                        if ( !override ) {
3108                            if ( typeof data[ "last_name" ] === 'undefined' || !data[ "last_name" ] ) {
3109                                data[ "last_name" ] = lastName;
3110                            }
3111                        } else {
3112                            data[ "last_name" ] = lastName;
3113                        }
3114
3115                        if ( typeof data[ "lns" ] === 'object' ) {
3116                            if ( override ) {
3117                                data[ "lns" ] = [ lastName, ...Object.values( data[ "lns" ] ) ];
3118                            } else {
3119                                data[ "lns" ] = [ ...Object.values( data[ "fns" ] ), lastName ];
3120                            }
3121                        } else {
3122                            data[ "lns" ] = [ lastName ];
3123                        }
3124                        data[ "lns" ] = [ ...new Set( data[ "lns" ] ) ];
3125                        data[ "lns" ] = data[ "lns" ].slice( 0, 2 );
3126                    }
3127
3128                    Cookies.set( 'pys_advanced_form_data', JSON.stringify( data ), { expires: 300,path: '/',domain: domain } );
3129                } else {
3130                    Cookies.remove( 'pys_advanced_form_data', { path: '/',domain: domain } )
3131                }
3132                if(GTM.isEnabled()){
3133                    GTM.updateEnhancedConversionData();
3134                }
3135                if(Analytics.isEnabled()){
3136                    Analytics.updateEnhancedConversionData();
3137                } else if ( GAds.isEnabled() ) {
3138                    GAds.updateEnhancedConversionData();
3139                }
3140            },
3141            getAdvancedMergeFormData: function (allways_provided_data = false) {
3142                const advanced = Utils.getAdvancedFormData();
3143                let mergedData = {},
3144                    limit = options.tracking_analytics.use_multiple_provided_data || allways_provided_data ? 3 : 1,
3145                    address_limit = options.tracking_analytics.use_multiple_provided_data || allways_provided_data ? 2 : 1;
3146
3147                if ( options.tracking_analytics.use_encoding_provided_data || allways_provided_data) {
3148                    mergedData.sha256_email_address = [];
3149                    mergedData.sha256_phone_number = [];
3150                    mergedData.address = [];
3151                    if ( options.tracking_analytics.hasOwnProperty( "userData" ) ) {
3152                        if ( options.tracking_analytics.userData.hasOwnProperty( "emails" ) && Object.keys( options.tracking_analytics.userData.emails ).length > 0 ) {
3153                            Object.keys( options.tracking_analytics.userData.emails ).forEach( ( key ) => {
3154                                mergedData.sha256_email_address.push( sha256( options.tracking_analytics.userData.emails[ key ] ) );
3155                            } )
3156                        }
3157                        if ( options.tracking_analytics.userData.hasOwnProperty( "phones" ) && Object.keys( options.tracking_analytics.userData.phones ).length > 0 ) {
3158                            Object.keys( options.tracking_analytics.userData.phones ).forEach( ( key ) => {
3159                                mergedData.sha256_phone_number.push( sha256( options.tracking_analytics.userData.phones[ key ] ) );
3160                            } )
3161                        }
3162                        if ( options.tracking_analytics.userData.hasOwnProperty( "addresses" ) && Object.keys( options.tracking_analytics.userData.addresses ).length > 0 ) {
3163                            Object.keys( options.tracking_analytics.userData.addresses ).forEach( ( key ) => {
3164                                let address = Object.assign( {}, options.tracking_analytics.userData.addresses[ key ] );
3165
3166                                if ( address.first_name ) {
3167                                    address.sha256_first_name = address.first_name !== '' ? sha256( address.first_name ) : '';
3168                                    delete address.first_name;
3169                                }
3170                                if ( address.last_name ) {
3171                                    address.sha256_last_name = address.last_name !== '' ? sha256( address.last_name ) : '';
3172                                    delete address.last_name;
3173                                }
3174                                mergedData.address.push( address );
3175                            } )
3176                        }
3177                    }
3178
3179                    let data_persistency = options.data_persistency;
3180
3181                    //emails
3182                    if ( advanced.emails && Object.keys( advanced.emails ).length > 0 ) {
3183                        Object.keys( advanced.emails ).forEach( ( ke
3183y ) => {
3184                            if ( data_persistency === 'recent_data' ) {
3185                                mergedData.sha256_email_address.push( sha256( advanced.emails[ key ] ) );
3186                            } else {
3187                                mergedData.sha256_email_address.unshift( sha256( advanced.emails[ key ] ) );
3188                            }
3189                        } )
3190                    }
3191                    if ( advanced.email && advanced.email !== '' ) {
3192                        if ( data_persistency === 'recent_data' ) {
3193                            mergedData.sha256_email_address.push( sha256( advanced.email ) );
3194                        } else {
3195                            mergedData.sha256_email_address.unshift( sha256( advanced.email ) );
3196                        }
3197                    }
3198                    mergedData.sha256_email_address = [ ...new Set( mergedData.sha256_email_address ) ];
3199                    mergedData.sha256_email_address = mergedData.sha256_email_address.slice( 0, limit );
3200
3201                    //phones
3202                    if ( advanced.phones && Object.keys( advanced.phones ).length > 0 ) {
3203                        Object.keys( advanced.phones ).forEach( ( key ) => {
3204                            if ( data_persistency === 'recent_data' ) {
3205                                mergedData.sha256_phone_number.push( sha256( advanced.phones[ key ] ) );
3206                            } else {
3207                                mergedData.sha256_phone_number.unshift( sha256( advanced.phones[ key ] ) );
3208                            }
3209                        } )
3210                    }
3211                    if ( advanced.phone && advanced.phone !== '' ) {
3212                        if ( data_persistency === 'recent_data' ) {
3213                            mergedData.sha256_phone_number.push( sha256( advanced.phone ) );
3214                        } else {
3215                            mergedData.sha256_phone_number.unshift( sha256( advanced.phone ) );
3216                        }
3217                    }
3218                    mergedData.sha256_phone_number = [ ...new Set( mergedData.sha256_phone_number ) ];
3219                    mergedData.sha256_phone_number = mergedData.sha256_phone_number.slice( 0, limit );
3220
3221                    //first and last names
3222                    if ( advanced.fns && Object.keys( advanced.fns ).length > 0 ) {
3223                        Object.entries( advanced.fns ).forEach( ( item ) => {
3224                            if ( mergedData.address.length < address_limit ) {
3225                                let first_name = item[ 1 ];
3226                                let last_name = ( advanced.lns && Object.keys( advanced.lns ).length > 0 ) ? ( advanced.lns[ item[ 0 ] ] ? advanced.lns[ item[ 0 ] ] : advanced.lns[ 0 ] ) : '';
3227                                let address = {
3228                                    sha256_first_name: first_name !== '' ? sha256( first_name ) : '',
3229                                    sha256_last_name: last_name !== '' ? sha256( last_name ) : '',
3230                                    // Add other address properties here if they exist in advanced
3231                                };
3232                                mergedData.address.push( address );
3233                            }
3234                        } )
3235                    }
3236
3237                    if ( advanced.first_name || advanced.last_name ) {
3238                        if ( mergedData.address.length < address_limit ) {
3239                            let address = {
3240                                sha256_first_name: advanced.first_name !== '' ? sha256( advanced.first_name ) : '',
3241                                sha256_last_name: advanced.last_name !== '' ? sha256( advanced.last_name ) : '',
3242                                // Add other address properties here if they exist in advanced
3243                            };
3244                            mergedData.address.push( address );
3245                        }
3246                    }
3247                } else {
3248                    mergedData.email = [];
3249                    mergedData.phone_number = [];
3250                    mergedData.address = [];
3251                    if ( options.tracking_analytics.hasOwnProperty( "userData" ) ) {
3252                        if ( options.tracking_analytics.userData.hasOwnProperty( "emails" ) && Object.keys( options.tracking_analytics.userData.emails ).length > 0 ) {
3253                            Object.keys( options.tracking_analytics.userData.emails ).forEach( ( ke
3253y ) => {
3254                                mergedData.email.push( options.tracking_analytics.userData.emails[ key ] );
3255                            } )
3256                        }
3257                        if ( options.tracking_analytics.userData.hasOwnProperty( "phones" ) && Object.keys( options.tracking_analytics.userData.phones ).length > 0 ) {
3258                            Object.keys( options.tracking_analytics.userData.phones ).forEach( ( key ) => {
3259                                mergedData.phone_number.push( options.tracking_analytics.userData.phones[ key ] );
3260                            } )
3261                        }
3262                        if ( options.tracking_analytics.userData.hasOwnProperty( "addresses" ) && Object.keys( options.tracking_analytics.userData.addresses ).length > 0 ) {
3263                            Object.keys( options.tracking_analytics.userData.addresses ).forEach( ( key ) => {
3264                                mergedData.address.push( options.tracking_analytics.userData.addresses[ key ] );
3265                            } )
3266                        }
3267                    }
3268
3269                    let data_persistency = options.data_persistency;
3270
3271                    //emails
3272                    if ( advanced.emails && Object.keys( advanced.emails ).length > 0 ) {
3273                        Object.keys( advanced.emails ).forEach( ( key ) => {
3274                            if ( data_persistency === 'recent_data' ) {
3275                                mergedData.email.push( advanced.emails[ key ] );
3276                            } else {
3277                                mergedData.email.unshift( advanced.emails[ key ] );
3278                            }
3279                        } )
3280                    }
3281                    if ( advanced.email && advanced.email !== '' ) {
3282                        if ( data_persistency === 'recent_data' ) {
3283                            mergedData.email.push( advanced.email );
3284                        } else {
3285                            mergedData.email.unshift( advanced.email );
3286                        }
3287                    }
3288                    mergedData.email = [ ...new Set( mergedData.email ) ];
3289                    mergedData.email = mergedData.email.slice( 0, limit );
3290
3291                    //phones
3292                    if ( advanced.phones && Object.keys( advanced.phones ).length > 0 ) {
3293                        Object.keys( advanced.phones ).forEach( ( key ) => {
3294                            if ( data_persistency === 'recent_data' ) {
3295                                mergedData.phone_number.push( advanced.phones[ key ] );
3296                            } else {
3297                                mergedData.phone_number.unshift( advanced.phones[ key ] );
3298                            }
3299                        } )
3300                    }
3301                    if ( advanced.phone && advanced.phone !== '' ) {
3302                        if ( data_persistency === 'recent_data' ) {
3303                            mergedData.phone_number.push( advanced.phone );
3304                        } else {
3305                            mergedData.phone_number.unshift( advanced.phone );
3306                        }
3307                    }
3308                    mergedData.phone_number = [ ...new Set( mergedData.phone_number ) ];
3309                    mergedData.phone_number = mergedData.phone_number.slice( 0, limit );
3310
3311                    //first and last names
3312                    if ( advanced.fns && Object.keys( advanced.fns ).length > 0 ) {
3313                        Object.entries( advanced.fns ).forEach( ( item ) => {
3314                            if ( mergedData.address.length < address_limit ) {
3315                                let first_name = item[ 1 ];
3316                                let last_name = ( advanced.lns && Object.keys( advanced.lns ).length > 0 ) ? ( advanced.lns[ item[ 0 ] ] ? advanced.lns[ item[ 0 ] ] : advanced.lns[ 0 ] ) : '';
3317                                let address = {
3318                                    first_name: first_name || '',
3319                                    last_name: last_name || '',
3320                                    // Add other address properties here if they exist in advanced
3321                                };
3322                                mergedData.address.push( address );
3323                            }
3324                        } )
3325                    }
3326
3327                    if ( advanced.first_name || advanced.last_name ) {
3328                        if ( mergedData.address.length < address_limit ) {
3329                            let address = {
3330                                first_name: advanced.first_name || '',
3331                                last_name: advanced.last_name || '',
3332                                // Add other address properties here if they exist in advanced
3333                            };
3334                            mergedData.address.push( address );
3335                        }
3336                    }
3337                }
3338
3339                Utils.removeEmptyProperties( mergedData );
3340                return mergedData;
3341            },
3342            removeEmptyProperties : function(obj) {
3343
3344                if (obj.hasOwnProperty('address')) {
3345                    // Проходим по каждому массиву в 'address'
3346                    for (let i = 0; i < obj['address'].length; i++) {
3347                        let address1 = obj['address'][i];
3348
3349                        // Сравниваем с каждым другим массивом в 'address'
3350                        for (let j = i + 1; j < obj['address'].length; j++) {
3351                            let address2 = obj['address'][j];
3352
3353                            // Если находим дублирующиеся свойства, удаляем их из address2
3354                            for (let prop in address1) {
3355                                if (address1[prop] === address2[prop]) {
3356                                    delete address2[prop];
3357                                }
3358                            }
3359                        }
3360                    }
3361                }
3362
3363                for (let key in obj) {
3364                    if (obj[key] === null || obj[key] === undefined || obj[key] === '') {
3365                        delete obj[key];
3366                    } else if (Array.isArray(obj[key])) {
3367                        obj[key] = [...new Set(obj[key])]; // Удаление дубликатов из массива
3368                        obj[key] = obj[key].filter(item => item !== null && item !== undefined && item !== '');
3369                        // Обработка объектов внутри массивов
3370                        obj[key] = obj[key].map(item => {
3371                            if (item === null) {
3372                                return; // Пропускаем null элементы
3373                            } else if (Array.isArray(item)) {
3374                                return this.removeEmptyProperties(item);
3375                            } else if (typeof item === 'object') {
3376                                let cleanedItem = this.removeEmptyProperties(item);
3377                                if (Object.keys(cleanedItem).length > 0) {
3378                                    return cleanedItem;
3379                                }
3380                            } else {
3381                                return item;
3382                            }
3383                        });
3384                        // Удаляем пустые объекты и null из массива
3385                        obj[key] = obj[key].filter(item => item !== undefined && !(typeof item === 'object' && Object.keys(item).length === 0));
3386                        if (obj[key].length === 0) {
3387                            delete obj[key];
3388                        }
3389                    } else if (typeof obj[key] === 'object') {
3390                        this.removeEmptyProperties(obj[key]);
3391                        if (Object.keys(obj[key]).length === 0) {
3392                            delete obj[key];
3393                        }
3394                    }
3395                }
3396                return obj;
3397            },
3398            getAdvancedFormData: function () {
3399                let dataStr = Cookies.get("pys_advanced_form_data");
3400                if(dataStr === undefined) {
3401                    return {'first_name':"",'last_name':"",'email':"",'phone':"",'fns':[],'lns':[],'emails':[],'phones':[]};
3402                } else {
3403                    return JSON.parse(dataStr);
3404                }
3405            },
3406
3407            getFormFilledData: function ( event ) {
3408                // First, resolve static/dynamic parameters
3409                if (event.params && Object.keys(event.params).length > 0) {
3410                    Object.entries(event.params).forEach(([key, value]) => {
3411                        // Resolve parameter value (static or dynamic)
3412                        const resolvedValue = resolveParamValue(value);
3413                        if (resolvedValue !== null) {
3414                            event.params[key] = resolvedValue;
3415                        }
3416                        else {
3417                            delete event.params[key];
3418                        }
3419                    });
3420                }
3421
3422                // Then, handle dynamic fields from cookies (existing logic)
3423
3424                if ( Object.keys(options.track_dynamic_fields).length > 0 && Object.keys(event.params).length > 0 ) {
3425                    Object.entries(event.params).forEach((item) => {
3426
3427                        if ( options.track_dynamic_fields.hasOwnProperty(item[0]) ) {
3428                            let fieldData = Cookies.get('pys_dyn_field_' + item[1] );
3429
3430                            if(fieldData !== undefined && fieldData !== '') {
3431                                event.params[item[0]] = fieldData;
3432                            } else {
3433                                delete event.params[item[0]];
3434                            }
3435                        }
3436                    })
3437                }
3438                return event;
3439            }
3440
3441        };
3442
3443    }(options);
3444
3445    var TikTok = function (options) {
3446
3447        var initialized = false;
3448
3449        function fireEvent(name, event) {
3450
3451            if(typeof window.pys_event_data_filter === "function" && window.pys_disable_event_filter(name,'tiktok')) {
3452                return;
3453            }
3454
3455            var data = event.params;
3456
3457            var ids = event.pixelIds.filter(function (pixelId) {
3458                return !Utils.hideMatchingPixel(pixelId, 'tiktok');
3459            })
3460            var params = {};
3461            Utils.copyProperties(data, params);
3462
3463            params.eventID = Utils.generateUniqueId(event);
3464
3465            if(ids.length > 0){
3466                TikTok.fireEventAPI(name, event, params);
3467            }
3468            ids.forEach(function(pixelId){
3469                if (options.debug) {
3470                    console.log('[TikTok] ' + name, params,"pixel_id",pixelId);
3471                }
3472
3473                ttq.instance(pixelId).track(name,params)
3474
3475            });
3476
3477            var customEvent = new CustomEvent('tiktok_event_sent', {
3478                detail: {
3479                    eventName: name,
3480                    params: params,
3481                    pixel_ids: ids
3482                }
3483            });
3484            window.dispatchEvent(customEvent);
3485        }
3486
3487        return {
3488            tag: function() {
3489                return "tiktok";
3490            },
3491            isEnabled: function () {
3492                return options.hasOwnProperty('tiktok');
3493            },
3494            getHidePixel: function(){
3495                if(this.isEnabled() && options.tiktok.hasOwnProperty('hide_pixels'))
3496                {
3497                    return options.tiktok.hide_pixels;
3498                }
3499                return [];
3500            },
3501            disable: function () {
3502                initialized = false;
3503            },
3504
3505            loadPixel:function () {
3506                if (initialized || !this.isEnabled() || !Utils.consentGiven('tiktok')) {
3507                    return;
3508                }
3509                for (var i = 0; i < options.tiktok.pixelIds.length; i++) {
3510                    var trackingId = options.tiktok.pixelIds[i];
3511                    if (!Utils.hideMatchingPixel(trackingId, 'tiktok')) {
3512                        !function (w, d, t) {
3513                            w.TiktokAnalyticsObject=t;
3514                            var ttq=w[t]=w[t]||[];
3515                            ttq.methods=["page","track","identify","instances","debug","on","off","once","ready","alias","group","enableCookie","disableCookie"];
3516                            ttq.setAndDefer=function(t,e){t[e]=function(){t.push([e].concat(Array.prototype.slice.call(arguments,0)))}};
3517                            for(var i=0;i<ttq.methods.length;i++)
3518                                ttq.setAndDefer(ttq,ttq.methods[i]);
3519                            ttq.instance=function(t){for(var e=ttq._i[t]||[],n=0;n<ttq.methods.length;n++)ttq.setAndDefer(e,ttq.methods[n]);return e};
3520                            ttq.load=function(e,n){var i="https://analytics.tiktok.com/i18n/pixel/events.js";ttq._i=ttq._i||{},ttq._i[e]=[],ttq._i[e]._u=i,ttq._t=ttq._t||{},ttq._t[e]=+new Date,ttq._o=ttq._o||{},ttq._o[e]=n||{};var o=document.createElement("script");o.type="text/javascript",o.async=!0,o.src=i+"?sdkid="+e+"&lib="+t;var a=document.getElementsByTagName("script")[0];a.parentNode.insertBefore(o,a)};
3521
3522                            //ttq.load('C60QSCQRVDG9JAKNPK2G');
3523                            //ttq.page();
3524                        }(window, document, 'ttq');
3525                        break;
3526                    }
3527                }
3528
3529
3530                var ids = options.tiktok.pixelIds.filter(function (pixelId) {
3531                    return !Utils.hideMatchingPixel(pixelId, 'tiktok');
3532                })
3533                ids.forEach(function (pixelId) {
3534
3535                    ttq.load(pixelId);
3536                    ttq.page();
3537                    let advancedMatching = {};
3538                    if(options.tiktok.hasOwnProperty('advanced_matching')
3539                        && Object.keys(options.tiktok.advanced_matching).length > 0) {
3540                        advancedMatching = options.tiktok.advanced_matching;
3541                        if(!advancedMatching.hasOwnProperty("external_id")){
3542                            if (Cookies.get('pbid')) {
3543                                advancedMatching["external_id"] = Cookies.get('pbid');
3544                            }
3545                        }
3546                        else if(advancedMatching.hasOwnProperty("external_id") && advancedMatching.external_id != Cookies.get('pbid'))
3547                        {
3548                            advancedMatching["external_id"] = Cookies.get('pbid') ? Cookies.get('pbid') : advancedMatching.external_id;
3549                        }
3550
3551                        ttq.instance(pixelId).identify(advancedMatching)
3552                    }
3553                });
3554                initialized = true;
3555
3556                if (options.staticEvents.hasOwnProperty('tiktok')) {
3557                    var timeout = 1;
3558                    setTimeout(function (timeout) {
3559                        Utils.fireStaticEvents('tiktok', timeout);
3560                    }, 1500, timeout)
3561                }
3562            },
3563
3564            fireEvent: function (name, data) {
3565                if (!initialized || !this.isEnabled()) {
3566                    return false;
3567                }
3568                data.delay = data.delay || 0;
3569
3570                if (data.delay === 0) {
3571                    fireEvent(name, data);
3572                } else {
3573                    setTimeout(function (name, params) {
3574                        fireEvent(name, params);
3575                    }, data.delay * 1000, name, data);
3576                }
3577                return true;
3578            },
3579
3580            fireEventAPI: function (name, event, params) {
3581
3582                var ids = event.pixelIds.filter(function (pixelId) {
3583                    return !Utils.hideMatchingPixel(pixelId, 'tiktok');
3584                })
3585                var notCachedEventsIds = new Array();
3586                var isAddToCartFromJs =  options.woo.hasOwnProperty("addToCartCatchMethod")
3587                    && options.woo.addToCartCatchMethod === "add_cart_js";
3588                if(!isAddToCartFromJs) {
3589                    notCachedEventsIds.push('woo_add_to_cart_on_button_click')
3590                }
3591
3592                if(options.tiktok.serverApiEnabled) {
3593                    if(!notCachedEventsIds.includes(event.e_id)) {
3594
3595                        var isApiDisabled = options.gdpr.all_disabled_by_api ||
3596                            options.gdpr.tiktok_disabled_by_api ||
3597                            options.gdpr.cookiebot_integration_enabled ||
3598                            options.gdpr.cookie_notice_integration_enabled ||
3599                            options.gdpr.consent_magic_integration_enabled ||
3600                            options.gdpr.cookie_law_info_integration_enabled;
3601                        // Update eventID
3602
3603                        // send event from server if they were block by gdpr or need send with delay
3604                        if( options.ajaxForServerEvent || isApiDisabled || event.delay > 0 || event.type !== "static" ){
3605
3606                            var json = {
3607                                action: 'pys_tiktok_api_event',
3608                                pixel: TikTok.tag(),
3609                                event: name,
3610                                event_slug: event.e_id,
3611                                ids: ids,
3612                                data:params,
3613                                url:window.location.href,
3614                                event_id:params.eventID,
3615                                ajax_event:options.ajax_event
3616                            };
3617
3618                            let delay = 0;
3619                            try {
3620                                if (sessionStorage) {
3621                                    Object.keys(sessionStorage)
3622                                        .filter(key => key.startsWith('wc_fragments_'))
3623                                        .forEach((key) => {
3624                                            let value = sessionStorage.getItem(key);
3625                                            if (event.e_id === 'woo_add_to_cart_on_button_click') {
3626                                                delay = 2000;
3627                                            }
3628                                        });
3629                                }
3630                            } catch (error) {
3631                                console.error('sessionStorage is not accessible:', error);
3632                            }
3633
3634
3635                            if(event.hasOwnProperty('woo_order')) {
3636                                json['woo_order'] = event.woo_order;
3637                            }
3638
3639                            if(event.hasOwnProperty('edd_order')) {
3640                                json['edd_order'] = event.edd_order;
3641                            }
3642                            if (event.e_id === "automatic_event_internal_link" || event.e_id === "automatic_event_outbound_link" || name == 'PageView') {
3643                                delay = delay === 0 ? 500 : delay;
3644                                setTimeout(() => Utils.sendServerAjaxRequest(options.ajaxUrl, json), delay);
3645                            } else if (event.type != 'static') {
3646                                setTimeout(() => Utils.sendServerAjaxRequest(options.ajaxUrl, json), delay);
3647                            }
3648
3649                            if ( ( event.type == 'static' && options.ajaxForServerStaticEvent ) || ( event.hasOwnProperty( 'ajaxFire' ) && event.ajaxFire ) ) {
3650                                setTimeout( () => Utils.sendServerAjaxRequest( options.ajaxUrl, json ), delay );
3651                            }
3652                        }
3653                    }
3654                }
3655            },
3656
3657            onClickEvent: function (event) {
3658                this.fireEvent(event.name, event);
3659            },
3660
3661            onWooAddToCartOnSingleEvent: function (product_id, qty, product_type, is_external, $form) {
3662
3663                window.pysWooProductData = window.pysWooProductData || [];
3664                if (!options.dynamicEvents.woo_add_to_cart_on_button_click.hasOwnProperty(this.tag()))
3665                    return;
3666
3667                if (window.pysWooProductData.hasOwnProperty(product_id)) {
3668                    if (window.pysWooProductData[product_id].hasOwnProperty(this.tag())) {
3669
3670                        var event = Utils.clone(options.dynamicEvents.woo_add_to_cart_on_button_click[this.tag()]);
3671
3672                        Utils.copyProperties(window.pysWooProductData[product_id][this.tag()]['params'], event.params);
3673
3674                        // maybe customize value option
3675                        if (options.woo.addToCartOnButtonValueEnabled && options.woo.addToCartOnButtonValueOption !== 'global') {
3676
3677                            if (product_type === Utils.PRODUCT_BUNDLE) {
3678                                var data = $(".bundle_form .bundle_data").data("bundle_form_data");
3679                                var items_sum = getBundlePriceOnSingleProduct(data);
3680                                event.params.value = (parseFloat(data.base_price) + items_sum) * qty;
3681                            } else {
3682                                event.params.value = event.params.value * qty;
3683                            }
3684                        }
3685
3686                        event.params.quantity = qty;
3687
3688                        this.fireEvent(event.name, event);
3689
3690                    }
3691                }
3692            },
3693
3694            onWooAddToCartOnButtonEvent: function (product_id) {
3695                if(!options.dynamicEvents.woo_add_to_cart_on_button_click.hasOwnProperty(this.tag()))
3696                    return;
3697
3698                if (window.pysWooProductData.hasOwnProperty(product_id)) {
3699                    if (window.pysWooProductData[product_id].hasOwnProperty(this.tag())) {
3700                        var productData = window.pysWooProductData[product_id][this.tag()]
3701                        var event = Utils.clone(options.dynamicEvents.woo_add_to_cart_on_button_click[this.tag()])
3702
3703                        Utils.copyProperties(productData['params'], event.params)
3704                        event.pixelIds = productData['pixelIds'];
3705                        this.fireEvent(event.name, event);
3706                    }
3707                }
3708            },
3709
3710            onEddAddToCartOnButtonEvent : function (download_id, price_index, qty) {
3711                if(!options.dynamicEvents.edd_add_to_cart_on_button_click.hasOwnProperty(this.tag()))
3712                    return;
3713                var event = Utils.clone(options.dynamicEvents.edd_add_to_cart_on_button_click[this.tag()]);
3714
3715
3716                if (window.pysEddProductData.hasOwnProperty(download_id)) {
3717
3718                    var index;
3719
3720                    if (price_index) {
3721                        index = download_id + '_' + price_index;
3722                    } else {
3723                        index = download_id;
3724                    }
3725
3726                    if (window.pysEddProductData[download_id].hasOwnProperty(index)) {
3727                        if (window.pysEddProductData[download_id][index].hasOwnProperty(this.tag())) {
3728
3729                            Utils.copyProperties(window.pysEddProductData[download_id][index][this.tag()].params, event.params);
3730                            this.fireEvent(event.name,event);
3731
3732                        }
3733                    }
3734
3735                }
3736            },
3737
3738            onPageScroll: function (event) {
3739                if (initialized && this.isEnabled()) {
3740                    this.fireEvent(event.name, event);
3741                }
3742            },
3743
3744            onWatchVideo: function (event) {
3745                if (initialized && this.isEnabled() && !event.fired) {
3746                    this.fireEvent(event.name, event);
3747                }
3748            },
3749
3750            onCommentEvent: function (event) {
3751                if (initialized && this.isEnabled()) {
3752                    this.fireEvent(event.name, event);
3753                }
3754            },
3755
3756            onAdSenseEvent: function (event) {
3757                if (initialized && this.isEnabled()) {
3758                    this.fireEvent(event.name, event);
3759                }
3760            },
3761
3762            onTime: function (event) {
3763                if (initialized && this.isEnabled()) {
3764                    this.fireEvent(event.name, event);
3765                }
3766            },
3767        }
3768    }(options);
3769
3770    var Facebook = function (options) {
3771
3772        var defaultEventTypes = [
3773            'PageView',
3774            'ViewContent',
3775            'Search',
3776            'AddToCart',
3777            'AddToWishlist',
3778            'InitiateCheckout',
3779            'AddPaymentInfo',
3780            'Purchase',
3781            'Lead',
3782
3783            'Subscribe',
3784            'CustomizeProduct',
3785            'FindLocation',
3786            'StartTrial',
3787            'SubmitApplication',
3788            'Schedule',
3789            'Contact',
3790            'Donate'
3791        ];
3792
3793        var notCachedEventsIds = new Array();
3794        var isAddToCartFromJs =  options.woo.hasOwnProperty("addToCartCatchMethod")
3795            && options.woo.addToCartCatchMethod === "add_cart_js";
3796        if(!isAddToCartFromJs) {
3797            notCachedEventsIds.push('woo_add_to_cart_on_button_click')
3798        }
3799
3800        var initialized = false;
3801
3802        var genereateFbp = function (){
3803            return !Cookies.get('_fbp') ? 'fb.1.'+Date.now()+'.'+Math.floor(1000000000 + Math.random() * 9000000000) : Cookies.get('_fbp');
3804        };
3805        var genereateFbc = function (){
3806            return getUrlParameter('fbclid') ? 'fb.1.'+Date.now()+'.'+getUrlParameter('fbclid') : ''
3807        };
3808
3809        var configuredPixels = new Array();
3810        function fireEvent(name, event) {
3811
3812
3813            if(typeof window.pys_event_data_filter === "function" && window.pys_disable_event_filter(name,'facebook')) {
3814                return;
3815            }
3816
3817            var data = event.params;
3818            var ids = event.pixelIds.filter(function (pixelId) {
3819                return !Utils.hideMatchingPixel(pixelId, 'facebook');
3820            });
3821
3822            var actionType = defaultEventTypes.includes(name) ? 'trackSingle' : 'trackSingleCustom';
3823
3824            var params = {};
3825
3826            Utils.copyProperties(data, params);
3827            Utils.copyProperties(Utils.getRequestParams(), params);
3828            Utils.copyProperties(Utils.getRequestParams(), data);
3829
3830            params = Facebook.filterParams(params);
3831
3832
3833            if(options.facebook.serverApiEnabled) {
3834                if(event.e_id === "woo_remove_from_cart" ) {
3835                    Facebook.updateEventId(event.name);
3836                    event.eventID = Facebook.getEventId(event.name);
3837                } else if(!notCachedEventsIds.includes(event.e_id)) {
3838                    var isApiDisabled = options.gdpr.all_disabled_by_api ||
3839                        options.gdpr.facebook_disabled_by_api ||
3840                        options.gdpr.cookiebot_integration_enabled ||
3841                        options.gdpr.cookie_notice_integration_enabled ||
3842                        options.gdpr.consent_magic_integration_enabled ||
3843                        options.gdpr.cookie_law_info_integration_enabled;
3844                    // Update eventID
3845
3846                    event.eventID = Utils.generateUniqueId(event);
3847
3848                    if(Cookies.get('_fbp')){
3849                        params._fbp = Cookies.get('_fbp');
3850                    }
3851                    if(Cookies.get('_fbc')){
3852                        params._fbc = Cookies.get('_fbc');
3853                    }
3854                    // send event from server if they was bloc by gdpr or need send with delay
3855                    if( options.ajaxForServerEvent || isApiDisabled ){
3856                        var json = {
3857                            action: 'pys_api_event',
3858                            pixel: 'facebook',
3859                            event: name,
3860                            event_slug: event.e_id,
3861                            ids: ids,
3862                            data:params,
3863                            url:window.location.href,
3864                            eventID:event.eventID,
3865                            ajax_event:options.ajax_event
3866                        };
3867
3868                        if(event.hasOwnProperty('woo_order')) {
3869                            json['woo_order'] = event.woo_order;
3870                        }
3871
3872                        if(event.hasOwnProperty('edd_order')) {
3873                            json['edd_order'] = event.edd_order;
3874                        }
3875
3876                        let delay = 0;
3877                        try {
3878                            if (sessionStorage) {
3879                                Object.keys(sessionStorage)
3880                                    .filter(key => key.startsWith('wc_fragments_'))
3881                                    .forEach((key) => {
3882                                        let value = sessionStorage.getItem(key);
3883                                        if (event.e_id === 'woo_add_to_cart_on_button_click') {
3884                                            delay = 2000;
3885                                        }
3886                                    });
3887                            }
3888                        } catch (error) {
3889                            console.error('sessionStorage is not accessible:', error);
3890                        }
3891
3892                        if (event.e_id === "automatic_event_internal_link" || event.e_id === "automatic_event_outbound_link") {
3893                            delay = delay === 0 ? 500 : delay;
3894                            setTimeout(() => Utils.sendServerAjaxRequest(options.ajaxUrl, json), delay);
3895                        } else if (event.type != 'static') {
3896                            setTimeout(() => Utils.sendServerAjaxRequest(options.ajaxUrl, json), delay);
3897                        }
3898
3899                        if ( ( event.type == 'static' && options.ajaxForServerStaticEvent ) || ( event.hasOwnProperty( 'ajaxFire' ) && event.ajaxFire ) ) {
3900                            setTimeout( () => Utils.sendServerAjaxRequest( options.ajaxUrl, json ), delay );
3901                        }
3902                    }
3903
3904                    if( event.e_id !== "automatic_event_signup" && name == "CompleteRegistration" && options.facebook.wooCRSendFromServer ) {
3905                        return;
3906                    }
3907                }
3908
3909            }
3910            delete params._fbp;
3911            delete params._fbc;
3912            if (options.debug) {
3913                console.log('[Facebook] ' + name, params,"pixel_ids",ids,"eventID",event.eventID);
3914            }
3915            // fire event for each pixel id
3916            ids.forEach(function (pixelId) {
3917                // add eventID for deduplicate events @see https://developers.facebook.com/docs/marketing-api/conversions-api/deduplicate-pixel-and-server-events/
3918                var args = {};
3919                if(options.facebook.serverApiEnabled && event.hasOwnProperty('eventID')) {
3920                    args.eventID = event.eventID;
3921                }
3922                Facebook.maybeInitPixel(pixelId);
3923                fbq(actionType,pixelId, name, params,args);
3924            });
3925            var customEvent = new CustomEvent('facebook_event_sent', {
3926                detail: {
3927                    eventName: name,
3928                    params: params,
3929                    pixel_ids: ids
3930                }
3931            });
3932            window.dispatchEvent(customEvent);
3933        }
3934
3935        /**
3936         * Public API
3937         */
3938        return {
3939            tag: function() {
3940                return "facebook";
3941            },
3942            isEnabled: function () {
3943                return options.hasOwnProperty('facebook');
3944            },
3945            getHidePixel: function(){
3946                if(this.isEnabled() && options.facebook.hasOwnProperty('hide_pixels'))
3947                {
3948                    return options.facebook.hide_pixels;
3949                }
3950                return [];
3951            },
3952            initEventIdCookies: function (key) {
3953                var ids = {};
3954                ids[key] = pys_generate_token(36)
3955                Cookies.set('pys_fb_event_id', JSON.stringify(ids), {path: '/',domain: domain});
3956            },
3957
3958            updateEventId:function(key) {
3959                var cooData = Cookies.get("pys_fb_event_id")
3960                if(cooData === undefined) {
3961                    this.initEventIdCookies(key);
3962                } else {
3963                    var data = JSON.parse(cooData);
3964                    data[key] = pys_generate_token(36);
3965                    Cookies.set('pys_fb_event_id', JSON.stringify(data), {path: '/',domain: domain} );
3966                }
3967            },
3968
3969            getEventId:function (key) {
3970                var data = Cookies.get("pys_fb_event_id");
3971                if(data === undefined) {
3972                    this.initEventIdCookies(key);
3973                    data = Cookies.get("pys_fb_event_id");
3974                }
3975                return JSON.parse(data)[key];
3976            },
3977
3978            disable: function () {
3979                initialized = false;
3980            },
3981
3982            filterParams: function (params) {
3983                var filteredParams = {};
3984
3985                if (options.facebook.hasOwnProperty('enabled_medical') && options.facebook.enabled_medical && options.facebook.hasOwnProperty('do_not_track_medical_param')) {
3986                    // Remove empty strings from the array
3987                    options.facebook.do_not_track_medical_param = options.facebook.do_not_track_medical_param.filter(Boolean);
3988                    for (const key in params) {
3989                        if (Array.isArray(options.facebook.do_not_track_medical_param)) {
3990                            if (!options.facebook.do_not_track_medical_param.includes(key)) {
3991                                filteredParams[key] = params[key];
3992                            }
3993                        }
3994                    }
3995                }
3996                else {
3997                    Utils.copyProperties(params, filteredParams);
3998                }
3999                return filteredParams;
4000            },
4001
4002            /**
4003             * Load pixel's JS
4004             */
4005            loadPixel: function () {
4006                if (initialized || !this.isEnabled() || !Utils.consentGiven('facebook')) {
4007                    return;
4008                }
4009
4010                ! function (f, b, e, v, n, t, s) {
4011                    if (f.fbq) return;
4012                    n = f.fbq = function () {
4013                        n.callMethod ?
4014                            n.callMethod.apply(n, arguments) : n.queue.push(arguments)
4015                    };
4016                    if (!f._fbq) f._fbq = n;
4017                    n.push = n;
4018                    n.loaded = !0;
4019                    n.version = '2.0';
4020                    n.agent = 'dvpixelyoursite';
4021                    n.queue = [];
4022                    t = b.createElement(e);
4023                    t.async = !0;
4024                    t.src = v;
4025                    s = b.getElementsByTagName(e)[0];
4026                    s.parentNode.insertBefore(t, s)
4027                }(window,
4028                    document, 'script', 'https://connect.facebook.net/en_US/fbevents.js');
4029                let expires = parseInt(options.cookie_duration);
4030                if(!Cookies.get('_fbp')) {
4031                    Cookies.set('_fbp',genereateFbp(),  { expires: expires,path: '/',domain: domain });
4032                }
4033
4034                if(getUrlParameter('fbclid')) {
4035                    Cookies.set('_fbc',genereateFbc(),  { expires: expires,path: '/',domain: domain });
4036                }
4037                var ids = options.facebook.pixelIds.filter(function (pixelId) {
4038                    return !Utils.hideMatchingPixel(pixelId, 'facebook');
4039                });
4040                // initialize default pixel
4041                ids.forEach(function (pixelId) {
4042                    Facebook.maybeInitPixel(pixelId);
4043                });
4044                initialized = true;
4045
4046                Utils.fireStaticEvents('facebook');
4047
4048            },
4049            advancedMatching: function () {
4050                if(options.facebook.advancedMatchingEnabled) {
4051                    let advancedMatchingForm = Utils.getAdvancedFormData();
4052                    let advancedMatching = {};
4053                    if(Object.keys(options.facebook.advancedMatching).length > 0) {
4054                        advancedMatching = options.facebook.advancedMatching;
4055                    }
4056
4057                    if(!advancedMatching.hasOwnProperty("em")
4058                        && advancedMatchingForm.hasOwnProperty("email") && advancedMatchingForm["email"].length > 0) {
4059                        advancedMatching["em"] = advancedMatchingForm["email"];
4060                    }
4061                    if(!advancedMatching.hasOwnProperty("ph")
4062                        && advancedMatchingForm.hasOwnProperty("phone") && advancedMatchingForm["phone"].length > 0) {
4063                        advancedMatching["ph"] = advancedMatchingForm["phone"];
4064                    }
4065                    if(!advancedMatching.hasOwnProperty("fn")
4066                        && advancedMatchingForm.hasOwnProperty("first_name") && advancedMatchingForm["first_name"].length > 0) {
4067                        advancedMatching["fn"] = advancedMatchingForm["first_name"];
4068                    }
4069                    if(!advancedMatching.hasOwnProperty("ln")
4070                        && advancedMatchingForm.hasOwnProperty("last_name") && advancedMatchingForm["last_name"].length > 0) {
4071                        advancedMatching["ln"] = advancedMatchingForm["last_name"];
4072                    }
4073                    if(!advancedMatching.hasOwnProperty("external_id")){
4074                        if (Cookies.get('pbid')) {
4075                            advancedMatching["external_id"] = Cookies.get('pbid');
4076                        }
4077                    }
4078                    else if(advancedMatching.hasOwnProperty("external_id") && advancedMatching.external_id != Cookies.get('pbid'))
4079                    {
4080                        advancedMatching["external_id"] = Cookies.get('pbid') ? Cookies.get('pbid') : advancedMatching.external_id;
4081                    }
4082
4083                    if(Object.keys(advancedMatching).length > 0) {
4084                        return advancedMatching;
4085                    }
4086                }
4087                return false
4088            },
4089            maybeInitPixel: function(pixelId) {
4090
4091                if(configuredPixels.includes(pixelId)) return;
4092
4093                if (options.facebook.removeMetadata || Utils.hideMatchingPixel(pixelId, this.tag())) {
4094                    fbq('set', 'autoConfig', false, pixelId);
4095                }
4096                let advancedMatching = Facebook.advancedMatching();
4097
4098                if ( +options.facebook.meta_ldu === 1  ) {
4099                    fbq( 'dataProcessingOptions', [ 'LDU' ], 0, 0 );
4100                }
4101
4102                if (options.gdpr.consent_magic_integration_enabled && typeof CS_Data !== "undefined") {
4103                    if(!advancedMatching) {
4104                        fbq('init', pixelId);
4105                    } else {
4106                        var test_prefix = CS_Data.test_prefix;
4107                        var cs_advanced_matching = Cookies.get('cs_enabled_advanced_matching'+test_prefix);
4108                        if (jQuery('#cs_enabled_advanced_matching'+test_prefix).length > 0) {
4109                            if (cs_advanced_matching == 'yes') {
4110                                fbq('init', pixelId, advancedMatching);
4111                            } else {
4112                                fbq('init', pixelId);
4113                            }
4114                        } else {
4115                            fbq('init', pixelId, advancedMatching);
4116                        }
4117                    }
4118                } else {
4119                    if(!advancedMatching) {
4120                        fbq('init', pixelId);
4121                    }  else {
4122                        fbq('init', pixelId, advancedMatching);
4123                    }
4124                }
4125                configuredPixels.push(pixelId);
4126            },
4127
4128            fireEvent: function (name, data) {
4129
4130                if (!initialized || !this.isEnabled()) {
4131                    return false;
4132                }
4133
4134                data.delay = data.delay || 0;
4135                data.params = data.params || {};
4136
4137                if (data.delay === 0) {
4138
4139                    fireEvent(name, data);
4140
4141                } else {
4142
4143                    setTimeout(function (name, params) {
4144                        fireEvent(name, params);
4145                    }, data.delay * 1000, name, data);
4146
4147                }
4148
4149                return true;
4150
4151            },
4152
4153            onAdSenseEvent: function (event) {
4154                this.fireEvent(event.name, event);
4155            },
4156
4157            onClickEvent: function (event) {
4158                this.fireEvent(event.name, event);
4159            },
4160
4161            onWatchVideo: function (event) {
4162                this.fireEvent(event.name, event);
4163            },
4164
4165            onCommentEvent: function (event) {
4166                this.fireEvent(event.name, event);
4167            },
4168
4169            onFormEvent: function (event) {
4170                this.fireEvent(event.name, event);
4171            },
4172
4173            onDownloadEvent: function (event) {
4174                this.fireEvent(event.name, event);
4175
4176            },
4177
4178
4179            onWooAddToCartOnButtonEvent: function (product_id) {
4180
4181                window.pysWooProductData = window.pysWooProductData || [];
4182                if(!options.dynamicEvents.woo_add_to_cart_on_button_click.hasOwnProperty(this.tag()))
4183                    return;
4184
4185                if (window.pysWooProductData.hasOwnProperty(product_id)) {
4186                    if (window.pysWooProductData[product_id].hasOwnProperty('facebook')) {
4187
4188                        var event = Utils.clone(options.dynamicEvents.woo_add_to_cart_on_button_click[this.tag()])
4189
4190                        Utils.copyProperties(window.pysWooProductData[product_id]['facebook']['params'], event.params)
4191                        event.pixelIds = window.pysWooProductData[product_id]['facebook']['pixelIds'];
4192                        this.fireEvent(event.name, event);
4193                    }
4194                }
4195            },
4196
4197            onWooAddToCartOnSingleEvent: function (product_id, qty, product_type, is_external, $form) {
4198
4199                window.pysWooProductData = window.pysWooProductData || [];
4200                if(!options.dynamicEvents.woo_add_to_cart_on_button_click.hasOwnProperty(this.tag()))
4201                    return;
4202
4203                if (product_type === Utils.PRODUCT_VARIABLE && !options.facebook.wooVariableAsSimple) {
4204                    product_id = parseInt($form.find('input[name="variation_id"]').val());
4205                }
4206
4207                if (window.pysWooProductData.hasOwnProperty(product_id)) {
4208                    if (window.pysWooProductData[product_id].hasOwnProperty('facebook')) {
4209
4210                        var event = Utils.clone(options.dynamicEvents.woo_add_to_cart_on_button_click.facebook);
4211
4212
4213                        Utils.copyProperties(window.pysWooProductData[product_id]['facebook']['params'], event.params);
4214
4215                        var groupValue = 0;
4216                        if(product_type === Utils.PRODUCT_GROUPED ) {
4217                            $form.find(".woocommerce-grouped-product-list .qty").each(function(index){
4218                                var childId = $(this).attr('name').replaceAll("quantity[","").replaceAll("]","");
4219                                var quantity = parseInt($(this).val());
4220                                if(isNaN(quantity)) {
4221                                    quantity = 0;
4222                                }
4223                                var childItem = window.pysWooProductData[product_id]['facebook'].grouped[childId];
4224
4225                                if(quantity == 0) {
4226                                    event.params.content_ids.forEach(function(el,index,array) {
4227                                        if(el == childItem.content_id) {
4228                                            array.splice(index, 1);
4229                                        }
4230                                    });
4231                                }
4232
4233                                if(event.params.hasOwnProperty('contents')) {
4234                                    event.params.contents.forEac
4234h(function(el,index,array) {
4235                                        if(el.id == childItem.content_id) {
4236                                            if(quantity > 0){
4237                                                el.quantity = quantity;
4238                                            } else {
4239                                                array.splice(index, 1);
4240                                            }
4241                                        }
4242                                    });
4243                                }
4244
4245
4246                                groupValue += childItem.price * quantity;
4247                            });
4248                            if(groupValue == 0) return; // skip if no items selected
4249                        }
4250
4251
4252
4253                        // maybe customize value option
4254                        if (options.woo.addToCartOnButtonValueEnabled && options.woo.addToCartOnButtonValueOption !== 'global') {
4255
4256                            if(product_type === Utils.PRODUCT_GROUPED) {
4257                                event.params.value = groupValue;
4258                            } else if(product_type === Utils.PRODUCT_BUNDLE) {
4259                                var data = $(".bundle_form .bundle_data").data("bundle_form_data");
4260                                var items_sum = getBundlePriceOnSingleProduct(data);
4261                                event.params.value = (parseFloat(data.base_price) + items_sum )* qty;
4262                            } else {
4263                                event.params.value = event.params.value * qty;
4264                            }
4265                        }
4266
4267                        // only when non Facebook for WooCommerce logic used
4268                        if (event.params.hasOwnProperty('contents') && product_type !== Utils.PRODUCT_GROUPED) {
4269                            event.params.contents[0].quantity = qty;
4270
4271                        }
4272
4273                        var event_name = is_external ? options.woo.affiliateEventName : event.name;
4274
4275                        this.fireEvent(event_name, event);
4276
4277                    }
4278                }
4279
4280            },
4281
4282            onWooRemoveFromCartEvent: function (event) {
4283                this.fireEvent(event.name, event);
4284            },
4285
4286            onWooAffiliateEvent: function (product_id) {
4287                if(!options.dynamicEvents.woo_affiliate.hasOwnProperty(this.tag()))
4288                    return;
4289                var event = Utils.clone(options.dynamicEvents.woo_affiliate[this.tag()]);
4290
4291
4292                if (window.pysWooProductData.hasOwnProperty(product_id)) {
4293                    if (window.pysWooProductData[product_id].hasOwnProperty('facebook')) {
4294
4295                        Utils.copyProperties(window.pysWooProductData[product_id][this.tag()].params, event.params)
4296                        this.fireEvent(options.woo.affiliateEventName, event);
4297
4298                    }
4299                }
4300
4301            },
4302
4303            onWooPayPalEvent: function (event) {
4304                this.fireEvent(event.name, event);
4305            },
4306
4307            onEddAddToCartOnButtonEvent: function (download_id, price_index, qty) {
4308                if(!options.dynamicEvents.edd_add_to_cart_on_button_click.hasOwnProperty(this.tag()))
4309                    return;
4310                var event = Utils.clone(options.dynamicEvents.edd_add_to_cart_on_button_click[this.tag()]);
4311
4312                if (window.pysEddProductData.hasOwnProperty(download_id)) {
4313
4314                    var index;
4315
4316                    if (price_index) {
4317                        index = download_id + '_' + price_index;
4318                    } else {
4319                        index = download_id;
4320                    }
4321
4322                    if (window.pysEddProductData[download_id].hasOwnProperty(index)) {
4323                        if (window.pysEddProductData[download_id][index].hasOwnProperty('facebook')) {
4324
4325                            Utils.copyProperties(window.pysEddProductData[download_id][index]['facebook']["params"], event.params)
4326
4327                            // maybe customize value option
4328                            if (options.edd.addToCartOnButtonValueEnabled && options.edd.addToCartOnButtonValueOption !== 'global') {
4329                                event.params.value = event.params.value * qty;
4330                            }
4331
4332                            // update contents qty param
4333                            var contents = event.params.contents;
4334                            contents[0].quantity = qty;
4335                            event.params.contents = contents;
4336
4337                            this.fireEvent(event.name,event);
4338
4339                        }
4340                    }
4341
4342                }
4343
4344            },
4345
4346            onEddRemoveFromCartEvent: function (event) {
4347                this.fireEvent(event.name, event);
4348            },
4349            onPageScroll: function (event) {
4350                this.fireEvent(event.name, event);
4351            },
4352            onTime: function (event) {
4353                this.fireEvent(event.name, event);
4354            },
4355        };
4356
4357    }(options);
4358
4359    var Analytics = function (options) {
4360
4361        var initialized = false;
4362        var isAllowEnhancedConversions = false;
4363
4364        /**
4365         * Fires event
4366         *
4367         * @link: https://developers.google.com/analytics/devguides/collection/gtagjs/sending-data
4368         * @link: https://developers.google.com/analytics/devguides/collection/gtagjs/events
4369         * @link: https://developers.google.com/gtagjs/reference/event
4370         * @link: https://developers.google.com/gtagjs/reference/parameter
4371         *
4372         * @link: https://developers.google.com/analytics/devguides/collection/gtagjs/custom-dim
4372s-mets
4373         *
4374         * @param name
4375         * @param data
4376         */
4377        function fireEvent(name, event) {
4378            if(typeof window.pys_event_data_filter === "function" && window.pys_disable_event_filter(name,'ga')) {
4379                return;
4380            }
4381
4382            var eventParams = event.params;
4383            var valuesArray = Object.values(event.trackingIds);
4384            var ids = valuesArray.filter(function (pixelId) {
4385                return loadTags.some(loadTag => pixelId.startsWith(loadTag)) && !Utils.hideMatchingPixel(pixelId, 'ga') && !Utils.hideMatchingPixel(pixelId, 'google_ads');
4386            })
4387
4388            // Generate unique event_id for deduplication
4389            eventParams.event_id = Utils.generateUniqueId(event);
4390            event.eventID = Utils.generateUniqueId(event);
4391
4392            Utils.copyProperties(Utils.getRequestParams(), eventParams);
4393
4394            var copyParams = Utils.copyProperties(eventParams, {}); // copy params because mapParamsTov4 can modify 
4394it
4395            var params = mapParamsTov4(ids,name,copyParams)
4396
4397            var _fireEvent = function (tracking_ids,name,params) {
4398
4399                params['send_to'] = tracking_ids;
4400
4401                if (options.debug) {
4402                    console.log('[Google Analytics #' + tracking_ids + '] ' + name, params);
4403                }
4404
4405                // Send via gtag
4406                gtag('event', name, params);
4407
4408                var customEvent = new CustomEvent('gtag_event_sent', {
4409                    detail: {
4410                        eventName: name,
4411                        params: params,
4412                        pixel_ids: tracking_ids
4413                    }
4414                });
4415                window.dispatchEvent(customEvent);
4416            };
4417
4418
4419            delete params.analytics_storage;
4420            delete params.ad_storage;
4421            delete params.ad_user_data;
4422            delete params.ad_personalization;
4423
4424            if(options.hasOwnProperty('google_ads')){
4425                var conversion_event_name = event.e_id;
4426                switch ( conversion_event_name ) {
4427                    case "woo_add_to_cart_on_cart_page":
4428                    case "woo_add_to_cart_on_checkout_page":
4429                    case "woo_add_to_cart_on_button_click":
4430                        conversion_event_name = 'woo_add_to_cart';
4431                        break;
4432                    case "edd_add_to_cart_on_cart_page":
4433                    case "edd_add_to_cart_on_checkout_page":
4434                    case "edd_add_to_cart_on_button_click":
4435                        conversion_event_name = 'edd_add_to_cart';
4436                        break;
4437                    case "automatic_event_adsense":
4438                    case "automatic_event_comment":
4439                    case "automatic_event_download":
4440                    case "automatic_event_email_link":
4441                    case "automatic_event_form":
4442                    case "automatic_event_internal_link":
4443                    case "automatic_event_outbound_link":
4444                    case "automatic_event_scroll":
4445                    case "automatic_event_tel_link":
4446                    case "automatic_event_time_on_page":
4447                    case "automatic_event_video":
4448                        conversion_event_name = 'automatic_event';
4449                        break;
4450                }
4451
4452                if ( conversion_event_name !== 'automatic_event' &&
4453                    typeof options.google_ads[conversion_event_name + '_conversion_track'] !== 'undefined' ) {
4454                    const conversionTrack = options.google_ads[ conversion_event_name + '_conversion_track' ];
4455
4456                    if ( conversionTrack === 'conversion' ) {
4457                        ids = ids.map(id => id.split('/')[0])
4458                    }
4459                }
4460            }
4461
4462
4463            _fireEvent(ids, name, params);
4464            if(event.hasOwnProperty('unify') && event.unify){
4465                isTrackEventForGA.push(name);
4466            }
4467        }
4468
4469        function normalizeEventName(eventName) {
4470
4471            var matches = {
4472                ViewContent: 'view_item',
4473                AddToCart: 'add_to_cart',
4474                AddToWishList: 'add_to_wishlist',
4475                InitiateCheckout: 'begin_checkout',
4476                Purchase: 'purchase',
4477                Lead: 'generate_lead',
4478                CompleteRegistration: 'sign_up',
4479                AddPaymentInfo: 'set_checkout_option'
4480            };
4481
4482            return matches.hasOwnProperty(eventName) ? matches[eventName] : eventName;
4483
4484        }
4485
4486        function mapParamsTov4(tag,name,param) {
4487            //GA4 automatically collects a number of parameters for all events
4488            var hasGA4Tag = false;
4489
4490            // end
4491            if (Array.isArray(tag)) {
4492                hasGA4Tag = tag.some(function (element) {
4493                    return isv4(element);
4494                });
4495            } else if(isv4(tag)) {
4496                // tag является строкой и соответствует GA4
4497                hasGA4Tag = true;
4498            }
4499            if(hasGA4Tag) {
4500                delete param.event_category;
4501                delete param.event_label;
4502                delete param.ecomm_prodid;
4503                delete param.ecomm_pagetype;
4504                delete param.ecomm_totalvalue;
4505                if(name === 'search') {
4506                    param['search'] = param.search_term;
4507                    delete param.search_term;
4508                    delete param.dynx_itemid;
4509                    delete param.dynx_pagetype;
4510                    delete param.dynx_totalvalue;
4511                }
4512            }
4513            return param;
4514        }
4515
4516        function isv4(tag) {
4517            return tag.indexOf('G') === 0;
4518        }
4519
4520        /**
4521         * Public API
4522         */
4523        return {
4524            tag: function() {
4525                return "ga";
4526            },
4527            isEnabled: function () {
4528                return options.hasOwnProperty('ga');
4529            },
4530            getHidePixel: function(){
4531                if(this.isEnabled() && options.ga.hasOwnProperty('hide_pixels'))
4532                {
4533                    return options.ga.hide_pixels;
4534                }
4535                return [];
4536            },
4537            disable: function () {
4538                initialized = false;
4539            },
4540            updateEnhancedConversionData : function () {
4541                if (!initialized || !this.isEnabled()) {
4542                    return;
4543                }
4544                if(options.hasOwnProperty("tracking_analytics") && options.tracking_analytics.hasOwnProperty("userDataEnable") && options.tracking_analytics.userDataEnable) {
4545                    var advanced = Utils.getAdvancedMergeFormData();
4546                    if (Object.keys(advanced).length > 0) {
4547                        gtag('set', 'user_data', advanced);
4548                    }
4549                }
4550            },
4551            loadPixel: function () {
4552                if (initialized || !this.isEnabled() || !Utils.consentGiven('analytics')) {
4553                    return;
4554                }
4555
4556
4557                for (var i = 0; i < options.ga.trackingIds.length; i++) {
4558                    var trackingId = options.ga.trackingIds[i];
4559                    if (!Utils.hideMatchingPixel(trackingId, 'ga')) {
4560                        Utils.loadGoogleTag(trackingId);
4561                        break;
4562                    }
4563                }
4564
4565
4566                if(options.hasOwnProperty("tracking_analytics") && options.tracking_analytics.hasOwnProperty("userDataEnable") && options.tracking_analytics.userDataEnable){
4567                    var advanced = Utils.getAdvancedMergeFormData();
4568                    if(Object.keys(advanced).length > 0){
4569                        gtag('set', 'user_data', advanced);
4570                    }
4571                }
4572
4573                var config = {};
4574
4575                if(options.user_id && options.user_id != 0) {
4576                    config.user_id = options.user_id;
4577                }
4578                config.url_passthrough = options.ga.url_passthrough;
4579                // Cross-Domain tracking
4580                if (options.ga.crossDomainEnabled) {
4581                    config.linker = {
4582                        accept_incoming: options.ga.crossDomainAcceptIncoming,
4583                        domains: options.ga.crossDomainDomains
4584                    };
4585                }
4586
4587                var ids = options.ga.trackingIds.filter(function (pixelId) {
4588                    return !Utils.hideMatchingPixel(pixelId, 'ga');
4589                });
4590                loadTags.push(...ids);
4591                ids.forEach(function (trackingId,index) {
4592
4593                    var obj = options.ga.isDebugEnabled;
4594                    var searchValue = "index_"+index;
4595                    var config_for_tag = Object.assign({}, config);
4596                    config_for_tag.debug_mode = false;
4597                    config_for_tag.send_page_view = !options.ga.custom_page_view_event;
4598                    for (var key in obj) {
4599                        if (obj[key] === searchValue) {
4600                            config_for_tag.debug_mode = true;
4601                            break;
4602                        }
4603                    }
4604                    if(!config_for_tag.debug_mode)
4605                    {
4606                        delete config_for_tag.debug_mode;
4607                    }
4608
4609                    if(isv4(trackingId)) {
4610                        if(options.ga.disableAdvertisingPersonalization) {
4611                            config_for_tag.allow_ad_personalization_signals = false
4612                        }
4613                    }
4614                    if(options.ga.hasOwnProperty('additionalConfig')){
4615                        if(options.ga.additionalConfig.hasOwnProperty(trackingId) && options.ga.additionalConfig[trackingId]){
4616                            config_for_tag.first_party_collection = options.ga.additionalConfig[trackingId].first_party_collection;
4617                        }
4618
4619                    }
4620                    if(options.ga.hasOwnProperty('serverContainerUrls')){
4621                        if(options.ga.serverContainerUrls.hasOwnProperty(trackingId) && options.ga.serverContainerUrls[trackingId].enable_server_container != false){
4622                            if(options.ga.serverContainerUrls[trackingId].server_container_url != ''){
4623                                config_for_tag.server_container_url = options.ga.serverContainerUrls[trackingId].server_container_url;
4624                            }
4625                            if(options.ga.serverContainerUrls[trackingId].transport_url != ''){
4626                                config_for_tag.transport_url = options.ga.serverContainerUrls[trackingId].transport_url;
4627                            }
4628                        }
4629                    }
4630                    if (options.gdpr.cookiebot_integration_enabled && typeof Cookiebot !== 'undefined') {
4631                        var cookiebot_consent_category = options.gdpr['cookiebot_analytics_consent_category'];
4632                        if (options.gdpr['analytics_prior_consent_enabled']) {
4633                            if (Cookiebot.consented === true && Cookiebot.consent[cookiebot_consent_category]) {
4634                                gtag('config', trackingId, config_for_tag);
4635                            }
4636                        } else {
4637                            if (Cookiebot.consent[cookiebot_consent_category]) {
4638                                gtag('config', trackingId, config_for_tag);
4639                            }
4640                        }
4641                    }
4642                    else
4643                    {
4644                        gtag('config', trackingId, config_for_tag);
4645                    }
4646                });
4647                if(!isAdsLoad && GAds.isEnabled() && options.google_ads.conversion_ids.length > 0 && Utils.consentGiven('google_ads')) {
4648                    for (var i = 0; i < options.google_ads.conversion_ids.length; i++) {
4649                        var trackingId = options.google_ads.conversion_ids[i];
4650                        if (!Utils.hideMatchingPixel(trackingId, 'google_ads')) {
4651                            Utils.loadGoogleTag(trackingId);
4652                            break;
4653                        }
4654                    }
4655                    var ids = options.google_ads.conversion_ids.filter(function (pixelId) {
4656                        return !Utils.hideMatchingPixel(pixelId, 'google_ads');
4657                    });
4658                    loadTags.push(...ids);
4659                    // configure conversion ids
4660                    ids.forEach(function (conversion_id,index) {
4661
4662                        gtag('config', conversion_id);
4663
4664                        if(options.google_ads.enhanced_conversion.includes("index_"+index)) {
4665                            isAllowEnhancedConversions = true
4666                            gtag('config', conversion_id,{ 'allow_enhanced_conversions':true });
4667                        }
4668
4669                    });
4670                    isAdsLoad = true;
4671                }
4672
4673                initialized = true;
4674
4675                Utils.fireStaticEvents('ga');
4676                $( document).trigger( "analytics_initialized")
4677            },
4678
4679            fireEvent: function (name, data) {
4680
4681                if (!initialized || !this.isEnabled()) {
4682                    return false;
4683                }
4684
4685                data.delay = data.delay || 0;
4686                data.params = data.params || {};
4687
4688                if (data.delay === 0) {
4689
4690                    fireEvent(name, data);
4691
4692                } else {
4693
4694                    setTimeout(function (name, params) {
4695                        fireEvent(name, params);
4696                    }, data.delay * 1000, name, data);
4697
4698                }
4699
4700                return true;
4701
4702            },
4703
4704            onAdSenseEvent: function (event) {
4705                this.fireEvent(event.name, event);
4706            },
4707
4708            onClickEvent: function (event) {
4709                this.fireEvent(event.name, event);
4710            },
4711
4712            onWatchVideo: function (event) {
4713                if(!event.hasOwnProperty("youtube_disabled")
4714                    || !event.youtube_disabled
4715                    || event.params.video_type !== "youtube") {
4716                    this.fireEvent(event.name, event);
4717                }
4718            },
4719
4720            onCommentEvent: function (event) {
4721
4722                this.fireEvent(event.name, event);
4723
4724            },
4725
4726            onFormEvent: function (event) {
4727
4728                this.fireEvent(event.name, event);
4729
4730            },
4731
4732            onDownloadEvent: function (event) {
4733
4734                this.fireEvent(event.name, event);
4735
4736            },
4737
4738            onWooAddToCartOnButtonEvent: function (product_id, prod_info = null) {
4739                if(!options.dynamicEvents.woo_add_to_cart_on_button_click.hasOwnProperty(this.tag()))
4740                    return;
4741
4742                if (window.pysWooProductData.hasOwnProperty(product_id)) {
4743                    if (window.pysWooProductData[product_id].hasOwnProperty('ga')) {
4744                        var event = Utils.clone(options.dynamicEvents.woo_add_to_cart_on_button_click[this.tag()]);
4745                        Utils.copyProperties(window.pysWooProductData[product_id]['ga'].params, event.params)
4746                        event.trackingIds = window.pysWooProductData[product_id]['ga']['trackingIds'];
4747                        if(prod_info)
4748                        {
4749                            if(prod_info['pys_list_name_productlist_id'])
4750                            {
4751                                event.params.items[0]['item_list_id'] = prod_info['pys_list_name_productlist_id']
4752                            }
4753                            if(prod_info['pys_list_name_productlist_name'])
4754                            {
4755                                event.params.items[0]['item_list_name'] =prod_info['pys_list_name_productlist_name']
4756                            }
4757                        }
4758                        this.fireEvent(event.name, event);
4759                    }
4760                }
4761
4762            },
4763
4764            onWooAddToCartOnSingleEvent: function (product_id, qty, product_type, is_external, $form, prod_info) {
4765
4766                window.pysWooProductData = window.pysWooProductData || [];
4767
4768                if(!options.dynamicEvents.woo_add_to_cart_on_button_click.hasOwnProperty(this.tag()))
4769                    return;
4770                var event = Utils.clone(options.dynamicEvents.woo_add_to_cart_on_button_click[this.tag()]);
4771
4772                if (product_type === Utils.PRODUCT_VARIABLE && !options.ga.wooVariableAsSimple) {
4773                    product_id = parseInt($form.find('input[name="variation_id"]').val());
4774                }
4775
4776                if (window.pysWooProductData.hasOwnProperty(product_id)) {
4777                    if (window.pysWooProductData[product_id].hasOwnProperty('ga')) {
4778
4779                        Utils.copyProperties(window.pysWooProductData[product_id]['ga'].params, event.params);
4780
4781
4782                        if(product_type === Utils.PRODUCT_GROUPED ) {
4783                            var groupValue = 0;
4784                            $form.find(".woocommerce-grouped-product-list .qty").each(function(index){
4785                                var childId = $(this).attr('name').replaceAll("quantity[","").replaceAll("]","");
4786                                var quantity = parseInt($(this).val());
4787                                if(isNaN(quantity)) {
4788                                    quantity = 0;
4789                                }
4790                                var childItem = window.pysWooProductData[product_id]['ga'].grouped[childId];
4791                                event.params.items.forEach(function(el,index,array) {
4792                                    if(el.id == childItem.content_id) {
4793                                        if(quantity > 0){
4794                                            el.quantity = quantity;
4795                                            el.price = childItem.price;
4796                                        } else {
4797                                            array.splice(index, 1);
4798                                        }
4799                                    }
4800                                });
4801                                groupValue += childItem.price * quantity;
4802                            });
4803
4804                            if(options.woo.addToCartOnButtonValueEnabled &&
4805                                options.woo.addToCartOnButtonValueOption !== 'global' &&
4806                                event.params.hasOwnProperty('value')) {
4807                                event.params.value = groupValue;
4808                            }
4809
4810                            if(groupValue == 0) return; // skip if no items selected
4811                        } else {
4812                            // update items qty param
4813                            event.params.items[0].quantity = qty;
4814                        }
4815
4816                        // maybe customize value option
4817                        if (options.woo.addToCartOnButtonValueEnabled &&
4818                            options.woo.addToCartOnButtonValueOption !== 'global' &&
4819                            product_type !== Utils.PRODUCT_GROUPED)
4820                        {
4821                            if(event.params.hasOwnProperty('value')) {
4822                                event.params.value = event.params.items[0].price * qty;
4823                            }
4824                        }
4825
4826                        if(prod_info)
4827                        {
4828                            if(prod_info['pys_list_name_productlist_id'])
4829                            {
4830                                event.params.items[0]['item_list_id'] = prod_info['pys_list_name_productlist_id']
4831                            }
4832                            if(prod_info['pys_list_name_productlist_name'])
4833                            {
4834                                event.params.items[0]['item_list_name'] =prod_info['pys_list_name_productlist_name']
4835                            }
4836                        }
4837
4838                        var eventName = is_external ? options.woo.affiliateEventName : event.name;
4839                        eventName = normalizeEventName(eventName);
4840
4841                        this.fireEvent(eventName, event);
4842
4843                    }
4844                }
4845
4846            },
4847
4848            onWooCheckoutProgressStep: function (event) {
4849                this.fireEvent(event.name, event);
4850            },
4851
4852            onWooSelectContent: function (event) {
4853                const select_prod_list = {};
4854
4855                if (event.params.items[0].item_list_name !== undefined) {
4856                    select_prod_list.list_name = event.params.items[0].item_list_name;
4857                }
4858
4859                if (event.params.items[0].item_list_id !== undefined) {
4860                    select_prod_list.list_id = event.params.items[0].item_list_id;
4861                }
4862                const url = new URL(window.location.href);
4863                select_prod_list.url = url.origin + url.pathname;
4864                Cookies.set('select_prod_list', JSON.stringify(select_prod_list), { expires: 1,path: '/' });
4865                this.fireEvent(event.name, event);
4866            },
4867
4868            onWooRemoveFromCartEvent: function (event) {
4869                this.fireEvent(event.name, event);
4870            },
4871
4872            onWooAffiliateEvent: function (product_id) {
4873                if(!options.dynamicEvents.woo_affiliate.hasOwnProperty(this.tag()))
4874                    return;
4875                var event = options.dynamicEvents.woo_affiliate[this.tag()];
4876
4877                if (window.pysWooProductData.hasOwnProperty(product_id)) {
4878                    if (window.pysWooProductData[product_id].hasOwnProperty('ga')) {
4879
4880                        event = Utils.clone(event );
4881                        Utils.copyProperties(window.pysWooProductData[product_id][this.tag()], event.params)
4882                        this.fireEvent(normalizeEventName(options.woo.affiliateEventName), event);
4883
4884                    }
4885                }
4886
4887            },
4888
4889            onWooPayPalEvent: function (event) {
4890                this.fireEvent(event.name, event);
4891            },
4892
4893            onEddAddToCartOnButtonEvent: function (download_id, price_index, qty) {
4894                if(!options.dynamicEvents.edd_add_to_cart_on_button_click.hasOwnProperty(this.tag()))
4895                    return;
4896                var event = Utils.clone(options.dynamicEvents.edd_add_to_cart_on_button_click[this.tag()]);
4897
4898
4899                if (window.pysEddProductData.hasOwnProperty(download_id)) {
4900
4901                    var index;
4902
4903                    if (price_index) {
4904                        index = download_id + '_' + price_index;
4905                    } else {
4906                        index = download_id;
4907                    }
4908
4909                    if (window.pysEddProductData[download_id].hasOwnProperty(index)) {
4910                        if (window.pysEddProductData[download_id][index].hasOwnProperty('ga')) {
4911
4912                            Utils.copyProperties(window.pysEddProductData[download_id][index]['ga'].params, event.params);
4913
4914                            // update items qty param
4915                            event.params.items[0].quantity = qty;
4916
4917                            this.fireEvent(event.name,event);
4918
4919                        }
4920                    }
4921
4922                }
4923
4924            },
4925
4926            onEddRemoveFromCartEvent: function (event) {
4927                this.fireEvent(event.name, event);
4928            },
4929
4930            onPageScroll: function (event) {
4931                if (initialized && this.isEnabled()) {
4932                    this.fireEvent(event.name, event);
4933                }
4934            },
4935            onTime: function (event) {
4936                if (initialized && this.isEnabled()) {
4937                    this.fireEvent(event.name, event);
4938                }
4939            },
4940        };
4941
4942    }(options);
4943
4944    var GAds = function (options) {
4945
4946        var initialized = false;
4947        var isAllowEnhancedConversions = false
4948        /**
4949         * Fires event
4950         *
4951         * @link: https://developers.google.com/analytics/devguides/collection/gtagjs/sending-data
4952         * @link: https://developers.google.com/analytics/devguides/collection/gtagjs/events
4953         * @link: https://developers.google.com/gtagjs/reference/event
4954         * @link: https://developers.google.com/gtagjs/reference/parameter
4955         */
4956        function fireEvent(name, data) {
4957            if(typeof window.pys_event_data_filter === "function" && window.pys_disable_event_filter(event_name,'google_ads')) {
4958                return;
4959            }
4960            var _params = Utils.copyProperties(data.params,{});
4961
4962            _params.event_id = Utils.generateUniqueId(data);
4963
4964            var ids = data.ids.filter(function (pixelId) {
4965                return !Utils.hideMatchingPixel(pixelId, 'google_ads');
4966            });
4967
4968            var conversionIds = data.hasOwnProperty('conversion_ids') ? data.conversion_ids.filter(function (conversion_id) {
4969                return !Utils.hideMatchingPixel(conversion_id, 'google_ads');
4970            }) : [];
4971            var conversion_labels = data.hasOwnProperty('conversion_labels') ? data.conversion_labels.filter(function (conversion_label) {
4972                conversion_id = conversion_label.split('/')[0];
4973                return !Utils.hideMatchingPixel(conversion_id, 'google_ads');
4974            }) : [];
4975
4976            Utils.copyProperties(Utils.getRequestParams(), _params);
4977            var _fireEvent = function (conversion_id,event_name) {
4978
4979                params = Utils.copyProperties(_params, { send_to: conversion_id });
4980
4981                if("conversion" === event_name) {
4982                    delete params.items;
4983                    delete params.ecomm_pagetype;
4984                    delete params.ecomm_prodid;
4985                    delete params.ecomm_totalvalue;
4986                }
4987
4988                if (options.debug) {
4989                    console.log('[Google Ads #' + conversion_id + '] ' + event_name, params);
4990                }
4991                gtag('event', event_name, params);
4992                var customEvent = new CustomEvent('gtag_event_sent', {
4993                    detail: {
4994                        eventName: event_name,
4995                        params: params,
4996                        pixel_ids: conversion_id
4997                    }
4998                });
4999                window.dispatchEvent(customEvent);
5000
5001            };
5002
5003
5004            if ( conversion_labels.length > 0 ) {
5005                ids = conversion_labels;
5006                if ( !isTrackEventForGA.includes( name ) ) {
5007                    _fireEvent( ids, name );
5008                }
5009            } else {
5010                var conversion_event_name = data.e_id;
5011                switch ( conversion_event_name ) {
5012                    case "woo_add_to_cart_on_cart_page":
5013                    case "woo_add_to_cart_on_checkout_page":
5014                    case "woo_add_to_cart_on_button_click":
5015                        conversion_event_name = 'woo_add_to_cart';
5016                        break;
5017                    case "edd_add_to_cart_on_cart_page":
5018                    case "edd_add_to_cart_on_checkout_page":
5019                    case "edd_add_to_cart_on_button_click":
5020                        conversion_event_name = 'edd_add_to_cart';
5021                        break;
5022                    case "automatic_event_adsense":
5023                    case "automatic_event_comment":
5024                    case "automatic_event_download":
5025                    case "automatic_event_email_link":
5026                    case "automatic_event_form":
5027                    case "automatic_event_internal_link":
5028                    case "automatic_event_outbound_link":
5029                    case "automatic_event_scroll":
5030                    case "automatic_event_tel_link":
5031                    case "automatic_event_time_on_page":
5032                    case "automatic_event_video":
5033                        conversion_event_name = 'automatic_event';
5034                        break;
5035                }
5036
5037                if ( ids.length ) {
5038                    if ( conversion_event_name !== 'automatic_event' && options.hasOwnProperty('google_ads') && options.google_ads[ conversion_event_name + '_conversion_track' ] ) {
5039                        const conversionTrack = options.google_ads[ conversion_event_name + '_conversion_track' ];
5040
5041                        if ( conversionTrack === 'conversion' ) {
5042                            _fireEvent( ids, "conversion" );
5043                            ids = conversionIds;
5044                        }
5045                    }
5046                } else {
5047                    ids = conversionIds;
5048                }
5049
5050                if ( !isTrackEventForGA.includes( name ) ) {
5051                    _fireEvent( ids, name );
5052                }
5053            }
5054        }
5055
5056        function normalizeEventName(eventName) {
5057
5058            var matches = {
5059                ViewContent: 'view_item',
5060                AddToCart: 'add_to_cart',
5061                AddToWishList: 'add_to_wishlist',
5062                InitiateCheckout: 'begin_checkout',
5063                Purchase: 'purchase',
5064                Lead: 'generate_lead',
5065                CompleteRegistration: 'sign_up',
5066                AddPaymentInfo: 'set_checkout_option'
5067            };
5068
5069            return matches.hasOwnProperty(eventName) ? matches[eventName] : eventName;
5070
5071        }
5072
5073        /**
5074         * Public API
5075         */
5076        return {
5077            tag: function() {
5078                return "google_ads";
5079            },
5080            isEnabled: function () {
5081                return options.hasOwnProperty('google_ads');
5082            },
5083            getHidePixel: function(){
5084                if(this.isEnabled() && options.google_ads.hasOwnProperty('hide_pixels'))
5085                {
5086                    return options.google_ads.hide_pixels;
5087                }
5088                return [];
5089            },
5090            disable: function () {
5091                initialized = false;
5092            },
5093
5094            updateEnhancedConversionData : function () {
5095
5096                if(options.hasOwnProperty("tracking_analytics") && options.tracking_analytics.hasOwnProperty("userDataEnable") && options.tracking_analytics.userDataEnable){
5097                    var advanced = Utils.getAdvancedMergeFormData()
5098                    gtag('set', 'user_data', advanced);
5099                }
5100            },
5101
5102            loadPixel: function () {
5103
5104                if (initialized || !this.isEnabled() || !Utils.consentGiven('google_ads')) {
5105                    return;
5106                }
5107                var ids = options.google_ads.conversion_ids.filter(function (pixelId) {
5108                    return !Utils.hideMatchingPixel(pixelId, 'google_ads');
5109                });
5110                loadTags.push(...ids);
5111                if(!isAdsLoad && options.google_ads.conversion_ids.length > 0){
5112                    for (var i = 0; i < options.google_ads.conversion_ids.length; i++) {
5113                        var trackingId = options.google_ads.conversion_ids[i];
5114                        if (!Utils.hideMatchingPixel(trackingId, 'google_ads')) {
5115                            Utils.loadGoogleTag(trackingId);
5116                            break;
5117                        }
5118                    }
5119
5120                    // configure conversion ids
5121                    ids.forEach(function (conversion_id,index) {
5122
5123                        let config = {};
5124
5125                        if(options.google_ads.enhanced_conversion.includes("index_"+index)) {
5126                            isAllowEnhancedConversions = true;
5127                            config.allow_enhanced_conversions = true
5128                        }
5129
5130                        // Cross-Domain tracking
5131                        if (options.google_ads.crossDomainEnabled) {
5132                            config.linker = {
5133                                accept_incoming: options.google_ads.crossDomainAcceptIncoming,
5134                                domains: options.google_ads.crossDomainDomains
5135                            };
5136                        }
5137
5138                        gtag('config', conversion_id, config );
5139
5140                        if(options.hasOwnProperty("tracking_analytics") && options.tracking_analytics.hasOwnProperty("userDataEnable") && options.tracking_analytics.userDataEnableuserDataEnable){
5141                            var advanced = Utils.getAdvancedMergeFormData()
5142                            gtag('set', 'user_data', advanced);
5143                        }
5144
5145                    });
5146                    isAdsLoad = true;
5147                }
5148
5149                initialized = true;
5150
5151                Utils.fireStaticEvents('google_ads');
5152
5153            },
5154
5155            fireEvent: function (name, data) {
5156
5157                if (!initialized || !this.isEnabled()) {
5158                    return false;
5159                }
5160
5161                data.delay = data.delay || 0;
5162                data.params = data.params || {};
5163                data.ids = data.ids || [];
5164                data.conversion_labels = data.conversion_labels || [];
5165
5166                if (data.delay === 0) {
5167                    fireEvent(name, data);
5168                } else {
5169                    setTimeout(function (name, data) {
5170                        fireEvent(name, data);
5171                    }, data.delay * 1000, name, data);
5172                }
5173
5174                return true;
5175
5176            },
5177
5178            onAdSenseEvent: function (event) {
5179                this.fireEvent(event.name, event);
5180            },
5181
5182            onClickEvent: function (action, params) {
5183                //disabled
5184            },
5185
5186            onWatchVideo: function (event) {
5187                this.fireEvent(event.name, event);
5188            },
5189
5190            onCommentEvent: function (event) {
5191                this.fireEvent(event.name, event);
5192            },
5193
5194            onFormEvent: function (event) {
5195                this.fireEvent(event.name, event);
5196            },
5197
5198            onDownloadEvent: function (event) {
5199                this.fireEvent(event.name, event);
5200            },
5201
5202
5203
5204
5205            onWooAddToCartOnButtonEvent: function (product_id) {
5206
5207                if(!options.dynamicEvents.woo_add_to_cart_on_button_click.hasOwnProperty(this.tag()))
5208                    return;
5209
5210                if (window.pysWooProductData.hasOwnProperty(product_id)) {
5211                    if (window.pysWooProductData[product_id].hasOwnProperty('google_ads')) {
5212
5213                        var event = Utils.clone(options.dynamicEvents.woo_add_to_cart_on_button_click[this.tag()])
5214                        Utils.copyProperties(window.pysWooProductData[product_id]['google_ads']['params'].params, event.params)
5215                        event["ids"] = window.pysWooProductData[product_id]['google_ads']['ids']
5216                        event["conversion_labels"] = window.pysWooProductData[product_id]['google_ads']['conversion_labels']
5217                        this.fireEvent(event.name, event);
5218                    }
5219                }
5220
5221            },
5222
5223            onWooAddToCartOnSingleEvent: function (product_id, qty, product_type, is_external, $form) {
5224
5225                window.pysWooProductData = window.pysWooProductData || [];
5226                if(!options.dynamicEvents.woo_add_to_cart_on_button_click.hasOwnProperty(this.tag()))
5227                    return;
5228                var event = Utils.clone(options.dynamicEvents.woo_add_to_cart_on_button_click[this.tag()]);
5229
5230                if (product_type === Utils.PRODUCT_VARIABLE && !options.google_ads.wooVariableAsSimple) {
5231                    product_id = parseInt($form.find('input[name="variation_id"]').val());
5232                }
5233
5234                if (window.pysWooProductData.hasOwnProperty(product_id)) {
5235                    if (window.pysWooProductData[product_id].hasOwnProperty('google_ads')) {
5236
5237                        Utils.copyProperties(window.pysWooProductData[product_id]['google_ads']["params"], event.params);
5238                        event["ids"] = window.pysWooProductData[product_id]['google_ads']['ids']
5239                        event["conversion_labels"] = window.pysWooProductData[product_id]['google_ads']['conversion_labels']
5240
5241                        var groupValue = 0;
5242                        if(product_type === Utils.PRODUCT_GROUPED ) {
5243                            $form.find(".woocommerce-grouped-product-list .qty").each(function(index){
5244                                var childId = $(this).attr('name').replaceAll("quantity[","").replaceAll("]","");
5245                                var quantity = parseInt($(this).val());
5246                                if(isNaN(quantity)) {
5247                                    quantity = 0;
5248                                }
5249
5250                                var childItem = window.pysWooProductData[product_id]['google_ads'].grouped[childId];
5251
5252                                if(options.woo.addToCartOnButtonValueEnabled &&
5253                                    options.woo.addToCartOnButtonValueOption !== 'global') {
5254
5255                                    event.params.items.forEach(function(el,index,array) {
5256                                        if(el.id == childItem.content_id) {
5257                                            if(quantity > 0){
5258                                                el.quantity = quantity;
5259                                                el.price = childItem.price;
5260                                            } else {
5261                                                array.splice(index, 1);
5262                                            }
5263                                        }
5264                                    });
5265                                }
5266                                groupValue += childItem.price * quantity;
5267                            });
5268                            if(groupValue == 0) return;
5269                            event.params.value = groupValue;
5270                        } else {
5271                            // update items qty param
5272                            event.params.items[0].quantity = qty;
5273                        }
5274
5275
5276
5277                        // maybe customize value option
5278                        if (options.woo.addToCartOnButtonValueEnabled &&
5279                            options.woo.addToCartOnButtonValueOption !== 'global' &&
5280                            product_type !== Utils.PRODUCT_GROUPED) {
5281                            event.params.value =  event.params.value * qty;
5282                        }
5283
5284
5285
5286                        var eventName = is_external ? options.woo.affiliateEventName : event.name;
5287                        eventName = normalizeEventName(eventName);
5288
5289                        this.fireEvent(eventName, event);
5290
5291                    }
5292                }
5293
5294            },
5295
5296            onWooRemoveFromCartEvent: function (event) {
5297                this.fireEvent(event.name, event);
5298            },
5299
5300            onWooAffiliateEvent: function (product_id) {
5301                if(!options.dynamicEvents.woo_affiliate.hasOwnProperty(this.tag()))
5302                    return;
5303                var event = options.dynamicEvents.woo_affiliate[this.tag()];
5304
5305                if (window.pysWooProductData.hasOwnProperty(product_id)) {
5306                    if (window.pysWooProductData[product_id].hasOwnProperty('google_ads')) {
5307
5308                        event = Utils.clone(event)
5309                        Utils.copyProperties(window.pysWooProductData[product_id][this.tag()], event.params)
5310                        this.fireEvent(normalizeEventName(options.woo.affiliateEventName), event);
5311
5312                    }
5313                }
5314
5315            },
5316
5317            onWooPayPalEvent: function (event) {
5318                this.fireEvent(event.name, event);
5319            },
5320
5321            onEddAddToCartOnButtonEvent: function (download_id, price_index, qty) {
5322                if(!options.dynamicEvents.edd_add_to_cart_on_button_click.hasOwnProperty(this.tag()))
5323                    return;
5324                var event = options.dynamicEvents.edd_add_to_cart_on_button_click[this.tag()];
5325
5326
5327                if (window.pysEddProductData.hasOwnProperty(download_id)) {
5328
5329                    var index;
5330
5331                    if (price_index) {
5332                        index = download_id + '_' + price_index;
5333                    } else {
5334                        index = download_id;
5335                    }
5336
5337                    if (window.pysEddProductData[download_id].hasOwnProperty(index)) {
5338                        if (window.pysEddProductData[download_id][index].hasOwnProperty('google_ads')) {
5339
5340                            event = Utils.clone(event)
5341                            Utils.copyProperties(window.pysEddProductData[download_id][index]['google_ads']['params'], event.params);
5342                            event.ids = window.pysEddProductData[download_id][index]['google_ads']['ids']
5343                            // update items qty param
5344                            //params.items[0].quantity = qty;
5345
5346                            this.fireEvent(event.name, event);
5347
5348                        }
5349                    }
5350
5351                }
5352
5353            },
5354
5355            onEddRemoveFromCartEvent: function (event) {
5356                this.fireEvent(event.name, event);
5357            },
5358            onPageScroll: function (event) {
5359                if (initialized && this.isEnabled()) {
5360                    this.fireEvent(event.name, event);
5361                }
5362            },
5363            onTime: function (event) {
5364                if (initialized && this.isEnabled()) {
5365                    this.fireEvent(event.name, event);
5366                }
5367            },
5368
5369        };
5370
5371    }(options);
5372
5373    var GTM = function (options) {
5374
5375        var initialized = false;
5376
5377        var datalayer_name = 'dataLayer';
5378        /*
5379         * @param name
5380         * @param data
5381         */
5382        function fireEvent(name, event) {
5383            if(typeof window.pys_event_data_filter === "function" && window.pys_disable_event_filter(name,'gtm')) {
5384                return;
5385            }
5386
5387
5388            var eventParams = event.params;
5389            var data = event.params;
5390            var valuesArray = Object.values(event.trackingIds);
5391            var ids = valuesArray.filter(function (pixelId) {
5392                return !Utils.hideMatchingPixel(pixelId, 'gtm');
5393            })
5394            Utils.copyProperties(Utils.getRequestParams(), eventParams);
5395            var _fireEvent = function (tracking_id,name,params, event=null) {
5396
5397                var eventData = {};
5398                var ContainerCodeHasTag = !options.gtm.gtm_just_data_layer && tracking_id.length > 0;
5399                if(ContainerCodeHasTag) {
5400                    params['send_to'] = tracking_id;
5401                }
5402                else if(!options.gtm.gtm_just_data_layer){
5403                    return
5404                }
5405
5406                if (params.hasOwnProperty('ecommerce')) {
5407                    eventData.ecommerce = params.ecommerce;
5408                    delete params.ecommerce;
5409                }
5410
5411                var automatedParams = { ...params };
5412                [params['manualName'], 'manualName', 'triggerType'].forEach(key => delete automatedParams[key]);
5413                if(event && (!event.hasOwnProperty('hasAutoParam') || (event.hasOwnProperty('hasAutoParam') && event.hasAutoParam))) {
5414                    eventData.automatedParameters = automatedParams;
5415                }
5416
5417// Move custom parameters to eventData
5418
5419                if (params.hasOwnProperty(params['manualName'])) {
5420                    eventData[params['manualName']] = params[params['manualName']];
5421                    delete params[params['manualName']];
5422                }
5423
5424                ['manualName','triggerType'].forEach(key => {
5425                    if (params.hasOwnProperty(key)) {
5426                        eventData[key] = params[key];
5427                        delete params[key];
5428                    }
5429                });
5430
5431                eventData.manualDataLayer = options.gtm.gtm_dataLayer_name ?? 'dataLayer';
5432
5433                eventData.event = name;
5434
5435                if (options.debug) {
5436                    if (ContainerCodeHasTag){
5437                        console.log('[Google GTM #' + tracking_id + '] ' + name, eventData);
5438                    }
5439                    else {
5440                        console.log('[Google GTM push to "'+datalayer_name+'"] ' + name, eventData);
5441                    }
5442                }
5443                window[datalayer_name].push(eventData);
5444
5445                var customEvent = new CustomEvent('gtm_event_sent', {
5446                    detail: {
5447                        eventName: name,
5448                        params: eventData,
5449                        pixel_ids: tracking_id
5450                    }
5451                });
5452                window.dispatchEvent(customEvent);
5453
5454            };
5455
5456            var copyParams = Utils.copyProperties(eventParams, {}); // copy params because mapParamsToGTM can modify it
5457
5458            var params = mapParamsToGTM(ids,name,copyParams)
5459
5460            params.event_id = Utils.generateUniqueId(event);
5461
5462            _fireEvent(ids, name, params, event);
5463        }
5464
5465        function normalizeEventName(eventName) {
5466
5467            var matches = {
5468                ViewContent: 'view_item',
5469                AddToCart: 'add_to_cart',
5470                AddToWishList: 'add_to_wishlist',
5471                InitiateCheckout: 'begin_checkout',
5472                Purchase: 'purchase',
5473                Lead: 'generate_lead',
5474                CompleteRegistration: 'sign_up',
5475                AddPaymentInfo: 'set_checkout_option'
5476            };
5477
5478            return matches.hasOwnProperty(eventName) ? matches[eventName] : eventName;
5479
5480        }
5481
5482        function mapParamsToGTM(tag,name,param) {
5483            var hasGTM = false;
5484
5485            // end
5486            if (Array.isArray(tag)) {
5487                hasGTM = tag.some(function (element) {
5488                    return isGTM(element);
5489                });
5490            } else if(isGTM(tag)) {
5491                hasGTM = true;
5492            }
5493            if(hasGTM) {
5494                delete param.event_category;
5495                delete param.event_label;
5496
5497                delete param.analytics_storage;
5498                delete param.ad_storage;
5499                delete param.ad_user_data;
5500                delete param.ad_personalization;
5501
5502                if(name === 'search') {
5503                    param['search'] = param.search_term;
5504                    delete param.search_term;
5505                    delete param.dynx_itemid;
5506                    delete param.dynx_pagetype;
5507                    delete param.dynx_totalvalue;
5508                }
5509            }
5510            return param;
5511        }
5512
5513        function isGTM(tag) {
5514            return tag.indexOf('GTM') === 0;
5515        }
5516        /**
5517         * Public API
5518         */
5519        return {
5520            tag: function() {
5521                return "gtm";
5522            },
5523            isEnabled: function () {
5524                return options.hasOwnProperty('gtm');
5525            },
5526            getHidePixel: function(){
5527                if(this.isEnabled() && options.gtm.hasOwnProperty('hide_pixels'))
5528                {
5529                    return options.gtm.hide_pixels;
5530                }
5531                return [];
5532            },
5533            disable: function () {
5534                initialized = false;
5535            },
5536            updateEnhancedConversionData : function () {
5537                if (!initialized || !this.isEnabled()) {
5538                    return;
5539                }
5540                if(options.hasOwnProperty("tracking_analytics") && options.tracking_analytics.hasOwnProperty("userDataEnable") && options.tracking_analytics.userDataEnable) {
5541                    var advanced = Utils.getAdvancedMergeFormData(true);
5542                    if (Object.keys(advanced).length > 0) {
5543                        window[datalayer_name].push({'user_data' : advanced});
5544                    }
5545                }
5546            },
5547            loadPixel: function () {
5548
5549                if (initialized || !this.isEnabled() || !Utils.consentGiven('analytics')) {
5550                    return;
5551                }
5552                datalayer_name = options.gtm.gtm_dataLayer_name ?? 'dataLayer';
5553
5554                for (var i = 0; i < options.gtm.trackingIds.length; i++) {
5555                    var trackingId = options.gtm.trackingIds[i];
5556                    if (!Utils.hideMatchingPixel(trackingId, 'gtm') && !options.gtm.gtm_just_data_layer) {
5557                        console.log('[PYS] Google Tag Manager container code loaded');
5558                        Utils.loadGTMScript(trackingId);
5559                        break;
5560                    }
5561                }
5562
5563                if(options.gtm.gtm_just_data_layer) {
5564                    console.warn && console.warn("[PYS] Google Tag Manager container code placement set to OFF !!!");
5565                    console.warn && console.warn("[PYS] Data layer codes are active but GTM container must be loaded using custom coding !!!");
5566                    if(options.gtm.trackingIds.length == 0){
5567                        Utils.loadGTMScript();
5568                    }
5569                }
5570
5571                if(options.hasOwnProperty("tracking_analytics") && options.tracking_analytics.hasOwnProperty("userDataEnable") && options.tracking_analytics.userDataEnable){
5572                    var advanced = Utils.getAdvancedMergeFormData(true);
5573                    if(Object.keys(advanced).length > 0){
5574                        window[datalayer_name].push({'user_data' : advanced});
5575                    }
5576                }
5577
5578
5579                var config = {};
5580
5581                if(options.user_id && options.user_id != 0) {
5582                    config.user_id = options.user_id;
5583                }
5584
5585                // Cross-Domain tracking
5586
5587                var ids = options.gtm.trackingIds.filter(function (pixelId) {
5588                    return !Utils.hideMatchingPixel(pixelId, 'gtm');
5589                });
5590
5591
5592                initialized = true;
5593
5594                Utils.fireStaticEvents('gtm');
5595            },
5596
5597            fireEvent: function (name, data) {
5598
5599                if (!initialized || !this.isEnabled()) {
5600                    return false;
5601                }
5602
5603                data.delay = data.delay || 0;
5604                data.params = data.params || {};
5605
5606                if (data.delay === 0) {
5607
5608                    fireEvent(name, data);
5609
5610                } else {
5611
5612                    setTimeout(function (name, params) {
5613                        fireEvent(name, params);
5614                    }, data.delay * 1000, name, data);
5615
5616                }
5617
5618                return true;
5619
5620            },
5621
5622            onAdSenseEvent: function (event) {
5623                this.fireEvent(event.name, event);
5624            },
5625
5626            onClickEvent: function (event) {
5627                this.fireEvent(event.name, event);
5628            },
5629
5630            onWatchVideo: function (event) {
5631                if(!event.hasOwnProperty("youtube_disabled")
5632                    || !event.youtube_disabled
5633                    || event.params.video_type !== "youtube") {
5634                    this.fireEvent(event.name, event);
5635                }
5636            },
5637
5638            onCommentEvent: function (event) {
5639
5640                this.fireEvent(event.name, event);
5641
5642            },
5643
5644            onFormEvent: function (event) {
5645
5646                this.fireEvent(event.name, event);
5647
5648            },
5649
5650            onDownloadEvent: function (event) {
5651
5652                this.fireEvent(event.name, event);
5653
5654            },
5655
5656            onWooAddToCartOnButtonEvent: function (product_id, prod_info = null) {
5657                if(!options.dynamicEvents.woo_add_to_cart_on_button_click.hasOwnProperty(this.tag()))
5658                    return;
5659                if (window.pysWooProductData.hasOwnProperty(product_id)) {
5660                    if (window.pysWooProductData[product_id].hasOwnProperty('gtm')) {
5661                        var event = Utils.clone(options.dynamicEvents.woo_add_to_cart_on_button_click[this.tag()]);
5662                        Utils.copyProperties(window.pysWooProductData[product_id]['gtm'].params, event.params)
5663                        event.trackingIds = window.pysWooProductData[product_id]['gtm']['trackingIds'];
5664
5665
5666                        if(prod_info)
5667                        {
5668                            item = event.params.hasOwnProperty('ecommerce') ? event.params.ecommerce.items[0] : event.params.items[0];
5669
5670                            if(prod_info['pys_list_name_productlist_id'])
5671                            {
5672                                item['item_list_id'] = prod_info['pys_list_name_productlist_id']
5673                            }
5674                            if(prod_info['pys_list_name_productlist_name'])
5675                            {
5676                                item['item_list_name'] =prod_info['pys_list_name_productlist_name']
5677                            }
5678                        }
5679                        this.fireEvent(event.name, event);
5680                    }
5681                }
5682
5683            },
5684
5685            onWooAddToCartOnSingleEvent: function (product_id, qty, product_type, is_external, $form, prod_info) {
5686                window.pysWooProductData = window.pysWooProductData || [];
5687
5688                if(!options.dynamicEvents.woo_add_to_cart_on_button_click.hasOwnProperty(this.tag()))
5689                    return;
5690                var event = Utils.clone(options.dynamicEvents.woo_add_to_cart_on_button_click[this.tag()]);
5691
5692                if (product_type === Utils.PRODUCT_VARIABLE && !options.gtm.wooVariableAsSimple) {
5693                    product_id = parseInt($form.find('input[name="variation_id"]').val());
5694                }
5695
5696                if (window.pysWooProductData.hasOwnProperty(product_id)) {
5697                    if (window.pysWooProductData[product_id].hasOwnProperty('gtm')) {
5698
5699                        Utils.copyProperties(window.pysWooProductData[product_id]['gtm'].params, event.params);
5700
5701                        params = event.params.hasOwnProperty('ecommerce') ? event.params.ecommerce : event.params;
5702
5703                        if(product_type === Utils.PRODUCT_GROUPED ) {
5704                            var groupValue = 0;
5705                            $form.find(".woocommerce-grouped-product-list .qty").each(function(index){
5706                                var childId = $(this).attr('name').replaceAll("quantity[","").replaceAll("]","");
5707                                var quantity = parseInt($(this).val());
5708                                if(isNaN(quantity)) {
5709                                    quantity = 0;
5710                                }
5711                                var childItem = window.pysWooProductData[product_id]['gtm'].grouped[childId];
5712
5713                                params.items.forEach(function(el,index,array) {
5714                                    if(el.id == childItem.content_id) {
5715                                        if(quantity > 0){
5716                                            el.quantity = quantity;
5717                                            el.price = childItem.price;
5718                                        } else {
5719                                            array.splice(index, 1);
5720                                        }
5721                                    }
5722                                });
5723                                groupValue += childItem.price * quantity;
5724                            });
5725
5726
5727
5728                            if(options.woo.addToCartOnButtonValueEnabled &&
5729                                options.woo.addToCartOnButtonValueOption !== 'global' &&
5730                                params.hasOwnProperty('value')) {
5731                                params.value = groupValue;
5732                            }
5733
5734                            if(groupValue == 0) return; // skip if no items selected
5735                        } else {
5736                            // update items qty param
5737                            params.items[0].quantity = qty;
5738                        }
5739
5740                        // maybe customize value option
5741                        if (options.woo.addToCartOnButtonValueEnabled &&
5742                            options.woo.addToCartOnButtonValueOption !== 'global' &&
5743                            product_type !== Utils.PRODUCT_GROUPED)
5744                        {
5745                            if(params.hasOwnProperty('value')) {
5746                                params.value = params.items[0].price * qty;
5747                            }
5748                        }
5749
5750                        if(prod_info)
5751                        {
5752                            if(prod_info['pys_list_name_productlist_id'])
5753                            {
5754                                params.items[0]['item_list_id'] = prod_info['pys_list_name_productlist_id']
5755                            }
5756                            if(prod_info['pys_list_name_productlist_name'])
5757                            {
5758                                params.items[0]['item_list_name'] =prod_info['pys_list_name_productlist_name']
5759                            }
5760                        }
5761
5762                        var eventName = is_external ? options.woo.affiliateEventName : event.name;
5763                        eventName = normalizeEventName(eventName);
5764
5765                        this.fireEvent(eventName, event);
5766
5767                    }
5768                }
5769
5770            },
5771
5772            onWooCheckoutProgressStep: function (event) {
5773                this.fireEvent(event.name, event);
5774            },
5775
5776            onWooSelectContent: function (event) {
5777                const select_prod_list = {};
5778
5779                if (event.params.items[0].item_list_name !== undefined) {
5780                    select_prod_list.list_name = event.params.items[0].item_list_name;
5781                }
5782
5783                if (event.params.items[0].item_list_id !== undefined) {
5784                    select_prod_list.list_id = event.params.items[0].item_list_id;
5785                }
5786                const url = new URL(window.location.href);
5787                select_prod_list.url = url.origin + url.pathname;
5788                Cookies.set('select_prod_list', JSON.stringify(select_prod_list), { expires: 1,path: '/' });
5789                this.fireEvent(event.name, event);
5790            },
5791
5792            onWooRemoveFromCartEvent: function (event) {
5793                this.fireEvent(event.name, event);
5794            },
5795
5796            onWooAffiliateEvent: function (product_id) {
5797                if(!options.dynamicEvents.woo_affiliate.hasOwnProperty(this.tag()))
5798                    return;
5799                var event = options.dynamicEvents.woo_affiliate[this.tag()];
5800
5801                if (window.pysWooProductData.hasOwnProperty(product_id)) {
5802                    if (window.pysWooProductData[product_id].hasOwnProperty('gtm')) {
5803
5804                        event = Utils.clone(event );
5805                        Utils.copyProperties(window.pysWooProductData[product_id][this.tag()], event.params)
5806                        this.fireEvent(normalizeEventName(options.woo.affiliateEventName), event);
5807
5808                    }
5809                }
5810
5811            },
5812
5813            onWooPayPalEvent: function (event) {
5814                this.fireEvent(event.name, event);
5815            },
5816
5817            onEddAddToCartOnButtonEvent: function (download_id, price_index, qty) {
5818                if(!options.dynamicEvents.edd_add_to_cart_on_button_click.hasOwnProperty(this.tag()))
5819                    return;
5820                var event = Utils.clone(options.dynamicEvents.edd_add_to_cart_on_button_click[this.tag()]);
5821
5822
5823                if (window.pysEddProductData.hasOwnProperty(download_id)) {
5824
5825                    var index;
5826
5827                    if (price_index) {
5828                        index = download_id + '_' + price_index;
5829                    } else {
5830                        index = download_id;
5831                    }
5832
5833                    if (window.pysEddProductData[download_id].hasOwnProperty(index)) {
5834                        if (window.pysEddProductData[download_id][index].hasOwnProperty('gtm')) {
5835
5836                            Utils.copyProperties(window.pysEddProductData[download_id][index]['gtm'].params, event.params);
5837                            item = event.params.hasOwnProperty('ecommerce') ? event.params.ecommerce.items[0] : event.params.items[0];
5838                            // update items qty param
5839                            item.quantity = qty;
5840
5841                            this.fireEvent(event.name,event);
5842
5843                        }
5844                    }
5845
5846                }
5847
5848            },
5849
5850            onEddRemoveFromCartEvent: function (event) {
5851                this.fireEvent(event.name, event);
5852            },
5853
5854            onPageScroll: function (event) {
5855                if (initialized && this.isEnabled()) {
5856                    this.fireEvent(event.name, event);
5857                }
5858            },
5859            onTime: function (event) {
5860                if (initialized && this.isEnabled()) {
5861                    this.fireEvent(event.name, event);
5862                }
5863            },
5864        };
5865
5866    }(options);
5867
5868    var getPixelBySlag = function getPixelBySlag(slug) {
5869        switch (slug) {
5870            case "facebook": return window.pys.Facebook;
5871            case "ga": return window.pys.Analytics;
5872            case "gtm": return window.pys.GTM;
5873            case "google_ads": return window.pys.GAds;
5874            case "bing": return window.pys.Bing;
5875            case "pinterest": return window.pys.Pinterest;
5876            case "tiktok": return window.pys.TikTok;
5877            case "reddit": return window.pys.Reddit;
5878        }
5879    }
5880
5881    window.pys = window.pys || {};
5882    window.pys.Facebook = Facebook;
5883    window.pys.Analytics = Analytics;
5884    window.pys.GAds = GAds;
5885    window.pys.GTM = GTM;
5886    window.pys.Utils = Utils;
5887    window.pys.TikTok = TikTok;
5888    window.pys.getPixelBySlag = getPixelBySlag;
5889    
5890    // Export getPixelBySlag globally for backward compatibility
5891    window.getPixelBySlag = getPixelBySlag;
5892
5893
5894
5895    $(document).ready(function () {
5896
5897        if(Cookies.get('form_track'))
5898        {
5899            Cookies.remove('form_track')
5900        }
5901
5902        if($("#pys_late_event").length > 0) {
5903            var dirAttr = $("#pys_late_event").attr("dir");
5904            if (dirAttr) {
5905                try {
5906                    var events = JSON.parse(dirAttr);
5907                } catch (e) {
5908                    console.warn("Invalid JSON in pys_late_event dir attribute:", e);
5909                }
5910            } else {
5911                console.warn("pys_late_event dir attribute is undefined or empty");
5912            }
5913            if (events) {
5914                for (var platform in events) {
5915                    if (events.hasOwnProperty(platform)) {
5916                        var platformEvents = events[platform];
5917                        platformEvents.forEach(function (event) {
5918                            var eventData = {};
5919                            eventData[event.e_id] = [event];
5920                            if (options.staticEvents.hasOwnProperty(platform)) {
5921                                Object.assign(options.staticEvents[platform], eventData);
5922                            } else {
5923                                options.staticEvents[platform] = eventData;
5924                            }
5925                        });
5926                    }
5927                }
5928            }
5929        }
5930
5931        var Pinterest = Utils.setupPinterestObject();
5932        var Bing = Utils.setupBingObject();
5933	    var Reddit = Utils.setupRedditObject();
5934        if(options.hasOwnProperty('cookie'))
5935        {
5936            if(options.cookie.externalID_disabled_by_api || options.cookie.disabled_all_cookie)
5937            {
5938                Cookies.remove('pbid')
5939            }
5940            if(options.cookie.disabled_advanced_form_data_cookie || options.cookie.disabled_all_cookie)
5941            {
5942                Cookies.remove('pys_advanced_form_data')
5943            }
5944
5945            if(options.cookie.disabled_landing_page_cookie || !options.enable_lading_page_param || options.cookie.disabled_all_cookie)
5946            {
5947                Cookies.remove('pys_landing_page', { path: '/',domain: domain })
5948                Cookies.remove('last_pys_landing_page', { path: '/',domain: domain })
5949            }
5950            if(options.cookie.disabled_trafficsource_cookie || options.cookie.disabled_all_cookie)
5951            {
5952                Cookies.remove('pysTrafficSource', { path: '/',domain: domain })
5953                Cookies.remove('last_pysTrafficSource', { path: '/',domain: domain })
5954            }
5955            if(options.cookie.disabled_first_visit_cookie || options.cookie.disabled_all_cookie)
5956            {
5957                Cookies.remove('pys_first_visit', { path: '/',domain: domain })
5958
5959            }
5960            if(options.cookie.disabled_utmTerms_cookie || options.cookie.disabled_all_cookie)
5961            {
5962                $.each(Utils.utmTerms, function (index, name) {
5963                    Cookies.remove('pys_' + name, { path: '/',domain: domain })
5964                });
5965                $.each(Utils.utmTerms, function (index, name) {
5966                    Cookies.remove('last_pys_' + name, { path: '/',domain: domain })
5967                });
5968            }
5969            if(options.cookie.disabled_utmId_cookie || options.cookie.disabled_all_cookie)
5970            {
5971                $.each(Utils.utmId,function(index,name) {
5972                    Cookies.remove('pys_' + name, { path: '/',domain: domain })
5973                })
5974                $.each(Utils.utmId,function(index,name) {
5975                    Cookies.remove('last_pys_' + name, { path: '/',domain: domain })
5976                });
5977            }
5978        }
5979
5980        if (options.gdpr.cookie_law_info_integration_enabled) {
5981            var cli_cookie = Cookies.get('cookieyes-consent') ?? Cookies.get('wt_consent') ?? Cookies.get('viewed_cookie_policy');
5982
5983            if (typeof cli_cookie !== 'undefined') {
5984                if (cli_cookie === Cookies.get('cookieyes-consent') || cli_cookie === Cookies.get('wt_consent')) {
5985                    if (getCookieYes('analytics') === 'yes') {
5986                        Utils.manageCookies();
5987                    }
5988                } else if (cli_cookie === Cookies.get('viewed_cookie_policy') && cli_cookie == 'yes') {
5989                    Utils.manageCookies();
5990                }
5991            }
5992        }
5993
5994        if ( options.gdpr.consent_magic_integration_enabled && typeof CS_Data !== "undefined" ) {
5995            if ( CS_Data.cs_script_cat.pys == CS_Data.cs_necessary_cat_id || CS_Data.cs_script_cat.pys == 0 ) {
5996                Utils.manageCookies();
5997            } else if ( Cookies.get( 'cs_enabled_cookie_term' + CS_Data.test_prefix + '_' + CS_Data.cs_script_cat.pys ) == 'yes' ) {
5998                Utils.manageCookies();
5999            }
6000        } else {
6001            Utils.manageCookies();
6002        }
6003
6004        Utils.initializeRequestParams();
6005        Utils.setupGdprCallbacks();
6006
6007        if ( options.enable_auto_save_advance_matching ) {
6008            let override = options.data_persistency == 'recent_data';
6009
6010            //Setup Advanced Form Data
6011            if ( options.advance_matching_form.enable_advance_matching_forms ) {
6012                $( document ).on( "blur", "input[type='email']", function () {
6013                    let email = $( this ).val().trim().toLowerCase();
6014                    if ( Utils.validateEmail( email ) ) {
6015                        Utils.saveAdvancedFormData( email, null, null, null, override );
6016                    }
6017                } )
6018                $( document ).on( "blur", "input[type='tel']", function () {
6019                    let phone = $( this ).val().trim().replace( /\D/g, "" );
6020                    if ( phone.length > 5 ) {
6021                        Utils.saveAdvancedFormData( null, phone, null, null, override );
6022                    }
6023                } )
6024                $( document ).on( "blur", "input[type='text']", function () {
6025                    let name;
6026                    if ( $( this ).attr( "name" ) && $( this ).attr( "name" ) != '' ) {
6027                        name = $( this ).attr( "name" ).trim()
6028                    }
6029                    if ( name && options.advance_matching_form.advance_matching_fn_names.includes( name ) ) {
6030                        let value = $( this ).val().trim();
6031                        if ( value.length > 0 ) {
6032                            Utils.saveAdvancedFormData( null, null, value, null, override );
6033                        }
6034                    }
6035                    if ( name && options.advance_matching_form.advance_matching_ln_names.includes( name ) ) {
6036                        let value = $( this ).val().trim();
6037                        if ( value.length > 0 ) {
6038                            Utils.saveAdvancedFormData( null, null, null, value, override );
6039                        }
6040                    }
6041                    if ( name && options.advance_matching_form.advance_matching_tel_names.includes( name ) ) {
6042                        let value = $( this ).val().trim();
6043                        if ( value.length > 0 ) {
6044                            Utils.saveAdvancedFormData( null, value, null, null, override );
6045                        }
6046                    }
6047                    if ( name && options.advance_matching_form.advance_matching_em_names.includes( name ) ) {
6048                        let email = $( this ).val().trim().toLowerCase();
6049
6050                        if ( Utils.validateEmail( email ) ) {
6051                            Utils.saveAdvancedFormData( email, null, null, null, false );
6052                        }
6053                    }
6054                } )
6055            }
6056
6057            //Setup Advanced Url Data
6058            if ( Object.keys( options.advance_matching_url ).length > 0 && options.advance_matching_url.enable_advance_matching_url ) {
6059                const url_params = new URLSearchParams( window.location.search );
6060                url_params.forEach( ( value, key ) => {
6061                    if ( options.advance_matching_url.advance_matching_fn_names.includes( key ) ) {
6062                        Utils.saveAdvancedFormData( null, null, value.trim(), null, override );
6063                    }
6064
6065                    if ( options.advance_matching_url.advance_matching_ln_names.includes( key ) ) {
6066                        Utils.saveAdvancedFormData( null, null, null, value.trim(), override );
6067                    }
6068
6069                    if ( options.advance_matching_url.advance_matching_tel_names.includes( key ) ) {
6070                        Utils.saveAdvancedFormData( null, value.trim(), null, null, override );
6071                    }
6072
6073                    if ( options.advance_matching_url.advance_matching_em_names.includes( key ) ) {
6074                        let email = value.trim().toLowerCase()
6075                        if ( Utils.validateEmail( email ) ) {
6076                            Utils.saveAdvancedFormData( email, null, null, null, override );
6077                        }
6078                    }
6079                } );
6080            }
6081        }
6082
6083        // setup Click Event
6084        if (
6085            options.dynamicEvents.hasOwnProperty("automatic_event_internal_link") ||
6086            options.dynamicEvents.hasOwnProperty("automatic_event_outbound_link") ||
6087            options.dynamicEvents.hasOwnProperty("automatic_event_tel_link") ||
6088            options.dynamicEvents.hasOwnProperty("automatic_event_email_link") ||
6089            options.dynamicEvents.hasOwnProperty("automatic_event_download")
6090        ) {
6091
6092            $(document).onFirst('click', 'a, button, input[type="button"], input[type="submit"]', function (e) {
6093
6094                var $elem = $(this);
6095
6096
6097                // Download
6098                if(options.dynamicEvents.hasOwnProperty("automatic_event_download")) {
6099                    var isFired = false;
6100                    if ($elem.is('a')) {
6101                        var href = $elem.attr('href');
6102                        if (typeof href !== "string") {
6103                            return;
6104                        }
6105                        href = href.trim();
6106                        var extension = Utils.getLinkExtension(href);
6107                        var track_download = false;
6108
6109                        if (extension.length > 0) {
6110
6111                            if(options.dynamicEvents.hasOwnProperty("automatic_event_download") ) {
6112                                var pixels = Object.keys(options.dynamicEvents.automatic_event_download);
6113                                for (var i = 0; i < pixels.length; i++) {
6114                                    var event = Utils.clone(options.dynamicEvents.automatic_event_download[pixels[i]]);
6115                                    var extensions = event.extensions;
6116                                    if (extensions.includes(extension)) {
6117
6118                                        if(pixels[i] == "tiktok" || pixels[i] == "reddit") {
6119                                            getPixelBySlag(pixels[i]).fireEvent(event.name, event);
6120                                        } else {
6121                                            if (options.enable_remove_download_url_param) {
6122                                                href = href.split('?')[0];
6123                                            }
6124                                            event.params.download_url = href;
6125                                            event.params.download_type = extension;
6126                                            event.params.download_name = Utils.getLinkFilename(href);
6127                                            getPixelBySlag(pixels[i]).onDownloadEvent(event);
6128                                        }
6129
6130                                        isFired = true;
6131                                    }
6132                                }
6133                            }
6134                        }
6135                    }
6136                    if(isFired) { // prevent duplicate events on the same element
6137                        return;
6138                    }
6139                }
6140
6141
6142                if (!e.hasOwnProperty('originalEvent')) {
6143                    return;
6144                }
6145                if($elem.hasClass("add_to_cart_button") ||
6146                    $elem.hasClass("single_add_to_cart_button") ) { // add_to_cart_button fire in woo
6147                    return;
6148                }
6149
6150                if(options.dynamicEvents.hasOwnProperty("wcf_add_to_cart_on_next_step_click")
6151                    && $elem.hasClass("wcf-next-step-link")) {
6152                    return;// add_to_cart_button fire in woo cf
6153                }
6154                if(options.dynamicEvents.hasOwnProperty("wcf_add_to_cart_on_bump_click")
6155                    && $elem.hasClass("wcf-bump-order-cb")) {
6156                    return;// add_to_cart_button fire in woo cf
6157                }
6158
6159                if($elem.hasClass("remove_from_cart_button") ) { // cancel remove from cart
6160                    return;
6161                }
6162                if($elem.hasClass("remove") ) { // cancel remove from cart
6163                    if($elem.parents('.cart_item').length || $elem.parents('.mini_cart_item').length)
6164                        return;
6165                }
6166                if($elem.attr("name") == "update_cart" || $elem.attr("name") == "apply_coupon") { // cancel update  c
6166art or coupon button
6167                    return;
6168                }
6169
6170
6171                if ($elem.hasClass('pys_block')) {
6172                    return; // avoiding fake double clicks from Affiliate event
6173                }
6174                var text = "";
6175                var target_url = "";
6176                var linkType = "Internal Click";
6177
6178                if ($elem.is('a')) {
6179                    var href = $elem.attr('href');
6180
6181                    // fixes #112
6182                    if (typeof href !== "string") {
6183                        return;
6184                    }
6185                    href = href.trim();
6186
6187                    text = $elem.contents().filter(function() {
6188                        return this.nodeType === 3; // Фильтруем только текстовые узлы
6189                    }).text().trim();
6190                    if(options.enable_remove_target_url_param) {
6191                        target_url = href.split('?')[0];
6192                    } else {
6193                        target_url = href
6194                    }
6195
6196
6197                    //Email Event
6198                    if ( href.startsWith( 'mailto:' ) ) {
6199                        if ( options.triggerEventTypes.hasOwnProperty( "email_link" ) ) {
6200                            return;
6201                        } else {
6202                            setupEmailLinks();
6203                        }
6204
6205                        return; // not fire next
6206                    }
6207
6208                    // Phone
6209                    if (href.startsWith('tel:')) {
6210                        if(options.dynamicEvents.hasOwnProperty("automatic_event_tel_link")) {
6211                            var pixels = Object.keys(options.dynamicEvents.automatic_event_tel_link);
6212                            for(var i = 0;i<pixels.length;i++) {
6213                                var event = Utils.clone(options.dynamicEvents.automatic_event_tel_link[pixels[i]]);
6214                                if ( pixels[i] !== 'tiktok' && pixels[i] !== 'reddit') {
6215                                    Utils.copyProperties(Utils.getRequestParam
6215s(), event.params);
6216                                }
6217                                getPixelBySlag(pixels[i]).fireEvent(event.name, event);
6218                            }
6219                        }
6220                        return; // not fire next
6221                    }
6222
6223                    if (href.startsWith('http')) {
6224                        // link type
6225                        var host = $elem.context != undefined ? $elem.context.host : $elem[0].host;
6226                        if (document.location.host != host) {
6227                            linkType = 'External Click';
6228                        }
6229                    }
6230                } else if ($elem.is('button')) {
6231                    if( $elem.hasClass("forminator-button-submit")) {
6232                        //disable duplicate events
6233                        return;
6234                    }
6235                    text = $elem.contents().filter(function() {
6236                        return this.nodeType === 3; // Фильтруем только текстовые узлы
6237                    }).text().trim();
6238                } else if ($elem.is('input[type="button"]')) {
6239                    text = $elem.val();
6240                } else if ($elem.is('input[type="submit"]')) {
6241                    if ( $elem.parents("form.comment-form")) {
6242                        //disable duplicate events
6243                        return;
6244                    }
6245                    if ($elem.parents("form")) {
6246                        //disable duplicate events
6247                        return;
6248                    }
6249                    text = $elem.val();
6250                } else {
6251                    return;
6252                }
6253
6254
6255
6256                text = Utils.filterEmails(text);
6257
6258
6259                if( linkType === "Internal Click"
6260                    && options.dynamicEvents.hasOwnProperty("automatic_event_internal_link")
6261                ) {
6262                    var pixels = Object.keys(options.dynamicEvents.automatic_event_internal_link);
6263
6264                    for(var i = 0;i<pixels.length;i++) {
6265                        var event = Utils.clone(options.dynamicEvents.automatic_event_internal_link[pixels[i]]);
6266
6267	                    if(pixels[i] !== "tiktok" && pixels[i] !== "reddit") { // TT and reddit don't support custom parameters
6268                            event.params["text"] = text;
6269                            if(target_url){
6270                                event.params["target_url"] = target_url;
6271                            }
6272                            Utils.copyProperties(Utils.getRequestParam
6272s(), event.params);
6273                        }
6274
6275
6276                        getPixelBySlag(pixels[i]).fireEvent(event.name, event);
6277                    }
6278                }
6279
6280                if( linkType === "External Click"
6281                    && options.dynamicEvents.hasOwnProperty("automatic_event_outbound_link")
6282                ) {
6283                    var pixels = Object.keys(options.dynamicEvents.automatic_event_outbound_link);
6284
6285                    for(var i = 0;i<pixels.length;i++) {
6286                        var event = Utils.clone(options.dynamicEvents.automatic_event_outbound_link[pixels[i]]);
6287
6288                        if(pixels[i] !== "tiktok" && pixels[i] !== "reddit") { // TT and reddit don't support custom parameters
6289                            event.params["text"] = text;
6290                            if(target_url){
6291                                event.params["target_url"] = target_url;
6292                            }
6293                            Utils.copyProperties(Utils.getRequestParams(), event.params);
6294                        }
6295
6296
6297                        getPixelBySlag(pixels[i]).fireEvent(event.name, event);
6298                    }
6299                }
6300
6301
6302
6303
6304            });
6305
6306        }
6307
6308        // setup AdSense Event
6309        if (options.dynamicEvents.hasOwnProperty("automatic_event_adsense")) {
6310
6311            var isOverGoogleAd = false;
6312
6313            $(document)
6314                .on('mouseover', 'ins iframe', function () { //class adsbygoogle adsbygoogle-noablate ??
6315                    isOverGoogleAd = true;
6316                })
6317                .on('mouseout', 'iframe', function () {
6318                    isOverGoogleAd = false;
6319                });
6320
6321            $(window)
6322                .on( "blur",function () {
6323                    if (isOverGoogleAd) {
6324                        if(options.dynamicEvents.hasOwnProperty("automatic_event_adsense")) {
6325                            var pixels = Object.keys(options.dynamicEvents.automatic_event_adsense);
6326                            for (var i = 0; i < pixels.length; i++) {
6327                                var event = Utils.clone(options.dynamicEvents.automatic_event_adsense[pixels[i]]);
6328                                if ( pixels[i] !== 'tiktok' && pixels[i] !== 'reddit') {
6329                                    Utils.copyProperties(Utils.getRequestParam
6329s(), event.params);
6330                                }
6331                                getPixelBySlag(pixels[i]).onAdSenseEvent(event);
6332                            }
6333                        }
6334
6335                        $.each(options.triggerEventTypes, function (triggerType, events) {
6336                            $.each(events, function (eventId, triggers) {
6337                                switch (triggerType) {
6338                                    case 'ad_sense_click':
6339                                        Utils.fireTriggerEvent(eventId);
6340                                        break;
6341                                }
6342                            });
6343                        });
6344                    }
6345                })
6346                .trigger("focus");
6347
6348        }
6349
6350        //setup adsense for custom events
6351        var dynamicAdsenseEventsTriggers = 0
6352        $.each(options.triggerEventTypes, function (triggerType, events) {
6353            if(triggerType == "ad_sense_click") {
6354                dynamicAdsenseEventsTriggers++;
6355            }
6356        });
6357        if (dynamicAdsenseEventsTriggers > 0) {
6358
6359            var isOverGoogleAd = false;
6360
6361            $(document)
6362                .on('mouseover', 'ins > ins > iframe', function () {
6363                    isOverGoogleAd = true;
6364                })
6365                .on('mouseout', 'iframe', function () {
6366                    isOverGoogleAd = false;
6367                });
6368
6369            $(window)
6370                .on( "blur",function () {
6371                    if (isOverGoogleAd) {
6372
6373                        $.each(options.triggerEventTypes, function (triggerType, events) {
6374                            $.each(events, function (eventId, triggers) {
6375                                switch (triggerType) {
6376                                    case 'ad_sense_click':
6377                                        Utils.fireTriggerEvent(eventId);
6378                                        break;
6379                                }
6380                            });
6381                        });
6382                    }
6383                })
6384                .trigger("focus");
6385
6386        }
6387
6388
6389        // page scroll event
6390        if (options.dynamicEvents.hasOwnProperty("automatic_event_scroll")
6391        ) {
6392
6393            var singlePageScroll = function () {
6394
6395
6396                var docHeight = $(document).height() - $(window).height();
6397                var isFired = false;
6398
6399                if (options.dynamicEvents.hasOwnProperty("automatic_event_scroll")) {
6400                    var pixels = Object.keys(options.dynamicEvents.automatic_event_scroll);
6401                    for(var i = 0;i<pixels.length;i++) {
6402                        var event = Utils.clone(options.dynamicEvents.automatic_event_scroll[pixels[i]]);
6403                        var scroll = Math.round(docHeight * event.scroll_percent / 100)// convert % to absolute positions
6404
6405                        if(scroll < $(window).scrollTop()) {
6406                            if ( pixels[i] !== 'tiktok' && pixels[i] !== 'reddit') {
6407                                Utils.copyProperties(Utils.getRequestParam
6407s(), event.params);
6408                            }
6409                            getPixelBySlag(pixels[i]).onPageScroll(event);
6410                            isFired = true
6411                        }
6412                    }
6413                }
6414                if(isFired) {
6415                    $(document).off("scroll",singlePageScroll);
6416                }
6417            }
6418            $(document).on("scroll",singlePageScroll);
6419        }
6420
6421
6422        if (options.dynamicEvents.hasOwnProperty("automatic_event_time_on_page")) {
6423            var pixels = Object.keys(options.dynamicEvents.automatic_event_time_on_page);
6424            var time = options.dynamicEvents.automatic_event_time_on_page[pixels[0]].time_on_page; // the same for all pixel
6425            setTimeout(function(){
6426                for(var i = 0;i<pixels.length;i++) {
6427                    var event = Utils.clone(options.dynamicEvents.automatic_event_time_on_page[pixels[i]]);
6428                    if ( pixels[i] !== 'tiktok' && pixels[i] !== 'reddit') {
6429                        Utils.copyProperties(Utils.getRequestParam
6429s(), event.params);
6430                    }
6431                    getPixelBySlag(pixels[i]).onTime(event);
6432                }
6433            },time*1000);
6434        }
6435
6436        // setup Dynamic events
6437
6438        $.each(options.triggerEventTypes, function (triggerType, events) {
6439
6440            $.each(events, function (eventId, triggers) {
6441                switch (triggerType) {
6442                    case 'url_click':
6443                        //@see: Utils.setupURLClickEvents()
6444                        break;
6445
6446                    case 'css_click':
6447                        Utils.setupCSSClickEvents(eventId, triggers);
6448                        break;
6449
6450                    case 'css_mouseover':
6451                        Utils.setupMouseOverClickEvents(eventId, triggers);
6452                        break;
6453
6454                    case 'scroll_pos':
6455                        Utils.setupScrollPosEvents(eventId, triggers);
6456                        break;
6457                    case 'comment':
6458                        Utils.setupCommentEvents(eventId, triggers);
6459                        break;
6460                    case 'video_view':
6461                        //@see: Utils.checkYouTubeCompletion() and Utils.addYouTubeEvents()
6462                        break;
6463
6464                    case 'form_field':
6465                        Utils.setupFormFieldEvents(eventId, triggers);
6466                        break;
6467                }
6468
6469            });
6470
6471            if ( triggerType == "email_link" ) {
6472                Utils.setupEmailLinkEvents( events )
6473            }
6474
6475        });
6476
6477        // setup WooCommerce events
6478        if (options.woo.enabled) {
6479
6480            // Woo CartFlow AddToCart
6481            if (options.dynamicEvents.hasOwnProperty("wcf_add_to_cart_on_next_step_click")) {
6482                $("body").on("click",'.wcf-next-step-link',function () {
6483                    var pixels = Object.keys(options.dynamicEvents.wcf_add_to_cart_on_next_step_click);
6484                    for(var i = 0;i<pixels.length;i++) {
6485                        var event = Utils.clone(options.dynamicEvents.wcf_add_to_cart_on_next_step_click[pixels[i]])
6486                        getPixelBySlag(pixels[i]).fireEvent(event.name, event);
6487                    }
6488                });
6489            }
6490            // Woo CartFlow Bump AddToCart
6491            if(options.dynamicEvents.hasOwnProperty("wcf_add_to_cart_on_bump_click") ||
6492                options.dynamicEvents.hasOwnProperty("wcf_bump")) {
6493                $("body").on('change','.wcf-bump-order-cb',function () {
6494
6495                    if(this.checked) {
6496                        if(options.dynamicEvents.hasOwnProperty("wcf_add_to_cart_on_bump_click")) {
6497                            var pixels = Object.keys(options.dynamicEvents.wcf_add_to_cart_on_bump_click);
6498                            for(var i = 0;i<pixels.length;i++) {
6499                                var event = Utils.clone(options.dynamicEvents.wcf_add_to_cart_on_bump_click[pixels[i]]);
6500                                getPixelBySlag(pixels[i]).fireEvent(event.name, event);
6501                            }
6502                        }
6503
6504
6505                        if(options.dynamicEvents.hasOwnProperty("wcf_bump")) {
6506                            var pixels = Object.keys(options.dynamicEvents.wcf_bump);
6507                            for(var i = 0;i<pixels.length;i++) {
6508                                var event = Utils.clone(options.dynamicEvents.wcf_bump[pixels[i]]);
6509                                getPixelBySlag(pixels[i]).fireEvent(event.name, event);
6510                            }
6511                        }
6512
6513                    } else {
6514                        if(options.dynamicEvents.hasOwnProperty("wcf_remove_from_cart_on_bump_click")) {
6515                            var pixels = Object.keys(options.dynamicEvents.wcf_remove_from_cart_on_bump_click);
6516                            for(var i = 0;i<pixels.length;i++) {
6517                                var event = Utils.clone(options.dynamicEvents.wcf_remove_from_cart_on_bump_click[pixels[i]]);
6518                                getPixelBySlag(pixels[i]).fireEvent(event.name, event);
6519                            }
6520                        }
6521
6522                    }
6523
6524
6525                });
6526            }
6527
6528
6529            // WooCommerce AddToCart
6530            if (options.dynamicEvents.hasOwnProperty("woo_add_to_cart_on_button_click")
6531                && options.woo.hasOwnProperty("addToCartCatchMethod")
6532                && options.woo.addToCartCatchMethod === "add_cart_js"
6533            ) {
6534                // Loop, any kind of "simple" product, except external
6535                $('.add_to_cart_button:not(.product_type_variable,.product_type_bundle,.single_add_to_cart_button)').on("click",function (e) {
6536
6537                    var $button = $(this);
6538                    var $prod_info = $button.siblings('.pys_list_name_productdata').data();
6539                    var product_id = $(this).data('product_id');
6540                    Cookies.set('productlist', JSON.stringify($prod_info), { expires: 1,path: '/' })
6541                    var product_id = $(this).data('product_id');
6542                    if (typeof product_id !== 'undefined') {
6543
6544                        if(options.dynamicEvents.hasOwnProperty("woo_add_to_cart_on_button_click")){
6545                            var tmpEventID = pys_generate_token();
6546                            $.each(options.dynamicEvents.woo_add_to_cart_on_button_click, function (i, tag) {
6547                                tag.eventID = tmpEventID;
6548                            });
6549                        }
6550
6551                        Facebook.onWooAddToCartOnButtonEvent(product_id,$(this));
6552                        Analytics.onWooAddToCartOnButtonEvent(product_id, $prod_info);
6553                        GTM.onWooAddToCartOnButtonEvent(product_id, $prod_info);
6554                        GAds.onWooAddToCartOnButtonEvent(product_id);
6555                        Pinterest.onWooAddToCartOnButtonEvent(product_id);
6556                        Bing.onWooAddToCartOnButtonEvent(product_id);
6557                        TikTok.onWooAddToCartOnButtonEvent(product_id);
6558                        Reddit.onWooAddToCartOnButtonEvent(product_id);
6559                    }
6560
6561                });
6562
6563                // Single Product
6564                // tap try to https://stackoverflow.com/questions/30990967/on-tap-click-event-firing-twice-how-to-avoid-it
6565                //  $(document) not work
6566                $('body').onFirst('click','button.single_add_to_cart_button,.single_add_to_cart_button',function (e) {
6567
6568                    var $button = $(this);
6569                    var $prod_info = $button.siblings('.pys_list_name_productdata').data();
6570                    var product_id = $(this).data('product_id');
6571                    Cookies.set('productlist', JSON.stringify($prod_info), { expires: 1,path: '/' })
6572                    if ($button.hasClass('disabled')) {
6573                        return;
6574                    }
6575
6576                    var $form = $button.closest('form');
6577
6578                    var product_type = Utils.PRODUCT_SIMPLE;
6579                    var is_external = false;
6580
6581                    if ($form.length === 0) {
6582                        is_external = true;
6583                    } else if ($form.hasClass('variations_form')) {
6584                        product_type = Utils.PRODUCT_VARIABLE;
6585                    } else if($form.hasClass('bundle_form')) {
6586                        product_type = Utils.PRODUCT_BUNDLE;
6587                    } else if($form.hasClass('grouped_form')) {
6588                        product_type = Utils.PRODUCT_GROUPED;
6589                    }
6590
6591
6592
6593                    var product_id;
6594                    var qty;
6595                    if (product_type === Utils.PRODUCT_GROUPED) {
6596                        qty = 1;
6597                        product_id = parseInt($form.find('*[name="add-to-cart"]').val());
6598                    } else if (product_type === Utils.PRODUCT_VARIABLE) {
6599                        product_id = parseInt($form.find('*[name="add-to-cart"]').val());
6600                        var qtyTag = $form.find('input[name="quantity"]');
6601                        if(qtyTag.length <= 0) {
6602                            qtyTag = $form.find('select[name="quantity"]');
6603                        }
6604                        qty = parseInt(qtyTag.val());
6605                    } else if (is_external) {
6606                        product_id = options.woo.singleProductId;
6607                        qty = 1;
6608                    } else {
6609                        product_id = parseInt($form.find('*[name="add-to-cart"]').val());
6610                        var qtyTag = $form.find('input[name="quantity"]');
6611                        if(qtyTag.length <= 0) {
6612                            qtyTag = $form.find('select[name="quantity"]');
6613                        }
6614                        qty = parseInt(qtyTag.val());
6615                    }
6616
6617                    //
6618                    if(options.dynamicEvents.hasOwnProperty("woo_add_to_cart_on_button_click")){
6619                        var tmpEventID = pys_generate_token();
6620                        $.each(options.dynamicEvents.woo_add_to_cart_on_button_click, function (i, tag) {
6621                            tag.eventID = tmpEventID;
6622                        });
6623                    }
6624
6625                    Facebook.onWooAddToCartOnSingleEvent(product_id, qty, product_type, is_external, $form);
6626                    Analytics.onWooAddToCartOnSingleEvent(product_id, qty, product_type, is_external, $form, $prod_info);
6627                    GTM.onWooAddToCartOnSingleEvent(product_id, qty, product_type, is_external, $form, $prod_info);
6628                    GAds.onWooAddToCartOnSingleEvent(product_id, qty, product_type, is_external, $form);
6629                    Pinterest.onWooAddToCartOnSingleEvent(product_id, qty, product_type, is_external, $form);
6630                    Bing.onWooAddToCartOnSingleEvent(product_id, qty, product_type, is_external, $form);
6631                    TikTok.onWooAddToCartOnSingleEvent(product_id, qty, product_type, is_external, $form);
6632                    Reddit.onWooAddToCartOnSingleEvent(product_id, qty, product_type, is_external, $form);
6633                });
6634
6635            } else {
6636                $('.add_to_cart_button:not(.product_type_variable,.product_type_bundle,.single_add_to_cart_button)').on("click",function (e) {
6637                    var $button = $(this);
6638                    var $prod_info = $button.siblings('.pys_list_name_productdata').data();
6639                    var product_id = $(this).data('product_id');
6640                    Cookies.set('productlist', JSON.stringify($prod_info), { expires: 1,path: '/' })
6641                });
6642
6643                // Single Product
6644                // tap try to https://stackoverflow.com/questions/30990967/on-tap-click-event-firing-twice-how-to-avoid-it
6645                //  $(document) not work
6646                $('body').onFirst('click','button.single_add_to_cart_button,.single_add_to_cart_button',function (e) {
6647
6648                    var $button = $(this);
6649                    var $prod_info = $button.siblings('.pys_list_name_productdata').data();
6650                    Cookies.set('productlist', $prod_info, { expires: 1,path: '/' })
6651                });
6652            }
6653
6654            // WooCommerce Affiliate
6655            if (options.dynamicEvents.hasOwnProperty("woo_affiliate")) {
6656
6657                // Loop, external
6658                $('.product_type_external').on("click",function (e) {
6659
6660                    var product_id = $(this).data('product_id');
6661
6662                    if (typeof product_id !== 'undefined') {
6663                        Facebook.onWooAffiliateEvent(product_id);
6664                        Analytics.onWooAffiliateEvent(product_id);
6665                        GTM.onWooAffiliateEvent(product_id);
6666                        GAds.onWooAffiliateEvent(product_id);
6667                        Pinterest.onWooAffiliateEvent(product_id);
6668                        Bing.onWooAffiliateEvent(product_id);
6669                    }
6670
6671                });
6672
6673            }
6674
6675            // WooCommerce RemoveFromCart
6676            if (options.dynamicEvents.hasOwnProperty("woo_remove_from_cart")) {
6677
6678                $('body').on('click', options.woo.removeFromCartSelector, function (e) {
6679
6680                    var $a = $(e.currentTarget),
6681                        href = $a.attr('href');
6682
6683                    // extract cart item hash from remove button URL
6684                    var regex = new RegExp("[\\?&]remove_item=([^&#]*)"),
6685                        results = regex.exec(href);
6686
6687                    if (results !== null) {
6688
6689                        var item_hash = results[1];
6690
6691                        if (options.dynamicEvents["woo_remove_from_cart"].hasOwnProperty(item_hash)) {
6692                            var events = options.dynamicEvents["woo_remove_from_cart"][item_hash];
6693                            Utils.fireEventForAllPixel("onWooRemoveFromCartEvent",events)
6694                        }
6695
6696                    }
6697
6698                });
6699
6700            }
6701
6702            // WooCommerce PayPal
6703            if (options.dynamicEvents.hasOwnProperty("woo_paypal")) {
6704
6705                // Non-default binding used to avoid situations when some code in external js
6706                // stopping events propagation, eg. returns false, and our handler will never called
6707                $(document).onFirst('submit click', '#place_order', function (e) {
6708
6709                    var method = $('form[name="checkout"] input[name="payment_method"]:checked').val();
6710
6711                    if (method !== 'paypal') {
6712                        return;
6713                    }
6714                    var events = options.dynamicEvents.woo_paypal;
6715                    Utils.fireEventForAllPixel("onWooPayPalEvent",events)
6716
6717                });
6718
6719            }
6720
6721            // WooCommerce checkout progress
6722            if(options.dynamicEvents.hasOwnProperty("woo_initiate_checkout_progress_f") ) {
6723
6724                $(document).on("change",".woocommerce-validated #billing_first_name",function () {
6725                    var pixels = Object.keys(options.dynamicEvents.woo_initiate_checkout_progress_f);
6726                    for (var i = 0; i < pixels.length; i++) {
6727                        var event = Utils.clone(options.dynamicEvents.woo_initiate_checkout_progress_f[pixels[i]]);
6728                        getPixelBySlag(pixels[i]).onWooCheckoutProgressStep(event);
6729                    }
6730                });
6731            }
6732            if(options.dynamicEvents.hasOwnProperty("woo_initiate_checkout_progress_l")) {
6733
6734                $(document).on("change",".woocommerce-validated #billing_last_name",function () {
6735                    var pixels = Object.keys(options.dynamicEvents.woo_initiate_checkout_progress_l);
6736                    for (var i = 0; i < pixels.length; i++) {
6737                        var event = Utils.clone(options.dynamicEvents.woo_initiate_checkout_progress_l[pixels[i]]);
6738                        getPixelBySlag(pixels[i]).onWooCheckoutProgressStep(event);
6739                    }
6740                });
6741            }
6742
6743            if(options.dynamicEvents.hasOwnProperty("woo_initiate_checkout_progress_e")) {
6744
6745                $(document).on("change",".woocommerce-validated #billing_email",function () {
6746                    var pixels = Object.keys(options.dynamicEvents.woo_initiate_checkout_progress_e);
6747                    for (var i = 0; i < pixels.length; i++) {
6748                        var event = Utils.clone(options.dynamicEvents.woo_initiate_checkout_progress_e[pixels[i]]);
6749                        getPixelBySlag(pixels[i]).onWooCheckoutProgressStep(event);
6750                    }
6751                });
6752            }
6753            if(options.dynamicEvents.hasOwnProperty("woo_initiate_checkout_progress_o")) {
6754                $(document).onFirst('submit click', '#place_order', function () {
6755                    var shippingMethodFull = $('[name="shipping_method[0]"]:checked').val();
6756                    var shippingMethod = shippingMethodFull ? shippingMethodFull.split(':')[0] : '';
6757                    var pixels = Object.keys(options.dynamicEvents.woo_initiate_checkout_progress_o);
6758 
6758                   for (var i = 0; i < pixels.length; i++) {
6759                        var event = Utils.clone(options.dynamicEvents.woo_initiate_checkout_progress_o[pixels[i]]);
6760                        // Add shipping_method to event params
6761                        event.params = event.params || {};
6762                        event.params.checkout_option = shippingMethod;
6763                        getPixelBySlag(pixels[i]).onWooCheckoutProgressStep(event);
6764                    }
6765                });
6766            }
6767
6768
6769            // WooCommerce
6770
6771            $('.product.type-product a.woocommerce-loop-product__link').onFirst('click', function (evt) {
6772                var productId = $(this).closest('.product').find(".add_to_cart_button").attr("data-product_id");
6773                var eventTypes = ["woo_select_content_search", "woo_select_content_shop", "woo_select_content_tag", "woo_select_content_single", "woo_select_content_category"];
6774                var isEventFired = false;
6775
6776                for (var i = 0; i < eventTypes.length; i++) {
6777                    var eventType = eventTypes[i];
6778                    if (options.dynamicEvents.hasOwnProperty(eventType) && options.dynamicEvents[eventType].hasOwnProperty(productId)) {
6779                        if(Analytics.isEnabled()){
6780                            Analytics.onWooSelectContent(options.dynamicEvents[eventType][productId][Analytics.tag()]);
6781                        }
6782                        if(GTM.isEnabled()){
6783                            GTM.onWooSelectContent(options.dynamicEvents[eventType][productId][GTM.tag()]);
6784                        }
6785                        isEventFired = true;
6786                        break;
6787                    }
6788                }
6789
6790                if (!isEventFired) {
6791                    let prod_info = $(this).parent().find('.pys_list_name_productdata').data();
6792                    if (prod_info) {
6793                        const select_prod_list = {};
6794                        if (prod_info['pys_list_name_productlist_name']) {
6795                            select_prod_list.list_name = prod_info['pys_list_name_productlist_name']
6796                        }
6797                        if (prod_info['pys_list_name_productlist_id']) {
6798                            select_prod_list.list_id = prod_info['pys_list_name_productlist_id']
6799                        }
6800                        const url = new URL(window.location.href);
6801                        select_prod_list.url = url.origin + url.pathname;
6802                        Cookies.set('select_prod_list', JSON.stringify(select_prod_list), { expires: 1,path: '/' });
6803                    }
6804                }
6805            });
6806
6807        }
6808
6809        // setup EDD events
6810        if (options.edd.enabled) {
6811
6812            // EDD AddToCart
6813            if (options.dynamicEvents.hasOwnProperty("edd_add_to_cart_on_button_click")) {
6814
6815                $('form.edd_download_purchase_form .edd-add-to-cart').on("click",function (e) {
6816
6817                    var $button = $(this);
6818                    var $form = $button.closest('form');
6819                    var variable_price = $button.data('variablePrice'); // yes/no
6820                    var price_mode = $button.data('priceMode'); // single/multi
6821                    var ids = [];
6822                    var quantities = [];
6823                    var qty;
6824                    var id;
6825
6826                    if (variable_price === 'yes' && price_mode === 'multi') {
6827
6828                        id = $form.find('input[name="download_id"]').val();
6829
6830                        // get selected variants
6831                        $.each($form.find('input[name="edd_options[price_id][]"]:checked'), function (i, el) {
6832                            ids.push(id + '_' + $(el).val());
6833                        });
6834
6835                        // get qty for selected variants
6836                        $.each(ids, function (i, variant_id) {
6837
6838                            var variant_index = variant_id.split('_', 2);
6839                            qty = $form.find('input[name="edd_download_quantity_' + variant_index[1] + '"]').val();
6840
6841                            if (typeof qty !== 'undefined') {
6842                                quantities.push(qty);
6843                            } else {
6844                                quantities.push(1);
6845                            }
6846
6847                        });
6848
6849                    } else if (variable_price === 'yes' && price_mode === 'single') {
6850
6851                        id = $form.find('input[name="download_id"]').val();
6852                        ids.push(id + '_' + $form.find('input[name="edd_options[price_id][]"]:checked').val());
6853
6854                        qty = $form.find('input[name="edd_download_quantity"]').val();
6855
6856                        if (typeof qty !== 'undefined') {
6857                            quantities.push(qty);
6858                        } else {
6859                            quantities.push(1);
6860                        }
6861
6862                    } else {
6863
6864                        ids.push($button.data('downloadId'));
6865
6866                        qty = $form.find('input[name="edd_download_quantity"]').val();
6867
6868                        if (typeof qty !== 'undefined') {
6869                            quantities.push(qty);
6870                        } else {
6871                            quantities.push(1);
6872                        }
6873                    }
6874
6875                    // fire event for each download/variant
6876                    $.each(ids, function (i, download_id) {
6877
6878                        var q = parseInt(quantities[i]);
6879                        var variant_index = download_id.toString().split('_', 2);
6880                        var price_index;
6881
6882                        if (variant_index.length === 2) {
6883                            download_id = variant_index[0];
6884                            price_index = variant_index[1];
6885                        }
6886
6887                        Facebook.onEddAddToCartOnButtonEvent(download_id, price_index, q);
6888                        Analytics.onEddAddToCartOnButtonEvent(download_id, price_index, q);
6889                        GTM.onEddAddToCartOnButtonEvent(download_id, price_index, q);
6890                        GAds.onEddAddToCartOnButtonEvent(download_id, price_index, q);
6891                        Pinterest.onEddAddToCartOnButtonEvent(download_id, price_index, q);
6892                        Bing.onEddAddToCartOnButtonEvent(download_id, price_index, q);
6893                        TikTok.onEddAddToCartOnButtonEvent(download_id, price_index, q);
6894                        Reddit.onEddAddToCartOnButtonEvent(download_id, price_index, q);
6895
6896                    });
6897
6898                });
6899
6900            }
6901
6902            // EDD RemoveFromCart
6903            if (options.dynamicEvents.hasOwnProperty("edd_remove_from_cart") ) {
6904
6905                $('form#edd_checkout_cart_form .edd_cart_remove_item_btn').on("click",function (e) {
6906
6907                    var href = $(this).attr('href');
6908                    var key = href.substring(href.indexOf('=') + 1).charAt(0);
6909
6910                    if (options.dynamicEvents.edd_remove_from_cart.hasOwnProperty(key)) {
6911                        var events = options.dynamicEvents.edd_remove_from_cart[key];
6912                        Utils.fireEventForAllPixel("onEddRemoveFromCartEvent",events)
6913                    }
6914
6915                });
6916
6917            }
6918
6919        }
6920
6921        Utils.setupURLClickEvents();
6922
6923        // setup Comment Event
6924        if (options.dynamicEvents.hasOwnProperty("automatic_event_comment")
6925        ) {
6926
6927            $('form.comment-form').on("submit",function () {
6928                if (options.dynamicEvents.hasOwnProperty("automatic_event_comment")) {
6929                    var pixels = Object.keys(options.dynamicEvents.automatic_event_comment);
6930                    for (var i = 0; i < pixels.length; i++) {
6931                        var event = Utils.clone(options.dynamicEvents.automatic_event_comment[pixels[i]]);
6932                        if ( pixels[i] !== 'tiktok' && pixels[i] !== 'reddit') {
6933                            Utils.copyProperties(Utils.getRequestParam
6933s(), event.params);
6934                        }
6935                        getPixelBySlag(pixels[i]).onCommentEvent(event);
6936                    }
6937                }
6938            });
6939
6940        }
6941
6942        // setup Form Event
6943        if ( options.dynamicEvents.hasOwnProperty("automatic_event_form")) {
6944
6945            $(document).onFirst('submit', 'form', function (e) {
6946
6947                var $form = $(this);
6948
6949                // exclude WP forms
6950                if ($form.hasClass('comment-form') || $form.hasClass('search-form') || $form.attr('id') === 'adminbarsearch') {
6951                    return;
6952                }
6953
6954                // exclude Woo forms
6955                if ($form.hasClass('woocommerce-product-search') || $form.hasClass('cart') || $form.hasClass('woocommerce-cart-form') ||
6956                    $form.hasClass('woocommerce-shipping-calculator') || $form.hasClass('checkout') || $form.hasClass('checkout_coupon')) {
6957                    return;
6958                }
6959
6960                // exclude EDD forms
6961                if ($form.hasClass('edd_form') || $form.hasClass('edd_download_purchase_form')) {
6962                    return;
6963                }
6964                // exclude CF7 forms
6965                if ($form.hasClass('wpcf7-form')) {
6966                    return;
6967                }
6968                // exclude Gravity forms
6969                if ($form.attr('id') && $form.attr('id').includes('gform')) {
6970                    var target = $form.attr('target');
6971                    if (target && target.indexOf('gform_ajax_frame') !== -1) {
6972                        return;
6973                    }
6974                }
6975                // exclude Forminator forms
6976                if ($form.hasClass('forminator-custom-form') || $form.hasClass('forminator_ajax')) {
6977                    return;
6978                }
6979                // exclude WPforms forms
6980                if ($form.hasClass('wpforms-form') || $form.hasClass('wpforms-ajax-form')) {
6981                    return;
6982                }
6983                // exclude Formidable forms
6984                /*if ($form.hasClass('frm-show-form')) {
6985                    return;
6986                }*/
6987                // exclude Ninja Forms forms
6988                if ($form.parent().hasClass('nf-form-layout')) {
6989                    return;
6990                }
6991                // exclude Fluent forms
6992                if ($form.hasClass('frm-fluent-form')) {
6993                    return;
6994                }
6995
6996                // exclude WS form forms
6997                if ($form.hasClass('wsf-form') ) {
6998                    return;
6999                }
7000
7001                // exclude WS form forms
7002                if ( $form.hasClass( 'elementor-form' ) ) {
7003                    return;
7004                }
7005
7006                if(!options.enable_success_send_form) {
7007                    var params = {
7008                        form_id: $form.attr('id'),
7009                        form_class: $form.attr('class') ? $form.attr('class') : $form.attr('id'),
7010                        text: $form.find('[type="submit"]').is('input') ?
7011                            $form.find('[type="submit"]').val() : $form.find('[type="submit"]').text()
7012                    };
7013
7014                    if (options.dynamicEvents.hasOwnProperty("automatic_event_form")) {
7015                        var pixels = Object.keys(options.dynamicEvents.automatic_event_form);
7016                        for (var i = 0; i < pixels.length; i++) {
7017                            var event = Utils.clone(options.dynamicEvents.automatic_event_form[pixels[i]]);
7018
7019                            if (pixels[i] === "tiktok" || pixels[i] === "reddit") {
7020                                getPixelBySlag(pixels[i]).fireEvent(event.name, event);
7021                            } else {
7022                                Utils.copyProperties(params, event.params,)
7023                                Utils.copyProperties(Utils.getRequestParam
7023s(), event.params);
7024                                getPixelBySlag(pixels[i]).onFormEvent(event);
7025                            }
7026                        }
7027                    }
7028                }
7029            });
7030
7031
7032        }
7033
7034        jQuery(document).on('elementor/popup/show', function(event) {
7035            for (var i = 0; i < jQuery(".wpcf7-form").length; i++) {
7036                wpcf7.init(jQuery(".wpcf7-form")[i]);
7037            }
7038        });
7039
7040        document.addEventListener( 'wpcf7mailsent', function ( event ) {
7041            let form_id = event.detail.contactFormId,
7042                sendEventId = null,
7043                disabled_form_action = false,
7044                form_submit_mode = 'both';
7045            if ( options.triggerEventTypes.hasOwnProperty( 'CF7' ) ) {
7046                $.each( options.triggerEventTypes.CF7, function ( eventId, triggers ) {
7047                    $.each( triggers, function ( index, trigger ) {
7048                        $.each( trigger.forms, function ( i, value ) {
7049                            if ( value == form_id ) {
7050                                sendEventId = eventId;
7051                                disabled_form_action = trigger.disabled_form_action;
7052                                form_submit_mode = trigger.form_submit_mode || 'both';
7053                            }
7054                        } )
7055                    } );
7056                } );
7057            }
7058            if ( sendEventId != null && ( form_submit_mode === 'both' || form_submit_mode === 'ajax_only' ) ) {
7059                Utils.fireTriggerEvent( sendEventId );
7060            }
7061            sendFormAction( $( event.target ), form_id, sendEventId, disabled_form_action, form_submit_mode );
7062
7063        }, false );
7064
7065        //GravityForm
7066        jQuery( document ).on( 'gform_confirmation_loaded', function ( event, formId ) {
7067            let form_id = formId,
7068                sendEventId = null,
7069                disabled_form_action = false,
7070                form_submit_mode = 'both';
7071            if ( options.triggerEventTypes.hasOwnProperty( 'gravity' ) ) {
7072                $.each( options.triggerEventTypes.gravity, function ( eventId, triggers ) {
7073                    $.each( triggers, function ( index, trigger ) {
7074                        $.each( trigger.forms, function ( i, value ) {
7075                            if ( value == form_id ) {
7076                                disabled_form_action = trigger.disabled_form_action;
7077                                sendEventId = eventId;
7078                                form_submit_mode = trigger.form_submit_mode || 'both';
7079                            }
7080                        } )
7081                    } );
7082                } );
7083            }
7084
7085            if ( sendEventId != null && ( form_submit_mode === 'both' || form_submit_mode === 'ajax_only' ) ) {
7086                Utils.fireTriggerEvent( sendEventId );
7087            }
7088            sendFormAction( $( event.target ), form_id, sendEventId, disabled_form_action, form_submit_mode );
7089            jQuery( document ).off( 'gform_confirmation_loaded' );
7090        } );
7091        //Forminator
7092        $( document ).on( 'forminator:form:submit:success', function ( event ) {
7093
7094            let form_id = $( event.target ).find( 'input[name="form_id"]' ).val(),
7095                sendEventId = null,
7096                disabled_form_action = false,
7097                form_submit_mode = 'both';
7098            if ( options.triggerEventTypes.hasOwnProperty( 'forminator' ) ) {
7099                $.each( options.triggerEventTypes.forminator, function ( eventId, triggers ) {
7100                    $.each( triggers, function ( index, trigger ) {
7101                        $.each( trigger.forms, function ( i, value ) {
7102                            if ( value == form_id ) {
7103                                disabled_form_action = trigger.disabled_form_action;
7104                                sendEventId = eventId;
7105                                form_submit_mode = trigger.form_submit_mode || 'both';
7106                            }
7107                        } )
7108                    } );
7109                } );
7110            }
7111            if ( sendEventId != null && ( form_submit_mode === 'both' || form_submit_mode === 'ajax_only' ) ) {
7112                Utils.fireTriggerEvent( sendEventId );
7113            }
7114            sendFormAction( $( event.target ), form_id, sendEventId, disabled_form_action, form_submit_mode );
7115        } );
7116
7117        //WPForm
7118        $( 'form.wpforms-form' ).on( 'wpformsAjaxSubmitSuccess', ( event ) => {
7119
7120            let form_id = $( event.target ).attr( 'data-formid' ),
7121                sendEventId = null,
7122                disabled_form_action = false,
7123                form_submit_mode = 'both';
7124
7125            if ( options.triggerEventTypes.hasOwnProperty( 'wpforms' ) ) {
7126                $.each( options.triggerEventTypes.wpforms, function ( eventId, triggers ) {
7127                    $.each( triggers, function ( index, trigger ) {
7128                        $.each( trigger.forms, function ( i, value ) {
7129                            if ( value == form_id ) {
7130                                sendEventId = eventId;
7131                                disabled_form_action = trigger.disabled_form_action;
7132                                form_submit_mode = trigger.form_submit_mode || 'both';
7133                            }
7134                        } )
7135                    } );
7136                } );
7137            }
7138            if ( sendEventId != null && ( form_submit_mode === 'both' || form_submit_mode === 'ajax_only' ) ) {
7139                Utils.fireTriggerEvent( sendEventId );
7140            }
7141            sendFormAction( $( event.target ), form_id, sendEventId, disabled_form_action, form_submit_mode );
7142        } )
7143
7144        $( document ).on( 'frmFormComplete', function ( event, form, response ) {
7145            const form_id = $( form ).find( 'input[name="form_id"]' ).val();
7146            let sendEventId = null,
7147                disabled_form_action = false,
7148                form_submit_mode = 'both';
7149            if ( options.triggerEventTypes.hasOwnProperty( 'formidable' ) ) {
7150                $.each( options.triggerEventTypes.formidable, function ( eventId, triggers ) {
7151                    $.each( triggers, function ( index, trigger ) {
7152                        $.each( trigger.forms, function ( i, value ) {
7153                            if ( value == form_id ) {
7154                                disabled_form_action = trigger.disabled_form_action;
7155                                sendEventId = eventId;
7156                                form_submit_mode = trigger.form_submit_mode || 'both';
7157                            }
7158                        } )
7159                    } );
7160                } );
7161            }
7162            if ( sendEventId != null && ( form_submit_mode === 'both' || form_submit_mode === 'ajax_only' ) ) {
7163                Utils.fireTriggerEvent( sendEventId );
7164            }
7165            sendFormAction( $( event.target ), form_id, sendEventId, disabled_form_action, form_submit_mode );
7166
7167        } );
7168
7169        // Ninja Forms
7170        $( document ).onFirst( 'nfFormSubmitResponse', function ( event, data ) {
7171            const form_id = data.response.data.form_id;
7172            let sendEventId = null,
7173                disabled_form_action = false,
7174                form_submit_mode = 'both';
7175            if ( options.triggerEventTypes.hasOwnProperty( 'ninjaform' ) ) {
7176                $.each( options.triggerEventTypes.ninjaform, function ( eventId, triggers ) {
7177                    $.each( triggers, function ( index, trigger ) {
7178                        $.each( trigger.forms, function ( i, value ) {
7179                            if ( value == form_id ) {
7180                                disabled_form_action = trigger.disabled_form_action;
7181                                sendEventId = eventId;
7182                                form_submit_mode = trigger.form_submit_mode || 'both';
7183                            }
7184                        } )
7185                    } );
7186                } );
7187            }
7188            if ( sendEventId != null && ( form_submit_mode === 'both' || form_submit_mode === 'ajax_only' ) ) {
7189                Utils.fireTriggerEvent( sendEventId );
7190            }
7191            sendFormAction( $( event.target ), form_id, sendEventId, disabled_form_action, form_submit_mode );
7192        } );
7193
7194
7195        $(document).on('fluentform_submission_success', function ( event, data ) {
7196            if(!data || !data.form){
7197                return;
7198            }
7199            let $form = data.form; // Submitted form
7200            let config = data.config; // Form configuration
7201            let response = data.response; // Server response
7202
7203
7204            let $formItem = $form;
7205            let form_id = config.id;
7206            let sendEventId = null,
7207                disabled_form_action = false,
7208                form_submit_mode = 'both';
7209            if ( options.triggerEventTypes.hasOwnProperty( 'fluentform' ) ) {
7210                $.each( options.triggerEventTypes.fluentform, function ( eventId, triggers ) {
7211                    $.each( triggers, function ( index, trigger ) {
7212                        $.each( trigger.forms, function ( i, value ) {
7213                            if ( value == form_id ) {
7214                                disabled_form_action = trigger.disabled_form_action;
7215                                sendEventId = eventId;
7216                                form_submit_mode = trigger.form_submit_mode || 'both';
7217                            }
7218                        } )
7219                    } );
7220                } );
7221            }
7222
7223            if ( sendEventId != null && ( form_submit_mode === 'both' || form_submit_mode === 'ajax_only' ) ) {
7224                Utils.fireTriggerEvent( sendEventId );
7225            }
7226            sendFormAction( $( event.target ), form_id, sendEventId, disabled_form_action, form_submit_mode );
7227        } );
7228
7229        //WSForm
7230        $( document ).on( 'wsf-submit-complete', ( event, form_object, form_id ) => {
7231            let sendEventId = null,
7232                disabled_form_action = false,
7233                form_submit_mode = 'both';
7234            if ( options.triggerEventTypes.hasOwnProperty( 'wsform' ) ) {
7235                $.each( options.triggerEventTypes.wsform, function ( eventId, triggers ) {
7236                    $.each( triggers, function ( index, trigger ) {
7237                        $.each( trigger.forms, function ( i, value ) {
7238                            if ( value == form_id ) {
7239                                disabled_form_action = trigger.disabled_form_action;
7240                                sendEventId = eventId;
7241                                form_submit_mode = trigger.form_submit_mode || 'both';
7242                            }
7243                        } )
7244                    } );
7245                } );
7246            }
7247
7248            if ( sendEventId != null && ( form_submit_mode === 'both' || form_submit_mode === 'ajax_only' ) ) {
7249                Utils.fireTriggerEvent( sendEventId );
7250            }
7251            sendFormAction( $( event.target ), form_id, sendEventId, disabled_form_action, form_submit_mode );
7252        } )
7253
7254        // Elementor Forms
7255        let forms = document.querySelectorAll( '.elementor-form' );
7256        // Apply the observer to each form
7257        forms.forEach( function ( form ) {
7258            observeElementorForm( form );
7259        } );
7260
7261        // watching Elementor Popup forms
7262        let observer = new MutationObserver( function ( mutationsList, observer ) {
7263            for ( let i = 0; i < mutationsList.length; i++ ) {
7264                let popupForm = document.querySelector( '[class*="elementor-popup"] form' );
7265                if ( popupForm ) {
7266                    observeElementorForm( popupForm );
7267                    observer.disconnect();
7268                    break;
7269                }
7270            }
7271        } );
7272        observer.observe( document.body, { childList: true, subtree: true } );
7273
7274        // load pixel APIs
7275        Utils.loadPixels();
7276
7277        // setup Enrich content
7278        if(Utils.isCheckoutPage()) {
7279            Utils.addCheckoutFields();
7280        }
7281        if(options.woo.hasOwnProperty('woo_view_content_variation_is_selected') && options.woo.woo_view_content_variation_is_selected) {
7282            handleWooViewContentVariation()
7283        }
7284
7285    });
7286
7287
7288    function handleWooViewContentVariation() {
7289        var form = $('form.variations_form');
7290
7291        form.on('change', 'select', function() {
7292            var selectedAttributes = {};
7293            form.find('select').each(function() {
7294                var attributeName = $(this).data('attribute_name') || $(this).attr('name');
7295                var attributeValue = $(this).val();
7296                if (attributeValue) {
7297                    selectedAttributes[attributeName] = attributeValue;
7298                }
7299            });
7300
7301            $.ajax({
7302                url: options.ajaxUrl,
7303                type: 'POST',
7304                data: {
7305                    action: 'get_variation_info',
7306                    product_id: form.data('product_id'), // Передаем ID основного товара
7307                    attributes: selectedAttributes
7308                },
7309                success: function(response) {
7310                    if (response.success) {
7311                        $.each(response.data, function(slug) {
7312                            $.each(response.data[slug], function(index, event) {
7313                                event.isVariationTrigger = true;
7314                                getPixelBySlag(slug).fireEvent(event.name, event);
7315                            });
7316                        });
7317                    } else {
7318                        console.log('Error retrieving data:', response.data);
7319                    }
7320                }
7321            });
7322        });
7323    }
7324    var sendFormAction = function (form_target, formId, customEventId = null, disabled = false, form_submit_mode = 'both'){
7325        // Check submit mode - skip automatic event if reload_only
7326        if (disabled == true || form_submit_mode === 'reload_only' ) {
7327            return;
7328        }
7329        
7330        var params = {
7331            form_id: formId,
7332            text: form_target.find('[type="submit"]').is('input') ? form_target.find('[type="submit"]').val() :
7333                form_target.find('.forminator-button-submit').text() != '' ? form_target.find('.forminator-button-submit').text() :
7334                    form_target.find('[type="submit"]').text()
7335        };
7336
7337        if (options.dynamicEvents.hasOwnProperty("automatic_event_form")) {
7338            var pixels = Object.keys(options.dynamicEvents.automatic_event_form);
7339            for (var i = 0; i < pixels.length; i++) {
7340
7341                if ( disabled && customEventId && typeof options.triggerEvents[customEventId][pixels[i]] !== 'undefined') {
7342                    continue;
7343                }
7344                var event = options.dynamicEvents.automatic_event_form[pixels[i]];
7345                if (pixels[i] === "tiktok" || pixels[i] === "reddit") {
7346                    getPixelBySlag(pixels[i]).fireEvent(event.name, event);
7347                } else {
7348                    Utils.copyProperties(params, event.params)
7349                    Utils.copyProperties(Utils.getRequestParams(), event.params);
7350                    getPixelBySlag(pixels[i]).onFormEvent(event);
7351                }
7352            }
7353        }
7354    }
7355
7356    var setupEmailLinks = function ( disabled_for_pixels = [] ) {
7357        if ( options.dynamicEvents.hasOwnProperty( "automatic_event_email_link" ) ) {
7358            var pixels = Object.keys( options.dynamicEvents.automatic_event_email_link );
7359            for ( var i = 0; i < pixels.length; i++ ) {
7360                if ( disabled_for_pixels.indexOf(pixels[ i ]) === -1 ) {
7361                    var event = Utils.clone( options.dynamicEvents.automatic_event_email_link[ pixels[ i ] ] );
7362                    if ( pixels[ i ] !== 'tiktok' && pixels[ i ] !== 'reddit' ) {
7363                        Utils.copyProperties( Utils.getRequestParams(), event.params );
7364                    }
7365                    getPixelBySlag( pixels[ i ] ).fireEvent( event.name, event );
7366                }
7367            }
7368        }
7369    }
7370
7371    //Elementor Forms Observer
7372    var observeElementorForm = function ( form ) {
7373        let observer = new MutationObserver( function ( mutations ) {
7374
7375            for ( let i = 0; i < mutations.length; i++ ) {
7376                let mutation = mutations[ i ];
7377
7378                if ( mutation.type === 'childList' || mutation.type === 'attributes' ) {
7379                    if ( $( form ).find( '.elementor-message-success' ).length > 0 ) {
7380
7381                        let form_id = $( form ).attr( 'id' );
7382                        if ( !form_id ) {
7383                            form_id = $( form ).find( 'input[name="form_id"]' ).val();
7384                        }
7385
7386                        let sendEventId = null,
7387                            disabled_form_action = false,
7388                            form_submit_mode = 'both';
7389                        if ( options.triggerEventTypes.hasOwnProperty( 'elementor_form' ) ) {
7390                            $.each( options.triggerEventTypes.elementor_form, function ( eventId, triggers ) {
7391                                $.each( triggers, function ( index, trigger ) {
7392                                    $.each( trigger.forms, function ( i, value ) {
7393                                        if ( value == form_id ) {
7394                                            disabled_form_action = trigger.disabled_form_action;
7395                                            sendEventId = eventId;
7396                                            form_submit_mode = trigger.form_submit_mode || 'both';
7397                                        }
7398                                    })
7399                                } );
7400                            } );
7401                        }
7402                        if ( sendEventId != null && ( form_submit_mode === 'both' || form_submit_mode === 'ajax_only' ) ) {
7403                            Utils.fireTriggerEvent( sendEventId );
7404                        }
7405                        sendFormAction( $( event.target ), form_id, sendEventId, disabled_form_action, form_submit_mode );
7406
7407                        observer.disconnect();
7408                        break;
7409                    }
7410                }
7411            }
7412        } );
7413
7414        // Start observing the form for changes
7415        observer.observe( form, {
7416            attributes: true,
7417            childList: true,
7418            subtree: true
7419        } );
7420    }
7421
7422}(jQuery, pysOptions);
7423
7424
7425function pys_generate_token() {
7426    return ([1e7]+-1e3+-4e3+-8e3+-1e11).replace(/[018]/g, c =>
7427        (c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16)
7428    );
7429}
7430function getBundlePriceOnSingleProduct(data) {
7431    var items_sum = 0;
7432    jQuery(".bundle_form .bundled_product").each(function(index){
7433        var id = jQuery(this).find(".cart").data("bundled_item_id");
7434        var item_price = data.prices[id];
7435        var item_quantity = jQuery(this).find(".bundled_qty").val();
7436        if(!jQuery(this).hasClass("bundled_item_optional") ||
7437            jQuery(this).find(".bundled_product_optional_checkbox input").prop('checked')) {
7438            items_sum += item_price*item_quantity;
7439        }
7440    });
7441    return items_sum;
7442}
7443function getUrlParameter(sParam) {
7444    var sPageURL = window.location.search.substring(1),
7445        sURLVariables = sPageURL.split('&'),
7446        sParameterName,
7447        i;
7448
7449    for (i = 0; i < sURLVariables.length; i++) {
7450        sParameterName = sURLVariables[i].split('=');
7451
7452        if (sParameterName[0] === sParam) {
7453            return sParameterName[1] === undefined ? true : decodeURIComponent(sParameterName[1]);
7454        }
7455    }
7456    return false;
7457};
7458function inArray(needle, haystack) {
7459    var length = haystack.length;
7460    for(var i = 0; i < length; i++) {
7461        if(haystack[i] == needle) return true;
7462    }
7463    return false;
7464}
7465
7466function getCookieYes(key) {
7467    const cookiesObj = document.cookie
7468        .split(";")
7469        .reduce((ac, cv) => {
7470            const [k, v] = cv.split("=");
7471            if (k && v) ac[k.trim()] = v;
7472            return ac;
7473        }, {});
7474    const consentCookie = cookiesObj["cookieyes-consent"] || cookiesObj["wt_consent"];
7475    if (!consentCookie) return undefined;
7476    const { [key]: value } = consentCookie
7477        .split(",")
7478        .reduce((obj, pair) => {
7479            const [k, v] = pair.split(":");
7480            if (k && v) obj[k] = v;
7481            return obj;
7482        }, {});
7483    return value;
7484}
7485
7486function getRootDomain(useSubdomain = false) {
7487    const hostname = window.location.hostname; // Get the current hostname
7488    // Check if tldjs is defined before using it
7489    if (typeof tldjs === "undefined") {
7490        console.warn("tldjs is not defined");
7491        return hostname; // Return hostname as a fallback
7492    }
7493
7494    const rootDomain = tldjs.getDomain(hostname); // Use tldjs to extract the root domain
7495
7496    // Return the root domain with or without a leading dot based on useSubdomain
7497    return rootDomain ? (useSubdomain ? '.' + rootDomain : rootDomain) : hostname;
7498}

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.