PageSourceSearch

https://tesseract.academy/wp-content/plugins/pixelyoursite-pro/dist/scripts/public.js?ver=12.3.4

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

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.