From 6dade4247ef86976d51bb8f771d47f8c2043ba48 Mon Sep 17 00:00:00 2001 From: Thomas Patrick Levy Date: Tue, 13 Sep 2022 16:49:36 -0700 Subject: [PATCH 1/3] Sanitize url hash before using to open achievement modals --- .changelogs/achievements-hash-validation.yml | 5 ++++ assets/js/app/llms-achievements.js | 29 ++++++++++++++------ 2 files changed, 26 insertions(+), 8 deletions(-) create mode 100644 .changelogs/achievements-hash-validation.yml diff --git a/.changelogs/achievements-hash-validation.yml b/.changelogs/achievements-hash-validation.yml new file mode 100644 index 0000000000..6dec13ee31 --- /dev/null +++ b/.changelogs/achievements-hash-validation.yml @@ -0,0 +1,5 @@ +significance: patch +type: security +links: + - gocodebox/private-issues#61 +entry: Fixed a data sanitization issue related to achievement permalinks. diff --git a/assets/js/app/llms-achievements.js b/assets/js/app/llms-achievements.js index e70ea6f920..14b79f3979 100644 --- a/assets/js/app/llms-achievements.js +++ b/assets/js/app/llms-achievements.js @@ -4,7 +4,7 @@ * @package LifterLMS/Scripts * * @since 3.14.0 - * @version 4.5.1 + * @version [version] */ LLMS.Achievements = { @@ -15,7 +15,7 @@ LLMS.Achievements = { * @since 3.14.0 * @since 4.5.1 Fix conditional loading check. * - * @return void + * @return {void} */ init: function() { @@ -36,7 +36,7 @@ LLMS.Achievements = { * * @since 3.14.0 * - * @return void + * @return {void} */ bind: function() { @@ -70,7 +70,7 @@ LLMS.Achievements = { * @since 3.14.0 * * @param obj $el The jQuery selector for the modal card. - * @return void + * @return {void} */ create_modal: function( $el ) { @@ -111,16 +111,29 @@ LLMS.Achievements = { * On page load, opens a modal if the URL contains an achievement in the location hash * * @since 3.14.0 + * @since [version] Sanitize achievement IDs before using window.location.hash to trigger the modal open. * - * @return void + * @return {void} */ maybe_open: function() { - var hash = window.location.hash; - if ( hash && -1 !== hash.indexOf( 'achievement-' ) ) { - $( 'a[href="' + hash + '"]' ).first().trigger( 'click' ); + let hash = window.location.hash.split( '-' ); + if ( 2 !== hash.length ) { + return; } + hash[1] = parseInt( hash[1] ); + if ( '#achievement-' !== hash[0] || ! Number.isInteger( hash[1] ) ) { + return; + } + + const a = document.querySelector( `a[href="${ hash.join( '-' ) }"]` ) + if ( ! a ) { + return; + } + + a.click(); + } }; From 2ba3cfd61767b0104de67cbd29876a4bcfdccc7d Mon Sep 17 00:00:00 2001 From: Thomas Patrick Levy Date: Wed, 14 Sep 2022 10:39:11 -0700 Subject: [PATCH 2/3] Update action scheduler to 3.5.1 --- .changelogs/wc-as-351.yml | 4 ++++ composer.json | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) create mode 100644 .changelogs/wc-as-351.yml diff --git a/.changelogs/wc-as-351.yml b/.changelogs/wc-as-351.yml new file mode 100644 index 0000000000..dbe3bc42e8 --- /dev/null +++ b/.changelogs/wc-as-351.yml @@ -0,0 +1,4 @@ +significance: patch +type: changed +entry: Updated `woocommerce/action-scheduler` to version + [3.5.1](https://github.com/woocommerce/action-scheduler/releases/tag/3.5.1). diff --git a/composer.json b/composer.json index cac8d2dd12..02927291cd 100644 --- a/composer.json +++ b/composer.json @@ -33,7 +33,7 @@ "lifterlms/lifterlms-cli": "0.0.3", "lifterlms/lifterlms-helper": "3.4.2", "lifterlms/lifterlms-rest": "1.0.0-beta.25", - "woocommerce/action-scheduler": "3.5.0" + "woocommerce/action-scheduler": "3.5.1" }, "require-dev": { "lifterlms/lifterlms-tests": "^3.3.1", From 72d64a6bddbfe2c09615df83a78b3c96b47dfe5f Mon Sep 17 00:00:00 2001 From: Thomas Patrick Levy Date: Wed, 14 Sep 2022 10:44:17 -0700 Subject: [PATCH 3/3] Build 6.10.2 --- .changelogs/achievements-hash-validation.yml | 5 --- .changelogs/wc-as-351.yml | 4 --- CHANGELOG.md | 12 +++++++ assets/js/app/llms-achievements.js | 4 +-- assets/js/llms.js | 29 +++++++++++----- assets/js/llms.min.js | 2 +- assets/maps/js/llms.js.map | 2 +- assets/maps/js/llms.min.js.map | 2 +- class-lifterlms.php | 2 +- languages/lifterlms.pot | 8 ++--- lifterlms.php | 2 +- package-lock.json | 4 +-- package.json | 2 +- readme.txt | 35 +++++++------------- 14 files changed, 57 insertions(+), 56 deletions(-) delete mode 100644 .changelogs/achievements-hash-validation.yml delete mode 100644 .changelogs/wc-as-351.yml diff --git a/.changelogs/achievements-hash-validation.yml b/.changelogs/achievements-hash-validation.yml deleted file mode 100644 index 6dec13ee31..0000000000 --- a/.changelogs/achievements-hash-validation.yml +++ /dev/null @@ -1,5 +0,0 @@ -significance: patch -type: security -links: - - gocodebox/private-issues#61 -entry: Fixed a data sanitization issue related to achievement permalinks. diff --git a/.changelogs/wc-as-351.yml b/.changelogs/wc-as-351.yml deleted file mode 100644 index dbe3bc42e8..0000000000 --- a/.changelogs/wc-as-351.yml +++ /dev/null @@ -1,4 +0,0 @@ -significance: patch -type: changed -entry: Updated `woocommerce/action-scheduler` to version - [3.5.1](https://github.com/woocommerce/action-scheduler/releases/tag/3.5.1). diff --git a/CHANGELOG.md b/CHANGELOG.md index 713fdd853f..31d8d5e9c4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,18 @@ LifterLMS Changelog =================== +v6.10.2 - 2022-09-14 +-------------------- + +##### Updates and Enhancements + ++ Updated `woocommerce/action-scheduler` to version [3.5.1](https://github.com/woocommerce/action-scheduler/releases/tag/3.5.1). + +##### Security Fixes + ++ Fixed a data sanitization issue related to achievement permalinks. + + v6.10.1 - 2022-09-07 -------------------- diff --git a/assets/js/app/llms-achievements.js b/assets/js/app/llms-achievements.js index 14b79f3979..5d7d6d4a81 100644 --- a/assets/js/app/llms-achievements.js +++ b/assets/js/app/llms-achievements.js @@ -4,7 +4,7 @@ * @package LifterLMS/Scripts * * @since 3.14.0 - * @version [version] + * @version 6.10.2 */ LLMS.Achievements = { @@ -111,7 +111,7 @@ LLMS.Achievements = { * On page load, opens a modal if the URL contains an achievement in the location hash * * @since 3.14.0 - * @since [version] Sanitize achievement IDs before using window.location.hash to trigger the modal open. + * @since 6.10.2 Sanitize achievement IDs before using window.location.hash to trigger the modal open. * * @return {void} */ diff --git a/assets/js/llms.js b/assets/js/llms.js index 7c2cc5c8fb..f7b4eb8772 100644 --- a/assets/js/llms.js +++ b/assets/js/llms.js @@ -28,7 +28,7 @@ var LLMS = window.LLMS || {}; * @package LifterLMS/Scripts * * @since 3.14.0 - * @version 4.5.1 + * @version 6.10.2 */ LLMS.Achievements = { @@ -39,7 +39,7 @@ var LLMS = window.LLMS || {}; * @since 3.14.0 * @since 4.5.1 Fix conditional loading check. * - * @return void + * @return {void} */ init: function() { @@ -60,7 +60,7 @@ var LLMS = window.LLMS || {}; * * @since 3.14.0 * - * @return void + * @return {void} */ bind: function() { @@ -94,7 +94,7 @@ var LLMS = window.LLMS || {}; * @since 3.14.0 * * @param obj $el The jQuery selector for the modal card. - * @return void + * @return {void} */ create_modal: function( $el ) { @@ -135,16 +135,29 @@ var LLMS = window.LLMS || {}; * On page load, opens a modal if the URL contains an achievement in the location hash * * @since 3.14.0 + * @since 6.10.2 Sanitize achievement IDs before using window.location.hash to trigger the modal open. * - * @return void + * @return {void} */ maybe_open: function() { - var hash = window.location.hash; - if ( hash && -1 !== hash.indexOf( 'achievement-' ) ) { - $( 'a[href="' + hash + '"]' ).first().trigger( 'click' ); + let hash = window.location.hash.split( '-' ); + if ( 2 !== hash.length ) { + return; + } + + hash[1] = parseInt( hash[1] ); + if ( '#achievement-' !== hash[0] || ! Number.isInteger( hash[1] ) ) { + return; } + const a = document.querySelector( `a[href="${ hash.join( '-' ) }"]` ) + if ( ! a ) { + return; + } + + a.click(); + } }; diff --git a/assets/js/llms.min.js b/assets/js/llms.min.js index aded776985..8179ebabbf 100644 --- a/assets/js/llms.min.js +++ b/assets/js/llms.min.js @@ -1,2 +1,2 @@ -var LLMS=window.LLMS||{};!function(a){"use strict";var t,e,n,i;LLMS.Achievements={init:function(){var t;a(".llms-achievement").length&&(t=this,a(function(){t.bind(),t.maybe_open()}))},bind:function(){var n=this;a(".llms-achievement").each(function(){n.create_modal(a(this))}),a(".llms-achievement").on("click",function(){var t=a(this),e="achievement-"+t.attr("data-id"),e=a("#"+e);e.length||n.create_modal(t),e.iziModal("open")})},create_modal:function(e){var t="achievement-"+e.attr("data-id"),n=a("#"+t);n.length||(n=a('
'),a("body").append(n)),n.iziModal({headerColor:"#3a3a3a",group:"achievements",history:!0,loop:!0,overlayColor:"rgba( 0, 0, 0, 0.6 )",transitionIn:"fadeInDown",transitionOut:"fadeOutDown",width:340,onOpening:function(t){t.setTitle(e.find(".llms-achievement-title").html()),t.setSubtitle(e.find(".llms-achievement-date").html()),t.setContent('
'+e.html()+"
")},onClosing:function(){window.history.pushState("",document.title,window.location.pathname+window.location.search)}})},maybe_open:function(){var t=window.location.hash;t&&-1!==t.indexOf("achievement-")&&a('a[href="'+t+'"]').first().trigger("click")}},LLMS.Ajax={url:window.ajaxurl||window.llms.ajaxurl,type:"post",data:[],cache:!1,dataType:"json",async:!0,response:[],init:function(t){if(null===t||"object"!=typeof t)return!1;t.url=("url"in t?t:this).url,t.type=("type"in t?t:this).type,t.data=("data"in t?t:this).data,t.cache=("cache"in t?t:this).cache,t.dataType=("dataType"in t?t:this).dataType,t.async=("async"in t?t:this).async,t.data._ajax_nonce=window.llms.ajax_nonce||wp_ajax_data.nonce;var e=LLMS.Rest.get_query_vars();return t.data.post_id="post"in e?e.post:null,!t.data.post_id&&a("input#post_ID").length&&(t.data.post_id=a("input#post_ID").val()),t},call:function(t){t=this.init(t);return!!t&&(this.request(t),this)},request:function(t){return a.ajax(t),this}},LLMS.Donut=function(t){function e(t){this.settings=a.extend({element:t.element,percent:100},t),this.circle=this.settings.element.find("path"),this.settings.stroke_width=parseInt(this.circle.css("stroke-width")),this.radius=(parseInt(this.settings.element.css("width"))-this.settings.stroke_width)/2,this.angle=a("body").hasClass("rtl")?82.5:97.5,this.i=Math.round(.75*this.settings.percent),this.first=!0,this.increment=a("body").hasClass("rtl")?-5:5,this.animate=function(){this.timer=setInterval(this.loop.bind(this),10)},this.loop=function(){this.angle+=this.increment,this.angle%=360;var t,e=this.angle/180*Math.PI,n=this.radius+this.settings.stroke_width/2+Math.cos(e)*this.radius,e=this.radius+this.settings.stroke_width/2+Math.sin(e)*this.radius;!0===this.first?(t=this.circle.attr("d")+" M "+n+" "+e,this.first=!1):t=this.circle.attr("d")+" L "+n+" "+e,this.circle.attr("d",t),this.i--,this.i<=0&&clearInterval(this.timer)}}(t=t).append(''),new e({element:t,percent:t.attr("data-perc")}).animate()},LLMS.Forms={address_info:{},$cities:null,$countries:null,$states:null,$states_holder:null,init:function(){var t;a("body").hasClass("wp-admin")&&!a("body").hasClass("profile-php")&&!a("body").hasClass("user-edit-php")||((t=this).bind_matching_fields(),t.bind_voucher_field(),t.bind_edit_account(),t.bind_l10n_selects())},bind_edit_account:function(){a("form.llms-person-form.edit-account").length&&a(".llms-toggle-fields").on("click",this.handle_toggle_click)},bind_l10n_selects:function(){var e=this;e.$cities=a("#llms_billing_city"),e.$countries=a(".llms-l10n-country-select select"),e.$states=a(".llms-l10n-state-select select"),e.$zips=a("#llms_billing_zip"),e.$countries.length&&LLMS.wait_for(function(){return void 0!==a.fn.llmsSelect2},function(){e.$states.length&&e.prep_state_field(),e.$countries.add(e.$states).llmsSelect2({width:"100%"}),window.llms.address_info&&(e.address_info=JSON.parse(window.llms.address_info)),e.$countries.on("change",function(){var t=a(this).val();e.update_locale_info(t)}).trigger("change")},"llmsSelect2")},bind_matching_fields:function(){a("input[data-match]").not('[type="password"]').each(function(){var n,i=a(this),s=a("#"+i.attr("data-match"));s.length&&(n=i.closest(".llms-form-field").add(s.closest(".llms-form-field")),i.on("input change",function(){var t=i.val(),e=s.val();t&&e&&t!==e?n.addClass("invalid"):n.removeClass("invalid")}))})},bind_voucher_field:function(){a("#llms-voucher-toggle").on("click",function(t){t.preventDefault(),a("#llms_voucher").toggle()})},get_field_parent:function(t){var e=t.closest(".wp-block-column");return e.length?e:t.closest(".llms-form-field")},get_label_text:function(t){t=t.clone();return t.find("*").remove(),t.text().trim()},handle_toggle_click:function(t){t.preventDefault();var t=a(this),e=a(a(this).attr("data-fields")),n=t.attr("data-is-showing")||"no",i="yes"===n?"hide":"show",s="yes"===n?"disabled":null,o="yes"===n?"data-change-text":"data-cancel-text";e.each(function(){a(this).closest(".llms-form-field")[i](),a(this).attr("disabled",s)}),t.text(t.attr(o)),t.attr("data-is-showing","yes"===n?"no":"yes")},prep_state_field:function(){var t=this.$states.closest(".llms-form-field");this.$holder=a('",{name:t.attr("name"),class:t.attr("class")+" hidden",type:"hidden"}).insertAfter(t),t.attr("disabled","disabled"),this.get_field_parent(t).hide()},enable_field:function(t){t.removeAttr("disabled"),t.next(".hidden[name="+t.attr("name")+"]").detach(),this.get_field_parent(t).show()}},LLMS.Instructors={init:function(){var t=this;a("body").hasClass("wp-admin")||a(".llms-instructors").length&&LLMS.wait_for_matchHeight(function(){t.bind()})},bind:function(){a(".llms-instructors .llms-author").matchHeight()}},LLMS.l10n=LLMS.l10n||{},LLMS.l10n.translate=function(t){return this.strings[t]||t},LLMS.l10n.replace=function(t,e){var n=this.translate(t);return a.each(e,function(t,e){-1!==t.indexOf("s")?e=e.toString():-1!==t.indexOf("d")&&(e=+e),n=n.replace(t,e)}),n},LLMS.LessonPreview={$els:null,init:function(){var t=this;this.$locked=a('a[href="#llms-lesson-locked"]'),this.$locked.length&&t.bind(),a(".llms-course-navigation").length&&LLMS.wait_for_matchHeight(function(){t.match_height()})},bind:function(){var n=this;this.$locked.on("click",function(){return!1}),this.$locked.on("mouseenter",function(){var t,e=a(this).find(".llms-tooltip");e.length||(t=(t=a(this).attr("data-tooltip-msg"))||LLMS.l10n.translate("You do not have permission to access this content"),e=n.get_tooltip(t),a(this).append(e)),setTimeout(function(){e.addClass("show")},10)}),this.$locked.on("mouseleave",function(){a(this).find(".llms-tooltip").removeClass("show")})},match_height:function(){a(".llms-course-navigation .llms-lesson-link").matchHeight()},get_tooltip:function(t){var e=a('
');return e.append('
'+t+"
"),e}},LLMS.Loops={init:function(){var t=this;a(".llms-loop").length&&LLMS.wait_for_matchHeight(function(){t.match_height()})},match_height:function(){a(".llms-loop-item .llms-loop-item-content").matchHeight(),a(".llms-achievement-loop-item .llms-achievement").matchHeight(),a(".llms-certificate-loop-item .llms-certificate").matchHeight()}},LLMS.OutlineCollapse={$outlines:null,init:function(){this.$outlines=a(".llms-widget-syllabus--collapsible"),this.$outlines.length&&this.bind()},bind:function(){var i=this;this.$outlines.each(function(){var t=a(this),e=t.find(".llms-section .section-header");e.on("click",function(t){t.preventDefault();var e=a(this).closest(".llms-section");switch(i.get_section_state(e)){case"closed":i.open_section(e);break;case"opened":i.close_section(e)}}),t.find(".llms-collapse-toggle").on("click",function(t){t.preventDefault();var n="close"===a(this).attr("data-action")?"opened":"closed";e.each(function(){var t=a(this).closest(".llms-section"),e=i.get_section_state(t);if(n!==e)return!0;switch(e){case"closed":i.close_section(t);break;case"opened":i.open_section(t)}a(this).trigger("click")})})})},close_section:function(t){t.removeClass("llms-section--opened").addClass("llms-section--closed")},open_section:function(t){t.removeClass("llms-section--closed").addClass("llms-section--opened")},get_section_state:function(t){return t.hasClass("llms-section--opened")?"opened":"closed"}},a.extend(LLMS.PasswordStrength,{$meter:a(".llms-password-strength-meter"),$pass:null,$conf:null,$form:null,init:function(){var t;a("body").hasClass("wp-admin")||this.setup_references()&&(t=this,LLMS.wait_for(function(){return"undefined"!=typeof wp&&void 0!==wp.passwordStrength},function(){t.bind(),t.$form.trigger("llms-password-strength-ready")}))},bind:function(){var t=this;this.$form.hasClass("llms-checkout")||t.$form.on("submit",t,t.submit),t.$pass.add(t.$conf).on("keyup",function(){t.check_strength()})},check_strength:function(){var t=this.$pass.closest(".llms-form-field"),e=this.$conf&&this.$conf.length?this.$conf.closest(".llms-form-field"):null,n=this.$pass.val().length,i=this.$conf&&this.$conf.length?this.$conf.val().length:0;n||i?(this.get_current_strength_status()?(t.removeClass("invalid").addClass("valid"),i&&e.removeClass("invalid").addClass("valid")):(t.removeClass("valid").addClass("invalid"),i&&e.removeClass("valid").addClass("invalid")),this.$meter.removeClass("too-short very-weak weak medium strong mismatch"),this.$meter.show().addClass(this.get_current_strength("slug")),this.$meter.html(this.get_current_strength("text"))):(t.removeClass("valid invalid"),e&&e.removeClass("valid invalid"),this.$meter.hide())},checkout:function(t,e){t.get_current_strength_status()?e(!0):e(LLMS.l10n.translate("There is an issue with your chosen password."))},get_blocklist:function(){var e=wp.passwordStrength.userInputDisallowedList().concat(this.get_setting("blocklist",[]));return this.$form.find('input[type="text"], input[type="email"], input[type="tel"], input[type="number"]').each(function(){var t=a(this).val();t&&e.push(t)}),e},get_current_strength:function(t){t=t||"int";var e,n=this.$pass.val(),i=this.$conf&&this.$conf.length?this.$conf.val():"";return n.length');return e.append(t.$element.closest(".llms-access-plan").find(".llms-access-plan-restrictions ul").clone()),e},placement:"top",style:"inverse",title:LLMS.l10n.translate("Members Only Pricing"),width:"280px"})})}},LLMS.Review={init:function(){this.bind()},bind:function(){a("#llms_review_submit_button").click(function(){""!==a("#review_title").val()&&""!==a("#review_text").val()?jQuery.ajax({type:"post",dataType:"json",url:window.llms.ajaxurl,data:{action:"LLMSSubmitReview",review_title:a("#review_title").val(),review_text:a("#review_text").val(),pageID:a("#post_ID").val()},success:function(){console.log("Review success"),a("#review_box").hide("swing"),a("#thank_you_box").show("swing")},error:function(t,e,n){console.log(t),console.log(e),console.log(n)}}):(""===a("#review_title").val()?a("#review_title_error").show("swing"):a("#review_title_error").hide("swing"),""===a("#review_text").val()?a("#review_text_error").show("swing"):a("#review_text_error").hide("swing"))}),a("#_llms_display_reviews").attr("checked")?(a(".llms-num-reviews-top").addClass("top"),a(".llms-num-reviews-bottom").show()):a(".llms-num-reviews-bottom").hide(),a("#_llms_display_reviews").change(function(){a("#_llms_display_reviews").attr("checked")?(a(".llms-num-reviews-top").addClass("top"),a(".llms-num-reviews-bottom").show()):(a(".llms-num-reviews-top").removeClass("top"),a(".llms-num-reviews-bottom").hide())})}},LLMS.Spinner={get:function(t,e){var n=t.find(".llms-spinning").first();return n.length||(n=a('
'),t.append(n)),n},start:function(t,e){var n=this;t.each(function(){n.get(a(this),e).show()})},stop:function(t){var e=this;t.each(function(){e.get(a(this)).hide()})}},t=function(){function l(){for(var t=0,e={};ts.get("events",[]).length&&(e=s.getAll(),s.clear("events"),e.events.push(t),LLMS.Ajax.call({data:{action:"persist_tracking_events","llms-tracking":JSON.stringify(e)},error:function(t,e,n){console.log(t,e,n)},success:function(t){"error"===t.code&&console.log(t.code,t.message)}})))},this.getSettings=function(){return n},this.makeEventObj=function(t){return a.extend(t,{url:window.location.href,time:Math.round((new Date).getTime()/1e3)})},a("body").hasClass("wp-admin")||(n.nonce&&s.set("nonce",n.nonce),i.addEvent("page.load"),window.addEventListener("beforeunload",t),window.addEventListener("unload",e),document.addEventListener("visibilitychange",o))},llms.tracking=new LLMS.Tracking(llms.tracking),LLMS.Rest={init:function(){this.bind()},bind:function(){},is_path:function(t){for(var e=!1,n=window.location.href,i=0;i'),l("body").append(n)),n.iziModal({headerColor:"#3a3a3a",group:"achievements",history:!0,loop:!0,overlayColor:"rgba( 0, 0, 0, 0.6 )",transitionIn:"fadeInDown",transitionOut:"fadeOutDown",width:340,onOpening:function(t){t.setTitle(e.find(".llms-achievement-title").html()),t.setSubtitle(e.find(".llms-achievement-date").html()),t.setContent('
'+e.html()+"
")},onClosing:function(){window.history.pushState("",document.title,window.location.pathname+window.location.search)}})},maybe_open:function(){let t=window.location.hash.split("-");if(2===t.length&&(t[1]=parseInt(t[1]),"#achievement-"===t[0]&&Number.isInteger(t[1]))){const e=document.querySelector(`a[href="${t.join("-")}"]`);e&&e.click()}}},LLMS.Ajax={url:window.ajaxurl||window.llms.ajaxurl,type:"post",data:[],cache:!1,dataType:"json",async:!0,response:[],init:function(t){if(null===t||"object"!=typeof t)return!1;t.url=("url"in t?t:this).url,t.type=("type"in t?t:this).type,t.data=("data"in t?t:this).data,t.cache=("cache"in t?t:this).cache,t.dataType=("dataType"in t?t:this).dataType,t.async=("async"in t?t:this).async,t.data._ajax_nonce=window.llms.ajax_nonce||wp_ajax_data.nonce;var e=LLMS.Rest.get_query_vars();return t.data.post_id="post"in e?e.post:null,!t.data.post_id&&l("input#post_ID").length&&(t.data.post_id=l("input#post_ID").val()),t},call:function(t){t=this.init(t);return!!t&&(this.request(t),this)},request:function(t){return l.ajax(t),this}},LLMS.Donut=function(t){function e(t){this.settings=l.extend({element:t.element,percent:100},t),this.circle=this.settings.element.find("path"),this.settings.stroke_width=parseInt(this.circle.css("stroke-width")),this.radius=(parseInt(this.settings.element.css("width"))-this.settings.stroke_width)/2,this.angle=l("body").hasClass("rtl")?82.5:97.5,this.i=Math.round(.75*this.settings.percent),this.first=!0,this.increment=l("body").hasClass("rtl")?-5:5,this.animate=function(){this.timer=setInterval(this.loop.bind(this),10)},this.loop=function(){this.angle+=this.increment,this.angle%=360;var t,e=this.angle/180*Math.PI,n=this.radius+this.settings.stroke_width/2+Math.cos(e)*this.radius,e=this.radius+this.settings.stroke_width/2+Math.sin(e)*this.radius;!0===this.first?(t=this.circle.attr("d")+" M "+n+" "+e,this.first=!1):t=this.circle.attr("d")+" L "+n+" "+e,this.circle.attr("d",t),this.i--,this.i<=0&&clearInterval(this.timer)}}(t=t).append(''),new e({element:t,percent:t.attr("data-perc")}).animate()},LLMS.Forms={address_info:{},$cities:null,$countries:null,$states:null,$states_holder:null,init:function(){var t;l("body").hasClass("wp-admin")&&!l("body").hasClass("profile-php")&&!l("body").hasClass("user-edit-php")||((t=this).bind_matching_fields(),t.bind_voucher_field(),t.bind_edit_account(),t.bind_l10n_selects())},bind_edit_account:function(){l("form.llms-person-form.edit-account").length&&l(".llms-toggle-fields").on("click",this.handle_toggle_click)},bind_l10n_selects:function(){var e=this;e.$cities=l("#llms_billing_city"),e.$countries=l(".llms-l10n-country-select select"),e.$states=l(".llms-l10n-state-select select"),e.$zips=l("#llms_billing_zip"),e.$countries.length&&LLMS.wait_for(function(){return void 0!==l.fn.llmsSelect2},function(){e.$states.length&&e.prep_state_field(),e.$countries.add(e.$states).llmsSelect2({width:"100%"}),window.llms.address_info&&(e.address_info=JSON.parse(window.llms.address_info)),e.$countries.on("change",function(){var t=l(this).val();e.update_locale_info(t)}).trigger("change")},"llmsSelect2")},bind_matching_fields:function(){l("input[data-match]").not('[type="password"]').each(function(){var n,i=l(this),s=l("#"+i.attr("data-match"));s.length&&(n=i.closest(".llms-form-field").add(s.closest(".llms-form-field")),i.on("input change",function(){var t=i.val(),e=s.val();t&&e&&t!==e?n.addClass("invalid"):n.removeClass("invalid")}))})},bind_voucher_field:function(){l("#llms-voucher-toggle").on("click",function(t){t.preventDefault(),l("#llms_voucher").toggle()})},get_field_parent:function(t){var e=t.closest(".wp-block-column");return e.length?e:t.closest(".llms-form-field")},get_label_text:function(t){t=t.clone();return t.find("*").remove(),t.text().trim()},handle_toggle_click:function(t){t.preventDefault();var t=l(this),e=l(l(this).attr("data-fields")),n=t.attr("data-is-showing")||"no",i="yes"===n?"hide":"show",s="yes"===n?"disabled":null,o="yes"===n?"data-change-text":"data-cancel-text";e.each(function(){l(this).closest(".llms-form-field")[i](),l(this).attr("disabled",s)}),t.text(t.attr(o)),t.attr("data-is-showing","yes"===n?"no":"yes")},prep_state_field:function(){var t=this.$states.closest(".llms-form-field");this.$holder=l('",{name:t.attr("name"),class:t.attr("class")+" hidden",type:"hidden"}).insertAfter(t),t.attr("disabled","disabled"),this.get_field_parent(t).hide()},enable_field:function(t){t.removeAttr("disabled"),t.next(".hidden[name="+t.attr("name")+"]").detach(),this.get_field_parent(t).show()}},LLMS.Instructors={init:function(){var t=this;l("body").hasClass("wp-admin")||l(".llms-instructors").length&&LLMS.wait_for_matchHeight(function(){t.bind()})},bind:function(){l(".llms-instructors .llms-author").matchHeight()}},LLMS.l10n=LLMS.l10n||{},LLMS.l10n.translate=function(t){return this.strings[t]||t},LLMS.l10n.replace=function(t,e){var n=this.translate(t);return l.each(e,function(t,e){-1!==t.indexOf("s")?e=e.toString():-1!==t.indexOf("d")&&(e=+e),n=n.replace(t,e)}),n},LLMS.LessonPreview={$els:null,init:function(){var t=this;this.$locked=l('a[href="#llms-lesson-locked"]'),this.$locked.length&&t.bind(),l(".llms-course-navigation").length&&LLMS.wait_for_matchHeight(function(){t.match_height()})},bind:function(){var n=this;this.$locked.on("click",function(){return!1}),this.$locked.on("mouseenter",function(){var t,e=l(this).find(".llms-tooltip");e.length||(t=(t=l(this).attr("data-tooltip-msg"))||LLMS.l10n.translate("You do not have permission to access this content"),e=n.get_tooltip(t),l(this).append(e)),setTimeout(function(){e.addClass("show")},10)}),this.$locked.on("mouseleave",function(){l(this).find(".llms-tooltip").removeClass("show")})},match_height:function(){l(".llms-course-navigation .llms-lesson-link").matchHeight()},get_tooltip:function(t){var e=l('
');return e.append('
'+t+"
"),e}},LLMS.Loops={init:function(){var t=this;l(".llms-loop").length&&LLMS.wait_for_matchHeight(function(){t.match_height()})},match_height:function(){l(".llms-loop-item .llms-loop-item-content").matchHeight(),l(".llms-achievement-loop-item .llms-achievement").matchHeight(),l(".llms-certificate-loop-item .llms-certificate").matchHeight()}},LLMS.OutlineCollapse={$outlines:null,init:function(){this.$outlines=l(".llms-widget-syllabus--collapsible"),this.$outlines.length&&this.bind()},bind:function(){var i=this;this.$outlines.each(function(){var t=l(this),e=t.find(".llms-section .section-header");e.on("click",function(t){t.preventDefault();var e=l(this).closest(".llms-section");switch(i.get_section_state(e)){case"closed":i.open_section(e);break;case"opened":i.close_section(e)}}),t.find(".llms-collapse-toggle").on("click",function(t){t.preventDefault();var n="close"===l(this).attr("data-action")?"opened":"closed";e.each(function(){var t=l(this).closest(".llms-section"),e=i.get_section_state(t);if(n!==e)return!0;switch(e){case"closed":i.close_section(t);break;case"opened":i.open_section(t)}l(this).trigger("click")})})})},close_section:function(t){t.removeClass("llms-section--opened").addClass("llms-section--closed")},open_section:function(t){t.removeClass("llms-section--closed").addClass("llms-section--opened")},get_section_state:function(t){return t.hasClass("llms-section--opened")?"opened":"closed"}},l.extend(LLMS.PasswordStrength,{$meter:l(".llms-password-strength-meter"),$pass:null,$conf:null,$form:null,init:function(){var t;l("body").hasClass("wp-admin")||this.setup_references()&&(t=this,LLMS.wait_for(function(){return"undefined"!=typeof wp&&void 0!==wp.passwordStrength},function(){t.bind(),t.$form.trigger("llms-password-strength-ready")}))},bind:function(){var t=this;this.$form.hasClass("llms-checkout")||t.$form.on("submit",t,t.submit),t.$pass.add(t.$conf).on("keyup",function(){t.check_strength()})},check_strength:function(){var t=this.$pass.closest(".llms-form-field"),e=this.$conf&&this.$conf.length?this.$conf.closest(".llms-form-field"):null,n=this.$pass.val().length,i=this.$conf&&this.$conf.length?this.$conf.val().length:0;n||i?(this.get_current_strength_status()?(t.removeClass("invalid").addClass("valid"),i&&e.removeClass("invalid").addClass("valid")):(t.removeClass("valid").addClass("invalid"),i&&e.removeClass("valid").addClass("invalid")),this.$meter.removeClass("too-short very-weak weak medium strong mismatch"),this.$meter.show().addClass(this.get_current_strength("slug")),this.$meter.html(this.get_current_strength("text"))):(t.removeClass("valid invalid"),e&&e.removeClass("valid invalid"),this.$meter.hide())},checkout:function(t,e){t.get_current_strength_status()?e(!0):e(LLMS.l10n.translate("There is an issue with your chosen password."))},get_blocklist:function(){var e=wp.passwordStrength.userInputDisallowedList().concat(this.get_setting("blocklist",[]));return this.$form.find('input[type="text"], input[type="email"], input[type="tel"], input[type="number"]').each(function(){var t=l(this).val();t&&e.push(t)}),e},get_current_strength:function(t){t=t||"int";var e,n=this.$pass.val(),i=this.$conf&&this.$conf.length?this.$conf.val():"";return n.length');return e.append(t.$element.closest(".llms-access-plan").find(".llms-access-plan-restrictions ul").clone()),e},placement:"top",style:"inverse",title:LLMS.l10n.translate("Members Only Pricing"),width:"280px"})})}},LLMS.Review={init:function(){this.bind()},bind:function(){l("#llms_review_submit_button").click(function(){""!==l("#review_title").val()&&""!==l("#review_text").val()?jQuery.ajax({type:"post",dataType:"json",url:window.llms.ajaxurl,data:{action:"LLMSSubmitReview",review_title:l("#review_title").val(),review_text:l("#review_text").val(),pageID:l("#post_ID").val()},success:function(){console.log("Review success"),l("#review_box").hide("swing"),l("#thank_you_box").show("swing")},error:function(t,e,n){console.log(t),console.log(e),console.log(n)}}):(""===l("#review_title").val()?l("#review_title_error").show("swing"):l("#review_title_error").hide("swing"),""===l("#review_text").val()?l("#review_text_error").show("swing"):l("#review_text_error").hide("swing"))}),l("#_llms_display_reviews").attr("checked")?(l(".llms-num-reviews-top").addClass("top"),l(".llms-num-reviews-bottom").show()):l(".llms-num-reviews-bottom").hide(),l("#_llms_display_reviews").change(function(){l("#_llms_display_reviews").attr("checked")?(l(".llms-num-reviews-top").addClass("top"),l(".llms-num-reviews-bottom").show()):(l(".llms-num-reviews-top").removeClass("top"),l(".llms-num-reviews-bottom").hide())})}},LLMS.Spinner={get:function(t,e){var n=t.find(".llms-spinning").first();return n.length||(n=l('
'),t.append(n)),n},start:function(t,e){var n=this;t.each(function(){n.get(l(this),e).show()})},stop:function(t){var e=this;t.each(function(){e.get(l(this)).hide()})}},t=function(){function a(){for(var t=0,e={};ts.get("events",[]).length&&(e=s.getAll(),s.clear("events"),e.events.push(t),LLMS.Ajax.call({data:{action:"persist_tracking_events","llms-tracking":JSON.stringify(e)},error:function(t,e,n){console.log(t,e,n)},success:function(t){"error"===t.code&&console.log(t.code,t.message)}})))},this.getSettings=function(){return n},this.makeEventObj=function(t){return l.extend(t,{url:window.location.href,time:Math.round((new Date).getTime()/1e3)})},l("body").hasClass("wp-admin")||(n.nonce&&s.set("nonce",n.nonce),i.addEvent("page.load"),window.addEventListener("beforeunload",t),window.addEventListener("unload",e),document.addEventListener("visibilitychange",o))},llms.tracking=new LLMS.Tracking(llms.tracking),LLMS.Rest={init:function(){this.bind()},bind:function(){},is_path:function(t){for(var e=!1,n=window.location.href,i=0;i' );\n\t\t\t\t$( 'body' ).append( $modal );\n\t\t\t}\n\t\n\t\t\t$modal.iziModal( {\n\t\t\t\theaderColor: '#3a3a3a',\n\t\t\t\tgroup: 'achievements',\n\t\t\t\thistory: true,\n\t\t\t\tloop: true,\n\t\t\t\toverlayColor: 'rgba( 0, 0, 0, 0.6 )',\n\t\t\t\ttransitionIn: 'fadeInDown',\n\t\t\t\ttransitionOut: 'fadeOutDown',\n\t\t\t\twidth: 340,\n\t\t\t\tonOpening: function( modal ) {\n\t\n\t\t\t\t\tmodal.setTitle( $el.find( '.llms-achievement-title' ).html() );\n\t\t\t\t\tmodal.setSubtitle( $el.find( '.llms-achievement-date' ).html() );\n\t\t\t\t\tmodal.setContent( '
' + $el.html() + '
' );\n\t\n\t\t\t\t},\n\t\n\t\t\t\tonClosing: function() {\n\t\t\t\t\twindow.history.pushState( '', document.title, window.location.pathname + window.location.search );\n\t\t\t\t},\n\t\n\t\t\t} );\n\t\n\t\t},\n\t\n\t\t/**\n\t\t * On page load, opens a modal if the URL contains an achievement in the location hash\n\t\t *\n\t\t * @since 3.14.0\n\t\t *\n\t\t * @return void\n\t\t */\n\t\tmaybe_open: function() {\n\t\n\t\t\tvar hash = window.location.hash;\n\t\t\tif ( hash && -1 !== hash.indexOf( 'achievement-' ) ) {\n\t\t\t\t$( 'a[href=\"' + hash + '\"]' ).first().trigger( 'click' );\n\t\t\t}\n\t\n\t\t}\n\t\n\t};\n\t\n\t\t/**\n\t * Main Ajax class\n\t * Handles Primary Ajax connection\n\t *\n\t * @package LifterLMS/Scripts\n\t *\n\t * @since Unknown\n\t * @version Unknown\n\t */\n\t\n\tLLMS.Ajax = {\n\t\n\t\t/**\n\t\t * Url\n\t\t *\n\t\t * @type {String}\n\t\t */\n\t\turl: window.ajaxurl || window.llms.ajaxurl,\n\t\n\t\t/**\n\t\t * Type\n\t\t *\n\t\t * @type {[type]}\n\t\t */\n\t\ttype: 'post',\n\t\n\t\t/**\n\t\t * Data\n\t\t *\n\t\t * @type {[type]}\n\t\t */\n\t\tdata: [],\n\t\n\t\t/**\n\t\t * Cache\n\t\t *\n\t\t * @type {[type]}\n\t\t */\n\t\tcache: false,\n\t\n\t\t/**\n\t\t * DataType\n\t\t * defaulted to json\n\t\t *\n\t\t * @type {String}\n\t\t */\n\t\tdataType: 'json',\n\t\n\t\t/**\n\t\t * Async\n\t\t * default to false\n\t\t *\n\t\t * @type {Boolean}\n\t\t */\n\t\tasync: true,\n\t\n\t\tresponse:[],\n\t\n\t\t/**\n\t\t * Initialize Ajax methods\n\t\t *\n\t\t * @since Unknown\n\t\t * @since 4.4.0 Update ajax nonce source.\n\t\t *\n\t\t * @param {Object} obj Options object.\n\t\t * @return {Object}\n\t\t */\n\t\tinit: function( obj ) {\n\t\n\t\t\t// If obj is not of type object or null return false.\n\t\t\tif ( obj === null || typeof obj !== 'object' ) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\n\t\t\t// set object defaults if values are not supplied\n\t\t\tobj.url = 'url' in obj ? obj.url : this.url;\n\t\t\tobj.type = 'type' \t\tin obj ? obj.type : this.type;\n\t\t\tobj.data = 'data' \t\tin obj ? obj.data : this.data;\n\t\t\tobj.cache = 'cache' \t\tin obj ? obj.cache : this.cache;\n\t\t\tobj.dataType = 'dataType'\tin obj ? obj.dataType : this.dataType;\n\t\t\tobj.async = 'async'\t\tin obj ? obj.async : this.async;\n\t\n\t\t\t// Add nonce to data object.\n\t\t\tobj.data._ajax_nonce = window.llms.ajax_nonce || wp_ajax_data.nonce;\n\t\n\t\t\t// Add post id to data object.\n\t\t\tvar $R = LLMS.Rest,\n\t\t\tquery_vars = $R.get_query_vars();\n\t\t\tobj.data.post_id = 'post' in query_vars ? query_vars.post : null;\n\t\t\tif ( ! obj.data.post_id && $( 'input#post_ID' ).length ) {\n\t\t\t\tobj.data.post_id = $( 'input#post_ID' ).val();\n\t\t\t}\n\t\n\t\t\treturn obj;\n\t\t},\n\t\n\t\t/**\n\t\t * Call\n\t\t * Called by external classes\n\t\t * Sets up jQuery Ajax object\n\t\t *\n\t\t * @param {[object]} [object of ajax settings]\n\t\t * @return {[mixed]} [false if not object or this]\n\t\t */\n\t\tcall: function(obj) {\n\t\n\t\t\t// get default variables if not included in call\n\t\t\tvar settings = this.init( obj );\n\t\n\t\t\t// if init return a response of false\n\t\t\tif ( ! settings) {\n\t\t\t\treturn false;\n\t\t\t} else {\n\t\t\t\tthis.request( settings );\n\t\t\t}\n\t\n\t\t\treturn this;\n\t\n\t\t},\n\t\n\t\t/**\n\t\t * Calls jQuery Ajax on settings object\n\t\t *\n\t\t * @return {[object]} [this]\n\t\t */\n\t\trequest: function(settings) {\n\t\n\t\t\t$.ajax( settings );\n\t\n\t\t\treturn this;\n\t\n\t\t}\n\t\n\t};\n\t\n\t\t/**\n\t * Create a Donut Chart\n\t *\n\t * @package LifterLMS/Scripts\n\t *\n\t * @since 3.9.0\n\t * @version 4.15.0\n\t *\n\t * @link https://gist.github.com/joeyinbox/8205962\n\t *\n\t * @param {Object} $el jQuery element to draw a chart within.\n\t */\n\t\n\tLLMS.Donut = function( $el ) {\n\t\n\t\t/**\n\t\t * Constructor\n\t\t *\n\t\t * @since 3.9.0\n\t\t * @since 4.15.0 Flip animation in RTL.\n\t\t *\n\t\t * @param {Object} options Donut options.\n\t\t * @return {Void}\n\t\t */\n\t\tfunction Donut(options) {\n\t\n\t\t\tthis.settings = $.extend( {\n\t\t\t\telement: options.element,\n\t\t\t\tpercent: 100\n\t\t\t}, options );\n\t\n\t\t\tthis.circle = this.settings.element.find( 'path' );\n\t\t\tthis.settings.stroke_width = parseInt( this.circle.css( 'stroke-width' ) );\n\t\t\tthis.radius = ( parseInt( this.settings.element.css( 'width' ) ) - this.settings.stroke_width ) / 2;\n\t\t\tthis.angle = $( 'body' ).hasClass( 'rtl' ) ? 82.5 : 97.5; // Origin of the draw at the top of the circle\n\t\t\tthis.i = Math.round( 0.75 * this.settings.percent );\n\t\t\tthis.first = true;\n\t\t\tthis.increment = $( 'body' ).hasClass( 'rtl' ) ? -5 : 5;\n\t\n\t\t\tthis.animate = function() {\n\t\t\t\tthis.timer = setInterval( this.loop.bind( this ), 10 );\n\t\t\t};\n\t\n\t\t\tthis.loop = function() {\n\t\t\t\tthis.angle += this.increment;\n\t\t\t\tthis.angle %= 360;\n\t\t\t\tvar radians = ( this.angle / 180 ) * Math.PI,\n\t\t\t\t\tx = this.radius + this.settings.stroke_width / 2 + Math.cos( radians ) * this.radius,\n\t\t\t\t\ty = this.radius + this.settings.stroke_width / 2 + Math.sin( radians ) * this.radius,\n\t\t\t\t\td;\n\t\t\t\tif (this.first === true) {\n\t\t\t\t\td = this.circle.attr( 'd' ) + ' M ' + x + ' ' + y;\n\t\t\t\t\tthis.first = false;\n\t\t\t\t} else {\n\t\t\t\t\td = this.circle.attr( 'd' ) + ' L ' + x + ' ' + y;\n\t\t\t\t}\n\t\t\t\tthis.circle.attr( 'd', d );\n\t\t\t\tthis.i--;\n\t\n\t\t\t\tif (this.i <= 0) {\n\t\t\t\t\tclearInterval( this.timer );\n\t\t\t\t}\n\t\t\t};\n\t\t}\n\t\n\t\t/**\n\t\t * Draw donut element\n\t\t *\n\t\t * @since 3.9.0\n\t\t *\n\t\t * @param {Object} $el jQuery element to draw a chart within.\n\t\t * @return {Void}\n\t\t */\n\t\tfunction draw( $el ) {\n\t\t\tvar path = '';\n\t\t\t$el.append( '' + path + '' );\n\t\t\tvar donut = new Donut( {\n\t\t\t\telement: $el,\n\t\t\t\tpercent: $el.attr( 'data-perc' )\n\t\t\t} );\n\t\t\tdonut.animate();\n\t\t}\n\t\n\t\tdraw( $el );\n\t\n\t};\n\t\n\t\t/**\n\t * Forms\n\t *\n\t * @package LifterLMS/Scripts\n\t *\n\t * @since 5.0.0\n\t * @version 5.3.3\n\t */\n\t\n\tLLMS.Forms = {\n\t\n\t\t/**\n\t\t * Stores locale information.\n\t\t *\n\t\t * Added via PHP.\n\t\t *\n\t\t * @type {Object}\n\t\t */\n\t\taddress_info: {},\n\t\n\t\t/**\n\t\t * jQuery ref. to the city text field.\n\t\t *\n\t\t * @type {Object}\n\t\t */\n\t\t$cities: null,\n\t\n\t\t/**\n\t\t * jQuery ref. to the countries select field.\n\t\t *\n\t\t * @type {Object}\n\t\t */\n\t\t$countries: null,\n\t\n\t\t/**\n\t\t * jQuery ref. to the states select field.\n\t\t *\n\t\t * @type {Object}\n\t\t */\n\t\t$states: null,\n\t\n\t\t/**\n\t\t * jQuery ref. to the hidden states holder field.\n\t\t *\n\t\t * @type {Object}\n\t\t */\n\t\t$states_holder: null,\n\t\n\t\t/**\n\t\t * Init\n\t\t *\n\t \t * @since 5.0.0\n\t \t * @since 5.3.3 Move select2 dependency check into the `bind_l10_selects()` method.\n\t \t *\n\t \t * @return {void}\n\t\t */\n\t\tinit: function() {\n\t\n\t\t\tif ( $( 'body' ).hasClass( 'wp-admin' ) ) {\n\t\t\t\tif ( ! ( $( 'body' ).hasClass( 'profile-php' ) || $( 'body' ).hasClass( 'user-edit-php' ) ) ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\n\t\t\tvar self = this;\n\t\n\t\t\tself.bind_matching_fields();\n\t\t\tself.bind_voucher_field();\n\t\t\tself.bind_edit_account();\n\t\t\tself.bind_l10n_selects();\n\t\n\t\t},\n\t\n\t\t/**\n\t\t * Bind DOM events for the edit account screen.\n\t\t *\n\t\t * @since 5.0.0\n\t\t *\n\t\t * @return {void}\n\t\t */\n\t\tbind_edit_account: function() {\n\t\n\t\t\t// Not an edit account form.\n\t\t\tif ( ! $( 'form.llms-person-form.edit-account' ).length ) {\n\t\t\t\treturn;\n\t\t\t}\n\t\n\t\t\t$( '.llms-toggle-fields' ).on( 'click', this.handle_toggle_click );\n\t\n\t\t},\n\t\n\t\t/**\n\t\t * Bind DOM Events fields with dynamic localization values and language.\n\t\t *\n\t\t * @since 5.0.0\n\t\t * @since 5.3.3 Bind select2-related events after ensuring select2 is available.\n\t\t *\n\t\t * @return {void}\n\t\t */\n\t\tbind_l10n_selects: function() {\n\t\n\t\t\tvar self = this;\n\t\n\t\t\tself.$cities = $( '#llms_billing_city' );\n\t\t\tself.$countries = $( '.llms-l10n-country-select select' );\n\t\t\tself.$states = $( '.llms-l10n-state-select select' );\n\t\t\tself.$zips = $( '#llms_billing_zip' );\n\t\n\t\t\tif ( ! self.$countries.length ) {\n\t\t\t\treturn;\n\t\t\t}\n\t\n\t\t\tvar isSelect2Available = function() {\n\t\t\t\treturn ( undefined !== $.fn.llmsSelect2 );\n\t\t\t};\n\t\n\t\t\tLLMS.wait_for( isSelect2Available, function() {\n\t\n\t\t\t\tif ( self.$states.length ) {\n\t\t\t\t\tself.prep_state_field();\n\t\t\t\t}\n\t\n\t\t\t\tself.$countries.add( self.$states ).llmsSelect2( { width: '100%' } );\n\t\n\t\t\t\tif ( window.llms.address_info ) {\n\t\t\t\t\tself.address_info = JSON.parse( window.llms.address_info );\n\t\t\t\t}\n\t\n\t\t\t\tself.$countries.on( 'change', function() {\n\t\n\t\t\t\t\tvar val = $( this ).val();\n\t\t\t\t\tself.update_locale_info( val );\n\t\n\t\t\t\t} ).trigger( 'change' );\n\t\n\t\t\t}, 'llmsSelect2' );\n\t\n\t\t},\n\t\n\t\t/**\n\t\t * Ensure \"matching\" fields match.\n\t\t *\n\t\t * @since 5.0.0\n\t\t *\n\t\t * @return {Void}\n\t\t */\n\t\tbind_matching_fields: function() {\n\t\n\t\t\tvar $fields = $( 'input[data-match]' ).not( '[type=\"password\"]' );\n\t\n\t\t\t$fields.each( function() {\n\t\n\t\t\t\tvar $field = $( this ),\n\t\t\t\t\t$match = $( '#' + $field.attr( 'data-match' ) ),\n\t\t\t\t\t$parents;\n\t\n\t\t\t\tif ( $match.length ) {\n\t\n\t\t\t\t\t$parents = $field.closest( '.llms-form-field' ).add( $match.closest( '.llms-form-field' ) );\n\t\n\t\t\t\t\t$field.on( 'input change', function() {\n\t\n\t\t\t\t\t\tvar val_1 = $field.val(),\n\t\t\t\t\t\t\tval_2 = $match.val();\n\t\n\t\t\t\t\t\tif ( val_1 && val_2 && val_1 !== val_2 ) {\n\t\t\t\t\t\t\t$parents.addClass( 'invalid' );\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t$parents.removeClass( 'invalid' );\n\t\t\t\t\t\t}\n\t\n\t\t\t\t\t} );\n\t\n\t\t\t\t}\n\t\n\t\t\t} );\n\t\n\t\t},\n\t\n\t\t/**\n\t\t * Bind DOM events for voucher toggles UX.\n\t\t *\n\t\t * @since 5.0.0\n\t\t *\n\t\t * @return {void}\n\t\t */\n\t\tbind_voucher_field: function() {\n\t\n\t\t\t$( '#llms-voucher-toggle' ).on( 'click', function( e ) {\n\t\t\t\te.preventDefault();\n\t\t\t\t$( '#llms_voucher' ).toggle();\n\t\t\t} );\n\t\n\t\t},\n\t\n\t\t/**\n\t\t * Retrieve the parent element for a given field.\n\t\t *\n\t\t * The parent element is hidden when the field isn't required.\n\t\t * Looks for a WP column wrapper and falls back to the field's\n\t\t * wrapper div.\n\t\t *\n\t\t * @since 5.0.0\n\t\t *\n\t\t * @param {Object} $field jQuery dom object.\n\t\t * @return {Object}\n\t\t */\n\t\tget_field_parent: function( $field ) {\n\t\n\t\t\tvar $block = $field.closest( '.wp-block-column' );\n\t\t\tif ( $block.length ) {\n\t\t\t\treturn $block;\n\t\t\t}\n\t\n\t\t\treturn $field.closest( '.llms-form-field' );\n\t\n\t\t},\n\t\n\t\t/**\n\t\t * Retrieve the text of a label\n\t\t *\n\t\t * Removes any children HTML elements (eg: required span elements) and returns only the labels text.\n\t\t *\n\t\t * @since 5.0.0\n\t\t *\n\t\t * @param {Object} $label jQuery object for a label element.\n\t\t * @return {String}\n\t\t */\n\t\tget_label_text: function( $label ) {\n\t\n\t\t\tvar $clone = $label.clone();\n\t\t\t$clone.find( '*' ).remove();\n\t\t\treturn $clone.text().trim();\n\t\n\t\t},\n\t\n\t\t/**\n\t\t * Callback function to handle the \"toggle\" button links for changing email address and password on account edit forms\n\t\t *\n\t\t * @since 5.0.0\n\t\t *\n\t\t * @param {Object} event Native JS event object.\n\t\t * @return {void}\n\t\t */\n\t\thandle_toggle_click: function( event ) {\n\t\n\t\t\tevent.preventDefault();\n\t\n\t\t\tvar $this = $( this ),\n\t\t\t\t$fields = $( $( this ).attr( 'data-fields' ) ),\n\t\t\t\tisShowing = $this.attr( 'data-is-showing' ) || 'no',\n\t\t\t\tdisplayFunc = 'yes' === isShowing ? 'hide' : 'show',\n\t\t\t\tdisabled = 'yes' === isShowing ? 'disabled' : null,\n\t\t\t\ttextAttr = 'yes' === isShowing ? 'data-change-text' : 'data-cancel-text';\n\t\n\t\t\t$fields.each( function() {\n\t\n\t\t\t\t$( this ).closest( '.llms-form-field' )[ displayFunc ]();\n\t\t\t\t$( this ).attr( 'disabled', disabled );\n\t\n\t\t\t} );\n\t\n\t\t\t$this.text( $this.attr( textAttr ) );\n\t\t\t$this.attr( 'data-is-showing', 'yes' === isShowing ? 'no' : 'yes' );\n\t\n\t\t},\n\t\n\t\t/**\n\t\t * Prepares the state select field.\n\t\t *\n\t\t * Moves All optgroup elements into a hidden & disabled select element.\n\t\t *\n\t\t * @since 5.0.0\n\t\t *\n\t\t * @return {void}\n\t\t */\n\t\tprep_state_field: function() {\n\t\n\t\t\tvar $parent = this.$states.closest( '.llms-form-field' );\n\t\n\t\t\tthis.$holder = $( '',\n\t\t\t\t{ name: $field.attr('name'), class: $field.attr( 'class' ) + ' hidden', type: 'hidden' }\n\t\t\t).insertAfter( $field );\n\t\t\t$field.attr( 'disabled', 'disabled' );\n\t\t\tthis.get_field_parent( $field ).hide();\n\t\t},\n\t\n\t\t/**\n\t\t * Enable a given field\n\t\t *\n\t\t * It also shows the parent element, and removes the empty hidden input field\n\t\t * previously added by disable_field().\n\t\t *\n\t\t * @since 5.0.0\n\t\t *\n\t\t * @param {Object} $field The jQuery object for the field.\n\t\t */\n\t\tenable_field: function( $field ) {\n\t\t\t$field.removeAttr( 'disabled' );\n\t\t\t$field.next( '.hidden[name='+$field.attr('name')+']' ).detach();\n\t\t\tthis.get_field_parent( $field ).show();\n\t\t}\n\t\n\t};\n\t\n\t\t/**\n\t * Instructors List\n\t *\n\t * @package LifterLMS/Scripts\n\t *\n\t * @since Unknown\n\t * @version Unknown\n\t */\n\t\n\tLLMS.Instructors = {\n\t\n\t\t/**\n\t\t * Init\n\t\t */\n\t\tinit: function() {\n\t\n\t\t\tvar self = this;\n\t\n\t\t\tif ( $( 'body' ).hasClass( 'wp-admin' ) ) {\n\t\t\t\treturn;\n\t\t\t}\n\t\n\t\t\tif ( $( '.llms-instructors' ).length ) {\n\t\n\t\t\t\tLLMS.wait_for_matchHeight( function() {\n\t\t\t\t\tself.bind();\n\t\t\t\t} );\n\t\n\t\t\t}\n\t\n\t\t},\n\t\n\t\t/**\n\t\t * Bind Method\n\t\t * Handles dom binding on load\n\t\t *\n\t\t * @return {[type]} [description]\n\t\t */\n\t\tbind: function() {\n\t\n\t\t\t$( '.llms-instructors .llms-author' ).matchHeight();\n\t\n\t\t},\n\t\n\t};\n\t\n\t\t/**\n\t * Localization functions for LifterLMS Javascript\n\t *\n\t * @package LifterLMS/Scripts\n\t *\n\t * @since 2.7.3\n\t * @version 2.7.3\n\t *\n\t * @todo we need more robust translation functions to handle sprintf and pluralization\n\t * at this moment we don't need those and haven't stubbed them out\n\t * those will be added when they're needed\n\t */\n\t\n\tLLMS.l10n = LLMS.l10n || {};\n\t\n\tLLMS.l10n.translate = function ( string ) {\n\t\n\t\tvar self = this;\n\t\n\t\tif ( self.strings[string] ) {\n\t\n\t\t\treturn self.strings[string];\n\t\n\t\t} else {\n\t\n\t\t\treturn string;\n\t\n\t\t}\n\t\n\t};\n\t\n\t/**\n\t * Translate and replace placeholders in a string\n\t *\n\t * @example LLMS.l10n.replace( 'This is a %2$s %1$s String', {\n\t * \t'%1$s': 'cool',\n\t * \t\t\t'%2$s': 'very'\n\t * \t\t} );\n\t * \t\tOutput: \"This is a very cool String\"\n\t *\n\t * @param string string text string\n\t * @param object replacements object containing token => replacement pairs\n\t * @return string\n\t * @since 3.16.0\n\t * @version 3.16.0\n\t */\n\tLLMS.l10n.replace = function( string, replacements ) {\n\t\n\t\tvar str = this.translate( string );\n\t\n\t\t$.each( replacements, function( token, value ) {\n\t\n\t\t\tif ( -1 !== token.indexOf( 's' ) ) {\n\t\t\t\tvalue = value.toString();\n\t\t\t} else if ( -1 !== token.indexOf( 'd' ) ) {\n\t\t\t\tvalue = value * 1;\n\t\t\t}\n\t\n\t\t\tstr = str.replace( token, value );\n\t\n\t\t} );\n\t\n\t\treturn str;\n\t\n\t};\n\t\n\t\t/**\n\t * Handle Lesson Preview Elements\n\t *\n\t * @package LifterLMS/Scripts\n\t *\n\t * @since 3.0.0\n\t * @version 3.16.12\n\t */\n\t\n\tLLMS.LessonPreview = {\n\t\n\t\t/**\n\t\t * A jQuery object of all outlines present on the current screen\n\t\t *\n\t\t * @type obj\n\t\t */\n\t\t$els: null,\n\t\n\t\t/**\n\t\t * Initialize\n\t\t *\n\t\t * @return void\n\t\t */\n\t\tinit: function() {\n\t\n\t\t\tvar self = this;\n\t\n\t\t\tthis.$locked = $( 'a[href=\"#llms-lesson-locked\"]' );\n\t\n\t\t\tif ( this.$locked.length ) {\n\t\n\t\t\t\tself.bind();\n\t\n\t\t\t}\n\t\n\t\t\tif ( $( '.llms-course-navigation' ).length ) {\n\t\n\t\t\t\tLLMS.wait_for_matchHeight( function() {\n\t\n\t\t\t\t\tself.match_height();\n\t\n\t\t\t\t} );\n\t\n\t\t\t}\n\t\n\t\t},\n\t\n\t\t/**\n\t\t * Bind DOM events\n\t\t *\n\t\t * @return void\n\t\t * @since 3.0.0\n\t\t * @version 3.16.12\n\t\t */\n\t\tbind: function() {\n\t\n\t\t\tvar self = this;\n\t\n\t\t\tthis.$locked.on( 'click', function() {\n\t\t\t\treturn false;\n\t\t\t} );\n\t\n\t\t\tthis.$locked.on( 'mouseenter', function() {\n\t\n\t\t\t\tvar $tip = $( this ).find( '.llms-tooltip' );\n\t\t\t\tif ( ! $tip.length ) {\n\t\t\t\t\tvar msg = $( this ).attr( 'data-tooltip-msg' );\n\t\t\t\t\tif ( ! msg ) {\n\t\t\t\t\t\tmsg = LLMS.l10n.translate( 'You do not have permission to access this content' );\n\t\t\t\t\t}\n\t\t\t\t\t$tip = self.get_tooltip( msg );\n\t\t\t\t\t$( this ).append( $tip );\n\t\t\t\t}\n\t\t\t\tsetTimeout( function() {\n\t\t\t\t\t$tip.addClass( 'show' );\n\t\t\t\t}, 10 );\n\t\n\t\t\t} );\n\t\n\t\t\tthis.$locked.on( 'mouseleave', function() {\n\t\n\t\t\t\tvar $tip = $( this ).find( '.llms-tooltip' );\n\t\t\t\t$tip.removeClass( 'show' );\n\t\n\t\t\t} );\n\t\n\t\t},\n\t\n\t\t/**\n\t\t * Match the height of lesson preview items in course navigation blocks\n\t\t *\n\t\t * @return void\n\t\t * @since 3.0.0\n\t\t * @version 3.0.0\n\t\t */\n\t\tmatch_height: function() {\n\t\n\t\t\t$( '.llms-course-navigation .llms-lesson-link' ).matchHeight();\n\t\n\t\t},\n\t\n\t\t/**\n\t\t * Get a tooltip element\n\t\t *\n\t\t * @param string msg message to display inside the tooltip\n\t\t * @return obj\n\t\t * @since 3.0.0\n\t\t * @version 3.2.4\n\t\t */\n\t\tget_tooltip: function( msg ) {\n\t\t\tvar $el = $( '
' );\n\t\t\t$el.append( '
' + msg + '
' );\n\t\t\treturn $el;\n\t\t},\n\t\n\t};\n\t\n\t\t/**\n\t * LifterLMS Loops JS\n\t *\n\t * @package LifterLMS/Scripts\n\t *\n\t * @since 3.0.0\n\t * @version 3.14.0\n\t */\n\t\n\tLLMS.Loops = {\n\t\n\t\t/**\n\t\t * Initialize\n\t\t *\n\t\t * @return void\n\t\t */\n\t\tinit: function() {\n\t\n\t\t\tvar self = this;\n\t\n\t\t\tif ( $( '.llms-loop' ).length ) {\n\t\n\t\t\t\tLLMS.wait_for_matchHeight( function() {\n\t\n\t\t\t\t\tself.match_height();\n\t\n\t\t\t\t} );\n\t\n\t\t\t}\n\t\n\t\t},\n\t\n\t\t/**\n\t\t * Match the height of .llms-loop-item\n\t\t *\n\t\t * @return void\n\t\t * @since 3.0.0\n\t\t * @version 3.14.0\n\t\t */\n\t\tmatch_height: function() {\n\t\n\t\t\t$( '.llms-loop-item .llms-loop-item-content' ).matchHeight();\n\t\t\t$( '.llms-achievement-loop-item .llms-achievement' ).matchHeight();\n\t\t\t$( '.llms-certificate-loop-item .llms-certificate' ).matchHeight();\n\t\n\t\t},\n\t\n\t};\n\t\n\t\t/**\n\t * Handle the Collapsible Syllabus Widget / Shortcode\n\t *\n\t * @package LifterLMS/Scripts\n\t *\n\t * @since Unknown\n\t * @version Unknown\n\t */\n\t\n\tLLMS.OutlineCollapse = {\n\t\n\t\t/**\n\t\t * A jQuery object of all outlines present on the current screen\n\t\t *\n\t\t * @type obj\n\t\t */\n\t\t$outlines: null,\n\t\n\t\t/**\n\t\t * Initialize\n\t\t *\n\t\t * @return void\n\t\t */\n\t\tinit: function() {\n\t\n\t\t\tthis.$outlines = $( '.llms-widget-syllabus--collapsible' );\n\t\n\t\t\tif ( this.$outlines.length ) {\n\t\n\t\t\t\tthis.bind();\n\t\n\t\t\t}\n\t\n\t\t},\n\t\n\t\t/**\n\t\t * Bind DOM events\n\t\t *\n\t\t * @return void\n\t\t */\n\t\tbind: function() {\n\t\n\t\t\tvar self = this;\n\t\n\t\t\tthis.$outlines.each( function() {\n\t\n\t\t\t\tvar $outline = $( this ),\n\t\t\t\t\t$headers = $outline.find( '.llms-section .section-header' );\n\t\n\t\t\t\t// bind header clicks\n\t\t\t\t$headers.on( 'click', function( e ) {\n\t\n\t\t\t\t\te.preventDefault();\n\t\n\t\t\t\t\tvar $toggle = $( this ),\n\t\t\t\t\t\t$section = $toggle.closest( '.llms-section' ),\n\t\t\t\t\t\tstate = self.get_section_state( $section );\n\t\n\t\t\t\t\tswitch ( state ) {\n\t\n\t\t\t\t\t\tcase 'closed':\n\t\t\t\t\t\t\tself.open_section( $section );\n\t\t\t\t\t\tbreak;\n\t\n\t\t\t\t\t\tcase 'opened':\n\t\t\t\t\t\t\tself.close_section( $section );\n\t\t\t\t\t\tbreak;\n\t\n\t\t\t\t\t}\n\t\n\t\t\t\t} );\n\t\n\t\t\t\t// bind optional toggle \"buttons\"\n\t\t\t\t$outline.find( '.llms-collapse-toggle' ).on( 'click', function( e ) {\n\t\n\t\t\t\t\te.preventDefault();\n\t\n\t\t\t\t\tvar $btn = $( this ),\n\t\t\t\t\t\taction = $btn.attr( 'data-action' ),\n\t\t\t\t\t\topposite_action = ( 'close' === action ) ? 'opened' : 'closed';\n\t\n\t\t\t\t\t$headers.each( function() {\n\t\n\t\t\t\t\t\tvar $section = $( this ).closest( '.llms-section' ),\n\t\t\t\t\t\t\tstate = self.get_section_state( $section );\n\t\n\t\t\t\t\t\tif ( opposite_action !== state ) {\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t}\n\t\n\t\t\t\t\t\tswitch ( state ) {\n\t\n\t\t\t\t\t\t\tcase 'closed':\n\t\t\t\t\t\t\t\tself.close_section( $section );\n\t\t\t\t\t\t\tbreak;\n\t\n\t\t\t\t\t\t\tcase 'opened':\n\t\t\t\t\t\t\t\tself.open_section( $section );\n\t\t\t\t\t\t\tbreak;\n\t\n\t\t\t\t\t\t}\n\t\n\t\t\t\t\t\t$( this ).trigger( 'click' );\n\t\n\t\t\t\t\t} );\n\t\n\t\t\t\t} );\n\t\n\t\t\t} );\n\t\n\t\t},\n\t\n\t\t/**\n\t\t * Close an outline section\n\t\t *\n\t\t * @param obj $section jQuery selector of a '.llms-section'\n\t\t * @return void\n\t\t */\n\t\tclose_section: function( $section ) {\n\t\n\t\t\t$section.removeClass( 'llms-section--opened' ).addClass( 'llms-section--closed' );\n\t\n\t\t},\n\t\n\t\t/**\n\t\t * Open an outline section\n\t\t *\n\t\t * @param obj $section jQuery selector of a '.llms-section'\n\t\t * @return void\n\t\t */\n\t\topen_section: function( $section ) {\n\t\n\t\t\t$section.removeClass( 'llms-section--closed' ).addClass( 'llms-section--opened' );\n\t\n\t\t},\n\t\n\t\t/**\n\t\t * Get the current state (open or closed) of an outline section\n\t\t *\n\t\t * @param obj $section jQuery selector of a '.llms-section'\n\t\t * @return string 'opened' or 'closed'\n\t\t */\n\t\tget_section_state: function( $section ) {\n\t\n\t\t\treturn $section.hasClass( 'llms-section--opened' ) ? 'opened' : 'closed';\n\t\n\t\t}\n\t\n\t};\n\t\n\t\t/**\n\t * Handle Password Strength Meter for registration and password update fields\n\t *\n\t * @package LifterLMS/Scripts\n\t *\n\t * @since 3.0.0\n\t * @version 5.0.0\n\t */\n\t\n\t$.extend( LLMS.PasswordStrength, {\n\t\n\t\t/**\n\t\t * jQuery ref for the password strength meter object.\n\t\t *\n\t\t * @type {Object}\n\t\t */\n\t\t$meter: $( '.llms-password-strength-meter' ),\n\t\n\t\t/**\n\t\t * jQuery ref for the password field.\n\t\t *\n\t\t * @type {Object}\n\t\t */\n\t\t$pass: null,\n\t\n\t\t/**\n\t\t * jQuery ref for the password confirmation field\n\t\t *\n\t\t * @type {Object}\n\t\t */\n\t\t$conf: null,\n\t\n\t\t/**\n\t\t * jQuery ref for form element.\n\t\t *\n\t\t * @type {Object}\n\t\t */\n\t\t$form: null,\n\t\n\t\t/**\n\t\t * Init\n\t\t * loads class methods\n\t\t *\n\t\t * @since 3.0.0\n\t\t * @since 3.7.0 Unknown\n\t\t * @since 5.0.0 Move reference setup to `setup_references()`.\n\t\t * Use `LLMS.wait_for()` for dependency waiting.\n\t\t *\n\t\t * @return {Void}\n\t\t */\n\t\tinit: function() {\n\t\n\t\t\tif ( $( 'body' ).hasClass( 'wp-admin' ) ) {\n\t\t\t\treturn;\n\t\t\t}\n\t\n\t\t\tif ( ! this.setup_references() ) {\n\t\t\t\treturn;\n\t\t\t}\n\t\n\t\t\tvar self = this;\n\t\n\t\t\tLLMS.wait_for( function() {\n\t\t\t\treturn ( 'undefined' !== typeof wp && 'undefined' !== typeof wp.passwordStrength );\n\t\t\t}, function() {\n\t\t\t\tself.bind();\n\t\t\t\tself.$form.trigger( 'llms-password-strength-ready' );\n\t\t\t} );\n\t\n\t\t},\n\t\n\t\t/**\n\t\t * Bind DOM Events\n\t\t *\n\t\t * @since 3.0.0\n\t\t *\n\t\t * @return void\n\t\t */\n\t\tbind: function() {\n\t\n\t\t\tvar self = this;\n\t\n\t\t\t// add submission event handlers when not on a checkout form\n\t\t\tif ( ! this.$form.hasClass( 'llms-checkout' ) ) {\n\t\t\t\tself.$form.on( 'submit', self, self.submit );\n\t\t\t}\n\t\n\t\t\t// check password strength on keyup\n\t\t\tself.$pass.add( self.$conf ).on( 'keyup', function() {\n\t\t\t\tself.check_strength();\n\t\t\t} );\n\t\n\t\t},\n\t\n\t\t/**\n\t\t * Check the strength of a user entered password\n\t\t * and update elements depending on the current strength\n\t\t *\n\t\t * @since 3.0.0\n\t\t * @since 5.0.0 Allow password confirmation to be optional when checking strength.\n\t\t *\n\t\t * @return void\n\t\t */\n\t\tcheck_strength: function() {\n\t\n\t\t\tvar $pass_field = this.$pass.closest( '.llms-form-field' ),\n\t\t\t\t$conf_field = this.$conf && this.$conf.length ? this.$conf.closest( '.llms-form-field' ) : null,\n\t\t\t\tpass_length = this.$pass.val().length,\n\t\t\t\tconf_length = this.$conf && this.$conf.length ? this.$conf.val().length : 0;\n\t\n\t\t\t// hide the meter if both fields are empty\n\t\t\tif ( ! pass_length && ! conf_length ) {\n\t\t\t\t$pass_field.removeClass( 'valid invalid' );\n\t\t\t\tif ( $conf_field ) {\n\t\t\t\t\t$conf_field.removeClass( 'valid invalid' );\n\t\t\t\t}\n\t\t\t\tthis.$meter.hide();\n\t\t\t\treturn;\n\t\t\t}\n\t\n\t\t\tif ( this.get_current_strength_status() ) {\n\t\t\t\t$pass_field.removeClass( 'invalid' ).addClass( 'valid' );\n\t\t\t\tif ( conf_length ) {\n\t\t\t\t\t$conf_field.removeClass( 'invalid' ).addClass( 'valid' );\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t$pass_field.removeClass( 'valid' ).addClass( 'invalid' );\n\t\t\t\tif ( conf_length ) {\n\t\t\t\t\t$conf_field.removeClass( 'valid' ).addClass( 'invalid' );\n\t\t\t\t}\n\t\t\t}\n\t\n\t\t\tthis.$meter.removeClass( 'too-short very-weak weak medium strong mismatch' );\n\t\t\tthis.$meter.show().addClass( this.get_current_strength( 'slug' ) );\n\t\t\tthis.$meter.html( this.get_current_strength( 'text' ) );\n\t\n\t\t},\n\t\n\t\t/**\n\t\t * Form submission action called during registration on checkout screen\n\t\t *\n\t\t * @since 3.0.0\n\t\t *\n\t\t * @param obj self instance of this class\n\t\t * @param Function callback callback function, passes error message or success back to checkout handler\n\t\t * @return void\n\t\t */\n\t\tcheckout: function( self, callback ) {\n\t\n\t\t\tif ( self.get_current_strength_status() ) {\n\t\n\t\t\t\tcallback( true );\n\t\n\t\t\t} else {\n\t\n\t\t\t\tcallback( LLMS.l10n.translate( 'There is an issue with your chosen password.' ) );\n\t\n\t\t\t}\n\t\t},\n\t\n\t\t/**\n\t\t * Get the list of blocklisted strings\n\t\t *\n\t\t * @since 5.0.0\n\t\t *\n\t\t * @return array\n\t\t */\n\t\tget_blocklist: function() {\n\t\n\t\t\t// Default values from WP Core + any values added via settings filter..\n\t\t\tvar blocklist = wp.passwordStrength.userInputDisallowedList().concat( this.get_setting( 'blocklist', [] ) );\n\t\n\t\t\t// Add values from all text fields in the form.\n\t\t\tthis.$form.find( 'input[type=\"text\"], input[type=\"email\"], input[type=\"tel\"], input[type=\"number\"]' ).each( function() {\n\t\t\t\tvar val = $( this ).val();\n\t\t\t\tif ( val ) {\n\t\t\t\t\tblocklist.push( val );\n\t\t\t\t}\n\t\t\t} );\n\t\n\t\t\treturn blocklist;\n\t\n\t\t},\n\t\n\t\t/**\n\t\t * Retrieve current strength as a number, a slug, or a translated text string\n\t\t *\n\t\t * @since 3.0.0\n\t\t * @since 5.0.0 Allow password confirmation to be optional when checking strength.\n\t\t *\n\t\t * @param {String} format Derived return format [int|slug|text] defaults to int.\n\t\t * @return mixed\n\t\t */\n\t\tget_current_strength: function( format ) {\n\t\n\t\t\tformat = format || 'int';\n\t\t\tvar pass = this.$pass.val(),\n\t\t\t\tconf = this.$conf && this.$conf.length ? this.$conf.val() : '',\n\t\t\t\tval;\n\t\n\t\t\t// enforce custom length requirement\n\t\t\tif ( pass.length < this.get_setting( 'min_length', 6 ) ) {\n\t\t\t\tval = -1;\n\t\t\t} else {\n\t\t\t\tval = wp.passwordStrength.meter( pass, this.get_blocklist(), conf );\n\t\t\t\t// 0 & 1 are both very-weak\n\t\t\t\tif ( 0 === val ) {\n\t\t\t\t\tval = 1;\n\t\t\t\t}\n\t\t\t}\n\t\n\t\t\tif ( 'slug' === format ) {\n\t\t\t\treturn this.get_strength_slug( val );\n\t\t\t} else if ( 'text' === format ) {\n\t\t\t\treturn this.get_strength_text( val );\n\t\t\t} else {\n\t\t\t\treturn val;\n\t\t\t}\n\t\t},\n\t\n\t\t/**\n\t\t * Determines if the current password strength meets the user-defined\n\t\t * minimum password strength requirements\n\t\t *\n\t\t * @since 3.0.0\n\t\t *\n\t\t * @return boolean\n\t\t */\n\t\tget_current_strength_status: function() {\n\t\t\tvar curr = this.get_current_strength(),\n\t\t\t\tmin = this.get_strength_value( this.get_minimum_strength() );\n\t\t\treturn ( 5 === curr ) ? false : ( curr >= min );\n\t\t},\n\t\n\t\t/**\n\t\t * Retrieve the minimum password strength for the current form.\n\t\t *\n\t\t * @since 3.0.0\n\t\t * @since 5.0.0 Replaces the version output via an inline PHP script in favor of utilizing values configured in the settings object.\n\t\t *\n\t\t * @return {string}\n\t\t */\n\t\tget_minimum_strength: function() {\n\t\t\treturn this.get_setting( 'min_strength', 'strong' );\n\t\t},\n\t\n\t\t/**\n\t\t * Get a setting and fallback to a default value.\n\t\t *\n\t\t * @since 5.0.0\n\t\t *\n\t\t * @param {String} key Setting key.\n\t\t * @param {mixed} default_val Default value when the requested setting cannot be located.\n\t\t * @return {mixed}\n\t\t */\n\t\tget_setting: function( key, default_val ) {\n\t\t\tvar settings = this.get_settings();\n\t\t\treturn settings[ key ] ? settings[ key ] : default_val;\n\t\t},\n\t\n\t\t/**\n\t\t * Get the slug associated with a strength value\n\t\t *\n\t\t * @since 3.0.0\n\t\t *\n\t\t * @param int strength_val Strength value number.\n\t\t * @return string\n\t\t */\n\t\tget_strength_slug: function( strength_val ) {\n\t\n\t\t\tvar slugs = {\n\t\t\t\t'-1': 'too-short',\n\t\t\t\t1: 'very-weak',\n\t\t\t\t2: 'weak',\n\t\t\t\t3: 'medium',\n\t\t\t\t4: 'strong',\n\t\t\t\t5: 'mismatch',\n\t\t\t};\n\t\n\t\t\treturn ( slugs[ strength_val ] ) ? slugs[ strength_val ] : slugs[5];\n\t\n\t\t},\n\t\n\t\t/**\n\t\t * Gets the translated text associated with a strength value\n\t\t *\n\t\t * @since 3.0.0\n\t\t *\n\t\t * @param {Integer} strength_val Strength value\n\t\t * @return {String}\n\t\t */\n\t\tget_strength_text: function( strength_val ) {\n\t\n\t\t\tvar texts = {\n\t\t\t\t'-1': LLMS.l10n.translate( 'Too Short' ),\n\t\t\t\t1: LLMS.l10n.translate( 'Very Weak' ),\n\t\t\t\t2: LLMS.l10n.translate( 'Weak' ),\n\t\t\t\t3: LLMS.l10n.translate( 'Medium' ),\n\t\t\t\t4: LLMS.l10n.translate( 'Strong' ),\n\t\t\t\t5: LLMS.l10n.translate( 'Mismatch' ),\n\t\t\t};\n\t\n\t\t\treturn ( texts[ strength_val ] ) ? texts[ strength_val ] : texts[5];\n\t\n\t\t},\n\t\n\t\t/**\n\t\t * Get the value associated with a strength slug\n\t\t *\n\t\t * @since 3.0.0\n\t\t *\n\t\t * @param string strength_slug A strength slug.\n\t\t * @return {Integer}\n\t\t */\n\t\tget_strength_value: function( strength_slug ) {\n\t\n\t\t\tvar values = {\n\t\t\t\t'too-short': -1,\n\t\t\t\t'very-weak': 1,\n\t\t\t\tweak: 2,\n\t\t\t\tmedium: 3,\n\t\t\t\tstrong: 4,\n\t\t\t\tmismatch: 5,\n\t\t\t};\n\t\n\t\t\treturn ( values[ strength_slug ] ) ? values[ strength_slug ] : values.mismatch;\n\t\n\t\t},\n\t\n\t\t/**\n\t\t * Setup jQuery references to DOM elements needed to power the password meter.\n\t\t *\n\t\t * @since 5.0.0\n\t\t *\n\t\t * @return {Boolean} Returns `true` if a meter element and password field are found, otherwise returns `false`.\n\t\t */\n\t\tsetup_references: function() {\n\t\n\t\t\tif ( ! this.$meter.length ) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\n\t\t\tthis.$form = this.$meter.closest( 'form' );\n\t\t\tthis.$pass = this.$form.find( 'input#password' );\n\t\n\t\t\tif ( this.$pass.length && this.$pass.attr( 'data-match' ) ) {\n\t\t\t\tthis.$conf = this.$form.find( '#' + this.$pass.attr( 'data-match' ) );\n\t\t\t}\n\t\n\t\t\treturn ( this.$pass.length > 0 );\n\t\n\t\t},\n\t\n\t\t/**\n\t\t * Form submission handler for registration and update forms\n\t\t *\n\t\t * @since 3.0.0\n\t\t * @since 5.0.0 Allow the account edit for to bypass strength checking when the password field is disabled (not being submitted).\n\t\t *\n\t\t * @param obj e Event data.\n\t\t * @return void\n\t\t */\n\t\tsubmit: function( e ) {\n\t\n\t\t\tvar self = e.data;\n\t\t\te.preventDefault();\n\t\t\tself.$pass.trigger( 'keyup' );\n\t\n\t\t\t// Meets the status requirements OR we're on the account edit form and the password field is disabled.\n\t\t\tif ( self.get_current_strength_status() || ( self.$form.hasClass( 'edit-account' ) && 'disabled' === self.$pass.attr( 'disabled' ) ) ) {\n\t\t\t\tself.$form.off( 'submit', self.submit );\n\t\t\t\tself.$form.trigger( 'submit' );\n\t\t\t} else {\n\t\t\t\t$( 'html, body' ).animate( {\n\t\t\t\t\tscrollTop: self.$meter.offset().top - 100,\n\t\t\t\t}, 200 );\n\t\t\t\tself.$meter.hide();\n\t\t\t\tsetTimeout( function() {\n\t\t\t\t\tself.$meter.fadeIn( 400 );\n\t\t\t\t}, 220 );\n\t\t\t}\n\t\t},\n\t\n\t\t/**\n\t\t * Get the list of blocklist strings\n\t\t *\n\t\t * @since 3.0.0\n\t\t * @deprecated 5.0.0 `LLMS.PasswordStrength.get_blacklist()` is deprecated in favor of `LLMS.PasswordStrength.get_blocklist()`.\n\t\t *\n\t\t * @return array\n\t\t */\n\t\tget_blacklist: function() {\n\t\t\tconsole.log( 'Method `get_blacklist()` is deprecated in favor of `get_blocklist()`.' );\n\t\t\treturn this.get_blacklist();\n\t\t},\n\t\n\t} );\n\t\n\t\t/**\n\t * Pricing Table UI\n\t *\n\t * @package LifterLMS/Scripts\n\t *\n\t * @since Unknown.\n\t * @version Unknown.\n\t */\n\t\n\tLLMS.Pricing_Tables = {\n\t\n\t\t/**\n\t\t * Init\n\t\t */\n\t\tinit: function() {\n\t\n\t\t\tvar self = this;\n\t\n\t\t\tif ( $( 'body' ).hasClass( 'wp-admin' ) ) {\n\t\t\t\treturn;\n\t\t\t}\n\t\n\t\t\tif ( $( '.llms-access-plans' ).length ) {\n\t\n\t\t\t\tLLMS.wait_for_matchHeight( function() {\n\t\t\t\t\tself.bind();\n\t\t\t\t} );\n\t\n\t\t\t\tthis.$locked = $( 'a[href=\"#llms-plan-locked\"]' );\n\t\n\t\t\t\tif ( this.$locked.length ) {\n\t\n\t\t\t\t\tLLMS.wait_for_popover( function() {\n\t\t\t\t\t\tself.bind_locked();\n\t\t\t\t\t} );\n\t\n\t\t\t\t}\n\t\n\t\t\t}\n\t\n\t\t},\n\t\n\t\t/**\n\t\t * Bind Method\n\t\t * Handles dom binding on load\n\t\t *\n\t\t * @return {[type]} [description]\n\t\t */\n\t\tbind: function() {\n\t\n\t\t\t$( '.llms-access-plan-content' ).matchHeight();\n\t\t\t$( '.llms-access-plan-pricing.trial' ).matchHeight();\n\t\n\t\t},\n\t\n\t\t/**\n\t\t * Setup a popover for members-only restricted plans\n\t\t *\n\t\t * @return void\n\t\t * @since 3.0.0\n\t\t * @version 3.9.1\n\t\t */\n\t\tbind_locked: function() {\n\t\n\t\t\tthis.$locked.each( function() {\n\t\n\t\t\t\t$( this ).webuiPopover( {\n\t\t\t\t\tanimation: 'pop',\n\t\t\t\t\tcloseable: true,\n\t\t\t\t\tcontent: function( e ) {\n\t\t\t\t\t\tvar $content = $( '
' );\n\t\t\t\t\t\t$content.append( e.$element.closest( '.llms-access-plan' ).find( '.llms-access-plan-restrictions ul' ).clone() );\n\t\t\t\t\t\treturn $content;\n\t\t\t\t\t},\n\t\t\t\t\tplacement: 'top',\n\t\t\t\t\tstyle: 'inverse',\n\t\t\t\t\ttitle: LLMS.l10n.translate( 'Members Only Pricing' ),\n\t\t\t\t\twidth: '280px',\n\t\t\t\t} );\n\t\n\t\t\t} );\n\t\n\t\t},\n\t\n\t};\n\t\n\t\t/**\n\t * LifterLMS Reviews JS\n\t *\n\t * @package LifterLMS/Scripts\n\t *\n\t * @since Unknown\n\t * @version Unknown\n\t */\n\t\n\tLLMS.Review = {\n\t\t/**\n\t\t * Init\n\t\t * loads class methods\n\t\t */\n\t\tinit: function() {\n\t\t\t// console.log('Initializing Review ');\n\t\t\tthis.bind();\n\t\t},\n\t\n\t\t/**\n\t\t * This function binds actions to the appropriate hooks\n\t\t */\n\t\tbind: function() {\n\t\t\t$( '#llms_review_submit_button' ).click(function()\n\t\t\t\t{\n\t\t\t\tif ($( '#review_title' ).val() !== '' && $( '#review_text' ).val() !== '') {\n\t\t\t\t\tjQuery.ajax({\n\t\t\t\t\t\ttype : 'post',\n\t\t\t\t\t\tdataType : 'json',\n\t\t\t\t\t\turl : window.llms.ajaxurl,\n\t\t\t\t\t\tdata : {\n\t\t\t\t\t\t\taction : 'LLMSSubmitReview',\n\t\t\t\t\t\t\treview_title: $( '#review_title' ).val(),\n\t\t\t\t\t\t\treview_text: $( '#review_text' ).val(),\n\t\t\t\t\t\t\tpageID : $( '#post_ID' ).val()\n\t\t\t\t\t\t},\n\t\t\t\t\t\tsuccess: function()\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tconsole.log( 'Review success' );\n\t\t\t\t\t\t\t$( '#review_box' ).hide( 'swing' );\n\t\t\t\t\t\t\t$( '#thank_you_box' ).show( 'swing' );\n\t\t\t\t\t\t},\n\t\t\t\t\t\terror: function(jqXHR, textStatus, errorThrown )\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tconsole.log( jqXHR );\n\t\t\t\t\t\t\tconsole.log( textStatus );\n\t\t\t\t\t\t\tconsole.log( errorThrown );\n\t\t\t\t\t\t},\n\t\t\t\t\t});\n\t\t\t\t} else {\n\t\t\t\t\tif ($( '#review_title' ).val() === '') {\n\t\t\t\t\t\t$( '#review_title_error' ).show( 'swing' );\n\t\t\t\t\t} else {\n\t\t\t\t\t\t$( '#review_title_error' ).hide( 'swing' );\n\t\t\t\t\t}\n\t\t\t\t\tif ($( '#review_text' ).val() === '') {\n\t\t\t\t\t\t$( '#review_text_error' ).show( 'swing' );\n\t\t\t\t\t} else {\n\t\t\t\t\t\t$( '#review_text_error' ).hide( 'swing' );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\t\tif ( $( '#_llms_display_reviews' ).attr( 'checked' ) ) {\n\t\t\t\t$( '.llms-num-reviews-top' ).addClass( 'top' );\n\t\t\t\t$( '.llms-num-reviews-bottom' ).show();\n\t\n\t\t\t} else {\n\t\t\t\t$( '.llms-num-reviews-bottom' ).hide();\n\t\t\t}\n\t\t\t$( '#_llms_display_reviews' ).change(function() {\n\t\t\t\tif ( $( '#_llms_display_reviews' ).attr( 'checked' ) ) {\n\t\t\t\t\t$( '.llms-num-reviews-top' ).addClass( 'top' );\n\t\t\t\t\t$( '.llms-num-reviews-bottom' ).show();\n\t\t\t\t} else {\n\t\t\t\t\t$( '.llms-num-reviews-top' ).removeClass( 'top' );\n\t\t\t\t\t$( '.llms-num-reviews-bottom' ).hide();\n\t\t\t\t}\n\t\t\t});\n\t\n\t\t},\n\t};\n\t\n\t\t/**\n\t * Add Spinners for AJAX events\n\t *\n\t * @package LifterLMS/Scripts\n\t *\n\t * @since 3.0.0\n\t * @version 3.0.0\n\t */\n\t\n\tLLMS.Spinner = {\n\t\n\t\t/**\n\t\t * Get an exiting spinner element or create a new one\n\t\t *\n\t\t * @param obj $el jQuery selector of the parent element that should hold and be mased by a spinner\n\t\t * @param string size size or the spinner [default|small]\n\t\t * default is 40px\n\t\t * small is 20px\n\t\t * @return obj\n\t\t * @since 3.0.0\n\t\t * @version 3.0.0\n\t\t */\n\t\tget: function( $el, size ) {\n\t\n\t\t\t// look for an existing spinner\n\t\t\tvar $spinner = $el.find( '.llms-spinning' ).first();\n\t\n\t\t\t// no spinner inside $el\n\t\t\tif ( ! $spinner.length ) {\n\t\n\t\t\t\tsize = ( size ) ? size : 'default';\n\t\n\t\t\t\t// create the spinner\n\t\t\t\t$spinner = $( '
' );\n\t\n\t\t\t\t// add it to the dom\n\t\t\t\t$el.append( $spinner );\n\t\n\t\t\t}\n\t\n\t\t\t// return it\n\t\t\treturn $spinner;\n\t\n\t\t},\n\t\n\t\t/**\n\t\t * Start spinner(s) inr=side a given element\n\t\t * Creates them if they don't exist!\n\t\t *\n\t\t * @param obj $el jQuery selector of the parent element that should hold and be mased by a spinner\n\t\t * @param string size size or the spinner [default|small]\n\t\t * default is 40px\n\t\t * small is 20px\n\t\t * @return void\n\t\t * @since 3.0.0\n\t\t * @version 3.0.0\n\t\t */\n\t\tstart: function( $el, size ) {\n\t\n\t\t\tvar self = this;\n\t\n\t\t\t$el.each( function() {\n\t\n\t\t\t\tself.get( $( this ), size ).show();\n\t\n\t\t\t} );\n\t\n\t\t},\n\t\n\t\t/**\n\t\t * Store spinners within an element\n\t\t *\n\t\t * @param obj $el jQuery selector of the parent element that should hold and be mased by a spinner\n\t\t * @return void\n\t\t * @since 3.0.0\n\t\t * @version 3.0.0\n\t\t */\n\t\tstop: function( $el ) {\n\t\n\t\t\tvar self = this;\n\t\n\t\t\t$el.each( function() {\n\t\n\t\t\t\tself.get( $( this ) ).hide();\n\t\n\t\t\t} );\n\t\n\t\t}\n\t\n\t};\n\t\n\t\t/* global LLMS, $ */\n\t\n\t/*!\n\t * JavaScript Cookie v2.2.1\n\t * https://github.com/js-cookie/js-cookie\n\t *\n\t * Copyright 2006, 2015 Klaus Hartl & Fagner Brack\n\t * Released under the MIT license\n\t */\n\t;(function (factory) {\n\t\tvar registeredInModuleLoader;\n\t\tif (typeof define === 'function' && define.amd) {\n\t\t\tdefine(factory);\n\t\t\tregisteredInModuleLoader = true;\n\t\t}\n\t\tif (typeof exports === 'object') {\n\t\t\tmodule.exports = factory();\n\t\t\tregisteredInModuleLoader = true;\n\t\t}\n\t\tif (!registeredInModuleLoader) {\n\t\t\tvar OldCookies = window.Cookies;\n\t\t\tvar api = window.Cookies = factory();\n\t\t\tapi.noConflict = function () {\n\t\t\t\twindow.Cookies = OldCookies;\n\t\t\t\treturn api;\n\t\t\t};\n\t\t}\n\t}(function () {\n\t\tfunction extend () {\n\t\t\tvar i = 0;\n\t\t\tvar result = {};\n\t\t\tfor (; i < arguments.length; i++) {\n\t\t\t\tvar attributes = arguments[ i ];\n\t\t\t\tfor (var key in attributes) {\n\t\t\t\t\tresult[key] = attributes[key];\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn result;\n\t\t}\n\t\n\t\tfunction decode (s) {\n\t\t\treturn s.replace(/(%[0-9A-Z]{2})+/g, decodeURIComponent);\n\t\t}\n\t\n\t\tfunction init (converter) {\n\t\t\tfunction api() {}\n\t\n\t\t\tfunction set (key, value, attributes) {\n\t\t\t\tif (typeof document === 'undefined') {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\n\t\t\t\tattributes = extend({\n\t\t\t\t\tpath: '/'\n\t\t\t\t}, api.defaults, attributes);\n\t\n\t\t\t\tif (typeof attributes.expires === 'number') {\n\t\t\t\t\tattributes.expires = new Date(new Date() * 1 + attributes.expires * 864e+5);\n\t\t\t\t}\n\t\n\t\t\t\t// We're using \"expires\" because \"max-age\" is not supported by IE\n\t\t\t\tattributes.expires = attributes.expires ? attributes.expires.toUTCString() : '';\n\t\n\t\t\t\ttry {\n\t\t\t\t\tvar result = JSON.stringify(value);\n\t\t\t\t\tif (/^[\\{\\[]/.test(result)) {\n\t\t\t\t\t\tvalue = result;\n\t\t\t\t\t}\n\t\t\t\t} catch (e) {}\n\t\n\t\t\t\tvalue = converter.write ?\n\t\t\t\t\tconverter.write(value, key) :\n\t\t\t\t\tencodeURIComponent(String(value))\n\t\t\t\t\t\t.replace(/%(23|24|26|2B|3A|3C|3E|3D|2F|3F|40|5B|5D|5E|60|7B|7D|7C)/g, decodeURIComponent);\n\t\n\t\t\t\tkey = encodeURIComponent(String(key))\n\t\t\t\t\t.replace(/%(23|24|26|2B|5E|60|7C)/g, decodeURIComponent)\n\t\t\t\t\t.replace(/[\\(\\)]/g, escape);\n\t\n\t\t\t\tvar stringifiedAttributes = '';\n\t\t\t\tfor (var attributeName in attributes) {\n\t\t\t\t\tif (!attributes[attributeName]) {\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tstringifiedAttributes += '; ' + attributeName;\n\t\t\t\t\tif (attributes[attributeName] === true) {\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\n\t\t\t\t\t// Considers RFC 6265 section 5.2:\n\t\t\t\t\t// ...\n\t\t\t\t\t// 3. If the remaining unparsed-attributes contains a %x3B (\";\")\n\t\t\t\t\t// character:\n\t\t\t\t\t// Consume the characters of the unparsed-attributes up to,\n\t\t\t\t\t// not including, the first %x3B (\";\") character.\n\t\t\t\t\t// ...\n\t\t\t\t\tstringifiedAttributes += '=' + attributes[attributeName].split(';')[0];\n\t\t\t\t}\n\t\n\t\t\t\treturn (document.cookie = key + '=' + value + stringifiedAttributes);\n\t\t\t}\n\t\n\t\t\tfunction get (key, json) {\n\t\t\t\tif (typeof document === 'undefined') {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\n\t\t\t\tvar jar = {};\n\t\t\t\t// To prevent the for loop in the first place assign an empty array\n\t\t\t\t// in case there are no cookies at all.\n\t\t\t\tvar cookies = document.cookie ? document.cookie.split('; ') : [];\n\t\t\t\tvar i = 0;\n\t\n\t\t\t\tfor (; i < cookies.length; i++) {\n\t\t\t\t\tvar parts = cookies[i].split('=');\n\t\t\t\t\tvar cookie = parts.slice(1).join('=');\n\t\n\t\t\t\t\tif (!json && cookie.charAt(0) === '\"') {\n\t\t\t\t\t\tcookie = cookie.slice(1, -1);\n\t\t\t\t\t}\n\t\n\t\t\t\t\ttry {\n\t\t\t\t\t\tvar name = decode(parts[0]);\n\t\t\t\t\t\tcookie = (converter.read || converter)(cookie, name) ||\n\t\t\t\t\t\t\tdecode(cookie);\n\t\n\t\t\t\t\t\tif (json) {\n\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\tcookie = JSON.parse(cookie);\n\t\t\t\t\t\t\t} catch (e) {}\n\t\t\t\t\t\t}\n\t\n\t\t\t\t\t\tjar[name] = cookie;\n\t\n\t\t\t\t\t\tif (key === name) {\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t} catch (e) {}\n\t\t\t\t}\n\t\n\t\t\t\treturn key ? jar[key] : jar;\n\t\t\t}\n\t\n\t\t\tapi.set = set;\n\t\t\tapi.get = function (key) {\n\t\t\t\treturn get(key, false /* read as raw */);\n\t\t\t};\n\t\t\tapi.getJSON = function (key) {\n\t\t\t\treturn get(key, true /* read as json */);\n\t\t\t};\n\t\t\tapi.remove = function (key, attributes) {\n\t\t\t\tset(key, '', extend(attributes, {\n\t\t\t\t\texpires: -1\n\t\t\t\t}));\n\t\t\t};\n\t\n\t\t\tapi.defaults = {};\n\t\n\t\t\tapi.withConverter = init;\n\t\n\t\t\treturn api;\n\t\t}\n\t\n\t\treturn init(function () {});\n\t}));\n\t\n\t/**\n\t * Create a no conflict reference to JS Cookies.\n\t *\n\t * @type {Object}\n\t */\n\tLLMS.CookieStore = Cookies.noConflict();\n\t\n\t/**\n\t * Store information in Local Storage by group.\n\t *\n\t * @since 3.36.0\n\t * @since 3.37.14 Use persistent reference to JS Cookies.\n\t * @since 4.2.0 Set sameSite to `strict` for cookies.\n\t *\n\t * @param string group Storage group id/name.\n\t */\n\tLLMS.Storage = function( group ) {\n\t\n\t\tvar self = this,\n\t\t\tstore = LLMS.CookieStore;\n\t\n\t\t/**\n\t\t * Clear all data for the group.\n\t\t *\n\t\t * @since 3.36.0\n\t\t *\n\t\t * @return void\n\t\t */\n\t\tthis.clearAll = function() {\n\t\t\tstore.remove( group );\n\t\t};\n\t\n\t\t/**\n\t\t * Clear a single item from the group by key.\n\t\t *\n\t\t * @since 3.36.0\n\t\t *\n\t\t * @return obj\n\t\t */\n\t\tthis.clear = function( key ) {\n\t\t\tvar data = self.getAll();\n\t\t\tdelete data[ key ];\n\t\t\treturn store.set( group, data );\n\t\t};\n\t\n\t\t/**\n\t\t * Retrieve (and parse) all data stored for the group.\n\t\t *\n\t\t * @since 3.36.0\n\t\t *\n\t\t * @return obj\n\t\t */\n\t\tthis.getAll = function() {\n\t\t\treturn store.getJSON( group ) || {};\n\t\t}\n\t\n\t\t/**\n\t\t * Retrieve an item from the group by key.\n\t\t *\n\t\t * @since 3.36.0\n\t\t *\n\t\t * @param string key Item key/name.\n\t\t * @param mixed default_val Item default value to be returned when item not found in the group.\n\t\t * @return mixed\n\t\t */\n\t\tthis.get = function( key, default_val ) {\n\t\t\tvar data = self.getAll();\n\t\t\treturn data[ key ] ? data[ key ] : default_val;\n\t\t}\n\t\n\t\t/**\n\t\t * Store an item in the group by key.\n\t\t *\n\t\t * @since 3.36.0\n\t\t * @since 4.2.0 Set sameSite to `strict` for cookies.\n\t\t *\n\t\t * @param string key Item key name.\n\t\t * @param mixed val Item value\n\t\t * @return obj\n\t\t */\n\t\tthis.set = function( key, val ) {\n\t\t\tvar data = self.getAll();\n\t\t\tdata[ key ] = val;\n\t\t\treturn store.set( group, data, { sameSite: 'strict' } );\n\t\t};\n\t\n\t}\n\t\n\t\t/**\n\t * Student Dashboard related JS\n\t *\n\t * @package LifterLMS/Scripts\n\t *\n\t * @since 3.7.0\n\t * @since 3.10.0 Bind events on the orders screen.\n\t * @since 5.0.0 Removed redundant password toggle logic for edit account screen.\n\t * @version 5.0.0\n\t */\n\tLLMS.StudentDashboard = {\n\t\n\t\t/**\n\t\t * Slug for the current screen/endpoint\n\t\t *\n\t\t * @type {String}\n\t\t */\n\t\tscreen: '',\n\t\n\t\t/**\n\t\t * Init\n\t\t *\n\t\t * @since 3.7.0\n\t\t * @since 3.10.0 Unknown\n\t\t * @since 5.0.0 Removed password toggle logic.\n\t\t *\n\t\t * @return void\n\t\t */\n\t\tinit: function() {\n\t\n\t\t\tif ( $( '.llms-student-dashboard' ).length ) {\n\t\t\t\tthis.bind();\n\t\t\t\tif ( 'orders' === this.get_screen() ) {\n\t\t\t\t\tthis.bind_orders();\n\t\t\t\t}\n\t\t\t}\n\t\n\t\t},\n\t\n\t\t/**\n\t\t * Bind DOM events\n\t\t *\n\t\t * @since 3.7.0\n\t\t * @since 3.7.4 Unknown.\n\t\t * @since 5.0.0 Removed password toggle logic.\n\t\t *\n\t\t * @return void\n\t\t */\n\t\tbind: function() {\n\t\n\t\t\t$( '.llms-donut' ).each( function() {\n\t\t\t\tLLMS.Donut( $( this ) );\n\t\t\t} );\n\t\n\t\t},\n\t\n\t\t/**\n\t\t * Bind events related to the orders screen on the dashboard\n\t\t *\n\t\t * @since 3.10.0\n\t\t *\n\t\t * @return void\n\t\t */\n\t\tbind_orders: function() {\n\t\n\t\t\t$( '#llms-cancel-subscription-form' ).on( 'submit', this.order_cancel_warning );\n\t\t\t$( '#llms_update_payment_method' ).on( 'click', function() {\n\t\t\t\t$( 'input[name=\"llms_payment_gateway\"]:checked' ).trigger( 'change' );\n\t\t\t\t$( this ).closest( 'form' ).find( '.llms-switch-payment-source-main' ).slideToggle( '200' );\n\t\t\t} );\n\t\n\t\t},\n\t\n\t\t/**\n\t\t * Get the current dashboard endpoint/tab slug\n\t\t *\n\t\t * @since 3.10.0\n\t\t *\n\t\t * @return void\n\t\t */\n\t\tget_screen: function() {\n\t\t\tif ( ! this.screen ) {\n\t\t\t\tthis.screen = $( '.llms-student-dashboard' ).attr( 'data-current' );\n\t\t\t}\n\t\t\treturn this.screen;\n\t\t},\n\t\n\t\t/**\n\t\t * Show a confirmation warning when Cancel Subscription form is submitted\n\t\t *\n\t\t * @since 3.10.0\n\t\t *\n\t\t * @param obj e JS event data.\n\t\t * @return void\n\t\t */\n\t\torder_cancel_warning: function( e ) {\n\t\t\te.preventDefault();\n\t\t\tvar msg = LLMS.l10n.translate( 'Are you sure you want to cancel your subscription?' );\n\t\t\tif ( window.confirm( LLMS.l10n.translate( msg ) ) ) {\n\t\t\t\t$( this ).off( 'submit', this.order_cancel_warning );\n\t\t\t\t$( this ).submit();\n\t\t\t}\n\t\t},\n\t\n\t};\n\t\n\t\t/* global LLMS, $ */\n\t\n\t/**\n\t * User event/interaction tracking.\n\t *\n\t * @since 3.36.0\n\t * @since 3.36.2 Fix JS error when settings aren't loaded.\n\t * @since 3.37.2 When adding an event to the storae also make sure the nonce is set for server-side verification.\n\t * @since 3.37.9 Fix IE compatibility issue related to usage of `Object.assign()`.\n\t * @since 3.37.14 Persist the tracking events via ajax when reaching the cookie size limit.\n\t * @since 5.0.0 Set `settings` as an empty object when no settings supplied.\n\t * Only attempt to add a nonce to the datastore when a nonce exists in the settings object.\n\t */\n\tLLMS.Tracking = function( settings ) {\n\t\n\t\tsettings = settings || {};\n\t\n\t\tvar self = this,\n\t\t\tstore = new LLMS.Storage( 'llms-tracking' );\n\t\n\t\tsettings = 'string' === typeof settings ? JSON.parse( settings ) : settings;\n\t\n\t\t/**\n\t\t * Initialize / Bind all tracking event listeners.\n\t\t *\n\t\t * @since 3.36.0\n\t\t * @since 5.0.0 Only attempt to add a nonce to the datastore when a nonce exists in the settings object.\n\t\t *\n\t\t * @return {void}\n\t\t */\n\t\tfunction init() {\n\t\n\t\t\t// Set the nonce for server-side verification.\n\t\t\tif ( settings.nonce ) {\n\t\n\t\t\t\tstore.set( 'nonce', settings.nonce );\n\t\n\t\t\t}\n\t\n\t\t\tself.addEvent( 'page.load' );\n\t\n\t\t\twindow.addEventListener( 'beforeunload', onBeforeUnload );\n\t\t\twindow.addEventListener( 'unload', onUnload );\n\t\n\t\t\tdocument.addEventListener( 'visibilitychange', onVisibilityChange );\n\t\n\t\t};\n\t\n\t\t/**\n\t\t * Add an event.\n\t\t *\n\t\t * @since 3.36.0\n\t\t * @since 3.36.2 Fix error when settings aren't loaded.\n\t\t * @since 3.37.2 Always make sure the nonce is set for server-side verification.\n\t\t * @since 3.37.14 Persist the tracking events via ajax when reaching the cookie size limit.\n\t\t *\n\t\t * @param string|obj event Event Id (type.event) or a full event object from `this.makeEventObj()`.\n\t\t * @param int args Optional additional arguments to pass to `this.makeEventObj()`.\n\t\t * @return {void}\n\t\t */\n\t\tthis.addEvent = function( event, args ) {\n\t\n\t\t\targs = args || {};\n\t\t\tif ( 'string' === typeof event ) {\n\t\t\t\targs.event = event;\n\t\t\t}\n\t\n\t\t\t// If the event isn't registered in the settings don't proceed.\n\t\t\tif ( !settings.events || -1 === settings.events.indexOf( args.event ) ) {\n\t\t\t\treturn;\n\t\t\t}\n\t\n\t\t\t// Make sure the nonce is set for server-side verification.\n\t\t\tstore.set( 'nonce', settings.nonce );\n\t\n\t\t\tevent = self.makeEventObj( args );\n\t\n\t\t\tvar all = store.get( 'events', [] );\n\t\t\tall.push( event );\n\t\t\tstore.set( 'events', all );\n\t\n\t\t\t// If couldn't store the latest event because of size limits.\n\t\t\tif ( all.length > store.get( 'events', [] ).length ) {\n\t\n\t\t\t\t// Copy the cookie in a temporary variable.\n\t\t\t\tvar _temp = store.getAll();\n\t\t\t\t// Clear the events from the cookie.\n\t\t\t\tstore.clear('events');\n\t\n\t\t\t\t// Add the latest event to the temporary variable.\n\t\t\t\t_temp['events'].push( event );\n\t\n\t\t\t\t// Send the temporary variable as string via ajax.\n\t\t\t\tLLMS.Ajax.call( {\n\t\t\t\t\tdata: {\n\t\t\t\t\t\taction: 'persist_tracking_events',\n\t\t\t\t\t\t'llms-tracking': JSON.stringify(_temp)\n\t\t\t\t\t},\n\t\n\t\t\t\t\terror: function( xhr, status, error ) {\n\t\n\t\t\t\t\t\tconsole.log( xhr, status, error );\n\t\n\t\t\t\t\t},\n\t\t\t\t\tsuccess: function( r ) {\n\t\n\t\t\t\t\t\tif ( 'error' === r.code ) {\n\t\t\t\t\t\t\tconsole.log(r.code, r.message);\n\t\t\t\t\t\t}\n\t\n\t\t\t\t\t}\n\t\n\t\t\t\t} );\n\t\n\t\t\t}\n\t\n\t\t}\n\t\n\t\t/**\n\t\t * Retrieve initialization settings.\n\t\t *\n\t\t * @since 3.36.0\n\t\t *\n\t\t * @return obj\n\t\t */\n\t\tthis.getSettings = function() {\n\t\t\treturn settings;\n\t\t}\n\t\n\t\t/**\n\t\t * Create an event object suitable to save as an event.\n\t\t *\n\t\t * @since 3.36.0\n\t\t * @since 3.37.9 Use `$.extend()` in favor of `Object.assign()`.\n\t\t *\n\t\t * @param obj event {\n\t\t * Event hash\n\t\t *\n\t\t * @param {string} event (Required) Event ID, eg: \"page.load\".\n\t\t * @param {url} url Event URL. (Optional, added automatically) Stored as metadata and used to infer an object_id for post events.\n\t\t * @param {time} float (Optional, added automatically) Timestamp (in milliseconds). Used for the event creation date.\n\t\t * @param {int} obj_id (Optional). The object ID. Inferred automatically via `url` if not provided.\n\t\t * @param {obj} meta (Optional) Hash of metadata to store with the event.\n\t\t * }\n\t\t * @return obj\n\t\t */\n\t\tthis.makeEventObj = function( event ) {\n\t\t\treturn $.extend( event, {\n\t\t\t\turl: window.location.href,\n\t\t\t\ttime: Math.round( new Date().getTime() / 1000 ),\n\t\t\t} );\n\t\t}\n\t\n\t\n\t\t/**\n\t\t * Remove the visibility change event listener on window.beforeunload\n\t\t *\n\t\t * Prevents actual unloading from recording a blur event from the visibility change listener\n\t\t *\n\t\t * @param obj e JS event object.\n\t\t * @return void\n\t\t */\n\t\tfunction onBeforeUnload( e ) {\n\t\t\tdocument.removeEventListener( 'visibilitychange', onVisibilityChange );\n\t\t}\n\t\n\t\t/**\n\t\t * Record a `page.exit` event on window.unload.\n\t\t *\n\t\t * @since 3.36.0\n\t\t *\n\t\t * @param obj e JS event object.\n\t\t * @return void\n\t\t */\n\t\tfunction onUnload( e ) {\n\t\t\tself.addEvent( 'page.exit' );\n\t\t}\n\t\n\t\t/**\n\t\t * Record `page.blur` and `page.focus` events via document.visilibitychange events.\n\t\t *\n\t\t * @since 3.36.0\n\t\t *\n\t\t * @param obj e JS event object.\n\t\t * @return void\n\t\t */\n\t\tfunction onVisibilityChange( e ) {\n\t\n\t\t\tvar event = document.hidden ? 'page.blur' : 'page.focus';\n\t\t\tself.addEvent( event );\n\t\n\t\t}\n\t\n\t\t// Initialize on the frontend only.\n\t\tif ( ! $( 'body' ).hasClass( 'wp-admin' ) ) {\n\t\t\tinit();\n\t\t}\n\t\n\t};\n\t\n\tllms.tracking = new LLMS.Tracking( llms.tracking );\n\t\n\t\t/**\n\t * Rest Methods\n\t * Manages URL and Rest object parsing\n\t *\n\t * @package LifterLMS/Scripts\n\t *\n\t * @since Unknown\n\t * @version Unknown\n\t */\n\t\n\tLLMS.Rest = {\n\t\n\t\t/**\n\t\t * Init\n\t\t * loads class methods\n\t\t */\n\t\tinit: function() {\n\t\t\tthis.bind();\n\t\t},\n\t\n\t\t/**\n\t\t * Bind Method\n\t\t * Handles dom binding on load\n\t\t *\n\t\t * @return {[type]} [description]\n\t\t */\n\t\tbind: function() {\n\t\t},\n\t\n\t\t/**\n\t\t * Searches for string matches in url path\n\t\t *\n\t\t * @param {Array} strings [Array of strings to search for matches]\n\t\t * @return {Boolean} [Was a match found?]\n\t\t */\n\t\tis_path: function( strings ) {\n\t\n\t\t\tvar path_exists = false,\n\t\t\t\turl = window.location.href;\n\t\n\t\t\tfor ( var i = 0; i < strings.length; i++ ) {\n\t\n\t\t\t\tif ( url.search( strings[i] ) > 0 && ! path_exists ) {\n\t\n\t\t\t\t\tpath_exists = true;\n\t\t\t\t}\n\t\t\t}\n\t\n\t\t\treturn path_exists;\n\t\t},\n\t\n\t\t/**\n\t\t * Retrieves query variables\n\t\t *\n\t\t * @return {[Array]} [array object of query variable key=>value pairs]\n\t\t */\n\t\tget_query_vars: function() {\n\t\n\t\t\tvar vars = [], hash,\n\t\t\t\thashes = window.location.href.slice( window.location.href.indexOf( '?' ) + 1 ).split( '&' );\n\t\n\t\t\tfor (var i = 0; i < hashes.length; i++) {\n\t\t\t\thash = hashes[i].split( '=' );\n\t\t\t\tvars.push( hash[0] );\n\t\t\t\tvars[hash[0]] = hash[1];\n\t\t\t}\n\t\n\t\t\treturn vars;\n\t\t}\n\t\n\t};\n\t\n\n\t/**\n\t * Initializes all classes within the LLMS Namespace\n\t *\n\t * @since Unknown\n\t *\n\t * @return {void}\n\t */\n\tLLMS.init = function() {\n\n\t\tfor (var func in LLMS) {\n\n\t\t\tif ( typeof LLMS[func] === 'object' && LLMS[func] !== null ) {\n\n\t\t\t\tif ( LLMS[func].init !== undefined ) {\n\n\t\t\t\t\tif ( typeof LLMS[func].init === 'function') {\n\t\t\t\t\t\tLLMS[func].init();\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t};\n\n\t/**\n\t * Determine if the current device is touch-enabled\n\t *\n\t * @since 3.24.3\n\t *\n\t * @see {@link https://stackoverflow.com/a/4819886/400568}\n\t *\n\t * @return {Boolean} Whether or not the device is touch-enabled.\n\t */\n\tLLMS.is_touch_device = function() {\n\n\t\tvar prefixes = ' -webkit- -moz- -o- -ms- '.split( ' ' );\n\t\tvar mq = function( query ) {\n\t\t\treturn window.matchMedia( query ).matches;\n\t\t}\n\n\t\tif ( ( 'ontouchstart' in window ) || window.DocumentTouch && document instanceof DocumentTouch ) {\n\t\t\treturn true;\n\t\t}\n\n\t\t/**\n\t\t * Include the 'heartz' as a way to have a non matching MQ to help terminate the join.\n\t\t *\n\t\t * @see {@link https://git.io/vznFH}\n\t\t */\n\t\tvar query = ['(', prefixes.join( 'touch-enabled),(' ), 'heartz', ')'].join( '' );\n\t\treturn mq( query );\n\n\t};\n\n\t/**\n\t * Wait for matchHeight to load\n\t *\n\t * @since 3.0.0\n\t * @since 3.16.6 Unknown.\n\t * @since 5.3.3 Pass a dependency name to `wait_for()`.\n\t *\n\t * @param {Function} cb Callback function to run when matchheight is ready.\n\t * @return {void}\n\t */\n\tLLMS.wait_for_matchHeight = function( cb ) {\n\t\tthis.wait_for( function() {\n\t\t\treturn ( undefined !== $.fn.matchHeight );\n\t\t}, cb, 'matchHeight' );\n\t}\n\n\t/**\n\t * Wait for webuiPopover to load\n\t *\n\t * @since 3.9.1\n\t * @since 3.16.6 Unknown.\n\t *\n\t * @param {Function} cb Callback function to run when matchheight is ready.\n\t * @return {void}\n\t */\n\tLLMS.wait_for_popover = function( cb ) {\n\t\tthis.wait_for( function() {\n\t\t\treturn ( undefined !== $.fn.webuiPopover );\n\t\t}, cb, 'webuiPopover' );\n\t}\n\n\t/**\n\t * Wait for a dependency to load and then run a callback once it has\n\t *\n\t * Temporary fix for a less-than-optimal assets loading function on the PHP side of things.\n\t *\n\t * @since 3.9.1\n\t * @since 5.3.3 Added optional `name` parameter.\n\t *\n\t * @param {Function} test A function that returns a truthy if the dependency is loaded.\n\t * @param {Function} cb A callback function executed once the dependency is loaded.\n\t * @param {string} name The dependency name.\n\t * @return {void}\n\t */\n\tLLMS.wait_for = function( test, cb, name ) {\n\n\t\tvar counter = 0,\n\t\t\tinterval;\n\n\t\tname = name ? name : 'unnamed';\n\n\t\tinterval = setInterval( function() {\n\n\t\t\t// If we get to 30 seconds log an error message.\n\t\t\tif ( counter >= 300 ) {\n\n\t\t\t\tconsole.log( 'Unable to load dependency: ' + name );\n\n\t\t\t\t// If we can't access yet, increment and wait...\n\t\t\t} else {\n\n\t\t\t\t// Bind the events, we're good!\n\t\t\t\tif ( test() ) {\n\t\t\t\t\tcb();\n\t\t\t\t} else {\n\t\t\t\t\t// console.log( 'Waiting for dependency: ' + name );\n\t\t\t\t\tcounter++;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tclearInterval( interval );\n\n\t\t}, 100 );\n\n\t};\n\n\tLLMS.init( $ );\n\n} )( jQuery );\n"],"sourceRoot":"../../js/private"} \ No newline at end of file +{"version":3,"sources":["llms.js"],"names":[],"mappings":";;;;;;;;;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA","file":"../../js/llms.js","sourcesContent":["/**\n * Main LLMS Namespace\n *\n * @since 1.0.0\n * @version 5.3.3\n */\n\nvar LLMS = window.LLMS || {};\n( function( $ ){\n\n\t'use strict';\n\n\t/**\n\t * Load all app modules\n\t */\n\t/**\n\t * Front End Achievements\n\t *\n\t * @package LifterLMS/Scripts\n\t *\n\t * @since 3.14.0\n\t * @version 6.10.2\n\t */\n\t\n\tLLMS.Achievements = {\n\t\n\t\t/**\n\t\t * Init\n\t\t *\n\t\t * @since 3.14.0\n\t\t * @since 4.5.1 Fix conditional loading check.\n\t\t *\n\t\t * @return {void}\n\t\t */\n\t\tinit: function() {\n\t\n\t\t\tif ( $( '.llms-achievement' ).length ) {\n\t\n\t\t\t\tvar self = this;\n\t\n\t\t\t\t$( function() {\n\t\t\t\t\tself.bind();\n\t\t\t\t\tself.maybe_open();\n\t\t\t\t} );\n\t\t\t}\n\t\n\t\t},\n\t\n\t\t/**\n\t\t * Bind DOM events\n\t\t *\n\t\t * @since 3.14.0\n\t\t *\n\t\t * @return {void}\n\t\t */\n\t\tbind: function() {\n\t\n\t\t\tvar self = this;\n\t\n\t\t\t$( '.llms-achievement' ).each( function() {\n\t\n\t\t\t\tself.create_modal( $( this ) );\n\t\n\t\t\t} );\n\t\n\t\t\t$( '.llms-achievement' ).on( 'click', function() {\n\t\n\t\t\t\tvar $this = $( this ),\n\t\t\t\t\tid = 'achievement-' + $this.attr( 'data-id' ),\n\t\t\t\t\t$modal = $( '#' + id );\n\t\n\t\t\t\tif ( ! $modal.length ) {\n\t\t\t\t\tself.create_modal( $this );\n\t\t\t\t}\n\t\n\t\t\t\t$modal.iziModal( 'open' );\n\t\n\t\t\t} );\n\t\n\t\t},\n\t\n\t\t/**\n\t\t * Creates modal a modal for an achievement\n\t\t *\n\t\t * @since 3.14.0\n\t\t *\n\t\t * @param obj $el The jQuery selector for the modal card.\n\t\t * @return {void}\n\t\t */\n\t\tcreate_modal: function( $el ) {\n\t\n\t\t\tvar id = 'achievement-' + $el.attr( 'data-id' ),\n\t\t\t\t$modal = $( '#' + id );\n\t\n\t\t\tif ( ! $modal.length ) {\n\t\t\t\t$modal = $( '
' );\n\t\t\t\t$( 'body' ).append( $modal );\n\t\t\t}\n\t\n\t\t\t$modal.iziModal( {\n\t\t\t\theaderColor: '#3a3a3a',\n\t\t\t\tgroup: 'achievements',\n\t\t\t\thistory: true,\n\t\t\t\tloop: true,\n\t\t\t\toverlayColor: 'rgba( 0, 0, 0, 0.6 )',\n\t\t\t\ttransitionIn: 'fadeInDown',\n\t\t\t\ttransitionOut: 'fadeOutDown',\n\t\t\t\twidth: 340,\n\t\t\t\tonOpening: function( modal ) {\n\t\n\t\t\t\t\tmodal.setTitle( $el.find( '.llms-achievement-title' ).html() );\n\t\t\t\t\tmodal.setSubtitle( $el.find( '.llms-achievement-date' ).html() );\n\t\t\t\t\tmodal.setContent( '
' + $el.html() + '
' );\n\t\n\t\t\t\t},\n\t\n\t\t\t\tonClosing: function() {\n\t\t\t\t\twindow.history.pushState( '', document.title, window.location.pathname + window.location.search );\n\t\t\t\t},\n\t\n\t\t\t} );\n\t\n\t\t},\n\t\n\t\t/**\n\t\t * On page load, opens a modal if the URL contains an achievement in the location hash\n\t\t *\n\t\t * @since 3.14.0\n\t\t * @since 6.10.2 Sanitize achievement IDs before using window.location.hash to trigger the modal open.\n\t\t *\n\t\t * @return {void}\n\t\t */\n\t\tmaybe_open: function() {\n\t\n\t\t\tlet hash = window.location.hash.split( '-' );\n\t\t\tif ( 2 !== hash.length ) {\n\t\t\t\treturn;\n\t\t\t}\n\t\n\t\t\thash[1] = parseInt( hash[1] );\n\t\t\tif ( '#achievement-' !== hash[0] || ! Number.isInteger( hash[1] ) ) {\n\t\t\t\treturn;\n\t\t\t}\n\t\n\t\t\tconst a = document.querySelector( `a[href=\"${ hash.join( '-' ) }\"]` )\n\t\t\tif ( ! a ) {\n\t\t\t\treturn;\n\t\t\t}\n\t\n\t\t\ta.click();\n\t\n\t\t}\n\t\n\t};\n\t\n\t\t/**\n\t * Main Ajax class\n\t * Handles Primary Ajax connection\n\t *\n\t * @package LifterLMS/Scripts\n\t *\n\t * @since Unknown\n\t * @version Unknown\n\t */\n\t\n\tLLMS.Ajax = {\n\t\n\t\t/**\n\t\t * Url\n\t\t *\n\t\t * @type {String}\n\t\t */\n\t\turl: window.ajaxurl || window.llms.ajaxurl,\n\t\n\t\t/**\n\t\t * Type\n\t\t *\n\t\t * @type {[type]}\n\t\t */\n\t\ttype: 'post',\n\t\n\t\t/**\n\t\t * Data\n\t\t *\n\t\t * @type {[type]}\n\t\t */\n\t\tdata: [],\n\t\n\t\t/**\n\t\t * Cache\n\t\t *\n\t\t * @type {[type]}\n\t\t */\n\t\tcache: false,\n\t\n\t\t/**\n\t\t * DataType\n\t\t * defaulted to json\n\t\t *\n\t\t * @type {String}\n\t\t */\n\t\tdataType: 'json',\n\t\n\t\t/**\n\t\t * Async\n\t\t * default to false\n\t\t *\n\t\t * @type {Boolean}\n\t\t */\n\t\tasync: true,\n\t\n\t\tresponse:[],\n\t\n\t\t/**\n\t\t * Initialize Ajax methods\n\t\t *\n\t\t * @since Unknown\n\t\t * @since 4.4.0 Update ajax nonce source.\n\t\t *\n\t\t * @param {Object} obj Options object.\n\t\t * @return {Object}\n\t\t */\n\t\tinit: function( obj ) {\n\t\n\t\t\t// If obj is not of type object or null return false.\n\t\t\tif ( obj === null || typeof obj !== 'object' ) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\n\t\t\t// set object defaults if values are not supplied\n\t\t\tobj.url = 'url' in obj ? obj.url : this.url;\n\t\t\tobj.type = 'type' \t\tin obj ? obj.type : this.type;\n\t\t\tobj.data = 'data' \t\tin obj ? obj.data : this.data;\n\t\t\tobj.cache = 'cache' \t\tin obj ? obj.cache : this.cache;\n\t\t\tobj.dataType = 'dataType'\tin obj ? obj.dataType : this.dataType;\n\t\t\tobj.async = 'async'\t\tin obj ? obj.async : this.async;\n\t\n\t\t\t// Add nonce to data object.\n\t\t\tobj.data._ajax_nonce = window.llms.ajax_nonce || wp_ajax_data.nonce;\n\t\n\t\t\t// Add post id to data object.\n\t\t\tvar $R = LLMS.Rest,\n\t\t\tquery_vars = $R.get_query_vars();\n\t\t\tobj.data.post_id = 'post' in query_vars ? query_vars.post : null;\n\t\t\tif ( ! obj.data.post_id && $( 'input#post_ID' ).length ) {\n\t\t\t\tobj.data.post_id = $( 'input#post_ID' ).val();\n\t\t\t}\n\t\n\t\t\treturn obj;\n\t\t},\n\t\n\t\t/**\n\t\t * Call\n\t\t * Called by external classes\n\t\t * Sets up jQuery Ajax object\n\t\t *\n\t\t * @param {[object]} [object of ajax settings]\n\t\t * @return {[mixed]} [false if not object or this]\n\t\t */\n\t\tcall: function(obj) {\n\t\n\t\t\t// get default variables if not included in call\n\t\t\tvar settings = this.init( obj );\n\t\n\t\t\t// if init return a response of false\n\t\t\tif ( ! settings) {\n\t\t\t\treturn false;\n\t\t\t} else {\n\t\t\t\tthis.request( settings );\n\t\t\t}\n\t\n\t\t\treturn this;\n\t\n\t\t},\n\t\n\t\t/**\n\t\t * Calls jQuery Ajax on settings object\n\t\t *\n\t\t * @return {[object]} [this]\n\t\t */\n\t\trequest: function(settings) {\n\t\n\t\t\t$.ajax( settings );\n\t\n\t\t\treturn this;\n\t\n\t\t}\n\t\n\t};\n\t\n\t\t/**\n\t * Create a Donut Chart\n\t *\n\t * @package LifterLMS/Scripts\n\t *\n\t * @since 3.9.0\n\t * @version 4.15.0\n\t *\n\t * @link https://gist.github.com/joeyinbox/8205962\n\t *\n\t * @param {Object} $el jQuery element to draw a chart within.\n\t */\n\t\n\tLLMS.Donut = function( $el ) {\n\t\n\t\t/**\n\t\t * Constructor\n\t\t *\n\t\t * @since 3.9.0\n\t\t * @since 4.15.0 Flip animation in RTL.\n\t\t *\n\t\t * @param {Object} options Donut options.\n\t\t * @return {Void}\n\t\t */\n\t\tfunction Donut(options) {\n\t\n\t\t\tthis.settings = $.extend( {\n\t\t\t\telement: options.element,\n\t\t\t\tpercent: 100\n\t\t\t}, options );\n\t\n\t\t\tthis.circle = this.settings.element.find( 'path' );\n\t\t\tthis.settings.stroke_width = parseInt( this.circle.css( 'stroke-width' ) );\n\t\t\tthis.radius = ( parseInt( this.settings.element.css( 'width' ) ) - this.settings.stroke_width ) / 2;\n\t\t\tthis.angle = $( 'body' ).hasClass( 'rtl' ) ? 82.5 : 97.5; // Origin of the draw at the top of the circle\n\t\t\tthis.i = Math.round( 0.75 * this.settings.percent );\n\t\t\tthis.first = true;\n\t\t\tthis.increment = $( 'body' ).hasClass( 'rtl' ) ? -5 : 5;\n\t\n\t\t\tthis.animate = function() {\n\t\t\t\tthis.timer = setInterval( this.loop.bind( this ), 10 );\n\t\t\t};\n\t\n\t\t\tthis.loop = function() {\n\t\t\t\tthis.angle += this.increment;\n\t\t\t\tthis.angle %= 360;\n\t\t\t\tvar radians = ( this.angle / 180 ) * Math.PI,\n\t\t\t\t\tx = this.radius + this.settings.stroke_width / 2 + Math.cos( radians ) * this.radius,\n\t\t\t\t\ty = this.radius + this.settings.stroke_width / 2 + Math.sin( radians ) * this.radius,\n\t\t\t\t\td;\n\t\t\t\tif (this.first === true) {\n\t\t\t\t\td = this.circle.attr( 'd' ) + ' M ' + x + ' ' + y;\n\t\t\t\t\tthis.first = false;\n\t\t\t\t} else {\n\t\t\t\t\td = this.circle.attr( 'd' ) + ' L ' + x + ' ' + y;\n\t\t\t\t}\n\t\t\t\tthis.circle.attr( 'd', d );\n\t\t\t\tthis.i--;\n\t\n\t\t\t\tif (this.i <= 0) {\n\t\t\t\t\tclearInterval( this.timer );\n\t\t\t\t}\n\t\t\t};\n\t\t}\n\t\n\t\t/**\n\t\t * Draw donut element\n\t\t *\n\t\t * @since 3.9.0\n\t\t *\n\t\t * @param {Object} $el jQuery element to draw a chart within.\n\t\t * @return {Void}\n\t\t */\n\t\tfunction draw( $el ) {\n\t\t\tvar path = '';\n\t\t\t$el.append( '' + path + '' );\n\t\t\tvar donut = new Donut( {\n\t\t\t\telement: $el,\n\t\t\t\tpercent: $el.attr( 'data-perc' )\n\t\t\t} );\n\t\t\tdonut.animate();\n\t\t}\n\t\n\t\tdraw( $el );\n\t\n\t};\n\t\n\t\t/**\n\t * Forms\n\t *\n\t * @package LifterLMS/Scripts\n\t *\n\t * @since 5.0.0\n\t * @version 5.3.3\n\t */\n\t\n\tLLMS.Forms = {\n\t\n\t\t/**\n\t\t * Stores locale information.\n\t\t *\n\t\t * Added via PHP.\n\t\t *\n\t\t * @type {Object}\n\t\t */\n\t\taddress_info: {},\n\t\n\t\t/**\n\t\t * jQuery ref. to the city text field.\n\t\t *\n\t\t * @type {Object}\n\t\t */\n\t\t$cities: null,\n\t\n\t\t/**\n\t\t * jQuery ref. to the countries select field.\n\t\t *\n\t\t * @type {Object}\n\t\t */\n\t\t$countries: null,\n\t\n\t\t/**\n\t\t * jQuery ref. to the states select field.\n\t\t *\n\t\t * @type {Object}\n\t\t */\n\t\t$states: null,\n\t\n\t\t/**\n\t\t * jQuery ref. to the hidden states holder field.\n\t\t *\n\t\t * @type {Object}\n\t\t */\n\t\t$states_holder: null,\n\t\n\t\t/**\n\t\t * Init\n\t\t *\n\t \t * @since 5.0.0\n\t \t * @since 5.3.3 Move select2 dependency check into the `bind_l10_selects()` method.\n\t \t *\n\t \t * @return {void}\n\t\t */\n\t\tinit: function() {\n\t\n\t\t\tif ( $( 'body' ).hasClass( 'wp-admin' ) ) {\n\t\t\t\tif ( ! ( $( 'body' ).hasClass( 'profile-php' ) || $( 'body' ).hasClass( 'user-edit-php' ) ) ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\n\t\t\tvar self = this;\n\t\n\t\t\tself.bind_matching_fields();\n\t\t\tself.bind_voucher_field();\n\t\t\tself.bind_edit_account();\n\t\t\tself.bind_l10n_selects();\n\t\n\t\t},\n\t\n\t\t/**\n\t\t * Bind DOM events for the edit account screen.\n\t\t *\n\t\t * @since 5.0.0\n\t\t *\n\t\t * @return {void}\n\t\t */\n\t\tbind_edit_account: function() {\n\t\n\t\t\t// Not an edit account form.\n\t\t\tif ( ! $( 'form.llms-person-form.edit-account' ).length ) {\n\t\t\t\treturn;\n\t\t\t}\n\t\n\t\t\t$( '.llms-toggle-fields' ).on( 'click', this.handle_toggle_click );\n\t\n\t\t},\n\t\n\t\t/**\n\t\t * Bind DOM Events fields with dynamic localization values and language.\n\t\t *\n\t\t * @since 5.0.0\n\t\t * @since 5.3.3 Bind select2-related events after ensuring select2 is available.\n\t\t *\n\t\t * @return {void}\n\t\t */\n\t\tbind_l10n_selects: function() {\n\t\n\t\t\tvar self = this;\n\t\n\t\t\tself.$cities = $( '#llms_billing_city' );\n\t\t\tself.$countries = $( '.llms-l10n-country-select select' );\n\t\t\tself.$states = $( '.llms-l10n-state-select select' );\n\t\t\tself.$zips = $( '#llms_billing_zip' );\n\t\n\t\t\tif ( ! self.$countries.length ) {\n\t\t\t\treturn;\n\t\t\t}\n\t\n\t\t\tvar isSelect2Available = function() {\n\t\t\t\treturn ( undefined !== $.fn.llmsSelect2 );\n\t\t\t};\n\t\n\t\t\tLLMS.wait_for( isSelect2Available, function() {\n\t\n\t\t\t\tif ( self.$states.length ) {\n\t\t\t\t\tself.prep_state_field();\n\t\t\t\t}\n\t\n\t\t\t\tself.$countries.add( self.$states ).llmsSelect2( { width: '100%' } );\n\t\n\t\t\t\tif ( window.llms.address_info ) {\n\t\t\t\t\tself.address_info = JSON.parse( window.llms.address_info );\n\t\t\t\t}\n\t\n\t\t\t\tself.$countries.on( 'change', function() {\n\t\n\t\t\t\t\tvar val = $( this ).val();\n\t\t\t\t\tself.update_locale_info( val );\n\t\n\t\t\t\t} ).trigger( 'change' );\n\t\n\t\t\t}, 'llmsSelect2' );\n\t\n\t\t},\n\t\n\t\t/**\n\t\t * Ensure \"matching\" fields match.\n\t\t *\n\t\t * @since 5.0.0\n\t\t *\n\t\t * @return {Void}\n\t\t */\n\t\tbind_matching_fields: function() {\n\t\n\t\t\tvar $fields = $( 'input[data-match]' ).not( '[type=\"password\"]' );\n\t\n\t\t\t$fields.each( function() {\n\t\n\t\t\t\tvar $field = $( this ),\n\t\t\t\t\t$match = $( '#' + $field.attr( 'data-match' ) ),\n\t\t\t\t\t$parents;\n\t\n\t\t\t\tif ( $match.length ) {\n\t\n\t\t\t\t\t$parents = $field.closest( '.llms-form-field' ).add( $match.closest( '.llms-form-field' ) );\n\t\n\t\t\t\t\t$field.on( 'input change', function() {\n\t\n\t\t\t\t\t\tvar val_1 = $field.val(),\n\t\t\t\t\t\t\tval_2 = $match.val();\n\t\n\t\t\t\t\t\tif ( val_1 && val_2 && val_1 !== val_2 ) {\n\t\t\t\t\t\t\t$parents.addClass( 'invalid' );\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t$parents.removeClass( 'invalid' );\n\t\t\t\t\t\t}\n\t\n\t\t\t\t\t} );\n\t\n\t\t\t\t}\n\t\n\t\t\t} );\n\t\n\t\t},\n\t\n\t\t/**\n\t\t * Bind DOM events for voucher toggles UX.\n\t\t *\n\t\t * @since 5.0.0\n\t\t *\n\t\t * @return {void}\n\t\t */\n\t\tbind_voucher_field: function() {\n\t\n\t\t\t$( '#llms-voucher-toggle' ).on( 'click', function( e ) {\n\t\t\t\te.preventDefault();\n\t\t\t\t$( '#llms_voucher' ).toggle();\n\t\t\t} );\n\t\n\t\t},\n\t\n\t\t/**\n\t\t * Retrieve the parent element for a given field.\n\t\t *\n\t\t * The parent element is hidden when the field isn't required.\n\t\t * Looks for a WP column wrapper and falls back to the field's\n\t\t * wrapper div.\n\t\t *\n\t\t * @since 5.0.0\n\t\t *\n\t\t * @param {Object} $field jQuery dom object.\n\t\t * @return {Object}\n\t\t */\n\t\tget_field_parent: function( $field ) {\n\t\n\t\t\tvar $block = $field.closest( '.wp-block-column' );\n\t\t\tif ( $block.length ) {\n\t\t\t\treturn $block;\n\t\t\t}\n\t\n\t\t\treturn $field.closest( '.llms-form-field' );\n\t\n\t\t},\n\t\n\t\t/**\n\t\t * Retrieve the text of a label\n\t\t *\n\t\t * Removes any children HTML elements (eg: required span elements) and returns only the labels text.\n\t\t *\n\t\t * @since 5.0.0\n\t\t *\n\t\t * @param {Object} $label jQuery object for a label element.\n\t\t * @return {String}\n\t\t */\n\t\tget_label_text: function( $label ) {\n\t\n\t\t\tvar $clone = $label.clone();\n\t\t\t$clone.find( '*' ).remove();\n\t\t\treturn $clone.text().trim();\n\t\n\t\t},\n\t\n\t\t/**\n\t\t * Callback function to handle the \"toggle\" button links for changing email address and password on account edit forms\n\t\t *\n\t\t * @since 5.0.0\n\t\t *\n\t\t * @param {Object} event Native JS event object.\n\t\t * @return {void}\n\t\t */\n\t\thandle_toggle_click: function( event ) {\n\t\n\t\t\tevent.preventDefault();\n\t\n\t\t\tvar $this = $( this ),\n\t\t\t\t$fields = $( $( this ).attr( 'data-fields' ) ),\n\t\t\t\tisShowing = $this.attr( 'data-is-showing' ) || 'no',\n\t\t\t\tdisplayFunc = 'yes' === isShowing ? 'hide' : 'show',\n\t\t\t\tdisabled = 'yes' === isShowing ? 'disabled' : null,\n\t\t\t\ttextAttr = 'yes' === isShowing ? 'data-change-text' : 'data-cancel-text';\n\t\n\t\t\t$fields.each( function() {\n\t\n\t\t\t\t$( this ).closest( '.llms-form-field' )[ displayFunc ]();\n\t\t\t\t$( this ).attr( 'disabled', disabled );\n\t\n\t\t\t} );\n\t\n\t\t\t$this.text( $this.attr( textAttr ) );\n\t\t\t$this.attr( 'data-is-showing', 'yes' === isShowing ? 'no' : 'yes' );\n\t\n\t\t},\n\t\n\t\t/**\n\t\t * Prepares the state select field.\n\t\t *\n\t\t * Moves All optgroup elements into a hidden & disabled select element.\n\t\t *\n\t\t * @since 5.0.0\n\t\t *\n\t\t * @return {void}\n\t\t */\n\t\tprep_state_field: function() {\n\t\n\t\t\tvar $parent = this.$states.closest( '.llms-form-field' );\n\t\n\t\t\tthis.$holder = $( '',\n\t\t\t\t{ name: $field.attr('name'), class: $field.attr( 'class' ) + ' hidden', type: 'hidden' }\n\t\t\t).insertAfter( $field );\n\t\t\t$field.attr( 'disabled', 'disabled' );\n\t\t\tthis.get_field_parent( $field ).hide();\n\t\t},\n\t\n\t\t/**\n\t\t * Enable a given field\n\t\t *\n\t\t * It also shows the parent element, and removes the empty hidden input field\n\t\t * previously added by disable_field().\n\t\t *\n\t\t * @since 5.0.0\n\t\t *\n\t\t * @param {Object} $field The jQuery object for the field.\n\t\t */\n\t\tenable_field: function( $field ) {\n\t\t\t$field.removeAttr( 'disabled' );\n\t\t\t$field.next( '.hidden[name='+$field.attr('name')+']' ).detach();\n\t\t\tthis.get_field_parent( $field ).show();\n\t\t}\n\t\n\t};\n\t\n\t\t/**\n\t * Instructors List\n\t *\n\t * @package LifterLMS/Scripts\n\t *\n\t * @since Unknown\n\t * @version Unknown\n\t */\n\t\n\tLLMS.Instructors = {\n\t\n\t\t/**\n\t\t * Init\n\t\t */\n\t\tinit: function() {\n\t\n\t\t\tvar self = this;\n\t\n\t\t\tif ( $( 'body' ).hasClass( 'wp-admin' ) ) {\n\t\t\t\treturn;\n\t\t\t}\n\t\n\t\t\tif ( $( '.llms-instructors' ).length ) {\n\t\n\t\t\t\tLLMS.wait_for_matchHeight( function() {\n\t\t\t\t\tself.bind();\n\t\t\t\t} );\n\t\n\t\t\t}\n\t\n\t\t},\n\t\n\t\t/**\n\t\t * Bind Method\n\t\t * Handles dom binding on load\n\t\t *\n\t\t * @return {[type]} [description]\n\t\t */\n\t\tbind: function() {\n\t\n\t\t\t$( '.llms-instructors .llms-author' ).matchHeight();\n\t\n\t\t},\n\t\n\t};\n\t\n\t\t/**\n\t * Localization functions for LifterLMS Javascript\n\t *\n\t * @package LifterLMS/Scripts\n\t *\n\t * @since 2.7.3\n\t * @version 2.7.3\n\t *\n\t * @todo we need more robust translation functions to handle sprintf and pluralization\n\t * at this moment we don't need those and haven't stubbed them out\n\t * those will be added when they're needed\n\t */\n\t\n\tLLMS.l10n = LLMS.l10n || {};\n\t\n\tLLMS.l10n.translate = function ( string ) {\n\t\n\t\tvar self = this;\n\t\n\t\tif ( self.strings[string] ) {\n\t\n\t\t\treturn self.strings[string];\n\t\n\t\t} else {\n\t\n\t\t\treturn string;\n\t\n\t\t}\n\t\n\t};\n\t\n\t/**\n\t * Translate and replace placeholders in a string\n\t *\n\t * @example LLMS.l10n.replace( 'This is a %2$s %1$s String', {\n\t * \t'%1$s': 'cool',\n\t * \t\t\t'%2$s': 'very'\n\t * \t\t} );\n\t * \t\tOutput: \"This is a very cool String\"\n\t *\n\t * @param string string text string\n\t * @param object replacements object containing token => replacement pairs\n\t * @return string\n\t * @since 3.16.0\n\t * @version 3.16.0\n\t */\n\tLLMS.l10n.replace = function( string, replacements ) {\n\t\n\t\tvar str = this.translate( string );\n\t\n\t\t$.each( replacements, function( token, value ) {\n\t\n\t\t\tif ( -1 !== token.indexOf( 's' ) ) {\n\t\t\t\tvalue = value.toString();\n\t\t\t} else if ( -1 !== token.indexOf( 'd' ) ) {\n\t\t\t\tvalue = value * 1;\n\t\t\t}\n\t\n\t\t\tstr = str.replace( token, value );\n\t\n\t\t} );\n\t\n\t\treturn str;\n\t\n\t};\n\t\n\t\t/**\n\t * Handle Lesson Preview Elements\n\t *\n\t * @package LifterLMS/Scripts\n\t *\n\t * @since 3.0.0\n\t * @version 3.16.12\n\t */\n\t\n\tLLMS.LessonPreview = {\n\t\n\t\t/**\n\t\t * A jQuery object of all outlines present on the current screen\n\t\t *\n\t\t * @type obj\n\t\t */\n\t\t$els: null,\n\t\n\t\t/**\n\t\t * Initialize\n\t\t *\n\t\t * @return void\n\t\t */\n\t\tinit: function() {\n\t\n\t\t\tvar self = this;\n\t\n\t\t\tthis.$locked = $( 'a[href=\"#llms-lesson-locked\"]' );\n\t\n\t\t\tif ( this.$locked.length ) {\n\t\n\t\t\t\tself.bind();\n\t\n\t\t\t}\n\t\n\t\t\tif ( $( '.llms-course-navigation' ).length ) {\n\t\n\t\t\t\tLLMS.wait_for_matchHeight( function() {\n\t\n\t\t\t\t\tself.match_height();\n\t\n\t\t\t\t} );\n\t\n\t\t\t}\n\t\n\t\t},\n\t\n\t\t/**\n\t\t * Bind DOM events\n\t\t *\n\t\t * @return void\n\t\t * @since 3.0.0\n\t\t * @version 3.16.12\n\t\t */\n\t\tbind: function() {\n\t\n\t\t\tvar self = this;\n\t\n\t\t\tthis.$locked.on( 'click', function() {\n\t\t\t\treturn false;\n\t\t\t} );\n\t\n\t\t\tthis.$locked.on( 'mouseenter', function() {\n\t\n\t\t\t\tvar $tip = $( this ).find( '.llms-tooltip' );\n\t\t\t\tif ( ! $tip.length ) {\n\t\t\t\t\tvar msg = $( this ).attr( 'data-tooltip-msg' );\n\t\t\t\t\tif ( ! msg ) {\n\t\t\t\t\t\tmsg = LLMS.l10n.translate( 'You do not have permission to access this content' );\n\t\t\t\t\t}\n\t\t\t\t\t$tip = self.get_tooltip( msg );\n\t\t\t\t\t$( this ).append( $tip );\n\t\t\t\t}\n\t\t\t\tsetTimeout( function() {\n\t\t\t\t\t$tip.addClass( 'show' );\n\t\t\t\t}, 10 );\n\t\n\t\t\t} );\n\t\n\t\t\tthis.$locked.on( 'mouseleave', function() {\n\t\n\t\t\t\tvar $tip = $( this ).find( '.llms-tooltip' );\n\t\t\t\t$tip.removeClass( 'show' );\n\t\n\t\t\t} );\n\t\n\t\t},\n\t\n\t\t/**\n\t\t * Match the height of lesson preview items in course navigation blocks\n\t\t *\n\t\t * @return void\n\t\t * @since 3.0.0\n\t\t * @version 3.0.0\n\t\t */\n\t\tmatch_height: function() {\n\t\n\t\t\t$( '.llms-course-navigation .llms-lesson-link' ).matchHeight();\n\t\n\t\t},\n\t\n\t\t/**\n\t\t * Get a tooltip element\n\t\t *\n\t\t * @param string msg message to display inside the tooltip\n\t\t * @return obj\n\t\t * @since 3.0.0\n\t\t * @version 3.2.4\n\t\t */\n\t\tget_tooltip: function( msg ) {\n\t\t\tvar $el = $( '
' );\n\t\t\t$el.append( '
' + msg + '
' );\n\t\t\treturn $el;\n\t\t},\n\t\n\t};\n\t\n\t\t/**\n\t * LifterLMS Loops JS\n\t *\n\t * @package LifterLMS/Scripts\n\t *\n\t * @since 3.0.0\n\t * @version 3.14.0\n\t */\n\t\n\tLLMS.Loops = {\n\t\n\t\t/**\n\t\t * Initialize\n\t\t *\n\t\t * @return void\n\t\t */\n\t\tinit: function() {\n\t\n\t\t\tvar self = this;\n\t\n\t\t\tif ( $( '.llms-loop' ).length ) {\n\t\n\t\t\t\tLLMS.wait_for_matchHeight( function() {\n\t\n\t\t\t\t\tself.match_height();\n\t\n\t\t\t\t} );\n\t\n\t\t\t}\n\t\n\t\t},\n\t\n\t\t/**\n\t\t * Match the height of .llms-loop-item\n\t\t *\n\t\t * @return void\n\t\t * @since 3.0.0\n\t\t * @version 3.14.0\n\t\t */\n\t\tmatch_height: function() {\n\t\n\t\t\t$( '.llms-loop-item .llms-loop-item-content' ).matchHeight();\n\t\t\t$( '.llms-achievement-loop-item .llms-achievement' ).matchHeight();\n\t\t\t$( '.llms-certificate-loop-item .llms-certificate' ).matchHeight();\n\t\n\t\t},\n\t\n\t};\n\t\n\t\t/**\n\t * Handle the Collapsible Syllabus Widget / Shortcode\n\t *\n\t * @package LifterLMS/Scripts\n\t *\n\t * @since Unknown\n\t * @version Unknown\n\t */\n\t\n\tLLMS.OutlineCollapse = {\n\t\n\t\t/**\n\t\t * A jQuery object of all outlines present on the current screen\n\t\t *\n\t\t * @type obj\n\t\t */\n\t\t$outlines: null,\n\t\n\t\t/**\n\t\t * Initialize\n\t\t *\n\t\t * @return void\n\t\t */\n\t\tinit: function() {\n\t\n\t\t\tthis.$outlines = $( '.llms-widget-syllabus--collapsible' );\n\t\n\t\t\tif ( this.$outlines.length ) {\n\t\n\t\t\t\tthis.bind();\n\t\n\t\t\t}\n\t\n\t\t},\n\t\n\t\t/**\n\t\t * Bind DOM events\n\t\t *\n\t\t * @return void\n\t\t */\n\t\tbind: function() {\n\t\n\t\t\tvar self = this;\n\t\n\t\t\tthis.$outlines.each( function() {\n\t\n\t\t\t\tvar $outline = $( this ),\n\t\t\t\t\t$headers = $outline.find( '.llms-section .section-header' );\n\t\n\t\t\t\t// bind header clicks\n\t\t\t\t$headers.on( 'click', function( e ) {\n\t\n\t\t\t\t\te.preventDefault();\n\t\n\t\t\t\t\tvar $toggle = $( this ),\n\t\t\t\t\t\t$section = $toggle.closest( '.llms-section' ),\n\t\t\t\t\t\tstate = self.get_section_state( $section );\n\t\n\t\t\t\t\tswitch ( state ) {\n\t\n\t\t\t\t\t\tcase 'closed':\n\t\t\t\t\t\t\tself.open_section( $section );\n\t\t\t\t\t\tbreak;\n\t\n\t\t\t\t\t\tcase 'opened':\n\t\t\t\t\t\t\tself.close_section( $section );\n\t\t\t\t\t\tbreak;\n\t\n\t\t\t\t\t}\n\t\n\t\t\t\t} );\n\t\n\t\t\t\t// bind optional toggle \"buttons\"\n\t\t\t\t$outline.find( '.llms-collapse-toggle' ).on( 'click', function( e ) {\n\t\n\t\t\t\t\te.preventDefault();\n\t\n\t\t\t\t\tvar $btn = $( this ),\n\t\t\t\t\t\taction = $btn.attr( 'data-action' ),\n\t\t\t\t\t\topposite_action = ( 'close' === action ) ? 'opened' : 'closed';\n\t\n\t\t\t\t\t$headers.each( function() {\n\t\n\t\t\t\t\t\tvar $section = $( this ).closest( '.llms-section' ),\n\t\t\t\t\t\t\tstate = self.get_section_state( $section );\n\t\n\t\t\t\t\t\tif ( opposite_action !== state ) {\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t}\n\t\n\t\t\t\t\t\tswitch ( state ) {\n\t\n\t\t\t\t\t\t\tcase 'closed':\n\t\t\t\t\t\t\t\tself.close_section( $section );\n\t\t\t\t\t\t\tbreak;\n\t\n\t\t\t\t\t\t\tcase 'opened':\n\t\t\t\t\t\t\t\tself.open_section( $section );\n\t\t\t\t\t\t\tbreak;\n\t\n\t\t\t\t\t\t}\n\t\n\t\t\t\t\t\t$( this ).trigger( 'click' );\n\t\n\t\t\t\t\t} );\n\t\n\t\t\t\t} );\n\t\n\t\t\t} );\n\t\n\t\t},\n\t\n\t\t/**\n\t\t * Close an outline section\n\t\t *\n\t\t * @param obj $section jQuery selector of a '.llms-section'\n\t\t * @return void\n\t\t */\n\t\tclose_section: function( $section ) {\n\t\n\t\t\t$section.removeClass( 'llms-section--opened' ).addClass( 'llms-section--closed' );\n\t\n\t\t},\n\t\n\t\t/**\n\t\t * Open an outline section\n\t\t *\n\t\t * @param obj $section jQuery selector of a '.llms-section'\n\t\t * @return void\n\t\t */\n\t\topen_section: function( $section ) {\n\t\n\t\t\t$section.removeClass( 'llms-section--closed' ).addClass( 'llms-section--opened' );\n\t\n\t\t},\n\t\n\t\t/**\n\t\t * Get the current state (open or closed) of an outline section\n\t\t *\n\t\t * @param obj $section jQuery selector of a '.llms-section'\n\t\t * @return string 'opened' or 'closed'\n\t\t */\n\t\tget_section_state: function( $section ) {\n\t\n\t\t\treturn $section.hasClass( 'llms-section--opened' ) ? 'opened' : 'closed';\n\t\n\t\t}\n\t\n\t};\n\t\n\t\t/**\n\t * Handle Password Strength Meter for registration and password update fields\n\t *\n\t * @package LifterLMS/Scripts\n\t *\n\t * @since 3.0.0\n\t * @version 5.0.0\n\t */\n\t\n\t$.extend( LLMS.PasswordStrength, {\n\t\n\t\t/**\n\t\t * jQuery ref for the password strength meter object.\n\t\t *\n\t\t * @type {Object}\n\t\t */\n\t\t$meter: $( '.llms-password-strength-meter' ),\n\t\n\t\t/**\n\t\t * jQuery ref for the password field.\n\t\t *\n\t\t * @type {Object}\n\t\t */\n\t\t$pass: null,\n\t\n\t\t/**\n\t\t * jQuery ref for the password confirmation field\n\t\t *\n\t\t * @type {Object}\n\t\t */\n\t\t$conf: null,\n\t\n\t\t/**\n\t\t * jQuery ref for form element.\n\t\t *\n\t\t * @type {Object}\n\t\t */\n\t\t$form: null,\n\t\n\t\t/**\n\t\t * Init\n\t\t * loads class methods\n\t\t *\n\t\t * @since 3.0.0\n\t\t * @since 3.7.0 Unknown\n\t\t * @since 5.0.0 Move reference setup to `setup_references()`.\n\t\t * Use `LLMS.wait_for()` for dependency waiting.\n\t\t *\n\t\t * @return {Void}\n\t\t */\n\t\tinit: function() {\n\t\n\t\t\tif ( $( 'body' ).hasClass( 'wp-admin' ) ) {\n\t\t\t\treturn;\n\t\t\t}\n\t\n\t\t\tif ( ! this.setup_references() ) {\n\t\t\t\treturn;\n\t\t\t}\n\t\n\t\t\tvar self = this;\n\t\n\t\t\tLLMS.wait_for( function() {\n\t\t\t\treturn ( 'undefined' !== typeof wp && 'undefined' !== typeof wp.passwordStrength );\n\t\t\t}, function() {\n\t\t\t\tself.bind();\n\t\t\t\tself.$form.trigger( 'llms-password-strength-ready' );\n\t\t\t} );\n\t\n\t\t},\n\t\n\t\t/**\n\t\t * Bind DOM Events\n\t\t *\n\t\t * @since 3.0.0\n\t\t *\n\t\t * @return void\n\t\t */\n\t\tbind: function() {\n\t\n\t\t\tvar self = this;\n\t\n\t\t\t// add submission event handlers when not on a checkout form\n\t\t\tif ( ! this.$form.hasClass( 'llms-checkout' ) ) {\n\t\t\t\tself.$form.on( 'submit', self, self.submit );\n\t\t\t}\n\t\n\t\t\t// check password strength on keyup\n\t\t\tself.$pass.add( self.$conf ).on( 'keyup', function() {\n\t\t\t\tself.check_strength();\n\t\t\t} );\n\t\n\t\t},\n\t\n\t\t/**\n\t\t * Check the strength of a user entered password\n\t\t * and update elements depending on the current strength\n\t\t *\n\t\t * @since 3.0.0\n\t\t * @since 5.0.0 Allow password confirmation to be optional when checking strength.\n\t\t *\n\t\t * @return void\n\t\t */\n\t\tcheck_strength: function() {\n\t\n\t\t\tvar $pass_field = this.$pass.closest( '.llms-form-field' ),\n\t\t\t\t$conf_field = this.$conf && this.$conf.length ? this.$conf.closest( '.llms-form-field' ) : null,\n\t\t\t\tpass_length = this.$pass.val().length,\n\t\t\t\tconf_length = this.$conf && this.$conf.length ? this.$conf.val().length : 0;\n\t\n\t\t\t// hide the meter if both fields are empty\n\t\t\tif ( ! pass_length && ! conf_length ) {\n\t\t\t\t$pass_field.removeClass( 'valid invalid' );\n\t\t\t\tif ( $conf_field ) {\n\t\t\t\t\t$conf_field.removeClass( 'valid invalid' );\n\t\t\t\t}\n\t\t\t\tthis.$meter.hide();\n\t\t\t\treturn;\n\t\t\t}\n\t\n\t\t\tif ( this.get_current_strength_status() ) {\n\t\t\t\t$pass_field.removeClass( 'invalid' ).addClass( 'valid' );\n\t\t\t\tif ( conf_length ) {\n\t\t\t\t\t$conf_field.removeClass( 'invalid' ).addClass( 'valid' );\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t$pass_field.removeClass( 'valid' ).addClass( 'invalid' );\n\t\t\t\tif ( conf_length ) {\n\t\t\t\t\t$conf_field.removeClass( 'valid' ).addClass( 'invalid' );\n\t\t\t\t}\n\t\t\t}\n\t\n\t\t\tthis.$meter.removeClass( 'too-short very-weak weak medium strong mismatch' );\n\t\t\tthis.$meter.show().addClass( this.get_current_strength( 'slug' ) );\n\t\t\tthis.$meter.html( this.get_current_strength( 'text' ) );\n\t\n\t\t},\n\t\n\t\t/**\n\t\t * Form submission action called during registration on checkout screen\n\t\t *\n\t\t * @since 3.0.0\n\t\t *\n\t\t * @param obj self instance of this class\n\t\t * @param Function callback callback function, passes error message or success back to checkout handler\n\t\t * @return void\n\t\t */\n\t\tcheckout: function( self, callback ) {\n\t\n\t\t\tif ( self.get_current_strength_status() ) {\n\t\n\t\t\t\tcallback( true );\n\t\n\t\t\t} else {\n\t\n\t\t\t\tcallback( LLMS.l10n.translate( 'There is an issue with your chosen password.' ) );\n\t\n\t\t\t}\n\t\t},\n\t\n\t\t/**\n\t\t * Get the list of blocklisted strings\n\t\t *\n\t\t * @since 5.0.0\n\t\t *\n\t\t * @return array\n\t\t */\n\t\tget_blocklist: function() {\n\t\n\t\t\t// Default values from WP Core + any values added via settings filter..\n\t\t\tvar blocklist = wp.passwordStrength.userInputDisallowedList().concat( this.get_setting( 'blocklist', [] ) );\n\t\n\t\t\t// Add values from all text fields in the form.\n\t\t\tthis.$form.find( 'input[type=\"text\"], input[type=\"email\"], input[type=\"tel\"], input[type=\"number\"]' ).each( function() {\n\t\t\t\tvar val = $( this ).val();\n\t\t\t\tif ( val ) {\n\t\t\t\t\tblocklist.push( val );\n\t\t\t\t}\n\t\t\t} );\n\t\n\t\t\treturn blocklist;\n\t\n\t\t},\n\t\n\t\t/**\n\t\t * Retrieve current strength as a number, a slug, or a translated text string\n\t\t *\n\t\t * @since 3.0.0\n\t\t * @since 5.0.0 Allow password confirmation to be optional when checking strength.\n\t\t *\n\t\t * @param {String} format Derived return format [int|slug|text] defaults to int.\n\t\t * @return mixed\n\t\t */\n\t\tget_current_strength: function( format ) {\n\t\n\t\t\tformat = format || 'int';\n\t\t\tvar pass = this.$pass.val(),\n\t\t\t\tconf = this.$conf && this.$conf.length ? this.$conf.val() : '',\n\t\t\t\tval;\n\t\n\t\t\t// enforce custom length requirement\n\t\t\tif ( pass.length < this.get_setting( 'min_length', 6 ) ) {\n\t\t\t\tval = -1;\n\t\t\t} else {\n\t\t\t\tval = wp.passwordStrength.meter( pass, this.get_blocklist(), conf );\n\t\t\t\t// 0 & 1 are both very-weak\n\t\t\t\tif ( 0 === val ) {\n\t\t\t\t\tval = 1;\n\t\t\t\t}\n\t\t\t}\n\t\n\t\t\tif ( 'slug' === format ) {\n\t\t\t\treturn this.get_strength_slug( val );\n\t\t\t} else if ( 'text' === format ) {\n\t\t\t\treturn this.get_strength_text( val );\n\t\t\t} else {\n\t\t\t\treturn val;\n\t\t\t}\n\t\t},\n\t\n\t\t/**\n\t\t * Determines if the current password strength meets the user-defined\n\t\t * minimum password strength requirements\n\t\t *\n\t\t * @since 3.0.0\n\t\t *\n\t\t * @return boolean\n\t\t */\n\t\tget_current_strength_status: function() {\n\t\t\tvar curr = this.get_current_strength(),\n\t\t\t\tmin = this.get_strength_value( this.get_minimum_strength() );\n\t\t\treturn ( 5 === curr ) ? false : ( curr >= min );\n\t\t},\n\t\n\t\t/**\n\t\t * Retrieve the minimum password strength for the current form.\n\t\t *\n\t\t * @since 3.0.0\n\t\t * @since 5.0.0 Replaces the version output via an inline PHP script in favor of utilizing values configured in the settings object.\n\t\t *\n\t\t * @return {string}\n\t\t */\n\t\tget_minimum_strength: function() {\n\t\t\treturn this.get_setting( 'min_strength', 'strong' );\n\t\t},\n\t\n\t\t/**\n\t\t * Get a setting and fallback to a default value.\n\t\t *\n\t\t * @since 5.0.0\n\t\t *\n\t\t * @param {String} key Setting key.\n\t\t * @param {mixed} default_val Default value when the requested setting cannot be located.\n\t\t * @return {mixed}\n\t\t */\n\t\tget_setting: function( key, default_val ) {\n\t\t\tvar settings = this.get_settings();\n\t\t\treturn settings[ key ] ? settings[ key ] : default_val;\n\t\t},\n\t\n\t\t/**\n\t\t * Get the slug associated with a strength value\n\t\t *\n\t\t * @since 3.0.0\n\t\t *\n\t\t * @param int strength_val Strength value number.\n\t\t * @return string\n\t\t */\n\t\tget_strength_slug: function( strength_val ) {\n\t\n\t\t\tvar slugs = {\n\t\t\t\t'-1': 'too-short',\n\t\t\t\t1: 'very-weak',\n\t\t\t\t2: 'weak',\n\t\t\t\t3: 'medium',\n\t\t\t\t4: 'strong',\n\t\t\t\t5: 'mismatch',\n\t\t\t};\n\t\n\t\t\treturn ( slugs[ strength_val ] ) ? slugs[ strength_val ] : slugs[5];\n\t\n\t\t},\n\t\n\t\t/**\n\t\t * Gets the translated text associated with a strength value\n\t\t *\n\t\t * @since 3.0.0\n\t\t *\n\t\t * @param {Integer} strength_val Strength value\n\t\t * @return {String}\n\t\t */\n\t\tget_strength_text: function( strength_val ) {\n\t\n\t\t\tvar texts = {\n\t\t\t\t'-1': LLMS.l10n.translate( 'Too Short' ),\n\t\t\t\t1: LLMS.l10n.translate( 'Very Weak' ),\n\t\t\t\t2: LLMS.l10n.translate( 'Weak' ),\n\t\t\t\t3: LLMS.l10n.translate( 'Medium' ),\n\t\t\t\t4: LLMS.l10n.translate( 'Strong' ),\n\t\t\t\t5: LLMS.l10n.translate( 'Mismatch' ),\n\t\t\t};\n\t\n\t\t\treturn ( texts[ strength_val ] ) ? texts[ strength_val ] : texts[5];\n\t\n\t\t},\n\t\n\t\t/**\n\t\t * Get the value associated with a strength slug\n\t\t *\n\t\t * @since 3.0.0\n\t\t *\n\t\t * @param string strength_slug A strength slug.\n\t\t * @return {Integer}\n\t\t */\n\t\tget_strength_value: function( strength_slug ) {\n\t\n\t\t\tvar values = {\n\t\t\t\t'too-short': -1,\n\t\t\t\t'very-weak': 1,\n\t\t\t\tweak: 2,\n\t\t\t\tmedium: 3,\n\t\t\t\tstrong: 4,\n\t\t\t\tmismatch: 5,\n\t\t\t};\n\t\n\t\t\treturn ( values[ strength_slug ] ) ? values[ strength_slug ] : values.mismatch;\n\t\n\t\t},\n\t\n\t\t/**\n\t\t * Setup jQuery references to DOM elements needed to power the password meter.\n\t\t *\n\t\t * @since 5.0.0\n\t\t *\n\t\t * @return {Boolean} Returns `true` if a meter element and password field are found, otherwise returns `false`.\n\t\t */\n\t\tsetup_references: function() {\n\t\n\t\t\tif ( ! this.$meter.length ) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\n\t\t\tthis.$form = this.$meter.closest( 'form' );\n\t\t\tthis.$pass = this.$form.find( 'input#password' );\n\t\n\t\t\tif ( this.$pass.length && this.$pass.attr( 'data-match' ) ) {\n\t\t\t\tthis.$conf = this.$form.find( '#' + this.$pass.attr( 'data-match' ) );\n\t\t\t}\n\t\n\t\t\treturn ( this.$pass.length > 0 );\n\t\n\t\t},\n\t\n\t\t/**\n\t\t * Form submission handler for registration and update forms\n\t\t *\n\t\t * @since 3.0.0\n\t\t * @since 5.0.0 Allow the account edit for to bypass strength checking when the password field is disabled (not being submitted).\n\t\t *\n\t\t * @param obj e Event data.\n\t\t * @return void\n\t\t */\n\t\tsubmit: function( e ) {\n\t\n\t\t\tvar self = e.data;\n\t\t\te.preventDefault();\n\t\t\tself.$pass.trigger( 'keyup' );\n\t\n\t\t\t// Meets the status requirements OR we're on the account edit form and the password field is disabled.\n\t\t\tif ( self.get_current_strength_status() || ( self.$form.hasClass( 'edit-account' ) && 'disabled' === self.$pass.attr( 'disabled' ) ) ) {\n\t\t\t\tself.$form.off( 'submit', self.submit );\n\t\t\t\tself.$form.trigger( 'submit' );\n\t\t\t} else {\n\t\t\t\t$( 'html, body' ).animate( {\n\t\t\t\t\tscrollTop: self.$meter.offset().top - 100,\n\t\t\t\t}, 200 );\n\t\t\t\tself.$meter.hide();\n\t\t\t\tsetTimeout( function() {\n\t\t\t\t\tself.$meter.fadeIn( 400 );\n\t\t\t\t}, 220 );\n\t\t\t}\n\t\t},\n\t\n\t\t/**\n\t\t * Get the list of blocklist strings\n\t\t *\n\t\t * @since 3.0.0\n\t\t * @deprecated 5.0.0 `LLMS.PasswordStrength.get_blacklist()` is deprecated in favor of `LLMS.PasswordStrength.get_blocklist()`.\n\t\t *\n\t\t * @return array\n\t\t */\n\t\tget_blacklist: function() {\n\t\t\tconsole.log( 'Method `get_blacklist()` is deprecated in favor of `get_blocklist()`.' );\n\t\t\treturn this.get_blacklist();\n\t\t},\n\t\n\t} );\n\t\n\t\t/**\n\t * Pricing Table UI\n\t *\n\t * @package LifterLMS/Scripts\n\t *\n\t * @since Unknown.\n\t * @version Unknown.\n\t */\n\t\n\tLLMS.Pricing_Tables = {\n\t\n\t\t/**\n\t\t * Init\n\t\t */\n\t\tinit: function() {\n\t\n\t\t\tvar self = this;\n\t\n\t\t\tif ( $( 'body' ).hasClass( 'wp-admin' ) ) {\n\t\t\t\treturn;\n\t\t\t}\n\t\n\t\t\tif ( $( '.llms-access-plans' ).length ) {\n\t\n\t\t\t\tLLMS.wait_for_matchHeight( function() {\n\t\t\t\t\tself.bind();\n\t\t\t\t} );\n\t\n\t\t\t\tthis.$locked = $( 'a[href=\"#llms-plan-locked\"]' );\n\t\n\t\t\t\tif ( this.$locked.length ) {\n\t\n\t\t\t\t\tLLMS.wait_for_popover( function() {\n\t\t\t\t\t\tself.bind_locked();\n\t\t\t\t\t} );\n\t\n\t\t\t\t}\n\t\n\t\t\t}\n\t\n\t\t},\n\t\n\t\t/**\n\t\t * Bind Method\n\t\t * Handles dom binding on load\n\t\t *\n\t\t * @return {[type]} [description]\n\t\t */\n\t\tbind: function() {\n\t\n\t\t\t$( '.llms-access-plan-content' ).matchHeight();\n\t\t\t$( '.llms-access-plan-pricing.trial' ).matchHeight();\n\t\n\t\t},\n\t\n\t\t/**\n\t\t * Setup a popover for members-only restricted plans\n\t\t *\n\t\t * @return void\n\t\t * @since 3.0.0\n\t\t * @version 3.9.1\n\t\t */\n\t\tbind_locked: function() {\n\t\n\t\t\tthis.$locked.each( function() {\n\t\n\t\t\t\t$( this ).webuiPopover( {\n\t\t\t\t\tanimation: 'pop',\n\t\t\t\t\tcloseable: true,\n\t\t\t\t\tcontent: function( e ) {\n\t\t\t\t\t\tvar $content = $( '
' );\n\t\t\t\t\t\t$content.append( e.$element.closest( '.llms-access-plan' ).find( '.llms-access-plan-restrictions ul' ).clone() );\n\t\t\t\t\t\treturn $content;\n\t\t\t\t\t},\n\t\t\t\t\tplacement: 'top',\n\t\t\t\t\tstyle: 'inverse',\n\t\t\t\t\ttitle: LLMS.l10n.translate( 'Members Only Pricing' ),\n\t\t\t\t\twidth: '280px',\n\t\t\t\t} );\n\t\n\t\t\t} );\n\t\n\t\t},\n\t\n\t};\n\t\n\t\t/**\n\t * LifterLMS Reviews JS\n\t *\n\t * @package LifterLMS/Scripts\n\t *\n\t * @since Unknown\n\t * @version Unknown\n\t */\n\t\n\tLLMS.Review = {\n\t\t/**\n\t\t * Init\n\t\t * loads class methods\n\t\t */\n\t\tinit: function() {\n\t\t\t// console.log('Initializing Review ');\n\t\t\tthis.bind();\n\t\t},\n\t\n\t\t/**\n\t\t * This function binds actions to the appropriate hooks\n\t\t */\n\t\tbind: function() {\n\t\t\t$( '#llms_review_submit_button' ).click(function()\n\t\t\t\t{\n\t\t\t\tif ($( '#review_title' ).val() !== '' && $( '#review_text' ).val() !== '') {\n\t\t\t\t\tjQuery.ajax({\n\t\t\t\t\t\ttype : 'post',\n\t\t\t\t\t\tdataType : 'json',\n\t\t\t\t\t\turl : window.llms.ajaxurl,\n\t\t\t\t\t\tdata : {\n\t\t\t\t\t\t\taction : 'LLMSSubmitReview',\n\t\t\t\t\t\t\treview_title: $( '#review_title' ).val(),\n\t\t\t\t\t\t\treview_text: $( '#review_text' ).val(),\n\t\t\t\t\t\t\tpageID : $( '#post_ID' ).val()\n\t\t\t\t\t\t},\n\t\t\t\t\t\tsuccess: function()\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tconsole.log( 'Review success' );\n\t\t\t\t\t\t\t$( '#review_box' ).hide( 'swing' );\n\t\t\t\t\t\t\t$( '#thank_you_box' ).show( 'swing' );\n\t\t\t\t\t\t},\n\t\t\t\t\t\terror: function(jqXHR, textStatus, errorThrown )\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tconsole.log( jqXHR );\n\t\t\t\t\t\t\tconsole.log( textStatus );\n\t\t\t\t\t\t\tconsole.log( errorThrown );\n\t\t\t\t\t\t},\n\t\t\t\t\t});\n\t\t\t\t} else {\n\t\t\t\t\tif ($( '#review_title' ).val() === '') {\n\t\t\t\t\t\t$( '#review_title_error' ).show( 'swing' );\n\t\t\t\t\t} else {\n\t\t\t\t\t\t$( '#review_title_error' ).hide( 'swing' );\n\t\t\t\t\t}\n\t\t\t\t\tif ($( '#review_text' ).val() === '') {\n\t\t\t\t\t\t$( '#review_text_error' ).show( 'swing' );\n\t\t\t\t\t} else {\n\t\t\t\t\t\t$( '#review_text_error' ).hide( 'swing' );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\t\tif ( $( '#_llms_display_reviews' ).attr( 'checked' ) ) {\n\t\t\t\t$( '.llms-num-reviews-top' ).addClass( 'top' );\n\t\t\t\t$( '.llms-num-reviews-bottom' ).show();\n\t\n\t\t\t} else {\n\t\t\t\t$( '.llms-num-reviews-bottom' ).hide();\n\t\t\t}\n\t\t\t$( '#_llms_display_reviews' ).change(function() {\n\t\t\t\tif ( $( '#_llms_display_reviews' ).attr( 'checked' ) ) {\n\t\t\t\t\t$( '.llms-num-reviews-top' ).addClass( 'top' );\n\t\t\t\t\t$( '.llms-num-reviews-bottom' ).show();\n\t\t\t\t} else {\n\t\t\t\t\t$( '.llms-num-reviews-top' ).removeClass( 'top' );\n\t\t\t\t\t$( '.llms-num-reviews-bottom' ).hide();\n\t\t\t\t}\n\t\t\t});\n\t\n\t\t},\n\t};\n\t\n\t\t/**\n\t * Add Spinners for AJAX events\n\t *\n\t * @package LifterLMS/Scripts\n\t *\n\t * @since 3.0.0\n\t * @version 3.0.0\n\t */\n\t\n\tLLMS.Spinner = {\n\t\n\t\t/**\n\t\t * Get an exiting spinner element or create a new one\n\t\t *\n\t\t * @param obj $el jQuery selector of the parent element that should hold and be mased by a spinner\n\t\t * @param string size size or the spinner [default|small]\n\t\t * default is 40px\n\t\t * small is 20px\n\t\t * @return obj\n\t\t * @since 3.0.0\n\t\t * @version 3.0.0\n\t\t */\n\t\tget: function( $el, size ) {\n\t\n\t\t\t// look for an existing spinner\n\t\t\tvar $spinner = $el.find( '.llms-spinning' ).first();\n\t\n\t\t\t// no spinner inside $el\n\t\t\tif ( ! $spinner.length ) {\n\t\n\t\t\t\tsize = ( size ) ? size : 'default';\n\t\n\t\t\t\t// create the spinner\n\t\t\t\t$spinner = $( '
' );\n\t\n\t\t\t\t// add it to the dom\n\t\t\t\t$el.append( $spinner );\n\t\n\t\t\t}\n\t\n\t\t\t// return it\n\t\t\treturn $spinner;\n\t\n\t\t},\n\t\n\t\t/**\n\t\t * Start spinner(s) inr=side a given element\n\t\t * Creates them if they don't exist!\n\t\t *\n\t\t * @param obj $el jQuery selector of the parent element that should hold and be mased by a spinner\n\t\t * @param string size size or the spinner [default|small]\n\t\t * default is 40px\n\t\t * small is 20px\n\t\t * @return void\n\t\t * @since 3.0.0\n\t\t * @version 3.0.0\n\t\t */\n\t\tstart: function( $el, size ) {\n\t\n\t\t\tvar self = this;\n\t\n\t\t\t$el.each( function() {\n\t\n\t\t\t\tself.get( $( this ), size ).show();\n\t\n\t\t\t} );\n\t\n\t\t},\n\t\n\t\t/**\n\t\t * Store spinners within an element\n\t\t *\n\t\t * @param obj $el jQuery selector of the parent element that should hold and be mased by a spinner\n\t\t * @return void\n\t\t * @since 3.0.0\n\t\t * @version 3.0.0\n\t\t */\n\t\tstop: function( $el ) {\n\t\n\t\t\tvar self = this;\n\t\n\t\t\t$el.each( function() {\n\t\n\t\t\t\tself.get( $( this ) ).hide();\n\t\n\t\t\t} );\n\t\n\t\t}\n\t\n\t};\n\t\n\t\t/* global LLMS, $ */\n\t\n\t/*!\n\t * JavaScript Cookie v2.2.1\n\t * https://github.com/js-cookie/js-cookie\n\t *\n\t * Copyright 2006, 2015 Klaus Hartl & Fagner Brack\n\t * Released under the MIT license\n\t */\n\t;(function (factory) {\n\t\tvar registeredInModuleLoader;\n\t\tif (typeof define === 'function' && define.amd) {\n\t\t\tdefine(factory);\n\t\t\tregisteredInModuleLoader = true;\n\t\t}\n\t\tif (typeof exports === 'object') {\n\t\t\tmodule.exports = factory();\n\t\t\tregisteredInModuleLoader = true;\n\t\t}\n\t\tif (!registeredInModuleLoader) {\n\t\t\tvar OldCookies = window.Cookies;\n\t\t\tvar api = window.Cookies = factory();\n\t\t\tapi.noConflict = function () {\n\t\t\t\twindow.Cookies = OldCookies;\n\t\t\t\treturn api;\n\t\t\t};\n\t\t}\n\t}(function () {\n\t\tfunction extend () {\n\t\t\tvar i = 0;\n\t\t\tvar result = {};\n\t\t\tfor (; i < arguments.length; i++) {\n\t\t\t\tvar attributes = arguments[ i ];\n\t\t\t\tfor (var key in attributes) {\n\t\t\t\t\tresult[key] = attributes[key];\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn result;\n\t\t}\n\t\n\t\tfunction decode (s) {\n\t\t\treturn s.replace(/(%[0-9A-Z]{2})+/g, decodeURIComponent);\n\t\t}\n\t\n\t\tfunction init (converter) {\n\t\t\tfunction api() {}\n\t\n\t\t\tfunction set (key, value, attributes) {\n\t\t\t\tif (typeof document === 'undefined') {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\n\t\t\t\tattributes = extend({\n\t\t\t\t\tpath: '/'\n\t\t\t\t}, api.defaults, attributes);\n\t\n\t\t\t\tif (typeof attributes.expires === 'number') {\n\t\t\t\t\tattributes.expires = new Date(new Date() * 1 + attributes.expires * 864e+5);\n\t\t\t\t}\n\t\n\t\t\t\t// We're using \"expires\" because \"max-age\" is not supported by IE\n\t\t\t\tattributes.expires = attributes.expires ? attributes.expires.toUTCString() : '';\n\t\n\t\t\t\ttry {\n\t\t\t\t\tvar result = JSON.stringify(value);\n\t\t\t\t\tif (/^[\\{\\[]/.test(result)) {\n\t\t\t\t\t\tvalue = result;\n\t\t\t\t\t}\n\t\t\t\t} catch (e) {}\n\t\n\t\t\t\tvalue = converter.write ?\n\t\t\t\t\tconverter.write(value, key) :\n\t\t\t\t\tencodeURIComponent(String(value))\n\t\t\t\t\t\t.replace(/%(23|24|26|2B|3A|3C|3E|3D|2F|3F|40|5B|5D|5E|60|7B|7D|7C)/g, decodeURIComponent);\n\t\n\t\t\t\tkey = encodeURIComponent(String(key))\n\t\t\t\t\t.replace(/%(23|24|26|2B|5E|60|7C)/g, decodeURIComponent)\n\t\t\t\t\t.replace(/[\\(\\)]/g, escape);\n\t\n\t\t\t\tvar stringifiedAttributes = '';\n\t\t\t\tfor (var attributeName in attributes) {\n\t\t\t\t\tif (!attributes[attributeName]) {\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tstringifiedAttributes += '; ' + attributeName;\n\t\t\t\t\tif (attributes[attributeName] === true) {\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\n\t\t\t\t\t// Considers RFC 6265 section 5.2:\n\t\t\t\t\t// ...\n\t\t\t\t\t// 3. If the remaining unparsed-attributes contains a %x3B (\";\")\n\t\t\t\t\t// character:\n\t\t\t\t\t// Consume the characters of the unparsed-attributes up to,\n\t\t\t\t\t// not including, the first %x3B (\";\") character.\n\t\t\t\t\t// ...\n\t\t\t\t\tstringifiedAttributes += '=' + attributes[attributeName].split(';')[0];\n\t\t\t\t}\n\t\n\t\t\t\treturn (document.cookie = key + '=' + value + stringifiedAttributes);\n\t\t\t}\n\t\n\t\t\tfunction get (key, json) {\n\t\t\t\tif (typeof document === 'undefined') {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\n\t\t\t\tvar jar = {};\n\t\t\t\t// To prevent the for loop in the first place assign an empty array\n\t\t\t\t// in case there are no cookies at all.\n\t\t\t\tvar cookies = document.cookie ? document.cookie.split('; ') : [];\n\t\t\t\tvar i = 0;\n\t\n\t\t\t\tfor (; i < cookies.length; i++) {\n\t\t\t\t\tvar parts = cookies[i].split('=');\n\t\t\t\t\tvar cookie = parts.slice(1).join('=');\n\t\n\t\t\t\t\tif (!json && cookie.charAt(0) === '\"') {\n\t\t\t\t\t\tcookie = cookie.slice(1, -1);\n\t\t\t\t\t}\n\t\n\t\t\t\t\ttry {\n\t\t\t\t\t\tvar name = decode(parts[0]);\n\t\t\t\t\t\tcookie = (converter.read || converter)(cookie, name) ||\n\t\t\t\t\t\t\tdecode(cookie);\n\t\n\t\t\t\t\t\tif (json) {\n\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\tcookie = JSON.parse(cookie);\n\t\t\t\t\t\t\t} catch (e) {}\n\t\t\t\t\t\t}\n\t\n\t\t\t\t\t\tjar[name] = cookie;\n\t\n\t\t\t\t\t\tif (key === name) {\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t} catch (e) {}\n\t\t\t\t}\n\t\n\t\t\t\treturn key ? jar[key] : jar;\n\t\t\t}\n\t\n\t\t\tapi.set = set;\n\t\t\tapi.get = function (key) {\n\t\t\t\treturn get(key, false /* read as raw */);\n\t\t\t};\n\t\t\tapi.getJSON = function (key) {\n\t\t\t\treturn get(key, true /* read as json */);\n\t\t\t};\n\t\t\tapi.remove = function (key, attributes) {\n\t\t\t\tset(key, '', extend(attributes, {\n\t\t\t\t\texpires: -1\n\t\t\t\t}));\n\t\t\t};\n\t\n\t\t\tapi.defaults = {};\n\t\n\t\t\tapi.withConverter = init;\n\t\n\t\t\treturn api;\n\t\t}\n\t\n\t\treturn init(function () {});\n\t}));\n\t\n\t/**\n\t * Create a no conflict reference to JS Cookies.\n\t *\n\t * @type {Object}\n\t */\n\tLLMS.CookieStore = Cookies.noConflict();\n\t\n\t/**\n\t * Store information in Local Storage by group.\n\t *\n\t * @since 3.36.0\n\t * @since 3.37.14 Use persistent reference to JS Cookies.\n\t * @since 4.2.0 Set sameSite to `strict` for cookies.\n\t *\n\t * @param string group Storage group id/name.\n\t */\n\tLLMS.Storage = function( group ) {\n\t\n\t\tvar self = this,\n\t\t\tstore = LLMS.CookieStore;\n\t\n\t\t/**\n\t\t * Clear all data for the group.\n\t\t *\n\t\t * @since 3.36.0\n\t\t *\n\t\t * @return void\n\t\t */\n\t\tthis.clearAll = function() {\n\t\t\tstore.remove( group );\n\t\t};\n\t\n\t\t/**\n\t\t * Clear a single item from the group by key.\n\t\t *\n\t\t * @since 3.36.0\n\t\t *\n\t\t * @return obj\n\t\t */\n\t\tthis.clear = function( key ) {\n\t\t\tvar data = self.getAll();\n\t\t\tdelete data[ key ];\n\t\t\treturn store.set( group, data );\n\t\t};\n\t\n\t\t/**\n\t\t * Retrieve (and parse) all data stored for the group.\n\t\t *\n\t\t * @since 3.36.0\n\t\t *\n\t\t * @return obj\n\t\t */\n\t\tthis.getAll = function() {\n\t\t\treturn store.getJSON( group ) || {};\n\t\t}\n\t\n\t\t/**\n\t\t * Retrieve an item from the group by key.\n\t\t *\n\t\t * @since 3.36.0\n\t\t *\n\t\t * @param string key Item key/name.\n\t\t * @param mixed default_val Item default value to be returned when item not found in the group.\n\t\t * @return mixed\n\t\t */\n\t\tthis.get = function( key, default_val ) {\n\t\t\tvar data = self.getAll();\n\t\t\treturn data[ key ] ? data[ key ] : default_val;\n\t\t}\n\t\n\t\t/**\n\t\t * Store an item in the group by key.\n\t\t *\n\t\t * @since 3.36.0\n\t\t * @since 4.2.0 Set sameSite to `strict` for cookies.\n\t\t *\n\t\t * @param string key Item key name.\n\t\t * @param mixed val Item value\n\t\t * @return obj\n\t\t */\n\t\tthis.set = function( key, val ) {\n\t\t\tvar data = self.getAll();\n\t\t\tdata[ key ] = val;\n\t\t\treturn store.set( group, data, { sameSite: 'strict' } );\n\t\t};\n\t\n\t}\n\t\n\t\t/**\n\t * Student Dashboard related JS\n\t *\n\t * @package LifterLMS/Scripts\n\t *\n\t * @since 3.7.0\n\t * @since 3.10.0 Bind events on the orders screen.\n\t * @since 5.0.0 Removed redundant password toggle logic for edit account screen.\n\t * @version 5.0.0\n\t */\n\tLLMS.StudentDashboard = {\n\t\n\t\t/**\n\t\t * Slug for the current screen/endpoint\n\t\t *\n\t\t * @type {String}\n\t\t */\n\t\tscreen: '',\n\t\n\t\t/**\n\t\t * Init\n\t\t *\n\t\t * @since 3.7.0\n\t\t * @since 3.10.0 Unknown\n\t\t * @since 5.0.0 Removed password toggle logic.\n\t\t *\n\t\t * @return void\n\t\t */\n\t\tinit: function() {\n\t\n\t\t\tif ( $( '.llms-student-dashboard' ).length ) {\n\t\t\t\tthis.bind();\n\t\t\t\tif ( 'orders' === this.get_screen() ) {\n\t\t\t\t\tthis.bind_orders();\n\t\t\t\t}\n\t\t\t}\n\t\n\t\t},\n\t\n\t\t/**\n\t\t * Bind DOM events\n\t\t *\n\t\t * @since 3.7.0\n\t\t * @since 3.7.4 Unknown.\n\t\t * @since 5.0.0 Removed password toggle logic.\n\t\t *\n\t\t * @return void\n\t\t */\n\t\tbind: function() {\n\t\n\t\t\t$( '.llms-donut' ).each( function() {\n\t\t\t\tLLMS.Donut( $( this ) );\n\t\t\t} );\n\t\n\t\t},\n\t\n\t\t/**\n\t\t * Bind events related to the orders screen on the dashboard\n\t\t *\n\t\t * @since 3.10.0\n\t\t *\n\t\t * @return void\n\t\t */\n\t\tbind_orders: function() {\n\t\n\t\t\t$( '#llms-cancel-subscription-form' ).on( 'submit', this.order_cancel_warning );\n\t\t\t$( '#llms_update_payment_method' ).on( 'click', function() {\n\t\t\t\t$( 'input[name=\"llms_payment_gateway\"]:checked' ).trigger( 'change' );\n\t\t\t\t$( this ).closest( 'form' ).find( '.llms-switch-payment-source-main' ).slideToggle( '200' );\n\t\t\t} );\n\t\n\t\t},\n\t\n\t\t/**\n\t\t * Get the current dashboard endpoint/tab slug\n\t\t *\n\t\t * @since 3.10.0\n\t\t *\n\t\t * @return void\n\t\t */\n\t\tget_screen: function() {\n\t\t\tif ( ! this.screen ) {\n\t\t\t\tthis.screen = $( '.llms-student-dashboard' ).attr( 'data-current' );\n\t\t\t}\n\t\t\treturn this.screen;\n\t\t},\n\t\n\t\t/**\n\t\t * Show a confirmation warning when Cancel Subscription form is submitted\n\t\t *\n\t\t * @since 3.10.0\n\t\t *\n\t\t * @param obj e JS event data.\n\t\t * @return void\n\t\t */\n\t\torder_cancel_warning: function( e ) {\n\t\t\te.preventDefault();\n\t\t\tvar msg = LLMS.l10n.translate( 'Are you sure you want to cancel your subscription?' );\n\t\t\tif ( window.confirm( LLMS.l10n.translate( msg ) ) ) {\n\t\t\t\t$( this ).off( 'submit', this.order_cancel_warning );\n\t\t\t\t$( this ).submit();\n\t\t\t}\n\t\t},\n\t\n\t};\n\t\n\t\t/* global LLMS, $ */\n\t\n\t/**\n\t * User event/interaction tracking.\n\t *\n\t * @since 3.36.0\n\t * @since 3.36.2 Fix JS error when settings aren't loaded.\n\t * @since 3.37.2 When adding an event to the storae also make sure the nonce is set for server-side verification.\n\t * @since 3.37.9 Fix IE compatibility issue related to usage of `Object.assign()`.\n\t * @since 3.37.14 Persist the tracking events via ajax when reaching the cookie size limit.\n\t * @since 5.0.0 Set `settings` as an empty object when no settings supplied.\n\t * Only attempt to add a nonce to the datastore when a nonce exists in the settings object.\n\t */\n\tLLMS.Tracking = function( settings ) {\n\t\n\t\tsettings = settings || {};\n\t\n\t\tvar self = this,\n\t\t\tstore = new LLMS.Storage( 'llms-tracking' );\n\t\n\t\tsettings = 'string' === typeof settings ? JSON.parse( settings ) : settings;\n\t\n\t\t/**\n\t\t * Initialize / Bind all tracking event listeners.\n\t\t *\n\t\t * @since 3.36.0\n\t\t * @since 5.0.0 Only attempt to add a nonce to the datastore when a nonce exists in the settings object.\n\t\t *\n\t\t * @return {void}\n\t\t */\n\t\tfunction init() {\n\t\n\t\t\t// Set the nonce for server-side verification.\n\t\t\tif ( settings.nonce ) {\n\t\n\t\t\t\tstore.set( 'nonce', settings.nonce );\n\t\n\t\t\t}\n\t\n\t\t\tself.addEvent( 'page.load' );\n\t\n\t\t\twindow.addEventListener( 'beforeunload', onBeforeUnload );\n\t\t\twindow.addEventListener( 'unload', onUnload );\n\t\n\t\t\tdocument.addEventListener( 'visibilitychange', onVisibilityChange );\n\t\n\t\t};\n\t\n\t\t/**\n\t\t * Add an event.\n\t\t *\n\t\t * @since 3.36.0\n\t\t * @since 3.36.2 Fix error when settings aren't loaded.\n\t\t * @since 3.37.2 Always make sure the nonce is set for server-side verification.\n\t\t * @since 3.37.14 Persist the tracking events via ajax when reaching the cookie size limit.\n\t\t *\n\t\t * @param string|obj event Event Id (type.event) or a full event object from `this.makeEventObj()`.\n\t\t * @param int args Optional additional arguments to pass to `this.makeEventObj()`.\n\t\t * @return {void}\n\t\t */\n\t\tthis.addEvent = function( event, args ) {\n\t\n\t\t\targs = args || {};\n\t\t\tif ( 'string' === typeof event ) {\n\t\t\t\targs.event = event;\n\t\t\t}\n\t\n\t\t\t// If the event isn't registered in the settings don't proceed.\n\t\t\tif ( !settings.events || -1 === settings.events.indexOf( args.event ) ) {\n\t\t\t\treturn;\n\t\t\t}\n\t\n\t\t\t// Make sure the nonce is set for server-side verification.\n\t\t\tstore.set( 'nonce', settings.nonce );\n\t\n\t\t\tevent = self.makeEventObj( args );\n\t\n\t\t\tvar all = store.get( 'events', [] );\n\t\t\tall.push( event );\n\t\t\tstore.set( 'events', all );\n\t\n\t\t\t// If couldn't store the latest event because of size limits.\n\t\t\tif ( all.length > store.get( 'events', [] ).length ) {\n\t\n\t\t\t\t// Copy the cookie in a temporary variable.\n\t\t\t\tvar _temp = store.getAll();\n\t\t\t\t// Clear the events from the cookie.\n\t\t\t\tstore.clear('events');\n\t\n\t\t\t\t// Add the latest event to the temporary variable.\n\t\t\t\t_temp['events'].push( event );\n\t\n\t\t\t\t// Send the temporary variable as string via ajax.\n\t\t\t\tLLMS.Ajax.call( {\n\t\t\t\t\tdata: {\n\t\t\t\t\t\taction: 'persist_tracking_events',\n\t\t\t\t\t\t'llms-tracking': JSON.stringify(_temp)\n\t\t\t\t\t},\n\t\n\t\t\t\t\terror: function( xhr, status, error ) {\n\t\n\t\t\t\t\t\tconsole.log( xhr, status, error );\n\t\n\t\t\t\t\t},\n\t\t\t\t\tsuccess: function( r ) {\n\t\n\t\t\t\t\t\tif ( 'error' === r.code ) {\n\t\t\t\t\t\t\tconsole.log(r.code, r.message);\n\t\t\t\t\t\t}\n\t\n\t\t\t\t\t}\n\t\n\t\t\t\t} );\n\t\n\t\t\t}\n\t\n\t\t}\n\t\n\t\t/**\n\t\t * Retrieve initialization settings.\n\t\t *\n\t\t * @since 3.36.0\n\t\t *\n\t\t * @return obj\n\t\t */\n\t\tthis.getSettings = function() {\n\t\t\treturn settings;\n\t\t}\n\t\n\t\t/**\n\t\t * Create an event object suitable to save as an event.\n\t\t *\n\t\t * @since 3.36.0\n\t\t * @since 3.37.9 Use `$.extend()` in favor of `Object.assign()`.\n\t\t *\n\t\t * @param obj event {\n\t\t * Event hash\n\t\t *\n\t\t * @param {string} event (Required) Event ID, eg: \"page.load\".\n\t\t * @param {url} url Event URL. (Optional, added automatically) Stored as metadata and used to infer an object_id for post events.\n\t\t * @param {time} float (Optional, added automatically) Timestamp (in milliseconds). Used for the event creation date.\n\t\t * @param {int} obj_id (Optional). The object ID. Inferred automatically via `url` if not provided.\n\t\t * @param {obj} meta (Optional) Hash of metadata to store with the event.\n\t\t * }\n\t\t * @return obj\n\t\t */\n\t\tthis.makeEventObj = function( event ) {\n\t\t\treturn $.extend( event, {\n\t\t\t\turl: window.location.href,\n\t\t\t\ttime: Math.round( new Date().getTime() / 1000 ),\n\t\t\t} );\n\t\t}\n\t\n\t\n\t\t/**\n\t\t * Remove the visibility change event listener on window.beforeunload\n\t\t *\n\t\t * Prevents actual unloading from recording a blur event from the visibility change listener\n\t\t *\n\t\t * @param obj e JS event object.\n\t\t * @return void\n\t\t */\n\t\tfunction onBeforeUnload( e ) {\n\t\t\tdocument.removeEventListener( 'visibilitychange', onVisibilityChange );\n\t\t}\n\t\n\t\t/**\n\t\t * Record a `page.exit` event on window.unload.\n\t\t *\n\t\t * @since 3.36.0\n\t\t *\n\t\t * @param obj e JS event object.\n\t\t * @return void\n\t\t */\n\t\tfunction onUnload( e ) {\n\t\t\tself.addEvent( 'page.exit' );\n\t\t}\n\t\n\t\t/**\n\t\t * Record `page.blur` and `page.focus` events via document.visilibitychange events.\n\t\t *\n\t\t * @since 3.36.0\n\t\t *\n\t\t * @param obj e JS event object.\n\t\t * @return void\n\t\t */\n\t\tfunction onVisibilityChange( e ) {\n\t\n\t\t\tvar event = document.hidden ? 'page.blur' : 'page.focus';\n\t\t\tself.addEvent( event );\n\t\n\t\t}\n\t\n\t\t// Initialize on the frontend only.\n\t\tif ( ! $( 'body' ).hasClass( 'wp-admin' ) ) {\n\t\t\tinit();\n\t\t}\n\t\n\t};\n\t\n\tllms.tracking = new LLMS.Tracking( llms.tracking );\n\t\n\t\t/**\n\t * Rest Methods\n\t * Manages URL and Rest object parsing\n\t *\n\t * @package LifterLMS/Scripts\n\t *\n\t * @since Unknown\n\t * @version Unknown\n\t */\n\t\n\tLLMS.Rest = {\n\t\n\t\t/**\n\t\t * Init\n\t\t * loads class methods\n\t\t */\n\t\tinit: function() {\n\t\t\tthis.bind();\n\t\t},\n\t\n\t\t/**\n\t\t * Bind Method\n\t\t * Handles dom binding on load\n\t\t *\n\t\t * @return {[type]} [description]\n\t\t */\n\t\tbind: function() {\n\t\t},\n\t\n\t\t/**\n\t\t * Searches for string matches in url path\n\t\t *\n\t\t * @param {Array} strings [Array of strings to search for matches]\n\t\t * @return {Boolean} [Was a match found?]\n\t\t */\n\t\tis_path: function( strings ) {\n\t\n\t\t\tvar path_exists = false,\n\t\t\t\turl = window.location.href;\n\t\n\t\t\tfor ( var i = 0; i < strings.length; i++ ) {\n\t\n\t\t\t\tif ( url.search( strings[i] ) > 0 && ! path_exists ) {\n\t\n\t\t\t\t\tpath_exists = true;\n\t\t\t\t}\n\t\t\t}\n\t\n\t\t\treturn path_exists;\n\t\t},\n\t\n\t\t/**\n\t\t * Retrieves query variables\n\t\t *\n\t\t * @return {[Array]} [array object of query variable key=>value pairs]\n\t\t */\n\t\tget_query_vars: function() {\n\t\n\t\t\tvar vars = [], hash,\n\t\t\t\thashes = window.location.href.slice( window.location.href.indexOf( '?' ) + 1 ).split( '&' );\n\t\n\t\t\tfor (var i = 0; i < hashes.length; i++) {\n\t\t\t\thash = hashes[i].split( '=' );\n\t\t\t\tvars.push( hash[0] );\n\t\t\t\tvars[hash[0]] = hash[1];\n\t\t\t}\n\t\n\t\t\treturn vars;\n\t\t}\n\t\n\t};\n\t\n\n\t/**\n\t * Initializes all classes within the LLMS Namespace\n\t *\n\t * @since Unknown\n\t *\n\t * @return {void}\n\t */\n\tLLMS.init = function() {\n\n\t\tfor (var func in LLMS) {\n\n\t\t\tif ( typeof LLMS[func] === 'object' && LLMS[func] !== null ) {\n\n\t\t\t\tif ( LLMS[func].init !== undefined ) {\n\n\t\t\t\t\tif ( typeof LLMS[func].init === 'function') {\n\t\t\t\t\t\tLLMS[func].init();\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t};\n\n\t/**\n\t * Determine if the current device is touch-enabled\n\t *\n\t * @since 3.24.3\n\t *\n\t * @see {@link https://stackoverflow.com/a/4819886/400568}\n\t *\n\t * @return {Boolean} Whether or not the device is touch-enabled.\n\t */\n\tLLMS.is_touch_device = function() {\n\n\t\tvar prefixes = ' -webkit- -moz- -o- -ms- '.split( ' ' );\n\t\tvar mq = function( query ) {\n\t\t\treturn window.matchMedia( query ).matches;\n\t\t}\n\n\t\tif ( ( 'ontouchstart' in window ) || window.DocumentTouch && document instanceof DocumentTouch ) {\n\t\t\treturn true;\n\t\t}\n\n\t\t/**\n\t\t * Include the 'heartz' as a way to have a non matching MQ to help terminate the join.\n\t\t *\n\t\t * @see {@link https://git.io/vznFH}\n\t\t */\n\t\tvar query = ['(', prefixes.join( 'touch-enabled),(' ), 'heartz', ')'].join( '' );\n\t\treturn mq( query );\n\n\t};\n\n\t/**\n\t * Wait for matchHeight to load\n\t *\n\t * @since 3.0.0\n\t * @since 3.16.6 Unknown.\n\t * @since 5.3.3 Pass a dependency name to `wait_for()`.\n\t *\n\t * @param {Function} cb Callback function to run when matchheight is ready.\n\t * @return {void}\n\t */\n\tLLMS.wait_for_matchHeight = function( cb ) {\n\t\tthis.wait_for( function() {\n\t\t\treturn ( undefined !== $.fn.matchHeight );\n\t\t}, cb, 'matchHeight' );\n\t}\n\n\t/**\n\t * Wait for webuiPopover to load\n\t *\n\t * @since 3.9.1\n\t * @since 3.16.6 Unknown.\n\t *\n\t * @param {Function} cb Callback function to run when matchheight is ready.\n\t * @return {void}\n\t */\n\tLLMS.wait_for_popover = function( cb ) {\n\t\tthis.wait_for( function() {\n\t\t\treturn ( undefined !== $.fn.webuiPopover );\n\t\t}, cb, 'webuiPopover' );\n\t}\n\n\t/**\n\t * Wait for a dependency to load and then run a callback once it has\n\t *\n\t * Temporary fix for a less-than-optimal assets loading function on the PHP side of things.\n\t *\n\t * @since 3.9.1\n\t * @since 5.3.3 Added optional `name` parameter.\n\t *\n\t * @param {Function} test A function that returns a truthy if the dependency is loaded.\n\t * @param {Function} cb A callback function executed once the dependency is loaded.\n\t * @param {string} name The dependency name.\n\t * @return {void}\n\t */\n\tLLMS.wait_for = function( test, cb, name ) {\n\n\t\tvar counter = 0,\n\t\t\tinterval;\n\n\t\tname = name ? name : 'unnamed';\n\n\t\tinterval = setInterval( function() {\n\n\t\t\t// If we get to 30 seconds log an error message.\n\t\t\tif ( counter >= 300 ) {\n\n\t\t\t\tconsole.log( 'Unable to load dependency: ' + name );\n\n\t\t\t\t// If we can't access yet, increment and wait...\n\t\t\t} else {\n\n\t\t\t\t// Bind the events, we're good!\n\t\t\t\tif ( test() ) {\n\t\t\t\t\tcb();\n\t\t\t\t} else {\n\t\t\t\t\t// console.log( 'Waiting for dependency: ' + name );\n\t\t\t\t\tcounter++;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tclearInterval( interval );\n\n\t\t}, 100 );\n\n\t};\n\n\tLLMS.init( $ );\n\n} )( jQuery );\n"],"sourceRoot":"../../js/private"} \ No newline at end of file diff --git a/assets/maps/js/llms.min.js.map b/assets/maps/js/llms.min.js.map index db516eae12..83c88c6633 100644 --- a/assets/maps/js/llms.min.js.map +++ b/assets/maps/js/llms.min.js.map @@ -1 +1 @@ -{"version":3,"sources":["llms.js"],"names":["LLMS","window","$","factory","registeredInModuleLoader","OldCookies","api","Achievements","init","self","length","this","bind","maybe_open","each","create_modal","on","$this","id","attr","$modal","iziModal","$el","append","headerColor","group","history","loop","overlayColor","transitionIn","transitionOut","width","onOpening","modal","setTitle","find","html","setSubtitle","setContent","onClosing","pushState","document","title","location","pathname","search","hash","indexOf","first","trigger","Ajax","url","ajaxurl","llms","type","data","cache","dataType","async","response","obj","_ajax_nonce","ajax_nonce","wp_ajax_data","nonce","query_vars","Rest","get_query_vars","post_id","post","val","call","settings","request","ajax","Donut","options","extend","element","percent","circle","stroke_width","parseInt","css","radius","angle","hasClass","i","Math","round","increment","animate","timer","setInterval","d","radians","PI","x","cos","y","sin","clearInterval","Forms","address_info","$cities","$countries","$states","$states_holder","bind_matching_fields","bind_voucher_field","bind_edit_account","bind_l10n_selects","handle_toggle_click","$zips","wait_for","undefined","fn","llmsSelect2","prep_state_field","add","JSON","parse","update_locale_info","not","$parents","$field","$match","closest","val_1","val_2","addClass","removeClass","e","preventDefault","toggle","get_field_parent","$block","get_label_text","$label","$clone","clone","remove","text","trim","event","$fields","isShowing","displayFunc","disabled","textAttr","$parent","$holder","appendTo","update_label","$required","country_code","info","update_state_options","state","update_locale_info_for_field","city","postcode","label","enable_field","disable_field","opts","name","class","insertAfter","hide","removeAttr","next","detach","show","Instructors","wait_for_matchHeight","matchHeight","l10n","translate","string","strings","replace","replacements","str","token","value","toString","LessonPreview","$els","$locked","match_height","msg","$tip","get_tooltip","setTimeout","Loops","OutlineCollapse","$outlines","$outline","$headers","$section","get_section_state","open_section","close_section","opposite_action","PasswordStrength","$meter","$pass","$conf","$form","setup_references","wp","passwordStrength","submit","check_strength","$pass_field","$conf_field","pass_length","conf_length","get_current_strength_status","get_current_strength","checkout","callback","get_blocklist","blocklist","userInputDisallowedList","concat","get_setting","push","format","pass","conf","meter","get_strength_slug","get_strength_text","curr","min","get_strength_value","get_minimum_strength","key","default_val","get_settings","strength_val","slugs","-1","1","2","3","4","5","texts","strength_slug","values","too-short","very-weak","weak","medium","strong","mismatch","off","scrollTop","offset","top","fadeIn","get_blacklist","console","log","Pricing_Tables","wait_for_popover","bind_locked","webuiPopover","animation","closeable","content","$content","$element","placement","style","Review","click","jQuery","action","review_title","review_text","pageID","success","error","jqXHR","textStatus","errorThrown","change","Spinner","get","size","$spinner","start","stop","result","arguments","attributes","decode","s","decodeURIComponent","converter","set","path","defaults","expires","Date","toUTCString","stringify","test","write","encodeURIComponent","String","escape","attributeName","stringifiedAttributes","split","cookie","json","jar","cookies","parts","slice","join","charAt","read","getJSON","withConverter","define","amd","exports","module","Cookies","noConflict","CookieStore","Storage","store","clearAll","clear","getAll","sameSite","StudentDashboard","screen","get_screen","bind_orders","order_cancel_warning","slideToggle","confirm","Tracking","onBeforeUnload","removeEventListener","onVisibilityChange","onUnload","addEvent","hidden","args","events","makeEventObj","all","_temp","llms-tracking","xhr","status","r","code","message","getSettings","href","time","getTime","addEventListener","tracking","is_path","path_exists","vars","hashes","func","is_touch_device","prefixes","DocumentTouch","query","matchMedia","matches","cb","interval","counter"],"mappings":"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","file":"../../js/llms.min.js","sourcesContent":["/**\n * Main LLMS Namespace\n *\n * @since 1.0.0\n * @version 5.3.3\n */\n\nvar LLMS = window.LLMS || {};\n( function( $ ){\n\n\t'use strict';\n\n\t/**\n\t * Load all app modules\n\t */\n\t/**\n\t * Front End Achievements\n\t *\n\t * @package LifterLMS/Scripts\n\t *\n\t * @since 3.14.0\n\t * @version 4.5.1\n\t */\n\t\n\tLLMS.Achievements = {\n\t\n\t\t/**\n\t\t * Init\n\t\t *\n\t\t * @since 3.14.0\n\t\t * @since 4.5.1 Fix conditional loading check.\n\t\t *\n\t\t * @return void\n\t\t */\n\t\tinit: function() {\n\t\n\t\t\tif ( $( '.llms-achievement' ).length ) {\n\t\n\t\t\t\tvar self = this;\n\t\n\t\t\t\t$( function() {\n\t\t\t\t\tself.bind();\n\t\t\t\t\tself.maybe_open();\n\t\t\t\t} );\n\t\t\t}\n\t\n\t\t},\n\t\n\t\t/**\n\t\t * Bind DOM events\n\t\t *\n\t\t * @since 3.14.0\n\t\t *\n\t\t * @return void\n\t\t */\n\t\tbind: function() {\n\t\n\t\t\tvar self = this;\n\t\n\t\t\t$( '.llms-achievement' ).each( function() {\n\t\n\t\t\t\tself.create_modal( $( this ) );\n\t\n\t\t\t} );\n\t\n\t\t\t$( '.llms-achievement' ).on( 'click', function() {\n\t\n\t\t\t\tvar $this = $( this ),\n\t\t\t\t\tid = 'achievement-' + $this.attr( 'data-id' ),\n\t\t\t\t\t$modal = $( '#' + id );\n\t\n\t\t\t\tif ( ! $modal.length ) {\n\t\t\t\t\tself.create_modal( $this );\n\t\t\t\t}\n\t\n\t\t\t\t$modal.iziModal( 'open' );\n\t\n\t\t\t} );\n\t\n\t\t},\n\t\n\t\t/**\n\t\t * Creates modal a modal for an achievement\n\t\t *\n\t\t * @since 3.14.0\n\t\t *\n\t\t * @param obj $el The jQuery selector for the modal card.\n\t\t * @return void\n\t\t */\n\t\tcreate_modal: function( $el ) {\n\t\n\t\t\tvar id = 'achievement-' + $el.attr( 'data-id' ),\n\t\t\t\t$modal = $( '#' + id );\n\t\n\t\t\tif ( ! $modal.length ) {\n\t\t\t\t$modal = $( '
' );\n\t\t\t\t$( 'body' ).append( $modal );\n\t\t\t}\n\t\n\t\t\t$modal.iziModal( {\n\t\t\t\theaderColor: '#3a3a3a',\n\t\t\t\tgroup: 'achievements',\n\t\t\t\thistory: true,\n\t\t\t\tloop: true,\n\t\t\t\toverlayColor: 'rgba( 0, 0, 0, 0.6 )',\n\t\t\t\ttransitionIn: 'fadeInDown',\n\t\t\t\ttransitionOut: 'fadeOutDown',\n\t\t\t\twidth: 340,\n\t\t\t\tonOpening: function( modal ) {\n\t\n\t\t\t\t\tmodal.setTitle( $el.find( '.llms-achievement-title' ).html() );\n\t\t\t\t\tmodal.setSubtitle( $el.find( '.llms-achievement-date' ).html() );\n\t\t\t\t\tmodal.setContent( '
' + $el.html() + '
' );\n\t\n\t\t\t\t},\n\t\n\t\t\t\tonClosing: function() {\n\t\t\t\t\twindow.history.pushState( '', document.title, window.location.pathname + window.location.search );\n\t\t\t\t},\n\t\n\t\t\t} );\n\t\n\t\t},\n\t\n\t\t/**\n\t\t * On page load, opens a modal if the URL contains an achievement in the location hash\n\t\t *\n\t\t * @since 3.14.0\n\t\t *\n\t\t * @return void\n\t\t */\n\t\tmaybe_open: function() {\n\t\n\t\t\tvar hash = window.location.hash;\n\t\t\tif ( hash && -1 !== hash.indexOf( 'achievement-' ) ) {\n\t\t\t\t$( 'a[href=\"' + hash + '\"]' ).first().trigger( 'click' );\n\t\t\t}\n\t\n\t\t}\n\t\n\t};\n\t\n\t\t/**\n\t * Main Ajax class\n\t * Handles Primary Ajax connection\n\t *\n\t * @package LifterLMS/Scripts\n\t *\n\t * @since Unknown\n\t * @version Unknown\n\t */\n\t\n\tLLMS.Ajax = {\n\t\n\t\t/**\n\t\t * Url\n\t\t *\n\t\t * @type {String}\n\t\t */\n\t\turl: window.ajaxurl || window.llms.ajaxurl,\n\t\n\t\t/**\n\t\t * Type\n\t\t *\n\t\t * @type {[type]}\n\t\t */\n\t\ttype: 'post',\n\t\n\t\t/**\n\t\t * Data\n\t\t *\n\t\t * @type {[type]}\n\t\t */\n\t\tdata: [],\n\t\n\t\t/**\n\t\t * Cache\n\t\t *\n\t\t * @type {[type]}\n\t\t */\n\t\tcache: false,\n\t\n\t\t/**\n\t\t * DataType\n\t\t * defaulted to json\n\t\t *\n\t\t * @type {String}\n\t\t */\n\t\tdataType: 'json',\n\t\n\t\t/**\n\t\t * Async\n\t\t * default to false\n\t\t *\n\t\t * @type {Boolean}\n\t\t */\n\t\tasync: true,\n\t\n\t\tresponse:[],\n\t\n\t\t/**\n\t\t * Initialize Ajax methods\n\t\t *\n\t\t * @since Unknown\n\t\t * @since 4.4.0 Update ajax nonce source.\n\t\t *\n\t\t * @param {Object} obj Options object.\n\t\t * @return {Object}\n\t\t */\n\t\tinit: function( obj ) {\n\t\n\t\t\t// If obj is not of type object or null return false.\n\t\t\tif ( obj === null || typeof obj !== 'object' ) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\n\t\t\t// set object defaults if values are not supplied\n\t\t\tobj.url = 'url' in obj ? obj.url : this.url;\n\t\t\tobj.type = 'type' \t\tin obj ? obj.type : this.type;\n\t\t\tobj.data = 'data' \t\tin obj ? obj.data : this.data;\n\t\t\tobj.cache = 'cache' \t\tin obj ? obj.cache : this.cache;\n\t\t\tobj.dataType = 'dataType'\tin obj ? obj.dataType : this.dataType;\n\t\t\tobj.async = 'async'\t\tin obj ? obj.async : this.async;\n\t\n\t\t\t// Add nonce to data object.\n\t\t\tobj.data._ajax_nonce = window.llms.ajax_nonce || wp_ajax_data.nonce;\n\t\n\t\t\t// Add post id to data object.\n\t\t\tvar $R = LLMS.Rest,\n\t\t\tquery_vars = $R.get_query_vars();\n\t\t\tobj.data.post_id = 'post' in query_vars ? query_vars.post : null;\n\t\t\tif ( ! obj.data.post_id && $( 'input#post_ID' ).length ) {\n\t\t\t\tobj.data.post_id = $( 'input#post_ID' ).val();\n\t\t\t}\n\t\n\t\t\treturn obj;\n\t\t},\n\t\n\t\t/**\n\t\t * Call\n\t\t * Called by external classes\n\t\t * Sets up jQuery Ajax object\n\t\t *\n\t\t * @param {[object]} [object of ajax settings]\n\t\t * @return {[mixed]} [false if not object or this]\n\t\t */\n\t\tcall: function(obj) {\n\t\n\t\t\t// get default variables if not included in call\n\t\t\tvar settings = this.init( obj );\n\t\n\t\t\t// if init return a response of false\n\t\t\tif ( ! settings) {\n\t\t\t\treturn false;\n\t\t\t} else {\n\t\t\t\tthis.request( settings );\n\t\t\t}\n\t\n\t\t\treturn this;\n\t\n\t\t},\n\t\n\t\t/**\n\t\t * Calls jQuery Ajax on settings object\n\t\t *\n\t\t * @return {[object]} [this]\n\t\t */\n\t\trequest: function(settings) {\n\t\n\t\t\t$.ajax( settings );\n\t\n\t\t\treturn this;\n\t\n\t\t}\n\t\n\t};\n\t\n\t\t/**\n\t * Create a Donut Chart\n\t *\n\t * @package LifterLMS/Scripts\n\t *\n\t * @since 3.9.0\n\t * @version 4.15.0\n\t *\n\t * @link https://gist.github.com/joeyinbox/8205962\n\t *\n\t * @param {Object} $el jQuery element to draw a chart within.\n\t */\n\t\n\tLLMS.Donut = function( $el ) {\n\t\n\t\t/**\n\t\t * Constructor\n\t\t *\n\t\t * @since 3.9.0\n\t\t * @since 4.15.0 Flip animation in RTL.\n\t\t *\n\t\t * @param {Object} options Donut options.\n\t\t * @return {Void}\n\t\t */\n\t\tfunction Donut(options) {\n\t\n\t\t\tthis.settings = $.extend( {\n\t\t\t\telement: options.element,\n\t\t\t\tpercent: 100\n\t\t\t}, options );\n\t\n\t\t\tthis.circle = this.settings.element.find( 'path' );\n\t\t\tthis.settings.stroke_width = parseInt( this.circle.css( 'stroke-width' ) );\n\t\t\tthis.radius = ( parseInt( this.settings.element.css( 'width' ) ) - this.settings.stroke_width ) / 2;\n\t\t\tthis.angle = $( 'body' ).hasClass( 'rtl' ) ? 82.5 : 97.5; // Origin of the draw at the top of the circle\n\t\t\tthis.i = Math.round( 0.75 * this.settings.percent );\n\t\t\tthis.first = true;\n\t\t\tthis.increment = $( 'body' ).hasClass( 'rtl' ) ? -5 : 5;\n\t\n\t\t\tthis.animate = function() {\n\t\t\t\tthis.timer = setInterval( this.loop.bind( this ), 10 );\n\t\t\t};\n\t\n\t\t\tthis.loop = function() {\n\t\t\t\tthis.angle += this.increment;\n\t\t\t\tthis.angle %= 360;\n\t\t\t\tvar radians = ( this.angle / 180 ) * Math.PI,\n\t\t\t\t\tx = this.radius + this.settings.stroke_width / 2 + Math.cos( radians ) * this.radius,\n\t\t\t\t\ty = this.radius + this.settings.stroke_width / 2 + Math.sin( radians ) * this.radius,\n\t\t\t\t\td;\n\t\t\t\tif (this.first === true) {\n\t\t\t\t\td = this.circle.attr( 'd' ) + ' M ' + x + ' ' + y;\n\t\t\t\t\tthis.first = false;\n\t\t\t\t} else {\n\t\t\t\t\td = this.circle.attr( 'd' ) + ' L ' + x + ' ' + y;\n\t\t\t\t}\n\t\t\t\tthis.circle.attr( 'd', d );\n\t\t\t\tthis.i--;\n\t\n\t\t\t\tif (this.i <= 0) {\n\t\t\t\t\tclearInterval( this.timer );\n\t\t\t\t}\n\t\t\t};\n\t\t}\n\t\n\t\t/**\n\t\t * Draw donut element\n\t\t *\n\t\t * @since 3.9.0\n\t\t *\n\t\t * @param {Object} $el jQuery element to draw a chart within.\n\t\t * @return {Void}\n\t\t */\n\t\tfunction draw( $el ) {\n\t\t\tvar path = '';\n\t\t\t$el.append( '' + path + '' );\n\t\t\tvar donut = new Donut( {\n\t\t\t\telement: $el,\n\t\t\t\tpercent: $el.attr( 'data-perc' )\n\t\t\t} );\n\t\t\tdonut.animate();\n\t\t}\n\t\n\t\tdraw( $el );\n\t\n\t};\n\t\n\t\t/**\n\t * Forms\n\t *\n\t * @package LifterLMS/Scripts\n\t *\n\t * @since 5.0.0\n\t * @version 5.3.3\n\t */\n\t\n\tLLMS.Forms = {\n\t\n\t\t/**\n\t\t * Stores locale information.\n\t\t *\n\t\t * Added via PHP.\n\t\t *\n\t\t * @type {Object}\n\t\t */\n\t\taddress_info: {},\n\t\n\t\t/**\n\t\t * jQuery ref. to the city text field.\n\t\t *\n\t\t * @type {Object}\n\t\t */\n\t\t$cities: null,\n\t\n\t\t/**\n\t\t * jQuery ref. to the countries select field.\n\t\t *\n\t\t * @type {Object}\n\t\t */\n\t\t$countries: null,\n\t\n\t\t/**\n\t\t * jQuery ref. to the states select field.\n\t\t *\n\t\t * @type {Object}\n\t\t */\n\t\t$states: null,\n\t\n\t\t/**\n\t\t * jQuery ref. to the hidden states holder field.\n\t\t *\n\t\t * @type {Object}\n\t\t */\n\t\t$states_holder: null,\n\t\n\t\t/**\n\t\t * Init\n\t\t *\n\t \t * @since 5.0.0\n\t \t * @since 5.3.3 Move select2 dependency check into the `bind_l10_selects()` method.\n\t \t *\n\t \t * @return {void}\n\t\t */\n\t\tinit: function() {\n\t\n\t\t\tif ( $( 'body' ).hasClass( 'wp-admin' ) ) {\n\t\t\t\tif ( ! ( $( 'body' ).hasClass( 'profile-php' ) || $( 'body' ).hasClass( 'user-edit-php' ) ) ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\n\t\t\tvar self = this;\n\t\n\t\t\tself.bind_matching_fields();\n\t\t\tself.bind_voucher_field();\n\t\t\tself.bind_edit_account();\n\t\t\tself.bind_l10n_selects();\n\t\n\t\t},\n\t\n\t\t/**\n\t\t * Bind DOM events for the edit account screen.\n\t\t *\n\t\t * @since 5.0.0\n\t\t *\n\t\t * @return {void}\n\t\t */\n\t\tbind_edit_account: function() {\n\t\n\t\t\t// Not an edit account form.\n\t\t\tif ( ! $( 'form.llms-person-form.edit-account' ).length ) {\n\t\t\t\treturn;\n\t\t\t}\n\t\n\t\t\t$( '.llms-toggle-fields' ).on( 'click', this.handle_toggle_click );\n\t\n\t\t},\n\t\n\t\t/**\n\t\t * Bind DOM Events fields with dynamic localization values and language.\n\t\t *\n\t\t * @since 5.0.0\n\t\t * @since 5.3.3 Bind select2-related events after ensuring select2 is available.\n\t\t *\n\t\t * @return {void}\n\t\t */\n\t\tbind_l10n_selects: function() {\n\t\n\t\t\tvar self = this;\n\t\n\t\t\tself.$cities = $( '#llms_billing_city' );\n\t\t\tself.$countries = $( '.llms-l10n-country-select select' );\n\t\t\tself.$states = $( '.llms-l10n-state-select select' );\n\t\t\tself.$zips = $( '#llms_billing_zip' );\n\t\n\t\t\tif ( ! self.$countries.length ) {\n\t\t\t\treturn;\n\t\t\t}\n\t\n\t\t\tvar isSelect2Available = function() {\n\t\t\t\treturn ( undefined !== $.fn.llmsSelect2 );\n\t\t\t};\n\t\n\t\t\tLLMS.wait_for( isSelect2Available, function() {\n\t\n\t\t\t\tif ( self.$states.length ) {\n\t\t\t\t\tself.prep_state_field();\n\t\t\t\t}\n\t\n\t\t\t\tself.$countries.add( self.$states ).llmsSelect2( { width: '100%' } );\n\t\n\t\t\t\tif ( window.llms.address_info ) {\n\t\t\t\t\tself.address_info = JSON.parse( window.llms.address_info );\n\t\t\t\t}\n\t\n\t\t\t\tself.$countries.on( 'change', function() {\n\t\n\t\t\t\t\tvar val = $( this ).val();\n\t\t\t\t\tself.update_locale_info( val );\n\t\n\t\t\t\t} ).trigger( 'change' );\n\t\n\t\t\t}, 'llmsSelect2' );\n\t\n\t\t},\n\t\n\t\t/**\n\t\t * Ensure \"matching\" fields match.\n\t\t *\n\t\t * @since 5.0.0\n\t\t *\n\t\t * @return {Void}\n\t\t */\n\t\tbind_matching_fields: function() {\n\t\n\t\t\tvar $fields = $( 'input[data-match]' ).not( '[type=\"password\"]' );\n\t\n\t\t\t$fields.each( function() {\n\t\n\t\t\t\tvar $field = $( this ),\n\t\t\t\t\t$match = $( '#' + $field.attr( 'data-match' ) ),\n\t\t\t\t\t$parents;\n\t\n\t\t\t\tif ( $match.length ) {\n\t\n\t\t\t\t\t$parents = $field.closest( '.llms-form-field' ).add( $match.closest( '.llms-form-field' ) );\n\t\n\t\t\t\t\t$field.on( 'input change', function() {\n\t\n\t\t\t\t\t\tvar val_1 = $field.val(),\n\t\t\t\t\t\t\tval_2 = $match.val();\n\t\n\t\t\t\t\t\tif ( val_1 && val_2 && val_1 !== val_2 ) {\n\t\t\t\t\t\t\t$parents.addClass( 'invalid' );\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t$parents.removeClass( 'invalid' );\n\t\t\t\t\t\t}\n\t\n\t\t\t\t\t} );\n\t\n\t\t\t\t}\n\t\n\t\t\t} );\n\t\n\t\t},\n\t\n\t\t/**\n\t\t * Bind DOM events for voucher toggles UX.\n\t\t *\n\t\t * @since 5.0.0\n\t\t *\n\t\t * @return {void}\n\t\t */\n\t\tbind_voucher_field: function() {\n\t\n\t\t\t$( '#llms-voucher-toggle' ).on( 'click', function( e ) {\n\t\t\t\te.preventDefault();\n\t\t\t\t$( '#llms_voucher' ).toggle();\n\t\t\t} );\n\t\n\t\t},\n\t\n\t\t/**\n\t\t * Retrieve the parent element for a given field.\n\t\t *\n\t\t * The parent element is hidden when the field isn't required.\n\t\t * Looks for a WP column wrapper and falls back to the field's\n\t\t * wrapper div.\n\t\t *\n\t\t * @since 5.0.0\n\t\t *\n\t\t * @param {Object} $field jQuery dom object.\n\t\t * @return {Object}\n\t\t */\n\t\tget_field_parent: function( $field ) {\n\t\n\t\t\tvar $block = $field.closest( '.wp-block-column' );\n\t\t\tif ( $block.length ) {\n\t\t\t\treturn $block;\n\t\t\t}\n\t\n\t\t\treturn $field.closest( '.llms-form-field' );\n\t\n\t\t},\n\t\n\t\t/**\n\t\t * Retrieve the text of a label\n\t\t *\n\t\t * Removes any children HTML elements (eg: required span elements) and returns only the labels text.\n\t\t *\n\t\t * @since 5.0.0\n\t\t *\n\t\t * @param {Object} $label jQuery object for a label element.\n\t\t * @return {String}\n\t\t */\n\t\tget_label_text: function( $label ) {\n\t\n\t\t\tvar $clone = $label.clone();\n\t\t\t$clone.find( '*' ).remove();\n\t\t\treturn $clone.text().trim();\n\t\n\t\t},\n\t\n\t\t/**\n\t\t * Callback function to handle the \"toggle\" button links for changing email address and password on account edit forms\n\t\t *\n\t\t * @since 5.0.0\n\t\t *\n\t\t * @param {Object} event Native JS event object.\n\t\t * @return {void}\n\t\t */\n\t\thandle_toggle_click: function( event ) {\n\t\n\t\t\tevent.preventDefault();\n\t\n\t\t\tvar $this = $( this ),\n\t\t\t\t$fields = $( $( this ).attr( 'data-fields' ) ),\n\t\t\t\tisShowing = $this.attr( 'data-is-showing' ) || 'no',\n\t\t\t\tdisplayFunc = 'yes' === isShowing ? 'hide' : 'show',\n\t\t\t\tdisabled = 'yes' === isShowing ? 'disabled' : null,\n\t\t\t\ttextAttr = 'yes' === isShowing ? 'data-change-text' : 'data-cancel-text';\n\t\n\t\t\t$fields.each( function() {\n\t\n\t\t\t\t$( this ).closest( '.llms-form-field' )[ displayFunc ]();\n\t\t\t\t$( this ).attr( 'disabled', disabled );\n\t\n\t\t\t} );\n\t\n\t\t\t$this.text( $this.attr( textAttr ) );\n\t\t\t$this.attr( 'data-is-showing', 'yes' === isShowing ? 'no' : 'yes' );\n\t\n\t\t},\n\t\n\t\t/**\n\t\t * Prepares the state select field.\n\t\t *\n\t\t * Moves All optgroup elements into a hidden & disabled select element.\n\t\t *\n\t\t * @since 5.0.0\n\t\t *\n\t\t * @return {void}\n\t\t */\n\t\tprep_state_field: function() {\n\t\n\t\t\tvar $parent = this.$states.closest( '.llms-form-field' );\n\t\n\t\t\tthis.$holder = $( '',\n\t\t\t\t{ name: $field.attr('name'), class: $field.attr( 'class' ) + ' hidden', type: 'hidden' }\n\t\t\t).insertAfter( $field );\n\t\t\t$field.attr( 'disabled', 'disabled' );\n\t\t\tthis.get_field_parent( $field ).hide();\n\t\t},\n\t\n\t\t/**\n\t\t * Enable a given field\n\t\t *\n\t\t * It also shows the parent element, and removes the empty hidden input field\n\t\t * previously added by disable_field().\n\t\t *\n\t\t * @since 5.0.0\n\t\t *\n\t\t * @param {Object} $field The jQuery object for the field.\n\t\t */\n\t\tenable_field: function( $field ) {\n\t\t\t$field.removeAttr( 'disabled' );\n\t\t\t$field.next( '.hidden[name='+$field.attr('name')+']' ).detach();\n\t\t\tthis.get_field_parent( $field ).show();\n\t\t}\n\t\n\t};\n\t\n\t\t/**\n\t * Instructors List\n\t *\n\t * @package LifterLMS/Scripts\n\t *\n\t * @since Unknown\n\t * @version Unknown\n\t */\n\t\n\tLLMS.Instructors = {\n\t\n\t\t/**\n\t\t * Init\n\t\t */\n\t\tinit: function() {\n\t\n\t\t\tvar self = this;\n\t\n\t\t\tif ( $( 'body' ).hasClass( 'wp-admin' ) ) {\n\t\t\t\treturn;\n\t\t\t}\n\t\n\t\t\tif ( $( '.llms-instructors' ).length ) {\n\t\n\t\t\t\tLLMS.wait_for_matchHeight( function() {\n\t\t\t\t\tself.bind();\n\t\t\t\t} );\n\t\n\t\t\t}\n\t\n\t\t},\n\t\n\t\t/**\n\t\t * Bind Method\n\t\t * Handles dom binding on load\n\t\t *\n\t\t * @return {[type]} [description]\n\t\t */\n\t\tbind: function() {\n\t\n\t\t\t$( '.llms-instructors .llms-author' ).matchHeight();\n\t\n\t\t},\n\t\n\t};\n\t\n\t\t/**\n\t * Localization functions for LifterLMS Javascript\n\t *\n\t * @package LifterLMS/Scripts\n\t *\n\t * @since 2.7.3\n\t * @version 2.7.3\n\t *\n\t * @todo we need more robust translation functions to handle sprintf and pluralization\n\t * at this moment we don't need those and haven't stubbed them out\n\t * those will be added when they're needed\n\t */\n\t\n\tLLMS.l10n = LLMS.l10n || {};\n\t\n\tLLMS.l10n.translate = function ( string ) {\n\t\n\t\tvar self = this;\n\t\n\t\tif ( self.strings[string] ) {\n\t\n\t\t\treturn self.strings[string];\n\t\n\t\t} else {\n\t\n\t\t\treturn string;\n\t\n\t\t}\n\t\n\t};\n\t\n\t/**\n\t * Translate and replace placeholders in a string\n\t *\n\t * @example LLMS.l10n.replace( 'This is a %2$s %1$s String', {\n\t * \t'%1$s': 'cool',\n\t * \t\t\t'%2$s': 'very'\n\t * \t\t} );\n\t * \t\tOutput: \"This is a very cool String\"\n\t *\n\t * @param string string text string\n\t * @param object replacements object containing token => replacement pairs\n\t * @return string\n\t * @since 3.16.0\n\t * @version 3.16.0\n\t */\n\tLLMS.l10n.replace = function( string, replacements ) {\n\t\n\t\tvar str = this.translate( string );\n\t\n\t\t$.each( replacements, function( token, value ) {\n\t\n\t\t\tif ( -1 !== token.indexOf( 's' ) ) {\n\t\t\t\tvalue = value.toString();\n\t\t\t} else if ( -1 !== token.indexOf( 'd' ) ) {\n\t\t\t\tvalue = value * 1;\n\t\t\t}\n\t\n\t\t\tstr = str.replace( token, value );\n\t\n\t\t} );\n\t\n\t\treturn str;\n\t\n\t};\n\t\n\t\t/**\n\t * Handle Lesson Preview Elements\n\t *\n\t * @package LifterLMS/Scripts\n\t *\n\t * @since 3.0.0\n\t * @version 3.16.12\n\t */\n\t\n\tLLMS.LessonPreview = {\n\t\n\t\t/**\n\t\t * A jQuery object of all outlines present on the current screen\n\t\t *\n\t\t * @type obj\n\t\t */\n\t\t$els: null,\n\t\n\t\t/**\n\t\t * Initialize\n\t\t *\n\t\t * @return void\n\t\t */\n\t\tinit: function() {\n\t\n\t\t\tvar self = this;\n\t\n\t\t\tthis.$locked = $( 'a[href=\"#llms-lesson-locked\"]' );\n\t\n\t\t\tif ( this.$locked.length ) {\n\t\n\t\t\t\tself.bind();\n\t\n\t\t\t}\n\t\n\t\t\tif ( $( '.llms-course-navigation' ).length ) {\n\t\n\t\t\t\tLLMS.wait_for_matchHeight( function() {\n\t\n\t\t\t\t\tself.match_height();\n\t\n\t\t\t\t} );\n\t\n\t\t\t}\n\t\n\t\t},\n\t\n\t\t/**\n\t\t * Bind DOM events\n\t\t *\n\t\t * @return void\n\t\t * @since 3.0.0\n\t\t * @version 3.16.12\n\t\t */\n\t\tbind: function() {\n\t\n\t\t\tvar self = this;\n\t\n\t\t\tthis.$locked.on( 'click', function() {\n\t\t\t\treturn false;\n\t\t\t} );\n\t\n\t\t\tthis.$locked.on( 'mouseenter', function() {\n\t\n\t\t\t\tvar $tip = $( this ).find( '.llms-tooltip' );\n\t\t\t\tif ( ! $tip.length ) {\n\t\t\t\t\tvar msg = $( this ).attr( 'data-tooltip-msg' );\n\t\t\t\t\tif ( ! msg ) {\n\t\t\t\t\t\tmsg = LLMS.l10n.translate( 'You do not have permission to access this content' );\n\t\t\t\t\t}\n\t\t\t\t\t$tip = self.get_tooltip( msg );\n\t\t\t\t\t$( this ).append( $tip );\n\t\t\t\t}\n\t\t\t\tsetTimeout( function() {\n\t\t\t\t\t$tip.addClass( 'show' );\n\t\t\t\t}, 10 );\n\t\n\t\t\t} );\n\t\n\t\t\tthis.$locked.on( 'mouseleave', function() {\n\t\n\t\t\t\tvar $tip = $( this ).find( '.llms-tooltip' );\n\t\t\t\t$tip.removeClass( 'show' );\n\t\n\t\t\t} );\n\t\n\t\t},\n\t\n\t\t/**\n\t\t * Match the height of lesson preview items in course navigation blocks\n\t\t *\n\t\t * @return void\n\t\t * @since 3.0.0\n\t\t * @version 3.0.0\n\t\t */\n\t\tmatch_height: function() {\n\t\n\t\t\t$( '.llms-course-navigation .llms-lesson-link' ).matchHeight();\n\t\n\t\t},\n\t\n\t\t/**\n\t\t * Get a tooltip element\n\t\t *\n\t\t * @param string msg message to display inside the tooltip\n\t\t * @return obj\n\t\t * @since 3.0.0\n\t\t * @version 3.2.4\n\t\t */\n\t\tget_tooltip: function( msg ) {\n\t\t\tvar $el = $( '
' );\n\t\t\t$el.append( '
' + msg + '
' );\n\t\t\treturn $el;\n\t\t},\n\t\n\t};\n\t\n\t\t/**\n\t * LifterLMS Loops JS\n\t *\n\t * @package LifterLMS/Scripts\n\t *\n\t * @since 3.0.0\n\t * @version 3.14.0\n\t */\n\t\n\tLLMS.Loops = {\n\t\n\t\t/**\n\t\t * Initialize\n\t\t *\n\t\t * @return void\n\t\t */\n\t\tinit: function() {\n\t\n\t\t\tvar self = this;\n\t\n\t\t\tif ( $( '.llms-loop' ).length ) {\n\t\n\t\t\t\tLLMS.wait_for_matchHeight( function() {\n\t\n\t\t\t\t\tself.match_height();\n\t\n\t\t\t\t} );\n\t\n\t\t\t}\n\t\n\t\t},\n\t\n\t\t/**\n\t\t * Match the height of .llms-loop-item\n\t\t *\n\t\t * @return void\n\t\t * @since 3.0.0\n\t\t * @version 3.14.0\n\t\t */\n\t\tmatch_height: function() {\n\t\n\t\t\t$( '.llms-loop-item .llms-loop-item-content' ).matchHeight();\n\t\t\t$( '.llms-achievement-loop-item .llms-achievement' ).matchHeight();\n\t\t\t$( '.llms-certificate-loop-item .llms-certificate' ).matchHeight();\n\t\n\t\t},\n\t\n\t};\n\t\n\t\t/**\n\t * Handle the Collapsible Syllabus Widget / Shortcode\n\t *\n\t * @package LifterLMS/Scripts\n\t *\n\t * @since Unknown\n\t * @version Unknown\n\t */\n\t\n\tLLMS.OutlineCollapse = {\n\t\n\t\t/**\n\t\t * A jQuery object of all outlines present on the current screen\n\t\t *\n\t\t * @type obj\n\t\t */\n\t\t$outlines: null,\n\t\n\t\t/**\n\t\t * Initialize\n\t\t *\n\t\t * @return void\n\t\t */\n\t\tinit: function() {\n\t\n\t\t\tthis.$outlines = $( '.llms-widget-syllabus--collapsible' );\n\t\n\t\t\tif ( this.$outlines.length ) {\n\t\n\t\t\t\tthis.bind();\n\t\n\t\t\t}\n\t\n\t\t},\n\t\n\t\t/**\n\t\t * Bind DOM events\n\t\t *\n\t\t * @return void\n\t\t */\n\t\tbind: function() {\n\t\n\t\t\tvar self = this;\n\t\n\t\t\tthis.$outlines.each( function() {\n\t\n\t\t\t\tvar $outline = $( this ),\n\t\t\t\t\t$headers = $outline.find( '.llms-section .section-header' );\n\t\n\t\t\t\t// bind header clicks\n\t\t\t\t$headers.on( 'click', function( e ) {\n\t\n\t\t\t\t\te.preventDefault();\n\t\n\t\t\t\t\tvar $toggle = $( this ),\n\t\t\t\t\t\t$section = $toggle.closest( '.llms-section' ),\n\t\t\t\t\t\tstate = self.get_section_state( $section );\n\t\n\t\t\t\t\tswitch ( state ) {\n\t\n\t\t\t\t\t\tcase 'closed':\n\t\t\t\t\t\t\tself.open_section( $section );\n\t\t\t\t\t\tbreak;\n\t\n\t\t\t\t\t\tcase 'opened':\n\t\t\t\t\t\t\tself.close_section( $section );\n\t\t\t\t\t\tbreak;\n\t\n\t\t\t\t\t}\n\t\n\t\t\t\t} );\n\t\n\t\t\t\t// bind optional toggle \"buttons\"\n\t\t\t\t$outline.find( '.llms-collapse-toggle' ).on( 'click', function( e ) {\n\t\n\t\t\t\t\te.preventDefault();\n\t\n\t\t\t\t\tvar $btn = $( this ),\n\t\t\t\t\t\taction = $btn.attr( 'data-action' ),\n\t\t\t\t\t\topposite_action = ( 'close' === action ) ? 'opened' : 'closed';\n\t\n\t\t\t\t\t$headers.each( function() {\n\t\n\t\t\t\t\t\tvar $section = $( this ).closest( '.llms-section' ),\n\t\t\t\t\t\t\tstate = self.get_section_state( $section );\n\t\n\t\t\t\t\t\tif ( opposite_action !== state ) {\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t}\n\t\n\t\t\t\t\t\tswitch ( state ) {\n\t\n\t\t\t\t\t\t\tcase 'closed':\n\t\t\t\t\t\t\t\tself.close_section( $section );\n\t\t\t\t\t\t\tbreak;\n\t\n\t\t\t\t\t\t\tcase 'opened':\n\t\t\t\t\t\t\t\tself.open_section( $section );\n\t\t\t\t\t\t\tbreak;\n\t\n\t\t\t\t\t\t}\n\t\n\t\t\t\t\t\t$( this ).trigger( 'click' );\n\t\n\t\t\t\t\t} );\n\t\n\t\t\t\t} );\n\t\n\t\t\t} );\n\t\n\t\t},\n\t\n\t\t/**\n\t\t * Close an outline section\n\t\t *\n\t\t * @param obj $section jQuery selector of a '.llms-section'\n\t\t * @return void\n\t\t */\n\t\tclose_section: function( $section ) {\n\t\n\t\t\t$section.removeClass( 'llms-section--opened' ).addClass( 'llms-section--closed' );\n\t\n\t\t},\n\t\n\t\t/**\n\t\t * Open an outline section\n\t\t *\n\t\t * @param obj $section jQuery selector of a '.llms-section'\n\t\t * @return void\n\t\t */\n\t\topen_section: function( $section ) {\n\t\n\t\t\t$section.removeClass( 'llms-section--closed' ).addClass( 'llms-section--opened' );\n\t\n\t\t},\n\t\n\t\t/**\n\t\t * Get the current state (open or closed) of an outline section\n\t\t *\n\t\t * @param obj $section jQuery selector of a '.llms-section'\n\t\t * @return string 'opened' or 'closed'\n\t\t */\n\t\tget_section_state: function( $section ) {\n\t\n\t\t\treturn $section.hasClass( 'llms-section--opened' ) ? 'opened' : 'closed';\n\t\n\t\t}\n\t\n\t};\n\t\n\t\t/**\n\t * Handle Password Strength Meter for registration and password update fields\n\t *\n\t * @package LifterLMS/Scripts\n\t *\n\t * @since 3.0.0\n\t * @version 5.0.0\n\t */\n\t\n\t$.extend( LLMS.PasswordStrength, {\n\t\n\t\t/**\n\t\t * jQuery ref for the password strength meter object.\n\t\t *\n\t\t * @type {Object}\n\t\t */\n\t\t$meter: $( '.llms-password-strength-meter' ),\n\t\n\t\t/**\n\t\t * jQuery ref for the password field.\n\t\t *\n\t\t * @type {Object}\n\t\t */\n\t\t$pass: null,\n\t\n\t\t/**\n\t\t * jQuery ref for the password confirmation field\n\t\t *\n\t\t * @type {Object}\n\t\t */\n\t\t$conf: null,\n\t\n\t\t/**\n\t\t * jQuery ref for form element.\n\t\t *\n\t\t * @type {Object}\n\t\t */\n\t\t$form: null,\n\t\n\t\t/**\n\t\t * Init\n\t\t * loads class methods\n\t\t *\n\t\t * @since 3.0.0\n\t\t * @since 3.7.0 Unknown\n\t\t * @since 5.0.0 Move reference setup to `setup_references()`.\n\t\t * Use `LLMS.wait_for()` for dependency waiting.\n\t\t *\n\t\t * @return {Void}\n\t\t */\n\t\tinit: function() {\n\t\n\t\t\tif ( $( 'body' ).hasClass( 'wp-admin' ) ) {\n\t\t\t\treturn;\n\t\t\t}\n\t\n\t\t\tif ( ! this.setup_references() ) {\n\t\t\t\treturn;\n\t\t\t}\n\t\n\t\t\tvar self = this;\n\t\n\t\t\tLLMS.wait_for( function() {\n\t\t\t\treturn ( 'undefined' !== typeof wp && 'undefined' !== typeof wp.passwordStrength );\n\t\t\t}, function() {\n\t\t\t\tself.bind();\n\t\t\t\tself.$form.trigger( 'llms-password-strength-ready' );\n\t\t\t} );\n\t\n\t\t},\n\t\n\t\t/**\n\t\t * Bind DOM Events\n\t\t *\n\t\t * @since 3.0.0\n\t\t *\n\t\t * @return void\n\t\t */\n\t\tbind: function() {\n\t\n\t\t\tvar self = this;\n\t\n\t\t\t// add submission event handlers when not on a checkout form\n\t\t\tif ( ! this.$form.hasClass( 'llms-checkout' ) ) {\n\t\t\t\tself.$form.on( 'submit', self, self.submit );\n\t\t\t}\n\t\n\t\t\t// check password strength on keyup\n\t\t\tself.$pass.add( self.$conf ).on( 'keyup', function() {\n\t\t\t\tself.check_strength();\n\t\t\t} );\n\t\n\t\t},\n\t\n\t\t/**\n\t\t * Check the strength of a user entered password\n\t\t * and update elements depending on the current strength\n\t\t *\n\t\t * @since 3.0.0\n\t\t * @since 5.0.0 Allow password confirmation to be optional when checking strength.\n\t\t *\n\t\t * @return void\n\t\t */\n\t\tcheck_strength: function() {\n\t\n\t\t\tvar $pass_field = this.$pass.closest( '.llms-form-field' ),\n\t\t\t\t$conf_field = this.$conf && this.$conf.length ? this.$conf.closest( '.llms-form-field' ) : null,\n\t\t\t\tpass_length = this.$pass.val().length,\n\t\t\t\tconf_length = this.$conf && this.$conf.length ? this.$conf.val().length : 0;\n\t\n\t\t\t// hide the meter if both fields are empty\n\t\t\tif ( ! pass_length && ! conf_length ) {\n\t\t\t\t$pass_field.removeClass( 'valid invalid' );\n\t\t\t\tif ( $conf_field ) {\n\t\t\t\t\t$conf_field.removeClass( 'valid invalid' );\n\t\t\t\t}\n\t\t\t\tthis.$meter.hide();\n\t\t\t\treturn;\n\t\t\t}\n\t\n\t\t\tif ( this.get_current_strength_status() ) {\n\t\t\t\t$pass_field.removeClass( 'invalid' ).addClass( 'valid' );\n\t\t\t\tif ( conf_length ) {\n\t\t\t\t\t$conf_field.removeClass( 'invalid' ).addClass( 'valid' );\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t$pass_field.removeClass( 'valid' ).addClass( 'invalid' );\n\t\t\t\tif ( conf_length ) {\n\t\t\t\t\t$conf_field.removeClass( 'valid' ).addClass( 'invalid' );\n\t\t\t\t}\n\t\t\t}\n\t\n\t\t\tthis.$meter.removeClass( 'too-short very-weak weak medium strong mismatch' );\n\t\t\tthis.$meter.show().addClass( this.get_current_strength( 'slug' ) );\n\t\t\tthis.$meter.html( this.get_current_strength( 'text' ) );\n\t\n\t\t},\n\t\n\t\t/**\n\t\t * Form submission action called during registration on checkout screen\n\t\t *\n\t\t * @since 3.0.0\n\t\t *\n\t\t * @param obj self instance of this class\n\t\t * @param Function callback callback function, passes error message or success back to checkout handler\n\t\t * @return void\n\t\t */\n\t\tcheckout: function( self, callback ) {\n\t\n\t\t\tif ( self.get_current_strength_status() ) {\n\t\n\t\t\t\tcallback( true );\n\t\n\t\t\t} else {\n\t\n\t\t\t\tcallback( LLMS.l10n.translate( 'There is an issue with your chosen password.' ) );\n\t\n\t\t\t}\n\t\t},\n\t\n\t\t/**\n\t\t * Get the list of blocklisted strings\n\t\t *\n\t\t * @since 5.0.0\n\t\t *\n\t\t * @return array\n\t\t */\n\t\tget_blocklist: function() {\n\t\n\t\t\t// Default values from WP Core + any values added via settings filter..\n\t\t\tvar blocklist = wp.passwordStrength.userInputDisallowedList().concat( this.get_setting( 'blocklist', [] ) );\n\t\n\t\t\t// Add values from all text fields in the form.\n\t\t\tthis.$form.find( 'input[type=\"text\"], input[type=\"email\"], input[type=\"tel\"], input[type=\"number\"]' ).each( function() {\n\t\t\t\tvar val = $( this ).val();\n\t\t\t\tif ( val ) {\n\t\t\t\t\tblocklist.push( val );\n\t\t\t\t}\n\t\t\t} );\n\t\n\t\t\treturn blocklist;\n\t\n\t\t},\n\t\n\t\t/**\n\t\t * Retrieve current strength as a number, a slug, or a translated text string\n\t\t *\n\t\t * @since 3.0.0\n\t\t * @since 5.0.0 Allow password confirmation to be optional when checking strength.\n\t\t *\n\t\t * @param {String} format Derived return format [int|slug|text] defaults to int.\n\t\t * @return mixed\n\t\t */\n\t\tget_current_strength: function( format ) {\n\t\n\t\t\tformat = format || 'int';\n\t\t\tvar pass = this.$pass.val(),\n\t\t\t\tconf = this.$conf && this.$conf.length ? this.$conf.val() : '',\n\t\t\t\tval;\n\t\n\t\t\t// enforce custom length requirement\n\t\t\tif ( pass.length < this.get_setting( 'min_length', 6 ) ) {\n\t\t\t\tval = -1;\n\t\t\t} else {\n\t\t\t\tval = wp.passwordStrength.meter( pass, this.get_blocklist(), conf );\n\t\t\t\t// 0 & 1 are both very-weak\n\t\t\t\tif ( 0 === val ) {\n\t\t\t\t\tval = 1;\n\t\t\t\t}\n\t\t\t}\n\t\n\t\t\tif ( 'slug' === format ) {\n\t\t\t\treturn this.get_strength_slug( val );\n\t\t\t} else if ( 'text' === format ) {\n\t\t\t\treturn this.get_strength_text( val );\n\t\t\t} else {\n\t\t\t\treturn val;\n\t\t\t}\n\t\t},\n\t\n\t\t/**\n\t\t * Determines if the current password strength meets the user-defined\n\t\t * minimum password strength requirements\n\t\t *\n\t\t * @since 3.0.0\n\t\t *\n\t\t * @return boolean\n\t\t */\n\t\tget_current_strength_status: function() {\n\t\t\tvar curr = this.get_current_strength(),\n\t\t\t\tmin = this.get_strength_value( this.get_minimum_strength() );\n\t\t\treturn ( 5 === curr ) ? false : ( curr >= min );\n\t\t},\n\t\n\t\t/**\n\t\t * Retrieve the minimum password strength for the current form.\n\t\t *\n\t\t * @since 3.0.0\n\t\t * @since 5.0.0 Replaces the version output via an inline PHP script in favor of utilizing values configured in the settings object.\n\t\t *\n\t\t * @return {string}\n\t\t */\n\t\tget_minimum_strength: function() {\n\t\t\treturn this.get_setting( 'min_strength', 'strong' );\n\t\t},\n\t\n\t\t/**\n\t\t * Get a setting and fallback to a default value.\n\t\t *\n\t\t * @since 5.0.0\n\t\t *\n\t\t * @param {String} key Setting key.\n\t\t * @param {mixed} default_val Default value when the requested setting cannot be located.\n\t\t * @return {mixed}\n\t\t */\n\t\tget_setting: function( key, default_val ) {\n\t\t\tvar settings = this.get_settings();\n\t\t\treturn settings[ key ] ? settings[ key ] : default_val;\n\t\t},\n\t\n\t\t/**\n\t\t * Get the slug associated with a strength value\n\t\t *\n\t\t * @since 3.0.0\n\t\t *\n\t\t * @param int strength_val Strength value number.\n\t\t * @return string\n\t\t */\n\t\tget_strength_slug: function( strength_val ) {\n\t\n\t\t\tvar slugs = {\n\t\t\t\t'-1': 'too-short',\n\t\t\t\t1: 'very-weak',\n\t\t\t\t2: 'weak',\n\t\t\t\t3: 'medium',\n\t\t\t\t4: 'strong',\n\t\t\t\t5: 'mismatch',\n\t\t\t};\n\t\n\t\t\treturn ( slugs[ strength_val ] ) ? slugs[ strength_val ] : slugs[5];\n\t\n\t\t},\n\t\n\t\t/**\n\t\t * Gets the translated text associated with a strength value\n\t\t *\n\t\t * @since 3.0.0\n\t\t *\n\t\t * @param {Integer} strength_val Strength value\n\t\t * @return {String}\n\t\t */\n\t\tget_strength_text: function( strength_val ) {\n\t\n\t\t\tvar texts = {\n\t\t\t\t'-1': LLMS.l10n.translate( 'Too Short' ),\n\t\t\t\t1: LLMS.l10n.translate( 'Very Weak' ),\n\t\t\t\t2: LLMS.l10n.translate( 'Weak' ),\n\t\t\t\t3: LLMS.l10n.translate( 'Medium' ),\n\t\t\t\t4: LLMS.l10n.translate( 'Strong' ),\n\t\t\t\t5: LLMS.l10n.translate( 'Mismatch' ),\n\t\t\t};\n\t\n\t\t\treturn ( texts[ strength_val ] ) ? texts[ strength_val ] : texts[5];\n\t\n\t\t},\n\t\n\t\t/**\n\t\t * Get the value associated with a strength slug\n\t\t *\n\t\t * @since 3.0.0\n\t\t *\n\t\t * @param string strength_slug A strength slug.\n\t\t * @return {Integer}\n\t\t */\n\t\tget_strength_value: function( strength_slug ) {\n\t\n\t\t\tvar values = {\n\t\t\t\t'too-short': -1,\n\t\t\t\t'very-weak': 1,\n\t\t\t\tweak: 2,\n\t\t\t\tmedium: 3,\n\t\t\t\tstrong: 4,\n\t\t\t\tmismatch: 5,\n\t\t\t};\n\t\n\t\t\treturn ( values[ strength_slug ] ) ? values[ strength_slug ] : values.mismatch;\n\t\n\t\t},\n\t\n\t\t/**\n\t\t * Setup jQuery references to DOM elements needed to power the password meter.\n\t\t *\n\t\t * @since 5.0.0\n\t\t *\n\t\t * @return {Boolean} Returns `true` if a meter element and password field are found, otherwise returns `false`.\n\t\t */\n\t\tsetup_references: function() {\n\t\n\t\t\tif ( ! this.$meter.length ) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\n\t\t\tthis.$form = this.$meter.closest( 'form' );\n\t\t\tthis.$pass = this.$form.find( 'input#password' );\n\t\n\t\t\tif ( this.$pass.length && this.$pass.attr( 'data-match' ) ) {\n\t\t\t\tthis.$conf = this.$form.find( '#' + this.$pass.attr( 'data-match' ) );\n\t\t\t}\n\t\n\t\t\treturn ( this.$pass.length > 0 );\n\t\n\t\t},\n\t\n\t\t/**\n\t\t * Form submission handler for registration and update forms\n\t\t *\n\t\t * @since 3.0.0\n\t\t * @since 5.0.0 Allow the account edit for to bypass strength checking when the password field is disabled (not being submitted).\n\t\t *\n\t\t * @param obj e Event data.\n\t\t * @return void\n\t\t */\n\t\tsubmit: function( e ) {\n\t\n\t\t\tvar self = e.data;\n\t\t\te.preventDefault();\n\t\t\tself.$pass.trigger( 'keyup' );\n\t\n\t\t\t// Meets the status requirements OR we're on the account edit form and the password field is disabled.\n\t\t\tif ( self.get_current_strength_status() || ( self.$form.hasClass( 'edit-account' ) && 'disabled' === self.$pass.attr( 'disabled' ) ) ) {\n\t\t\t\tself.$form.off( 'submit', self.submit );\n\t\t\t\tself.$form.trigger( 'submit' );\n\t\t\t} else {\n\t\t\t\t$( 'html, body' ).animate( {\n\t\t\t\t\tscrollTop: self.$meter.offset().top - 100,\n\t\t\t\t}, 200 );\n\t\t\t\tself.$meter.hide();\n\t\t\t\tsetTimeout( function() {\n\t\t\t\t\tself.$meter.fadeIn( 400 );\n\t\t\t\t}, 220 );\n\t\t\t}\n\t\t},\n\t\n\t\t/**\n\t\t * Get the list of blocklist strings\n\t\t *\n\t\t * @since 3.0.0\n\t\t * @deprecated 5.0.0 `LLMS.PasswordStrength.get_blacklist()` is deprecated in favor of `LLMS.PasswordStrength.get_blocklist()`.\n\t\t *\n\t\t * @return array\n\t\t */\n\t\tget_blacklist: function() {\n\t\t\tconsole.log( 'Method `get_blacklist()` is deprecated in favor of `get_blocklist()`.' );\n\t\t\treturn this.get_blacklist();\n\t\t},\n\t\n\t} );\n\t\n\t\t/**\n\t * Pricing Table UI\n\t *\n\t * @package LifterLMS/Scripts\n\t *\n\t * @since Unknown.\n\t * @version Unknown.\n\t */\n\t\n\tLLMS.Pricing_Tables = {\n\t\n\t\t/**\n\t\t * Init\n\t\t */\n\t\tinit: function() {\n\t\n\t\t\tvar self = this;\n\t\n\t\t\tif ( $( 'body' ).hasClass( 'wp-admin' ) ) {\n\t\t\t\treturn;\n\t\t\t}\n\t\n\t\t\tif ( $( '.llms-access-plans' ).length ) {\n\t\n\t\t\t\tLLMS.wait_for_matchHeight( function() {\n\t\t\t\t\tself.bind();\n\t\t\t\t} );\n\t\n\t\t\t\tthis.$locked = $( 'a[href=\"#llms-plan-locked\"]' );\n\t\n\t\t\t\tif ( this.$locked.length ) {\n\t\n\t\t\t\t\tLLMS.wait_for_popover( function() {\n\t\t\t\t\t\tself.bind_locked();\n\t\t\t\t\t} );\n\t\n\t\t\t\t}\n\t\n\t\t\t}\n\t\n\t\t},\n\t\n\t\t/**\n\t\t * Bind Method\n\t\t * Handles dom binding on load\n\t\t *\n\t\t * @return {[type]} [description]\n\t\t */\n\t\tbind: function() {\n\t\n\t\t\t$( '.llms-access-plan-content' ).matchHeight();\n\t\t\t$( '.llms-access-plan-pricing.trial' ).matchHeight();\n\t\n\t\t},\n\t\n\t\t/**\n\t\t * Setup a popover for members-only restricted plans\n\t\t *\n\t\t * @return void\n\t\t * @since 3.0.0\n\t\t * @version 3.9.1\n\t\t */\n\t\tbind_locked: function() {\n\t\n\t\t\tthis.$locked.each( function() {\n\t\n\t\t\t\t$( this ).webuiPopover( {\n\t\t\t\t\tanimation: 'pop',\n\t\t\t\t\tcloseable: true,\n\t\t\t\t\tcontent: function( e ) {\n\t\t\t\t\t\tvar $content = $( '
' );\n\t\t\t\t\t\t$content.append( e.$element.closest( '.llms-access-plan' ).find( '.llms-access-plan-restrictions ul' ).clone() );\n\t\t\t\t\t\treturn $content;\n\t\t\t\t\t},\n\t\t\t\t\tplacement: 'top',\n\t\t\t\t\tstyle: 'inverse',\n\t\t\t\t\ttitle: LLMS.l10n.translate( 'Members Only Pricing' ),\n\t\t\t\t\twidth: '280px',\n\t\t\t\t} );\n\t\n\t\t\t} );\n\t\n\t\t},\n\t\n\t};\n\t\n\t\t/**\n\t * LifterLMS Reviews JS\n\t *\n\t * @package LifterLMS/Scripts\n\t *\n\t * @since Unknown\n\t * @version Unknown\n\t */\n\t\n\tLLMS.Review = {\n\t\t/**\n\t\t * Init\n\t\t * loads class methods\n\t\t */\n\t\tinit: function() {\n\t\t\t// console.log('Initializing Review ');\n\t\t\tthis.bind();\n\t\t},\n\t\n\t\t/**\n\t\t * This function binds actions to the appropriate hooks\n\t\t */\n\t\tbind: function() {\n\t\t\t$( '#llms_review_submit_button' ).click(function()\n\t\t\t\t{\n\t\t\t\tif ($( '#review_title' ).val() !== '' && $( '#review_text' ).val() !== '') {\n\t\t\t\t\tjQuery.ajax({\n\t\t\t\t\t\ttype : 'post',\n\t\t\t\t\t\tdataType : 'json',\n\t\t\t\t\t\turl : window.llms.ajaxurl,\n\t\t\t\t\t\tdata : {\n\t\t\t\t\t\t\taction : 'LLMSSubmitReview',\n\t\t\t\t\t\t\treview_title: $( '#review_title' ).val(),\n\t\t\t\t\t\t\treview_text: $( '#review_text' ).val(),\n\t\t\t\t\t\t\tpageID : $( '#post_ID' ).val()\n\t\t\t\t\t\t},\n\t\t\t\t\t\tsuccess: function()\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tconsole.log( 'Review success' );\n\t\t\t\t\t\t\t$( '#review_box' ).hide( 'swing' );\n\t\t\t\t\t\t\t$( '#thank_you_box' ).show( 'swing' );\n\t\t\t\t\t\t},\n\t\t\t\t\t\terror: function(jqXHR, textStatus, errorThrown )\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tconsole.log( jqXHR );\n\t\t\t\t\t\t\tconsole.log( textStatus );\n\t\t\t\t\t\t\tconsole.log( errorThrown );\n\t\t\t\t\t\t},\n\t\t\t\t\t});\n\t\t\t\t} else {\n\t\t\t\t\tif ($( '#review_title' ).val() === '') {\n\t\t\t\t\t\t$( '#review_title_error' ).show( 'swing' );\n\t\t\t\t\t} else {\n\t\t\t\t\t\t$( '#review_title_error' ).hide( 'swing' );\n\t\t\t\t\t}\n\t\t\t\t\tif ($( '#review_text' ).val() === '') {\n\t\t\t\t\t\t$( '#review_text_error' ).show( 'swing' );\n\t\t\t\t\t} else {\n\t\t\t\t\t\t$( '#review_text_error' ).hide( 'swing' );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\t\tif ( $( '#_llms_display_reviews' ).attr( 'checked' ) ) {\n\t\t\t\t$( '.llms-num-reviews-top' ).addClass( 'top' );\n\t\t\t\t$( '.llms-num-reviews-bottom' ).show();\n\t\n\t\t\t} else {\n\t\t\t\t$( '.llms-num-reviews-bottom' ).hide();\n\t\t\t}\n\t\t\t$( '#_llms_display_reviews' ).change(function() {\n\t\t\t\tif ( $( '#_llms_display_reviews' ).attr( 'checked' ) ) {\n\t\t\t\t\t$( '.llms-num-reviews-top' ).addClass( 'top' );\n\t\t\t\t\t$( '.llms-num-reviews-bottom' ).show();\n\t\t\t\t} else {\n\t\t\t\t\t$( '.llms-num-reviews-top' ).removeClass( 'top' );\n\t\t\t\t\t$( '.llms-num-reviews-bottom' ).hide();\n\t\t\t\t}\n\t\t\t});\n\t\n\t\t},\n\t};\n\t\n\t\t/**\n\t * Add Spinners for AJAX events\n\t *\n\t * @package LifterLMS/Scripts\n\t *\n\t * @since 3.0.0\n\t * @version 3.0.0\n\t */\n\t\n\tLLMS.Spinner = {\n\t\n\t\t/**\n\t\t * Get an exiting spinner element or create a new one\n\t\t *\n\t\t * @param obj $el jQuery selector of the parent element that should hold and be mased by a spinner\n\t\t * @param string size size or the spinner [default|small]\n\t\t * default is 40px\n\t\t * small is 20px\n\t\t * @return obj\n\t\t * @since 3.0.0\n\t\t * @version 3.0.0\n\t\t */\n\t\tget: function( $el, size ) {\n\t\n\t\t\t// look for an existing spinner\n\t\t\tvar $spinner = $el.find( '.llms-spinning' ).first();\n\t\n\t\t\t// no spinner inside $el\n\t\t\tif ( ! $spinner.length ) {\n\t\n\t\t\t\tsize = ( size ) ? size : 'default';\n\t\n\t\t\t\t// create the spinner\n\t\t\t\t$spinner = $( '
' );\n\t\n\t\t\t\t// add it to the dom\n\t\t\t\t$el.append( $spinner );\n\t\n\t\t\t}\n\t\n\t\t\t// return it\n\t\t\treturn $spinner;\n\t\n\t\t},\n\t\n\t\t/**\n\t\t * Start spinner(s) inr=side a given element\n\t\t * Creates them if they don't exist!\n\t\t *\n\t\t * @param obj $el jQuery selector of the parent element that should hold and be mased by a spinner\n\t\t * @param string size size or the spinner [default|small]\n\t\t * default is 40px\n\t\t * small is 20px\n\t\t * @return void\n\t\t * @since 3.0.0\n\t\t * @version 3.0.0\n\t\t */\n\t\tstart: function( $el, size ) {\n\t\n\t\t\tvar self = this;\n\t\n\t\t\t$el.each( function() {\n\t\n\t\t\t\tself.get( $( this ), size ).show();\n\t\n\t\t\t} );\n\t\n\t\t},\n\t\n\t\t/**\n\t\t * Store spinners within an element\n\t\t *\n\t\t * @param obj $el jQuery selector of the parent element that should hold and be mased by a spinner\n\t\t * @return void\n\t\t * @since 3.0.0\n\t\t * @version 3.0.0\n\t\t */\n\t\tstop: function( $el ) {\n\t\n\t\t\tvar self = this;\n\t\n\t\t\t$el.each( function() {\n\t\n\t\t\t\tself.get( $( this ) ).hide();\n\t\n\t\t\t} );\n\t\n\t\t}\n\t\n\t};\n\t\n\t\t/* global LLMS, $ */\n\t\n\t/*!\n\t * JavaScript Cookie v2.2.1\n\t * https://github.com/js-cookie/js-cookie\n\t *\n\t * Copyright 2006, 2015 Klaus Hartl & Fagner Brack\n\t * Released under the MIT license\n\t */\n\t;(function (factory) {\n\t\tvar registeredInModuleLoader;\n\t\tif (typeof define === 'function' && define.amd) {\n\t\t\tdefine(factory);\n\t\t\tregisteredInModuleLoader = true;\n\t\t}\n\t\tif (typeof exports === 'object') {\n\t\t\tmodule.exports = factory();\n\t\t\tregisteredInModuleLoader = true;\n\t\t}\n\t\tif (!registeredInModuleLoader) {\n\t\t\tvar OldCookies = window.Cookies;\n\t\t\tvar api = window.Cookies = factory();\n\t\t\tapi.noConflict = function () {\n\t\t\t\twindow.Cookies = OldCookies;\n\t\t\t\treturn api;\n\t\t\t};\n\t\t}\n\t}(function () {\n\t\tfunction extend () {\n\t\t\tvar i = 0;\n\t\t\tvar result = {};\n\t\t\tfor (; i < arguments.length; i++) {\n\t\t\t\tvar attributes = arguments[ i ];\n\t\t\t\tfor (var key in attributes) {\n\t\t\t\t\tresult[key] = attributes[key];\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn result;\n\t\t}\n\t\n\t\tfunction decode (s) {\n\t\t\treturn s.replace(/(%[0-9A-Z]{2})+/g, decodeURIComponent);\n\t\t}\n\t\n\t\tfunction init (converter) {\n\t\t\tfunction api() {}\n\t\n\t\t\tfunction set (key, value, attributes) {\n\t\t\t\tif (typeof document === 'undefined') {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\n\t\t\t\tattributes = extend({\n\t\t\t\t\tpath: '/'\n\t\t\t\t}, api.defaults, attributes);\n\t\n\t\t\t\tif (typeof attributes.expires === 'number') {\n\t\t\t\t\tattributes.expires = new Date(new Date() * 1 + attributes.expires * 864e+5);\n\t\t\t\t}\n\t\n\t\t\t\t// We're using \"expires\" because \"max-age\" is not supported by IE\n\t\t\t\tattributes.expires = attributes.expires ? attributes.expires.toUTCString() : '';\n\t\n\t\t\t\ttry {\n\t\t\t\t\tvar result = JSON.stringify(value);\n\t\t\t\t\tif (/^[\\{\\[]/.test(result)) {\n\t\t\t\t\t\tvalue = result;\n\t\t\t\t\t}\n\t\t\t\t} catch (e) {}\n\t\n\t\t\t\tvalue = converter.write ?\n\t\t\t\t\tconverter.write(value, key) :\n\t\t\t\t\tencodeURIComponent(String(value))\n\t\t\t\t\t\t.replace(/%(23|24|26|2B|3A|3C|3E|3D|2F|3F|40|5B|5D|5E|60|7B|7D|7C)/g, decodeURIComponent);\n\t\n\t\t\t\tkey = encodeURIComponent(String(key))\n\t\t\t\t\t.replace(/%(23|24|26|2B|5E|60|7C)/g, decodeURIComponent)\n\t\t\t\t\t.replace(/[\\(\\)]/g, escape);\n\t\n\t\t\t\tvar stringifiedAttributes = '';\n\t\t\t\tfor (var attributeName in attributes) {\n\t\t\t\t\tif (!attributes[attributeName]) {\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tstringifiedAttributes += '; ' + attributeName;\n\t\t\t\t\tif (attributes[attributeName] === true) {\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\n\t\t\t\t\t// Considers RFC 6265 section 5.2:\n\t\t\t\t\t// ...\n\t\t\t\t\t// 3. If the remaining unparsed-attributes contains a %x3B (\";\")\n\t\t\t\t\t// character:\n\t\t\t\t\t// Consume the characters of the unparsed-attributes up to,\n\t\t\t\t\t// not including, the first %x3B (\";\") character.\n\t\t\t\t\t// ...\n\t\t\t\t\tstringifiedAttributes += '=' + attributes[attributeName].split(';')[0];\n\t\t\t\t}\n\t\n\t\t\t\treturn (document.cookie = key + '=' + value + stringifiedAttributes);\n\t\t\t}\n\t\n\t\t\tfunction get (key, json) {\n\t\t\t\tif (typeof document === 'undefined') {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\n\t\t\t\tvar jar = {};\n\t\t\t\t// To prevent the for loop in the first place assign an empty array\n\t\t\t\t// in case there are no cookies at all.\n\t\t\t\tvar cookies = document.cookie ? document.cookie.split('; ') : [];\n\t\t\t\tvar i = 0;\n\t\n\t\t\t\tfor (; i < cookies.length; i++) {\n\t\t\t\t\tvar parts = cookies[i].split('=');\n\t\t\t\t\tvar cookie = parts.slice(1).join('=');\n\t\n\t\t\t\t\tif (!json && cookie.charAt(0) === '\"') {\n\t\t\t\t\t\tcookie = cookie.slice(1, -1);\n\t\t\t\t\t}\n\t\n\t\t\t\t\ttry {\n\t\t\t\t\t\tvar name = decode(parts[0]);\n\t\t\t\t\t\tcookie = (converter.read || converter)(cookie, name) ||\n\t\t\t\t\t\t\tdecode(cookie);\n\t\n\t\t\t\t\t\tif (json) {\n\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\tcookie = JSON.parse(cookie);\n\t\t\t\t\t\t\t} catch (e) {}\n\t\t\t\t\t\t}\n\t\n\t\t\t\t\t\tjar[name] = cookie;\n\t\n\t\t\t\t\t\tif (key === name) {\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t} catch (e) {}\n\t\t\t\t}\n\t\n\t\t\t\treturn key ? jar[key] : jar;\n\t\t\t}\n\t\n\t\t\tapi.set = set;\n\t\t\tapi.get = function (key) {\n\t\t\t\treturn get(key, false /* read as raw */);\n\t\t\t};\n\t\t\tapi.getJSON = function (key) {\n\t\t\t\treturn get(key, true /* read as json */);\n\t\t\t};\n\t\t\tapi.remove = function (key, attributes) {\n\t\t\t\tset(key, '', extend(attributes, {\n\t\t\t\t\texpires: -1\n\t\t\t\t}));\n\t\t\t};\n\t\n\t\t\tapi.defaults = {};\n\t\n\t\t\tapi.withConverter = init;\n\t\n\t\t\treturn api;\n\t\t}\n\t\n\t\treturn init(function () {});\n\t}));\n\t\n\t/**\n\t * Create a no conflict reference to JS Cookies.\n\t *\n\t * @type {Object}\n\t */\n\tLLMS.CookieStore = Cookies.noConflict();\n\t\n\t/**\n\t * Store information in Local Storage by group.\n\t *\n\t * @since 3.36.0\n\t * @since 3.37.14 Use persistent reference to JS Cookies.\n\t * @since 4.2.0 Set sameSite to `strict` for cookies.\n\t *\n\t * @param string group Storage group id/name.\n\t */\n\tLLMS.Storage = function( group ) {\n\t\n\t\tvar self = this,\n\t\t\tstore = LLMS.CookieStore;\n\t\n\t\t/**\n\t\t * Clear all data for the group.\n\t\t *\n\t\t * @since 3.36.0\n\t\t *\n\t\t * @return void\n\t\t */\n\t\tthis.clearAll = function() {\n\t\t\tstore.remove( group );\n\t\t};\n\t\n\t\t/**\n\t\t * Clear a single item from the group by key.\n\t\t *\n\t\t * @since 3.36.0\n\t\t *\n\t\t * @return obj\n\t\t */\n\t\tthis.clear = function( key ) {\n\t\t\tvar data = self.getAll();\n\t\t\tdelete data[ key ];\n\t\t\treturn store.set( group, data );\n\t\t};\n\t\n\t\t/**\n\t\t * Retrieve (and parse) all data stored for the group.\n\t\t *\n\t\t * @since 3.36.0\n\t\t *\n\t\t * @return obj\n\t\t */\n\t\tthis.getAll = function() {\n\t\t\treturn store.getJSON( group ) || {};\n\t\t}\n\t\n\t\t/**\n\t\t * Retrieve an item from the group by key.\n\t\t *\n\t\t * @since 3.36.0\n\t\t *\n\t\t * @param string key Item key/name.\n\t\t * @param mixed default_val Item default value to be returned when item not found in the group.\n\t\t * @return mixed\n\t\t */\n\t\tthis.get = function( key, default_val ) {\n\t\t\tvar data = self.getAll();\n\t\t\treturn data[ key ] ? data[ key ] : default_val;\n\t\t}\n\t\n\t\t/**\n\t\t * Store an item in the group by key.\n\t\t *\n\t\t * @since 3.36.0\n\t\t * @since 4.2.0 Set sameSite to `strict` for cookies.\n\t\t *\n\t\t * @param string key Item key name.\n\t\t * @param mixed val Item value\n\t\t * @return obj\n\t\t */\n\t\tthis.set = function( key, val ) {\n\t\t\tvar data = self.getAll();\n\t\t\tdata[ key ] = val;\n\t\t\treturn store.set( group, data, { sameSite: 'strict' } );\n\t\t};\n\t\n\t}\n\t\n\t\t/**\n\t * Student Dashboard related JS\n\t *\n\t * @package LifterLMS/Scripts\n\t *\n\t * @since 3.7.0\n\t * @since 3.10.0 Bind events on the orders screen.\n\t * @since 5.0.0 Removed redundant password toggle logic for edit account screen.\n\t * @version 5.0.0\n\t */\n\tLLMS.StudentDashboard = {\n\t\n\t\t/**\n\t\t * Slug for the current screen/endpoint\n\t\t *\n\t\t * @type {String}\n\t\t */\n\t\tscreen: '',\n\t\n\t\t/**\n\t\t * Init\n\t\t *\n\t\t * @since 3.7.0\n\t\t * @since 3.10.0 Unknown\n\t\t * @since 5.0.0 Removed password toggle logic.\n\t\t *\n\t\t * @return void\n\t\t */\n\t\tinit: function() {\n\t\n\t\t\tif ( $( '.llms-student-dashboard' ).length ) {\n\t\t\t\tthis.bind();\n\t\t\t\tif ( 'orders' === this.get_screen() ) {\n\t\t\t\t\tthis.bind_orders();\n\t\t\t\t}\n\t\t\t}\n\t\n\t\t},\n\t\n\t\t/**\n\t\t * Bind DOM events\n\t\t *\n\t\t * @since 3.7.0\n\t\t * @since 3.7.4 Unknown.\n\t\t * @since 5.0.0 Removed password toggle logic.\n\t\t *\n\t\t * @return void\n\t\t */\n\t\tbind: function() {\n\t\n\t\t\t$( '.llms-donut' ).each( function() {\n\t\t\t\tLLMS.Donut( $( this ) );\n\t\t\t} );\n\t\n\t\t},\n\t\n\t\t/**\n\t\t * Bind events related to the orders screen on the dashboard\n\t\t *\n\t\t * @since 3.10.0\n\t\t *\n\t\t * @return void\n\t\t */\n\t\tbind_orders: function() {\n\t\n\t\t\t$( '#llms-cancel-subscription-form' ).on( 'submit', this.order_cancel_warning );\n\t\t\t$( '#llms_update_payment_method' ).on( 'click', function() {\n\t\t\t\t$( 'input[name=\"llms_payment_gateway\"]:checked' ).trigger( 'change' );\n\t\t\t\t$( this ).closest( 'form' ).find( '.llms-switch-payment-source-main' ).slideToggle( '200' );\n\t\t\t} );\n\t\n\t\t},\n\t\n\t\t/**\n\t\t * Get the current dashboard endpoint/tab slug\n\t\t *\n\t\t * @since 3.10.0\n\t\t *\n\t\t * @return void\n\t\t */\n\t\tget_screen: function() {\n\t\t\tif ( ! this.screen ) {\n\t\t\t\tthis.screen = $( '.llms-student-dashboard' ).attr( 'data-current' );\n\t\t\t}\n\t\t\treturn this.screen;\n\t\t},\n\t\n\t\t/**\n\t\t * Show a confirmation warning when Cancel Subscription form is submitted\n\t\t *\n\t\t * @since 3.10.0\n\t\t *\n\t\t * @param obj e JS event data.\n\t\t * @return void\n\t\t */\n\t\torder_cancel_warning: function( e ) {\n\t\t\te.preventDefault();\n\t\t\tvar msg = LLMS.l10n.translate( 'Are you sure you want to cancel your subscription?' );\n\t\t\tif ( window.confirm( LLMS.l10n.translate( msg ) ) ) {\n\t\t\t\t$( this ).off( 'submit', this.order_cancel_warning );\n\t\t\t\t$( this ).submit();\n\t\t\t}\n\t\t},\n\t\n\t};\n\t\n\t\t/* global LLMS, $ */\n\t\n\t/**\n\t * User event/interaction tracking.\n\t *\n\t * @since 3.36.0\n\t * @since 3.36.2 Fix JS error when settings aren't loaded.\n\t * @since 3.37.2 When adding an event to the storae also make sure the nonce is set for server-side verification.\n\t * @since 3.37.9 Fix IE compatibility issue related to usage of `Object.assign()`.\n\t * @since 3.37.14 Persist the tracking events via ajax when reaching the cookie size limit.\n\t * @since 5.0.0 Set `settings` as an empty object when no settings supplied.\n\t * Only attempt to add a nonce to the datastore when a nonce exists in the settings object.\n\t */\n\tLLMS.Tracking = function( settings ) {\n\t\n\t\tsettings = settings || {};\n\t\n\t\tvar self = this,\n\t\t\tstore = new LLMS.Storage( 'llms-tracking' );\n\t\n\t\tsettings = 'string' === typeof settings ? JSON.parse( settings ) : settings;\n\t\n\t\t/**\n\t\t * Initialize / Bind all tracking event listeners.\n\t\t *\n\t\t * @since 3.36.0\n\t\t * @since 5.0.0 Only attempt to add a nonce to the datastore when a nonce exists in the settings object.\n\t\t *\n\t\t * @return {void}\n\t\t */\n\t\tfunction init() {\n\t\n\t\t\t// Set the nonce for server-side verification.\n\t\t\tif ( settings.nonce ) {\n\t\n\t\t\t\tstore.set( 'nonce', settings.nonce );\n\t\n\t\t\t}\n\t\n\t\t\tself.addEvent( 'page.load' );\n\t\n\t\t\twindow.addEventListener( 'beforeunload', onBeforeUnload );\n\t\t\twindow.addEventListener( 'unload', onUnload );\n\t\n\t\t\tdocument.addEventListener( 'visibilitychange', onVisibilityChange );\n\t\n\t\t};\n\t\n\t\t/**\n\t\t * Add an event.\n\t\t *\n\t\t * @since 3.36.0\n\t\t * @since 3.36.2 Fix error when settings aren't loaded.\n\t\t * @since 3.37.2 Always make sure the nonce is set for server-side verification.\n\t\t * @since 3.37.14 Persist the tracking events via ajax when reaching the cookie size limit.\n\t\t *\n\t\t * @param string|obj event Event Id (type.event) or a full event object from `this.makeEventObj()`.\n\t\t * @param int args Optional additional arguments to pass to `this.makeEventObj()`.\n\t\t * @return {void}\n\t\t */\n\t\tthis.addEvent = function( event, args ) {\n\t\n\t\t\targs = args || {};\n\t\t\tif ( 'string' === typeof event ) {\n\t\t\t\targs.event = event;\n\t\t\t}\n\t\n\t\t\t// If the event isn't registered in the settings don't proceed.\n\t\t\tif ( !settings.events || -1 === settings.events.indexOf( args.event ) ) {\n\t\t\t\treturn;\n\t\t\t}\n\t\n\t\t\t// Make sure the nonce is set for server-side verification.\n\t\t\tstore.set( 'nonce', settings.nonce );\n\t\n\t\t\tevent = self.makeEventObj( args );\n\t\n\t\t\tvar all = store.get( 'events', [] );\n\t\t\tall.push( event );\n\t\t\tstore.set( 'events', all );\n\t\n\t\t\t// If couldn't store the latest event because of size limits.\n\t\t\tif ( all.length > store.get( 'events', [] ).length ) {\n\t\n\t\t\t\t// Copy the cookie in a temporary variable.\n\t\t\t\tvar _temp = store.getAll();\n\t\t\t\t// Clear the events from the cookie.\n\t\t\t\tstore.clear('events');\n\t\n\t\t\t\t// Add the latest event to the temporary variable.\n\t\t\t\t_temp['events'].push( event );\n\t\n\t\t\t\t// Send the temporary variable as string via ajax.\n\t\t\t\tLLMS.Ajax.call( {\n\t\t\t\t\tdata: {\n\t\t\t\t\t\taction: 'persist_tracking_events',\n\t\t\t\t\t\t'llms-tracking': JSON.stringify(_temp)\n\t\t\t\t\t},\n\t\n\t\t\t\t\terror: function( xhr, status, error ) {\n\t\n\t\t\t\t\t\tconsole.log( xhr, status, error );\n\t\n\t\t\t\t\t},\n\t\t\t\t\tsuccess: function( r ) {\n\t\n\t\t\t\t\t\tif ( 'error' === r.code ) {\n\t\t\t\t\t\t\tconsole.log(r.code, r.message);\n\t\t\t\t\t\t}\n\t\n\t\t\t\t\t}\n\t\n\t\t\t\t} );\n\t\n\t\t\t}\n\t\n\t\t}\n\t\n\t\t/**\n\t\t * Retrieve initialization settings.\n\t\t *\n\t\t * @since 3.36.0\n\t\t *\n\t\t * @return obj\n\t\t */\n\t\tthis.getSettings = function() {\n\t\t\treturn settings;\n\t\t}\n\t\n\t\t/**\n\t\t * Create an event object suitable to save as an event.\n\t\t *\n\t\t * @since 3.36.0\n\t\t * @since 3.37.9 Use `$.extend()` in favor of `Object.assign()`.\n\t\t *\n\t\t * @param obj event {\n\t\t * Event hash\n\t\t *\n\t\t * @param {string} event (Required) Event ID, eg: \"page.load\".\n\t\t * @param {url} url Event URL. (Optional, added automatically) Stored as metadata and used to infer an object_id for post events.\n\t\t * @param {time} float (Optional, added automatically) Timestamp (in milliseconds). Used for the event creation date.\n\t\t * @param {int} obj_id (Optional). The object ID. Inferred automatically via `url` if not provided.\n\t\t * @param {obj} meta (Optional) Hash of metadata to store with the event.\n\t\t * }\n\t\t * @return obj\n\t\t */\n\t\tthis.makeEventObj = function( event ) {\n\t\t\treturn $.extend( event, {\n\t\t\t\turl: window.location.href,\n\t\t\t\ttime: Math.round( new Date().getTime() / 1000 ),\n\t\t\t} );\n\t\t}\n\t\n\t\n\t\t/**\n\t\t * Remove the visibility change event listener on window.beforeunload\n\t\t *\n\t\t * Prevents actual unloading from recording a blur event from the visibility change listener\n\t\t *\n\t\t * @param obj e JS event object.\n\t\t * @return void\n\t\t */\n\t\tfunction onBeforeUnload( e ) {\n\t\t\tdocument.removeEventListener( 'visibilitychange', onVisibilityChange );\n\t\t}\n\t\n\t\t/**\n\t\t * Record a `page.exit` event on window.unload.\n\t\t *\n\t\t * @since 3.36.0\n\t\t *\n\t\t * @param obj e JS event object.\n\t\t * @return void\n\t\t */\n\t\tfunction onUnload( e ) {\n\t\t\tself.addEvent( 'page.exit' );\n\t\t}\n\t\n\t\t/**\n\t\t * Record `page.blur` and `page.focus` events via document.visilibitychange events.\n\t\t *\n\t\t * @since 3.36.0\n\t\t *\n\t\t * @param obj e JS event object.\n\t\t * @return void\n\t\t */\n\t\tfunction onVisibilityChange( e ) {\n\t\n\t\t\tvar event = document.hidden ? 'page.blur' : 'page.focus';\n\t\t\tself.addEvent( event );\n\t\n\t\t}\n\t\n\t\t// Initialize on the frontend only.\n\t\tif ( ! $( 'body' ).hasClass( 'wp-admin' ) ) {\n\t\t\tinit();\n\t\t}\n\t\n\t};\n\t\n\tllms.tracking = new LLMS.Tracking( llms.tracking );\n\t\n\t\t/**\n\t * Rest Methods\n\t * Manages URL and Rest object parsing\n\t *\n\t * @package LifterLMS/Scripts\n\t *\n\t * @since Unknown\n\t * @version Unknown\n\t */\n\t\n\tLLMS.Rest = {\n\t\n\t\t/**\n\t\t * Init\n\t\t * loads class methods\n\t\t */\n\t\tinit: function() {\n\t\t\tthis.bind();\n\t\t},\n\t\n\t\t/**\n\t\t * Bind Method\n\t\t * Handles dom binding on load\n\t\t *\n\t\t * @return {[type]} [description]\n\t\t */\n\t\tbind: function() {\n\t\t},\n\t\n\t\t/**\n\t\t * Searches for string matches in url path\n\t\t *\n\t\t * @param {Array} strings [Array of strings to search for matches]\n\t\t * @return {Boolean} [Was a match found?]\n\t\t */\n\t\tis_path: function( strings ) {\n\t\n\t\t\tvar path_exists = false,\n\t\t\t\turl = window.location.href;\n\t\n\t\t\tfor ( var i = 0; i < strings.length; i++ ) {\n\t\n\t\t\t\tif ( url.search( strings[i] ) > 0 && ! path_exists ) {\n\t\n\t\t\t\t\tpath_exists = true;\n\t\t\t\t}\n\t\t\t}\n\t\n\t\t\treturn path_exists;\n\t\t},\n\t\n\t\t/**\n\t\t * Retrieves query variables\n\t\t *\n\t\t * @return {[Array]} [array object of query variable key=>value pairs]\n\t\t */\n\t\tget_query_vars: function() {\n\t\n\t\t\tvar vars = [], hash,\n\t\t\t\thashes = window.location.href.slice( window.location.href.indexOf( '?' ) + 1 ).split( '&' );\n\t\n\t\t\tfor (var i = 0; i < hashes.length; i++) {\n\t\t\t\thash = hashes[i].split( '=' );\n\t\t\t\tvars.push( hash[0] );\n\t\t\t\tvars[hash[0]] = hash[1];\n\t\t\t}\n\t\n\t\t\treturn vars;\n\t\t}\n\t\n\t};\n\t\n\n\t/**\n\t * Initializes all classes within the LLMS Namespace\n\t *\n\t * @since Unknown\n\t *\n\t * @return {void}\n\t */\n\tLLMS.init = function() {\n\n\t\tfor (var func in LLMS) {\n\n\t\t\tif ( typeof LLMS[func] === 'object' && LLMS[func] !== null ) {\n\n\t\t\t\tif ( LLMS[func].init !== undefined ) {\n\n\t\t\t\t\tif ( typeof LLMS[func].init === 'function') {\n\t\t\t\t\t\tLLMS[func].init();\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t};\n\n\t/**\n\t * Determine if the current device is touch-enabled\n\t *\n\t * @since 3.24.3\n\t *\n\t * @see {@link https://stackoverflow.com/a/4819886/400568}\n\t *\n\t * @return {Boolean} Whether or not the device is touch-enabled.\n\t */\n\tLLMS.is_touch_device = function() {\n\n\t\tvar prefixes = ' -webkit- -moz- -o- -ms- '.split( ' ' );\n\t\tvar mq = function( query ) {\n\t\t\treturn window.matchMedia( query ).matches;\n\t\t}\n\n\t\tif ( ( 'ontouchstart' in window ) || window.DocumentTouch && document instanceof DocumentTouch ) {\n\t\t\treturn true;\n\t\t}\n\n\t\t/**\n\t\t * Include the 'heartz' as a way to have a non matching MQ to help terminate the join.\n\t\t *\n\t\t * @see {@link https://git.io/vznFH}\n\t\t */\n\t\tvar query = ['(', prefixes.join( 'touch-enabled),(' ), 'heartz', ')'].join( '' );\n\t\treturn mq( query );\n\n\t};\n\n\t/**\n\t * Wait for matchHeight to load\n\t *\n\t * @since 3.0.0\n\t * @since 3.16.6 Unknown.\n\t * @since 5.3.3 Pass a dependency name to `wait_for()`.\n\t *\n\t * @param {Function} cb Callback function to run when matchheight is ready.\n\t * @return {void}\n\t */\n\tLLMS.wait_for_matchHeight = function( cb ) {\n\t\tthis.wait_for( function() {\n\t\t\treturn ( undefined !== $.fn.matchHeight );\n\t\t}, cb, 'matchHeight' );\n\t}\n\n\t/**\n\t * Wait for webuiPopover to load\n\t *\n\t * @since 3.9.1\n\t * @since 3.16.6 Unknown.\n\t *\n\t * @param {Function} cb Callback function to run when matchheight is ready.\n\t * @return {void}\n\t */\n\tLLMS.wait_for_popover = function( cb ) {\n\t\tthis.wait_for( function() {\n\t\t\treturn ( undefined !== $.fn.webuiPopover );\n\t\t}, cb, 'webuiPopover' );\n\t}\n\n\t/**\n\t * Wait for a dependency to load and then run a callback once it has\n\t *\n\t * Temporary fix for a less-than-optimal assets loading function on the PHP side of things.\n\t *\n\t * @since 3.9.1\n\t * @since 5.3.3 Added optional `name` parameter.\n\t *\n\t * @param {Function} test A function that returns a truthy if the dependency is loaded.\n\t * @param {Function} cb A callback function executed once the dependency is loaded.\n\t * @param {string} name The dependency name.\n\t * @return {void}\n\t */\n\tLLMS.wait_for = function( test, cb, name ) {\n\n\t\tvar counter = 0,\n\t\t\tinterval;\n\n\t\tname = name ? name : 'unnamed';\n\n\t\tinterval = setInterval( function() {\n\n\t\t\t// If we get to 30 seconds log an error message.\n\t\t\tif ( counter >= 300 ) {\n\n\t\t\t\tconsole.log( 'Unable to load dependency: ' + name );\n\n\t\t\t\t// If we can't access yet, increment and wait...\n\t\t\t} else {\n\n\t\t\t\t// Bind the events, we're good!\n\t\t\t\tif ( test() ) {\n\t\t\t\t\tcb();\n\t\t\t\t} else {\n\t\t\t\t\t// console.log( 'Waiting for dependency: ' + name );\n\t\t\t\t\tcounter++;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tclearInterval( interval );\n\n\t\t}, 100 );\n\n\t};\n\n\tLLMS.init( $ );\n\n} )( jQuery );\n"],"sourceRoot":"../../js"} \ No newline at end of file +{"version":3,"sources":["llms.js"],"names":["LLMS","window","$","factory","registeredInModuleLoader","OldCookies","api","Achievements","init","self","length","this","bind","maybe_open","each","create_modal","on","$this","id","attr","$modal","iziModal","$el","append","headerColor","group","history","loop","overlayColor","transitionIn","transitionOut","width","onOpening","modal","setTitle","find","html","setSubtitle","setContent","onClosing","pushState","document","title","location","pathname","search","let","hash","split","parseInt","Number","isInteger","a","querySelector","join","click","Ajax","url","ajaxurl","llms","type","data","cache","dataType","async","response","obj","_ajax_nonce","ajax_nonce","wp_ajax_data","nonce","query_vars","Rest","get_query_vars","post_id","post","val","call","settings","request","ajax","Donut","options","extend","element","percent","circle","stroke_width","css","radius","angle","hasClass","i","Math","round","first","increment","animate","timer","setInterval","d","radians","PI","x","cos","y","sin","clearInterval","Forms","address_info","$cities","$countries","$states","$states_holder","bind_matching_fields","bind_voucher_field","bind_edit_account","bind_l10n_selects","handle_toggle_click","$zips","wait_for","undefined","fn","llmsSelect2","prep_state_field","add","JSON","parse","update_locale_info","trigger","not","$parents","$field","$match","closest","val_1","val_2","addClass","removeClass","e","preventDefault","toggle","get_field_parent","$block","get_label_text","$label","$clone","clone","remove","text","trim","event","$fields","isShowing","displayFunc","disabled","textAttr","$parent","$holder","appendTo","update_label","$required","country_code","info","update_state_options","state","update_locale_info_for_field","city","postcode","label","enable_field","disable_field","opts","name","class","insertAfter","hide","removeAttr","next","detach","show","Instructors","wait_for_matchHeight","matchHeight","l10n","translate","string","strings","replace","replacements","str","token","value","indexOf","toString","LessonPreview","$els","$locked","match_height","msg","$tip","get_tooltip","setTimeout","Loops","OutlineCollapse","$outlines","$outline","$headers","$section","get_section_state","open_section","close_section","opposite_action","PasswordStrength","$meter","$pass","$conf","$form","setup_references","wp","passwordStrength","submit","check_strength","$pass_field","$conf_field","pass_length","conf_length","get_current_strength_status","get_current_strength","checkout","callback","get_blocklist","blocklist","userInputDisallowedList","concat","get_setting","push","format","pass","conf","meter","get_strength_slug","get_strength_text","curr","min","get_strength_value","get_minimum_strength","key","default_val","get_settings","strength_val","slugs","-1","1","2","3","4","5","texts","strength_slug","values","too-short","very-weak","weak","medium","strong","mismatch","off","scrollTop","offset","top","fadeIn","get_blacklist","console","log","Pricing_Tables","wait_for_popover","bind_locked","webuiPopover","animation","closeable","content","$content","$element","placement","style","Review","jQuery","action","review_title","review_text","pageID","success","error","jqXHR","textStatus","errorThrown","change","Spinner","get","size","$spinner","start","stop","result","arguments","attributes","decode","s","decodeURIComponent","converter","set","path","defaults","expires","Date","toUTCString","stringify","test","write","encodeURIComponent","String","escape","attributeName","stringifiedAttributes","cookie","json","jar","cookies","parts","slice","charAt","read","getJSON","withConverter","define","amd","exports","module","Cookies","noConflict","CookieStore","Storage","store","clearAll","clear","getAll","sameSite","StudentDashboard","screen","get_screen","bind_orders","order_cancel_warning","slideToggle","confirm","Tracking","onBeforeUnload","removeEventListener","onVisibilityChange","onUnload","addEvent","hidden","args","events","makeEventObj","all","_temp","llms-tracking","xhr","status","r","code","message","getSettings","href","time","getTime","addEventListener","tracking","is_path","path_exists","vars","hashes","func","is_touch_device","prefixes","DocumentTouch","query","matchMedia","matches","cb","interval","counter"],"mappings":"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","file":"../../js/llms.min.js","sourcesContent":["/**\n * Main LLMS Namespace\n *\n * @since 1.0.0\n * @version 5.3.3\n */\n\nvar LLMS = window.LLMS || {};\n( function( $ ){\n\n\t'use strict';\n\n\t/**\n\t * Load all app modules\n\t */\n\t/**\n\t * Front End Achievements\n\t *\n\t * @package LifterLMS/Scripts\n\t *\n\t * @since 3.14.0\n\t * @version 6.10.2\n\t */\n\t\n\tLLMS.Achievements = {\n\t\n\t\t/**\n\t\t * Init\n\t\t *\n\t\t * @since 3.14.0\n\t\t * @since 4.5.1 Fix conditional loading check.\n\t\t *\n\t\t * @return {void}\n\t\t */\n\t\tinit: function() {\n\t\n\t\t\tif ( $( '.llms-achievement' ).length ) {\n\t\n\t\t\t\tvar self = this;\n\t\n\t\t\t\t$( function() {\n\t\t\t\t\tself.bind();\n\t\t\t\t\tself.maybe_open();\n\t\t\t\t} );\n\t\t\t}\n\t\n\t\t},\n\t\n\t\t/**\n\t\t * Bind DOM events\n\t\t *\n\t\t * @since 3.14.0\n\t\t *\n\t\t * @return {void}\n\t\t */\n\t\tbind: function() {\n\t\n\t\t\tvar self = this;\n\t\n\t\t\t$( '.llms-achievement' ).each( function() {\n\t\n\t\t\t\tself.create_modal( $( this ) );\n\t\n\t\t\t} );\n\t\n\t\t\t$( '.llms-achievement' ).on( 'click', function() {\n\t\n\t\t\t\tvar $this = $( this ),\n\t\t\t\t\tid = 'achievement-' + $this.attr( 'data-id' ),\n\t\t\t\t\t$modal = $( '#' + id );\n\t\n\t\t\t\tif ( ! $modal.length ) {\n\t\t\t\t\tself.create_modal( $this );\n\t\t\t\t}\n\t\n\t\t\t\t$modal.iziModal( 'open' );\n\t\n\t\t\t} );\n\t\n\t\t},\n\t\n\t\t/**\n\t\t * Creates modal a modal for an achievement\n\t\t *\n\t\t * @since 3.14.0\n\t\t *\n\t\t * @param obj $el The jQuery selector for the modal card.\n\t\t * @return {void}\n\t\t */\n\t\tcreate_modal: function( $el ) {\n\t\n\t\t\tvar id = 'achievement-' + $el.attr( 'data-id' ),\n\t\t\t\t$modal = $( '#' + id );\n\t\n\t\t\tif ( ! $modal.length ) {\n\t\t\t\t$modal = $( '
' );\n\t\t\t\t$( 'body' ).append( $modal );\n\t\t\t}\n\t\n\t\t\t$modal.iziModal( {\n\t\t\t\theaderColor: '#3a3a3a',\n\t\t\t\tgroup: 'achievements',\n\t\t\t\thistory: true,\n\t\t\t\tloop: true,\n\t\t\t\toverlayColor: 'rgba( 0, 0, 0, 0.6 )',\n\t\t\t\ttransitionIn: 'fadeInDown',\n\t\t\t\ttransitionOut: 'fadeOutDown',\n\t\t\t\twidth: 340,\n\t\t\t\tonOpening: function( modal ) {\n\t\n\t\t\t\t\tmodal.setTitle( $el.find( '.llms-achievement-title' ).html() );\n\t\t\t\t\tmodal.setSubtitle( $el.find( '.llms-achievement-date' ).html() );\n\t\t\t\t\tmodal.setContent( '
' + $el.html() + '
' );\n\t\n\t\t\t\t},\n\t\n\t\t\t\tonClosing: function() {\n\t\t\t\t\twindow.history.pushState( '', document.title, window.location.pathname + window.location.search );\n\t\t\t\t},\n\t\n\t\t\t} );\n\t\n\t\t},\n\t\n\t\t/**\n\t\t * On page load, opens a modal if the URL contains an achievement in the location hash\n\t\t *\n\t\t * @since 3.14.0\n\t\t * @since 6.10.2 Sanitize achievement IDs before using window.location.hash to trigger the modal open.\n\t\t *\n\t\t * @return {void}\n\t\t */\n\t\tmaybe_open: function() {\n\t\n\t\t\tlet hash = window.location.hash.split( '-' );\n\t\t\tif ( 2 !== hash.length ) {\n\t\t\t\treturn;\n\t\t\t}\n\t\n\t\t\thash[1] = parseInt( hash[1] );\n\t\t\tif ( '#achievement-' !== hash[0] || ! Number.isInteger( hash[1] ) ) {\n\t\t\t\treturn;\n\t\t\t}\n\t\n\t\t\tconst a = document.querySelector( `a[href=\"${ hash.join( '-' ) }\"]` )\n\t\t\tif ( ! a ) {\n\t\t\t\treturn;\n\t\t\t}\n\t\n\t\t\ta.click();\n\t\n\t\t}\n\t\n\t};\n\t\n\t\t/**\n\t * Main Ajax class\n\t * Handles Primary Ajax connection\n\t *\n\t * @package LifterLMS/Scripts\n\t *\n\t * @since Unknown\n\t * @version Unknown\n\t */\n\t\n\tLLMS.Ajax = {\n\t\n\t\t/**\n\t\t * Url\n\t\t *\n\t\t * @type {String}\n\t\t */\n\t\turl: window.ajaxurl || window.llms.ajaxurl,\n\t\n\t\t/**\n\t\t * Type\n\t\t *\n\t\t * @type {[type]}\n\t\t */\n\t\ttype: 'post',\n\t\n\t\t/**\n\t\t * Data\n\t\t *\n\t\t * @type {[type]}\n\t\t */\n\t\tdata: [],\n\t\n\t\t/**\n\t\t * Cache\n\t\t *\n\t\t * @type {[type]}\n\t\t */\n\t\tcache: false,\n\t\n\t\t/**\n\t\t * DataType\n\t\t * defaulted to json\n\t\t *\n\t\t * @type {String}\n\t\t */\n\t\tdataType: 'json',\n\t\n\t\t/**\n\t\t * Async\n\t\t * default to false\n\t\t *\n\t\t * @type {Boolean}\n\t\t */\n\t\tasync: true,\n\t\n\t\tresponse:[],\n\t\n\t\t/**\n\t\t * Initialize Ajax methods\n\t\t *\n\t\t * @since Unknown\n\t\t * @since 4.4.0 Update ajax nonce source.\n\t\t *\n\t\t * @param {Object} obj Options object.\n\t\t * @return {Object}\n\t\t */\n\t\tinit: function( obj ) {\n\t\n\t\t\t// If obj is not of type object or null return false.\n\t\t\tif ( obj === null || typeof obj !== 'object' ) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\n\t\t\t// set object defaults if values are not supplied\n\t\t\tobj.url = 'url' in obj ? obj.url : this.url;\n\t\t\tobj.type = 'type' \t\tin obj ? obj.type : this.type;\n\t\t\tobj.data = 'data' \t\tin obj ? obj.data : this.data;\n\t\t\tobj.cache = 'cache' \t\tin obj ? obj.cache : this.cache;\n\t\t\tobj.dataType = 'dataType'\tin obj ? obj.dataType : this.dataType;\n\t\t\tobj.async = 'async'\t\tin obj ? obj.async : this.async;\n\t\n\t\t\t// Add nonce to data object.\n\t\t\tobj.data._ajax_nonce = window.llms.ajax_nonce || wp_ajax_data.nonce;\n\t\n\t\t\t// Add post id to data object.\n\t\t\tvar $R = LLMS.Rest,\n\t\t\tquery_vars = $R.get_query_vars();\n\t\t\tobj.data.post_id = 'post' in query_vars ? query_vars.post : null;\n\t\t\tif ( ! obj.data.post_id && $( 'input#post_ID' ).length ) {\n\t\t\t\tobj.data.post_id = $( 'input#post_ID' ).val();\n\t\t\t}\n\t\n\t\t\treturn obj;\n\t\t},\n\t\n\t\t/**\n\t\t * Call\n\t\t * Called by external classes\n\t\t * Sets up jQuery Ajax object\n\t\t *\n\t\t * @param {[object]} [object of ajax settings]\n\t\t * @return {[mixed]} [false if not object or this]\n\t\t */\n\t\tcall: function(obj) {\n\t\n\t\t\t// get default variables if not included in call\n\t\t\tvar settings = this.init( obj );\n\t\n\t\t\t// if init return a response of false\n\t\t\tif ( ! settings) {\n\t\t\t\treturn false;\n\t\t\t} else {\n\t\t\t\tthis.request( settings );\n\t\t\t}\n\t\n\t\t\treturn this;\n\t\n\t\t},\n\t\n\t\t/**\n\t\t * Calls jQuery Ajax on settings object\n\t\t *\n\t\t * @return {[object]} [this]\n\t\t */\n\t\trequest: function(settings) {\n\t\n\t\t\t$.ajax( settings );\n\t\n\t\t\treturn this;\n\t\n\t\t}\n\t\n\t};\n\t\n\t\t/**\n\t * Create a Donut Chart\n\t *\n\t * @package LifterLMS/Scripts\n\t *\n\t * @since 3.9.0\n\t * @version 4.15.0\n\t *\n\t * @link https://gist.github.com/joeyinbox/8205962\n\t *\n\t * @param {Object} $el jQuery element to draw a chart within.\n\t */\n\t\n\tLLMS.Donut = function( $el ) {\n\t\n\t\t/**\n\t\t * Constructor\n\t\t *\n\t\t * @since 3.9.0\n\t\t * @since 4.15.0 Flip animation in RTL.\n\t\t *\n\t\t * @param {Object} options Donut options.\n\t\t * @return {Void}\n\t\t */\n\t\tfunction Donut(options) {\n\t\n\t\t\tthis.settings = $.extend( {\n\t\t\t\telement: options.element,\n\t\t\t\tpercent: 100\n\t\t\t}, options );\n\t\n\t\t\tthis.circle = this.settings.element.find( 'path' );\n\t\t\tthis.settings.stroke_width = parseInt( this.circle.css( 'stroke-width' ) );\n\t\t\tthis.radius = ( parseInt( this.settings.element.css( 'width' ) ) - this.settings.stroke_width ) / 2;\n\t\t\tthis.angle = $( 'body' ).hasClass( 'rtl' ) ? 82.5 : 97.5; // Origin of the draw at the top of the circle\n\t\t\tthis.i = Math.round( 0.75 * this.settings.percent );\n\t\t\tthis.first = true;\n\t\t\tthis.increment = $( 'body' ).hasClass( 'rtl' ) ? -5 : 5;\n\t\n\t\t\tthis.animate = function() {\n\t\t\t\tthis.timer = setInterval( this.loop.bind( this ), 10 );\n\t\t\t};\n\t\n\t\t\tthis.loop = function() {\n\t\t\t\tthis.angle += this.increment;\n\t\t\t\tthis.angle %= 360;\n\t\t\t\tvar radians = ( this.angle / 180 ) * Math.PI,\n\t\t\t\t\tx = this.radius + this.settings.stroke_width / 2 + Math.cos( radians ) * this.radius,\n\t\t\t\t\ty = this.radius + this.settings.stroke_width / 2 + Math.sin( radians ) * this.radius,\n\t\t\t\t\td;\n\t\t\t\tif (this.first === true) {\n\t\t\t\t\td = this.circle.attr( 'd' ) + ' M ' + x + ' ' + y;\n\t\t\t\t\tthis.first = false;\n\t\t\t\t} else {\n\t\t\t\t\td = this.circle.attr( 'd' ) + ' L ' + x + ' ' + y;\n\t\t\t\t}\n\t\t\t\tthis.circle.attr( 'd', d );\n\t\t\t\tthis.i--;\n\t\n\t\t\t\tif (this.i <= 0) {\n\t\t\t\t\tclearInterval( this.timer );\n\t\t\t\t}\n\t\t\t};\n\t\t}\n\t\n\t\t/**\n\t\t * Draw donut element\n\t\t *\n\t\t * @since 3.9.0\n\t\t *\n\t\t * @param {Object} $el jQuery element to draw a chart within.\n\t\t * @return {Void}\n\t\t */\n\t\tfunction draw( $el ) {\n\t\t\tvar path = '';\n\t\t\t$el.append( '' + path + '' );\n\t\t\tvar donut = new Donut( {\n\t\t\t\telement: $el,\n\t\t\t\tpercent: $el.attr( 'data-perc' )\n\t\t\t} );\n\t\t\tdonut.animate();\n\t\t}\n\t\n\t\tdraw( $el );\n\t\n\t};\n\t\n\t\t/**\n\t * Forms\n\t *\n\t * @package LifterLMS/Scripts\n\t *\n\t * @since 5.0.0\n\t * @version 5.3.3\n\t */\n\t\n\tLLMS.Forms = {\n\t\n\t\t/**\n\t\t * Stores locale information.\n\t\t *\n\t\t * Added via PHP.\n\t\t *\n\t\t * @type {Object}\n\t\t */\n\t\taddress_info: {},\n\t\n\t\t/**\n\t\t * jQuery ref. to the city text field.\n\t\t *\n\t\t * @type {Object}\n\t\t */\n\t\t$cities: null,\n\t\n\t\t/**\n\t\t * jQuery ref. to the countries select field.\n\t\t *\n\t\t * @type {Object}\n\t\t */\n\t\t$countries: null,\n\t\n\t\t/**\n\t\t * jQuery ref. to the states select field.\n\t\t *\n\t\t * @type {Object}\n\t\t */\n\t\t$states: null,\n\t\n\t\t/**\n\t\t * jQuery ref. to the hidden states holder field.\n\t\t *\n\t\t * @type {Object}\n\t\t */\n\t\t$states_holder: null,\n\t\n\t\t/**\n\t\t * Init\n\t\t *\n\t \t * @since 5.0.0\n\t \t * @since 5.3.3 Move select2 dependency check into the `bind_l10_selects()` method.\n\t \t *\n\t \t * @return {void}\n\t\t */\n\t\tinit: function() {\n\t\n\t\t\tif ( $( 'body' ).hasClass( 'wp-admin' ) ) {\n\t\t\t\tif ( ! ( $( 'body' ).hasClass( 'profile-php' ) || $( 'body' ).hasClass( 'user-edit-php' ) ) ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\n\t\t\tvar self = this;\n\t\n\t\t\tself.bind_matching_fields();\n\t\t\tself.bind_voucher_field();\n\t\t\tself.bind_edit_account();\n\t\t\tself.bind_l10n_selects();\n\t\n\t\t},\n\t\n\t\t/**\n\t\t * Bind DOM events for the edit account screen.\n\t\t *\n\t\t * @since 5.0.0\n\t\t *\n\t\t * @return {void}\n\t\t */\n\t\tbind_edit_account: function() {\n\t\n\t\t\t// Not an edit account form.\n\t\t\tif ( ! $( 'form.llms-person-form.edit-account' ).length ) {\n\t\t\t\treturn;\n\t\t\t}\n\t\n\t\t\t$( '.llms-toggle-fields' ).on( 'click', this.handle_toggle_click );\n\t\n\t\t},\n\t\n\t\t/**\n\t\t * Bind DOM Events fields with dynamic localization values and language.\n\t\t *\n\t\t * @since 5.0.0\n\t\t * @since 5.3.3 Bind select2-related events after ensuring select2 is available.\n\t\t *\n\t\t * @return {void}\n\t\t */\n\t\tbind_l10n_selects: function() {\n\t\n\t\t\tvar self = this;\n\t\n\t\t\tself.$cities = $( '#llms_billing_city' );\n\t\t\tself.$countries = $( '.llms-l10n-country-select select' );\n\t\t\tself.$states = $( '.llms-l10n-state-select select' );\n\t\t\tself.$zips = $( '#llms_billing_zip' );\n\t\n\t\t\tif ( ! self.$countries.length ) {\n\t\t\t\treturn;\n\t\t\t}\n\t\n\t\t\tvar isSelect2Available = function() {\n\t\t\t\treturn ( undefined !== $.fn.llmsSelect2 );\n\t\t\t};\n\t\n\t\t\tLLMS.wait_for( isSelect2Available, function() {\n\t\n\t\t\t\tif ( self.$states.length ) {\n\t\t\t\t\tself.prep_state_field();\n\t\t\t\t}\n\t\n\t\t\t\tself.$countries.add( self.$states ).llmsSelect2( { width: '100%' } );\n\t\n\t\t\t\tif ( window.llms.address_info ) {\n\t\t\t\t\tself.address_info = JSON.parse( window.llms.address_info );\n\t\t\t\t}\n\t\n\t\t\t\tself.$countries.on( 'change', function() {\n\t\n\t\t\t\t\tvar val = $( this ).val();\n\t\t\t\t\tself.update_locale_info( val );\n\t\n\t\t\t\t} ).trigger( 'change' );\n\t\n\t\t\t}, 'llmsSelect2' );\n\t\n\t\t},\n\t\n\t\t/**\n\t\t * Ensure \"matching\" fields match.\n\t\t *\n\t\t * @since 5.0.0\n\t\t *\n\t\t * @return {Void}\n\t\t */\n\t\tbind_matching_fields: function() {\n\t\n\t\t\tvar $fields = $( 'input[data-match]' ).not( '[type=\"password\"]' );\n\t\n\t\t\t$fields.each( function() {\n\t\n\t\t\t\tvar $field = $( this ),\n\t\t\t\t\t$match = $( '#' + $field.attr( 'data-match' ) ),\n\t\t\t\t\t$parents;\n\t\n\t\t\t\tif ( $match.length ) {\n\t\n\t\t\t\t\t$parents = $field.closest( '.llms-form-field' ).add( $match.closest( '.llms-form-field' ) );\n\t\n\t\t\t\t\t$field.on( 'input change', function() {\n\t\n\t\t\t\t\t\tvar val_1 = $field.val(),\n\t\t\t\t\t\t\tval_2 = $match.val();\n\t\n\t\t\t\t\t\tif ( val_1 && val_2 && val_1 !== val_2 ) {\n\t\t\t\t\t\t\t$parents.addClass( 'invalid' );\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t$parents.removeClass( 'invalid' );\n\t\t\t\t\t\t}\n\t\n\t\t\t\t\t} );\n\t\n\t\t\t\t}\n\t\n\t\t\t} );\n\t\n\t\t},\n\t\n\t\t/**\n\t\t * Bind DOM events for voucher toggles UX.\n\t\t *\n\t\t * @since 5.0.0\n\t\t *\n\t\t * @return {void}\n\t\t */\n\t\tbind_voucher_field: function() {\n\t\n\t\t\t$( '#llms-voucher-toggle' ).on( 'click', function( e ) {\n\t\t\t\te.preventDefault();\n\t\t\t\t$( '#llms_voucher' ).toggle();\n\t\t\t} );\n\t\n\t\t},\n\t\n\t\t/**\n\t\t * Retrieve the parent element for a given field.\n\t\t *\n\t\t * The parent element is hidden when the field isn't required.\n\t\t * Looks for a WP column wrapper and falls back to the field's\n\t\t * wrapper div.\n\t\t *\n\t\t * @since 5.0.0\n\t\t *\n\t\t * @param {Object} $field jQuery dom object.\n\t\t * @return {Object}\n\t\t */\n\t\tget_field_parent: function( $field ) {\n\t\n\t\t\tvar $block = $field.closest( '.wp-block-column' );\n\t\t\tif ( $block.length ) {\n\t\t\t\treturn $block;\n\t\t\t}\n\t\n\t\t\treturn $field.closest( '.llms-form-field' );\n\t\n\t\t},\n\t\n\t\t/**\n\t\t * Retrieve the text of a label\n\t\t *\n\t\t * Removes any children HTML elements (eg: required span elements) and returns only the labels text.\n\t\t *\n\t\t * @since 5.0.0\n\t\t *\n\t\t * @param {Object} $label jQuery object for a label element.\n\t\t * @return {String}\n\t\t */\n\t\tget_label_text: function( $label ) {\n\t\n\t\t\tvar $clone = $label.clone();\n\t\t\t$clone.find( '*' ).remove();\n\t\t\treturn $clone.text().trim();\n\t\n\t\t},\n\t\n\t\t/**\n\t\t * Callback function to handle the \"toggle\" button links for changing email address and password on account edit forms\n\t\t *\n\t\t * @since 5.0.0\n\t\t *\n\t\t * @param {Object} event Native JS event object.\n\t\t * @return {void}\n\t\t */\n\t\thandle_toggle_click: function( event ) {\n\t\n\t\t\tevent.preventDefault();\n\t\n\t\t\tvar $this = $( this ),\n\t\t\t\t$fields = $( $( this ).attr( 'data-fields' ) ),\n\t\t\t\tisShowing = $this.attr( 'data-is-showing' ) || 'no',\n\t\t\t\tdisplayFunc = 'yes' === isShowing ? 'hide' : 'show',\n\t\t\t\tdisabled = 'yes' === isShowing ? 'disabled' : null,\n\t\t\t\ttextAttr = 'yes' === isShowing ? 'data-change-text' : 'data-cancel-text';\n\t\n\t\t\t$fields.each( function() {\n\t\n\t\t\t\t$( this ).closest( '.llms-form-field' )[ displayFunc ]();\n\t\t\t\t$( this ).attr( 'disabled', disabled );\n\t\n\t\t\t} );\n\t\n\t\t\t$this.text( $this.attr( textAttr ) );\n\t\t\t$this.attr( 'data-is-showing', 'yes' === isShowing ? 'no' : 'yes' );\n\t\n\t\t},\n\t\n\t\t/**\n\t\t * Prepares the state select field.\n\t\t *\n\t\t * Moves All optgroup elements into a hidden & disabled select element.\n\t\t *\n\t\t * @since 5.0.0\n\t\t *\n\t\t * @return {void}\n\t\t */\n\t\tprep_state_field: function() {\n\t\n\t\t\tvar $parent = this.$states.closest( '.llms-form-field' );\n\t\n\t\t\tthis.$holder = $( '',\n\t\t\t\t{ name: $field.attr('name'), class: $field.attr( 'class' ) + ' hidden', type: 'hidden' }\n\t\t\t).insertAfter( $field );\n\t\t\t$field.attr( 'disabled', 'disabled' );\n\t\t\tthis.get_field_parent( $field ).hide();\n\t\t},\n\t\n\t\t/**\n\t\t * Enable a given field\n\t\t *\n\t\t * It also shows the parent element, and removes the empty hidden input field\n\t\t * previously added by disable_field().\n\t\t *\n\t\t * @since 5.0.0\n\t\t *\n\t\t * @param {Object} $field The jQuery object for the field.\n\t\t */\n\t\tenable_field: function( $field ) {\n\t\t\t$field.removeAttr( 'disabled' );\n\t\t\t$field.next( '.hidden[name='+$field.attr('name')+']' ).detach();\n\t\t\tthis.get_field_parent( $field ).show();\n\t\t}\n\t\n\t};\n\t\n\t\t/**\n\t * Instructors List\n\t *\n\t * @package LifterLMS/Scripts\n\t *\n\t * @since Unknown\n\t * @version Unknown\n\t */\n\t\n\tLLMS.Instructors = {\n\t\n\t\t/**\n\t\t * Init\n\t\t */\n\t\tinit: function() {\n\t\n\t\t\tvar self = this;\n\t\n\t\t\tif ( $( 'body' ).hasClass( 'wp-admin' ) ) {\n\t\t\t\treturn;\n\t\t\t}\n\t\n\t\t\tif ( $( '.llms-instructors' ).length ) {\n\t\n\t\t\t\tLLMS.wait_for_matchHeight( function() {\n\t\t\t\t\tself.bind();\n\t\t\t\t} );\n\t\n\t\t\t}\n\t\n\t\t},\n\t\n\t\t/**\n\t\t * Bind Method\n\t\t * Handles dom binding on load\n\t\t *\n\t\t * @return {[type]} [description]\n\t\t */\n\t\tbind: function() {\n\t\n\t\t\t$( '.llms-instructors .llms-author' ).matchHeight();\n\t\n\t\t},\n\t\n\t};\n\t\n\t\t/**\n\t * Localization functions for LifterLMS Javascript\n\t *\n\t * @package LifterLMS/Scripts\n\t *\n\t * @since 2.7.3\n\t * @version 2.7.3\n\t *\n\t * @todo we need more robust translation functions to handle sprintf and pluralization\n\t * at this moment we don't need those and haven't stubbed them out\n\t * those will be added when they're needed\n\t */\n\t\n\tLLMS.l10n = LLMS.l10n || {};\n\t\n\tLLMS.l10n.translate = function ( string ) {\n\t\n\t\tvar self = this;\n\t\n\t\tif ( self.strings[string] ) {\n\t\n\t\t\treturn self.strings[string];\n\t\n\t\t} else {\n\t\n\t\t\treturn string;\n\t\n\t\t}\n\t\n\t};\n\t\n\t/**\n\t * Translate and replace placeholders in a string\n\t *\n\t * @example LLMS.l10n.replace( 'This is a %2$s %1$s String', {\n\t * \t'%1$s': 'cool',\n\t * \t\t\t'%2$s': 'very'\n\t * \t\t} );\n\t * \t\tOutput: \"This is a very cool String\"\n\t *\n\t * @param string string text string\n\t * @param object replacements object containing token => replacement pairs\n\t * @return string\n\t * @since 3.16.0\n\t * @version 3.16.0\n\t */\n\tLLMS.l10n.replace = function( string, replacements ) {\n\t\n\t\tvar str = this.translate( string );\n\t\n\t\t$.each( replacements, function( token, value ) {\n\t\n\t\t\tif ( -1 !== token.indexOf( 's' ) ) {\n\t\t\t\tvalue = value.toString();\n\t\t\t} else if ( -1 !== token.indexOf( 'd' ) ) {\n\t\t\t\tvalue = value * 1;\n\t\t\t}\n\t\n\t\t\tstr = str.replace( token, value );\n\t\n\t\t} );\n\t\n\t\treturn str;\n\t\n\t};\n\t\n\t\t/**\n\t * Handle Lesson Preview Elements\n\t *\n\t * @package LifterLMS/Scripts\n\t *\n\t * @since 3.0.0\n\t * @version 3.16.12\n\t */\n\t\n\tLLMS.LessonPreview = {\n\t\n\t\t/**\n\t\t * A jQuery object of all outlines present on the current screen\n\t\t *\n\t\t * @type obj\n\t\t */\n\t\t$els: null,\n\t\n\t\t/**\n\t\t * Initialize\n\t\t *\n\t\t * @return void\n\t\t */\n\t\tinit: function() {\n\t\n\t\t\tvar self = this;\n\t\n\t\t\tthis.$locked = $( 'a[href=\"#llms-lesson-locked\"]' );\n\t\n\t\t\tif ( this.$locked.length ) {\n\t\n\t\t\t\tself.bind();\n\t\n\t\t\t}\n\t\n\t\t\tif ( $( '.llms-course-navigation' ).length ) {\n\t\n\t\t\t\tLLMS.wait_for_matchHeight( function() {\n\t\n\t\t\t\t\tself.match_height();\n\t\n\t\t\t\t} );\n\t\n\t\t\t}\n\t\n\t\t},\n\t\n\t\t/**\n\t\t * Bind DOM events\n\t\t *\n\t\t * @return void\n\t\t * @since 3.0.0\n\t\t * @version 3.16.12\n\t\t */\n\t\tbind: function() {\n\t\n\t\t\tvar self = this;\n\t\n\t\t\tthis.$locked.on( 'click', function() {\n\t\t\t\treturn false;\n\t\t\t} );\n\t\n\t\t\tthis.$locked.on( 'mouseenter', function() {\n\t\n\t\t\t\tvar $tip = $( this ).find( '.llms-tooltip' );\n\t\t\t\tif ( ! $tip.length ) {\n\t\t\t\t\tvar msg = $( this ).attr( 'data-tooltip-msg' );\n\t\t\t\t\tif ( ! msg ) {\n\t\t\t\t\t\tmsg = LLMS.l10n.translate( 'You do not have permission to access this content' );\n\t\t\t\t\t}\n\t\t\t\t\t$tip = self.get_tooltip( msg );\n\t\t\t\t\t$( this ).append( $tip );\n\t\t\t\t}\n\t\t\t\tsetTimeout( function() {\n\t\t\t\t\t$tip.addClass( 'show' );\n\t\t\t\t}, 10 );\n\t\n\t\t\t} );\n\t\n\t\t\tthis.$locked.on( 'mouseleave', function() {\n\t\n\t\t\t\tvar $tip = $( this ).find( '.llms-tooltip' );\n\t\t\t\t$tip.removeClass( 'show' );\n\t\n\t\t\t} );\n\t\n\t\t},\n\t\n\t\t/**\n\t\t * Match the height of lesson preview items in course navigation blocks\n\t\t *\n\t\t * @return void\n\t\t * @since 3.0.0\n\t\t * @version 3.0.0\n\t\t */\n\t\tmatch_height: function() {\n\t\n\t\t\t$( '.llms-course-navigation .llms-lesson-link' ).matchHeight();\n\t\n\t\t},\n\t\n\t\t/**\n\t\t * Get a tooltip element\n\t\t *\n\t\t * @param string msg message to display inside the tooltip\n\t\t * @return obj\n\t\t * @since 3.0.0\n\t\t * @version 3.2.4\n\t\t */\n\t\tget_tooltip: function( msg ) {\n\t\t\tvar $el = $( '
' );\n\t\t\t$el.append( '
' + msg + '
' );\n\t\t\treturn $el;\n\t\t},\n\t\n\t};\n\t\n\t\t/**\n\t * LifterLMS Loops JS\n\t *\n\t * @package LifterLMS/Scripts\n\t *\n\t * @since 3.0.0\n\t * @version 3.14.0\n\t */\n\t\n\tLLMS.Loops = {\n\t\n\t\t/**\n\t\t * Initialize\n\t\t *\n\t\t * @return void\n\t\t */\n\t\tinit: function() {\n\t\n\t\t\tvar self = this;\n\t\n\t\t\tif ( $( '.llms-loop' ).length ) {\n\t\n\t\t\t\tLLMS.wait_for_matchHeight( function() {\n\t\n\t\t\t\t\tself.match_height();\n\t\n\t\t\t\t} );\n\t\n\t\t\t}\n\t\n\t\t},\n\t\n\t\t/**\n\t\t * Match the height of .llms-loop-item\n\t\t *\n\t\t * @return void\n\t\t * @since 3.0.0\n\t\t * @version 3.14.0\n\t\t */\n\t\tmatch_height: function() {\n\t\n\t\t\t$( '.llms-loop-item .llms-loop-item-content' ).matchHeight();\n\t\t\t$( '.llms-achievement-loop-item .llms-achievement' ).matchHeight();\n\t\t\t$( '.llms-certificate-loop-item .llms-certificate' ).matchHeight();\n\t\n\t\t},\n\t\n\t};\n\t\n\t\t/**\n\t * Handle the Collapsible Syllabus Widget / Shortcode\n\t *\n\t * @package LifterLMS/Scripts\n\t *\n\t * @since Unknown\n\t * @version Unknown\n\t */\n\t\n\tLLMS.OutlineCollapse = {\n\t\n\t\t/**\n\t\t * A jQuery object of all outlines present on the current screen\n\t\t *\n\t\t * @type obj\n\t\t */\n\t\t$outlines: null,\n\t\n\t\t/**\n\t\t * Initialize\n\t\t *\n\t\t * @return void\n\t\t */\n\t\tinit: function() {\n\t\n\t\t\tthis.$outlines = $( '.llms-widget-syllabus--collapsible' );\n\t\n\t\t\tif ( this.$outlines.length ) {\n\t\n\t\t\t\tthis.bind();\n\t\n\t\t\t}\n\t\n\t\t},\n\t\n\t\t/**\n\t\t * Bind DOM events\n\t\t *\n\t\t * @return void\n\t\t */\n\t\tbind: function() {\n\t\n\t\t\tvar self = this;\n\t\n\t\t\tthis.$outlines.each( function() {\n\t\n\t\t\t\tvar $outline = $( this ),\n\t\t\t\t\t$headers = $outline.find( '.llms-section .section-header' );\n\t\n\t\t\t\t// bind header clicks\n\t\t\t\t$headers.on( 'click', function( e ) {\n\t\n\t\t\t\t\te.preventDefault();\n\t\n\t\t\t\t\tvar $toggle = $( this ),\n\t\t\t\t\t\t$section = $toggle.closest( '.llms-section' ),\n\t\t\t\t\t\tstate = self.get_section_state( $section );\n\t\n\t\t\t\t\tswitch ( state ) {\n\t\n\t\t\t\t\t\tcase 'closed':\n\t\t\t\t\t\t\tself.open_section( $section );\n\t\t\t\t\t\tbreak;\n\t\n\t\t\t\t\t\tcase 'opened':\n\t\t\t\t\t\t\tself.close_section( $section );\n\t\t\t\t\t\tbreak;\n\t\n\t\t\t\t\t}\n\t\n\t\t\t\t} );\n\t\n\t\t\t\t// bind optional toggle \"buttons\"\n\t\t\t\t$outline.find( '.llms-collapse-toggle' ).on( 'click', function( e ) {\n\t\n\t\t\t\t\te.preventDefault();\n\t\n\t\t\t\t\tvar $btn = $( this ),\n\t\t\t\t\t\taction = $btn.attr( 'data-action' ),\n\t\t\t\t\t\topposite_action = ( 'close' === action ) ? 'opened' : 'closed';\n\t\n\t\t\t\t\t$headers.each( function() {\n\t\n\t\t\t\t\t\tvar $section = $( this ).closest( '.llms-section' ),\n\t\t\t\t\t\t\tstate = self.get_section_state( $section );\n\t\n\t\t\t\t\t\tif ( opposite_action !== state ) {\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t}\n\t\n\t\t\t\t\t\tswitch ( state ) {\n\t\n\t\t\t\t\t\t\tcase 'closed':\n\t\t\t\t\t\t\t\tself.close_section( $section );\n\t\t\t\t\t\t\tbreak;\n\t\n\t\t\t\t\t\t\tcase 'opened':\n\t\t\t\t\t\t\t\tself.open_section( $section );\n\t\t\t\t\t\t\tbreak;\n\t\n\t\t\t\t\t\t}\n\t\n\t\t\t\t\t\t$( this ).trigger( 'click' );\n\t\n\t\t\t\t\t} );\n\t\n\t\t\t\t} );\n\t\n\t\t\t} );\n\t\n\t\t},\n\t\n\t\t/**\n\t\t * Close an outline section\n\t\t *\n\t\t * @param obj $section jQuery selector of a '.llms-section'\n\t\t * @return void\n\t\t */\n\t\tclose_section: function( $section ) {\n\t\n\t\t\t$section.removeClass( 'llms-section--opened' ).addClass( 'llms-section--closed' );\n\t\n\t\t},\n\t\n\t\t/**\n\t\t * Open an outline section\n\t\t *\n\t\t * @param obj $section jQuery selector of a '.llms-section'\n\t\t * @return void\n\t\t */\n\t\topen_section: function( $section ) {\n\t\n\t\t\t$section.removeClass( 'llms-section--closed' ).addClass( 'llms-section--opened' );\n\t\n\t\t},\n\t\n\t\t/**\n\t\t * Get the current state (open or closed) of an outline section\n\t\t *\n\t\t * @param obj $section jQuery selector of a '.llms-section'\n\t\t * @return string 'opened' or 'closed'\n\t\t */\n\t\tget_section_state: function( $section ) {\n\t\n\t\t\treturn $section.hasClass( 'llms-section--opened' ) ? 'opened' : 'closed';\n\t\n\t\t}\n\t\n\t};\n\t\n\t\t/**\n\t * Handle Password Strength Meter for registration and password update fields\n\t *\n\t * @package LifterLMS/Scripts\n\t *\n\t * @since 3.0.0\n\t * @version 5.0.0\n\t */\n\t\n\t$.extend( LLMS.PasswordStrength, {\n\t\n\t\t/**\n\t\t * jQuery ref for the password strength meter object.\n\t\t *\n\t\t * @type {Object}\n\t\t */\n\t\t$meter: $( '.llms-password-strength-meter' ),\n\t\n\t\t/**\n\t\t * jQuery ref for the password field.\n\t\t *\n\t\t * @type {Object}\n\t\t */\n\t\t$pass: null,\n\t\n\t\t/**\n\t\t * jQuery ref for the password confirmation field\n\t\t *\n\t\t * @type {Object}\n\t\t */\n\t\t$conf: null,\n\t\n\t\t/**\n\t\t * jQuery ref for form element.\n\t\t *\n\t\t * @type {Object}\n\t\t */\n\t\t$form: null,\n\t\n\t\t/**\n\t\t * Init\n\t\t * loads class methods\n\t\t *\n\t\t * @since 3.0.0\n\t\t * @since 3.7.0 Unknown\n\t\t * @since 5.0.0 Move reference setup to `setup_references()`.\n\t\t * Use `LLMS.wait_for()` for dependency waiting.\n\t\t *\n\t\t * @return {Void}\n\t\t */\n\t\tinit: function() {\n\t\n\t\t\tif ( $( 'body' ).hasClass( 'wp-admin' ) ) {\n\t\t\t\treturn;\n\t\t\t}\n\t\n\t\t\tif ( ! this.setup_references() ) {\n\t\t\t\treturn;\n\t\t\t}\n\t\n\t\t\tvar self = this;\n\t\n\t\t\tLLMS.wait_for( function() {\n\t\t\t\treturn ( 'undefined' !== typeof wp && 'undefined' !== typeof wp.passwordStrength );\n\t\t\t}, function() {\n\t\t\t\tself.bind();\n\t\t\t\tself.$form.trigger( 'llms-password-strength-ready' );\n\t\t\t} );\n\t\n\t\t},\n\t\n\t\t/**\n\t\t * Bind DOM Events\n\t\t *\n\t\t * @since 3.0.0\n\t\t *\n\t\t * @return void\n\t\t */\n\t\tbind: function() {\n\t\n\t\t\tvar self = this;\n\t\n\t\t\t// add submission event handlers when not on a checkout form\n\t\t\tif ( ! this.$form.hasClass( 'llms-checkout' ) ) {\n\t\t\t\tself.$form.on( 'submit', self, self.submit );\n\t\t\t}\n\t\n\t\t\t// check password strength on keyup\n\t\t\tself.$pass.add( self.$conf ).on( 'keyup', function() {\n\t\t\t\tself.check_strength();\n\t\t\t} );\n\t\n\t\t},\n\t\n\t\t/**\n\t\t * Check the strength of a user entered password\n\t\t * and update elements depending on the current strength\n\t\t *\n\t\t * @since 3.0.0\n\t\t * @since 5.0.0 Allow password confirmation to be optional when checking strength.\n\t\t *\n\t\t * @return void\n\t\t */\n\t\tcheck_strength: function() {\n\t\n\t\t\tvar $pass_field = this.$pass.closest( '.llms-form-field' ),\n\t\t\t\t$conf_field = this.$conf && this.$conf.length ? this.$conf.closest( '.llms-form-field' ) : null,\n\t\t\t\tpass_length = this.$pass.val().length,\n\t\t\t\tconf_length = this.$conf && this.$conf.length ? this.$conf.val().length : 0;\n\t\n\t\t\t// hide the meter if both fields are empty\n\t\t\tif ( ! pass_length && ! conf_length ) {\n\t\t\t\t$pass_field.removeClass( 'valid invalid' );\n\t\t\t\tif ( $conf_field ) {\n\t\t\t\t\t$conf_field.removeClass( 'valid invalid' );\n\t\t\t\t}\n\t\t\t\tthis.$meter.hide();\n\t\t\t\treturn;\n\t\t\t}\n\t\n\t\t\tif ( this.get_current_strength_status() ) {\n\t\t\t\t$pass_field.removeClass( 'invalid' ).addClass( 'valid' );\n\t\t\t\tif ( conf_length ) {\n\t\t\t\t\t$conf_field.removeClass( 'invalid' ).addClass( 'valid' );\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t$pass_field.removeClass( 'valid' ).addClass( 'invalid' );\n\t\t\t\tif ( conf_length ) {\n\t\t\t\t\t$conf_field.removeClass( 'valid' ).addClass( 'invalid' );\n\t\t\t\t}\n\t\t\t}\n\t\n\t\t\tthis.$meter.removeClass( 'too-short very-weak weak medium strong mismatch' );\n\t\t\tthis.$meter.show().addClass( this.get_current_strength( 'slug' ) );\n\t\t\tthis.$meter.html( this.get_current_strength( 'text' ) );\n\t\n\t\t},\n\t\n\t\t/**\n\t\t * Form submission action called during registration on checkout screen\n\t\t *\n\t\t * @since 3.0.0\n\t\t *\n\t\t * @param obj self instance of this class\n\t\t * @param Function callback callback function, passes error message or success back to checkout handler\n\t\t * @return void\n\t\t */\n\t\tcheckout: function( self, callback ) {\n\t\n\t\t\tif ( self.get_current_strength_status() ) {\n\t\n\t\t\t\tcallback( true );\n\t\n\t\t\t} else {\n\t\n\t\t\t\tcallback( LLMS.l10n.translate( 'There is an issue with your chosen password.' ) );\n\t\n\t\t\t}\n\t\t},\n\t\n\t\t/**\n\t\t * Get the list of blocklisted strings\n\t\t *\n\t\t * @since 5.0.0\n\t\t *\n\t\t * @return array\n\t\t */\n\t\tget_blocklist: function() {\n\t\n\t\t\t// Default values from WP Core + any values added via settings filter..\n\t\t\tvar blocklist = wp.passwordStrength.userInputDisallowedList().concat( this.get_setting( 'blocklist', [] ) );\n\t\n\t\t\t// Add values from all text fields in the form.\n\t\t\tthis.$form.find( 'input[type=\"text\"], input[type=\"email\"], input[type=\"tel\"], input[type=\"number\"]' ).each( function() {\n\t\t\t\tvar val = $( this ).val();\n\t\t\t\tif ( val ) {\n\t\t\t\t\tblocklist.push( val );\n\t\t\t\t}\n\t\t\t} );\n\t\n\t\t\treturn blocklist;\n\t\n\t\t},\n\t\n\t\t/**\n\t\t * Retrieve current strength as a number, a slug, or a translated text string\n\t\t *\n\t\t * @since 3.0.0\n\t\t * @since 5.0.0 Allow password confirmation to be optional when checking strength.\n\t\t *\n\t\t * @param {String} format Derived return format [int|slug|text] defaults to int.\n\t\t * @return mixed\n\t\t */\n\t\tget_current_strength: function( format ) {\n\t\n\t\t\tformat = format || 'int';\n\t\t\tvar pass = this.$pass.val(),\n\t\t\t\tconf = this.$conf && this.$conf.length ? this.$conf.val() : '',\n\t\t\t\tval;\n\t\n\t\t\t// enforce custom length requirement\n\t\t\tif ( pass.length < this.get_setting( 'min_length', 6 ) ) {\n\t\t\t\tval = -1;\n\t\t\t} else {\n\t\t\t\tval = wp.passwordStrength.meter( pass, this.get_blocklist(), conf );\n\t\t\t\t// 0 & 1 are both very-weak\n\t\t\t\tif ( 0 === val ) {\n\t\t\t\t\tval = 1;\n\t\t\t\t}\n\t\t\t}\n\t\n\t\t\tif ( 'slug' === format ) {\n\t\t\t\treturn this.get_strength_slug( val );\n\t\t\t} else if ( 'text' === format ) {\n\t\t\t\treturn this.get_strength_text( val );\n\t\t\t} else {\n\t\t\t\treturn val;\n\t\t\t}\n\t\t},\n\t\n\t\t/**\n\t\t * Determines if the current password strength meets the user-defined\n\t\t * minimum password strength requirements\n\t\t *\n\t\t * @since 3.0.0\n\t\t *\n\t\t * @return boolean\n\t\t */\n\t\tget_current_strength_status: function() {\n\t\t\tvar curr = this.get_current_strength(),\n\t\t\t\tmin = this.get_strength_value( this.get_minimum_strength() );\n\t\t\treturn ( 5 === curr ) ? false : ( curr >= min );\n\t\t},\n\t\n\t\t/**\n\t\t * Retrieve the minimum password strength for the current form.\n\t\t *\n\t\t * @since 3.0.0\n\t\t * @since 5.0.0 Replaces the version output via an inline PHP script in favor of utilizing values configured in the settings object.\n\t\t *\n\t\t * @return {string}\n\t\t */\n\t\tget_minimum_strength: function() {\n\t\t\treturn this.get_setting( 'min_strength', 'strong' );\n\t\t},\n\t\n\t\t/**\n\t\t * Get a setting and fallback to a default value.\n\t\t *\n\t\t * @since 5.0.0\n\t\t *\n\t\t * @param {String} key Setting key.\n\t\t * @param {mixed} default_val Default value when the requested setting cannot be located.\n\t\t * @return {mixed}\n\t\t */\n\t\tget_setting: function( key, default_val ) {\n\t\t\tvar settings = this.get_settings();\n\t\t\treturn settings[ key ] ? settings[ key ] : default_val;\n\t\t},\n\t\n\t\t/**\n\t\t * Get the slug associated with a strength value\n\t\t *\n\t\t * @since 3.0.0\n\t\t *\n\t\t * @param int strength_val Strength value number.\n\t\t * @return string\n\t\t */\n\t\tget_strength_slug: function( strength_val ) {\n\t\n\t\t\tvar slugs = {\n\t\t\t\t'-1': 'too-short',\n\t\t\t\t1: 'very-weak',\n\t\t\t\t2: 'weak',\n\t\t\t\t3: 'medium',\n\t\t\t\t4: 'strong',\n\t\t\t\t5: 'mismatch',\n\t\t\t};\n\t\n\t\t\treturn ( slugs[ strength_val ] ) ? slugs[ strength_val ] : slugs[5];\n\t\n\t\t},\n\t\n\t\t/**\n\t\t * Gets the translated text associated with a strength value\n\t\t *\n\t\t * @since 3.0.0\n\t\t *\n\t\t * @param {Integer} strength_val Strength value\n\t\t * @return {String}\n\t\t */\n\t\tget_strength_text: function( strength_val ) {\n\t\n\t\t\tvar texts = {\n\t\t\t\t'-1': LLMS.l10n.translate( 'Too Short' ),\n\t\t\t\t1: LLMS.l10n.translate( 'Very Weak' ),\n\t\t\t\t2: LLMS.l10n.translate( 'Weak' ),\n\t\t\t\t3: LLMS.l10n.translate( 'Medium' ),\n\t\t\t\t4: LLMS.l10n.translate( 'Strong' ),\n\t\t\t\t5: LLMS.l10n.translate( 'Mismatch' ),\n\t\t\t};\n\t\n\t\t\treturn ( texts[ strength_val ] ) ? texts[ strength_val ] : texts[5];\n\t\n\t\t},\n\t\n\t\t/**\n\t\t * Get the value associated with a strength slug\n\t\t *\n\t\t * @since 3.0.0\n\t\t *\n\t\t * @param string strength_slug A strength slug.\n\t\t * @return {Integer}\n\t\t */\n\t\tget_strength_value: function( strength_slug ) {\n\t\n\t\t\tvar values = {\n\t\t\t\t'too-short': -1,\n\t\t\t\t'very-weak': 1,\n\t\t\t\tweak: 2,\n\t\t\t\tmedium: 3,\n\t\t\t\tstrong: 4,\n\t\t\t\tmismatch: 5,\n\t\t\t};\n\t\n\t\t\treturn ( values[ strength_slug ] ) ? values[ strength_slug ] : values.mismatch;\n\t\n\t\t},\n\t\n\t\t/**\n\t\t * Setup jQuery references to DOM elements needed to power the password meter.\n\t\t *\n\t\t * @since 5.0.0\n\t\t *\n\t\t * @return {Boolean} Returns `true` if a meter element and password field are found, otherwise returns `false`.\n\t\t */\n\t\tsetup_references: function() {\n\t\n\t\t\tif ( ! this.$meter.length ) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\n\t\t\tthis.$form = this.$meter.closest( 'form' );\n\t\t\tthis.$pass = this.$form.find( 'input#password' );\n\t\n\t\t\tif ( this.$pass.length && this.$pass.attr( 'data-match' ) ) {\n\t\t\t\tthis.$conf = this.$form.find( '#' + this.$pass.attr( 'data-match' ) );\n\t\t\t}\n\t\n\t\t\treturn ( this.$pass.length > 0 );\n\t\n\t\t},\n\t\n\t\t/**\n\t\t * Form submission handler for registration and update forms\n\t\t *\n\t\t * @since 3.0.0\n\t\t * @since 5.0.0 Allow the account edit for to bypass strength checking when the password field is disabled (not being submitted).\n\t\t *\n\t\t * @param obj e Event data.\n\t\t * @return void\n\t\t */\n\t\tsubmit: function( e ) {\n\t\n\t\t\tvar self = e.data;\n\t\t\te.preventDefault();\n\t\t\tself.$pass.trigger( 'keyup' );\n\t\n\t\t\t// Meets the status requirements OR we're on the account edit form and the password field is disabled.\n\t\t\tif ( self.get_current_strength_status() || ( self.$form.hasClass( 'edit-account' ) && 'disabled' === self.$pass.attr( 'disabled' ) ) ) {\n\t\t\t\tself.$form.off( 'submit', self.submit );\n\t\t\t\tself.$form.trigger( 'submit' );\n\t\t\t} else {\n\t\t\t\t$( 'html, body' ).animate( {\n\t\t\t\t\tscrollTop: self.$meter.offset().top - 100,\n\t\t\t\t}, 200 );\n\t\t\t\tself.$meter.hide();\n\t\t\t\tsetTimeout( function() {\n\t\t\t\t\tself.$meter.fadeIn( 400 );\n\t\t\t\t}, 220 );\n\t\t\t}\n\t\t},\n\t\n\t\t/**\n\t\t * Get the list of blocklist strings\n\t\t *\n\t\t * @since 3.0.0\n\t\t * @deprecated 5.0.0 `LLMS.PasswordStrength.get_blacklist()` is deprecated in favor of `LLMS.PasswordStrength.get_blocklist()`.\n\t\t *\n\t\t * @return array\n\t\t */\n\t\tget_blacklist: function() {\n\t\t\tconsole.log( 'Method `get_blacklist()` is deprecated in favor of `get_blocklist()`.' );\n\t\t\treturn this.get_blacklist();\n\t\t},\n\t\n\t} );\n\t\n\t\t/**\n\t * Pricing Table UI\n\t *\n\t * @package LifterLMS/Scripts\n\t *\n\t * @since Unknown.\n\t * @version Unknown.\n\t */\n\t\n\tLLMS.Pricing_Tables = {\n\t\n\t\t/**\n\t\t * Init\n\t\t */\n\t\tinit: function() {\n\t\n\t\t\tvar self = this;\n\t\n\t\t\tif ( $( 'body' ).hasClass( 'wp-admin' ) ) {\n\t\t\t\treturn;\n\t\t\t}\n\t\n\t\t\tif ( $( '.llms-access-plans' ).length ) {\n\t\n\t\t\t\tLLMS.wait_for_matchHeight( function() {\n\t\t\t\t\tself.bind();\n\t\t\t\t} );\n\t\n\t\t\t\tthis.$locked = $( 'a[href=\"#llms-plan-locked\"]' );\n\t\n\t\t\t\tif ( this.$locked.length ) {\n\t\n\t\t\t\t\tLLMS.wait_for_popover( function() {\n\t\t\t\t\t\tself.bind_locked();\n\t\t\t\t\t} );\n\t\n\t\t\t\t}\n\t\n\t\t\t}\n\t\n\t\t},\n\t\n\t\t/**\n\t\t * Bind Method\n\t\t * Handles dom binding on load\n\t\t *\n\t\t * @return {[type]} [description]\n\t\t */\n\t\tbind: function() {\n\t\n\t\t\t$( '.llms-access-plan-content' ).matchHeight();\n\t\t\t$( '.llms-access-plan-pricing.trial' ).matchHeight();\n\t\n\t\t},\n\t\n\t\t/**\n\t\t * Setup a popover for members-only restricted plans\n\t\t *\n\t\t * @return void\n\t\t * @since 3.0.0\n\t\t * @version 3.9.1\n\t\t */\n\t\tbind_locked: function() {\n\t\n\t\t\tthis.$locked.each( function() {\n\t\n\t\t\t\t$( this ).webuiPopover( {\n\t\t\t\t\tanimation: 'pop',\n\t\t\t\t\tcloseable: true,\n\t\t\t\t\tcontent: function( e ) {\n\t\t\t\t\t\tvar $content = $( '
' );\n\t\t\t\t\t\t$content.append( e.$element.closest( '.llms-access-plan' ).find( '.llms-access-plan-restrictions ul' ).clone() );\n\t\t\t\t\t\treturn $content;\n\t\t\t\t\t},\n\t\t\t\t\tplacement: 'top',\n\t\t\t\t\tstyle: 'inverse',\n\t\t\t\t\ttitle: LLMS.l10n.translate( 'Members Only Pricing' ),\n\t\t\t\t\twidth: '280px',\n\t\t\t\t} );\n\t\n\t\t\t} );\n\t\n\t\t},\n\t\n\t};\n\t\n\t\t/**\n\t * LifterLMS Reviews JS\n\t *\n\t * @package LifterLMS/Scripts\n\t *\n\t * @since Unknown\n\t * @version Unknown\n\t */\n\t\n\tLLMS.Review = {\n\t\t/**\n\t\t * Init\n\t\t * loads class methods\n\t\t */\n\t\tinit: function() {\n\t\t\t// console.log('Initializing Review ');\n\t\t\tthis.bind();\n\t\t},\n\t\n\t\t/**\n\t\t * This function binds actions to the appropriate hooks\n\t\t */\n\t\tbind: function() {\n\t\t\t$( '#llms_review_submit_button' ).click(function()\n\t\t\t\t{\n\t\t\t\tif ($( '#review_title' ).val() !== '' && $( '#review_text' ).val() !== '') {\n\t\t\t\t\tjQuery.ajax({\n\t\t\t\t\t\ttype : 'post',\n\t\t\t\t\t\tdataType : 'json',\n\t\t\t\t\t\turl : window.llms.ajaxurl,\n\t\t\t\t\t\tdata : {\n\t\t\t\t\t\t\taction : 'LLMSSubmitReview',\n\t\t\t\t\t\t\treview_title: $( '#review_title' ).val(),\n\t\t\t\t\t\t\treview_text: $( '#review_text' ).val(),\n\t\t\t\t\t\t\tpageID : $( '#post_ID' ).val()\n\t\t\t\t\t\t},\n\t\t\t\t\t\tsuccess: function()\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tconsole.log( 'Review success' );\n\t\t\t\t\t\t\t$( '#review_box' ).hide( 'swing' );\n\t\t\t\t\t\t\t$( '#thank_you_box' ).show( 'swing' );\n\t\t\t\t\t\t},\n\t\t\t\t\t\terror: function(jqXHR, textStatus, errorThrown )\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tconsole.log( jqXHR );\n\t\t\t\t\t\t\tconsole.log( textStatus );\n\t\t\t\t\t\t\tconsole.log( errorThrown );\n\t\t\t\t\t\t},\n\t\t\t\t\t});\n\t\t\t\t} else {\n\t\t\t\t\tif ($( '#review_title' ).val() === '') {\n\t\t\t\t\t\t$( '#review_title_error' ).show( 'swing' );\n\t\t\t\t\t} else {\n\t\t\t\t\t\t$( '#review_title_error' ).hide( 'swing' );\n\t\t\t\t\t}\n\t\t\t\t\tif ($( '#review_text' ).val() === '') {\n\t\t\t\t\t\t$( '#review_text_error' ).show( 'swing' );\n\t\t\t\t\t} else {\n\t\t\t\t\t\t$( '#review_text_error' ).hide( 'swing' );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\t\tif ( $( '#_llms_display_reviews' ).attr( 'checked' ) ) {\n\t\t\t\t$( '.llms-num-reviews-top' ).addClass( 'top' );\n\t\t\t\t$( '.llms-num-reviews-bottom' ).show();\n\t\n\t\t\t} else {\n\t\t\t\t$( '.llms-num-reviews-bottom' ).hide();\n\t\t\t}\n\t\t\t$( '#_llms_display_reviews' ).change(function() {\n\t\t\t\tif ( $( '#_llms_display_reviews' ).attr( 'checked' ) ) {\n\t\t\t\t\t$( '.llms-num-reviews-top' ).addClass( 'top' );\n\t\t\t\t\t$( '.llms-num-reviews-bottom' ).show();\n\t\t\t\t} else {\n\t\t\t\t\t$( '.llms-num-reviews-top' ).removeClass( 'top' );\n\t\t\t\t\t$( '.llms-num-reviews-bottom' ).hide();\n\t\t\t\t}\n\t\t\t});\n\t\n\t\t},\n\t};\n\t\n\t\t/**\n\t * Add Spinners for AJAX events\n\t *\n\t * @package LifterLMS/Scripts\n\t *\n\t * @since 3.0.0\n\t * @version 3.0.0\n\t */\n\t\n\tLLMS.Spinner = {\n\t\n\t\t/**\n\t\t * Get an exiting spinner element or create a new one\n\t\t *\n\t\t * @param obj $el jQuery selector of the parent element that should hold and be mased by a spinner\n\t\t * @param string size size or the spinner [default|small]\n\t\t * default is 40px\n\t\t * small is 20px\n\t\t * @return obj\n\t\t * @since 3.0.0\n\t\t * @version 3.0.0\n\t\t */\n\t\tget: function( $el, size ) {\n\t\n\t\t\t// look for an existing spinner\n\t\t\tvar $spinner = $el.find( '.llms-spinning' ).first();\n\t\n\t\t\t// no spinner inside $el\n\t\t\tif ( ! $spinner.length ) {\n\t\n\t\t\t\tsize = ( size ) ? size : 'default';\n\t\n\t\t\t\t// create the spinner\n\t\t\t\t$spinner = $( '
' );\n\t\n\t\t\t\t// add it to the dom\n\t\t\t\t$el.append( $spinner );\n\t\n\t\t\t}\n\t\n\t\t\t// return it\n\t\t\treturn $spinner;\n\t\n\t\t},\n\t\n\t\t/**\n\t\t * Start spinner(s) inr=side a given element\n\t\t * Creates them if they don't exist!\n\t\t *\n\t\t * @param obj $el jQuery selector of the parent element that should hold and be mased by a spinner\n\t\t * @param string size size or the spinner [default|small]\n\t\t * default is 40px\n\t\t * small is 20px\n\t\t * @return void\n\t\t * @since 3.0.0\n\t\t * @version 3.0.0\n\t\t */\n\t\tstart: function( $el, size ) {\n\t\n\t\t\tvar self = this;\n\t\n\t\t\t$el.each( function() {\n\t\n\t\t\t\tself.get( $( this ), size ).show();\n\t\n\t\t\t} );\n\t\n\t\t},\n\t\n\t\t/**\n\t\t * Store spinners within an element\n\t\t *\n\t\t * @param obj $el jQuery selector of the parent element that should hold and be mased by a spinner\n\t\t * @return void\n\t\t * @since 3.0.0\n\t\t * @version 3.0.0\n\t\t */\n\t\tstop: function( $el ) {\n\t\n\t\t\tvar self = this;\n\t\n\t\t\t$el.each( function() {\n\t\n\t\t\t\tself.get( $( this ) ).hide();\n\t\n\t\t\t} );\n\t\n\t\t}\n\t\n\t};\n\t\n\t\t/* global LLMS, $ */\n\t\n\t/*!\n\t * JavaScript Cookie v2.2.1\n\t * https://github.com/js-cookie/js-cookie\n\t *\n\t * Copyright 2006, 2015 Klaus Hartl & Fagner Brack\n\t * Released under the MIT license\n\t */\n\t;(function (factory) {\n\t\tvar registeredInModuleLoader;\n\t\tif (typeof define === 'function' && define.amd) {\n\t\t\tdefine(factory);\n\t\t\tregisteredInModuleLoader = true;\n\t\t}\n\t\tif (typeof exports === 'object') {\n\t\t\tmodule.exports = factory();\n\t\t\tregisteredInModuleLoader = true;\n\t\t}\n\t\tif (!registeredInModuleLoader) {\n\t\t\tvar OldCookies = window.Cookies;\n\t\t\tvar api = window.Cookies = factory();\n\t\t\tapi.noConflict = function () {\n\t\t\t\twindow.Cookies = OldCookies;\n\t\t\t\treturn api;\n\t\t\t};\n\t\t}\n\t}(function () {\n\t\tfunction extend () {\n\t\t\tvar i = 0;\n\t\t\tvar result = {};\n\t\t\tfor (; i < arguments.length; i++) {\n\t\t\t\tvar attributes = arguments[ i ];\n\t\t\t\tfor (var key in attributes) {\n\t\t\t\t\tresult[key] = attributes[key];\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn result;\n\t\t}\n\t\n\t\tfunction decode (s) {\n\t\t\treturn s.replace(/(%[0-9A-Z]{2})+/g, decodeURIComponent);\n\t\t}\n\t\n\t\tfunction init (converter) {\n\t\t\tfunction api() {}\n\t\n\t\t\tfunction set (key, value, attributes) {\n\t\t\t\tif (typeof document === 'undefined') {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\n\t\t\t\tattributes = extend({\n\t\t\t\t\tpath: '/'\n\t\t\t\t}, api.defaults, attributes);\n\t\n\t\t\t\tif (typeof attributes.expires === 'number') {\n\t\t\t\t\tattributes.expires = new Date(new Date() * 1 + attributes.expires * 864e+5);\n\t\t\t\t}\n\t\n\t\t\t\t// We're using \"expires\" because \"max-age\" is not supported by IE\n\t\t\t\tattributes.expires = attributes.expires ? attributes.expires.toUTCString() : '';\n\t\n\t\t\t\ttry {\n\t\t\t\t\tvar result = JSON.stringify(value);\n\t\t\t\t\tif (/^[\\{\\[]/.test(result)) {\n\t\t\t\t\t\tvalue = result;\n\t\t\t\t\t}\n\t\t\t\t} catch (e) {}\n\t\n\t\t\t\tvalue = converter.write ?\n\t\t\t\t\tconverter.write(value, key) :\n\t\t\t\t\tencodeURIComponent(String(value))\n\t\t\t\t\t\t.replace(/%(23|24|26|2B|3A|3C|3E|3D|2F|3F|40|5B|5D|5E|60|7B|7D|7C)/g, decodeURIComponent);\n\t\n\t\t\t\tkey = encodeURIComponent(String(key))\n\t\t\t\t\t.replace(/%(23|24|26|2B|5E|60|7C)/g, decodeURIComponent)\n\t\t\t\t\t.replace(/[\\(\\)]/g, escape);\n\t\n\t\t\t\tvar stringifiedAttributes = '';\n\t\t\t\tfor (var attributeName in attributes) {\n\t\t\t\t\tif (!attributes[attributeName]) {\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tstringifiedAttributes += '; ' + attributeName;\n\t\t\t\t\tif (attributes[attributeName] === true) {\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\n\t\t\t\t\t// Considers RFC 6265 section 5.2:\n\t\t\t\t\t// ...\n\t\t\t\t\t// 3. If the remaining unparsed-attributes contains a %x3B (\";\")\n\t\t\t\t\t// character:\n\t\t\t\t\t// Consume the characters of the unparsed-attributes up to,\n\t\t\t\t\t// not including, the first %x3B (\";\") character.\n\t\t\t\t\t// ...\n\t\t\t\t\tstringifiedAttributes += '=' + attributes[attributeName].split(';')[0];\n\t\t\t\t}\n\t\n\t\t\t\treturn (document.cookie = key + '=' + value + stringifiedAttributes);\n\t\t\t}\n\t\n\t\t\tfunction get (key, json) {\n\t\t\t\tif (typeof document === 'undefined') {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\n\t\t\t\tvar jar = {};\n\t\t\t\t// To prevent the for loop in the first place assign an empty array\n\t\t\t\t// in case there are no cookies at all.\n\t\t\t\tvar cookies = document.cookie ? document.cookie.split('; ') : [];\n\t\t\t\tvar i = 0;\n\t\n\t\t\t\tfor (; i < cookies.length; i++) {\n\t\t\t\t\tvar parts = cookies[i].split('=');\n\t\t\t\t\tvar cookie = parts.slice(1).join('=');\n\t\n\t\t\t\t\tif (!json && cookie.charAt(0) === '\"') {\n\t\t\t\t\t\tcookie = cookie.slice(1, -1);\n\t\t\t\t\t}\n\t\n\t\t\t\t\ttry {\n\t\t\t\t\t\tvar name = decode(parts[0]);\n\t\t\t\t\t\tcookie = (converter.read || converter)(cookie, name) ||\n\t\t\t\t\t\t\tdecode(cookie);\n\t\n\t\t\t\t\t\tif (json) {\n\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\tcookie = JSON.parse(cookie);\n\t\t\t\t\t\t\t} catch (e) {}\n\t\t\t\t\t\t}\n\t\n\t\t\t\t\t\tjar[name] = cookie;\n\t\n\t\t\t\t\t\tif (key === name) {\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t} catch (e) {}\n\t\t\t\t}\n\t\n\t\t\t\treturn key ? jar[key] : jar;\n\t\t\t}\n\t\n\t\t\tapi.set = set;\n\t\t\tapi.get = function (key) {\n\t\t\t\treturn get(key, false /* read as raw */);\n\t\t\t};\n\t\t\tapi.getJSON = function (key) {\n\t\t\t\treturn get(key, true /* read as json */);\n\t\t\t};\n\t\t\tapi.remove = function (key, attributes) {\n\t\t\t\tset(key, '', extend(attributes, {\n\t\t\t\t\texpires: -1\n\t\t\t\t}));\n\t\t\t};\n\t\n\t\t\tapi.defaults = {};\n\t\n\t\t\tapi.withConverter = init;\n\t\n\t\t\treturn api;\n\t\t}\n\t\n\t\treturn init(function () {});\n\t}));\n\t\n\t/**\n\t * Create a no conflict reference to JS Cookies.\n\t *\n\t * @type {Object}\n\t */\n\tLLMS.CookieStore = Cookies.noConflict();\n\t\n\t/**\n\t * Store information in Local Storage by group.\n\t *\n\t * @since 3.36.0\n\t * @since 3.37.14 Use persistent reference to JS Cookies.\n\t * @since 4.2.0 Set sameSite to `strict` for cookies.\n\t *\n\t * @param string group Storage group id/name.\n\t */\n\tLLMS.Storage = function( group ) {\n\t\n\t\tvar self = this,\n\t\t\tstore = LLMS.CookieStore;\n\t\n\t\t/**\n\t\t * Clear all data for the group.\n\t\t *\n\t\t * @since 3.36.0\n\t\t *\n\t\t * @return void\n\t\t */\n\t\tthis.clearAll = function() {\n\t\t\tstore.remove( group );\n\t\t};\n\t\n\t\t/**\n\t\t * Clear a single item from the group by key.\n\t\t *\n\t\t * @since 3.36.0\n\t\t *\n\t\t * @return obj\n\t\t */\n\t\tthis.clear = function( key ) {\n\t\t\tvar data = self.getAll();\n\t\t\tdelete data[ key ];\n\t\t\treturn store.set( group, data );\n\t\t};\n\t\n\t\t/**\n\t\t * Retrieve (and parse) all data stored for the group.\n\t\t *\n\t\t * @since 3.36.0\n\t\t *\n\t\t * @return obj\n\t\t */\n\t\tthis.getAll = function() {\n\t\t\treturn store.getJSON( group ) || {};\n\t\t}\n\t\n\t\t/**\n\t\t * Retrieve an item from the group by key.\n\t\t *\n\t\t * @since 3.36.0\n\t\t *\n\t\t * @param string key Item key/name.\n\t\t * @param mixed default_val Item default value to be returned when item not found in the group.\n\t\t * @return mixed\n\t\t */\n\t\tthis.get = function( key, default_val ) {\n\t\t\tvar data = self.getAll();\n\t\t\treturn data[ key ] ? data[ key ] : default_val;\n\t\t}\n\t\n\t\t/**\n\t\t * Store an item in the group by key.\n\t\t *\n\t\t * @since 3.36.0\n\t\t * @since 4.2.0 Set sameSite to `strict` for cookies.\n\t\t *\n\t\t * @param string key Item key name.\n\t\t * @param mixed val Item value\n\t\t * @return obj\n\t\t */\n\t\tthis.set = function( key, val ) {\n\t\t\tvar data = self.getAll();\n\t\t\tdata[ key ] = val;\n\t\t\treturn store.set( group, data, { sameSite: 'strict' } );\n\t\t};\n\t\n\t}\n\t\n\t\t/**\n\t * Student Dashboard related JS\n\t *\n\t * @package LifterLMS/Scripts\n\t *\n\t * @since 3.7.0\n\t * @since 3.10.0 Bind events on the orders screen.\n\t * @since 5.0.0 Removed redundant password toggle logic for edit account screen.\n\t * @version 5.0.0\n\t */\n\tLLMS.StudentDashboard = {\n\t\n\t\t/**\n\t\t * Slug for the current screen/endpoint\n\t\t *\n\t\t * @type {String}\n\t\t */\n\t\tscreen: '',\n\t\n\t\t/**\n\t\t * Init\n\t\t *\n\t\t * @since 3.7.0\n\t\t * @since 3.10.0 Unknown\n\t\t * @since 5.0.0 Removed password toggle logic.\n\t\t *\n\t\t * @return void\n\t\t */\n\t\tinit: function() {\n\t\n\t\t\tif ( $( '.llms-student-dashboard' ).length ) {\n\t\t\t\tthis.bind();\n\t\t\t\tif ( 'orders' === this.get_screen() ) {\n\t\t\t\t\tthis.bind_orders();\n\t\t\t\t}\n\t\t\t}\n\t\n\t\t},\n\t\n\t\t/**\n\t\t * Bind DOM events\n\t\t *\n\t\t * @since 3.7.0\n\t\t * @since 3.7.4 Unknown.\n\t\t * @since 5.0.0 Removed password toggle logic.\n\t\t *\n\t\t * @return void\n\t\t */\n\t\tbind: function() {\n\t\n\t\t\t$( '.llms-donut' ).each( function() {\n\t\t\t\tLLMS.Donut( $( this ) );\n\t\t\t} );\n\t\n\t\t},\n\t\n\t\t/**\n\t\t * Bind events related to the orders screen on the dashboard\n\t\t *\n\t\t * @since 3.10.0\n\t\t *\n\t\t * @return void\n\t\t */\n\t\tbind_orders: function() {\n\t\n\t\t\t$( '#llms-cancel-subscription-form' ).on( 'submit', this.order_cancel_warning );\n\t\t\t$( '#llms_update_payment_method' ).on( 'click', function() {\n\t\t\t\t$( 'input[name=\"llms_payment_gateway\"]:checked' ).trigger( 'change' );\n\t\t\t\t$( this ).closest( 'form' ).find( '.llms-switch-payment-source-main' ).slideToggle( '200' );\n\t\t\t} );\n\t\n\t\t},\n\t\n\t\t/**\n\t\t * Get the current dashboard endpoint/tab slug\n\t\t *\n\t\t * @since 3.10.0\n\t\t *\n\t\t * @return void\n\t\t */\n\t\tget_screen: function() {\n\t\t\tif ( ! this.screen ) {\n\t\t\t\tthis.screen = $( '.llms-student-dashboard' ).attr( 'data-current' );\n\t\t\t}\n\t\t\treturn this.screen;\n\t\t},\n\t\n\t\t/**\n\t\t * Show a confirmation warning when Cancel Subscription form is submitted\n\t\t *\n\t\t * @since 3.10.0\n\t\t *\n\t\t * @param obj e JS event data.\n\t\t * @return void\n\t\t */\n\t\torder_cancel_warning: function( e ) {\n\t\t\te.preventDefault();\n\t\t\tvar msg = LLMS.l10n.translate( 'Are you sure you want to cancel your subscription?' );\n\t\t\tif ( window.confirm( LLMS.l10n.translate( msg ) ) ) {\n\t\t\t\t$( this ).off( 'submit', this.order_cancel_warning );\n\t\t\t\t$( this ).submit();\n\t\t\t}\n\t\t},\n\t\n\t};\n\t\n\t\t/* global LLMS, $ */\n\t\n\t/**\n\t * User event/interaction tracking.\n\t *\n\t * @since 3.36.0\n\t * @since 3.36.2 Fix JS error when settings aren't loaded.\n\t * @since 3.37.2 When adding an event to the storae also make sure the nonce is set for server-side verification.\n\t * @since 3.37.9 Fix IE compatibility issue related to usage of `Object.assign()`.\n\t * @since 3.37.14 Persist the tracking events via ajax when reaching the cookie size limit.\n\t * @since 5.0.0 Set `settings` as an empty object when no settings supplied.\n\t * Only attempt to add a nonce to the datastore when a nonce exists in the settings object.\n\t */\n\tLLMS.Tracking = function( settings ) {\n\t\n\t\tsettings = settings || {};\n\t\n\t\tvar self = this,\n\t\t\tstore = new LLMS.Storage( 'llms-tracking' );\n\t\n\t\tsettings = 'string' === typeof settings ? JSON.parse( settings ) : settings;\n\t\n\t\t/**\n\t\t * Initialize / Bind all tracking event listeners.\n\t\t *\n\t\t * @since 3.36.0\n\t\t * @since 5.0.0 Only attempt to add a nonce to the datastore when a nonce exists in the settings object.\n\t\t *\n\t\t * @return {void}\n\t\t */\n\t\tfunction init() {\n\t\n\t\t\t// Set the nonce for server-side verification.\n\t\t\tif ( settings.nonce ) {\n\t\n\t\t\t\tstore.set( 'nonce', settings.nonce );\n\t\n\t\t\t}\n\t\n\t\t\tself.addEvent( 'page.load' );\n\t\n\t\t\twindow.addEventListener( 'beforeunload', onBeforeUnload );\n\t\t\twindow.addEventListener( 'unload', onUnload );\n\t\n\t\t\tdocument.addEventListener( 'visibilitychange', onVisibilityChange );\n\t\n\t\t};\n\t\n\t\t/**\n\t\t * Add an event.\n\t\t *\n\t\t * @since 3.36.0\n\t\t * @since 3.36.2 Fix error when settings aren't loaded.\n\t\t * @since 3.37.2 Always make sure the nonce is set for server-side verification.\n\t\t * @since 3.37.14 Persist the tracking events via ajax when reaching the cookie size limit.\n\t\t *\n\t\t * @param string|obj event Event Id (type.event) or a full event object from `this.makeEventObj()`.\n\t\t * @param int args Optional additional arguments to pass to `this.makeEventObj()`.\n\t\t * @return {void}\n\t\t */\n\t\tthis.addEvent = function( event, args ) {\n\t\n\t\t\targs = args || {};\n\t\t\tif ( 'string' === typeof event ) {\n\t\t\t\targs.event = event;\n\t\t\t}\n\t\n\t\t\t// If the event isn't registered in the settings don't proceed.\n\t\t\tif ( !settings.events || -1 === settings.events.indexOf( args.event ) ) {\n\t\t\t\treturn;\n\t\t\t}\n\t\n\t\t\t// Make sure the nonce is set for server-side verification.\n\t\t\tstore.set( 'nonce', settings.nonce );\n\t\n\t\t\tevent = self.makeEventObj( args );\n\t\n\t\t\tvar all = store.get( 'events', [] );\n\t\t\tall.push( event );\n\t\t\tstore.set( 'events', all );\n\t\n\t\t\t// If couldn't store the latest event because of size limits.\n\t\t\tif ( all.length > store.get( 'events', [] ).length ) {\n\t\n\t\t\t\t// Copy the cookie in a temporary variable.\n\t\t\t\tvar _temp = store.getAll();\n\t\t\t\t// Clear the events from the cookie.\n\t\t\t\tstore.clear('events');\n\t\n\t\t\t\t// Add the latest event to the temporary variable.\n\t\t\t\t_temp['events'].push( event );\n\t\n\t\t\t\t// Send the temporary variable as string via ajax.\n\t\t\t\tLLMS.Ajax.call( {\n\t\t\t\t\tdata: {\n\t\t\t\t\t\taction: 'persist_tracking_events',\n\t\t\t\t\t\t'llms-tracking': JSON.stringify(_temp)\n\t\t\t\t\t},\n\t\n\t\t\t\t\terror: function( xhr, status, error ) {\n\t\n\t\t\t\t\t\tconsole.log( xhr, status, error );\n\t\n\t\t\t\t\t},\n\t\t\t\t\tsuccess: function( r ) {\n\t\n\t\t\t\t\t\tif ( 'error' === r.code ) {\n\t\t\t\t\t\t\tconsole.log(r.code, r.message);\n\t\t\t\t\t\t}\n\t\n\t\t\t\t\t}\n\t\n\t\t\t\t} );\n\t\n\t\t\t}\n\t\n\t\t}\n\t\n\t\t/**\n\t\t * Retrieve initialization settings.\n\t\t *\n\t\t * @since 3.36.0\n\t\t *\n\t\t * @return obj\n\t\t */\n\t\tthis.getSettings = function() {\n\t\t\treturn settings;\n\t\t}\n\t\n\t\t/**\n\t\t * Create an event object suitable to save as an event.\n\t\t *\n\t\t * @since 3.36.0\n\t\t * @since 3.37.9 Use `$.extend()` in favor of `Object.assign()`.\n\t\t *\n\t\t * @param obj event {\n\t\t * Event hash\n\t\t *\n\t\t * @param {string} event (Required) Event ID, eg: \"page.load\".\n\t\t * @param {url} url Event URL. (Optional, added automatically) Stored as metadata and used to infer an object_id for post events.\n\t\t * @param {time} float (Optional, added automatically) Timestamp (in milliseconds). Used for the event creation date.\n\t\t * @param {int} obj_id (Optional). The object ID. Inferred automatically via `url` if not provided.\n\t\t * @param {obj} meta (Optional) Hash of metadata to store with the event.\n\t\t * }\n\t\t * @return obj\n\t\t */\n\t\tthis.makeEventObj = function( event ) {\n\t\t\treturn $.extend( event, {\n\t\t\t\turl: window.location.href,\n\t\t\t\ttime: Math.round( new Date().getTime() / 1000 ),\n\t\t\t} );\n\t\t}\n\t\n\t\n\t\t/**\n\t\t * Remove the visibility change event listener on window.beforeunload\n\t\t *\n\t\t * Prevents actual unloading from recording a blur event from the visibility change listener\n\t\t *\n\t\t * @param obj e JS event object.\n\t\t * @return void\n\t\t */\n\t\tfunction onBeforeUnload( e ) {\n\t\t\tdocument.removeEventListener( 'visibilitychange', onVisibilityChange );\n\t\t}\n\t\n\t\t/**\n\t\t * Record a `page.exit` event on window.unload.\n\t\t *\n\t\t * @since 3.36.0\n\t\t *\n\t\t * @param obj e JS event object.\n\t\t * @return void\n\t\t */\n\t\tfunction onUnload( e ) {\n\t\t\tself.addEvent( 'page.exit' );\n\t\t}\n\t\n\t\t/**\n\t\t * Record `page.blur` and `page.focus` events via document.visilibitychange events.\n\t\t *\n\t\t * @since 3.36.0\n\t\t *\n\t\t * @param obj e JS event object.\n\t\t * @return void\n\t\t */\n\t\tfunction onVisibilityChange( e ) {\n\t\n\t\t\tvar event = document.hidden ? 'page.blur' : 'page.focus';\n\t\t\tself.addEvent( event );\n\t\n\t\t}\n\t\n\t\t// Initialize on the frontend only.\n\t\tif ( ! $( 'body' ).hasClass( 'wp-admin' ) ) {\n\t\t\tinit();\n\t\t}\n\t\n\t};\n\t\n\tllms.tracking = new LLMS.Tracking( llms.tracking );\n\t\n\t\t/**\n\t * Rest Methods\n\t * Manages URL and Rest object parsing\n\t *\n\t * @package LifterLMS/Scripts\n\t *\n\t * @since Unknown\n\t * @version Unknown\n\t */\n\t\n\tLLMS.Rest = {\n\t\n\t\t/**\n\t\t * Init\n\t\t * loads class methods\n\t\t */\n\t\tinit: function() {\n\t\t\tthis.bind();\n\t\t},\n\t\n\t\t/**\n\t\t * Bind Method\n\t\t * Handles dom binding on load\n\t\t *\n\t\t * @return {[type]} [description]\n\t\t */\n\t\tbind: function() {\n\t\t},\n\t\n\t\t/**\n\t\t * Searches for string matches in url path\n\t\t *\n\t\t * @param {Array} strings [Array of strings to search for matches]\n\t\t * @return {Boolean} [Was a match found?]\n\t\t */\n\t\tis_path: function( strings ) {\n\t\n\t\t\tvar path_exists = false,\n\t\t\t\turl = window.location.href;\n\t\n\t\t\tfor ( var i = 0; i < strings.length; i++ ) {\n\t\n\t\t\t\tif ( url.search( strings[i] ) > 0 && ! path_exists ) {\n\t\n\t\t\t\t\tpath_exists = true;\n\t\t\t\t}\n\t\t\t}\n\t\n\t\t\treturn path_exists;\n\t\t},\n\t\n\t\t/**\n\t\t * Retrieves query variables\n\t\t *\n\t\t * @return {[Array]} [array object of query variable key=>value pairs]\n\t\t */\n\t\tget_query_vars: function() {\n\t\n\t\t\tvar vars = [], hash,\n\t\t\t\thashes = window.location.href.slice( window.location.href.indexOf( '?' ) + 1 ).split( '&' );\n\t\n\t\t\tfor (var i = 0; i < hashes.length; i++) {\n\t\t\t\thash = hashes[i].split( '=' );\n\t\t\t\tvars.push( hash[0] );\n\t\t\t\tvars[hash[0]] = hash[1];\n\t\t\t}\n\t\n\t\t\treturn vars;\n\t\t}\n\t\n\t};\n\t\n\n\t/**\n\t * Initializes all classes within the LLMS Namespace\n\t *\n\t * @since Unknown\n\t *\n\t * @return {void}\n\t */\n\tLLMS.init = function() {\n\n\t\tfor (var func in LLMS) {\n\n\t\t\tif ( typeof LLMS[func] === 'object' && LLMS[func] !== null ) {\n\n\t\t\t\tif ( LLMS[func].init !== undefined ) {\n\n\t\t\t\t\tif ( typeof LLMS[func].init === 'function') {\n\t\t\t\t\t\tLLMS[func].init();\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t};\n\n\t/**\n\t * Determine if the current device is touch-enabled\n\t *\n\t * @since 3.24.3\n\t *\n\t * @see {@link https://stackoverflow.com/a/4819886/400568}\n\t *\n\t * @return {Boolean} Whether or not the device is touch-enabled.\n\t */\n\tLLMS.is_touch_device = function() {\n\n\t\tvar prefixes = ' -webkit- -moz- -o- -ms- '.split( ' ' );\n\t\tvar mq = function( query ) {\n\t\t\treturn window.matchMedia( query ).matches;\n\t\t}\n\n\t\tif ( ( 'ontouchstart' in window ) || window.DocumentTouch && document instanceof DocumentTouch ) {\n\t\t\treturn true;\n\t\t}\n\n\t\t/**\n\t\t * Include the 'heartz' as a way to have a non matching MQ to help terminate the join.\n\t\t *\n\t\t * @see {@link https://git.io/vznFH}\n\t\t */\n\t\tvar query = ['(', prefixes.join( 'touch-enabled),(' ), 'heartz', ')'].join( '' );\n\t\treturn mq( query );\n\n\t};\n\n\t/**\n\t * Wait for matchHeight to load\n\t *\n\t * @since 3.0.0\n\t * @since 3.16.6 Unknown.\n\t * @since 5.3.3 Pass a dependency name to `wait_for()`.\n\t *\n\t * @param {Function} cb Callback function to run when matchheight is ready.\n\t * @return {void}\n\t */\n\tLLMS.wait_for_matchHeight = function( cb ) {\n\t\tthis.wait_for( function() {\n\t\t\treturn ( undefined !== $.fn.matchHeight );\n\t\t}, cb, 'matchHeight' );\n\t}\n\n\t/**\n\t * Wait for webuiPopover to load\n\t *\n\t * @since 3.9.1\n\t * @since 3.16.6 Unknown.\n\t *\n\t * @param {Function} cb Callback function to run when matchheight is ready.\n\t * @return {void}\n\t */\n\tLLMS.wait_for_popover = function( cb ) {\n\t\tthis.wait_for( function() {\n\t\t\treturn ( undefined !== $.fn.webuiPopover );\n\t\t}, cb, 'webuiPopover' );\n\t}\n\n\t/**\n\t * Wait for a dependency to load and then run a callback once it has\n\t *\n\t * Temporary fix for a less-than-optimal assets loading function on the PHP side of things.\n\t *\n\t * @since 3.9.1\n\t * @since 5.3.3 Added optional `name` parameter.\n\t *\n\t * @param {Function} test A function that returns a truthy if the dependency is loaded.\n\t * @param {Function} cb A callback function executed once the dependency is loaded.\n\t * @param {string} name The dependency name.\n\t * @return {void}\n\t */\n\tLLMS.wait_for = function( test, cb, name ) {\n\n\t\tvar counter = 0,\n\t\t\tinterval;\n\n\t\tname = name ? name : 'unnamed';\n\n\t\tinterval = setInterval( function() {\n\n\t\t\t// If we get to 30 seconds log an error message.\n\t\t\tif ( counter >= 300 ) {\n\n\t\t\t\tconsole.log( 'Unable to load dependency: ' + name );\n\n\t\t\t\t// If we can't access yet, increment and wait...\n\t\t\t} else {\n\n\t\t\t\t// Bind the events, we're good!\n\t\t\t\tif ( test() ) {\n\t\t\t\t\tcb();\n\t\t\t\t} else {\n\t\t\t\t\t// console.log( 'Waiting for dependency: ' + name );\n\t\t\t\t\tcounter++;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tclearInterval( interval );\n\n\t\t}, 100 );\n\n\t};\n\n\tLLMS.init( $ );\n\n} )( jQuery );\n"],"sourceRoot":"../../js"} \ No newline at end of file diff --git a/class-lifterlms.php b/class-lifterlms.php index 70e96a80e8..745a7d05d9 100644 --- a/class-lifterlms.php +++ b/class-lifterlms.php @@ -34,7 +34,7 @@ final class LifterLMS { * * @var string */ - public $version = '6.10.1'; + public $version = '6.10.2'; /** * LLMS_Assets instance diff --git a/languages/lifterlms.pot b/languages/lifterlms.pot index a79de50ad3..bca72b43e3 100644 --- a/languages/lifterlms.pot +++ b/languages/lifterlms.pot @@ -2,14 +2,14 @@ # This file is distributed under the GPLv3. msgid "" msgstr "" -"Project-Id-Version: LifterLMS 6.10.1\n" +"Project-Id-Version: LifterLMS 6.10.2\n" "Report-Msgid-Bugs-To: https://lifterlms.com/my-account/my-tickets\n" "Last-Translator: Team LifterLMS \n" "Language-Team: Team LifterLMS \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"POT-Creation-Date: 2022-09-07T09:15:44-07:00\n" +"POT-Creation-Date: 2022-09-14T11:42:42-06:00\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "X-Generator: llms/dev 0.1.0\n" "X-Domain: lifterlms\n" @@ -2509,7 +2509,6 @@ msgstr "" msgid "Template" msgstr "" -#. Translators: %s: Post title. #: includes/admin/post-types/post-tables/class-llms-admin-post-table-awards.php:117 #: includes/admin/post-types/post-tables/class-llms-admin-post-table-awards.php:325 msgid "Delete Permanently" @@ -4038,7 +4037,6 @@ msgstr "" msgid "Deletes pending batches generated by LifterLMS background processors." msgstr "" -#. Translators: %d = the number of pending batches. #: includes/admin/tools/class-llms-admin-tool-batch-eraser.php:44 msgid "There is currently %d pending batch that will be deleted." msgid_plural "There are currently %d pending batches that will be deleted." @@ -4082,7 +4080,6 @@ msgstr "" msgid "The method used to determine when a limited-billing recurring order has completed its payment plan changed during version 5.3.0. This tool provides a report of orders which may been affected by this change. %1$sRead more%2$s about this change." msgstr "" -#. Translators: %d = the number of pending batches. #: includes/admin/tools/class-llms-admin-tool-limited-billing-order-locator.php:134 msgid "There is %d order that should be reviewed." msgid_plural "There are %d orders that should be reviewed." @@ -4101,7 +4098,6 @@ msgstr "" msgid "Check active recurring orders to ensure their recurring payment action is properly scheduled for the next payment. If a recurring payment is due and not scheduled it will be rescheduled." msgstr "" -#. Translators: %d = the number of pending batches. #: includes/admin/tools/class-llms-admin-tool-recurring-payment-rescheduler.php:46 msgid "There is %d order that will be checked." msgid_plural "There are %d orders that will be checked in batches of 50." diff --git a/lifterlms.php b/lifterlms.php index 8624edeb29..977bff0e4d 100644 --- a/lifterlms.php +++ b/lifterlms.php @@ -10,7 +10,7 @@ * Plugin Name: LifterLMS * Plugin URI: https://lifterlms.com/ * Description: LifterLMS is a powerful WordPress learning management system plugin that makes it easy to create, sell, and protect engaging online courses and training based membership websites. - * Version: 6.10.1 + * Version: 6.10.2 * Author: LifterLMS * Author URI: https://lifterlms.com/ * Text Domain: lifterlms diff --git a/package-lock.json b/package-lock.json index 427214ea01..129e7a22f4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "lifterlms", - "version": "6.10.1", + "version": "6.10.2", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "lifterlms", - "version": "6.10.1", + "version": "6.10.2", "license": "GPL-3.0", "dependencies": { "@babel/core": "^7.16.5", diff --git a/package.json b/package.json index fdeaaae436..eea372dff6 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "lifterlms", - "version": "6.10.1", + "version": "6.10.2", "description": "LifterLMS by codeBOX", "repository": { "type": "git", diff --git a/readme.txt b/readme.txt index dc31ee768c..ed0f0161bd 100644 --- a/readme.txt +++ b/readme.txt @@ -7,7 +7,7 @@ License URI: https://www.gnu.org/licenses/gpl-3.0.html Requires at least: 5.6 Tested up to: 6.0 Requires PHP: 7.4 -Stable tag: 6.10.1 +Stable tag: 6.10.2 LifterLMS is a powerful WordPress learning management system plugin that makes it easy to create, sell, and protect engaging online courses and training based membership websites. @@ -540,6 +540,17 @@ You can review our full security policy at [https://lifterlms.com/security-polic == Changelog == += v6.10.2 - 2022-09-14 = + +##### Updates and Enhancements + ++ Updated `woocommerce/action-scheduler` to version [3.5.1](https://github.com/woocommerce/action-scheduler/releases/tag/3.5.1). + +##### Security Fixes + ++ Fixed a data sanitization issue related to achievement permalinks. + + = v6.10.1 - 2022-09-07 = ##### Bug Fixes @@ -722,26 +733,4 @@ You can review our full security policy at [https://lifterlms.com/security-polic + Added new filter `llms_buddypress_min_nav_item_position` to control the LifterLMS main BuddyPress' nav item position. -= v6.2.0 - 2022-03-30 = - -##### Updates and Enhancements - -+ Changed the `llmsStudentsSelect2()` JavaScript function to use the LifterLMS REST API "list students" endpoint instead of the `LLMS_AJAX_Handler::query_students()` PHP function. -+ Upgraded LifterLMS Blocks to [v2.4.1](https://make.lifterlms.com/2022/03/30/lifterlms-blocks-version-2-4-1/). - -##### Bug Fixes - -+ Fixed issue with hidden checkboxes on LifterLMS forms. -+ Fixed a compatiblity issue with the Divi Theme Builder ignoring access restrictions when using template with custom body. [#2063](https://github.com/gocodebox/lifterlms/issues/2063) -+ Fixed an error encountered on the Engagements > Certificates screen when using the BuddyBoss theme. [#2080](https://github.com/gocodebox/lifterlms/issues/2080) - -##### Deprecations - -+ Deprecated `LLMS_AJAX_Handler::query_students()`. Use the [REST API list students](https://developer.lifterlms.com/rest-api/#tag/Students/paths/~1students/get) endpoint instead. - -##### Developer Notes - -+ Added new filter `llms_template_loader_priority` to control the priority of the `template_include` hook callback used to load restricted content templates. - - [Read the full changelog](https://make.lifterlms.com/tag/lifterlms)