PageSourceSearch

https://matractrend.hu/wp-content/plugins/pixelyoursite-pro/dist/scripts/public.js?ver=12.4.1.2

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

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.