PageSourceSearch

https://www.smumn.edu/wp-content/plugins/handl-utm-grabber-v3/js/handl-utm-grabber.js?ver=1789124850

js smumn.edu collected 2026-09-24 19:14:41 UTC 34,466 bytes, 956 lines download raw bytes

1// (function(history){
2//     var replaceState = history.replaceState;
3//     history.replaceState = function(state) {
4//         if (typeof history.onreplacestate == "function") {
5//             history.onreplacestate({state: state});
6//         }
7//         return replaceState.apply(history, arguments);
8//     };
9// })(window.history);
10//
11// window.onpopstate = history.onreplacestate = function(e) {
12//     var domain = getDomainName()
13//     console.log(e.state.path)
14//     Cookies.set('handl_url', e.state.path, {
15//         expires: parseInt(handl_utm_cookie_duration[0]),
16//         domain: domain,
17//         sameSite:'None',
18//         secure: true }
19//     );
20// }
21
22var qvars = getUrlVars()
23var domain = getDomainName()
24
25jQuery(function($) {
26    if (handl_utm_cookie_duration[1] === '1' &&
27        typeof(TVE) === "undefined" //thrive editor fix
28    ){
29        console.log('Running HandL');
30        RunHandL()
31
32        const borlabsCookie = Cookies.get('borlabs-cookie'); // Get the cookie as a JSON string
33        if (borlabsCookie) {
34            try {
35                // Parse the JSON string into an object
36                const cookieData = JSON.parse(borlabsCookie);
37
38                // Check if the 'marketing' key has 'handl-utm-grabber'
39                if (cookieData.consents.marketing.includes('handl-utm-grabber')) {
40                    console.log("handl-utm-grabber checked by Borlabs.. RunHandL...");
41                    RunHandL()
42                } else {
43                    console.log("handl-utm-grabber not checked by Borlabs"); // or return false;
44                }
45            } catch (e) {
46                console.error('Error parsing JSON:', e);
47            }
48        }
49    }
50});
51
52
53function RunHandL(){
54    window.utms_js = {}
55    window.gaNames = []
56
57    //simulate referrer locally
58    // Object.defineProperty(document, "referrer", {get : function(){ return "https://google.com"; }});
59
60    SetRefLink('handlID', Math.floor(Math.random() * Date.now()), false, 0)
61
62    GAClientID()
63    setHandLParams()
64
65    // console.log("after handl params")
66
67    RunFieldFiller()
68    // Occasionally, the page takes longer to render, so it makes sense to introduce a delay. However, we have not yet investigated the potential negative effects of doing this when it is not necessary.
69    // setTimeout(RunFieldFiller, 1000)
70
71    jQuery.each(handl_utm_predefined, function( i,v ) {
72        let cookie_name = v.name;
73        let value = v.value
74
75        if ( value.startsWith('[') && value.endsWith(']') ){ //it's a shortcode!
76            value = v.value.replace(/^\[|\]$/g,'');
77        }else{ //it is a hardcoded default value
78            value = cookie_name
79        }
80
81        if ( ['_ga','gaclientid'].indexOf(value) > -1 ){
82            gaNames.push(cookie_name)
83        }
84
85        if (cookie_name != ''){
86            var cookie_field = GetQVars(value,qvars)
87
88            if (cookie_field == ''){
89                cookie_field = Cookies.get(value)
90            }
91
92            if ( cookie_field != '' && cookie_field != 'PANTHEON_STRIPPED' ){
93                utms_js[cookie_name] = cookie_field
94                SetRefLink(cookie_name, cookie_field, true, 0)
95            }
96        }
97    })
98
99    populateLinks()
100
101    jQuery(document).on( 'nfFormReady', function() {
102        // Loop through each form in nfForms array
103        nfForms.forEach(form => {
104            form.fields.map(item => {
105                if (item.default) {
106                    var matches = String(item.default).match(/^{(\w+):(\w+)/)
107                    if (matches && matches.length == 3) {
108                        let key = matches[1]
109                        let value = matches[2]
110
111                        if (key === 'handl') {
112                            console.log(key, value)
113                            jQuery('#nf-field-' + item.id).val(Cookies.get(value))
114                        }
115                    }
116                }
117            })
118        })
119
120        //hide hidden fields
121        // jQuery('.nf-field-container.hidden-container').map( (i, item) => jQuery(item).parents().eq(4).hide())
122    })
123
124    document.dispatchEvent(new Event('HandL-After-Main-Function'));
125}
126
127function RunFieldFiller(){
128
129    let cookieOptions = {
130        domain: domain,
131        secure: true,
132        sameSite: 'None'
133    };
134
135    if (!parseInt(handl_utm_session_cookies?.enabled)) {
136        cookieOptions.expires = parseInt(handl_utm_cookie_duration[0]);
137    }
138
139    Cookies.set('user_agent', navigator.userAgent, cookieOptions)
140
141    jQuery.each(handl_utm_all_params, function( i,vi ) {
142        var cookie_field = GetQVars(vi,qvars)
143
144        var cookie_params = [vi]
145        if ( handl_utm_first_touch_params.includes(vi) )
146            cookie_params.push('first_'+vi)
147
148        cookie_params.forEach( (v, ind) => {
149
150            if ( cookie_field != '' && cookie_field != 'PANTHEON_STRIPPED' ){
151                if ( v.startsWith('first_') && Cookies.get(v) != undefined ){
152                            //do not update the first attributes...
153                }else{
154                    if (cookie_field.includes('#')) {
155                        cookie_field = cookie_field.split('#')[0];
156                    }
157
158                    let cookieOptions = {
159                        domain: domain,
160                        sameSite: 'None',
161                        secure: true
162                    };
163
164                    if (!parseInt(handl_utm_session_cookies?.enabled)) {
165                        cookieOptions.expires = parseInt(handl_utm_cookie_duration[0]);
166                    }
167
168                    Cookies.set(v, cookie_field, cookieOptions);
169                }
170            }
171
172            var curval = decodeURI(Cookies.get(v))
173            curval = curval != 'undefined' ? curval : ''
174            if (curval != 'undefined') {
175                curval = sanitizeInput(curval);
176                utms_js[v] = curval
177                curval = decodeURIComponent(curval)
178                // curval = curval.replace(/[%]/g,' ')
179                if (v == 'username') {
180                    //Maybe this should apply to all... We'll see...
181                    curval = curval.replace(/\+/g, ' ')
182                }
183
184                jQuery('input[name=\"'+v+'\"]').val(curval)
185                jQuery('input#'+v).val(curval)
186                jQuery('input.'+v).val(curval)
187                jQuery('input#form-field-'+v).val(curval)
188
189                //for nested input fix
190                jQuery('#'+v).find('input').val(curval)
191                jQuery('.'+v).find('input').val(curval)
192
193                jQuery("[data-original_id='"+v+"']").val(curval)
194                jQuery("[data-name='"+v+"']").val(curval)
195                jQuery("[data-name='"+v.replace(/_/g,'')+"']").val(curval) //Active Campaign
196                jQuery("[placeholder='"+v+"']").val(curval) //Dyanmics 365 + Generic
197
198
199
200                if (v.length > 4){ // this is for making sure wildcards are not hyper sensitive.
201                    //wildcard selector
202                    jQuery("[name*="+v+"]").val(curval)
203                    jQuery("[id*="+v+"]").val(curval)
204                    jQuery("[class*="+v+"]").val(curval)
205
206                    jQuery("[class*="+v+"_out]").html(curval)
207                    jQuery("[id*="+v+"_out]").html(curval)
208                }
209
210            }
211        })
212    });
213}
214
215function handlUtmIsInsideAdminBar($el) {
216    return $el.closest('#wpadminbar').length > 0;
217}
218
219function populateLinks(){
220    jQuery('.utm-out-js, .utm-out-js a').each(function(){
221        var $el = jQuery(this);
222        if (handlUtmIsInsideAdminBar($el)) {
223            return;
224        }
225        var merged_raw = jQuery.extend( {}, utms_js )
226        var merged = Object.keys(merged_raw)
227            .filter(key => handl_utm_append_params.includes(key))
228            .reduce((obj, key) => {
229                if (merged_raw[key]) {
230                    obj[key] = decodeURIComponent(merged_raw[key]);
231                }
232                return obj;
233            }, {});
234        merged = jQuery.extend(merged, getSearchParams(this.href))
235        var current_page = window.location.href.split('?')[0]
236        if (
237            this.href !== undefined &&
238            this.href !== "" &&
239            !this.href.match("#") &&
240            !this.href.startsWith("tel:") &&
241            !this.href.startsWith("mailto:") &&
242            !this.href.startsWith("sms:") &&
243            !jQuery(this).attr('onclick') &&
244            !jQuery(this).closest('.no-utm').length // Check if the link or any of its parents have the no-utm class
245            // this.href.match(new RegExp("^"+current_page+"$")) == null
246        ){
247            var href = this.href.split("?")[0];
248            if ( !jQuery.isEmptyObject(merged) )
249                this.href = href+"?"+decodeURIComponent(jQuery.param(merged))
250        }
251    })  ;
252
253    // console.log(handl_utm)
254    // console.log(utms_js)
255
256    jQuery('.utm-out, .utm-out a').each(function(){
257        var $el = jQuery(this);
258        if (handlUtmIsInsideAdminBar($el)) {
259            return;
260        }
261        var merged_raw = jQuery.extend( {}, handl_utm, utms_js )
262        var merged = Object.keys(merged_raw)
263            .filter(key => handl_utm_append_params.includes(key))
264            .reduce((obj, key) => {
265                if (merged_raw[key]) {
266                    obj[key] = decodeURIComponent(merged_raw[key]);
267                }
268                return obj
269            }, {});
270        merged = jQuery.extend(merged, getSearchParams(this.href))
271        var current_page = window.location.href.split('?')[0]
272        if (
273            this.href !== undefined &&
274            this.href !== "" &&
275            !this.href.match("#") &&
276            !this.href.startsWith("tel:") &&
277            !this.href.startsWith("mailto:") &&
278            !this.href.startsWith("sms:") &&
279            !jQuery(this).closest('.no-utm').length // Check if the link or any of its parents have the no-utm class
280            // !jQuery(this).attr('onclick') &&
281            // this.href.match(new RegExp("^"+current_page+"$")) == null
282        ){
283            var href = this.href.split("?")[0];
284            var parts = []
285            if (this.href.match("#")){
286                parts = this.href.split("#")
287                if (parts[1] != ""){
288                    href = parts[0]
289                }
290            }
291
292            // console.log(parts, href)
293            if ( !jQuery.isEmptyObject(merged)  ){
294                if (this.href.match("#") && parts.length == 2){
295                    this.href = href+"?"+decodeURIComponent(jQuery.param(merged))+"#"+parts[1].split("?")[0]
296                }else{
297                    this.href = href+"?"+decodeURIComponent(jQuery.param(merged))
298                }
299            }
300        }
301    });
302
303    jQuery('.utm-src').each(function(){
304        if (handlUtmIsInsideAdminBar(jQuery(this))) {
305            return;
306        }
307        var target_url
308        if (this.src){
309            target_url = this.src
310        }else if (jQuery(this).data('url')){
311            target_url = jQuery(this).data('url')
312        }else if (jQuery(this).data('src')){
313            target_url = jQuery(this).data('src')
314        }
315
316        var merged_raw = jQuery.extend( {}, handl_utm, utms_js )
317        var merged = Object.keys(merged_raw)
318            .filter(key => handl_utm_append_params.includes(key))
319            .reduce((obj, key) => {
320                if (merged_raw[key]) {
321                    obj[key] = decodeURIComponent(merged_raw[key]);
322                }
323                return obj;
324            }, {});
325        merged = jQuery.extend( merged, getSearchParams(target_url) )
326
327        var src = target_url.split("?")[0];
328        if ( !jQuery.isEmptyObject(merged) ){
329            var final_target = src + "?" + decodeURIComponent(jQuery.param(merged))
330            if (this.src) {
331                this.src = final_target
332            }else if (jQuery(this).data('url')){
333                jQuery(this).data('url', final_target)
334            }
335        }
336    });
337
338    jQuery("[data-fillout-id]").each(function(){
339        handl_utm_append_params.map(t=>{
340            jQuery(this).attr(`data-${t}`, utms_js[t])
341        })
342
343        var script = document.createElement('script');
344        script.src ='https://server.fillout.com/embed/v1/';
345        document.head.appendChild(script);
346
347    })
348}
349
350function getSearchParams(url,k){
351    var p={};
352    var a = document.createElement('a');
353    a.href = url;
354    a.search.replace(/[?&]+([^=&]+)=([^&]*)/gi,function(s,k,v){p[k]=v})
355    return k?p[k]:p;
356}
357
358function GetQVars(v,qvars){
359    if (qvars[v] != undefined) {
360        return qvars[v]
361    }
362    return ''
363}
364
365function getUrlVars() {
366    var vars = {};
367    window.location.href.replace(/[?&]+([^=&]+)=([^&]*)/gi, function(m,key,value) {
368        vars[key] = decodeURIComponent(value);
369    });
370    return vars;
371}
372
373function GAClientID(){
374    if ( typeof(ga) == 'function' && typeof(ga.getAll) == 'function'){
375        var trackers = ga.getAll();
376        if (trackers.length > 0 ){
377            //maybe we'll update this later, so we can loop all the tracking ids...
378            var entries = Object.entries({"clientId":"gaclientid","referrer":"organic_source"})
379            var domain = getDomainName()
380            for (const [gaName, handlName] of entries) {
381                var gaValue = trackers[0].get(gaName)
382                if (gaValue !== undefined) {
383                    if (gaName != 'clientId'){ // we should reset the array for anythng other than clientId
384                        gaNames = []
385                    }
386
387                    gaNames.push(handlName)
388
389                    for (const curName of gaNames){
390                        // console.log(curName, gaValue)
391                        utms_js[curName] = gaValue
392                        let cookieOptions = {
393                            domain: domain,
394                            sameSite: 'None',
395                            secure: true
396                        };
397
398                        if (!parseInt(handl_utm_session_cookies?.enabled)) {
399                            cookieOptions.expires = parseInt(handl_utm_cookie_duration[0]);
400                        }
401
402                        Cookies.set(curName, gaValue, cookieOptions);
403                        // console.log(`Setting ${handlName} as ${gaValue}`)
404                        jQuery('input[name=\"' + curName + '\"]').val(gaValue)
405                        jQuery('input#' + curName).val(gaValue)
406                        jQuery('input.' + curName).val(gaValue)
407                    }
408
409                    // so we can include gaclientid to the links incase needed
410                    populateLinks()
411                }
412            }
413        }
414    }else{
415        setTimeout(GAClientID,500);
416    }
417}
418
419function getDomainName(){
420    var name="HandLtestDomainName"
421    var value="HandLtestDomainValue"
422    var host=location.host
423    var domain;
424
425    // Use the configured domain instead of probing with a test c
425ookie.
426    if (typeof handl_utm_cookie_domain !== 'undefined' && handl_utm_cookie_domain[0]) {
427        var configuredDomain = handl_utm_cookie_domain[0]
428        var configuredHost = configuredDomain.replace(/^\./, '').toLowerCase()
429        var currentHost = location.hostname.toLowerCase()
430        if (currentHost !== configuredHost && !currentHost.endsWith('.' + configuredHost)) {
431            console.warn('HandL UTM Grabber: the Domain setting "' + configuredDomain + '" does not match this site\'s host "' + location.hostname + '" — the browser may reject cookies set for that domain. Update it in HandL UTM Grabber → Options.')
432        }
433        return configuredDomain
434    }
435
436    if (host.split('.').length === 1){
437        domain = '';
438    }else{
439        var domainParts = host.split('.');
440        domainParts.shift();
441        domain = '.'+domainParts.join('.');
442        Cookies.set(name, value, {
443            domain: domain,
444            secure: true,
445            sameSite: 'None'
446        })
447        if (Cookies.get(name) == null || Cookies.get(name) != value)
448        {
449            domain = '.'+host;
450        }
451    }
452
453    return domain;
454}
455
456function setHandLParams(){
457    // console.log("set handl params")
458
459    SetRefLink('handl_url_base', document.location.origin + document.location.pathname, true, 0)
460    SetRefLink('handl_url', document.location.href, true, 0)
461    SetRefLink('handl_ref', document.referrer, true, 0)
462    SetRefLink('handl_ref_domain', document.referrer == '' ? '' : this.get_url_domain(document.referrer), true, 0)
463    SetRefLink('handl_landing_page', document.location.href, false, 0)
464    SetRefLink('handl_landing_page_base', new URL(document.location.href).origin + new URL(document.location.href).pathname, false, 0)
465    SetRefLink('handl_original_ref', document.referrer, false, 0)
466
467    let original_ref =  Cookies.get('handl_ref_domain')
468    let this_domain = document.location.host
469    let source = "Other";
470    if (original_ref == '') {
471        source = "Direct";
472    }else if ( original_ref.match(/google\.co.*/i) !== null ){
473        source = "Google";
474    }else if ( original_ref.match(/bing\.co.*/i) !== null ){
475        source = "Bing";
476    }else if ( original_ref.match(/instagram\.co.*/i) !== null ){
477        source = "Instagram";
478    }else if ( original_ref.match(/facebook\.co.*/i) !== null || original_ref.match(/fb\.co.*/i) !== null ){
479        source = "Facebook";
480    }else if ( original_ref.match(/reddit\.com/i) !== null ){
481        source = "Reddit";
482    }else if ( original_ref.match(/twitter\.com/i) !== null || original_ref.match(/t\.co$/i) !== null || original_ref.match(/x\.com$/i) !== null ){
483        source = "Twitter";
484    }else if ( original_ref.match(/snapchat\.co.*/i) !== null ){
485        source = "Snapchat";
486    }else if ( original_ref.match(/youtube\.co.*/i) !== null ){
487        source = "YouTube";
488    }else if ( original_ref.match(/pinterest\.co.*/i) !== null ){
489        source = "Pinterest";
490    }else if ( original_ref.match(/linkedin\.co.*/i) !== null ){
491        source = "LinkedIn";
492    }else if ( original_ref.match(/tumblr\.com/i) !== null ){
493        source = "Tumblr";
494    }else if ( original_ref.match(/duckduckgo\.co.*/i) !== null ){
495        source = "Duckduckgo";
496    }else if ( original_ref.match(/openai\.com/i) !== null || original_ref.match(/chatgpt\.com/i) !== null ){
497        source = "OpenAI";
498    }else if ( original_ref.match(/perplexity\.ai/i) !== null ){
499        source = "Perplexity";
500    }else if ( original_ref.match(/claude\.ai/i) !== null ){
501        source = "Claude";
502    }else if ( original_ref.match(/gemini\.google\.com/i) !== null ){
503        source = "Gemini";
504    }else if ( original_ref.match(/copilot\.microsoft\.com/i) !== null ){
505        source = "Copilot";
506    }else if ( original_ref.match(/yelp\.com/i) !== null ){
507        source = "Yelp";
508    }else if (this_domain == original_ref){
509        source = "Internal";
510    }
511
512    if(
513        ( !Cookies.get('organic_source_str') || Cookies.get('organic_source_str') == '' ) ||
514        ( Cookies.get('organic_source_str') && Cookies.get('organic_source_str') != '' && ['Internal','Direct'].indexOf(source) == -1 )
515    ){
516        SetRefLink('organic_source', document.referrer, true, 0)
517        SetRefLink('organic_source_str', source, true, 0)
518    }
519
520    var qvars = getUrlVars()
521    var googlePaidFromQuery =
522        Object.keys(qvars).indexOf('gad_source') !== -1 ||
523        Object.keys(qvars).indexOf('gad_campaignid') !== -1 ||
524        Object.keys(qvars).indexOf('gclid') !== -1 ||
525        Object.keys(qvars).indexOf('wbraid') !== -1 ||
526        Object.keys(qvars).indexOf('gbraid') !== -1
527    var googlePaidFromCookie =
528        Cookies.get('gclid') !== undefined ||
529        Cookies.get('wbraid') !== undefined ||
530        Cookies.get('gbraid') !== undefined
531    if (googlePaidFromQuery || googlePaidFromCookie) {
532        SetRefLink('organic_source_str', 'Google', true, 0)
533    }
534
535    let traffic_source = 'Other'
536    if (
537        Cookies.get('gclid') != undefined ||
538        Cookies.get('msclkid') != undefined ||
539        Cookies.get('wbraid') != undefined ||
540        Cookies.get('gbraid') != undefined ||
541        Object.keys(qvars).indexOf('gclid') != -1 ||
542        Object.keys(qvars).indexOf('msclkid') != -1 ||
543        Object.keys(qvars).indexOf('wbraid') != -1 ||
544        Object.keys(qvars).indexOf('gbraid') != -1 ||
545        (Cookies.get('fbclid') != undefined && Cookies.get('_fbc') != undefined) ||
546        (Object.keys(qvars).indexOf('fbclid') != -1 && Cookies.get('_fbc') != undefined) ||
547        Object.keys(qvars).indexOf('gad_source') != -1 ||
548        Object.keys(qvars).indexOf('gad_campaignid') != -1 
549    ){
550        traffic_source = 'Paid'
551    }
551else if ( ['Google','Bing','Yahoo','Duckduckgo'].indexOf(Cookies.get('organic_source_str')) > -1 ){
552        traffic_source = 'Organic'
553    }else if ( ['Facebook','Twitter','Instagram','Snapchat','YouTube','Pinterest','LinkedIn','Tumblr','Reddit'].indexOf(Cookies.get('organic_source_str')) > -1 ){
554        traffic_source = 'Social'
555    }else if ( ['Internal','Direct'].indexOf(Cookies.get('organic_source_str')) > -1 ){
556        traffic_source = 'Direct'
557    }else if ( Cookies.get('organic_source_str') && ['Internal'].indexOf(Cookies.get('organic_source_str')) == -1 ){
558        traffic_source = 'Referral'
559    }
560
561    SetRefLink('traffic_source', traffic_source, true, 0)
562    SetRefLink('first_traffic_source', traffic_source, false, 0)
563
564    document.dispatchEvent(new CustomEvent('handl_cookies_set'));
565
566}
567
568function SetRefLink(field, value, overwrite, count){
569    // console.log(`Trying ${count} for ${field} ---> ${value}`)
570    var domain = getDomainName()
571
572    if (Cookies.get(field) != value) {
573        if (Cookies.get(field) !== undefined && Cookies.get(field) != "" && !overwrite ){
574            //bail...
575            // console.log(`No need to update... ${field}`)
576        }else if (Cookies.get(field) === undefined || Cookies.get(field) == '' || overwrite) {
577            if (count == undefined) {
578                count = 0
579            }
580
581            // utms_js[field] = value //not sure if we really need it here
582            // console.log(`Setting cookies for ${field} as ${value}`)
583            let cookieOptions = {
584                domain: domain,
585                sameSite: 'None',
586                secure: true
587            };
588
589            if (!parseInt(handl_utm_session_cookies?.enabled)) {
590                cookieOptions.expires = parseInt(handl_utm_cookie_duration[0]);
591            }
592
593            Cookies.set(field, value, cookieOptions);
594
595        } else {
596            count = count + 1
597            if (count < 3) {
598                setTimeout(function () {
599                    SetRefLink(field, value, overwrite, count)
600                }, 500)
601            }
602        }
603    }
604}
605
606function get_url_domain(url) {
607    let a      = document.createElement('a');
608    a.href = url;
609    return a.hostname;
610}
611
612//This is for OptinMonster events: https://optinmonster.com/docs/optinmonster-javascript-events-api/
613document.addEventListener('om.Campaign.afterShow',function(){
614    RunFieldFiller()
615})
616
617window.addEventListener('CookiebotOnAccept', function (e) {
618    if (Cookiebot.consent.marketing)
619    {
620        RunHandL()
621    }
622}, false);
623
624document.addEventListener("cmplz_enable_category", function(consentData) {
625    var category = consentData.detail.category;
626    if (category==='marketing'){
627        RunHandL()
628    }
629});
630
631// Marketing consent granted -> capture; withdrawn -> clean up. No reload.
632function HandLOnMarketingConsentChange(changedConsentCategory) {
633    for (var key in changedConsentCategory) {
634        if (changedConsentCategory.hasOwnProperty(key)) {
635            if (key === 'marketing' && changedConsentCategory[key] === 'allow') {
636                console.log('Consent: Marketing consent granted, running HandL');
637                RunHandL();
638            } else if (key === 'marketing' && changedConsentCategory[key] === 'deny') {
639                console.log('Consent: Marketing consent withdrawn, removing HandL cookies');
640                RemoveHandLCookies();
641            }
642        }
643    }
644}
645
646// WP Consent API broadcasts (any consent manager, incl. our banner in manager mode).
647document.addEventListener('wp_listen_for_consent_change', function (e) {
648    HandLOnMarketingConsentChange(e.detail);
649});
650
651// Our banner's own event, standalone mode.
652document.addEventListener('handl_consent_change', function (e) {
653    HandLOnMarketingConsentChange(e.detail);
654});
655
656// Check if consent already exists on page load
657if (typeof wp_has_consent === 'function' && wp_has_consent('marketing')) {
658    console.log('WP Consent API: Marketing consent already granted');
659}
660
661// ===== WPConsent (Cookies Banner & Privacy Suite) native integration =====
662(function () {
663    function handlWPConsentRun(prefs) {
664        if (prefs && prefs.marketing) {
665            console.log('WPConsent: marketing consent granted, running HandL');
666            RunHandL();
667        }
668    }
669    // Fires on first save and on later updates (detail = preferences object).
670    window.addEventListener('wpconsent_consent_updated', function (e) { handlWPConsentRun(e.detail); });
671    window.addEventListener('wpconsent_consent_saved',   function (e) { handlWPConsentRun(e.detail); });
672    // Already-consented visitors: WPConsent calls back immediately if state is known.
673    if (window.WPConsent && typeof WPConsent.registerListener === 'function') {
674        WPConsent.registerListener(handlWPConsentRun);
675    }
676})();
677
678
679function afterBookingSelectDateAndTime(a){
680    Object.keys(a.bookings[0].customFields).forEach(function(key) {
681        let label = a.bookings[0].customFields[key].label
682        if (Cookies.get(label)){
683            a.bookings[0].customFields[key].value = Cookies.get(label)
684        }
685    });
686}
687
688window.ameliaActions = {
689    beforeBooking: function(x,y,a){
690        afterBookingSelectDateAndTime(a)
691        x()
692    }
693}
694
695/*
696FormStack solution...
697 */
698function FF_AutoFiller(v){
699    let it = jQuery(v)
700
701    for ( vv of ['placeholder', 'title'] ) {
702        var ph = it.attr(vv)
703        var params = Object.values(handl_utm_all_params)
704        var n = params.findIndex( (p) => new RegExp(p,'i').test(ph) )
705        if (n > -1){
706            var cval = Cookies.get(params[n])
707            it.val(cval).attr('value',cval)
708        }
709    }
710}
711setTimeout(function () {
712    jQuery('.fsCell.fsHidden>input').map( (i, v) => { FF_AutoFiller(v)  })
713}, 3000)
714
715jQuery(document).on('wsf-rendered', function(event, form_object, form_id, instance_id) {
716    RunFieldFiller()
717});
718
719// function FF_OnAfterRender(){
720//     console.log("Form rendered successfully!");
721//     // var vars = ["Lead.UTM_Campaign__c","Lead.UTM_Medium__c","Lead.UTM_Source__c","Lead.UTM_Term__c","Lead.UTM_Content__c","Lead.GCLID__c","Lead.FBclid__c"]
722//     // for (v of vars){
723//     //     escape_v = v.replace(/\./g, '\\.')
724//     //     jQuery("#"+escape_v).val(Cookies.get(v));
725//     // }
726//     return true;
727// }
728
729// wp.hooks.addFilter('jet.fb.inputs','jet-plugins',function(x,y,z,t,i){console.log(x,y,z,t,i)})
730// wp.hooks.addFilter('jet.fb.macro.field.value','jet-plugins',function(x,y,z,t,i){console.log(x,y,z,t,i)})
731// wp.hooks.addAction('jet.fb.observe.after','jet-plugins',function(x,y,z,t,i){console.log(x,y,z,t,i)})
732
733//This is to support Jet Form Builder
734jQuery(document).on('jet-form-builder/after-init',function(e){
735    RunFieldFiller()
736})
737
738setTimeout(() => { //jotform iframe embed support
739    if (typeof(window.utms_js) == 'object' && typeof(iframeParams) == 'object'){
740        var iframeParams = [];
741        iframeParams.push( jQuery.param(window.utms_js) )
742        var src = ifr.src;
743        ifr.src = src + "?" + iframeParams.join('&');
744    }
745}, "500");
746
747
748jQuery( document ).on( 'elementor/popup/show' , function () {
749    setTimeout(RunFieldFiller, 1000)
750} );
751
752//Borlabs cookie client-side
753window.addEventListener('borlabs-cookie-consent-saved', () => {
754    if (window.BorlabsCookie.Consents.hasConsent('handl-utm-grabber')){
755        RunHandL()
756    }
757});
758
759getAllHandLUTMParams = function() {
760    var values = {};
761
762    Object.values(handl_utm_all_params).forEach(function(param) {
763        var value = Cookies.get(param);
764        if (value) {
765            values[param] = decodeURIComponent(value);
766        }
767    });
768
769    return values;
770};
771
772function getUserData() {
773    return {
774        fbc: Cookies.get('_fbc') || '',
775        fbp: Cookies.get('_fbp') || '',
776        client_ip_address: Cookies.get('handl_ip') || '',
777        client_user_agent: navigator.userAgent
778    };
779}
780
781jQuery(document).ready(function($) {
782    setTimeout(() => {
783        var emailField = $('#email');
784        var hasInitiatedCheckout = false;
785
786        // Check if we're on the WooCommerce checkout page
787        if ($('body').hasClass('woocommerce-checkout')) {
788            emailField.on('blur', function() {
789                if (!hasInitiatedCheckout && emailField.val().trim() !== '') {
790                    hasInitiatedCheckout = true;
791                    var userData = getUserData();
792                    userData.em = [emailField.val()];
793                    $.ajax({
794                        url: handl_ajax.ajax_url,
795                        type: 'POST',
796                        data: {
797                            action: 'handl_initiate_checkout',
798                            user_data: userData
799                        },
800                        success: function(response) {
801                            console.log('InitiateCheckout event sent:', response);
802                        }
803                    });
804                }
805                });
806            }
807    }, 500);
808});
809
810function isFBCAPIEnabled() {
811    return handl_ajax.fb_capi_enabled === '1';
812}
813
814jQuery(document).on('added_to_cart', function(event, fragments, cart_hash, button) {
815    if (!isFBCAPIEnabled()) return;
816
817    var productId = button.data('product_id');
818    var quantity = button.data('quantity');
819
820    if (typeof productId !== 'undefined' && typeof quantity !== 'undefined') {
821        var userData = getUserData();
822
823        jQuery.ajax({
824            url: handl_ajax.ajax_url,
825            type: 'POST',
826            data: {
827                action: 'handl_ajax_add_to_cart',
828                product_id: productId,
829                quantity: quantity,
830                user_data: userData
831            },
832            success: function(response) {
833                console.log('AddToCart event sent:', response);
834            }
835        });
836    }
837});
838
839
840jQuery(function($) {
841    $('form.checkout').on('checkout_place_order', function() {
842        if (!isFBCAPIEnabled()) return;
843
844        var userData = getUserData();
845
846        $.ajax({
847            url: handl_ajax.ajax_url,
848            type: 'POST',
849            data: {
850                action: 'handl_add_payment_info',
851                user_data: userData
852            },
853            success: function(response) {
854                console.log('AddPaymentInfo event sent:', response);
855            }
856        });
857    });
858});
859
860function sanitizeInput(input) {
861    var element = document.createElement('div');
862    element.innerText = input;
863    return element.innerHTML;
864}
865
866function getConsentStatus() {
867    if (!window.dataLayer) {
868        console.warn('dataLayer is not defined.');
869        return null;
870    }
871    let consent = null;
872    // Iterate through dataLayer in reverse to find the latest consent event
873    for (let i = window.dataLayer.length - 1; i >= 0; i--) {
874        if (window.dataLayer[i][0] === 'consent' && window.dataLayer[i][1] === 'update') {
875            consent = window.dataLayer[i][2];
876            break;
877        }else if (typeof window.dataLayer[i] === 'object' && window.dataLayer[i].value && window.dataLayer[i].value.event && window.dataLayer[i].value.event.includes('consent')) {
878            consent = window.dataLayer[i].value;
879            break;
880        }
881    }
882    return consent;
883}
884
885function isConsentDenied() {
886    const consentStatus = getConsentStatus();
887    return consentStatus && (consentStatus.ad_user_data === 'denied' && (consentStatus.analytics_storage === 'denied' || !consentStatus.analytics_storage));
888}
889
890function handleConsentStatus() {
891    if (isConsentDenied()) {
892        RemoveHandLCookies();
893    } else {
894        RunHandL();
895    }
896}
897
898function RemoveHandLCookies() {
899    console.log('Removing HandL cookies');
900    Object.values(handl_utm_all_params).forEach(param => {
901        Cookies.remove(param, { path: '/', domain: getDomainName() });
902    });
903}
904
905(function() {
906    if (typeof handl_ajax.require_third_party_consent !== 'undefined' && handl_ajax.require_third_party_consent) {
907        if (!window.dataLayer) {
908            window.dataLayer = [];
909        }
910
911        const originalPush = window.dataLayer.push;
912
913        window.dataLayer.push = function(...args) {
914            args.forEach(entry => {
915                if (
916                    (Array.isArray(entry) && entry[0] === 'consent' && entry[1] === 'update')
917                    || (entry.event && entry.event.includes('consent'))
918                    || (entry.value && entry.value.event && entry.value.event.includes('consent'))
919                ) {
920                    // Handle the consent update
921                    // console.log(`entry3: ${JSON.stringify(entry)}`);
922                    handleConsentStatus();
923                }
924
925                // if (entry.event && entry.event.includes('marketing')) {
926                //     // Handle the consent update
927                //     console.log(`entry4: ${JSON.stringify(entry)}`);
928                //     console.log(getConsentStatus());
929                // }
930                //
931                // if (typeof entry === 'object' && Object.keys(entry).some(key => key.includes('marketing'))) {
932                //     // Handle the consent update
933                //     console.log(`entry5: ${JSON.stringify(entry)}`);
934                //     console.log(getConsentStatus());
935                // }
936            });
937
938            return originalPush.apply(this, args);
939        };
940    }
941
942    window.addEventListener("hs-form-event:on-ready", event => {
943        const form = window.HubSpotFormsV4.getFormFromEvent(event);
944
945        form.getFormFieldValues().then(fields => {
946            const fieldNames = new Set(fields.map(f => f.name));
947
948            for (const field of handl_utm_all_params) {
949                const fieldName = `0-1/${field}`;
950                if (Cookies.get(field) && fieldNames.has(fieldName)) {
951                    form.setFieldValue(fieldName, [Cookies.get(field)]);
952                }
953            }
954        });
955    });
956})();

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.