const isDebugMode = window.location.search.includes('debug=true'); let debugLogContainer = null; let debugLogCounter = 0; const cookieDomain = '.' + getMainDomain(window.location.href); firebaseDebugLog(true, 'cookieDomain-' + cookieDomain); let refreshInterval; let logoutInProgress = false; let pendingCred = null; document.addEventListener('DOMContentLoaded', function () { // Create debug overlay if debug mode is enabled if (isDebugMode) { createDebugOverlay(); } //Safe to expose as they are identification values not auth keys const firebaseConfig = { apiKey: "AIzaSyA6qrL3tY40YlRkSK4XTS7zijAJ4n15MNU", authDomain: "sso.consequence.net", projectId: "consequence-25a8e", storageBucket: "consequence-25a8e.appspot.com", messagingSenderId: "993189234631", appId: "1:993189234631:web:4d0a240cc0ab799b65fbe2", measurementId: "G-V7CZFS1TQG" }; firebase.initializeApp(firebaseConfig); // Check for native Facebook OAuth callback first (Option 5) handleFacebookOAuthCallback().then(handled => { if (handled) { firebaseDebugLog(true, 'Facebook OAuth callback handled, skipping Firebase redirect check'); return; } // If not a Facebook OAuth callback, check for Firebase redirect result return firebase.auth().getRedirectResult(); }).then(async (result) => { if (!result) return; // Already handled by Facebook OAuth callback if (!result || !result.user) return; const user = result.user; const idToken = await user.getIdToken(); const response = await login(user, idToken); if (response && response.success) { window.location.reload(); } else { console.log("WP login failed after redirect"); } }) .catch((e) => { console.log("getRedirectResult error:", e.code, e.message, e); }); var googleLoginBtn = document.getElementById('googleLoginBtn'); var facebookLoginBtn = document.getElementById('facebook-login'); var twitterLoginBtn = document.getElementById('twitter-login'); var appleLoginBtn = document.getElementById('apple-login'); var logoutBtn = document.getElementById('logoutBtn'); if (googleLoginBtn) { googleLoginBtn.addEventListener('click', function () { var provider = new firebase.auth.GoogleAuthProvider(); provider.setCustomParameters({ prompt: 'select_account' }); handleSignInWithProvider(provider, 'google'); }); } // Facebook Authentication if (facebookLoginBtn) { facebookLoginBtn.addEventListener('click', function () { var provider = new firebase.auth.FacebookAuthProvider(); // provider.setCustomParameters({ // auth_type: 'reauthenticate' // }); handleSignInWithProvider(provider, 'facebook'); }); } // Twitter Authentication if (twitterLoginBtn) { twitterLoginBtn.addEventListener('click', function () { var provider = new firebase.auth.TwitterAuthProvider(); provider.setCustomParameters({ 'force_login': 'true' // Forces the user to reauthenticate }); handleSignInWithProvider(provider, 'twitter'); }); } // Apple Authentication if (appleLoginBtn) { appleLoginBtn.addEventListener('click', function () { var provider = new firebase.auth.OAuthProvider('apple.com'); handleSignInWithProvider(provider, 'apple'); }); } if (logoutBtn) { logoutBtn.addEventListener('click', function () { logout(); }); } firebase.auth().onAuthStateChanged((user) => { firebaseDebugLog(true, '---Start onAuthStateChanged---'); if (logoutInProgress == true) return; // Don't logout if Facebook OAuth is in progress (Option 5 only) if (localStorage.getItem('fb_oauth_processing') === 'true') { firebaseDebugLog(true, 'Facebook OAuth in progress, skipping auth state check'); firebaseDebugLog(true, '---End onAuthStateChanged---'); return; } if (user) { syncGeoToLambda(user.email); firebaseDebugLog(true, 'User signed in:' + user); // regenerateIdToken(user); // Start the refresh process if (checkCookieExists()) { firebaseDebugLog(true, 'CookieExists'); startTokenRefresh(user); } else { firebaseDebugLog(true, 'No CookieExists'); firebaseDebugLog(true, 'No sessioncookie found, logout'); localStorage.setItem('localLogout', 2); //1=local, 2=auto logout(); } } else { firebaseDebugLog(true, 'No user signed in'); clearInterval(refreshInterval); // Clear the interval on sign-out firebaseDebugLog(true, 'On authstatechange check cookie'); // checkSessionCookie(); } firebaseDebugLog(true, '---End onAuthStateChanged---'); }); async function handleSignInWithProvider(provider, pname) { firebaseDebugLog(true, '---Start handleSignInWithProvider'); const loader = document.getElementById('loginSpinner'); try { localStorage.setItem('loggedInLocally', 'true'); logoutInProgress = true; // Option 5: Use native Facebook OAuth for mobile devices ONLY // This includes: mobile regular browsers AND mobile in-app browsers // Desktop in-app browsers will use standard popup flow // This bypasses Firebase's /__/auth/ handler which is blocked by nginx if (pname === 'facebook' && isMobileDevice()) { firebaseDebugLog(true, 'Using custom Facebook OAuth (Option 5) for mobile device'); await handleFacebookNativeAuth(); return; } if (isInAppBrowser()) { await firebase.auth().signInWithRedirect(provider); return; } const result = await firebase.auth().signInWithPopup(provider); loader.style.display = 'flex'; document.getElementById('socialLogin').style.display = 'none'; document.querySelector('.sfba-close').style.display = 'none'; const user = result.user; firebaseDebugLog(true, 'handleSignInWithProvider-' + user); const idToken = await user.getIdToken(); firebaseDebugLog(true, 'ID Token:-' + idToken); const response = await login(user, idToken); if (!response || !response.success) { // Handle unsuccessful login localStorage.removeItem('loggedInLocally'); document.getElementById('socialLogin').style.display = 'block'; document.querySelector('.sfba-close').style.display = 'block'; loader.style.display = 'none'; throw new Error('Failed to authenticate.'); } logoutInProgress = false; window.location.reload(); // Reload the page on successful login } catch (error) { logoutInProgress = false; firebaseDebugLog(true, 'Error during Firebase authentication:' + error.message); localStorage.removeItem('loggedInLocally'); // Ensure localStorage is cleaned up handleLoginError(error); } firebaseDebugLog(true, '---End handleSignInWithProvider'); } function login(user, idToken) { firebaseDebugLog(true, '---Start Login'); return new Promise((resolve, reject) => { jQuery.ajax({ url: firebaseAuthAjax.ajax_url, method: 'POST', data: { action: 'firebase_login', nonce: firebaseAuthAjax.nonce, email: user.email, display_name: user.displayName, provider_id: user.providerData[0].uid, provider_name: user.providerData[0].providerId, idToken: idToken, firebase_uid: user.uid }, success: function (response) { firebaseDebugLog(true, 'login success response:-' + response); setCookie('ssosession', idToken, 24, cookieDomain); syncGeoToLambda(user.email); resolve(response); firebaseDebugLog(true, '---End Login'); }, error: function (error) { firebaseDebugLog(true, 'Error logging in:-' + error); reject(error); } }); }); } async function handleLoginError(error) { if (error.code === 'auth/account-exists-with-different-credential') { jQuery('.temp-preferences').show(); jQuery('.temp-preferences .sfba-before-login').show(); jQuery(".socialLogin").hide(); var email = error.email; // Store credential in memory - cannot reliably serialize Firebase credentials to JSON pendingCred = error.credential; try { var methods = await firebase.auth().fetchSignInMethodsForEmail(email); if (methods.length > 0) { localStorage.setItem('existingProvider', methods[0]); jQuery(".sfba-mask").removeClass("sfba-active"); jQuery(".sfba-link-mask").addClass('sfba-active'); handleLinkModel(methods[0]); } } catch (fetchError) { firebaseDebugLog(true, 'Error fetching sign-in methods: ' + fetchError.message); } } else if (error.code === 'auth/popup-blocked' || error.code === 'auth/popup-closed-by-user') { firebaseDebugLog(true, 'Popup blocked or closed by user'); // Note: Cannot redirect here as we don't have provider context } else { firebaseDebugLog(true, error.message); jQuery('.temp-preferences').hide(); jQuery('.temp-preferences .sfba-before-login').hide(); jQuery(".socialLogin").show(); localStorage.removeItem('Firebaseuserstorage'); } } function handleLinkModel(provider) { // Hide all link buttons first, then show only the relevant one jQuery(".sfba-social-btn-link").hide(); if (provider == 'google.com') { jQuery("#socialLoginLink .link-message .provider-name").html("Google"); jQuery(".sfba-social-btn-link.sfba-login-with-google-btn").show(); } else if (provider == 'facebook.com') { jQuery("#socialLoginLink .link-message .provider-name").html("Facebook"); jQuery(".sfba-social-btn-link.sfba-login-with-facebook-btn").show(); } else if (provider == 'apple.com') { jQuery("#socialLoginLink .link-message .provider-name").html("Apple"); jQuery(".sfba-social-btn-link.sfba-login-with-apple-btn").show(); } else { firebaseDebugLog(true, 'Provider doesnt exist: ' + provider); } } function getAuthProvider(providerId) { switch (providerId) { case firebase.auth.GoogleAuthProvider.PROVIDER_ID: return new firebase.auth.GoogleAuthProvider(); case firebase.auth.FacebookAuthProvider.PROVIDER_ID: return new firebase.auth.FacebookAuthProvider(); case 'apple.com': return new firebase.auth.OAuthProvider('apple.com'); default: throw new Error('No provider found for the given provider ID.'); } } // Modal for SSO Social media buttons and Add ARtist/Tags jQuery(".sfba-show").on("click", function () { var errorElement = document.getElementById("errorMessage"); if (errorElement) { errorElement.innerHTML = ''; } jQuery(".sfba-mask").addClass("sfba-active"); }); // Close popup jQuery(".sfba-close").on("click", function () { jQuery(".sfba-mask").removeClass("sfba-active"); }); // Close popup jQuery(".sfba-link-close").on("click", function () { jQuery(".sfba-link-mask").removeClass("sfba-active"); }); jQuery(".sfba-show-pref").on("click", function () { jQuery(".sfba-mask-pref").addClass("sfba-active"); }); jQuery(".sfba-close-pref").on("click", function () { jQuery(".sfba-mask-pref").removeClass("sfba-active"); }); jQuery('.tab-nav span').on('click', function () { if (jQuery(this).text() == 'My Tags') { jQuery('#all-preferences .tab-nav ul li').removeClass('active'); jQuery('#all-preferences .tab-nav ul li:nth-child(2)').addClass('active'); jQuery('#all-preferences #all-artists').removeClass('active'); jQuery('#all-preferences #all-tags').addClass('active'); } else { jQuery('#all-preferences .tab-nav ul li').addClass('active'); jQuery('#all-preferences .tab-nav ul li:nth-child(2)').removeClass('active'); jQuery('#all-preferences #all-artists').addClass('active'); jQuery('#all-preferences #all-tags').removeClass('active'); } jQuery([jQuery(this).parent()[0], jQuery(jQuery(this).data('href'))[0]]).addClass('active').siblings('.active').removeClass('active'); }); // Delete Artists/Tags jQuery('body').on('click', '.preference-delete, .preference-add.deleteid', function () { var preftype = jQuery(this).data("preftype"); var currentemailaddress = jQuery("#current-email-address").val(); if (jQuery(this).hasClass('deleteid')) { jQuery(this).removeClass('deleteid'); jQuery(this).addClass('addid'); jQuery(this).find('span.pref-add').html('').html('✛'); jQuery(this).find('span.pref-add').css('color', '#009b1a'); var delId = jQuery(this).data("addid"); if (preftype == "artist") { jQuery(".my-artist-list li").each(function () { if (jQuery(this).find("a").attr("data-delid") == delId) { jQuery(this).remove(); } }); } else { jQuery(".my-tags-list li").each(function () { if (jQuery(this).find("a").attr("data-delid") == delId) { jQuery(this).remove(); } }); } } else { var delId = jQuery(this).data("delid"); jQuery(this).parent().remove(); if (preftype == "artist") { jQuery(".preferences-list ul.artist-list li").each(function () { if (jQuery(this).find("a").attr("data-addid") == delId) { jQuery(this).find('span.pref-add').html('').html('✛'); jQuery(this).find('span.pref-add').css('color', '#009b1a'); } }); } else { jQuery(".preferences-list ul.post_tag-list li").each(function () { if (jQuery(this).find("a").attr("data-addid") == delId) { jQuery(this).find('span.pref-add').html('').html('✛'); jQuery(this).find('span.pref-add').css('color', '#009b1a'); } }); } } jQuery.ajax({ type: 'POST', url: firebaseAuthAjax.ajax_url, cache: true, data: { action: 'delete_preferences_action', currentemailaddress: currentemailaddress, delId: delId, preftype: preftype, }, success: function (response) { if (preftype == "artist") { if (jQuery('ul.my-artist-list').find('li').length === 0) { jQuery('.preferences-list.my-artists-ul').html('

Please click the "plus" icon to the right to add Artists to your profile

'); } } else { if (jQuery('ul.my-tags-list').find('li').length === 0) { jQuery('.preferences-list.my-tags-ul').html('

Please click the "plus" icon to the right to add Tags to your profile

'); } } } }); }); let currentAjaxRequest = null; jQuery('.search-preferences').keyup(function (event) { if ((event.key === 'Enter' && jQuery(this).val().length > 2) || jQuery(this).val().length > 2) { jQuery('.search-pref-btn').click(); } if (event.key === 'Backspace') { jQuery('.search-pref-btn').click(); } }); jQuery('.search-pref-btn').on('click', function () { jQuery('.filterButton').removeClass('active'); searchTerm = jQuery(this).prev().val(); var ptype = jQuery(this).data('type'); var preftype = ''; var prefidstring = ''; var textpref = ''; var arrayinside = false; if (ptype === 'artist') { preftype = "artist"; prefidstring = jQuery("#artist_id").val(); textpref = "Artist"; } else if (ptype === 'post_tag') { preftype = "tags"; prefidstring = jQuery("#tag_id").val(); textpref = "Tags"; } if (searchTerm != "") { // Make AJAX request if (currentAjaxRequest) { currentAjaxRequest.abort(); } currentAjaxRequest = jQuery.ajax({ type: 'POST', url: firebaseAuthAjax.ajax_url, dataType: 'json', data: { action: 'preferences_search_action', nonce: firebaseAuthAjax.nonce, search_term: searchTerm, ptype: ptype }, success: function (response) { currentAjaxRequest = null; jQuery('.' + ptype + '-list li').css("display", "none"); jQuery('.' + ptype + '-list li.nonpop-search-data').remove(); var jsonString = JSON.stringify(response); var dataArray = JSON.parse(jsonString); setTimeout(function () { if (Array.isArray(dataArray) && dataArray.length > 0) { jQuery('.post_tag-list p').remove(); jQuery('.artist-list p').remove(); $.each(dataArray, function (index, item) { if (prefidstring !== '' && prefidstring.includes(item.term_id)) { arrayinside = true; } if (arrayinside) { jQuery('.' + ptype + '-list').append('
  • ' + item.name + '
  • '); } else { jQuery('.' + ptype + '-list').append('
  • ' + item.name + '
  • '); } jQuery('.' + ptype + '-list li.nonpop-search-data').css("display", "block"); }); } else { if (jQuery('.not-found').length === 0) { jQuery('.' + ptype + '-list').append('

    No ' + textpref + ' found

    '); } } }, 500); } }); } else { jQuery('.filterButton:first-child').addClass('active'); jQuery('.' + ptype + '-list li').css("display", "block"); jQuery('.' + ptype + '-list li.nonpop-search-data').remove(); } }); jQuery('.filterButton').on('click', function () { jQuery('.post_tag-list p').remove(); jQuery('.artist-list p').remove(); jQuery('.filterButton').removeClass("active"); var filter = jQuery(this).data('filter'); jQuery(this).addClass("active"); jQuery(this).parent().prev().find('.search-preferences').val(filter); var preid = jQuery(this).parent().parent().attr('id'); if (preid === 'all-artists') { var ptype = 'artist'; } else { var ptype = 'post_tag'; } if (ptype == "artist") { var customclass = '.artist-list li'; } else if (ptype == "post_tag") { var customclass = '.post_tag-list li'; } if (filter == "ALL") { jQuery('.' + ptype + '-list li').css("display", "block"); jQuery('.' + ptype + '-list li.nonpop-search-data').remove(); } else { jQuery(customclass).each(function () { var firstLetter = jQuery(this).text().charAt(0).toUpperCase(); if (firstLetter === filter) { jQuery(this).show(); } else { jQuery(this).hide(); } }); jQuery('.' + ptype + '-list li.nonpop-search-data').remove(); } }); // Add Artists/Tags jQuery('body').on('click', '.preference-add.addid', function () { var preftype = jQuery(this).data("preftype"); var currentemailaddress = jQuery("#current-email-address").val(); var newValueartist = '', newValuetags = '', artistadd = '', tagsadd = ''; if (preftype == 'artist') { newValueartist = jQuery(this).data('addid'); artistname = jQuery(this).data('title'); artistadd = '
  • ' + artistname + '
  • '; } else { newValuetags = jQuery(this).data('addid'); tagsname = jQuery(this).data('title'); tagsadd = '
  • ' + tagsname + '
  • '; } jQuery(this).find('span.pref-add').html('').html('✕'); jQuery(this).find('span.pref-add').css('color', '#ff0000'); jQuery(this).removeClass('addid'); jQuery(this).addClass('deleteid'); jQuery.ajax({ type: 'POST', url: firebaseAuthAjax.ajax_url, cache: true, data: { action: 'add_preferences_action', currentemailaddress: currentemailaddress, preftype: preftype, newValueartist: newValueartist, newValuetags: newValuetags, }, success: function (response) { if (artistadd != '') { if (jQuery(".my-artists-ul").find('p').length) { jQuery(".my-artists-ul").html(''); jQuery(".my-artists-ul").append('
    '); jQuery(".my-artists-ul p").css("display", "none"); } else { // jQuery(".my-artists-ul ul").append(artistadd); appendLi('.my-artist-list', artistadd, artistname); } } if (tagsadd != '') { if (jQuery(".my-tags-ul").find('p').length) { jQuery(".my-tags-ul").html(''); jQuery(".my-tags-ul").append('
    '); jQuery(".my-tags-ul p").css("display", "none"); } else { // jQuery(".my-tags-ul ul").append(tagsadd); appendLi('.my-tags-list', tagsadd, tagsname); } } } }); }); // Delete Artists/Tags jQuery('body').on('click', '.preference-delete, .preference-add.deleteid', function () { var preftype = jQuery(this).data("preftype"); var currentemailaddress = jQuery("#current-email-address").val(); if (jQuery(this).hasClass('deleteid')) { jQuery(this).removeClass('deleteid'); jQuery(this).addClass('addid'); jQuery(this).find('span.pref-add').html('').html('✛'); jQuery(this).find('span.pref-add').css('color', '#009b1a'); var delId = jQuery(this).data("addid"); if (preftype == "artist") { jQuery(".my-artist-list li").each(function () { if (jQuery(this).find("a").attr("data-delid") == delId) { jQuery(this).remove(); } }); } else { jQuery(".my-tags-list li").each(function () { if (jQuery(this).find("a").attr("data-delid") == delId) { jQuery(this).remove(); } }); } } else { var delId = jQuery(this).data("delid"); if (preftype == "artist") { jQuery(".preferences-list ul.artist-list li").each(function () { if (jQuery(this).find("a").attr("data-addid") == delId) { jQuery(this).find('span.pref-add').html('').html('✛'); jQuery(this).find('span.pref-add').css('color', '#009b1a'); } }); } else { jQuery(".preferences-list ul.post_tag-list li").each(function () { if (jQuery(this).find("a").attr("data-addid") == delId) { jQuery(this).find('span.pref-add').html('').html('✛'); jQuery(this).find('span.pref-add').css('color', '#009b1a'); } }); } } jQuery.ajax({ type: 'POST', url: firebaseAuthAjax.ajax_url, cache: true, data: { action: 'delete_preferences_action', currentemailaddress: currentemailaddress, delId: delId, preftype: preftype, }, success: function (response) { if (preftype == "artist") { if (jQuery('ul.my-artist-list').find('li').length === 0) { jQuery('.preferences-list.my-artists-ul').html('

    Please click the "plus" icon to the right to add Artists to your profile

    '); } } else { if (jQuery('ul.my-tags-list').find('li').length === 0) { jQuery('.preferences-list.my-tags-ul').html('

    Please click the "plus" icon to the right to add Tags to your profile

    '); } } } }); }); function appendLi(selector, litoadd, textname) { var $list = jQuery(selector); var $newItem = jQuery(litoadd); var textnameIsNumeric = !isNaN(textname); var inserted = false; $list.children('li').each(function () { var $currentItem = jQuery(this); var currentTextName = $currentItem.find('span:first').text(); var currentIsNumeric = !isNaN(currentTextName); if (textnameIsNumeric && currentIsNumeric) { if (parseFloat(textname) < parseFloat(currentTextName)) { $currentItem.before($newItem); inserted = true; return false; } } else if (!textnameIsNumeric && !currentIsNumeric) { if (String(textname).toLowerCase() < String(currentTextName).toLowerCase()) { $currentItem.before($newItem); inserted = true; return false; } } else if (textnameIsNumeric && !currentIsNumeric) { $currentItem.before($newItem); inserted = true; return false; } }); if (!inserted) { $list.append($newItem); } } jQuery(".sfba-social-btn-link").on("click", async function () { jQuery(".sfba-link-mask").removeClass('sfba-active'); var existingProvider = localStorage.getItem('existingProvider'); localStorage.removeItem('existingProvider'); var authProvider = getAuthProvider(existingProvider); try { // Step 1: Sign in with the existing (original) provider var result = await firebase.auth().signInWithPopup(authProvider); var user = result.user; var idToken = await user.getIdToken(); // Step 2: Log in / create the WordPress user (reuses the same login() helper) var loginResponse = await login(user, idToken); if (!loginResponse || !loginResponse.success) { localStorage.removeItem('loggedInLocally'); throw new Error('Failed to authenticate with WordPress.'); } // Step 3: Link the pending credential (from the failed sign-in attempt) if (pendingCred) { try { // var linkResult = await user.linkWithCredential(pendingCred); // // Update cookie with fresh token from the now-linked account // var newIdToken = await linkResult.user.getIdToken(true); setCookie('ssosession', idToken, 24, cookieDomain); firebaseDebugLog(true, 'Account linking successful'); } catch (linkError) { firebaseDebugLog(true, 'Error linking account (non-fatal): ' + linkError.message); // Linking failed but user is already logged in — proceed with existing token } pendingCred = null; } window.location.reload(); } catch (error) { firebaseDebugLog(true, 'Error during account link flow: ' + error.message); } }); /** * Handle native Facebook OAuth (Option 5) * Redirects to Facebook OAuth URL */ async function handleFacebookNativeAuth() { firebaseDebugLog(true, '=== NATIVE FACEBOOK OAUTH (Option 5) ==='); // Facebook App ID (from Facebook Developer Console) const facebookAppId = '2018160385090572'; // Build Facebook OAuth URL const redirectUri = encodeURIComponent(window.location.origin + window.location.pathname); const state = Math.random().toString(36).substring(7); // Random state for security localStorage.setItem('fb_oauth_state', state); localStorage.setItem('fb_oauth_redirect', window.location.href); const facebookAuthUrl = `https://www.facebook.com/v12.0/dialog/oauth?` + `client_id=${facebookAppId}` + `&redirect_uri=${redirectUri}` + `&state=${state}` + `&scope=email,public_profile` + `&response_type=token`; firebaseDebugLog(true, 'Redirecting to Facebook OAuth:', facebookAuthUrl); // Redirect to Facebook window.location.href = facebookAuthUrl; } /** * Handle Facebook OAuth callback * Called on page load to check if we're returning from Facebook OAuth */ async function handleFacebookOAuthCallback() { // Check if login just completed (prevent reload loop) if (sessionStorage.getItem('fb_login_complete') === 'true') { firebaseDebugLog(true, 'Facebook login already completed this session, skipping callback'); sessionStorage.removeItem('fb_login_complete'); return false; } firebaseDebugLog(true, 'Checking for Facebook OAuth callback...'); // Check if URL has Facebook OAuth response (access_token in hash) const hash = window.location.hash; if (!hash || hash.indexOf('access_token=') === -1) { firebaseDebugLog(true, 'No access_token in hash, not a Facebook OAuth callback'); return false; } // Prevent multiple executions if (localStorage.getItem('fb_oauth_processing') === 'true') { firebaseDebugLog(true, 'Already processing Facebook OAuth, skipping'); return true; // Return true to prevent other handlers } localStorage.setItem('fb_oauth_processing', 'true'); firebaseDebugLog(true, '=== FACEBOOK OAUTH CALLBACK DETECTED ==='); try { // Parse the hash fragment const params = new URLSearchParams(hash.substring(1)); const accessToken = params.get('access_token'); const state = params.get('state'); firebaseDebugLog(true, 'Parsed access_token length:', accessToken?.length); firebaseDebugLog(true, 'Parsed state:', state); // Verify state to prevent CSRF const savedState = localStorage.getItem('fb_oauth_state'); firebaseDebugLog(true, 'Saved state:', savedState); if (state !== savedState) { firebaseDebugLog(true, 'ERROR: State mismatch, possible CSRF attack'); localStorage.removeItem('fb_oauth_processing'); return false; } // Exchange Facebook access token for Firebase credential firebaseDebugLog(true, 'Creating Facebook credential from access token'); const credential = firebase.auth.FacebookAuthProvider.credential(accessToken); firebaseDebugLog(true, 'Signing into Firebase with Facebook credential'); const result = await firebase.auth().signInWithCredential(credential); firebaseDebugLog(true, 'Firebase signInWithCredential successful'); const user = result.user; firebaseDebugLog(true, 'User:', user.email, 'UID:', user.uid); // Get Firebase ID token const idToken = await user.getIdToken(); firebaseDebugLog(true, 'Got Firebase ID token, length:', idToken.length); // Login to WordPress firebaseDebugLog(true, 'Calling WordPress login'); const loginResponse = await login(user, idToken); if (!loginResponse || !loginResponse.success) { firebaseDebugLog(true, 'ERROR: WordPress login failed'); localStorage.removeItem('fb_oauth_processing'); throw new Error('Failed to authenticate with WordPress.'); } firebaseDebugLog(true, 'WordPress login successful!'); // Clean up localStorage.removeItem('fb_oauth_state'); localStorage.removeItem('fb_oauth_processing'); localStorage.removeItem('fb_oauth_redirect'); // Set flag to prevent re-processing on reload sessionStorage.setItem('fb_login_complete', 'true'); // Clean hash from URL and reload window.location.hash = ''; window.location.reload(); return true; } catch (error) { firebaseDebugLog(true, 'ERROR in Facebook OAuth callback:', error.code, error.message); localStorage.removeItem('fb_oauth_processing'); // Handle account-exists-with-different-credential error (same as standard flow) if (error.code === 'auth/account-exists-with-different-credential') { // Clean the hash from URL first window.location.hash = ''; jQuery('.temp-preferences').show(); jQuery('.temp-preferences .sfba-before-login').show(); jQuery(".socialLogin").hide(); var email = error.email; // Store credential in memory pendingCred = error.credential; try { var methods = await firebase.auth().fetchSignInMethodsForEmail(email); if (methods.length > 0) { localStorage.setItem('existingProvider', methods[0]); jQuery(".sfba-mask").removeClass("sfba-active"); jQuery(".sfba-link-mask").addClass('sfba-active'); handleLinkModel(methods[0]); } } catch (fetchError) { firebaseDebugLog(true, 'Error fetching sign-in methods: ' + fetchError.message); } } return false; } } }); function logout() { firebaseDebugLog(true, '---Start Logout'); logoutInProgress = true; if (localStorage.getItem('localLogout') === null || localStorage.getItem('localLogout') == 1) { logoutPopup(); } localStorage.removeItem('localLogout'); // Sign out from Firebase firebase.auth().signOut().then(function () { firebaseDebugLog(true, 'User signed out from Firebase.'); // Perform an AJAX request to log the user out from WordPress jQuery.ajax({ url: firebaseAuthAjax.ajax_url, type: 'POST', data: { action: 'firebase_logout' // nonce: firebaseAuthAjax.nonce }, success: function (response) { if (response.success) { localStorage.removeItem('loggedInLocally'); logoutInProgress = false; document.cookie = 'ssosession=; path=/; domain=' + cookieDomain + '; expires=Thu, 01 Jan 1970 00:00:00 UTC;'; window.location.reload(); // Reload the page after successful logout } else { firebaseDebugLog(true, 'Logout failed: ', response.data.message); } firebaseDebugLog(true, '---End Logout'); }, error: function (xhr, status, error) { firebaseDebugLog(true, 'Error logging out: ', xhr.responseText); } }); }).catch(function (error) { firebaseDebugLog(true, 'Firebase logout failed: ', error.message); }); } function loginPopup() { const popupOverlay = document.createElement('div'); popupOverlay.className = 'popup-overlay'; popupOverlay.innerHTML = ``; // Append overlay to the body document.body.appendChild(popupOverlay); // Display the popup popupOverlay.style.display = 'block'; } function logoutPopup() { const popupOverlay = document.createElement('div'); popupOverlay.className = 'popup-overlay'; popupOverlay.innerHTML = ``; // Append overlay to the body document.body.appendChild(popupOverlay); // Display the popup popupOverlay.style.display = 'block'; } function checkCookieExists() { const sessionCookie = getCookie('ssosession'); if (sessionCookie) { return sessionCookie; } return null; } function getCookie(name) { const value = `; ${document.cookie}`; const parts = value.split(`; ${name}=`); if (parts.length === 2) return parts.pop().split(';').shift(); } function startTokenRefresh(user) { firebaseDebugLog('refreshInterval-' + new Date().toLocaleString() + '---' + refreshInterval); // Clear any existing intervals clearInterval(refreshInterval); // Refresh the token every 50 minutes (3000 seconds) refreshInterval = setInterval(() => { regenerateIdToken(user); }, 50 * 60 * 1000); // 50 minutes in milliseconds } function regenerateIdToken(user) { user.getIdToken(true) .then((idToken) => { firebaseDebugLog('New ID Token:' + idToken); setCookie('ssosession', idToken, 24, cookieDomain); }) .catch((error) => { firebaseDebugLog('Error getting ID token:', error); }); } function setCookie(name, value, hours, domain) { const expires = new Date(Date.now() + hours * 60 * 60 * 1000).toUTCString(); const cookieValue = `${name}=${encodeURIComponent(value)}; expires=${expires}; path=/; domain=${domain}; secure=false; SameSite=Lax`; firebaseDebugLog('cookieValue' + cookieValue); document.cookie = cookieValue; } function getMainDomain(url) { const urlObject = new URL(url); const hostParts = urlObject.hostname.split('.'); // If the host has two or more parts, join the last two parts as the main domain if (hostParts.length >= 2) { const mainDomain = hostParts.slice(-2).join('.'); return mainDomain; } // Fallback for a single part (e.g., localhost) return urlObject.hostname; } function createDebugOverlay() { // Create overlay container debugLogContainer = document.createElement('div'); debugLogContainer.id = 'firebase-debug-overlay'; debugLogContainer.style.cssText = ` position: fixed; top: 0; left: 0; width: 300px; height: 70vh; max-height: 70vh; background: rgba(0, 0, 0, 0.9); color: #0f0; font-family: monospace; font-size: 11px; padding: 10px; overflow-y: auto; z-index: 999999; border-right: 2px solid #0f0; border-bottom: 2px solid #0f0; `; // Add title bar with download button const titleBar = document.createElement('div'); titleBar.style.cssText = 'display: flex; justify-content: space-between; align-items: center; margin-bottom: 5px;'; const title = document.createElement('div'); title.textContent = '🔥 Firebase Debug Log'; title.style.cssText = 'font-weight: bold; color: #ff0;'; const downloadBtn = document.createElement('button'); downloadBtn.textContent = '📥 Download'; downloadBtn.style.cssText = ` background: #0f0; color: #000; border: none; padding: 3px 8px; font-size: 10px; font-weight: bold; cursor: pointer; border-radius: 3px; `; downloadBtn.addEventListener('click', function (e) { e.stopPropagation(); downloadDebugLog(); }); titleBar.appendChild(title); titleBar.appendChild(downloadBtn); debugLogContainer.appendChild(titleBar); // Add close instruction const closeMsg = document.createElement('div'); closeMsg.textContent = '(Tap log area to close)'; closeMsg.style.cssText = 'font-size: 9px; color: #888; margin-bottom: 5px;'; debugLogContainer.appendChild(closeMsg); // Make it closable (but not the download button) debugLogContainer.addEventListener('click', function (e) { if (e.target !== downloadBtn) { debugLogContainer.style.display = 'none'; } }); document.body.appendChild(debugLogContainer); console.log('Debug overlay created'); } function firebaseDebugLog(stat = false, ...messages) { if (isDebugMode && stat) { console.log('Firebase:-', ...messages); // Also write to overlay if it exists if (debugLogContainer) { try { debugLogCounter++; const logEntry = document.createElement('div'); logEntry.style.cssText = 'margin: 2px 0; padding: 2px; border-bottom: 1px solid #333;'; const timestamp = new Date().toLocaleTimeString(); const messageText = messages.map(m => typeof m === 'object' ? JSON.stringify(m) : String(m) ).join(' '); logEntry.innerHTML = `[${debugLogCounter}] ${timestamp}
    ${messageText}`; debugLogContainer.appendChild(logEntry); // Auto-scroll to bottom debugLogContainer.scrollTop = debugLogContainer.scrollHeight; } catch (e) { console.error('Failed to write to debug log:', e); } } } } // Wrapper function for backward compatibility function debugLog(stat = false, ...messages) { firebaseDebugLog(stat, ...messages); } function downloadDebugLog() { if (!debugLogContainer) { console.error('Debug log container not found'); return; } // Collect all log entries const logEntries = debugLogContainer.querySelectorAll('div'); let logText = 'Firebase Authentication Debug Log\n'; logText += '=================================\n'; logText += 'Generated: ' + new Date().toLocaleString() + '\n'; logText += 'URL: ' + window.location.href + '\n'; logText += 'User Agent: ' + navigator.userAgent + '\n'; logText += '=================================\n\n'; // Extract text from each log entry logEntries.forEach((entry, index) => { // Skip the title and close message if (index > 1) { const text = entry.innerText || entry.textContent; if (text && text.trim()) { logText += text + '\n'; } } }); // Create blob and download const blob = new Blob([logText], { type: 'text/plain' }); const url = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = 'firebase-debug-log-' + Date.now() + '.txt'; document.body.appendChild(a); a.click(); document.body.removeChild(a); URL.revokeObjectURL(url); console.log('Debug log downloaded'); } function isInAppBrowser() { const ua = navigator.userAgent || ""; return /FBAN|FBAV|Instagram|Line|Twitter|Snapchat|MicroMessenger/i.test(ua); } function isMobileDevice() { const ua = navigator.userAgent || ""; // Check for mobile devices (iPhone, iPad, Android, etc.) return /iPhone|iPad|iPod|Android|webOS|BlackBerry|IEMobile|Opera Mini/i.test(ua); } function getCurrentGeoData() { return { country: typeof COS_COUNTRY !== 'undefined' ? COS_COUNTRY : '', state: typeof COS_STATE !== 'undefined' ? COS_STATE : '', city: typeof COS_CITY !== 'undefined' ? COS_CITY : '', latitude: typeof COS_LATITUDE !== 'undefined' ? COS_LATITUDE : '', longitude: typeof COS_LONGITUDE !== 'undefined' ? COS_LONGITUDE : '', }; } function hasGeoChanged(currentGeo, lastSyncedGeo) { return ( currentGeo.country !== (lastSyncedGeo.country || '') || currentGeo.state !== (lastSyncedGeo.state || '') || currentGeo.city !== (lastSyncedGeo.city || '') || String(currentGeo.latitude) !== String(lastSyncedGeo.latitude || '') || String(currentGeo.longitude) !== String(lastSyncedGeo.longitude || '') ); } async function syncGeoToLambda(userEmail) { if (!userEmail) return; const currentGeo = getCurrentGeoData(); const lastSyncedGeo = JSON.parse(localStorage.getItem('COS_GEO_DATA') || '{}'); if (currentGeo && !hasGeoChanged(currentGeo, lastSyncedGeo)) { return; } try { const response = await fetch('/wp-admin/admin-ajax.php', { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, body: new URLSearchParams({ action: 'save_geo_to_dynamodb', geo: JSON.stringify(currentGeo), userEmail: userEmail }) }); localStorage.setItem('COS_GEO_DATA', JSON.stringify(currentGeo)); const result = await response.json(); // console.log('Geo synced:', result); } catch (err) { console.error('Geo sync failed:', err); } } ; !function(){"use strict";var e,t={noop:function(){},texturize:function(e){return(e=(e=(e=(e+="").replace(/'/g,"’").replace(/'/g,"’")).replace(/"/g,"”").replace(/"/g,"”").replace(/"/g,"”").replace(/[\u201D]/g,"”")).replace(/([\w]+)=&#[\d]+;(.+?)&#[\d]+;/g,'$1="$2"')).trim()},applyReplacements:function(e,t){if(e)return t?e.replace(/{(\d+)}/g,function(e,r){return void 0!==t[r]?t[r]:e}):e},getBackgroundImage:function(e){var t=document.createElement("canvas"),r=t.getContext&&t.getContext("2d");if(e){r.filter="blur(20px) ",r.drawImage(e,0,0);var o=t.toDataURL("image/png");return t=null,o}}},r=function(){function e(e,t){return Element.prototype.matches?e.matches(t):Element.prototype.msMatchesSelector?e.msMatchesSelector(t):void 0}function r(e,t,r,o){if(!e)return o();e.style.removeProperty("display"),e.style.opacity=t,e.style.pointerEvents="none";var a=function(i,n){var l=(performance.now()-i)/n;l<1?(e.style.opacity=t+(r-t)*l,requestAnimationFrame(()=>a(i,n))):(e.style.opacity=r,e.style.removeProperty("pointer-events"),o())};requestAnimationFrame(function(){requestAnimationFrame(function(){a(performance.now(),200)})})}return{closest:function(t,r){if(t.closest)return t.closest(r);var o=t;do{if(e(o,r))return o;o=o.parentElement||o.parentNode}while(null!==o&&1===o.nodeType);return null},matches:e,hide:function(e){e&&(e.style.display="none")},show:function(e){e&&(e.style.display="block")},fadeIn:function(e,o){r(e,0,1,o=o||t.noop)},fadeOut:function(e,o){o=o||t.noop,r(e,1,0,function(){e&&(e.style.display="none"),o()})},scrollToElement:function(e,t,r){if(!e||!t)return r?r():void 0;var o=t.querySelector(".jp-carousel-info-extra");o&&(o.style.minHeight=window.innerHeight-64+"px");var a=!0,i=Date.now(),n=t.scrollTop,l=Math.max(0,e.offsetTop-Math.max(0,window.innerHeight-function(e){var t=e.querySelector(".jp-carousel-info-footer"),r=e.querySelector(".jp-carousel-info-extra"),o=e.querySelector(".jp-carousel-info-content-wrapper");if(t&&r&&o){var a=window.getComputedStyle(r),i=parseInt(a.paddingTop,10)+parseInt(a.paddingBottom,10);return i=isNaN(i)?0:i,o.offsetHeight+t.offsetHeight+i}return 0}(t)))-t.scrollTop;function s(){a=!1}l=Math.min(l,t.scrollHeight-window.innerHeight),t.addEventListener("wheel",s),function e(){var c,u=Date.now(),d=(c=(u-i)/300)<.5?2*c*c:1-Math.pow(-2*c+2,2)/2,p=(d=d>1?1:d)*l;if(t.scrollTop=n+p,u<=i+300&&a)return requestAnimationFrame(e);r&&r(),o&&(o.style.minHeight=""),a=!1,t.removeEventListener("wheel",s)}()},getJSONAttribute:function(e,t){if(e&&e.hasAttribute(t))try{return JSON.parse(e.getAttribute(t))}catch{return}},convertToPlainText:function(e){var t=document.createElement("div");return t.textContent=e,t.innerHTML},stripHTML:function(e){return e.replace(/<[^>]*>?/gm,"")},emitEvent:function(e,t,r){var o;try{o=new CustomEvent(t,{bubbles:!0,cancelable:!0,detail:r||null})}catch{(o=document.createEvent("CustomEvent")).initCustomEvent(t,!0,!0,r||null)}e.dispatchEvent(o)},isTouch:function(){return"ontouchstart"in window||window.DocumentTouch&&document instanceof DocumentTouch}}}();function o(){var o,a,i,n,l="",s=!1,c="div.gallery, div.tiled-gallery, ul.wp-block-gallery, ul.blocks-gallery-grid, figure.wp-block-gallery.has-nested-images, div.wp-block-jetpack-tiled-gallery, a.single-image-gallery",u=".gallery-item, .tiled-gallery-item, .blocks-gallery-item, .tiled-gallery__item",d=u+", .wp-block-image",p={},m="undefined"!=typeof wpcom&&wpcom.carousel&&wpcom.carousel.stat?wpcom.carousel.stat:t.noop,g="undefined"!=typeof wpcom&&wpcom.carousel&&wpcom.carousel.pageview?wpcom.carousel.pageview:t.noop;function h(t){if(!s)switch(t.which){case 38:t.preventDefault(),p.overlay.scrollTop-=100;break;case 40:t.preventDefault(),p.overlay.scrollTop+=100;break;case 39:t.preventDefault(),e.slideNext();break;case 37:case 8:t.preventDefault(),e.slidePrev();break;case 27:t.preventDefault(),k()}}function f(){s=!0}function v(){s=!1}function y(e){e.role="button",e.tabIndex=0,e.ariaLabel=jetpackCarouselStrings.image_label}function w(){p.overlay||(p.overlay=document.querySelector(".jp-carousel-overlay"),p.container=p.overlay.querySelector(".jp-carousel-wrap"),p.gallery=p.container.querySelector(".jp-carousel"),p.info=p.overlay.querySelector(".jp-carousel-info"),p.caption=p.info.querySelector(".jp-carousel-caption"),p.commentField=p.overlay.querySelector("#jp-carousel-comment-form-comment-field"),p.emailField=p.overlay.querySelector("#jp-carousel-comment-form-email-field"),p.authorField=p.overlay.querySelector("#jp-carousel-comment-form-author-field"),p.urlField=p.overlay.querySelector("#jp-carousel-comment-form-url-field"),window.innerWidth<=760&&Math.round(window.innerWidth/760*110)<40&&r.isTouch(),[p.commentField,p.emailField,p.authorField,p.urlField].forEach(function(e){e&&(e.addEventListener("focus",f),e.addEventListener("blur",v))}),p.overlay.addEventListener("click",function(e){var t,o,a=e.target,i=!!r.closest(a,".jp-carousel-close-hint"),n=!!window.matchMedia("(max-device-width: 760px)").matches;a===p.overlay?n||k():i?k():a.classList.contains("jp-carousel-image-download")?m("download_original_click"):a.classList.contains("jp-carousel-comment-login")?(t=p.currentSlide,o=t?t.attrs.attachmentId:"0",window.location.href=jetpackCarouselStrings.login_url+"%23jp-carousel-"+o):r.closest(a,"#jp-carousel-comment-form-container")?function(e){var t=e.target,o=r.getJSONAttribute(p.container,"data-carousel-extra")||{},a=p.currentSlide.attrs.attachmentId,i=document.querySelector("#jp-carousel-comment-form-submit-and-info-wrapper"),n=document.querySelector("#jp-carousel-comment-form-spinner"),l=document.querySelector("#jp-carousel-comment-form-button-submit"),s=document.querySelector("#jp-carousel-comment-form");if(p.commentField&&p.commentField.getAttribute("id")===t.getAttribute("id"))f(),r.show(i);else if(r.matches(t,'input[type="submit"]')){e.preventDefault(),e.stopPropagation(),r.show(n),s.classList.add("jp-carousel-is-disabled");var c={action:"post_attachment_comment",nonce:jetpackCarouselStrings.nonce,blog_id:o.blog_id,id:a,comment:p.commentField.value};if(!c.comment.length)return void j(jetpackCarouselStrings.no_comment_text,!1);if(1!==Number(jetpackCarouselStrings.is_logged_in)&&(c.email=p.emailField.value,c.author=p.authorField.value,c.url=p.urlField.value,1===Number(jetpackCarouselStrings.require_name_email))){if(!c.email.length||!c.email.match("@"))return void j(jetpackCarouselStrings.no_comment_email,!1);if(!c.author.length)return void j(jetpackCarouselStrings.no_comment_author,!1)}var u=new XMLHttpRequest;u.open("POST",jetpackCarouselStrings.ajaxurl,!0),u.setRequestHeader("X-Requested-With","XMLHttpRequest"),u.setRequestHeader("Content-Type","application/x-www-form-urlencoded; charset=UTF-8"),u.onreadystatechange=function(){if(this.readyState===XMLHttpRequest.DONE&&this.status>=200&&this.status<300){var e;try{e=JSON.parse(this.response)}catch{return void j(jetpackCarouselStrings.comment_post_error,!1)}"approved"===e.comment_status?j(jetpackCarouselStrings.comment_approved,!0):"unapproved"===e.comment_status?j(jetpackCarouselStrings.comment_unapproved,!0):j(jetpackCarouselStrings.comment_post_error,!1),I(),_(a),l.value=jetpackCarouselStrings.post_comment,r.hide(n),s.classList.remove("jp-carousel-is-disabled")}else j(jetpackCarouselStrings.comment_post_error,!1)};var d=[];for(var m in c)if(m){var g=encodeURIComponent(m)+"="+encodeURIComponent(c[m]);d.push(g.replace(/%20/g,"+"))}var h=d.join("&");u.send(h)}}(e):(r.closest(a,".jp-carousel-photo-icons-container")||a.classList.contains("jp-carousel-photo-title"))&&function(e){e.preventDefault();var t=e.target,o=p.info.querySelector(".jp-carousel-info-extra"),a=p.info.querySelector(".jp-carousel-image-meta"),i=p.info.querySelector(".jp-carousel-comments-wrapper"),n=p.info.querySelector(".jp-carousel-icon-info"),l=p.info.querySelector(".jp-carousel-icon-comments");function s(){l&&l.classList.remove("jp-carousel-selected"),n.classList.toggle("jp-carousel-selected"),i&&i.classList.remove("jp-carousel-show"),a&&(a.classList.toggle("jp-carousel-show"),a.classList.contains("jp-carousel-show")?o.classList.add("jp-carousel-show"):o.classList.remove("jp-carousel-show"))}function c(){n&&n.classList.remove("jp-carousel-selected"),l.classList.toggle("jp-carousel-selected"),a&&a.classList.remove("jp-carousel-show"),i&&(i.classList.toggle("jp-carousel-show"),i.classList.contains("jp-carousel-show")?o.classList.add("jp-carousel-show"):o.classList.remove("jp-carousel-show"))}(r.closest(t,".jp-carousel-icon-info")||t.classList.contains("jp-carousel-photo-title"))&&(a&&a.classList.contains("jp-carousel-show")?r.scrollToElement(p.overlay,p.overlay,s):(s(),r.scrollToElement(p.info,p.overlay))),r.closest(t,".jp-carousel-icon-comments")&&(i&&i.classList.contains("jp-carousel-show")?r.scrollToElement(p.overlay,p.overlay,c):(c(),r.scrollToElement(p.info,p.overlay)))}(e)}),window.addEventListener("keydown",h),p.overlay.addEventListener("jp_carousel.afterOpen",function(){v(),p.slides.length<=1||(p.slides.length<=5?r.show(p.info.querySelector(".jp-swiper-pagination")):r.show(p.info.querySelector(".jp-carousel-pagination")))}),p.overlay.addEventListener("jp_carousel.beforeClose",function(){f(),document.documentElement.style.removeProperty("height"),e&&e.enable(),r.hide(p.info.querySelector(".jp-swiper-pagination")),r.hide(p.info.querySelector(".jp-carousel-pagination"))}),p.overlay.addEventListener("jp_carousel.afterClose",function(){window.history.pushState?history.pushState("",document.title,window.location.pathname+window.location.search):window.location.href="",l="",p.isOpen=!1}),p.overlay.addEventListener("touchstart",function(e){e.touches.length>1&&e.preventDefault()}))}function j(e,t){var o=p.overlay.querySelector("#jp-carousel-comment-post-results"),a="jp-carousel-comment-post-"+(t?"success":"error");o.innerHTML=''+e+"",r.hide(p.overlay.querySelector("#jp-carousel-comment-form-spinner")),p.overlay.querySelector("#jp-carousel-comment-form").classList.remove("jp-carousel-is-disabled"),r.show(o)}function b(){var e=document.querySelectorAll("a img[data-attachment-id]");Array.prototype.forEach.call(e,function(e){var t=e.parentElement,o=t.parentElement;if(!o.classList.contains("gallery-icon")&&!r.closest(o,u)&&t.hasAttribute("href")){var a=!1;t.getAttribute("href").split("?")[0]===e.getAttribute("data-orig-file").split("?")[0]&&1===Number(jetpackCarouselStrings.single_image_gallery_media_file)&&(a=!0),t.getAttribute("href")===e.getAttribute("data-permalink")&&(a=!0),a&&(y(e),t.classList.add("single-image-gallery"),t.setAttribute("data-carousel-extra",JSON.stringify({blog_id:Number(jetpackCarouselStrings.blog_id)})))}})}function S(t,r){p.isOpen?(L(r),e.slideTo(r+1)):F(t,{startIndex:r})}function L(e){(!e||e<0||e>p.slides.length)&&(e=0),p.currentSlide=p.slides[e];var o,a,i=p.currentSlide,n=i.attrs.attachmentId;H(p.slides[e]),function(e){var t=[],r=p.slides.length;if(r>1){var o=e>0?e-1:r-1;t.push(o);var a=e
    "+jetpackCarouselStrings[o]+"
    "+a+""}}t.innerHTML=r,t.style.removeProperty("display")}(p.slides[e].attrs.imageMeta),function(e){if(!e)return!1;var r,o=[e.attrs.origWidth,e.attrs.origHeight],a=document.createElement("a");a.href=e.attrs.src.replace(/\?.+$/,""),r=null!==a.hostname.match(/^i[\d]{1}\.wp\.com$/i)?a.href:e.attrs.origFile.replace(/\?.+$/,"");var i=p.info.querySelector(".jp-carousel-download-text"),n=p.info.querySelector(".jp-carousel-image-download");i.innerHTML=t.applyReplacements(jetpackCarouselStrings.download_original,o),n.setAttribute("href",r),n.style.removeProperty("display")}(i),1===Number(jetpackCarouselStrings.display_comments)&&(o=p.slides[e].attrs.commentsOpened,a=p.info.querySelector("#jp-carousel-comment-form-container"),1===parseInt(o,10)?r.fadeIn(a):r.fadeOut(a),_(n),r.hide(p.info.querySelector("#jp-carousel-comment-post-results")));var s=p.info.querySelector(".jp-carousel-pagination");if(s&&p.slides.length>5){var c=e+1;s.innerHTML=""+c+" / "+p.slides.length+""}jetpackCarouselStrings.stats&&p.isOpen&&((new Image).src=document.location.protocol+"//pixel.wp.com/g.gif?"+jetpackCarouselStrings.stats+"&post="+encodeURIComponent(n)+"&rand="+Math.random()),p.isOpen&&g(n),l="#jp-carousel-"+n,window.location.hash=l}function k(){document.body.style.overflow=a,document.documentElement.style.overflow=i,I(),f(),r.emitEvent(p.overlay,"jp_carousel.beforeClose"),window.scrollTo(window.scrollX||window.pageXOffset||0,n||0),p.isOpen=!1,e.destroy(),p.slides=[],p.currentSlide=void 0,p.gallery.innerHTML="",r.fadeOut(p.overlay,function(){r.emitEvent(p.overlay,"jp_carousel.afterClose")})}function x(e){if("object"!=typeof e&&(e={}),void 0===e.origFile)return"";if(void 0===e.origWidth||void 0===e.maxWidth)return e.origFile;if(void 0===e.mediumFile||void 0===e.largeFile)return e.origFile;var t=document.createElement("a");t.href=e.largeFile;var r=/^i[0-2]\.wp\.com$/i.test(t.hostname),o=q(e.largeFile,e.origWidth,r),a=parseInt(o[0],10),i=parseInt(o[1],10);if(e.origMaxWidth=e.maxWidth,e.origMaxHeight=e.maxHeight,void 0!==window.devicePixelRatio&&window.devicePixelRatio>1&&(e.maxWidth=e.maxWidth*window.devicePixelRatio,e.maxHeight=e.maxHeight*window.devicePixelRatio),a>=e.maxWidth||i>=e.maxHeight)return e.largeFile;var n=q(e.mediumFile,e.origWidth,r),l=parseInt(n[0],10),s=parseInt(n[1],10);if(l>=e.maxWidth||s>=e.maxHeight)return e.mediumFile;if(r){if(-1===e.largeFile.lastIndexOf("?"))return e.largeFile;var c=function(e){var t;try{t=new URL(e)}catch(t){return e}var r=["quality","ssl","filter","brightness","contrast","colorize","smooth"],o=Array.from(t.searchParams.entries());return t.search="",o.forEach(([e,o])=>{r.includes(e)&&t.searchParams.append(e,o)}),t}(e.largeFile);return(e.origWidth>e.maxWidth||e.origHeight>e.maxHeight)&&(e.origMaxWidth=2*e.maxWidth,e.origMaxHeight=2*e.maxHeight,c.searchParams.set("fit",e.origMaxWidth+","+e.origMaxHeight)),c.toString()}return e.origFile}function q(e,t,r){var o,a=r?e.replace(/.*=([\d]+%2C[\d]+).*$/,"$1"):e.replace(/.*-([\d]+x[\d]+)\..+$/,"$1");return"9999"===(o=a!==e?r?a.split("%2C"):a.split("x"):[t,0])[0]&&(o[0]="0"),"9999"===o[1]&&(o[1]="0"),o}function A(e){return e>=1?Math.round(10*e)/10+"s":"1/"+Math.round(1/e)+"s"}function E(e){return!e.match(" ")&&e.match("_")?"":e}function _(e,t){var a=void 0===t,i=p.info.querySelector(".jp-carousel-icon-comments .jp-carousel-has-comments-indicator");if(i.classList.remove("jp-carousel-show"),clearInterval(o),e){(!t||t<1)&&(t=0);var n=p.info.querySelector(".jp-carousel-comments"),l=p.info.querySelector("#jp-carousel-comments-loading");r.show(l),a&&(r.hide(n),n.innerHTML="");var s=new XMLHttpRequest,c=jetpackCarouselStrings.ajaxurl+"?action=get_attachment_comments&nonce="+jetpackCarouselStrings.nonce+"&id="+e+"&offset="+t;s.open("GET",c),s.setRequestHeader("X-Requested-With","XMLHttpRequest");var u=function(){r.fadeIn(n),r.fadeOut(l)};s.onload=function(){if(p.currentSlide&&p.currentSlide.attrs.attachmentId===e){var c,d=s.status>=200&&s.status<300;try{c=JSON.parse(s.responseText)}catch{}if(!d||!c||!Array.isArray(c))return u();a&&(n.innerHTML="");for(var m=0;m'+g.gravatar_markup+'
    '+g.author_markup+'
    '+g.date_gmt+"
    "+g.content+"
    ",n.appendChild(h),clearInterval(o),o=setInterval(function(){p.container.scrollTop+150>window.innerHeight&&(_(e,t+10),clearInterval(o))},300)}c.length>0&&(r.show(n),i.innerText=c.length,i.classList.add("jp-carousel-show")),r.hide(l)}},s.onerror=u,s.send()}}function H(e){var t=e.el,r=e.attrs,o=t.querySelector("img");if(!o.hasAttribute("data-loaded")){var a=!!r.previewImage,i=r.thumbSize;!a||i&&t.offsetWidth>i.width?o.src=r.src:o.src=r.previewImage,o.setAttribute("itemprop","image"),o.setAttribute("data-loaded",1)}}function T(t){var r=t.el;e&&e.slides&&(r=e.slides[e.activeIndex]);var o=t.attrs.originalElement;o.complete&&0!==o.naturalHeight?C(t,r,o):o.onload=function(){C(t,r,o)}}function C(e,r,o){var a=t.getBackgroundImage(o);e.backgroundImage=a,r.style.backgroundImage="url("+a+")",r.style.backgroundSize="cover"}function I(){p.commentField&&(p.commentField.value="")}function M(e,o){p.slides=[];var a={width:window.innerWidth,height:window.innerHeight-64};0!==o&&null!==e[o].getAttribute("data-gallery-src")&&((new Image).src=e[o].getAttribute("data-gallery-src"));var i=!!r.closest(e[0],".tiled-gallery.type-rectangular");Array.prototype.forEach.call(e,function(e,o){var n=r.closest(e,"a"),l=e.getAttribute("data-orig-file")||e.getAttribute("src-orig"),s=e.getAttribute("data-attachment-id")||e.getAttribute("data-id")||"0",c=document.querySelector('img[data-attachment-id="'+s+'"] + figcaption');c=c?c.innerHTML:e.getAttribute("data-image-caption");var u={originalElement:e,attachmentId:s,commentsOpened:e.getAttribute("data-comments-opened")||"0",imageMeta:r.getJSONAttribute(e,"data-image-meta")||{},title:e.getAttribute("data-image-title")||"",desc:e.getAttribute("data-image-description")||"",mediumFile:e.getAttribute("data-medium-file")||"",largeFile:e.getAttribute("data-large-file")||"",origFile:l||"",thumbSize:{width:e.naturalWidth,height:e.naturalHeight},caption:c||"",permalink:n&&n.getAttribute("href"),src:l||e.getAttribute("src")||""},d=r.closest(e,".tiled-gallery-item"),m=d&&d.querySelector(".tiled-gallery-caption"),g=m&&m.innerHTML;g&&(u.caption=g);var h=function(e){var t=e.getAttribute("data-orig-size")||"";if(t){var r=t.split(",");return{width:parseInt(r[0],10),height:parseInt(r[1],10)}}return{width:e.getAttribute("data-original-width")||e.getAttribute("width")||void 0,height:e.getAttribute("data-original-height")||e.getAttribute("height")||void 0}}(e);if(u.origWidth=h.width||u.thumbSize.width,u.origHeight=h.height||u.thumbSize.height,"undefined"!=typeof wpcom&&wpcom.carousel&&wpcom.carousel.generateImgSrc?u.src=wpcom.carousel.generateImgSrc(e,a):u.src=x({origFile:u.src,origWidth:u.origWidth,origHeight:u.origHeight,maxWidth:a.width,maxHeight:a.height,mediumFile:u.mediumFile,largeFile:u.largeFile}),e.setAttribute("data-gallery-src",u.src),"0"!==u.attachmentId){u.title=t.texturize(u.title),u.desc=t.texturize(u.desc),u.caption=t.texturize(u.caption);var f=new Image,v=document.createElement("div");v.classList.add("swiper-slide"),v.setAttribute("itemprop","associatedMedia"),v.setAttribute("itemscope",""),v.setAttribute("itemtype","https://schema.org/ImageObject");var y=document.createElement("div");y.classList.add("swiper-zoom-container"),p.gallery.appendChild(v),v.appendChild(y),y.appendChild(f),v.setAttribute("data-attachment-id",u.attachmentId),v.setAttribute("data-permalink",u.permalink),v.setAttribute("data-orig-file",u.origFile),i&&(u.previewImage=u.src);var w={el:v,attrs:u,index:o};p.slides.push(w)}})}function F(e,t){if(!window.JetpackSwiper){var o=document.querySelector("#jp-carousel-loading-overlay");r.show(o);var a=document.createElement("script");return a.id="jetpack-carousel-swiper-js",a.src=window.jetpackSwiperLibraryPath.url,a.async=!0,a.onload=function(){r.hide(o),O(e,t)},a.onerror=function(){r.hide(o)},void document.head.appendChild(a)}O(e,t)}function O(t,o){var l,s={imgSelector:".gallery-item [data-attachment-id], .tiled-gallery-item [data-attachment-id], img[data-attachment-id], img[data-id]",startIndex:0},c=r.getJSONAttribute(t,"data-carousel-extra");if(!c)return;const u=t.querySelectorAll(s.imgSelector);if(u.length&&(w(),!p.isOpen)){for(var d in p.isOpen=!0,a=getComputedStyle(document.body).overflow,document.body.style.overflow="hidden",i=getComputedStyle(document.documentElement).overflow,document.documentElement.style.overflow="hidden",n=window.scrollY||window.pageYOffset||0,p.container.setAttribute("data-carousel-extra",JSON.stringify(c)),m(["open","view_image"]),o||{})s[d]=o[d];-1===s.startIndex&&(s.startIndex=0),r.emitEvent(p.overlay,"jp_carousel.beforeOpen"),p.gallery.innerHTML="",p.overlay.style.opacity=1,p.overlay.style.display="block",M(u,s.startIndex),(e=new window.JetpackSwiper(".jp-carousel-swiper-container",{centeredSlides:!0,zoom:!0,loop:p.slides.length>1,enabled:p.slides.length>1,pagination:{el:".jp-swiper-pagination",clickable:!0},navigation:{nextEl:".jp-swiper-button-next",prevEl:".jp-swiper-button-prev"},initialSlide:s.startIndex,on:{init:function(){L(s.startIndex)}},preventClicks:!1,preventClicksPropagation:!1,preventInteractionOnTransition:!r.isTouch(),threshold:5})).on("slideChange",function(e){p.isOpen&&(L(e.realIndex),p.overlay.classList.remove("jp-carousel-hide-controls"))}),e.on("zoomChange",function(e,t){t>1&&p.overlay.classList.add("jp-carousel-hide-controls"),1===t&&p.overlay.classList.remove("jp-carousel-hide-controls")}),e.on("doubleTap",function(e){if(clearTimeout(l),1===e.zoom.scale)var t=setTimeout(function(){p.overlay.classList.remove("jp-carousel-hide-controls"),clearTimeout(t)},150)}),e.on("tap",function(){e.zoom.scale>1&&(l=setTimeout(function(){p.overlay.classList.toggle("jp-carousel-hide-controls")},150))}),r.fadeIn(p.overlay,function(){r.emitEvent(p.overlay,"jp_carousel.afterOpen")})}}function W(e){if("click"!==e.type){if("keydown"===e.type){const t=document.activeElement.parentElement,r=t&&t.classList.contains("tiled-gallery__item");" "!==e.key&&"Enter"!==e.key||!r||R(e)}}else R(e)}function N(e){var t=e.parentElement,o=t.parentElement,a=null;return o&&o.classList.contains("wp-block-image")?a=t.getAttribute("href"):t&&t.classList.contains("wp-block-image")&&t.querySelector(":scope > a")&&(a=t.querySelector(":scope > a").getAttribute("href")),!(a&&a.split("?")[0]!==e.getAttribute("data-orig-file").split("?")[0]&&a!==e.getAttribute("data-permalink")||t.classList.contains("gallery-caption")||r.matches(t,"figcaption"))}function R(e){if(window.CSS&&window.CSS.supports&&window.CSS.supports("display","grid")){var t,o=e.target,a=r.closest(o,c);if(a){if(!(t=a)||!t.getAttribute("data-carousel-extra"))return;if(!N(o))return;document.documentElement.style.height="auto",e.preventDefault(),e.stopPropagation();var i=r.closest(o,d),n=Array.prototype.indexOf.call(a.querySelectorAll(d),i);F(a,{startIndex:n})}}}document.body.addEventListener("click",W),document.body.addEventListener("keydown",W),document.querySelectorAll(u+"img").forEach(function(e){N(e)&&y(e)}),1===Number(jetpackCarouselStrings.single_image_gallery)&&(b(),document.body.addEventListener("is.post-load",function(){b()})),window.addEventListener("hashchange",function(){var e=/jp-carousel-(\d+)/;if(window.location.hash&&e.test(window.location.hash)){if(window.location.hash!==l||!p.isOpen)if(window.location.hash&&p.gallery&&!p.isOpen&&history.back)history.back();else{l=window.location.hash;for(var t=window.location.hash.match(e),r=parseInt(t[1],10),o=document.querySelectorAll(c),a=0;a 400) { $(".fixed-top").addClass("scrolled slideInDown"); } else { $(".fixed-top").removeClass("scrolled"); } }); // FIXED TOP CATEGORIES NAV INNER PAGE $(document).on("scroll", function() { if ($(document).scrollTop() > 1200) { $(".cats-bar").addClass("scrolled slideInDown"); } else { $(".cats-bar").removeClass("scrolled"); } }); */ // MENU $(".but-menu").click(function () { $("#menu").addClass("reveal slideInLeft"); $('html').css('overflow', 'hidden'); $('body').bind('touchmove', function (e) { e.preventDefault() }); }); $(".menu-close").click(function () { $("#menu").removeClass("reveal"); $('html').css('overflow', 'scroll'); $('body').unbind('touchmove'); }); // MENU CATS $(document).ready(function() { // 1. Identify "flat" items (no sub-menu) and add the CSS flag $('.accordion .col').each(function() { // If this column does not contain a sub-menu list if ($(this).find('.sub-cats').length === 0) { // Add a class so CSS can hide the arrow icon $(this).find('.menu-item').addClass('no-sub'); } }); // 2. Unified Click Handler $(".menu-item").on('click', function(e) { // Stop default behavior and event clashing e.preventDefault(); e.stopImmediatePropagation(); var $this = $(this); var $parentCol = $this.closest('.col'); var $subMenu = $parentCol.find('.sub-cats'); var $link = $parentCol.find('.menu-d a').attr('href'); // Close all other open submenus $(".sub-cats").not($subMenu).hide(); $(".menu-item").not($this).removeClass("open"); // IF SUBMENU EXISTS: Toggle the accordion if ($subMenu.length > 0) { $this.toggleClass("open"); $subMenu.stop(true, true).toggle(); } // IF NO SUBMENU: Navigate to the destination URL else if ($link) { window.location.href = $link; } }); }); // SEARCH $(".but-search").click(function () { $("#search-bar").addClass("reveal slideInDown"); }); $(".search-close").click(function () { $("#search-bar").removeClass("reveal"); }); $("#search_404").click(function () { $("#search-bar").addClass("reveal slideInDown"); }); // FIXED FILTERS / TRENDING BAR ON SCROLL /* $('.fixed-bar.trending-bar').scrollToFixed({ marginTop: 130 }); */ $(window).on('load', function () { if ( $('.mobile-bar-drop').length > 0 && typeof $.fn.scrollToFixed === 'function' ) { $('.mobile-bar-drop').scrollToFixed({ marginTop: 110 }); } }); // FIXED AD ON SCROLL /* $('.fixed-ad-scroll').scrollToFixed({ marginTop: 140, zIndex: 10, limit: function() { var limit = $('#footer').offset().top - $('.fixed-ad-scroll').outerHeight(true) - 0; return limit; } }); */ /* $('.fixed-ad-scroll-bottom').scrollToFixed({ marginTop:400, limit: function() { var limit; if ($('.post-related').length > 0) { limit = $('.post-related').offset().top - $('.fixed-ad-scroll-bottom').outerHeight(true) - 80; } else { limit = $('#footer').offset().top - $('.fixed-ad-scroll-bottom').outerHeight(true) - 40; } return limit; } }); */ // FIXED SOCIAL ON SCROLL /* $('.social-follow.fixed').scrollToFixed({ marginTop: 200, limit: function() { var limit = $('.post-tags').offset().top - $('.social-follow.fixed').outerHeight(true) - 40; return limit; } }); */ // FIXED VIDEO ON SCROLL /* $('.fixed-watch-video').scrollToFixed({ marginTop: 200, limit: function() { var limit; if ($('.post-related').length > 0) { limit = $('.post-related').offset().top - $('.fixed-watch-video').outerHeight(true) - 80; } else { limit = $('#footer').offset().top - $('.fixed-watch-video').outerHeight(true) - 40; } return limit; } }); */ // FIXED SQUARE ON SCROLL /* $('.fixed-ad-aside').scrollToFixed({ marginTop: 200, limit: function() { var limit; if ($('.post-related').length > 0) { limit = $('.post-related').offset().top - $('.fixed-ad-aside').outerHeight(true) - 80; } else { limit = $('#footer').offset().top - $('.fixed-ad-aside').outerHeight(true) - 40; } if ($('.fixed-watch-video').length > 0) { limit += $('.fixed-watch-video').outerHeight(true); } return limit; } }); */ // READER'S RATING $(document).on("scroll", function () { if ($(document).scrollTop() > 200) { $(".reader-rating").addClass("scrolled bounceInUp"); } else { $(".reader-rating").removeClass("scrolled"); } }); // MOBILE BAR DROP $(".open-drop").click(function () { $(".open-drop").toggleClass("open"); }); $(".open-drop").click(function () { $(".mobile-bar-drop ul").toggle(); }); // VIDEOS PLAYLIST $(".video-playlist a").click(function () { var parent_div = $(this).closest('div'); var src = $(parent_div).attr('data-src'); var type = $(parent_div).attr('data-type'); var poster = $(parent_div).attr('data-poster'); var title = $(parent_div).attr('data-title'); var videoObj = $(this).parents(".mod-playlist").find(".video-js"); if (videoObj.length !== 0) { var player = videojs(videoObj.attr('id')); if (src == player.src()) { return; } if (player.ads && player.ads.isInAdMode()) { return; } player.poster(poster); player.src([{ type: type, src: src }]); player.play(); player.on('loadstart', function (event) { $('#' + player.id() + '_title').text(title) }); $(this).parents('.col-video-scrollable').find('p.play-now a').text('Play Now'); $(this).parents('.video-playlist').find('p.play-now a').text('Now Playing'); } }); // VIDEOS Playing Now Text $("p.play-now a").first().text('Now Playing'); // MOBILE ADHESION //$(".mobile-adhesion").delay(5000).fadeOut('slow'); /* // RENDER PENDING ADS function renderPendingAds() { $(".ad_pending").each(function(i, e){ renderAd($(e).attr('data-adunit'), $(e).attr('data-size'), $(e).attr('id')); $(e).removeClass('ad_pending'); }); } // REGULAR ADS renderPendingAds(); // INFINITE SCROLL ADS $(document.body).on('post-load', function () { renderPendingAds(); }); */ resizeIframes(); }); // IFRAME RESIZING function resizeIframes() { $("iframe").each(function (i, v) { if ($(v).hasClass('no-resize')) { return; } var domains = ['spotify', 'apple', 'vevo', 'music.amazon']; if (typeof $(v).attr('src') !== 'undefined') { $(domains).each(function (di, dv) { if ($(v).attr('src').indexOf(dv) !== -1) { $(v).attr('height', 450); } }); if ($(v).attr('src').indexOf('anchor') !== -1) { $(v).attr('height', 160); $(v).attr('scrolling', 'no'); } } }); } // inifiite scroll on category and tag pages (function ($) { $(document.body).on('post-load', function () { window.EncoreAdSystem.observerAds(); embedInitiate(); }); })(jQuery); // For initial load window.addEventListener('load', function () { embedInitiate(); }); function embedInitiate() { if (window.instgrm) { window.instgrm.Embeds.process(); } if (window.twttr && window.twttr.widgets && typeof window.twttr.widgets.load === 'function') { window.twttr.widgets.load(); } if (typeof window.tiktokEmbedLoad === 'function') { window.tiktokEmbedLoad(); } } // ajax load more - next page in infinite scroll window.almComplete = function (alm) { resizeIframes(); setupAllDfpAds(); //setupIframeOnDemand(); if (typeof initGallery === 'function') initGallery(); // actual code in partials/common/_gallery.php window.EncoreAdSystem.observerAds(); } $(document).ready(function () { if (typeof initGallery === 'function') initGallery(); // actual code in partials/common/_gallery.php }); window.almUrlUpdate = function (permalink, type) { gtag("event", "page_view", { page_path: window.location.pathname, custom_map: { 'dimension1': 'Categories', 'dimension2': 'Tags', 'dimension3': 'Authors', 'dimension4': 'Artists', 'dimension6': 'page_id', 'dimension7': 'Primary Category', 'dimension9': 'Paged Article', 'dimension10': 'Primary Search Term' } }); } // iframe on demand for youtube function setupIframeOnDemand() { $(".embed-youtube-on-demand").click(function () { var id = $(this).children('img').attr('data-id'); var iframe = ''; $(this).replaceWith(iframe); }); } $(function () { var url = new URL(window.location.href); if (url.searchParams.get('app')) { $("a").attr('href', function (index, item) { if (item) return item + (item.indexOf('?') != -1 ? "&app=true" : "?app=true"); }); } var subId3 = ''; if (subId3 = url.searchParams.get('subId3')) { $("a").attr('href', function (index, item) { if (item && item.indexOf('ticketmaster') !== -1) return item + (item.indexOf('?') != -1 ? "&subId3=" + subId3 : "?subId3=" + subId3); }); } let appleRegex = /(itunes.apple.com|podcasts.apple.com)([A-Za-z0-9\/_-]+)/gm; $("a").attr('href', function (index, item) { let affId = 'at=1001l36gv'; if (item && item.match(appleRegex) && item.indexOf(affId) === -1) { if (item.indexOf('?') != -1) return item + "&" + affId; else return item + "?" + affId; } }); });;