PageSourceSearch

https://www.bartonenergy.it/wp-content/plugins/pixelyoursite-pro/dist/scripts/public.js?ver=12.5.0.2

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

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.