(function ($) { "use strict"; // Spinner var spinner = function () { setTimeout(function () { if ($('#spinner').length > 0) { $('#spinner').removeClass('show'); } }, 1); }; spinner(); // Initiate the wowjs new WOW().init(); // Sticky Navbar $(window).scroll(function () { if ($(this).scrollTop() > 45) { $('.navbar').addClass('sticky-top shadow-sm'); } else { $('.navbar').removeClass('sticky-top shadow-sm'); } }); // Smooth scrolling on the navbar links $(".navbar-nav a").on('click', function (event) { if (this.hash !== "") { event.preventDefault(); $('html, body').animate({ scrollTop: $(this.hash).offset().top - 60 }, 1500, 'easeInOutExpo'); if ($(this).parents('.navbar-nav').length) { $('.navbar-nav .active').removeClass('active'); $(this).closest('a').addClass('active'); } } }); // Back to top button $(window).scroll(function () { if ($(this).scrollTop() > 100) { $('.back-to-top').fadeIn('slow'); } else { $('.back-to-top').fadeOut('slow'); } }); $('.back-to-top').click(function () { $('html, body').animate({scrollTop: 0}, 1500, 'easeInOutExpo'); return false; }); // Facts counter $('[data-toggle="counter-up"]').counterUp({ delay: 10, time: 2000 }); // Testimonials carousel $(".testimonial-carousel").owlCarousel({ autoplay: true, smartSpeed: 1000, margin: 25, dots: false, loop: true, nav : true, navText : [ '', '' ], responsive: { 0:{ items:1 }, 992:{ items:2 } } }); //frontend $("body").on("click",":input",function (e){ $(this).addClass("border-1").removeClass("border-3 is-invalid"); }).on("click",".form-submit",function(e){ e.preventDefault(); let form = $(this).closest("form"); pckt.processForm(form); }).on("click",".init-tiny",function (e){ let id = $(this).closest("div").find(":input").attr("id"); $(".modal-dialog").addClass("modal-lg"); if(tinymce.get(id)){ tinyRemove("#" + id); }else{ tinyInit("#" + id); } }).on("click",":input",function (e){ $(this).addClass("border-1").removeClass("border-3 is-invalid"); }).on("submit","form",function (e){ e.preventDefault(); let form = $(this); pckt.processForm(form); }).on("click","a",function (e){ e.preventDefault(); let data = $(this).data(); let endpoint = $(this).attr("href"); let fqEndpoint = endpoint; if(data.hasOwnProperty("pocket") && data.hasOwnProperty("items")){ let pocket = '
'; $(data.pocket).html(pocket); if($(".modal").find(".pocket").length){ modal.show(); } if(data.hasOwnProperty("reset") && data.reset){ removeDataSource($(this).closest(".pocket")); } pckt.emptyPockets(); pckt.fillPockets(); }else if(data.hasOwnProperty("name")){ let pocketData = {}; let key = "override" + data.name.charAt(0).toUpperCase() + data.name.slice(1); pocketData[key] = fqEndpoint; pckt.getHtml(data.name,pocketData); }else{ pckt.getData(fqEndpoint,[]); } }).on("change","#sequence",function (){ $("#sequencePhone").attr("data-scrubs","").removeData("scrubs").closest("div").hide(); if($(this).val() === "text"){ $("#sequencePhone").attr("data-scrubs","req,numonly").data("scrubs","req,numonly").closest("div").show(); } }).on("mouseover","[type]",function (){ let data = $(this).closest(".cloned").data(); if(!data) return; if(!$(this).attr("title")){ let type = $(this).attr("type"); if(type === "email") type = "subject"; if(type === "html") type = "display"; let dataIndex = data.recordHeader.indexOf("data"); $(this).attr("title",data.record[dataIndex][type]); } }).on("click","button",function (){ buttonClickManager($(this)); }).on("click",".pocket-request",function (){ let data = $(this).data(); }).on("hide.bs.modal hidden.bs.modal",function (){ //reset the modal $(this).find(".modal-dialog").removeClass("modal-lg"); $(this).find(".modal-title, .modal-body, .modal-footer").empty(); }); const modal = new bootstrap.Modal(document.getElementById("generic-modal"), { keyboard: false }); const buttonClickManager = function(button){ let data = $(button).closest(".cloned").data(); let text = $(button).text(); if(data && data.hasOwnProperty("recordHeader")){ let buttonText = $(button).text().toLowerCase(); let isSequence = (data.recordHeader.indexOf("sequenceCd") >= 0); if(isSequence){ let nocodeIndex = data.recordHeader.indexOf("nocode"); let nocode = data.record[nocodeIndex]; let sequenceCdIndex = data.recordHeader.indexOf("sequenceCd"); let sequenceCd = data.record[sequenceCdIndex]; switch(buttonText){ case "run": case "trigger": let fails = []; nocode = nocode.split("?").join("/asJSON?"); nocode.match(/[^{\{]+(?=}\})/g).forEach(function(placeholder){ let val = prompt("What is the " + placeholder.toUpperCase() + "?"); if(!val){ fails.push(placeholder); } nocode = nocode.replace("{{" + placeholder + "}}",val); }) data.endpoint = nocode; copyToClipboard(data.endpoint); if(!fails.length){ sequencer("start",data.endpoint,data); }else{ console.log("Not Running Sequence. Missing requirements: " + fails.join(', ')); } break; case "delete": if(confirm("You will be permanently removing this Sequence template.\r\r*Accounts that are actively running this Sequence WILL NOT be deleted.")){ pckt.getData("Sequence/archiveSeq/" + sequenceCd,[]); strg.del($(button).closest(".cloned").data().objectName); $(button).closest(".cloned").hide(); } break case "copy": //copy strg.set("nocode",nocode); pckt.getData("Sequence/getAuthCd"); break; default: } }else{ //step let stepCdIndex = data.recordHeader.indexOf("stepCd"); let udNameIndex = data.recordHeader.indexOf("udName"); let stepCd = data.record[stepCdIndex]; let udName = data.record[udNameIndex]; switch (buttonText){ case "view": let url = strg.get("baseUrl") + "/Sequence/getStepView/" + stepCd; $("#popup").find("iframe").attr("src",url); let pocket = '
'; $(".modal-body").append(pocket); $(".modal-title").html(udName); modal.show(); pckt.fillPockets(); break; case "delete": if(confirm("You will be permanently removing this Step template.\r\r*Sequences and Accounts that are actively running this Step WILL NOT be deleted.")){ pckt.getData("Sequence/archiveStep/" + stepCd,[]); strg.del($(button).closest(".cloned").data().objectName); $(button).closest(".cloned").hide(); } break; } } }else if(text.toLowerCase().includes("payment")){ $(button).hide(function (){ $(this).delay(8000).fadeIn(2000); }); }else if(text === "Save Config"){ $(button).closest("form").trigger("submit"); } } const removeDataSource = function (pocket){ let pData = $(pocket).find("[data-data-source]").data(); return strg.del(pData.dataSource); } //begin defaults pckt.getData("/Auth/remote/status"); pckt.getData("/Process/planData"); pckt.getData("/Process/frontendBaseUrl"); strg.set("linkType","JSON"); pckt.processForm = function(form){ let formData = new FormData(); let myHeaders = new Headers(); let fails = []; let action = $(form).attr("action"); let pairs = $(form).serializeArray(); if(!action){ console.log("No action!"); return; } $(form).find(":input").each(function(){ let data = $(this).data(); let scrubs = (data.hasOwnProperty("scrubs") ? data.scrubs.split(",") : []) let elemData = {name:$(this).attr("name"),value:$(this).val(),scrubs:scrubs}; if(elemData.name){ formData.append(elemData.name, elemData.value); } let check = scrb.scrubEach(elemData,pairs); if(!check.success){ $(this).addClass("is-invalid border-3").removeClass("border-0").attr("title",check.errors.join(" ")); fails.push(elemData); } }) if(!fails.length){ if(action.includes("upload")){ let formDataPost = new FormData(form[0]); $.ajax({ url: action, type: "POST", data: formDataPost, success: function (result) { pckt.callback(action,result); }, cache: false, contentType: false, processData: false }); }else{ let requestOptions = { method: "POST", headers: myHeaders, body: formData, redirect: "follow" }; //console.log(fqReq,requestOptions); fetch(action, requestOptions) .then(response => response.json()) .then(result => pckt.callback(action,result)) .catch(error => console.log({action: action, error})); } }else{ console.log({fails}); } } pckt.checkComms = function (response){ if(!response || typeof response === "string") return; if(response.hasOwnProperty("errors")){ modal.hide(); pckt.displayComms(response.errors); } if(response.hasOwnProperty("messages")){ pckt.displayComms(response.messages); } } pckt.displayComms = function(comms,title){ title = (title || "Message Center"); let element = $("#generic-modal"); $(element).find(".modal-footer").hide() .end().find(".modal-title").html(title); (Object.keys(comms) || []).every(function(key){ $(element).find(".modal-body").append("
" + key.toUpperCase() + "
"); if(comms.hasOwnProperty(key) && typeof key === "string"){ $(element).find(".modal-body").append(comms[key].join("

")) modal.show(); } }) } pckt.loginView = function(){ if(strg.get("login")){ strg.set("authCheck",true); $("div.manage, .admin").show(); $("a.login, .marketing").hide(); $(".manage").trigger("click"); $("div.manage").find("a.manage").text(strg.get("login").entities.user.user); //sequencer("start","/Auth/remote/status/pulse",60000); } } pckt.logoutView = function (){ $("div.manage").hide(); $("a.login, .marketing").show(); $("a.admin").remove(); $(".main-section").empty(); sequencer("kill"); strg.clear(); pckt.getData("/Process/planData"); strg.set("linkType","JSON"); } pckt.callback = function(name,obj){ let nameClean = scrb.format(name,"alphaonly"); //check sequencer if(sequenceCycles.hasOwnProperty(nameClean) && nameClean !== "Authremotestatuspulse"){ if(obj.response.dateComplete){ sequencer("stop",nameClean); } return; } //send out messages if(obj && strg.get("authCheck") && !name.includes("pulse")) { pckt.checkComms(obj); } //check the object if(name.includes("pulse")){ if(!obj.response.hasOwnProperty("isAuthenticated")){ //you've been logged out pckt.logoutView(); } }else if(nameClean.includes("planData")){ let plans = obj.response; strg.set("plans",plans); (Object.keys(plans) || []).forEach(function(plan){ let limits = plans[plan].limits; let fees = plans[plan].fees; $("." + plan).find("span.sequences").text(limits.sequences).end() .find("span.steps").text(limits.steps).end() .find("span.monthly").text((fees.monthly).toFixed(2)).end() .find("span.email").text((fees.email*100).toFixed()).end() .find("span.text").text((fees.text*100).toFixed()).end() .find("span.transaction").text((fees.transaction*100).toFixed(2)).end() .find("span.signature").text((fees.signature).toFixed(2)) }) }else if(nameClean === "ProcessdemoRequest" || nameClean === "Processcontact"){ sequencer("start",obj.response.url,obj.response); $(":input:visible").val(""); }else if(name.includes("frontendBaseUrl")){ strg.set("baseUrl",obj.response.baseUrl); }else if(name.includes("adminNavigation")){ $("a.admin").remove(); $(".navbar-nav").append(obj.response).hide().fadeIn(250); }else if(name.includes("archive") || name.includes("/Sequence/create")){ //need to delete data-source and/or redraw screen $(".main-section").find("[data-reset]").trigger("click"); }else if(nameClean.includes("signup")){ strg.set("signup",obj.response); modal.hide(); if(obj.response.sequenceType === "popup"){ let url = obj.response.url; $("#popup").find("iframe").attr("src",url); let pocket = '
'; $(".modal-body").append(pocket); $(".modal-title").html("Plan Payment"); modal.show(); pckt.fillPockets(); setTimeout(function(){ sequencer("start",url.split("?").join("/asJSON?"),obj.response); },5000); }else{ obj.messages.primary.push("The payment Sequence has started."); obj.messages.primary.push("Check your " + obj.response.sequenceType + " messages to continue."); pckt.displayComms(obj.messages,"...awaiting Payment"); sequencer("start",obj.response.url,obj.response); } }else if(nameClean.includes("modalContent")){ let content = name.split("/").pop().split("?").shift(); $(".modal-dialog").addClass("modal-lg"); pckt.displayComms({"content":[obj.response]},content.toUpperCase()); if(nameClean.includes("planDetail")){ let container = $(".plan-detail"); let data = $(container).data(); if(data.hasOwnProperty("plan")){ let plan = strg.get("plans")[data.plan]; let amountDue = Math.floor(Math.random() * (500- 100 + 1) + 100); let totalFail = plan.fees.email + plan.fees.text; let totalSuccess = (amountDue * plan.fees.transaction) + totalFail; $(container).find(".sample-detail").find(".plan").text(data.plan.toUpperCase()); $(container).find(".sample-detail").find(".amount-due").text(amountDue.toFixed(2)); $(container).find(".sample-detail").find(".total-success").text(totalSuccess.toFixed(2)); $(container).find(".sample-detail").find(".total-fail").text(totalFail.toFixed(2)); } } }else if(name === "/Auth/remote/signOut"){ pckt.logoutView(); }else if(name.includes("getAuthCd")){ if(strg.get("nocode") && obj.response){ let link = strg.get("nocode") + '&ts=" & TODAY() & "&PublicAuthCd=' + obj.response; let placeholders = link.match(/[^{\{]+(?=}\})/g); switch (strg.get("linkType")){ case "GOOGLE": const cells = "ABCDEFGHIJKLMNOQRSTUVWXYZ".split(""); link = '=IMPORTXML(ArrayFormula("' + link + '"),"//response")'; placeholders.forEach(function(placeholder,i){ link = link.replace('{{'+placeholder+'}}','" & ' + cells[i] + '2 & "'); }) //fall through case "XML": link = link.split("?").join("/asXML?"); break case "JSON": link = link.split("?").join("/asJSON?"); break } copyToClipboard(link); $(".modal-dialog").addClass("modal-lg"); pckt.displayComms({[strg.get("linkType") + " sequence link"]:[link,"*Do not share this link as it contains private access keys.
**This link will expire in 30 days."]},"Sequence Link Copied"); } }else if(name === "/Auth/remote/status"){ strg.set("authCheck",true); if(obj.response.hasOwnProperty("isAuthenticated") && obj.response.isAuthenticated){ pckt.loginView(); } }else if(name === "/Auth/signIn"){ if(typeof obj.response === "object"){ pckt.displayComms({"message":["You are now logged in."]}); strg.set("login",obj.response); setTimeout(function (){ pckt.loginView(); }) }else{ pckt.displayComms({"message":["Login not found.
Try again!"]}); pckt.logoutView(); } }else if(name === "signout"){ if(obj.response.hasOwnProperty("success") && obj.response.success){ pckt.logoutView(); } }else if(name === "sequence" || name === "step" || name === "login" || name === "popupForm" || name === "wrapBuilder" || name === "view"){ $(".modal-dialog").removeClass("modal-lg"); pckt.displayComms({[name.toUpperCase()]:[obj]},name.toUpperCase()); switch (name){ case "step": $("textarea, [name=subject], [name=wrapCd]").parent().parent().hide(); $("body").off("change","[name=actionType]").on("change","[name=actionType]",function(){ let val = $(this).val(); $("textarea, [name=subject], [name=wrapCd]").val(""); $("textarea, [name=subject], [name=wrapCd]").removeData("scrubs").removeAttr("data-scrubs").parent().parent().hide(); tinyRemove(); switch(val){ case "relay-sms": $("[name=sms]").data("scrubs","req").attr("data-scrubs","req").parent().parent().show(); break; case "relay-email": $("[name=subject], [name=html], [name=text]").data("scrubs","req").attr("data-scrubs","req").parent().parent().show(); break; case "relay-phone": $("[name=robo]").data("scrubs","req").attr("data-scrubs","req").parent().parent().show(); break; case "display-html": $("[name=display]").data("scrubs","req").attr("data-scrubs","req").parent().parent().show(); break; case "input-custom": $("[name=form]").data("scrubs","req").attr("data-scrubs","req").parent().parent().show(); $("[name=wrapCd]").parent().parent().show(); break; case "input-payment": case "input-subscription": $("[name=wrapCd]").parent().parent().show(); break; } }); break; case "sequence": $("body").off("click",".add-step").on("click",".add-step",function(){ let form = $(this).closest("form"); let stepCount = $(form).find("select[name*=step]").length; let newStep = $(form).find("[name=step1]").parent().parent().clone(); $(newStep).find("span.step-count").text(stepCount+1).end().find(":input").attr("name","step" + (stepCount+1)); $(newStep).insertBefore($(".sequence-submit").parent()); }).off("click",".remove-step").on("click",".remove-step",function(){ let form = $(this).closest("form"); let stepCount = $(form).find("select[name*=step]").length; if(stepCount > 1){ $(form).find("[name=step" + (stepCount) + "]").parent().parent().remove(); } }); break; case "wrapBuilder": $("body").off("change","[name=wrapType]").on("change","[name=wrapType]",function(){ let form = $(this).closest("form"); $(form).find("textarea").parent().parent().show(); $(form).find("textarea[name=wrap]").attr("data-scrubs","expect:{{form}}").data("scrubs","expect:{{form}}"); if($(this).val() === "a"){ $(form).find("textarea[name=header], textarea[name=footer]").parent().parent().hide(); }else{ $(form).find("textarea[name=wrap]").removeAttr("data-scrubs").removeData("scrubs").parent().parent().hide(); } }).off("click",".wrap-cleaner").on("click",".wrap-cleaner",function(){ let form = $(this).closest("form"); $(form).find("textarea:hidden").val(""); }); $("[name=wrapType]").trigger("change"); } } //add tinymce button $(".tinymce").each(function(i,obj){ $(obj).closest(".col-12").find(".badge").remove(); $(obj).after(''); }) $("label").parent().each(function(i,obj){ $($(obj).find(".badge")).appendTo($(obj).find("label")); }) //display console.log({name,nameClean,obj}); } })(jQuery); const showTicker = function (msg){ let div = $("
").html(msg).hide(); $(".ticker").prepend(div); $(div).fadeIn(500,function(){ $(this).fadeOut(2500,function(){ $(this).remove(); }); }); } let sequenceCycles = {}; const sequencer = function (which, url, data, delay) { let urlClean = scrb.format((url || ""),"alphaonly"); delay = delay || 2500; data = data || {}; if(!strg.has(urlClean)){ strg.set(urlClean,data); } switch (which) { case "start": if(!url) return; showTicker("Started : " + url.split("/")[4]); sequenceCycles[urlClean] = setInterval(function(){ let data = strg.get(urlClean) || {}; showTicker("Checking : " + url.split("/")[4]); pckt.getData(url,[]); }, delay); break; case "stop": if(!url) return; let data = strg.get(urlClean) || {}; showTicker("Completed : " + url.split("/")[4]); clearInterval(sequenceCycles[urlClean]); break; case "kill": (Object.keys(sequenceCycles) || []).forEach(function (urlClean){ let data = strg.del(urlClean) || {}; showTicker("Killing " + urlClean) clearInterval(sequenceCycles[urlClean]); }) break; } return sequenceCycles; }; const copyToClipboard = function (text) { // Create a new temporary textarea element const textarea = document.createElement("textarea"); // Set the text content of the textarea to the input text textarea.value = text; // Append the textarea to the document document.body.appendChild(textarea); // Select the text inside the textarea textarea.select(); // Copy the selected text to the clipboard document.execCommand("copy"); //navigator.clipboard.writeText(textarea.value); // Remove the temporary textarea from the document document.body.removeChild(textarea); //https://www.freecodecamp.org/news/copy-text-to-clipboard-javascript/ } const tinyInit = function(id){ tinymce.init({ selector: id, plugins: 'anchor autolink charmap codesample emoticons image link lists media searchreplace table visualblocks wordcount checklist mediaembed casechange export formatpainter pageembed linkchecker a11ychecker tinymcespellchecker permanentpen powerpaste advtable advcode editimage tinycomments tableofcontents footnotes mergetags autocorrect typography inlinecss', toolbar: 'undo redo | blocks fontfamily fontsize | bold italic underline strikethrough | link image media table mergetags | addcomment showcomments | spellcheckdialog a11ycheck typography | align lineheight | checklist numlist bullist indent outdent | emoticons charmap | removeformat', tinycomments_mode: 'embedded', tinycomments_author: 'Author name', mergetags_list: [ { value: 'First.Name', title: 'First Name' }, { value: 'Email', title: 'Email' }, ] }); } const tinyRemove = function(id){ tinymce.remove(id); } const getParameterValue = function (parameterName, url) { url = url || window.location.href; const parameters = url.slice(url.indexOf('?') + 1).split('&'); for (let i = 0; i < parameters.length; i++) { const pair = parameters[i].split('='); const name = decodeURIComponent(pair[0]); const val = decodeURIComponent(pair[1]); if (name === parameterName) { return val; } } return null; } setTimeout(function (){ const paramTriggers = ["click","focus","promo","view","pop"]; paramTriggers.forEach(function(trigger){ const clickId = getParameterValue(trigger); if(clickId){ if($("#" + clickId).length){ setTimeout(function (){ $("#" + clickId).trigger("click"); },300); removeParameter(trigger); } } }) },500); function removeParameter(parameterName) { const url = window.location.href; const [baseUrl, queryString] = url.split('?'); if (!queryString) { return url; } const params = new URLSearchParams(queryString); params.delete(parameterName); const updatedQueryString = params.toString(); const updatedUrl = updatedQueryString ? `${baseUrl}?${updatedQueryString}` : baseUrl; // Update the URL in the address bar without reloading the page history.replaceState(null, '', updatedUrl); //history.pushState(obj, obj.Title, obj.Url); return updatedUrl; }