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