PageSourceSearch

https://orcawhalewatch.com/wp-content/plugins/pixelyoursite/dist/scripts/public.js?js_icv=5a08ad

js orcawhalewatch.com collected 2026-10-03 21:26:12 UTC 103,990 bytes, 2,677 lines download raw bytes

1/* global pysOptions */
2
3// https://bitbucket.org/pixelyoursite/pys_pro_7/issues/7/possible-ie-11-error
4// https://tc39.github.io/ecma262/#sec-array.prototype.includes
5if (!Array.prototype.includes) {
6    Object.defineProperty(Array.prototype, 'includes', {
7        value: function (searchElement, fromIndex) {
8
9            if (this == null) {
10                throw new TypeError('"this" is null or not defined');
11            }
12
13            // 1. Let O be ? ToObject(this value).
14            var o = Object(this);
15
16            // 2. Let len be ? ToLength(? Get(O, "length")).
17            var len = o.length >>> 0;
18
19            // 3. If len is 0, return false.
20            if (len === 0) {
21                return false;
22            }
23
24            // 4. Let n be ? ToInteger(fromIndex).
25            //    (If fromIndex is undefined, this step produces the value 0.)
26            var n = fromIndex | 0;
27
28            // 5. If n ≥ 0, then
29            //  a. Let k be n.
30            // 6. Else n < 0,
31            //  a. Let k be len + n.
32            //  b. If k < 0, let k be 0.
33            var k = Math.max(n >= 0 ? n : len - Math.abs(n), 0);
34
35            function sameValueZero(x, y) {
36                return x === y || (typeof x === 'number' && typeof y === 'number' && isNaN(x) && isNaN(y));
37            }
38
39            // 7. Repeat, while k < len
40            while (k < len) {
41                // a. Let elementK be the result of ? Get(O, ! ToString(k)).
42                // b. If SameValueZero(searchElement, elementK) is true, return true.
43                if (sameValueZero(o[k], searchElement)) {
44                    return true;
45                }
46                // c. Increase k by 1.
47                k++;
48            }
49
50            // 8. Return false
51            return false;
52        }
53    });
54}
55
56!function ($, options) {
57
58    if (options.debug) {
59        console.log('PYS:', options);
60    }
61
62    var dummyPinterest = function () {
63
64        /**
65         * Public API
66         */
67        return {
68
69            isEnabled: function () {
70            },
71
72            disable: function () {
73            },
74
75            loadPixel: function () {
76            },
77
78            fireEvent: function (name, data) {
79                return false;
80            },
81
82            onCommentEvent: function () {
83            },
84
85            onDownloadEvent: function (params) {
86            },
87
88            onFormEvent: function (params) {
89            },
90
91            onWooAddToCartOnButtonEvent: function (product_id) {
92            },
93
94            onWooAddToCartOnSingleEvent: function (product_id, qty, is_variable, is_external, $form) {
95            },
96
97            onWooRemoveFromCartEvent: function (cart_item_hash) {
98            },
99
100            onEddAddToCartOnButtonEvent: function (download_id, price_index, qty) {
101            },
102
103            onEddRemoveFromCartEvent: function (item) {
104            },
105            onPageScroll: function (event) {},
106            onTime: function (event) {
107
108            },
109
110        }
111
112    }();
113
114    var dummyBing = function () {
115
116        /**
117         * Public API
118         */
119        return {
120
121            isEnabled: function () {
122            },
123
124            disable: function () {
125            },
126
127            loadPixel: function () {
128            },
129
130            fireEvent: function (name, data) {
131                return false;
132            },
133
134            onAdSenseEvent: function () {
135            },
136
137            onClickEvent: function (params) {
138            },
139
140            onWatchVideo: function (params) {
141            },
142
143            onCommentEvent: function () {
144            },
145
146            onFormEvent: function (params) {
147            },
148
149            onDownloadEvent: function (params) {
150            },
151
152            onWooAddToCartOnButtonEvent: function (product_id) {
153            },
154
155            onWooAddToCartOnSingleEvent: function (product_id, qty, is_variable, is_external, $form) {
156            },
157
158            onWooRemoveFromCartEvent: function (cart_item_hash) {
159            },
160
161            onWooAffiliateEvent: function (product_id) {
162            },
163
164            onWooPayPalEvent: function () {
165            },
166
167            onEddAddToCartOnButtonEvent: function (download_id, price_index, qty) {
168            },
169
170            onEddRemoveFromCartEvent: function (item) {
171            },
172
173            onPageScroll: function (event) {
174            },
175
176            onTime: function (event) {
177            },
178
179        }
180
181    }();
182
183    var Utils = function (options) {
184
185        var Pinterest = dummyPinterest;
186
187        var Bing = dummyBing;
188
189        var gtag_loaded = false;
190
191        let isNewSession = checkSession();
192
193        var utmTerms = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content'];
194
195        var utmId = ['fbadid', 'gadid', 'padid', 'bingid'];
196
197        function validateEmail(email) {
198            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,}))$/;
199            return re.test(email);
200        }
201        function getDomain(url) {
202
203            url = url.replace(/(https?:\/\/)?(www.)?/i, '');
204
205            if (url.indexOf('/') !== -1) {
206                return url.split('/')[0];
207            }
208
209            return url;
210        }
211        function loadPixels() {
212
213            if (!options.gdpr.all_disabled_by_api) {
214
215                if (!options.gdpr.facebook_disabled_by_api) {
216                    Facebook.loadPixel();
217                }
218
219                if (!options.gdpr.analytics_disabled_by_api) {
220                    Analytics.loadPixel();
221                }
222
223                if (!options.gdpr.pinterest_disabled_by_api) {
224                    Pinterest.loadPixel();
225                }
226
227                if (!options.gdpr.bing_disabled_by_api) {
228                    Bing.loadPixel();
229                }
230            }
231            if (options.gdpr.consent_magic_integration_enabled && typeof CS_Data !== "undefined") {
232                if (typeof CS_Data.cs_google_analytics_consent_mode !== "undefined" && CS_Data.cs_google_analytics_consent_mode == 1) {
233                    Analytics.loadPixel();
234                }
235            }
236
237        }
238
239        function checkSession() {
240            let duration = options.last_visit_duration * 60000
241            if( Cookies.get('pys_start_session') === undefined ||
242                Cookies.get('pys_session_limit') === undefined) {
243                var now = new Date();
244                now.setTime(now.getTime() + duration);
245                Cookies.set('pys_session_limit', true,{ expires: now })
246                Cookies.set('pys_start_session', true)
247                return true
248            }
249            return false
250
251        }
252
253        function getTrafficSource() {
254
255            try {
256
257                let referrer = document.referrer.toString(),
258                    source;
259
260                let direct = referrer.length === 0;
261                let internal = direct ? false : referrer.indexOf(options.siteUrl) === 0;
262                let external = !direct && !internal;
263
264                if (external === false) {
265                    source = 'direct';
266                } else {
267                    source = referrer;
268                }
269
270                if (source !== 'direct') {
271                    // leave only domain (Issue #70)
272                    return getDomain(source);
273                } else {
274                    return source;
275                }
276
277            } catch (e) {
278                console.error(e);
279                return 'direct';
280            }
281
282        }
283
284        /**
285         * Return query variables object with where property name is query variable
286         * and property value is query variable value.
287         */
288        function getQueryVars() {
289
290            try {
291
292                var result = {},
293                    tmp = [];
294
295                window.location.search
296                    .substr(1)
297                    .split("&")
298                    .forEach(function (item) {
299
300                        tmp = item.split('=');
301
302                        if (tmp.length > 1) {
303                            result[tmp[0]] = tmp[1];
304                        }
305
306                    });
307
308                return result;
309
310            } catch (e) {
311                console.error(e);
312                return {};
313            }
314
315        }
316
317
318        function getUTMId(useLast = false) {
319            try {
320                let cookiePrefix = 'pys_'
321                let terms = [];
322                if (useLast) {
323                    cookiePrefix = 'last_pys_'
324                }
325                $.each(utmId, function (index, name) {
326                    if (Cookies.get(cookiePrefix + name)) {
327                        terms[name] = Cookies.get(cookiePrefix + name)
328                    }
329                });
330                return terms;
331            } catch (e) {
332                console.error(e);
333                return [];
334            }
335        }
336        /**
337         * Return UTM terms from request query variables or from cookies.
338         */
339        function getUTMs(useLast = false) {
340
341            try {
342                let cookiePrefix = 'pys_'
343                if(useLast) {
344                    cookiePrefix = 'last_pys_'
345                }
346                let terms = [];
347                $.each(utmTerms, function (index, name) {
348                    if (Cookies.get(cookiePrefix + name)) {
349                        let value = Cookies.get(cookiePrefix + name);
350                        terms[name] = filterEmails(value); // do not allow email in request params (Issue #70)
351                    }
352                });
353
354                return terms;
355
356            } catch (e) {
357                console.error(e);
358                return [];
359            }
360
361        }
362
363        function getDateTime() {
364            var dateTime = new Array();
365            var date = new Date(),
366                days = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'],
367                months = ['January', 'February', 'March', 'April', 'May', 'June',
368                    'July', 'August', 'September', 'October', 'November', 'December'
369                ],
370                hours = ['00-01', '01-02', '02-03', '03-04', '04-05', '05-06', '06-07', '07-08',
371                    '08-09', '09-10', '10-11', '11-12', '12-13', '13-14', '14-15', '15-16', '16-17',
372                    '17-18', '18-19', '19-20', '20-21', '21-22', '22-23', '23-24'
373                ];
374            dateTime.push(hours[date.getHours()]);
375            dateTime.push(days[date.getDay()]);
376            dateTime.push(months[date.getMonth()]);
377            return dateTime;
378        }
379
380        function filterEmails(value) {
381            return validateEmail(value) ? undefined : value;
382        }
383
384        /**
385         * PUBLIC API
386         */
387        return {
388            PRODUCT_SIMPLE : 0,
389            PRODUCT_VARIABLE : 1,
390            PRODUCT_BUNDLE : 2,
391            PRODUCT_GROUPED : 3,
392
393            fireEventForAllPixel:function(functionName,events){
394                if (events.hasOwnProperty(Facebook.tag()))
395                    Facebook[functionName](events[Facebook.tag()]);
396                if (events.hasOwnProperty(Analytics.tag()))
397                    Analytics[functionName](events[Analytics.tag()]);
398                if (events.hasOwnProperty(Pinterest.tag()))
399                    Pinterest[functionName](events[Pinterest.tag()]);
400                if (events.hasOwnProperty(Bing.tag()))
401                    Bing[functionName](events[Bing.tag()]);
402            },
403
404            setupPinterestObject: function () {
405                Pinterest = window.pys.Pinterest || Pinterest;
406                return Pinterest;
407            },
408
409            setupBingObject: function () {
410                Bing = window.pys.Bing || Bing;
411                return Bing;
412            },
413
414            // Clone all object members to another and return it
415            copyProperties: function (from, to) {
416                for (var key in from) {
417                    if("function" == typeof from[key]) {
418                        continue;
419                    }
420                    to[key] = from[key];
421                }
422                return to;
423            },
424
425            manageCookies: function () {
426                let expires = parseInt(options.cookie_duration); //  days
427                let queryVars = getQueryVars();
428                let landing = window.location.href.split('?')[0];
429                try {
430                    // save data for first visit
431                    if(Cookies.get('pys_first_visit') === undefined) {
432                        Cookies.set('pys_first_visit', true, { expires: expires });
433                        Cookies.set('pysTrafficSource', getTrafficSource(), { expires: expires });
434                        Cookies.set('pys_landing_page',landing,{ expires: expires });
435                        $.each(utmTerms, function (index, name) {
436                            if (queryVars.hasOwnProperty(name)) {
437                                Cookies.set('pys_' + name, queryVars[name], { expires: expires });
438                            } else {
439                                Cookies.remove('pys_' + name)
440                            }
441                        });
442                        $.each(utmId,function(index,name) {
443                            if (queryVars.hasOwnProperty(name)) {
444                                Cookies.set('pys_' + name, queryVars[name], { expires: expires });
445                            } else {
446                                Cookies.remove('pys_' + name)
447                            }
448                        })
449                    }
450
451                    // save data for last visit if it new session
452                    if(isNewSession) {
453                        Cookies.set('last_pysTrafficSource', getTrafficSource(), { expires: expires });
454                        $.each(utmTerms, function (index, name) {
455                            if (queryVars.hasOwnProperty(name)) {
456                                Cookies.set('last_pys_' + name, queryVars[name], { expires: expires });
457                            } else {
458                                Cookies.remove('last_pys_' + name)
459                            }
460                        });
461                        $.each(utmId,function(index,name) {
462                            if (queryVars.hasOwnProperty(name)) {
463                                Cookies.set('last_pys_' + name, queryVars[name], { expires: expires });
464                            } else {
465                                Cookies.remove('last_pys_' + name)
466                            }
467                        })
468                        Cookies.set('last_pys_landing_page',landing,{ expires: expires });
469                    }
470                } catch (e) {
471                    console.error(e);
472                }
473            },
474            // clone object
475            clone: function(obj) {
476                var copy;
477
478                // Handle the 3 simple types, and null or undefined
479                if (null == obj || "object" != typeof obj) return obj;
480
481                // Handle Date
482                if (obj instanceof Date) {
483                    copy = new Date();
484                    copy.setTime(obj.getTime());
485                    return copy;
486                }
487
488                // Handle Array
489                if (obj instanceof Array) {
490                    copy = [];
491                    for (var i = 0, len = obj.length; i < len; i++) {
492                        if("function" == typeof obj[i]) {
493                            continue;
494                        }
495                        copy[i] = Utils.clone(obj[i]);
496                    }
497                    return copy;
498                }
499
500                // Handle Object
501                if (obj instanceof Object) {
502                    copy = {};
503                    for (var attr in obj) {
504                        if (obj.hasOwnProperty(attr)) {
505                            if("function" == typeof obj[attr]) {
506                                continue;
507                            }
508                            copy[attr] = Utils.clone(obj[attr]);
509                        }
510                    }
511                    return copy;
512                }
513
514                return obj;
515            },
516
517            // Returns array of elements with given tag name
518            getTagsAsArray: function (tag) {
519                return [].slice.call(document.getElementsByTagName(tag));
520            },
521
522            getRequestParams: function () {
523                return [];
524            },
525
526            /**
527             * CUSTOM EVENTS
528             */
529
530            setupMouseOverClickEvents: function (eventId, triggers) {
531
532                // Non-default binding used to avoid situations when some code in external js
533                // stopping events propagation, eg. returns false, and our handler will never called
534                document.addEventListener('mouseover', function(event) {
535                    var matchedElements = Array.from(document.querySelectorAll(triggers));
536                    if (matchedElements.includes(event.target)) {
537                        if (event.target.classList.contains('pys-mouse-over-' + eventId)) {
538                            return true;
539                        } else {
540                            event.target.classList.add('pys-mouse-over-' + eventId);
541                        }
542
543                        Utils.fireTriggerEvent(eventId);
544                    }
545                });
546
547            },
548
549            setupCSSClickEvents: function (eventId, triggers) {
550                // Non-default binding used to avoid situations when some code in external js
551                // stopping events propagation, eg. returns false, and our handler will never called
552                document.addEventListener('click', function(event) {
553                    var matchedElements = Array.from(document.querySelectorAll(triggers));
554                    if (matchedElements.includes(event.target)) {
555                        console.log(event.target)
556                        Utils.fireTriggerEvent(eventId);
557                    }
558                }, true);
559            },
560
561            setupURLClickEvents: function () {
562
563                // Non-default binding used to avoid situations when some code in external js
564                // stopping events propagation, eg. returns false, and our handler will never called
565                $('a[data-pys-event-id]').onFirst('click', function (evt) {
566
567                    $(this).attr('data-pys-event-id').split(',').forEach(function (eventId) {
568
569                        eventId = parseInt(eventId);
570
571                        if (isNaN(eventId) === false) {
572                            Utils.fireTriggerEvent(eventId);
573                        }
574
575                    });
576
577                });
578
579
580            },
581
582            setupScrollPosEvents: function (eventId, triggers) {
583
584                var scrollPosThresholds = {},
585                    docHeight = $(document).height() - $(window).height();
586
587                // convert % to absolute positions
588                $.each(triggers, function (index, scrollPos) {
589
590                    // convert % to pixels
591                    scrollPos = docHeight * scrollPos / 100;
592                    scrollPos = Math.round(scrollPos);
593
594                    scrollPosThresholds[scrollPos] = eventId;
595
596                });
597
598                $(document).on("scroll",function () {
599
600                    var scrollPos = $(window).scrollTop();
601
602                    $.each(scrollPosThresholds, function (threshold, eventId) {
603
604                        // position has not reached yes
605                        if (scrollPos <= threshold) {
606                            return true;
607                        }
608
609                        // fire event only once
610                        if (eventId === null) {
611                            return true;
612                        } else {
613                            scrollPosThresholds[threshold] = null;
614                        }
615
616                        Utils.fireTriggerEvent(eventId);
617
618                    });
619
620                });
621
622
623            },
624            setupCommentEvents : function (eventId,triggers) {
625                $('form.comment-form').on("submit",function () {
626                    Utils.fireTriggerEvent(eventId);
627                });
628            },
629
630            /**
631             * Events
632             */
633
634            fireTriggerEvent: function (eventId) {
635
636                if (!options.triggerEvents.hasOwnProperty(eventId)) {
637                    return;
638                }
639
640                var event = {};
641                var events = options.triggerEvents[eventId];
642
643                if (events.hasOwnProperty('facebook')) {
644                    event = events.facebook;
645                    Facebook.fireEvent(event.name, event);
646                }
647
648                if (events.hasOwnProperty('ga')) {
649                    event = events.ga;
650                    Analytics.fireEvent(event.name, event);
651                }
652
653                if (events.hasOwnProperty('pinterest')) {
654                    event = events.pinterest;
655                    Pinterest.fireEvent(event.name, event);
656                }
657
658                if (events.hasOwnProperty('bing')) {
659                    event = events.bing;
660                    Bing.fireEvent(event.name, event);
661                }
662            },
663
664            fireStaticEvents: function (pixel) {
665
666                if (options.staticEvents.hasOwnProperty(pixel)) {
667
668                    $.each(options.staticEvents[pixel], function (eventName, events) {
669                        $.each(events, function (index, eventData) {
670
671                            eventData.fired = eventData.fired || false;
672
673                            if (!eventData.fired) {
674
675                                var fired = false;
676
677                                // fire event
678                                if ('facebook' === pixel) {
679                                    fired = Facebook.fireEvent(eventData.name, eventData);
680                                } else if ('ga' === pixel) {
681                                    fired = Analytics.fireEvent(eventData.name, eventData);
682                                } else if ('pinterest' === pixel) {
683                                    fired = Pinterest.fireEvent(eventData.name, eventData);
684                                } else if ('bing' === pixel) {
685                                    fired = Bing.fireEvent(eventData.name, eventData);
686                                }
687
688                                // prevent event double event firing
689                                eventData.fired = fired;
690
691                            }
692
693                        });
694                    });
695
696                }
697
698            },
699
700            /**
701             * Load tag's JS
702             *
703             * @link: https://developers.google.com/analytics/devguides/collection/gtagjs/
704             * @link: https://developers.google.com/analytics/devguides/collection/gtagjs/custom-dims-mets
705             */
706            loadGoogleTag: function (id) {
707
708                if (!gtag_loaded) {
709
710                    (function (window, document, src) {
711                        var a = document.createElement('script'),
712                            m = document.getElementsByTagName('script')[0];
713                        a.async = 1;
714                        a.src = src;
715                        m.parentNode.insertBefore(a, m);
716                    })(window, document, '//www.googletagmanager.com/gtag/js?id=' + id);
717
718                    window.dataLayer = window.dataLayer || [];
719                    window.gtag = window.gtag || function gtag() {
720                        dataLayer.push(arguments);
721                    };
722
723                    gtag('js', new Date());
724
725                    gtag_loaded = true;
726
727                }
728
729            },
730
731            /**
732             * GDPR
733             */
734
735            loadPixels: function () {
736
737                if (options.gdpr.ajax_enabled && !options.gdpr.consent_magic_integration_enabled) {
738
739                    // retrieves actual PYS GDPR filters values which allow to avoid cache issues
740                    $.get({
741                        url: options.ajaxUrl,
742                        dataType: 'json',
743                        data: {
744                            action: 'pys_get_gdpr_filters_values'
745                        },
746                        success: function (res) {
747
748                            if (res.success) {
749
750                                options.gdpr.all_disabled_by_api = res.data.all_disabled_by_api;
751                                options.gdpr.facebook_disabled_by_api = res.data.facebook_disabled_by_api;
752                                options.gdpr.analytics_disabled_by_api = res.data.analytics_disabled_by_api;
753                                options.gdpr.google_ads_disabled_by_api = res.data.google_ads_disabled_by_api;
754                                options.gdpr.pinterest_disabled_by_api = res.data.pinterest_disabled_by_api;
755                                options.gdpr.bing_disabled_by_api = res.data.bing_disabled_by_api;
756
757                            }
758
759                            loadPixels();
760
761                        }
762                    });
763
764                } else {
765                    loadPixels();
766                }
767
768            },
769
770            consentGiven: function (pixel) {
771
772                /**
773                 * ConsentMagic
774                 */
775                if (options.gdpr.consent_magic_integration_enabled && typeof CS_Data !== "undefined" ) {
776
777                    var test_prefix = CS_Data.test_prefix;
778                    if ((typeof CS_Data.cs_google_analytics_consent_mode !== "undefined" && CS_Data.cs_google_analytics_consent_mode == 1) && pixel == 'analytics') {
779                        return true;
780                    }
781                    if ((typeof CS_Data.cs_google_ads_consent_mode !== "undefined" && CS_Data.cs_google_ads_consent_mode == 1) && pixel == 'google_ads') {
782                        return true;
783                    }
784
785                    if ( CS_Data.cs_cache_enabled == 1 ) {
786                        var substring = "cs_enabled_cookie_term";
787                        var theCookies = document.cookie.split(';');
788
789                        for (var i = 1 ; i <= theCookies.length; i++) {
790                            if ( theCookies[ i - 1 ].indexOf( substring ) !== -1 ) {
791                                var categoryCookie = theCookies[ i - 1 ].replace( 'cs_enabled_cookie_term' + test_prefix + '_', '' );
792                                categoryCookie = Number( categoryCookie.replace( /\D+/g, "" ) );
793                                var cs_cookie_val = Cookies.get( 'cs_enabled_cookie_term' + test_prefix + '_' + categoryCookie );
794
795                                if ( categoryCookie === CS_Data.cs_script_cat.facebook && pixel == 'facebook' ) {
796                                    if ( cs_cookie_val == 'yes' ) {
797                                        return true;
798                                    } else {
799                                        return false;
800                                    }
801                                } else if ( categoryCookie === CS_Data.cs_script_cat.bing && pixel == 'bing' ) {
802                                    if ( cs_cookie_val == 'yes' ) {
803                                        return true;
804                                    } else {
805                                        return false;
806                                    }
807                                } else if ( categoryCookie === CS_Data.cs_script_cat.analytics && pixel == 'analytics' ) {
808                                    if ( cs_cookie_val == 'yes' ) {
809                                        return true;
810                                    } else {
811                                        return false;
812                                    }
813                                } else if ( categoryCookie === CS_Data.cs_script_cat.gads && pixel == 'google_ads' ) {
814                                    if ( cs_cookie_val == 'yes' ) {
815                                        return true;
816                                    } else {
817                                        return false;
818                                    }
819                                } else if ( categoryCookie === CS_Data.cs_script_cat.pinterest && pixel == 'pinterest' ) {
820                                    if ( cs_cookie_val == 'yes' ) {
821                                        return true;
822                                    } else {
823                                        return false;
824                                    }
825                                } else if ( categoryCookie === CS_Data.cs_script_cat.tiktok && pixel == 'tiktok' ) {
826                                    if ( cs_cookie_val == 'yes' ) {
827                                        return true;
828                                    } else {
829                                        return false;
830                                    }
831                                }
832                            }
833                        }
834                    } else {
835                        var cs_cookie = Cookies.get('cs_viewed_cookie_policy'+test_prefix);
836                        if (typeof cs_cookie === 'undefined' || cs_cookie === 'yes') {
837                            return true;
838                        }
839                    }
840
841                    return false;
842
843                }
844
845                /**
846                 * Real Cookie Banner
847                 */
848                if(options.gdpr.real_cookie_banner_integration_enabled) {
849                    var consentApi = window.consentApi;
850                    if (consentApi) {
851                        switch (pixel) {
852                            case "analytics":
853                                return consentApi.consentSync("http", "_ga", "*").cookieOptIn;
854                            case "facebook":
855                                return consentApi.consentSync("http", "_fbp", "*").cookieOptIn;
856                            case "pinterest":
857                                return consentApi.consentSync("http", "_pinterest_sess", ".pinterest.com").cookieOptIn;
858                            default:
859                                return true;
860                        }
861                    }
862                }
863
864                /**
865                 * Cookiebot
866                 */
867                if (options.gdpr.cookiebot_integration_enabled && typeof Cookiebot !== 'undefined') {
868
869                    var cookiebot_consent_category = options.gdpr['cookiebot_' + pixel + '_consent_category'];
870
871                    if (options.gdpr[pixel + '_prior_consent_enabled']) {
872                        if (Cookiebot.consented === false || Cookiebot.consent[cookiebot_consent_category]) {
873                            return true;
874                        }
875                    } else {
876                        if (Cookiebot.consent[cookiebot_consent_category]) {
877                            return true;
878                        }
879                    }
880
881                    return false;
882
883                }
884
885                /**
886                 * Cookie Notice
887                 */
888                if (options.gdpr.cookie_notice_integration_enabled && typeof cnArgs !== 'undefined') {
889
890                    var cn_cookie = Cookies.get(cnArgs.cookieName);
891
892                    if (options.gdpr[pixel + '_prior_consent_enabled']) {
893                        if (typeof cn_cookie === 'undefined' || cn_cookie === 'true') {
894                            return true;
895                        }
896                    } else {
897                        if (cn_cookie === 'true') {
898                            return true;
899                        }
900                    }
901
902                    return false;
903
904                }
905
906                /**
907                 * Cookie Law Info
908                 */
909                if (options.gdpr.cookie_law_info_integration_enabled) {
910
911                    var cli_cookie = Cookies.get('viewed_cookie_policy');
912
913                    if (options.gdpr[pixel + '_prior_consent_enabled']) {
914                        if (typeof cli_cookie === 'undefined' || cli_cookie === 'yes') {
915                            return true;
916                        }
917                    } else {
918                        if (cli_cookie === 'yes') {
919                            return true;
920                        }
921                    }
922
923                    return false;
924
925                }
926
927                return true;
928
929            },
930
931            setupGdprCallbacks: function () {
932                /**
933                 * ConsentMagic
934                 */
935                if (options.gdpr.consent_magic_integration_enabled && typeof CS_Data !== "undefined") {
936                    var test_prefix = CS_Data.test_prefix,
937                        cs_refresh_after_consent = false,
938                        substring = "cs_enabled_cookie_term";
939
940                    if (CS_Data.cs_refresh_after_consent == 1) {
941                        cs_refresh_after_consent = CS_Data.cs_refresh_after_consent;
942                    }
943
944                    if (!cs_refresh_after_consent) {
945                        var theCookies = document.cookie.split(';');
946                        for (var i = 1 ; i <= theCookies.length; i++) {
947                            if (theCookies[i-1].indexOf(substring) !== -1) {
948                                var categoryCookie = theCookies[i-1].replace('cs_enabled_cookie_term'+test_prefix+'_','');
949                                categoryCookie = Number(categoryCookie.replace(/\D+/g,""));
950                                var cs_cookie_val = Cookies.get('cs_enabled_cookie_term'+test_prefix+'_'+categoryCookie);
951                                if(cs_cookie_val == 'yes') {
952                                    if (categoryCookie === CS_Data.cs_script_cat.facebook) {
953                                        Facebook.loadPixel();
954                                    } 
955                                    
956                                    if (categoryCookie === CS_Data.cs_script_cat.bing) {
957                                        Bing.loadPixel();
958                                    }
959
960                                    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)) {
961
962                                        Analytics.loadPixel();
963                                    }
964                                    
965                                     if (categoryCookie === CS_Data.cs_script_cat.pinterest) {
966                                        Pinterest.loadPixel();
967                                    }
968                                } else {
969                                    if (categoryCookie === CS_Data.cs_script_cat.facebook) {
970                                        Facebook.disable();
971                                    } 
972                                    
973                                     if (categoryCookie === CS_Data.cs_script_cat.bing) {
974                                        Bing.disable();
975                                    }
976                                    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)) {
977                                        Analytics.disable();
978                                    }
979                                    
980                                     if (categoryCookie === CS_Data.cs_script_cat.pinterest) {
981                                        Pinterest.disable();
982                                    }
983                                }
984                                if (Cookies.get('cs_enabled_advanced_matching') == 'yes') {
985                                    Facebook.loadPixel();
986                                }
987                            }
988                        }
989
990                        $(document).on('click','.cs_action_btn',function(e) {
991                            e.preventDefault();
992                            var elm = $(this),
993                                button_action = elm.attr('data-cs_action');
994
995                            if(button_action === 'allow_all') {
996                                Facebook.loadPixel();
997                                Bing.loadPixel();
998                                Analytics.loadPixel();
999                                Pinterest.loadPixel();
1000                            } else if(button_action === 'disable_all') {
1001                                Facebook.disable();
1002                                Bing.disable();
1003                                if(CS_Data.cs_google_analytics_consent_mode == 0 || typeof CS_Data.cs_google_analytics_consent_mode == "undefined")
1004                                {
1005                                    Analytics.disable();
1006                                }
1007                                Pinterest.disable();
1008                            }
1009                        });
1010                    }
1011                }
1012                /**
1013                 * Real Cookie Banner
1014                 */
1015                if(options.gdpr.real_cookie_banner_integration_enabled) {
1016                    var consentApi = window.consentApi;
1017                    if (consentApi) {
1018                        consentApi.consent("http", "_ga", "*")
1019                            .then(Analytics.loadPixel.bind(Analytics), Analytics.disable.bind(Analytics));
1020                        consentApi.consent("http", "_fbp", "*")
1021                            .then(Facebook.loadPixel.bind(Facebook), Facebook.disable.bind(Facebook));
1022                        consentApi.consent("http", "_pinterest_sess", ".pinterest.com")
1023                            .then(Pinterest.loadPixel.bind(Pinterest), Pinterest.disable.bind(Pinterest));
1024                    }
1025                }
1026                /**
1027                 * Cookiebot
1028                 */
1029                if (options.gdpr.cookiebot_integration_enabled && typeof Cookiebot !== 'undefined') {
1030
1031                    window.addEventListener("CookiebotOnConsentReady", function() {
1032                        if (Cookiebot.consent.marketing) {
1033                            Facebook.loadPixel();
1034                            Bing.loadPixel();
1035                            Pinterest.loadPixel();
1036
1037                        }
1038                        if (Cookiebot.consent.statistics) {
1039                            Analytics.loadPixel();
1040                        }
1041                        if (!Cookiebot.consent.marketing) {
1042                            Facebook.disable();
1043                            Pinterest.disable();
1044                            Bing.disable()
1045                        }
1046                        if (!Cookiebot.consent.statistics) {
1047                            Analytics.disable();
1048                        }
1049                    });
1050
1051                }
1052
1053                /**
1054                 * Cookie Notice
1055                 */
1056                if (options.gdpr.cookie_notice_integration_enabled) {
1057
1058                    $(document).onFirst('click', '.cn-set-cookie', function () {
1059
1060                        if ($(this).data('cookie-set') === 'accept') {
1061                            Facebook.loadPixel();
1062                            Analytics.loadPixel();
1063                            Pinterest.loadPixel();
1064                            Bing.loadPixel();
1065                        } else {
1066                            Facebook.disable();
1067                            Analytics.disable();
1068                            Pinterest.disable();
1069                            Bing.disable();
1070                        }
1071
1072                    });
1073
1074                    $(document).onFirst('click', '.cn-revoke-cookie', function () {
1075                        Facebook.disable();
1076                        Analytics.disable();
1077                        Pinterest.disable();
1078                        Bing.disable();
1079                    });
1080
1081                }
1082
1083                /**
1084                 * Cookie Law Info
1085                 */
1086                if (options.gdpr.cookie_law_info_integration_enabled) {
1087
1088                    $(document).onFirst('click', '#cookie_action_close_header', function () {
1089                        Facebook.loadPixel();
1090                        Analytics.loadPixel();
1091                        Pinterest.loadPixel();
1092                        Bing.loadPixel();
1093                    });
1094
1095                    $(document).onFirst('click', '#cookie_action_close_header_reject', function () {
1096                        Facebook.disable();
1097                        Analytics.disable();
1098                        Pinterest.disable();
1099                        Bing.disable();
1100                    });
1101
1102                }
1103
1104            },
1105
1106            /**
1107             * DOWNLOAD DOCS
1108             */
1109
1110            getLinkExtension: function (link) {
1111
1112                // Remove anchor, query string and everything before last slash
1113                link = link.substring(0, (link.indexOf("#") === -1) ? link.length : link.indexOf("#"));
1114                link = link.substring(0, (link.indexOf("?") === -1) ? link.length : link.indexOf("?"));
1115                link = link.substring(link.lastIndexOf("/") + 1, link.length);
1116
1117                // If there's a period left in the URL, then there's a extension
1118                if (link.length > 0 && link.indexOf('.') !== -1) {
1119                    link = link.substring(link.indexOf(".") + 1); // Remove everything but what's after the first period
1120                    return link;
1121                } else {
1122                    return "";
1123                }
1124            },
1125
1126            getLinkFilename: function (link) {
1127
1128                // Remove anchor, query string and everything before last slash
1129                link = link.substring(0, (link.indexOf("#") === -1) ? link.length : link.indexOf("#"));
1130                link = link.substring(0, (link.indexOf("?") === -1) ? link.length : link.indexOf("?"));
1131                link = link.substring(link.lastIndexOf("/") + 1, link.length);
1132
1133                // If there's a period left in the URL, then there's a extension
1134                if (link.length > 0 && link.indexOf('.') !== -1) {
1135                    return link;
1136                } else {
1137                    return "";
1138                }
1139            },
1140            /**
1141             * Enrich
1142             */
1143            isCheckoutPage: function () {
1144                return $('body').hasClass('woocommerce-checkout') || document.querySelector('.woocommerce-checkout') ||
1145                    $('body').hasClass('edd-checkout');
1146            },
1147            addCheckoutFields : function() {
1148                var utm = "";
1149                var utms = getUTMs()
1150
1151                $.each(utmTerms, function (index, name) {
1152                    if(index > 0) {
1153                        utm+="|";
1154                    }
1155                    utm+=name+":"+utms[name];
1156                });
1157                var utmIdList = "";
1158                var utmsIds = getUTMId()
1159                $.each(utmId, function (index, name) {
1160                    if(index > 0) {
1161                        utmIdList+="|";
1162                    }
1163                    utmIdList+=name+":"+utmsIds[name];
1164                });
1165                var utmIdListLast = "";
1166                var utmsIdsLast = getUTMId(true)
1167                $.each(utmId, function (index, name) {
1168                    if(index > 0) {
1169                        utmIdListLast+="|";
1170                    }
1171                    utmIdListLast+=name+":"+utmsIdsLast[name];
1172                });
1173
1174
1175                var utmLast = "";
1176                var utmsLast = getUTMs(true)
1177                $.each(utmTerms, function (index, name) {
1178                    if(index > 0) {
1179                        utmLast+="|";
1180                    }
1181                    utmLast+=name+":"+utmsLast[name];
1182                });
1183
1184                var dateTime = getDateTime();
1185                var landing = Cookies.get('pys_landing_page');
1186                var lastLanding = Cookies.get('last_pys_landing_page');
1187                var trafic = Cookies.get('pysTrafficSource');
1188                var lastTrafic = Cookies.get('last_pysTrafficSource');
1189
1190                var $form = null;
1191                if($('body').hasClass('woocommerce-checkout')) {
1192                    $form = $("form.woocommerce-checkout");
1193                } else {
1194                    $form = $("#edd_purchase_form");
1195                }
1196                var inputs = {'pys_utm':utm,
1197                    'pys_utm_id':utmIdList,
1198                    'pys_browser_time':dateTime.join("|"),
1199                    'pys_landing':landing,
1200                    'pys_source':trafic,
1201                    'pys_order_type': $(".wcf-optin-form").length > 0 ? "wcf-optin" : "normal",
1202
1203                    'last_pys_landing':lastLanding,
1204                    'last_pys_source':lastTrafic,
1205                    'last_pys_utm':utmLast,
1206                    'last_pys_utm_id':utmIdListLast,
1207                }
1208
1209                Object.keys(inputs).forEach(function(key,index) {
1210                    $form.append("<input type='hidden' name='"+key+"' value='"+inputs[key]+"' /> ");
1211                });
1212
1213
1214            }
1215        };
1216
1217    }(options);
1218
1219    var Facebook = function (options) {
1220
1221
1222        var defaultEventTypes = [
1223            'PageView',
1224            'ViewContent',
1225            'Search',
1226            'AddToCart',
1227            'AddToWishlist',
1228            'InitiateCheckout',
1229            'AddPaymentInfo',
1230            'Purchase',
1231            'Lead',
1232
1233            'Subscribe',
1234            'CustomizeProduct',
1235            'FindLocation',
1236            'StartTrial',
1237            'SubmitApplication',
1238            'Schedule',
1239            'Contact',
1240            'Donate'
1241        ];
1242
1243        var initialized = false;
1244
1245        // fire server side event gdpr plugin installed
1246        var isApiDisabled = options.gdpr.all_disabled_by_api ||
1247            options.gdpr.facebook_disabled_by_api ||
1248            options.gdpr.cookiebot_integration_enabled ||
1249            options.gdpr.consent_magic_integration_enabled ||
1250            options.gdpr.cookie_notice_integration_enabled ||
1251            options.gdpr.cookie_law_info_integration_enabled;
1252
1253        /**
1254         *
1255         * @param allData
1256         * @param params
1257         * @returns {string | null}
1258         */
1259        function sendFbServerEvent(allData,name,params) {
1260            let eventId = null;
1261            if(options.facebook.serverApiEnabled) {
1262
1263                if(allData.e_id === "woo_remove_from_cart" || allData.e_id === "woo_add_to_cart_on_button_click") {// server event will sended from hook
1264                    let isAddToCartFromJs =  options.woo.hasOwnProperty("addToCartCatchMethod")
1265                        && options.woo.addToCartCatchMethod === "add_cart_js";
1266
1267                    if(isAddToCartFromJs || allData.e_id !== "woo_add_to_cart_on_button_click") {
1268                        Facebook.updateEventId(allData.name);
1269                        allData.eventID = Facebook.getEventId(allData.name);
1270                    } else {
1271                        // not update eventID for woo_add_to_cart_on_button_click,
1272                        // web event created by ajax from server
1273                    }
1274                } else {
1275                    if(  options.facebook.ajaxForServerEvent
1276                        || isApiDisabled
1277                        || allData.delay > 0
1278                        || allData.type !== "static")
1279                    { // send event from server if they was bloc by gdpr or need send with delay
1280                        allData.eventID = pys_generate_token(36);
1281                        var json = {
1282                            action: 'pys_api_event',
1283                            pixel: 'facebook',
1284                            event: name,
1285                            data:params,
1286                            ids:options.facebook.pixelIds,
1287                            eventID:allData.eventID,
1288                            url:window.location.href,
1289                            ajax_event:options.ajax_event
1290                        };
1291                        if(allData.hasOwnProperty('woo_order')) {
1292                            json['woo_order'] = allData.woo_order;
1293                        }
1294                        if(allData.hasOwnProperty('edd_order')) {
1295                            json['edd_order'] = allData.edd_order;
1296                        }
1297
1298                        if(name == 'PageView') {
1299                            let expires = parseInt(options.cookie_duration);
1300                            var currentTimeInSeconds=Date.now();
1301                            var randomNum = Math.floor(1000000000 + Math.random() * 9000000000);
1302                            timeoutDelay = 0;
1303                            if(allData.delay > 0)
1304                            {
1305                                timeoutDelay = allData.delay;
1306                            }
1307                            if(!Cookies.get('_fbp'))
1308                            {
1309                                timeoutDelay = 100;
1310                            }
1311                            if(getUrlParameter('fbclid') && !Cookies.get('_fbc'))
1312                            {
1313                                timeoutDelay = 100;
1314                            }
1315                            setTimeout(function(){
1316                                if(!Cookies.get('_fbp'))
1317                                {
1318                                    Cookies.set('_fbp','fb.1.'+currentTimeInSeconds+'.'+randomNum,  { expires: expires })
1319                                }
1320                                if(getUrlParameter('fbclid') && !Cookies.get('_fbc'))
1321                                {
1322                                    Cookies.set('_fbc', 'fb.1.'+currentTimeInSeconds+'.'+getUrlParameter('fbclid'),  { expires: expires })
1323                                }
1324                                jQuery.ajax( {
1325                                    type: 'POST',
1326                                    url: options.ajaxUrl,
1327                                    data: json,
1328                                    headers: {
1329                                        'Cache-Control': 'no-cache'
1330                                    },
1331                                    success: function(){},
1332                                });
1333                            },timeoutDelay)
1334                        }
1335                        else
1336                        {
1337                            jQuery.ajax( {
1338                                type: 'POST',
1339                                url: options.ajaxUrl,
1340                                data: json,
1341                                headers: {
1342                                    'Cache-Control': 'no-cache'
1343                                },
1344                                success: function(){},
1345                            });
1346                        }
1347                    }
1348                }
1349                eventId = allData.eventID
1350            }
1351
1352            return eventId;
1353        }
1354
1355        function fireEvent(name, allData) {
1356
1357            if(typeof window.pys_event_data_filter === "function" && window.pys_disable_event_filter(name,'facebook')) {
1358                return;
1359            }
1360
1361            var actionType = defaultEventTypes.includes(name) ? 'track' : 'trackCustom';
1362            var data = allData.params;
1363            var params = {};
1364            var arg = {};
1365            Utils.copyProperties(data, params);
1366
1367            let eventId = sendFbServerEvent(allData,name,params)
1368
1369
1370            if("hCR" === name) {
1371                return;
1372            }
1373
1374            if (options.debug) {
1375                console.log('[Facebook] ' + name, params,"eventID",eventId);
1376            }
1377
1378            if(eventId != null) {
1379                arg.eventID = eventId;
1380            }
1381
1382            fbq(actionType, name, params,arg);
1383        }
1384
1385        /**
1386         * Public API
1387         */
1388        return {
1389            tag: function() {
1390                return "facebook";
1391            },
1392            isEnabled: function () {
1393                return options.hasOwnProperty('facebook');
1394            },
1395
1396            disable: function () {
1397                initialized = false;
1398            },
1399
1400            /**
1401             * Load pixel's JS
1402             */
1403            loadPixel: function () {
1404
1405                if (initialized || !this.isEnabled() || !Utils.consentGiven('facebook')) {
1406                    return;
1407                }
1408
1409                !function (f, b, e, v, n, t, s) {
1410                    if (f.fbq) return;
1411                    n = f.fbq = function () {
1412                        n.callMethod ?
1413                            n.callMethod.apply(n, arguments) : n.queue.push(arguments)
1414                    };
1415                    if (!f._fbq) f._fbq = n;
1416                    n.push = n;
1417                    n.loaded = !0;
1418                    n.version = '2.0';
1419                    n.agent = 'dvpixelyoursite';
1420                    n.queue = [];
1421                    t = b.createElement(e);
1422                    t.async = !0;
1423                    t.src = v;
1424                    s = b.getElementsByTagName(e)[0];
1425                    s.parentNode.insertBefore(t, s)
1426                }(window,
1427                    document, 'script', 'https://connect.facebook.net/en_US/fbevents.js');
1428
1429                // initialize pixel
1430                options.facebook.pixelIds.forEach(function (pixelId) {
1431
1432                    if (options.facebook.removeMetadata) {
1433                        fbq('set', 'autoConfig', false, pixelId);
1434                    }
1435                    if (options.gdpr.consent_magic_integration_enabled && typeof CS_Data !== "undefined") {
1436                        if(options.facebook.advancedMatching.length === 0) {
1437                            fbq('init', pixelId);
1438                        } else {
1439                            var cs_advanced_matching = Cookies.get('cs_enabled_advanced_matching'+test_prefix);
1440                            if (jQuery('#cs_enabled_advanced_matching'+test_prefix).length > 0) {
1441                                if (cs_advanced_matching == 'yes') {
1442                                    fbq('init', pixelId, options.facebook.advancedMatching);
1443                                } else {
1444                                    fbq('init', pixelId);
1445                                }
1446                            } else {
1447                                fbq('init', pixelId, options.facebook.advancedMatching);
1448                            }
1449                        }
1450                    } else {
1451                        if (options.facebook.advancedMatching.length === 0) {
1452                            fbq('init', pixelId);
1453                        } else {
1454                            fbq('init', pixelId, options.facebook.advancedMatching);
1455                        }
1456                    }
1457                });
1458
1459                initialized = true;
1460
1461                Utils.fireStaticEvents('facebook');
1462
1463            },
1464
1465            fireEvent: function (name, data) {
1466
1467                if (!initialized || !this.isEnabled()) {
1468                    return false;
1469                }
1470
1471                data.delay = data.delay || 0;
1472                data.params = data.params || {};
1473
1474                if (data.delay === 0) {
1475
1476                    fireEvent(name, data);
1477
1478                } else {
1479
1480                    setTimeout(function (name, params) {
1481                        fireEvent(name, params);
1482                    }, data.delay * 1000, name, data);
1483
1484                }
1485
1486                return true;
1487
1488            },
1489
1490            onCommentEvent: function (event) {
1491                this.fireEvent(event.name, event);
1492            },
1493
1494            onDownloadEvent: function (event) {
1495                this.fireEvent(event.name, event);
1496            },
1497
1498            onFormEvent: function (event) {
1499
1500                this.fireEvent(event.name, event);
1501
1502            },
1503
1504            onWooAddToCartOnButtonEvent: function (product_id) {
1505
1506                if(!options.dynamicEvents.woo_add_to_cart_on_button_click.hasOwnProperty(this.tag()))
1507                    return;
1508                var event = options.dynamicEvents.woo_add_to_cart_on_button_click[this.tag()];
1509
1510                if (window.pysWooProductData.hasOwnProperty(product_id)) {
1511                    if (window.pysWooProductData[product_id].hasOwnProperty('facebook')) {
1512                        event = Utils.copyProperties(event, {})
1513                        Utils.copyProperties(window.pysWooProductData[product_id]['facebook'].params, event.params)
1514                        this.fireEvent(event.name, event);
1515                    }
1516                }
1517            },
1518
1519            onWooAddToCartOnSingleEvent: function (product_id, qty, product_type, $form) {
1520
1521                window.pysWooProductData = window.pysWooProductData || [];
1522                if(!options.dynamicEvents.woo_add_to_cart_on_button_click.hasOwnProperty(this.tag()))
1523                    return;
1524                var event = Utils.clone(options.dynamicEvents.woo_add_to_cart_on_button_click[this.tag()]);
1525
1526                if (product_type === Utils.PRODUCT_VARIABLE && !options.facebook.wooVariableAsSimple) {
1527                    product_id = parseInt($form.find('input[name="variation_id"]').val());
1528                }
1529
1530                if (window.pysWooProductData.hasOwnProperty(product_id)) {
1531                    if (window.pysWooProductData[product_id].hasOwnProperty('facebook')) {
1532
1533
1534                        Utils.copyProperties(window.pysWooProductData[product_id]['facebook'].params, event.params);
1535
1536                        var groupValue = 0;
1537                        if(product_type === Utils.PRODUCT_GROUPED ) {
1538                            $form.find(".woocommerce-grouped-product-list .qty").each(function(index){
1539                                var childId = $(this).attr('name').replaceAll("quantity[","").replaceAll("]","");
1540                                var quantity = parseInt($(this).val());
1541                                if(isNaN(quantity)) {
1542                                    quantity = 0;
1543                                }
1544                                var childItem = window.pysWooProductData[product_id]['facebook'].grouped[childId];
1545
1546                                if(quantity == 0) {
1547                                    event.params.content_ids.forEach(function(el,index,array) {
1548                                        if(el == childItem.content_id) {
1549                                            array.splice(index, 1);
1550                                        }
1551                                    });
1552                                }
1553
1554                                if(event.params.hasOwnProperty('contents')) {
1555                                    event.params.contents.forEac
1555h(function(el,index,array) {
1556                                        if(el.id == childItem.content_id) {
1557                                            if(quantity > 0){
1558                                                el.quantity = quantity;
1559                                            } else {
1560                                                array.splice(index, 1);
1561                                            }
1562                                        }
1563                                    });
1564                                }
1565
1566
1567                                groupValue += childItem.price * quantity;
1568                            });
1569                            if(groupValue == 0) return; // skip if no items selected
1570                        }
1571
1572                        // maybe customize value option
1573                        if (options.woo.addToCartOnButtonValueEnabled && options.woo.addToCartOnButtonValueOption !== 'global') {
1574
1575                            if(product_type === Utils.PRODUCT_GROUPED) {
1576                                event.params.value = groupValue;
1577                            } else if(product_type === Utils.PRODUCT_BUNDLE) {
1578                                var data = $(".bundle_form .bundle_data").data("bundle_form_data");
1579                                var items_sum = getBundlePriceOnSingleProduct(data);
1580                                event.params.value = (parseInt(data.base_price) + items_sum )* qty;
1581                            } else {
1582                                event.params.value = event.params.value * qty;
1583                            }
1584                        }
1585
1586                        // only when non Facebook for WooCommerce logic used
1587                        if (event.params.hasOwnProperty('contents') && product_type !== Utils.PRODUCT_GROUPED) {
1588                            event.params.contents[0].quantity = qty;
1589                        }
1590
1591                        this.fireEvent(event.name, event);
1592
1593                    }
1594                }
1595            },
1596
1597            onWooRemoveFromCartEvent: function (event) {
1598                this.fireEvent(event.name, event);
1599            },
1600
1601            onEddAddToCartOnButtonEvent: function (download_id, price_index, qty) {
1602
1603                if(!options.dynamicEvents.edd_add_to_cart_on_button_click.hasOwnProperty(this.tag()))
1604                    return;
1605                var event = Utils.clone(options.dynamicEvents.edd_add_to_cart_on_button_click[this.tag()]);
1606
1607                if (window.pysEddProductData.hasOwnProperty(download_id)) {
1608
1609                    var index;
1610
1611                    if (price_index) {
1612                        index = download_id + '_' + price_index;
1613                    } else {
1614                        index = download_id;
1615                    }
1616
1617                    if (window.pysEddProductData[download_id].hasOwnProperty(index)) {
1618                        if (window.pysEddProductData[download_id][index].hasOwnProperty('facebook')) {
1619
1620
1621                            Utils.copyProperties(window.pysEddProductData[download_id][index]['facebook']["params"], event.params)
1622
1623                            // maybe customize value option
1624                            if (options.edd.addToCartOnButtonValueEnabled && options.edd.addToCartOnButtonValueOption !== 'global') {
1625                                event.params.value = event.params.value * qty;
1626                            }
1627
1628                            // update contents qty param
1629                            var contents = event.params.contents;
1630                            contents[0].quantity = qty;
1631                            event.params.contents = contents;
1632
1633                            this.fireEvent(event.name,event);
1634
1635                        }
1636                    }
1637
1638                }
1639
1640            },
1641
1642            onEddRemoveFromCartEvent: function (event) {
1643                this.fireEvent(event.name, event);
1644            },
1645            onPageScroll: function (event) {
1646                this.fireEvent(event.name, event);
1647            },
1648            onTime: function (event) {
1649                this.fireEvent(event.name, event);
1650            },
1651            initEventIdCookies: function (key) {
1652                var ids = {};
1653                ids[key] = pys_generate_token(36)
1654                Cookies.set('pys_fb_event_id', JSON.stringify(ids));
1655            },
1656            updateEventId:function(key) {
1657                var cooData = Cookies.get("pys_fb_event_id")
1658                if(cooData === undefined) {
1659                    this.initEventIdCookies(key);
1660                } else {
1661                    var data = JSON.parse(cooData);
1662                    data[key] = pys_generate_token(36);
1663                    Cookies.set('pys_fb_event_id', JSON.stringify(data) );
1664                }
1665            },
1666
1667            getEventId:function (key) {
1668                var data = Cookies.get("pys_fb_event_id");
1669                if(data === undefined) {
1670                    this.initEventIdCookies(key);
1671                    data = Cookies.get("pys_fb_event_id");
1672                }
1673                return JSON.parse(data)[key];
1674            },
1675        };
1676
1677    }(options);
1678
1679    var Analytics = function (options) {
1680
1681        var initialized = false;
1682
1683        /**
1684         * Fires event
1685         *
1686         * @link: https://developers.google.com/analytics/devguides/collection/gtagjs/sending-data
1687         * @link: https://developers.google.com/analytics/devguides/collection/gtagjs/events
1688         * @link: https://developers.google.com/gtagjs/reference/event
1689         * @link: https://developers.google.com/gtagjs/reference/parameter
1690         *
1691         * @link: https://developers.google.com/analytics/devguides/collection/gtagjs/custom-dims-mets
1692         *
1693         * @param name
1694         * @param data
1695         */
1696        function fireEvent(name, data) {
1697
1698            if(typeof window.pys_event_data_filter === "function" && window.pys_disable_event_filter(name,'ga')) {
1699                return;
1700            }
1701
1702            var eventParams = Utils.copyProperties(data, {});
1703
1704            var _fireEvent = function (tracking_id,name,params) {
1705
1706                params['send_to'] = tracking_id;
1707
1708                if (options.debug) {
1709                    console.log('[Google Analytics #' + tracking_id + '] ' + name, params);
1710                }
1711
1712                gtag('event', name, params);
1713
1714            };
1715
1716            options.ga.trackingIds.forEach(function (tracking_id) {
1717                var copyParams = Utils.copyProperties(eventParams, {}); // copy params because mapParamsTov4 can modify it
1718                var params = mapParamsTov4(tracking_id,name,copyParams)
1719                _fireEvent(tracking_id,name,params);
1720            });
1721
1722        }
1723        function mapParamsTov4(tag,name,param) {
1724            //GA4 automatically collects a number of parameters for all events
1725            delete param.page_title;
1726            delete param.event_url;
1727            delete param.landing_page;
1728            // end
1729            if(isv4(tag)) {
1730                delete param.traffic_source;
1731                delete param.event_category;
1732                delete param.event_label;
1733                delete param.ecomm_prodid;
1734                delete param.ecomm_pagetype;
1735                delete param.ecomm_totalvalue;
1736                delete param.non_interaction;
1737                if(name === 'search') {
1738                    param['search'] = param.search_term;
1739                    delete param.search_term;
1740                    delete param.non_interaction;
1741                    delete param.dynx_itemid;
1742                    delete param.dynx_pagetype;
1743                    delete param.dynx_totalvalue;
1744                }
1745            } else {
1746
1747                switch (name) {
1748
1749                    case 'Comment' :
1750                    case 'login' :
1751                    case 'sign_up' :
1752                    case 'EmailClick' :
1753                    case 'TelClick' : {
1754                        let params = {
1755                            event_category: "Key Actions",
1756                            event_action: name,
1757                             non_interaction: param.non_interaction,
1758                        }
1759                        return params;
1760                    }
1761                    case 'Form' : {
1762                        let params = {
1763                            event_category: "Key Actions",
1764                            event_action: name,
1765                            non_interaction: param.non_interaction,
1766                        }
1767                        var formClass = (typeof param.form_class != 'undefined') ? 'class: ' + param.form_class : '';
1768                        if(formClass != "") {
1769                            params["event_label"] = formClass;
1770                        }
1771                        return params;
1772                    }
1773                    case 'Download' : {
1774                        let params = {
1775                            event_category: "Key Actions",
1776                            event_action: name,
1777                            event_label: param.download_name,
1778                              non_interaction: param.non_interaction,
1779                        }
1780                        return params;
1781                    }
1782                    case 'TimeOnPage' :
1783                    case 'PageScroll' : {
1784                        let params = {
1785                            event_category: "Key Actions",
1786                            event_action: name,
1787                            event_label: document.title,
1788                              non_interaction: param.non_interaction,
1789                        }
1790                        return params;
1791                    }
1792                    case 'search' : {
1793                        let params = {
1794                            event_category: "Key Actions",
1795                            event_action: name,
1796                            event_label: param.search_term,
1797                              non_interaction: param.non_interaction,
1798                        }
1799                        return params;
1800                    }
1801                }
1802
1803                //delete standard params
1804
1805                delete param.post_type;
1806                delete param.post_id;
1807                delete param.plugin;
1808                delete param.user_role;
1809                delete param.cartlows;
1810                delete param.cartflows_flow;
1811                delete param.cartflows_step;
1812            }
1813            return param;
1814        }
1815
1816        function isv4(tag) {
1817            return tag.indexOf('G') === 0;
1818        }
1819
1820        /**
1821         * Public API
1822         */
1823        return {
1824            tag: function() {
1825                return "ga";
1826            },
1827            isEnabled: function () {
1828                return options.hasOwnProperty('ga');
1829            },
1830
1831            disable: function () {
1832                initialized = false;
1833            },
1834
1835            loadPixel: function () {
1836
1837                if (initialized || !this.isEnabled() || !Utils.consentGiven('analytics')) {
1838                    return;
1839                }
1840
1841                Utils.loadGoogleTag(options.ga.trackingIds[0]);
1842
1843                var config = {
1844                    'link_attribution': options.ga.enhanceLinkAttr,
1845                    'anonymize_ip': options.ga.anonimizeIP
1846                };
1847
1848                // Cross-Domain tracking
1849                if (options.ga.crossDomainEnabled) {
1850                    config.linker = {
1851                        accept_incoming: options.ga.crossDomainAcceptIncoming,
1852                        domains: options.ga.crossDomainDomains
1853                    };
1854                }
1855
1856
1857
1858                // configure tracking ids
1859                options.ga.trackingIds.forEach(function (trackingId,index) {
1860                    config.debug_mode = options.ga.isDebugEnabled.includes("index_" + index);
1861                    if(isv4(trackingId)) {
1862                        if(options.ga.disableAdvertisingFeatures) {
1863                            config.allow_google_signals = false
1864                        }
1865                        if(options.ga.disableAdvertisingPersonalization) {
1866                            config.allow_ad_personalization_signals = false
1867                        }
1868                    }
1869                    if (options.gdpr.cookiebot_integration_enabled && typeof Cookiebot !== 'undefined') {
1870
1871                        var cookiebot_consent_category = options.gdpr['cookiebot_analytics_consent_category'];
1872                        if (options.gdpr['analytics_prior_consent_enabled']) {
1873                            if (Cookiebot.consented === true && Cookiebot.consent[cookiebot_consent_category]) {
1874                                gtag('config', trackingId, config);
1875                            }
1876                        } else {
1877                            if (Cookiebot.consent[cookiebot_consent_category]) {
1878                                gtag('config', trackingId, config);
1879                            }
1880                        }
1881
1882                    }
1883                    else
1884                    {
1885                        gtag('config', trackingId, config);
1886                    }
1887                });
1888
1889                initialized = true;
1890
1891                Utils.fireStaticEvents('ga');
1892
1893            },
1894
1895            fireEvent: function (name, data) {
1896
1897                if (!initialized || !this.isEnabled()) {
1898                    return false;
1899                }
1900
1901                data.delay = data.delay || 0;
1902                data.params = data.params || {};
1903
1904                if (data.delay === 0) {
1905
1906                    fireEvent(name, data.params);
1907
1908                } else {
1909
1910                    setTimeout(function (name, params) {
1911                        fireEvent(name, params);
1912                    }, data.delay * 1000, name, data.params);
1913
1914                }
1915
1916                return true;
1917
1918            },
1919
1920            onCommentEvent: function (event) {
1921                this.fireEvent(event.name, event);
1922            },
1923
1924            onDownloadEvent: function (event) {
1925                this.fireEvent(event.name, event);
1926            },
1927
1928            onFormEvent: function (event) {
1929                this.fireEvent(event.name, event);
1930            },
1931
1932            onWooAddToCartOnButtonEvent: function (product_id) {
1933
1934                if(!options.dynamicEvents.woo_add_to_cart_on_button_click.hasOwnProperty(this.tag()))
1935                    return;
1936                var event = Utils.clone(options.dynamicEvents.woo_add_to_cart_on_button_click[this.tag()]);
1937
1938                if (window.pysWooProductData.hasOwnProperty(product_id)) {
1939                    if (window.pysWooProductData[product_id].hasOwnProperty('ga')) {
1940                        Utils.copyProperties(window.pysWooProductData[product_id]['ga'].params, event.params)
1941                        this.fireEvent(event.name, event);
1942                    }
1943                }
1944
1945
1946            },
1947
1948            onWooAddToCartOnSingleEvent: function (product_id, qty, product_type, $form) {
1949
1950                window.pysWooProductData = window.pysWooProductData || [];
1951
1952                if(!options.dynamicEvents.woo_add_to_cart_on_button_click.hasOwnProperty(this.tag()))
1953                    return;
1954                var event = Utils.clone(options.dynamicEvents.woo_add_to_cart_on_button_click[this.tag()]);
1955
1956                if (product_type === Utils.PRODUCT_VARIABLE && !options.ga.wooVariableAsSimple) {
1957                    product_id = parseInt($form.find('input[name="variation_id"]').val());
1958                }
1959
1960                if (window.pysWooProductData.hasOwnProperty(product_id)) {
1961                    if (window.pysWooProductData[product_id].hasOwnProperty('ga')) {
1962
1963                        Utils.copyProperties(window.pysWooProductData[product_id]['ga'].params, event.params);
1964                        if(product_type === Utils.PRODUCT_GROUPED ) {
1965                            var groupValue = 0;
1966                            $form.find(".woocommerce-grouped-product-list .qty").each(function(index){
1967                                var childId = $(this).attr('name').replaceAll("quantity[","").replaceAll("]","");
1968                                var quantity = parseInt($(this).val());
1969                                if(isNaN(quantity)) {
1970                                    quantity = 0;
1971                                }
1972                                var childItem = window.pysWooProductData[product_id]['ga'].grouped[childId];
1973                                // update quantity
1974                                event.params.items.forEach(function(el,index,array) {
1975                                    if(el.id == childItem.content_id) {
1976                                        if(quantity > 0){
1977                                            el.quantity = quantity;
1978                                        } else {
1979                                            array.splice(index, 1);
1980                                        }
1981                                    }
1982                                });
1983                                groupValue += childItem.price * quantity;
1984                            });
1985                            if(options.woo.addToCartOnButtonValueEnabled &&
1986                                options.woo.addToCartOnButtonValueOption !== 'global' &&
1987                                event.params.hasOwnProperty('ecomm_totalvalue')) {
1988                                event.params.ecomm_totalvalue = groupValue;
1989                            }
1990
1991                            if(groupValue == 0) return;
1991 // skip if no items selected
1992                        } else {
1993                            // update items qty param
1994                            event.params.items[0].quantity = qty;
1995                        }
1996
1997                        // maybe customize value option
1998                        if (options.woo.addToCartOnButtonValueEnabled &&
1999                            options.woo.addToCartOnButtonValueOption !== 'global' &&
2000                            product_type !== Utils.PRODUCT_GROUPED)
2001                        {
2002                            if(event.params.hasOwnProperty('ecomm_totalvalue')) {
2003                                event.params.ecomm_totalvalue = event.params.items[0].price * qty;
2004                            }
2005
2006                        }
2007
2008
2009                        this.fireEvent(event.name, event);
2010                    }
2011                }
2012
2013            },
2014
2015            onWooRemoveFromCartEvent: function (event) {
2016
2017                this.fireEvent(event.name, event);
2018
2019            },
2020
2021            onEddAddToCartOnButtonEvent: function (download_id, price_index, qty) {
2022
2023                if(!options.dynamicEvents.edd_add_to_cart_on_button_click.hasOwnProperty(this.tag()))
2024                    return;
2025                var event = Utils.clone(options.dynamicEvents.edd_add_to_cart_on_button_click[this.tag()]);
2026
2027
2028                if (window.pysEddProductData.hasOwnProperty(download_id)) {
2029
2030                    var index;
2031
2032                    if (price_index) {
2033                        index = download_id + '_' + price_index;
2034                    } else {
2035                        index = download_id;
2036                    }
2037
2038                    if (window.pysEddProductData[download_id].hasOwnProperty(index)) {
2039                        if (window.pysEddProductData[download_id][index].hasOwnProperty('ga')) {
2040
2041                            Utils.copyProperties(window.pysEddProductData[download_id][index]['ga'].params, event.params);
2042
2043                            // update items qty param
2044                            event.params.items[0].quantity = qty;
2045
2046                            this.fireEvent(event.name,event);
2047
2048                        }
2049                    }
2050
2051                }
2052
2053            },
2054
2055            onEddRemoveFromCartEvent: function (event) {
2056                this.fireEvent(event.name, event);
2057            },
2058            onPageScroll: function (event) {
2059                this.fireEvent(event.name, event);
2060            },
2061            onTime: function (event) {
2062                this.fireEvent(event.name, event);
2063            },
2064
2065        };
2066
2067    }(options);
2068
2069    window.pys = window.pys || {};
2070    window.pys.Facebook = Facebook;
2071    window.pys.Analytics = Analytics;
2072    window.pys.Utils = Utils;
2073
2074
2075
2076
2077    $(document).ready(function () {
2078
2079        if($("#pys_late_event").length > 0) {
2080            var events =  JSON.parse($("#pys_late_event").attr("dir"));
2081            for(var key in events) {
2082                var event = {};
2083                event[events[key].e_id] = [events[key]];
2084                if(options.staticEvents.hasOwnProperty(key)) {
2085                    Object.assign(options.staticEvents[key], event);
2086                } else {
2087                    options.staticEvents[key] = event;
2088                }
2089
2090            }
2091        }
2092
2093        var Pinterest = Utils.setupPinterestObject();
2094        var Bing = Utils.setupBingObject();
2095
2096        if((options.woo.enabled || options.edd.enabled) && (options.woo.enabled_save_data_to_orders || options.edd.enabled_save_data_to_orders))
2097        {
2098            Utils.manageCookies();
2099        }
2100        else
2101        {
2102            Cookies.remove('pys_first_visit')
2103            Cookies.remove('pysTrafficSource')
2104            Cookies.remove('pys_landing_page')
2105            Cookies.remove('last_pys_landing_page')
2106            Cookies.remove('last_pysTrafficSource')
2107            Cookies.remove('pys_start_session')
2108            Cookies.remove('pys_session_limit')
2109
2110            $.each(Utils.utmTerms, function (index, name) {
2111                Cookies.remove('pys_' + name)
2112            });
2113            $.each(Utils.utmId,function(index,name) {
2114                Cookies.remove('pys_' + name)
2115            })
2116            $.each(Utils.utmTerms, function (index, name) {
2117                Cookies.remove('last_pys_' + name)
2118            });
2119            $.each(Utils.utmId,function(index,name) {
2120                Cookies.remove('last_pys_' + name)
2121            });
2122        }
2123        Utils.setupGdprCallbacks();
2124        // page scroll event
2125        if ( options.dynamicEvents.hasOwnProperty("automatic_event_scroll")
2126        ) {
2127
2128            var singlePageScroll = function () {
2129
2130
2131                var docHeight = $(document).height() - $(window).height();
2132                var isFired = false;
2133
2134                if (options.dynamicEvents.hasOwnProperty("automatic_event_scroll")) {
2135                    var pixels = Object.keys(options.dynamicEvents.automatic_event_scroll);
2136                    for(var i = 0;i<pixels.length;i++) {
2137                        var event = Utils.clone(options.dynamicEvents.automatic_event_scroll[pixels[i]]);
2138                        var scroll = Math.round(docHeight * event.scroll_percent / 100)// convert % to absolute positions
2139
2140                        if(scroll < $(window).scrollTop()) {
2141                            Utils.copyProperties(Utils.getRequestParams(), event.params);
2142                            getPixelBySlag(pixels[i]).onPageScroll(event);
2143                            isFired = true
2144                        }
2145                    }
2146                }
2147                if(isFired) {
2148                    $(document).off("scroll",singlePageScroll);
2149                }
2150            }
2151            $(document).on("scroll",singlePageScroll);
2152        }
2153
2154
2155        if (options.dynamicEvents.hasOwnProperty("automatic_event_time_on_page")) {
2156            var pixels = Object.keys(options.dynamicEvents.automatic_event_time_on_page);
2157            var time = options.dynamicEvents.automatic_event_time_on_page[pixels[0]].time_on_page; // the same for all pixel
2158            setTimeout(function(){
2159                for(var i = 0;i<pixels.length;i++) {
2160                    var event = Utils.clone(options.dynamicEvents.automatic_event_time_on_page[pixels[i]]);
2161                    Utils.copyProperties(Utils.getRequestParams(), event.params);
2162                    getPixelBySlag(pixels[i]).onTime(event);
2163                }
2164            },time*1000);
2165        }
2166
2167        // setup Click Event
2168        if (options.dynamicEvents.hasOwnProperty("automatic_event_download")) {
2169
2170            $(document).onFirst('click', 'a, button, input[type="button"], input[type="submit"]', function (e) {
2171
2172                var $elem = $(this);
2173
2174                // Download
2175                if(options.dynamicEvents.hasOwnProperty("automatic_event_download")
2176                ) {
2177                    var isFired = false;
2178                    if ($elem.is('a')) {
2179                        var href = $elem.attr('href');
2180                        if (typeof href !== "string") {
2181                            return;
2182                        }
2183                        href = href.trim();
2184                        var extension = Utils.getLinkExtension(href);
2185                        var track_download = false;
2186
2187                        if (extension.length > 0) {
2188
2189                            if(options.dynamicEvents.hasOwnProperty("automatic_event_download") ) {
2190                                var pixels = Object.keys(options.dynamicEvents.automatic_event_download);
2191                                for (var i = 0; i < pixels.length; i++) {
2192                                    var event = Utils.clone(options.dynamicEvents.automatic_event_download[pixels[i]]);
2193                                    var extensions = event.extensions;
2194                                    if (extensions.includes(extension)) {
2195
2196                                        if(pixels[i] == "tiktok") {
2197                                            getPixelBySlag(pixels[i]).fireEvent(tikEvent.name, event);
2198                                        } else {
2199                                            if (options.enable_remove_download_url_param) {
2200                                                href = href.split('?')[0];
2201                                            }
2202                                            event.params.download_url = href;
2203                                            event.params.download_type = extension;
2204                                            event.params.download_name = Utils.getLinkFilename(href);
2205                                            getPixelBySlag(pixels[i]).onDownloadEvent(event);
2206                                        }
2207
2208                                        isFired = true;
2209                                    }
2210                                }
2211                            }
2212                        }
2213                    }
2214                    if(isFired) { // prevent duplicate events on the same element
2215                        return;
2216                    }
2217                }
2218            });
2219        }
2220
2221
2222        // setup Dynamic events
2223        $.each(options.triggerEventTypes, function (triggerType, events) {
2224
2225            $.each(events, function (eventId, triggers) {
2226
2227                switch (triggerType) {
2228                    case 'url_click':
2229                        //@see: Utils.setupURLClickEvents()
2230                        break;
2231
2232                    case 'css_click':
2233                        Utils.setupCSSClickEvents(eventId, triggers);
2234                        break;
2235
2236                    case 'css_mouseover':
2237                        Utils.setupMouseOverClickEvents(eventId, triggers);
2238                        break;
2239
2240                    case 'scroll_pos':
2241                        Utils.setupScrollPosEvents(eventId, triggers);
2242                        break;
2243                    case 'comment':
2244                        Utils.setupCommentEvents(eventId, triggers);
2245                        break;
2246                }
2247
2248            });
2249
2250        });
2251        // setup WooCommerce events
2252        if (options.woo.enabled) {
2253
2254            // WooCommerce AddToCart
2255            if (options.dynamicEvents.hasOwnProperty("woo_add_to_cart_on_button_click")
2256                && options.woo.hasOwnProperty("addToCartCatchMethod")
2257                && options.woo.addToCartCatchMethod === "add_cart_js"
2258            ) {
2259
2260                // Loop, any kind of "simple" product, except external
2261                $('.add_to_cart_button:not(.product_type_variable,.product_type_bundle,.single_add_to_cart_button)').on("click",function (e) {
2262
2263                    var product_id = $(this).data('product_id');
2264
2265                    if (typeof product_id !== 'undefined') {
2266                        Facebook.onWooAddToCartOnButtonEvent(product_id);
2267                        Analytics.onWooAddToCartOnButtonEvent(product_id);
2268                        Pinterest.onWooAddToCartOnButtonEvent(product_id);
2269                        Bing.onWooAddToCartOnButtonEvent(product_id);
2270                    }
2271
2272                });
2273
2274                // Single Product
2275                // tap try to https://stackoverflow.com/questions/30990967/on-tap-click-event-firing-twice-how-to-avoid-it
2276                //  $(document) not work
2277                $('body').onFirst('click','button.single_add_to_cart_button,.single_add_to_cart_button',function (e) {
2278
2279                    var $button = $(this);
2280
2281                    if ($button.hasClass('disabled')) {
2282                        return;
2283                    }
2284
2285                    var $form = $button.closest('form');
2286
2287                    var product_type = Utils.PRODUCT_SIMPLE;
2288
2289                    if ($form.length === 0) {
2290                        return ;
2291                    } else if ($form.hasClass('variations_form')) {
2292                        product_type = Utils.PRODUCT_VARIABLE;
2293                    } else if($form.hasClass('bundle_form')) {
2294                        product_type = Utils.PRODUCT_BUNDLE;
2295                    } else if($form.hasClass('grouped_form')) {
2296                        product_type = Utils.PRODUCT_GROUPED;
2297                    }
2298
2299
2300
2301
2302                    var product_id;
2303                    var qty;
2304
2305                    if (product_type === Utils.PRODUCT_GROUPED) {
2306                        qty = 1;
2307                        product_id = parseInt($form.find('*[name="add-to-cart"]').val());
2308                    } else if (product_type === Utils.PRODUCT_VARIABLE) {
2309                        product_id = parseInt($form.find('*[name="add-to-cart"]').val());
2310                        var qtyTag = $form.find('input[name="quantity"]');
2311                        if(qtyTag.length <= 0) {
2312                            qtyTag = $form.find('select[name="quantity"]');
2313                        }
2314                        qty = parseInt(qtyTag.val());
2315                    } else {
2316                        product_id = parseInt($form.find('*[name="add-to-cart"]').val());
2317                        var qtyTag = $form.find('input[name="quantity"]');
2318                        if(qtyTag.length <= 0) {
2319                            qtyTag = $form.find('select[name="quantity"]');
2320                        }
2321                        qty = parseInt(qtyTag.val());
2322                    }
2323
2324                    Facebook.onWooAddToCartOnSingleEvent(product_id, qty, product_type, $form);
2325                    Analytics.onWooAddToCartOnSingleEvent(product_id, qty, product_type, $form);
2326
2327                    Pinterest.onWooAddToCartOnSingleEvent(product_id, qty, product_type, false, $form);
2328                    Bing.onWooAddToCartOnSingleEvent(product_id, qty, product_type, false, $form);
2329
2330                });
2331
2332            }
2333
2334            // WooCommerce RemoveFromCart
2335            if (options.dynamicEvents.hasOwnProperty("woo_remove_from_cart")) {
2336
2337                $('body').on('click', options.woo.removeFromCartSelector, function (e) {
2338
2339                    var $a = $(e.currentTarget),
2340                        href = $a.attr('href');
2341
2342                    // extract cart item hash from remove button URL
2343                    var regex = new RegExp("[\\?&]remove_item=([^&#]*)"),
2344                        results = regex.exec(href);
2345
2346                    if (results !== null) {
2347
2348                        var item_hash = results[1];
2349
2350                        if (options.dynamicEvents["woo_remove_from_cart"].hasOwnProperty(item_hash)) {
2351                            var events = options.dynamicEvents["woo_remove_from_cart"][item_hash];
2352                            Utils.fireEventForAllPixel("onWooRemoveFromCartEvent",events)
2353                        }
2354
2355                    }
2356
2357                });
2358            }
2359        }
2360
2361        // setup EDD events
2362        if (options.edd.enabled) {
2363
2364            // EDD AddToCart
2365            if (options.dynamicEvents.hasOwnProperty("edd_add_to_cart_on_button_click")) {
2366
2367                $('form.edd_download_purchase_form .edd-add-to-cart').on("click",function (e) {
2368
2369                    var $button = $(this);
2370                    var $form = $button.closest('form');
2371                    var variable_price = $button.data('variablePrice'); // yes/no
2372                    var price_mode = $button.data('priceMode'); // single/multi
2373                    var ids = [];
2374                    var quantities = [];
2375                    var qty;
2376                    var id;
2377
2378                    if (variable_price === 'yes' && price_mode === 'multi') {
2379
2380                        id = $form.find('input[name="download_id"]').val();
2381
2382                        // get selected variants
2383                        $.each($form.find('input[name="edd_options[price_id][]"]:checked'), function (i, el) {
2384                            ids.push(id + '_' + $(el).val());
2385                        });
2386
2387                        // get qty for selected variants
2388                        $.each(ids, function (i, variant_id) {
2389
2390                            var variant_index = variant_id.split('_', 2);
2391                            qty = $form.find('input[name="edd_download_quantity_' + variant_index[1] + '"]').val();
2392
2393                            if (typeof qty !== 'undefined') {
2394                                quantities.push(qty);
2395                            } else {
2396                                quantities.push(1);
2397                            }
2398
2399                        });
2400
2401                    } else if (variable_price === 'yes' && price_mode === 'single') {
2402
2403                        id = $form.find('input[name="download_id"]').val();
2404                        ids.push(id + '_' + $form.find('input[name="edd_options[price_id][]"]:checked').val());
2405
2406                        qty = $form.find('input[name="edd_download_quantity"]').val();
2407
2408                        if (typeof qty !== 'undefined') {
2409                            quantities.push(qty);
2410                        } else {
2411                            quantities.push(1);
2412                        }
2413
2414                    } else {
2415
2416                        ids.push($button.data('downloadId'));
2417
2418                        qty = $form.find('input[name="edd_download_quantity"]').val();
2419
2420                        if (typeof qty !== 'undefined') {
2421                            quantities.push(qty);
2422                        } else {
2423                            quantities.push(1);
2424                        }
2425                    }
2426
2427                    // fire event for each download/variant
2428                    $.each(ids, function (i, download_id) {
2429
2430                        var q = parseInt(quantities[i]);
2431                        var variant_index = download_id.toString().split('_', 2);
2432                        var price_index;
2433
2434                        if (variant_index.length === 2) {
2435                            download_id = variant_index[0];
2436                            price_index = variant_index[1];
2437                        }
2438
2439                        Facebook.onEddAddToCartOnButtonEvent(download_id, price_index, q);
2440                        Analytics.onEddAddToCartOnButtonEvent(download_id, price_index, q);
2441                        Pinterest.onEddAddToCartOnButtonEvent(download_id, price_index, q);
2442                        Bing.onEddAddToCartOnButtonEvent(download_id, price_index, q);
2443
2444                    });
2445
2446                });
2447
2448            }
2449
2450
2451            // EDD RemoveFromCart
2452            if (options.dynamicEvents.hasOwnProperty("edd_remove_from_cart") ) {
2453
2454                $('form#edd_checkout_cart_form .edd_cart_remove_item_btn').on("click",function (e) {
2455
2456                    var href = $(this).attr('href');
2457                    if(href) {
2458                        var key = href.substring(href.indexOf('=') + 1).charAt(0);
2459                        if (options.dynamicEvents.edd_remove_from_cart.hasOwnProperty(key)) {
2460                            var events = options.dynamicEvents.edd_remove_from_cart[key];
2461                            Utils.fireEventForAllPixel("onEddRemoveFromCartEvent",events)
2462                        }
2463                    }
2464                });
2465
2466            }
2467
2468        }
2469
2470        // setup Comment Event
2471        if (options.dynamicEvents.hasOwnProperty("automatic_event_c
2471omment")
2472        ) {
2473
2474            $('form.comment-form').on("submit",function () {
2475                if (options.dynamicEvents.hasOwnProperty("automatic_event_comment")) {
2476                    var pixels = Object.keys(options.dynamicEvents.automatic_event_comment);
2477                    for (var i = 0; i < pixels.length; i++) {
2478                        var event = Utils.clone(options.dynamicEvents.automatic_event_comment[pixels[i]]);
2479                        Utils.copyProperties(Utils.getRequestParams(), event.params);
2480                        getPixelBySlag(pixels[i]).onCommentEvent(event);
2481                    }
2482                }
2483            });
2484
2485        }
2486
2487
2488        // setup Form Event
2489        if ( options.dynamicEvents.hasOwnProperty("automatic_event_form")) {
2490
2491            $(document).onFirst('submit', 'form', function (e) {
2492
2493                var $form = $(this);
2494
2495                // exclude WP forms
2496                if ($form.hasClass('comment-form') || $form.hasClass('search-form') || $form.attr('id') === 'adminbarsearch') {
2497                    return;
2498                }
2499
2500                // exclude Woo forms
2501                if ($form.hasClass('woocommerce-product-search') || $form.hasClass('cart') || $form.hasClass('woocommerce-cart-form') ||
2502                    $form.hasClass('woocommerce-shipping-calculator') || $form.hasClass('checkout') || $form.hasClass('checkout_coupon')) {
2503                    return;
2504                }
2505
2506                // exclude EDD forms
2507                if ($form.hasClass('edd_form') || $form.hasClass('edd_download_purchase_form')) {
2508                    return;
2509                }
2510// exclude CF7 forms
2511                if ($form.hasClass('wpcf7-form')) {
2512                    return;
2513                }
2514                // exclude Forminator forms
2515                if ($form.hasClass('forminator-custom-form') || $form.hasClass('forminator_ajax')) {
2516                    return;
2517                }
2518                // exclude WPforms forms
2519                if ($form.hasClass('wpforms-form') || $form.hasClass('wpforms-ajax-form')) {
2520                    return;
2521                }
2522                // exclude Formidable forms
2523                /*if ($form.hasClass('frm-show-form')) {
2524                    return;
2525                }*/
2526                // exclude Ninja Forms forms
2527                if ($form.parent().hasClass('nf-form-layout')) {
2528                    return;
2529                }
2530                // exclude Fluent forms
2531                if ($form.hasClass('frm-fluent-form')) {
2532                    return;
2533                }
2534                if(!options.enable_success_send_form) {
2535                    var params = {
2536                        form_id: $form.attr('id'),
2537                        form_class: $form.attr('class'),
2538                        text: $form.find('[type="submit"]').is('input') ?
2539                            $form.find('[type="submit"]').val() : $form.find('[type="submit"]').text()
2540                    };
2541
2542                    if (options.dynamicEvents.hasOwnProperty("automatic_event_form")) {
2543                        var pixels = Object.keys(options.dynamicEvents.automatic_event_form);
2544                        for (var i = 0; i < pixels.length; i++) {
2545                            var event = Utils.clone(options.dynamicEvents.automatic_event_form[pixels[i]]);
2546
2547                            if (pixels[i] === "tiktok") {
2548                                getPixelBySlag(pixels[i]).fireEvent(event.name, event);
2549                            } else {
2550                                Utils.copyProperties(params, event.params,)
2551                                Utils.copyProperties(Utils.getRequestParam
2551s(), event.params);
2552                                getPixelBySlag(pixels[i]).onFormEvent(event);
2553                            }
2554                        }
2555                    }
2556                }
2557            });
2558
2559            document.addEventListener( 'wpcf7mailsent', function( event ) {
2560                var form_id = event.detail.contactFormId;
2561                sendFormAction($(event.target), form_id);
2562            }, false );
2563            //Forminator
2564            $(document).on( 'forminator:form:submit:success', function( event ){
2565                var form_id = $(event.target).find('input[name="form_id"]').val();
2566                sendFormAction($(event.target), form_id);
2567            });
2568
2569            //WPForm
2570            $('form.wpforms-form').on('wpformsAjaxSubmitSuccess', (event) => {
2571                var form_id = $(event.target).attr('data-formid');
2572                sendFormAction($(event.target), form_id);
2573            })
2574            $(document).on( 'frmFormComplete', function( event, form, response ) {
2575                const form_id = $(form).find('input[name="form_id"]').val();
2576                sendFormAction($(event.target), form_id);
2577            });
2578            // Ninja Forms
2579            $(document).onFirst('nfFormSubmitResponse', function (event, data) {
2580                const form_id = data.response.data.form_id;
2581                sendFormAction($(event.target), form_id);
2582            });
2583
2584            var fluentForms = $('form.frm-fluent-form');
2585            fluentForms.each(function() {
2586                var $form = $(this);
2587                $form.on('fluentform_submission_success', function(event) {
2588                    var $formItem = $(this);
2589                    var form_id = $formItem.attr('data-form_id');
2590                    sendFormAction($(event.target), form_id);
2591                });
2592            });
2593
2594        }
2595
2596
2597        // load pixel APIs
2598        Utils.loadPixels();
2599        // setup Enrich content
2600        if(Utils.isCheckoutPage()) {
2601            Utils.addCheckoutFields();
2602        }
2603    });
2604
2605    var sendFormAction = function (form_target, formId){
2606        var params = {
2607            form_id: formId,
2608            text: form_target.find('[type="submit"]').is('input') ? form_target.find('[type="submit"]').val() :
2609                form_target.find('.forminator-button-submit').text() != '' ? form_target.find('.forminator-button-submit').text() :
2610                    form_target.find('[type="submit"]').text()
2611        };
2612
2613        if (options.dynamicEvents.hasOwnProperty("automatic_event_form")) {
2614            var pixels = Object.keys(options.dynamicEvents.automatic_event_form);
2615            for (var i = 0; i < pixels.length; i++) {
2616                var event = options.dynamicEvents.automatic_event_form[pixels[i]];
2617                if (pixels[i] === "tiktok") {
2618                    getPixelBySlag(pixels[i]).fireEvent(event.name, event);
2619                } else {
2620                    Utils.copyProperties(params, event.params)
2621                    Utils.copyProperties(Utils.getRequestParams(), event.params);
2622                    getPixelBySlag(pixels[i]).onFormEvent(event);
2623                }
2624            }
2625        }
2626    }
2627
2628}(jQuery, pysOptions);
2629
2630function pys_generate_token(length){
2631    //edit the token allowed characters
2632    var a = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890".split("");
2633    var b = [];
2634    for (var i=0; i<length; i++) {
2635        var j = (Math.random() * (a.length-1)).toFixed(0);
2636        b[i] = a[j];
2637    }
2638    return b.join("");
2639}
2640
2641function getBundlePriceOnSingleProduct(data) {
2642    var items_sum = 0;
2643    jQuery(".bundle_form .bundled_product").each(function(index){
2644        var id = jQuery(this).find(".cart").data("bundled_item_id");
2645        var item_price = data.prices[id];
2646        var item_quantity = jQuery(this).find(".bundled_qty").val();
2647        if(!jQuery(this).hasClass("bundled_item_optional") ||
2648            jQuery(this).find(".bundled_product_optional_checkbox input").prop('checked')) {
2649            items_sum += item_price*item_quantity;
2650        }
2651    });
2652    return items_sum;
2653}
2654
2655function getPixelBySlag(slug) {
2656    switch (slug) {
2657        case "facebook": return window.pys.Facebook;
2658        case "ga": return window.pys.Analytics;
2659        case "bing": return window.pys.Bing;
2660        case "pinterest": return window.pys.Pinterest;
2661    }
2662}
2663var getUrlParameter = function getUrlParameter(sParam) {
2664    var sPageURL = window.location.search.substring(1),
2665        sURLVariables = sPageURL.split('&'),
2666        sParameterName,
2667        i;
2668
2669    for (i = 0; i < sURLVariables.length; i++) {
2670        sParameterName = sURLVariables[i].split('=');
2671
2672        if (sParameterName[0] === sParam) {
2673            return sParameterName[1] === undefined ? true : decodeURIComponent(sParameterName[1]);
2674        }
2675    }
2676    return false;
2677};

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.