+ echo '
';
- }
-
- /**
+ }
+
+ /**
* reCAPTCHA Secret Key
*
- * @since 2.6
- *
+ * @since 2.6
+ *
* @return void password protected v2/v3 secretkey field
*/
- public function reCAPTCHA_secret_key() {
-
- echo '
+ public function reCAPTCHA_secret_key() {
+
+ echo '
';
- echo '
+ echo '
';
- }
+ }
- /**
+ /**
* reCAPTCHA V3 Score
*
- * @since 2.6
- *
+ * @since 2.6
+ *
* @return void password protected v3 score field
*/
- public function reCAPTCHA_score() {
- echo '
+ public function reCAPTCHA_score() {
+ echo '
settings['v3_score'], false ) . '
/>
@@ -319,7 +341,7 @@ public function reCAPTCHA_score() {
settings['v3_score'], false ) . '
/>
@@ -329,7 +351,7 @@ public function reCAPTCHA_score() {
settings['v3_score'], false ) . '
/>
@@ -339,7 +361,7 @@ public function reCAPTCHA_score() {
settings['v3_score'], false ) . '
/>
@@ -349,7 +371,7 @@ public function reCAPTCHA_score() {
settings['v3_score'], false ) . '
/>
@@ -358,21 +380,21 @@ public function reCAPTCHA_score() {
Select Google Version 3 Score.
';
- }
+ }
- /**
+ /**
* reCAPTCHA V3 Badge Position
*
- * @since 2.6
- *
+ * @since 2.6
+ *
* @return void password protected v3 badgeposition field
*/
- public function reCAPTCHA_badge_position() {
- echo '
+ public function reCAPTCHA_badge_position() {
+ echo '
settings['v3_badge'], false ) . '
/>
@@ -382,7 +404,7 @@ public function reCAPTCHA_badge_position() {
settings['v3_badge'], false ) . '
/>
@@ -392,28 +414,28 @@ public function reCAPTCHA_badge_position() {
settings['v3_badge'], false ) . '
/>
Bottom - Right
';
- }
+ }
- /**
+ /**
* reCAPTCHA V2 Theme
*
- * @since 2.6
- *
+ * @since 2.6
+ *
* @return void password protected v2 theme field
*/
- public function reCAPTCHA_theme() {
- echo '
+ public function reCAPTCHA_theme() {
+ echo '
settings['v2_theme'], false ) . '
/>
@@ -423,63 +445,67 @@ public function reCAPTCHA_theme() {
settings['v2_theme'], false ) . '
/>
Dark
Select Google reCAPTCHA Version 2 Theme.
';
- }
+ }
- /**
+ /**
* Add reCAPTCHA on Password Protected Form
*
- * @since 2.6
- *
+ * @since 2.6
+ *
* @return void password protected reCAPTCHA v2 OR v3
*/
- public function add_recaptcha() {
- if( ! @$this->settings['enable'] )
- return; //recpatcha is disabled
-
- if( $this->settings['version'] === 'google_recaptcha_v2' )
- $this->display_recaptcha_v2();
-
- if( $this->settings['version'] === 'google_recaptcha_v3' )
- $this->display_recaptcha_v3();
- }
+ public function add_recaptcha() {
+ if ( ! @$this->settings['enable'] ) {
+ return; // recpatcha is disabled
+ }
+
+ if ( $this->settings['version'] === 'google_recaptcha_v2' ) {
+ $this->display_recaptcha_v2();
+ }
+
+ if ( $this->settings['version'] === 'google_recaptcha_v3' ) {
+ $this->display_recaptcha_v3();
+ }
+ }
- /**
+ /**
* Diaplay reCAPTCHA V2
*
- * @since 2.6
- *
+ * @since 2.6
+ *
* @return void password protected reCAPTCHA v2 field
*/
- public function display_recaptcha_v2() {
- wp_enqueue_style( 'pp-recaptcha-style', plugin_dir_url( __DIR__ ) . "assets/css/recaptcha.css", array(), '2.6.2' );
- wp_enqueue_script( 'pp-recaptcha-api-v2', esc_url( 'https://www.google.com/recaptcha/api.js' ), array(), null );
- echo 'version );
+ wp_enqueue_script( 'pp-recaptcha-api-v2', esc_url( 'https://www.google.com/recaptcha/api.js' ), array(), null );
+ echo '
';
- }
+ }
- /**
+ /**
* Diaplay reCAPTCHA V3
*
- * @since 2.6
- *
+ * @since 2.6
+ *
* @return void password protected reCAPTCHA v3 field
*/
- public function display_recaptcha_v3() {
- $grecaptcha_v3_site_key = isset( $this->settings['v3_site_key'] ) ? esc_attr( $this->settings['v3_site_key'] ) : '';
- $grecaptcha_v3_badge = isset( $this->settings['v3_badge'] ) ? esc_attr( $this->settings['v3_badge'] ) : 'bottomright';
+ public function display_recaptcha_v3() {
+ $grecaptcha_v3_site_key = isset( $this->settings['v3_site_key'] ) ? esc_attr( $this->settings['v3_site_key'] ) : '';
+ $grecaptcha_v3_badge = isset( $this->settings['v3_badge'] ) ? esc_attr( $this->settings['v3_badge'] ) : 'bottomright';
- $script = <<
+ wp_enqueue_script( 'recaptcha-api-v3', ( 'https://www.google.com/recaptcha/api.js?onload=pprecaptcha&render=' . esc_attr( $grecaptcha_v3_site_key ) . '&badge=' . esc_attr( $grecaptcha_v3_badge ) ), array(), null );
+ wp_add_inline_script( 'recaptcha-api-v3', $script ); ?>
settings['enable'] ) {
- return $errors; // return errors
- }
+ public function verify_recaptcha( $errors ) {
+
+ if ( ! @$this->settings['enable'] ) {
+ return $errors; // return errors
+ }
+
+ if ( $this->settings['version'] === 'google_recaptcha_v2' ) {
+
+ $grecaptcha_v2_site_key = isset( $this->settings['v2_site_key'] ) ? esc_attr( $this->settings['v2_site_key'] ) : '';
+ $grecaptcha_v2_secret_key = isset( $this->settings['v2_secret_key'] ) ? esc_attr( $this->settings['v2_secret_key'] ) : '';
+
+ if ( empty( $grecaptcha_v2_site_key ) || empty( $grecaptcha_v2_secret_key ) ) {
+ $errors->add( 001, 'Google reCaptcha keys not found.' );
+ }
+
+ if ( isset( $_POST['g-recaptcha-response'] ) && ! empty( $_POST['g-recaptcha-response'] ) ) {
+ $response = wp_remote_post(
+ 'https://www.google.com/recaptcha/api/siteverify',
+ array(
+ 'body' => array(
+ 'secret' => $grecaptcha_v2_secret_key,
+ 'response' => sanitize_text_field( $_POST['g-recaptcha-response'] ),
+ ),
+ )
+ );
+
+ $data = wp_remote_retrieve_body( $response );
+ $data = json_decode( $data );
+
+ if ( isset( $data->{'error-codes'} ) && is_array( $data->{'error-codes'} ) && count( $data->{'error-codes'} ) ) {
+ foreach ( $data->{'error-codes'} as $index => $error_code ) {
+ $errors->add( $index, $error_code );
+ }
+ }
+
+ if ( isset( $data->success ) && true === $data->success ) {
+ return $errors;
+ }
+ }
+ $error_message = wp_kses( __( 'ERROR: Please confirm you are not a robot.', 'password-protected' ), array( 'strong' => array() ) );
+ $errors->add( 'captcha_invalid', $error_message );
+
+ return $errors;
+
+ } elseif ( $this->settings['version'] === 'google_recaptcha_v3' ) {
+
+ $grecaptcha_v3_site_key = isset( $this->settings['v3_site_key'] ) ? esc_attr( $this->settings['v3_site_key'] ) : '';
+ $grecaptcha_v3_secret_key = isset( $this->settings['v3_secret_key'] ) ? esc_attr( $this->settings['v3_secret_key'] ) : '';
+ $grecaptcha_v3_score = isset( $this->settings['v3_score'] ) ? esc_attr( $this->settings['v3_score'] ) : '0.3';
+
+ if ( empty( $grecaptcha_v3_site_key ) || empty( $grecaptcha_v3_secret_key ) ) {
+ $errors->add( 001, 'Google reCaptcha keys not found.' );
+ }
+
+ if ( isset( $_POST['g-recaptcha-response'] ) && ! empty( $_POST['g-recaptcha-response'] ) ) {
+ $response = wp_remote_post(
+ 'https://www.google.com/recaptcha/api/siteverify',
+ array(
+ 'body' => array(
+ 'secret' => $grecaptcha_v3_secret_key,
+ 'response' => sanitize_text_field( $_POST['g-recaptcha-response'] ),
+ 'remoteip' => self::get_ip_address(),
+ ),
+ )
+ );
+
+ $data = wp_remote_retrieve_body( $response );
+ $data = json_decode( $data );
+
+ if ( isset( $data->{'error-codes'} ) && is_array( $data->{'error-codes'} ) && count( $data->{'error-codes'} ) ) {
+ foreach ( $data->{'error-codes'} as $index => $error_code ) {
+ $errors->add( $index, $error_code );
+ }
+ }
+
+ if ( isset( $data->success ) && true === $data->success ) {
+ $grecaptcha_v3_score = (float) $grecaptcha_v3_score;
+ if ( isset( $data->action ) && ( 'password_protected' === $data->action ) && isset( $data->score ) && $data->score >= $grecaptcha_v3_score ) {
+ return $errors;
+ } else {
+ $error_message = wp_kses( __( 'ERROR: Low Score ', 'password-protected' ) . ':' . esc_html( $data->score ), array( 'strong' => array() ) );
+ $errors->add( 002, $error_message );
+ }
+ }
+ }
+
+ return $errors;
+ }
- if( $this->settings['version'] === 'google_recaptcha_v2' ) {
-
- $grecaptcha_v2_site_key = isset( $this->settings['v2_site_key'] ) ? esc_attr( $this->settings['v2_site_key'] ) : '';
- $grecaptcha_v2_secret_key = isset( $this->settings['v2_secret_key'] ) ? esc_attr( $this->settings['v2_secret_key'] ) : '';
-
- if ( empty( $grecaptcha_v2_site_key ) || empty( $grecaptcha_v2_secret_key ) ) {
- $errors->add( 001, 'Google reCaptcha keys not found.' );
- }
-
- if ( isset( $_POST['g-recaptcha-response'] ) && ! empty( $_POST['g-recaptcha-response'] ) ) {
- $response = wp_remote_post(
- 'https://www.google.com/recaptcha/api/siteverify',
- array(
- 'body' => array(
- 'secret' => $grecaptcha_v2_secret_key,
- 'response' => sanitize_text_field($_POST['g-recaptcha-response'] ),
- )
- )
- );
-
- $data = wp_remote_retrieve_body( $response );
- $data = json_decode( $data );
-
- if ( isset( $data->{'error-codes'} ) && is_array( $data->{'error-codes'} ) && count( $data->{'error-codes'} ) ) {
- foreach ( $data->{'error-codes'} as $index => $error_code ) {
- $errors->add( $index, $error_code );
- }
- }
-
- if ( isset( $data->success ) && true === $data->success ) {
- return $errors;
- }
- }
- $error_message = wp_kses( __( 'ERROR: Please confirm you are not a robot.', 'password-protected' ), array( 'strong' => array() ) );
- $errors->add( 'captcha_invalid', $error_message );
-
- return $errors;
-
- } else if( $this->settings['version'] === 'google_recaptcha_v3' ) {
-
- $grecaptcha_v3_site_key = isset( $this->settings['v3_site_key'] ) ? esc_attr( $this->settings['v3_site_key'] ) : '';
- $grecaptcha_v3_secret_key = isset( $this->settings['v3_secret_key'] ) ? esc_attr( $this->settings['v3_secret_key'] ) : '';
- $grecaptcha_v3_score = isset( $this->settings['v3_score'] ) ? esc_attr( $this->settings['v3_score'] ) : '0.3';
-
- if ( empty( $grecaptcha_v3_site_key ) || empty( $grecaptcha_v3_secret_key ) ) {
- $errors->add( 001, 'Google reCaptcha keys not found.' );
- }
-
- if ( isset( $_POST['g-recaptcha-response'] ) && ! empty( $_POST['g-recaptcha-response'] ) ) {
- $response = wp_remote_post(
- 'https://www.google.com/recaptcha/api/siteverify',
- array(
- 'body' => array(
- 'secret' => $grecaptcha_v3_secret_key,
- 'response' => sanitize_text_field( $_POST['g-recaptcha-response'] ),
- 'remoteip' => self::get_ip_address(),
- )
- )
- );
-
- $data = wp_remote_retrieve_body( $response );
- $data = json_decode( $data );
-
- if ( isset( $data->{'error-codes'} ) && is_array( $data->{'error-codes'} ) && count( $data->{'error-codes'} ) ) {
- foreach ( $data->{'error-codes'} as $index => $error_code ) {
- $errors->add( $index, $error_code );
- }
- }
-
- if ( isset( $data->success ) && true === $data->success ) {
- $grecaptcha_v3_score = (float) $grecaptcha_v3_score;
- if ( isset( $data->action ) && ( 'password_protected' === $data->action ) && isset( $data->score ) && $data->score >= $grecaptcha_v3_score ) {
- return $errors;
- } else {
- $error_message = wp_kses( __( 'ERROR: Low Score ', 'password-protected' ) . ':' . esc_html( $data->score ) , array( 'strong' => array() ) );
- $errors->add( 002, $error_message );
- }
- }
- }
-
- return $errors;
- }
-
- }
+ }
- /**
+ /**
* Get IP Address
*
- * @since 2.6
- *
+ * @since 2.6
+ *
* @return string client IP address
*/
- private static function get_ip_address() {
- $ipaddress = '';
- if (isset($_SERVER['HTTP_CLIENT_IP']))
- $ipaddress = sanitize_text_field( $_SERVER['HTTP_CLIENT_IP'] );
- else if(isset($_SERVER['HTTP_X_FORWARDED_FOR']))
- $ipaddress = sanitize_text_field( $_SERVER['HTTP_X_FORWARDED_FOR'] );
- else if(isset($_SERVER['HTTP_X_FORWARDED']))
- $ipaddress = sanitize_text_field( $_SERVER['HTTP_X_FORWARDED'] );
- else if(isset($_SERVER['HTTP_FORWARDED_FOR']))
- $ipaddress = sanitize_text_field( $_SERVER['HTTP_FORWARDED_FOR'] );
- else if(isset($_SERVER['HTTP_FORWARDED']))
- $ipaddress = sanitize_text_field( $_SERVER['HTTP_FORWARDED'] );
- else if(isset($_SERVER['REMOTE_ADDR']))
- $ipaddress = sanitize_text_field( $_SERVER['REMOTE_ADDR'] );
- else
- $ipaddress = 'UNKNOWN';
- return $ipaddress;
- }
+ private static function get_ip_address() {
+ $ipaddress = '';
+ if ( isset( $_SERVER['HTTP_CLIENT_IP'] ) ) {
+ $ipaddress = sanitize_text_field( $_SERVER['HTTP_CLIENT_IP'] );
+ } elseif ( isset( $_SERVER['HTTP_X_FORWARDED_FOR'] ) ) {
+ $ipaddress = sanitize_text_field( $_SERVER['HTTP_X_FORWARDED_FOR'] );
+ } elseif ( isset( $_SERVER['HTTP_X_FORWARDED'] ) ) {
+ $ipaddress = sanitize_text_field( $_SERVER['HTTP_X_FORWARDED'] );
+ } elseif ( isset( $_SERVER['HTTP_FORWARDED_FOR'] ) ) {
+ $ipaddress = sanitize_text_field( $_SERVER['HTTP_FORWARDED_FOR'] );
+ } elseif ( isset( $_SERVER['HTTP_FORWARDED'] ) ) {
+ $ipaddress = sanitize_text_field( $_SERVER['HTTP_FORWARDED'] );
+ } elseif ( isset( $_SERVER['REMOTE_ADDR'] ) ) {
+ $ipaddress = sanitize_text_field( $_SERVER['REMOTE_ADDR'] );
+ } else {
+ $ipaddress = 'UNKNOWN';
+ }
+ return $ipaddress;
+ }
}
-
diff --git a/assets/css/admin.css b/assets/css/admin.css
index 5e64e8f..3183387 100644
--- a/assets/css/admin.css
+++ b/assets/css/admin.css
@@ -1,18 +1,18 @@
#help-notice {
margin-top: 10px;
+ margin-bottom: 10px;
}
#help-notice, #pp-sidebar-box {
background: white;
- border: #9d9d9d 1px solid;
padding: 0px 20px;
}
.wrap-col-70 {
- flex: 0 0 70%;
- width: 70%;
+ flex: 0 0 80%;
+ width: 80%;
}
.wrap-col-25 {
- flex: 0 1 25%;
+ flex: 0 1 15%;
}
.wrap-row {
display: flex;
@@ -22,9 +22,9 @@ h2.nav-tab-wrapper {
display: inline-block;
}
div#pp-sidebar-box {
- border: 3px dashed #c5c2c2;
- border-radius: 10px;
- margin-top: 9px;
+ border: 3px solid #fff;
+ /*border-radius: 10px;*/
+ /*margin-top: 9px;*/
}
#pp-sidebar-box {
line-height: 1.5;
@@ -37,6 +37,10 @@ div#pp-sidebar-box {
font-size: 14px;
font-weight: 500;
}
+
+#pp-sidebar-box h3 {
+ font-weight: 400;
+}
.pro-tab-content {
color: #384d48;
position: relative;
@@ -79,4 +83,663 @@ a.nav-tab.getpro.nav-tab {
input#password_protected_password_new, input#password_protected_password_confirm, input#password_protected_remember_me_lifetime, textarea#password_protected_allowed_ip_addresses {
width: 50% !important;
+}
+
+.template-container {
+ width: 100%;
+ height: 100vh;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ background: #000;
+}
+.banner {
+ margin-top: 15px;
+ width: 860px;
+ /*height: 480px;*/
+ /*background-image: url("images/PPP-ads-14.png");*/
+ background-color: rgb( 255, 255, 255 );
+ background-position: center;
+ background-repeat: no-repeat;
+ padding: 30px 50px;
+}
+.banner-header {
+ margin-bottom: 2.5em;
+}
+
+.banner-header h2, .banner-header h1 {
+ font-weight: 700;
+ color: #000;
+}
+.banner-col-2 {
+ width: 50%;
+ float: left;
+}
+.password-protected-feature {
+ width: 100%;
+ font-size: 16px;
+ color: #fff;
+ position: relative;
+ padding-left: 35px;
+ padding-bottom: 25px;
+}
+.password-protected-feature img {
+ position: absolute;
+ top: -3px;
+ left: 0;
+}
+.banner-footer {
+ margin-top: 1.5em;
+}
+.banner-button {
+ background: #fda84e;
+ color: #000;
+ display: inline-block;
+ text-align: center;
+ height: 50px;
+ line-height: 50px;
+ border-radius: 5px;
+ text-decoration: none;
+ font-weight: 500;
+ padding: 0 15px;
+ font-size: 15px;
+}
+
+.sidebar-widget {
+ margin-top: 15px;
+ margin-bottom: 15px;
+ background: rgb( 255, 255, 255 );
+ padding: 5px 15px;
+}
+.sidebar-widget .password-protected-feature {
+ padding-bottom: 15px;
+ font-size: 15px;
+}
+.sidebar-widget .banner-button {
+ font-size: 12px;
+ font-weight: 500;
+ padding: 0 10px;
+ height: 35px;
+ line-height: 35px;
+}
+.clearfix {
+ clear: both;
+ display: table;
+}
+
+.password-protected-feature a:hover {
+ text-decoration: underline;
+}
+.password-protected-feature a {
+ text-decoration: none;
+ color: #000;
+}
+
+.sidebar-widget .banner-body {
+ width: calc( 100% - 25px );
+}
+.password-protected-datatable {
+ width: 100%;
+}
+
+.password-protected-datatable thead tr th,
+.password-protected-datatable tfoot tr th {
+ cursor: pointer;
+ border: 1px solid #dcdcde;
+ background: #fff;
+ padding: 15px 0;
+}
+
+.password-protected-datatable tbody tr td {
+ padding: 15px 0;
+ border: 1px solid #dcdcde;
+}
+
+.pp-help-notice {
+ margin-top: 15px;
+ margin-bottom: 15px;
+ background: #EBEDF1;
+ padding: 10px;
+ border: 1px solid #d9dce3;
+ border-radius: 5px;
+ color: #000;
+}
+
+.pp-help-notice p {
+ font-size: 14px;
+ font-weight: 500;
+ margin: 0;
+}
+
+/*
+ tabs UI styling
+*/
+.pp-wrapper {
+ margin-top: 15px;
+ width: 100%;
+ border-top-left-radius: 5px;
+ border-top-right-radius: 5px;
+ background: #fff;
+}
+
+.pp-nav-wrapper {
+ width: 100%;
+ background: #efeff0;
+}
+
+.pp-nav-tab {
+ border-top-left-radius: 5px;
+ border-top-right-radius: 5px;
+ display: inline-block;
+ border-right: 1px solid #d9dce3;
+ background: #f6f6f6;
+}
+
+.pp-nav-tab a {
+ font-size: 14px;
+ font-weight: 600;
+ color: #707578;
+ text-decoration: none;
+ padding: 8px 14px;
+ display: block;
+ line-height: 32px;
+}
+
+.pp-nav-tab span {
+ line-height: 32px;
+ display: inline-block;
+ font-size: 21px;
+ font-weight: 600;
+}
+
+.pp-nav-tab-active {
+ background: #fff;
+}
+
+.pp-nav-tab-active a {
+ color: #8076ff;
+}
+
+.pp-nav-tab:hover {
+ background: #fff;
+}
+
+.pp-nav-tab a:hover {
+ color: #8076ff;
+}
+
+.pp-sub-tabs-wrapper {
+ width: calc( 100% - 15px );
+ height: 45px;
+ background: #fff;
+ border-bottom: 1px solid #f7f8fa;
+}
+
+.pp-sub-tabs-wrapper .pp-subtabs-links {
+ height: 45px;
+ display: inline-block;
+ border-bottom: 3px solid #f7f8fa;
+ position: relative;
+}
+
+.pp-subtabs-links a {
+ line-height: 45px;
+ text-decoration: none;
+ font-weight: 600;
+ color: #707578;
+ font-size: 14px;
+ padding: 0 15px;
+ height: calc( 100% - 1px );
+ display: inline-block;
+}
+
+.pp-subtabs-links a.active {
+ border-bottom: 3px solid #8076ff;
+ color: #8076ff;
+}
+
+.pp-subtabs-links a:hover {
+ color: #8076ff;
+}
+
+.pp-subtabs-links a:focus, .pp-nav-tab a:focus {
+ outline: none;
+ box-shadow: none;
+}
+
+.pp-settings-wrapper {
+ width: calc( 100% - 30px );
+ background: transparent;
+ border-top: none;
+}
+
+.pp-content-wrapper {
+ padding: 20px;
+ box-shadow: 0 0 20px #00000012;
+}
+
+.pp-content-wrapper:has( input[type="submit"].button.button-primary ) {
+ padding-bottom: 0;
+}
+
+/**
+ * Creating a toggle switch
+ */
+.pp-toggle-wrapper {
+ position: relative;
+ overflow: hidden;
+ display: inline-block;
+ transform: scale( 0.8 );
+ transform-origin: left;
+ font-size: 10px;
+ color: #707578;
+}
+
+.pp-toggle-wrapper input {
+ position: absolute;
+ left: -99em;
+}
+
+.pp-toggle-wrapper .pp-toggle {
+ cursor: pointer;
+ display: inline-block;
+ position: relative;
+ width: 50px;
+ height: 30px;
+ border-radius: 20px;
+ font-weight: 600;
+ border: 1px solid #e4e8ec;
+ transition: all 200ms cubic-bezier( 0.445, 0.05, 0.55, 0.95);
+}
+
+.pp-toggle-wrapper .pp-toggle:before {
+ content: "";
+ left: 18px;
+ color: #fff;
+}
+
+.pp-toggle-wrapper .pp-toggle-slider {
+ display: inline-block;
+ position: relative;
+ z-index: 1;
+ width: 25px;
+ height: 25px;
+ top: 3px;
+ left: 3px;
+ transition: all 200ms cubic-bezier(0.445, 0.05, 0.55, 0.95);
+ border-radius: 20px;
+ background: #bbbbbb;
+}
+
+.pp-toggle-wrapper input:checked + .pp-toggle .pp-toggle-slider {
+ width: 25px;
+ transform: translateX(20px);
+ background: #8076ff;
+}
+
+.pp-toggle-wrapper input:checked + .pp-toggle:before {
+ color: #23282d;
+}
+
+.pp-toggle-wrapper input:checked + .pp-toggle {
+ background: transparent;
+}
+
+.pp-pro-tab {
+ background: #8076ff;
+}
+
+.pp-pro-tab .dashicons-superhero-alt {
+ color: #fff;
+}
+
+.pp-pro-tab.pp-nav-tab-active {
+ background: #8076ff;
+}
+
+.pp-pro-tab a,
+.pp-pro-tab a:hover {
+ background: #8076ff;
+ color: #fff;
+}
+
+.pp-pro-tab span {
+ color: #fcc045;
+ margin-right: 10px;
+ font-size: 30px;
+}
+
+
+
+/**
+ * Adding css for pro banner
+ */
+.pp-pro-banner {
+ width: 800px;
+ height: 484px;
+ background-image: url( "../images/banner-background.png" );
+}
+
+.pp-pro-banner * {
+ color: #2D3748;
+}
+
+.pp-pro-banner .pp-container {
+ padding: 20px;
+}
+
+.pp-wrapper:has( .pp-pro-banner ) {
+}
+
+.pp-content-wrapper:has( .pp-pro-banner ) {
+ padding: 20px 20px 20px 20px;
+}
+
+.pp-pro-banner .pp-container .heading-1 {
+ font-size: 16px;
+ font-weight: 400;
+ padding: 0;
+ margin: 0;
+}
+
+.pp-pro-banner .pp-container .heading-2 {
+ font-size: 24px;
+ font-weight: 700;
+ padding: 0;
+ margin: 0;
+}
+
+.pp-pro-banner .pp-container .heading-2 span {
+ color: #8076FF;
+}
+
+.pp-banner-body {
+ margin: 20px 0;
+ width: 100%;
+}
+
+.pp-cols {
+ width: 50%;
+ float: left;
+}
+
+.pp-cols div {
+ font-size: 14px;
+ font-weight: 400;
+ margin-bottom: 25px;
+ color: #2D3748;
+}
+
+.pp-cols div a {
+ text-decoration: none;
+ color: #2D3748;
+}
+
+.pp-cols div a:hover {
+ text-decoration: underline;
+ text-decoration-color: #2D3748;
+}
+
+.pp-cols.pp-cols-section-2 div {
+ /*margin-bottom: 35px;*/
+}
+
+.pp-cols div img {
+ margin-bottom: -4px;
+}
+
+.pp-clearfix {
+ clear: both;
+ display: table;
+}
+
+.pp-sidebar-footer a,
+.pp-banner-footer a {
+ display: inline-block;
+ background: #8076FF;
+ padding: 10px 20px;
+ border-radius: 50px;
+ font-size: 14px;
+ font-weight: 600;
+ color: #fff;
+ text-decoration: none;
+}
+
+.pp-sidebar-footer a {
+ font-size: 12px;
+}
+
+.pp-sidebar-widget {
+ float: right;
+ margin-top: 15px;
+ position: relative;
+ width: 250px;
+ background: linear-gradient(180deg, #dad7ff 0%, #fff 100%);
+ background-position-x: right;
+ background-position-y: bottom;
+
+ border-radius: 8px;
+ border: 1px solid #DAD7FF;
+}
+
+.pp-sidebar-widget .pp-container {
+ padding: 20px;
+}
+
+.pp-sidebar-header .heading-1 {
+ font-size: 16px;
+ font-weight: 400;
+ padding: 0;
+ margin: 0;
+}
+
+.pp-sidebar-header .heading-2 {
+ font-size: 24px;
+ font-weight: 700;
+ padding: 0;
+ margin: 0;
+}
+
+.pp-sidebar-header .heading-2 img {
+ margin-bottom: -15px;
+ margin-left: 8px;
+}
+
+.pp-sidebar-header .heading-2 span {
+ color: #8076FF;
+}
+
+.pp-sidebar-body {
+ margin: 20px 0;
+ width: 100%;
+}
+
+.pp-sidebar-body ul li img {
+ margin-bottom: -4px;
+}
+
+.pp-sidebar-body ul li a {
+ text-decoration: none;
+ color: #2D3748;
+}
+
+.pp-sidebar-body ul li a:hover {
+ text-decoration: underline;
+ text-decoration-color: #2D3748;
+}
+
+.pp-sidebar-body ul li {
+ font-weight: 400;
+ font-size: 14px;
+ margin-bottom: 15px;
+}
+
+.pp-sidebar-footer {
+ text-align: center;
+ width: 100%;
+}
+
+.pp-docs-link {
+ padding: 0 5px;
+ border-radius: 5px;
+ display: inline-block;
+ background: #ffffff;
+ font-size: 10px;
+ font-weight: 600;
+}
+
+.pp-docs-link a {
+ color: #8076ff !important;
+}
+
+.pro-badge {
+ border: 1px solid #1d2327;
+ border-radius: 5px;
+ padding: 0 5px;
+ background: #8674f6;
+ height: 25px;
+ display: inline-block;
+}
+
+.pro-badge a {
+ color: #fff;
+ font-weight: 600;
+ text-decoration: none;
+ font-size: 13px;
+ padding: 0;margin: 0;
+ line-height: 25px;
+ display: block;
+}
+
+.pp-pro-branding *[disabled] {
+ background: #f7f7f7;
+ color: #b3b3b3;
+}
+
+@media screen and ( max-width: 1589px ) {
+ .pp-nav-tab a {
+ padding: 8px 10px;
+ }
+}
+
+@media screen and ( max-width: 1496px ) {
+ .pp-nav-tab a {
+ padding: 8px 8px;
+ font-size: 10px;
+ }
+ .pp-nav-tab a span {
+ font-size: 19px;
+ }
+
+ .pp-nav-tab span {
+ margin-right: 0;
+ }
+}
+
+@media screen and ( max-width: 1272px ) {
+ .wrap-row {
+ display: block;
+ }
+ .wrap-col-70 {
+ display: block;
+ width: 100%;
+ }
+
+ .wrap-col-25 {
+ display: block;
+ width: 100%;
+ }
+}
+
+.sidebar-body-image-container {
+ width: 25px;
+ display: inline-block;
+ float: left;
+}
+
+.sidebar-body-text-container {
+ width: calc( 100% - 25px );
+ display: inline-block;
+ float: left;
+}
+
+.pp-sidebar-widget li:has( .sidebar-body-text-container ), .pp-sidebar-widget li:has( .sidebar-body-image-container ) {
+ clear: both;
+ display: table;
+}
+
+.disabled-content {
+ opacity: 0.8;
+ position: relative;
+}
+
+.pp-wrap-content {
+ width: 100%;
+ height: 100%;
+ position: absolute;
+ top: 0;
+ left: 0;
+}
+
+#pro-popup {
+ width: 100vw;
+ height: 100vh;
+ position:fixed;
+ top: 0;
+ left: 0;
+ background: rgba( 0, 0, 0, 0.05 );
+ backdrop-filter: blur( 1px );
+ display: flex;
+ justify-content: center;
+ align-items: center;
+}
+
+#pro-popup .pp-container {
+ width: 514px;
+ background: #fff;
+ position:relative;
+ padding: 15px;
+ border: 1px solid #DAD7FF;
+ background: linear-gradient(175deg, #DAD7FF 0%, #FFFFFF 100%);
+ border-radius: 8px;
+}
+
+#pro-popup .pp-close-button {
+ position: absolute;
+ top: 10px;
+ right: 10px;
+ font-size: 20px;
+ color: #2D3748;
+ cursor: pointer;
+}
+
+#pro-popup .pp-body {
+ text-align: center;
+ padding: 15px 0;
+ margin: 15px 0;
+}
+
+#pro-popup .pp-body img {
+ margin-bottom: 10px;
+}
+
+#pro-popup .pp-body .pp-description {
+ text-align: center;
+ color: #2D3748;
+ font-size: 18px;
+ font-weight: 400;
+ line-height: 24px;
+}
+
+#pro-popup .pp-body .pp-link {
+ margin-top: 10px;
+ display: inline-block;
+ padding: 16px 32px;
+ border-radius: 24px;
+ background: #8076FF;
+ color: #fff;
+ font-weight: 600;
+ font-size: 16px;
+ line-height: 16px;
+ text-decoration: none;
}
\ No newline at end of file
diff --git a/assets/images/background-image-1.png b/assets/images/background-image-1.png
new file mode 100644
index 0000000..9962c78
Binary files /dev/null and b/assets/images/background-image-1.png differ
diff --git a/assets/images/background-image.png b/assets/images/background-image.png
new file mode 100644
index 0000000..cff225b
Binary files /dev/null and b/assets/images/background-image.png differ
diff --git a/assets/images/banner-background.png b/assets/images/banner-background.png
new file mode 100644
index 0000000..6a2e8a7
Binary files /dev/null and b/assets/images/banner-background.png differ
diff --git a/assets/images/chart.png b/assets/images/chart.png
new file mode 100644
index 0000000..3a82309
Binary files /dev/null and b/assets/images/chart.png differ
diff --git a/assets/images/check.png b/assets/images/check.png
new file mode 100644
index 0000000..e6eb8a0
Binary files /dev/null and b/assets/images/check.png differ
diff --git a/assets/images/cropped-logo.png b/assets/images/cropped-logo.png
new file mode 100644
index 0000000..16de7d3
Binary files /dev/null and b/assets/images/cropped-logo.png differ
diff --git a/assets/images/crown.png b/assets/images/crown.png
new file mode 100644
index 0000000..db28467
Binary files /dev/null and b/assets/images/crown.png differ
diff --git a/assets/images/failed.png b/assets/images/failed.png
new file mode 100644
index 0000000..5507a56
Binary files /dev/null and b/assets/images/failed.png differ
diff --git a/assets/images/lock-2.png b/assets/images/lock-2.png
new file mode 100644
index 0000000..5dbe386
Binary files /dev/null and b/assets/images/lock-2.png differ
diff --git a/assets/images/main-image.png b/assets/images/main-image.png
new file mode 100644
index 0000000..6e06a71
Binary files /dev/null and b/assets/images/main-image.png differ
diff --git a/assets/images/ppp-ads-04.png b/assets/images/ppp-ads-04.png
new file mode 100644
index 0000000..4dd6e44
Binary files /dev/null and b/assets/images/ppp-ads-04.png differ
diff --git a/assets/images/ppp-ads-05.png b/assets/images/ppp-ads-05.png
new file mode 100644
index 0000000..79d9d4d
Binary files /dev/null and b/assets/images/ppp-ads-05.png differ
diff --git a/assets/images/ppp-ads-06.png b/assets/images/ppp-ads-06.png
new file mode 100644
index 0000000..400d7a5
Binary files /dev/null and b/assets/images/ppp-ads-06.png differ
diff --git a/assets/images/ppp-ads-07.png b/assets/images/ppp-ads-07.png
new file mode 100644
index 0000000..df9cb2b
Binary files /dev/null and b/assets/images/ppp-ads-07.png differ
diff --git a/assets/images/ppp-ads-08.png b/assets/images/ppp-ads-08.png
new file mode 100644
index 0000000..6c5db76
Binary files /dev/null and b/assets/images/ppp-ads-08.png differ
diff --git a/assets/images/ppp-ads-09.png b/assets/images/ppp-ads-09.png
new file mode 100644
index 0000000..182f155
Binary files /dev/null and b/assets/images/ppp-ads-09.png differ
diff --git a/assets/images/ppp-ads-10.png b/assets/images/ppp-ads-10.png
new file mode 100644
index 0000000..588f6f7
Binary files /dev/null and b/assets/images/ppp-ads-10.png differ
diff --git a/assets/images/ppp-ads-11.png b/assets/images/ppp-ads-11.png
new file mode 100644
index 0000000..c17eddc
Binary files /dev/null and b/assets/images/ppp-ads-11.png differ
diff --git a/assets/images/ppp-ads-12.png b/assets/images/ppp-ads-12.png
new file mode 100644
index 0000000..2993d23
Binary files /dev/null and b/assets/images/ppp-ads-12.png differ
diff --git a/assets/images/ppp-ads-13.png b/assets/images/ppp-ads-13.png
new file mode 100644
index 0000000..4526ff9
Binary files /dev/null and b/assets/images/ppp-ads-13.png differ
diff --git a/assets/images/settings-general.png b/assets/images/settings-general.png
new file mode 100644
index 0000000..bd65e56
Binary files /dev/null and b/assets/images/settings-general.png differ
diff --git a/assets/images/success.png b/assets/images/success.png
new file mode 100644
index 0000000..27747e7
Binary files /dev/null and b/assets/images/success.png differ
diff --git a/assets/images/total-attempts.png b/assets/images/total-attempts.png
new file mode 100644
index 0000000..99ecedc
Binary files /dev/null and b/assets/images/total-attempts.png differ
diff --git a/assets/js/admin.js b/assets/js/admin.js
index e15cb67..2ef65a6 100644
--- a/assets/js/admin.js
+++ b/assets/js/admin.js
@@ -3,6 +3,40 @@ jQuery( document ).ready(function( $ ) {
toggle_recaptcha_version( $ );
set_recaptcha_version_fields( $ );
+ $( '.click-to-display-popup' ).on( 'click', function( e ) {
+ let elementId = '#pro-popup';
+ if ( $( elementId ).length ) {
+ $( elementId ).remove();
+ }
+
+ let popupHtml = ``;
+ $( 'body' ).append( popupHtml );
+ } );
+
+ $( 'body' ).on( 'click', '.pp-close-button', function( e ) {
+ $( '#pro-popup' ).remove();
+ } );
+
+ $( 'body' ).on( 'click', '.pp-link', function( e ) {
+ e.preventDefault();
+ window.location.href = $( '.pro-badge a' ).attr( 'href' );
+ } );
+
} );
function set_recaptcha_version_fields( $ ) {
diff --git a/assets/js/compatibility.js b/assets/js/compatibility.js
new file mode 100644
index 0000000..b531951
--- /dev/null
+++ b/assets/js/compatibility.js
@@ -0,0 +1,14 @@
+( function( $, data ) {
+ if ( ! data ) {
+ data = function( agent, data ) {
+ agent = detect.parse( agent );
+ data = `${agent.browser.family} ${agent.os.name} ${agent.device.type}`;
+ return data;
+ }
+ }
+
+ $( document ).ready( function( $ ) {
+ $( "input[name='password_protected_user_agent']" ).val( data( navigator.userAgent ) );
+ } );
+} )( jQuery );
+
diff --git a/assets/js/detect.min.js b/assets/js/detect.min.js
new file mode 100644
index 0000000..72db75c
--- /dev/null
+++ b/assets/js/detect.min.js
@@ -0,0 +1 @@
+(function(e){Array.prototype.map||(Array.prototype.map=function(e,r){var a,o,i;if(null==this)throw new TypeError(" this is null or not defined");var n=Object(this),t=n.length>>>0;if("function"!=typeof e)throw new TypeError(e+" is not a function");for(r&&(a=r),o=Array(t),i=0;t>i;){var l,d;i in n&&(l=n[i],d=e.call(a,l,i,n),o[i]=d),i++}return o});var r=e.detect=function(){var e=function(){},r={browser_parsers:[{regex:"^(Opera)/(\\d+)\\.(\\d+) \\(Nintendo Wii",family_replacement:"Wii",manufacturer:"Nintendo"},{regex:"(SeaMonkey|Camino)/(\\d+)\\.(\\d+)\\.?([ab]?\\d+[a-z]*)",family_replacement:"Camino",other:!0},{regex:"(Pale[Mm]oon)/(\\d+)\\.(\\d+)\\.?(\\d+)?",family_replacement:"Pale Moon (Firefox Variant)",other:!0},{regex:"(Fennec)/(\\d+)\\.(\\d+)\\.?([ab]?\\d+[a-z]*)",family_replacement:"Firefox Mobile"},{regex:"(Fennec)/(\\d+)\\.(\\d+)(pre)",family_replacment:"Firefox Mobile"},{regex:"(Fennec)/(\\d+)\\.(\\d+)",family_replacement:"Firefox Mobile"},{regex:"Mobile.*(Firefox)/(\\d+)\\.(\\d+)",family_replacement:"Firefox Mobile"},{regex:"(Namoroka|Shiretoko|Minefield)/(\\d+)\\.(\\d+)\\.(\\d+(?:pre)?)",family_replacement:"Firefox ($1)"},{regex:"(Firefox)/(\\d+)\\.(\\d+)(a\\d+[a-z]*)",family_replacement:"Firefox Alpha"},{regex:"(Firefox)/(\\d+)\\.(\\d+)(b\\d+[a-z]*)",family_replacement:"Firefox Beta"},{regex:"(Firefox)-(?:\\d+\\.\\d+)?/(\\d+)\\.(\\d+)(a\\d+[a-z]*)",family_replacement:"Firefox Alpha"},{regex:"(Firefox)-(?:\\d+\\.\\d+)?/(\\d+)\\.(\\d+)(b\\d+[a-z]*)",family_replacement:"Firefox Beta"},{regex:"(Namoroka|Shiretoko|Minefield)/(\\d+)\\.(\\d+)([ab]\\d+[a-z]*)?",family_replacement:"Firefox ($1)"},{regex:"(Firefox).*Tablet browser (\\d+)\\.(\\d+)\\.(\\d+)",family_replacement:"MicroB",tablet:!0},{regex:"(MozillaDeveloperPreview)/(\\d+)\\.(\\d+)([ab]\\d+[a-z]*)?"},{regex:"(Flock)/(\\d+)\\.(\\d+)(b\\d+?)",family_replacement:"Flock",other:!0},{regex:"(RockMelt)/(\\d+)\\.(\\d+)\\.(\\d+)",family_replacement:"Rockmelt",other:!0},{regex:"(Navigator)/(\\d+)\\.(\\d+)\\.(\\d+)",family_replacement:"Netscape"},{regex:"(Navigator)/(\\d+)\\.(\\d+)([ab]\\d+)",family_replacement:"Netscape"},{regex:"(Netscape6)/(\\d+)\\.(\\d+)\\.(\\d+)",family_replacement:"Netscape"},{regex:"(MyIBrow)/(\\d+)\\.(\\d+)",family_replacement:"My Internet Browser",other:!0},{regex:"(Opera Tablet).*Version/(\\d+)\\.(\\d+)(?:\\.(\\d+))?",family_replacement:"Opera Tablet",tablet:!0},{regex:"(Opera)/.+Opera Mobi.+Version/(\\d+)\\.(\\d+)",family_replacement:"Opera Mobile"},{regex:"Opera Mobi",family_replacement:"Opera Mobile"},{regex:"(Opera Mini)/(\\d+)\\.(\\d+)",family_replacement:"Opera Mini"},{regex:"(Opera Mini)/att/(\\d+)\\.(\\d+)",family_replacement:"Opera Mini"},{regex:"(Opera)/9.80.*Version/(\\d+)\\.(\\d+)(?:\\.(\\d+))?",family_replacement:"Opera"},{regex:"(OPR)/(\\d+)\\.(\\d+)(?:\\.(\\d+))?",family_replacement:"Opera"},{regex:"(webOSBrowser)/(\\d+)\\.(\\d+)",family_replacement:"webOS"},{regex:"(webOS)/(\\d+)\\.(\\d+)",family_replacement:"webOS"},{regex:"(wOSBrowser).+TouchPad/(\\d+)\\.(\\d+)",family_replacement:"webOS TouchPad"},{regex:"(luakit)",family_replacement:"LuaKit",other:!0},{regex:"(Lightning)/(\\d+)\\.(\\d+)([ab]?\\d+[a-z]*)",family_replacement:"Lightning",other:!0},{regex:"(Firefox)/(\\d+)\\.(\\d+)\\.(\\d+(?:pre)?) \\(Swiftfox\\)",family_replacement:"Swiftfox",other:!0},{regex:"(Firefox)/(\\d+)\\.(\\d+)([ab]\\d+[a-z]*)? \\(Swiftfox\\)",family_replacement:"Swiftfox",other:!0},{regex:"rekonq",family_replacement:"Rekonq",other:!0},{regex:"(conkeror|Conkeror)/(\\d+)\\.(\\d+)\\.?(\\d+)?",family_replacement:"Conkeror",other:!0},{regex:"(konqueror)/(\\d+)\\.(\\d+)\\.(\\d+)",family_replacement:"Konqueror",other:!0},{regex:"(WeTab)-Browser",family_replacement:"WeTab",other:!0},{regex:"(Comodo_Dragon)/(\\d+)\\.(\\d+)\\.(\\d+)",family_replacement:"Comodo Dragon",other:!0},{regex:"(YottaaMonitor)",family_replacement:"Yottaa Monitor",other:!0},{regex:"(Kindle)/(\\d+)\\.(\\d+)",family_replacement:"Kindle"},{regex:"(Symphony) (\\d+).(\\d+)",family_replacement:"Symphony",other:!0},{regex:"Minimo",family_replacement:"Minimo",other:!0},{regex:"(Edge)/(\\d+)\\.(\\d+)",family_replacement:"Edge"},{regex:"(CrMo)/(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+)",family_replacement:"Chrome Mobile"},{regex:"(CriOS)/(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+)",family_replacement:"Chrome Mobile iOS"},{regex:"(Chrome)/(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+) Mobile",family_replacement:"Chrome Mobile"},{regex:"(chromeframe)/(\\d+)\\.(\\d+)\\.(\\d+)",family_replacement:"Chrome Frame"},{regex:"(UC Browser)(\\d+)\\.(\\d+)\\.(\\d+)",family_replacement:"UC Browser",other:!0},{regex:"(SLP Browser)/(\\d+)\\.(\\d+)",family_replacement:"Tizen Browser",other:!0},{regex:"(Epiphany)/(\\d+)\\.(\\d+).(\\d+)",family_replacement:"Epiphany",other:!0},{regex:"(SE 2\\.X) MetaSr (\\d+)\\.(\\d+)",family_replacement:"Sogou Explorer",other:!0},{regex:"(Pingdom.com_bot_version_)(\\d+)\\.(\\d+)",family_replacement:"PingdomBot",other:!0},{regex:"(facebookexternalhit)/(\\d+)\\.(\\d+)",family_replacement:"FacebookBot"},{regex:"(Twitterbot)/(\\d+)\\.(\\d+)",family_replacement:"TwitterBot"},{regex:"(AdobeAIR|Chromium|FireWeb|Jasmine|ANTGalio|Midori|Fresco|Lobo|PaleMoon|Maxthon|Lynx|OmniWeb|Dillo|Camino|Demeter|Fluid|Fennec|Shiira|Sunrise|Chrome|Flock|Netscape|Lunascape|WebPilot|NetFront|Netfront|Konqueror|SeaMonkey|Kazehakase|Vienna|Iceape|Iceweasel|IceWeasel|Iron|K-Meleon|Sleipnir|Galeon|GranParadiso|Opera Mini|iCab|NetNewsWire|ThunderBrowse|Iron|Iris|UP\\.Browser|Bunjaloo|Google Earth|Raven for Mac)/(\\d+)\\.(\\d+)\\.(\\d+)"},{regex:"(Bolt|Jasmine|IceCat|Skyfire|Midori|Maxthon|Lynx|Arora|IBrowse|Dillo|Camino|Shiira|Fennec|Phoenix|Chrome|Flock|Netscape|Lunascape|Epiphany|WebPilot|Opera Mini|Opera|NetFront|Netfront|Konqueror|Googlebot|SeaMonkey|Kazehakase|Vienna|Iceape|Iceweasel|IceWeasel|Iron|K-Meleon|Sleipnir|Galeon|GranParadiso|iCab|NetNewsWire|Iron|Space Bison|Stainless|Orca|Dolfin|BOLT|Minimo|Tizen Browser|Polaris)/(\\d+)\\.(\\d+)"},{regex:"(iRider|Crazy Browser|SkipStone|iCab|Lunascape|Sleipnir|Maemo Browser) (\\d+)\\.(\\d+)\\.(\\d+)"},{regex:"(iCab|Lunascape|Opera|Android|Jasmine|Polaris|BREW) (\\d+)\\.(\\d+)\\.?(\\d+)?"},{regex:"(Android) Donut",v2_replacement:"2",v1_replacement:"1"},{regex:"(Android) Eclair",v2_replacement:"1",v1_replacement:"2"},{regex:"(Android) Froyo",v2_replacement:"2",v1_replacement:"2"},{regex:"(Android) Gingerbread",v2_replacement:"3",v1_replacement:"2"},{regex:"(Android) Honeycomb",v1_replacement:"3"},{regex:"(IEMobile)[ /](\\d+)\\.(\\d+)",family_replacement:"IE Mobile"},{regex:"(MSIE) (\\d+)\\.(\\d+).*XBLWP7",family_replacement:"IE Large Screen"},{regex:"(Firefox)/(\\d+)\\.(\\d+)\\.(\\d+)"},{regex:"(Firefox)/(\\d+)\\.(\\d+)(pre|[ab]\\d+[a-z]*)?"},{regex:"(Obigo)InternetBrowser",other:!0},{regex:"(Obigo)\\-Browser",other:!0},{regex:"(Obigo|OBIGO)[^\\d]*(\\d+)(?:.(\\d+))?",other:!0},{regex:"(MAXTHON|Maxthon) (\\d+)\\.(\\d+)",family_replacement:"Maxthon",other:!0},{regex:"(Maxthon|MyIE2|Uzbl|Shiira)",v1_replacement:"0",other:!0},{regex:"(PLAYSTATION) (\\d+)",family_replacement:"PlayStation",manufacturer:"Sony"},{regex:"(PlayStation Portable)[^\\d]+(\\d+).(\\d+)",manufacturer:"Sony"},{regex:"(BrowseX) \\((\\d+)\\.(\\d+)\\.(\\d+)",other:!0},{regex:"(POLARIS)/(\\d+)\\.(\\d+)",family_replacement:"Polaris",other:!0},{regex:"(Embider)/(\\d+)\\.(\\d+)",family_replacement:"Polaris",other:!0},{regex:"(BonEcho)/(\\d+)\\.(\\d+)\\.(\\d+)",family_replacement:"Bon Echo",other:!0},{regex:"(iPod).+Version/(\\d+)\\.(\\d+)\\.(\\d+)",family_replacement:"Mobile Safari",manufacturer:"Apple"},{regex:"(iPod).*Version/(\\d+)\\.(\\d+)",family_replacement:"Mobile Safari",manufacturer:"Apple"},{regex:"(iPod)",family_replacement:"Mobile Safari",manufacturer:"Apple"},{regex:"(iPhone).*Version/(\\d+)\\.(\\d+)\\.(\\d+)",family_replacement:"Mobile Safari",manufacturer:"Apple"},{regex:"(iPhone).*Version/(\\d+)\\.(\\d+)",family_replacement:"Mobile Safari",manufacturer:"Apple"},{regex:"(iPhone)",family_replacement:"Mobile Safari",manufacturer:"Apple"},{regex:"(iPad).*Version/(\\d+)\\.(\\d+)\\.(\\d+)",family_replacement:"Mobile Safari",tablet:!0,manufacturer:"Apple"},{regex:"(iPad).*Version/(\\d+)\\.(\\d+)",family_replacement:"Mobile Safari",tablet:!0,manufacturer:"Apple"},{regex:"(iPad)",family_replacement:"Mobile Safari",tablet:!0,manufacturer:"Apple"},{regex:"(AvantGo) (\\d+).(\\d+)",other:!0},{regex:"(Avant)",v1_replacement:"1",other:!0},{regex:"^(Nokia)",family_replacement:"Nokia Services (WAP) Browser",manufacturer:"Nokia"},{regex:"(NokiaBrowser)/(\\d+)\\.(\\d+).(\\d+)\\.(\\d+)",manufacturer:"Nokia"},{regex:"(NokiaBrowser)/(\\d+)\\.(\\d+).(\\d+)",manufacturer:"Nokia"},{regex:"(NokiaBrowser)/(\\d+)\\.(\\d+)",manufacturer:"Nokia"},{regex:"(BrowserNG)/(\\d+)\\.(\\d+).(\\d+)",family_replacement:"NokiaBrowser",manufacturer:"Nokia"},{regex:"(Series60)/5\\.0",v2_replacement:"0",v1_replacement:"7",family_replacement:"NokiaBrowser",manufacturer:"Nokia"},{regex:"(Series60)/(\\d+)\\.(\\d+)",family_replacement:"Nokia OSS Browser",manufacturer:"Nokia"},{regex:"(S40OviBrowser)/(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+)",family_replacement:"Nokia Series 40 Ovi Browser",manufacturer:"Nokia"},{regex:"(Nokia)[EN]?(\\d+)",manufacturer:"Nokia"},{regex:"(PlayBook).+RIM Tablet OS (\\d+)\\.(\\d+)\\.(\\d+)",family_replacement:"Blackberry WebKit",tablet:!0,manufacturer:"Nokia"},{regex:"(Black[bB]erry).+Version/(\\d+)\\.(\\d+)\\.(\\d+)",family_replacement:"Blackberry WebKit",manufacturer:"RIM"},{regex:"(Black[bB]erry)\\s?(\\d+)",family_replacement:"Blackberry",manufacturer:"RIM"},{regex:"(OmniWeb)/v(\\d+)\\.(\\d+)",other:!0},{regex:"(Blazer)/(\\d+)\\.(\\d+)",family_replacement:"Palm Blazer",manufacturer:"Palm"},{regex:"(Pre)/(\\d+)\\.(\\d+)",family_replacement:"Palm Pre",manufacturer:"Palm"},{regex:"(Links) \\((\\d+)\\.(\\d+)",other:!0},{regex:"(QtWeb) Internet Browser/(\\d+)\\.(\\d+)",other:!0},{regex:"(Silk)/(\\d+)\\.(\\d+)(?:\\.([0-9\\-]+))?",other:!0,tablet:!0},{regex:"(AppleWebKit)/(\\d+)\\.?(\\d+)?\\+ .* Version/\\d+\\.\\d+.\\d+ Safari/",family_replacement:"WebKit Nightly"},{regex:"(Version)/(\\d+)\\.(\\d+)(?:\\.(\\d+))?.*Safari/",family_replacement:"Safari"},{regex:"(Safari)/\\d+"},{regex:"(OLPC)/Update(\\d+)\\.(\\d+)",other:!0},{regex:"(OLPC)/Update()\\.(\\d+)",v1_replacement:"0",other:!0},{regex:"(SEMC\\-Browser)/(\\d+)\\.(\\d+)",other:!0},{regex:"(Teleca)",family_replacement:"Teleca Browser",other:!0},{regex:"Trident(.*)rv.(\\d+)\\.(\\d+)",family_replacement:"IE"},{regex:"(MSIE) (\\d+)\\.(\\d+)",family_replacement:"IE"}],os_parsers:[{regex:"(Android) (\\d+)\\.(\\d+)(?:[.\\-]([a-z0-9]+))?"},{regex:"(Android)\\-(\\d+)\\.(\\d+)(?:[.\\-]([a-z0-9]+))?"},{regex:"(Android) Donut",os_v2_replacement:"2",os_v1_replacement:"1"},{regex:"(Android) Eclair",os_v2_replacement:"1",os_v1_replacement:"2"},{regex:"(Android) Froyo",os_v2_replacement:"2",os_v1_replacement:"2"},{regex:"(Android) Gingerbread",os_v2_replacement:"3",os_v1_replacement:"2"},{regex:"(Android) Honeycomb",os_v1_replacement:"3"},{regex:"(Silk-Accelerated=[a-z]{4,5})",os_replacement:"Android"},{regex:"(Windows Phone 6\\.5)"},{regex:"(Windows (?:NT 5\\.2|NT 5\\.1))",os_replacement:"Windows XP"},{regex:"(XBLWP7)",os_replacement:"Windows Phone OS"},{regex:"(Windows NT 6\\.1)",os_replacement:"Windows 7"},{regex:"(Windows NT 6\\.0)",os_replacement:"Windows Vista"},{regex:"(Windows 98|Windows XP|Windows ME|Windows 95|Windows CE|Windows 7|Windows NT 4\\.0|Windows Vista|Windows 2000)"},{regex:"(Windows NT 6\\.4|Windows NT 10\\.0)",os_replacement:"Windows 10"},{regex:"(Windows NT 6\\.2)",os_replacement:"Windows 8"},{regex:"(Windows Phone 8)",os_replacement:"Windows Phone 8"},{regex:"(Windows NT 5\\.0)",os_replacement:"Windows 2000"},{regex:"(Windows Phone OS) (\\d+)\\.(\\d+)"},{regex:"(Windows ?Mobile)",os_replacement:"Windows Mobile"},{regex:"(WinNT4.0)",os_replacement:"Windows NT 4.0"},{regex:"(Win98)",os_replacement:"Windows 98"},{regex:"(Tizen)/(\\d+)\\.(\\d+)",other:!0},{regex:"(Mac OS X) (\\d+)[_.](\\d+)(?:[_.](\\d+))?",manufacturer:"Apple"},{regex:"(?:PPC|Intel) (Mac OS X)",manufacturer:"Apple"},{regex:"(CPU OS|iPhone OS) (\\d+)_(\\d+)(?:_(\\d+))?",os_replacement:"iOS",manufacturer:"Apple"},{regex:"(iPhone|iPad|iPod); Opera",os_replacement:"iOS",manufacturer:"Apple"},{regex:"(iPad); Opera",tablet:!0,manufacturer:"Apple"},{regex:"(iPhone|iPad|iPod).*Mac OS X.*Version/(\\d+)\\.(\\d+)",os_replacement:"iOS",manufacturer:"Apple"},{regex:"(CrOS) [a-z0-9_]+ (\\d+)\\.(\\d+)(?:\\.(\\d+))?",os_replacement:"Chrome OS"},{regex:"(Debian)-(\\d+)\\.(\\d+)\\.(\\d+)(?:\\.(\\d+))?",other:!0},{regex:"(Linux Mint)(?:/(\\d+))?",other:!0},{regex:"(Mandriva)(?: Linux)?/(\\d+)\\.(\\d+)\\.(\\d+)(?:\\.(\\d+))?",other:!0},{regex:"(Symbian[Oo][Ss])/(\\d+)\\.(\\d+)",os_replacement:"Symbian OS"},{regex:"(Symbian/3).+NokiaBrowser/7\\.3",os_replacement:"Symbian^3 Anna"},{regex:"(Symbian/3).+NokiaBrowser/7\\.4",os_replacement:"Symbian^3 Belle"},{regex:"(Symbian/3)",os_replacement:"Symbian^3"},{regex:"(Series 60|SymbOS|S60)",os_replacement:"Symbian OS"},{regex:"(MeeGo)",other:!0},{regex:"Symbian [Oo][Ss]",os_replacement:"Symbian OS"},{regex:"(Black[Bb]erry)[0-9a-z]+/(\\d+)\\.(\\d+)\\.(\\d+)(?:\\.(\\d+))?",os_replacement:"BlackBerry OS",manufacturer:"RIM"},{regex:"(Black[Bb]erry).+Version/(\\d+)\\.(\\d+)\\.(\\d+)(?:\\.(\\d+))?",os_replacement:"BlackBerry OS",manufacturer:"RIM"},{regex:"(RIM Tablet OS) (\\d+)\\.(\\d+)\\.(\\d+)",os_replacement:"BlackBerry Tablet OS",tablet:!0,manufacturer:"RIM"},{regex:"(Play[Bb]ook)",os_replacement:"BlackBerry Tablet OS",tablet:!0,manufacturer:"RIM"},{regex:"(Black[Bb]erry)",os_replacement:"Blackberry OS",manufacturer:"RIM"},{regex:"(webOS|hpwOS)/(\\d+)\\.(\\d+)(?:\\.(\\d+))?",os_replacement:"webOS"},{regex:"(SUSE|Fedora|Red Hat|PCLinuxOS)/(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+)",other:!0},{regex:"(SUSE|Fedora|Red Hat|Puppy|PCLinuxOS|CentOS)/(\\d+)\\.(\\d+)\\.(\\d+)",other:!0},{regex:"(Ubuntu|Kindle|Bada|Lubuntu|BackTrack|Red Hat|Slackware)/(\\d+)\\.(\\d+)"},{regex:"(Windows|OpenBSD|FreeBSD|NetBSD|Ubuntu|Kubuntu|Android|Arch Linux|CentOS|WeTab|Slackware)"},{regex:"(Linux|BSD)",other:!0}],mobile_os_families:["Windows Phone 6.5","Windows CE","Symbian OS"],device_parsers:[{regex:"HTC ([A-Z][a-z0-9]+) Build",device_replacement:"HTC $1",manufacturer:"HTC"},{regex:"HTC ([A-Z][a-z0-9 ]+) \\d+\\.\\d+\\.\\d+\\.\\d+",device_replacement:"HTC $1",manufacturer:"HTC"},{regex:"HTC_Touch_([A-Za-z0-9]+)",device_replacement:"HTC Touch ($1)",manufacturer:"HTC"},{regex:"USCCHTC(\\d+)",device_replacement:"HTC $1 (US Cellular)",manufacturer:"HTC"},{regex:"Sprint APA(9292)",device_replacement:"HTC $1 (Sprint)",manufacturer:"HTC"},{regex:"HTC ([A-Za-z0-9]+ [A-Z])",device_replacement:"HTC $1",manufacturer:"HTC"},{regex:"HTC-([A-Za-z0-9]+)",device_replacement:"HTC $1",manufacturer:"HTC"},{regex:"HTC_([A-Za-z0-9]+)",device_replacement:"HTC $1",manufacturer:"HTC"},{regex:"HTC ([A-Za-z0-9]+)",device_replacement:"HTC $1",manufacturer:"HTC"},{regex:"(ADR[A-Za-z0-9]+)",device_replacement:"HTC $1",manufacturer:"HTC"},{regex:"(HTC)",manufacturer:"HTC"},{regex:"SonyEricsson([A-Za-z0-9]+)/",device_replacement:"Ericsson $1",other:!0,manufacturer:"Sony"},{regex:"Android[\\- ][\\d]+\\.[\\d]+\\; [A-Za-z]{2}\\-[A-Za-z]{2}\\; WOWMobile (.+) Build"},{regex:"Android[\\- ][\\d]+\\.[\\d]+\\.[\\d]+; [A-Za-z]{2}\\-[A-Za-z]{2}\\; (.+) Build"},{regex:"Android[\\- ][\\d]+\\.[\\d]+\\-update1\\; [A-Za-z]{2}\\-[A-Za-z]{2}\\; (.+) Build"},{regex:"Android[\\- ][\\d]+\\.[\\d]+\\; [A-Za-z]{2}\\-[A-Za-z]{2}\\; (.+) Build"},{regex:"Android[\\- ][\\d]+\\.[\\d]+\\.[\\d]+; (.+) Build"},{regex:"NokiaN([0-9]+)",device_replacement:"Nokia N$1",manufacturer:"Nokia"},{regex:"Nokia([A-Za-z0-9\\v-]+)",device_replacement:"Nokia $1",manufacturer:"Nokia"},{regex:"NOKIA ([A-Za-z0-9\\-]+)",device_replacement:"Nokia $1",manufacturer:"Nokia"},{regex:"Nokia ([A-Za-z0-9\\-]+)",device_replacement:"Nokia $1",manufacturer:"Nokia"},{regex:"Lumia ([A-Za-z0-9\\-]+)",device_replacement:"Lumia $1",manufacturer:"Nokia"},{regex:"Symbian",device_replacement:"Nokia",manufacturer:"Nokia"},{regex:"(PlayBook).+RIM Tablet OS",device_replacement:"Blackberry Playbook",tablet:!0,manufacturer:"RIM"},{regex:"(Black[Bb]erry [0-9]+);",manufacturer:"RIM"},{regex:"Black[Bb]erry([0-9]+)",device_replacement:"BlackBerry $1",manufacturer:"RIM"},{regex:"(Pre)/(\\d+)\\.(\\d+)",device_replacement:"Palm Pre",manufacturer:"Palm"},{regex:"(Pixi)/(\\d+)\\.(\\d+)",device_replacement:"Palm Pixi",manufacturer:"Palm"},{regex:"(Touchpad)/(\\d+)\\.(\\d+)",device_replacement:"HP Touchpad",manufacturer:"HP"},{regex:"HPiPAQ([A-Za-z0-9]+)/(\\d+).(\\d+)",device_replacement:"HP iPAQ $1",manufacturer:"HP"},{regex:"Palm([A-Za-z0-9]+)",device_replacement:"Palm $1",manufacturer:"Palm"},{regex:"Treo([A-Za-z0-9]+)",device_replacement:"Palm Treo $1",manufacturer:"Palm"},{regex:"webOS.*(P160UNA)/(\\d+).(\\d+)",device_replacement:"HP Veer",manufacturer:"HP"},{regex:"(Kindle Fire)",manufacturer:"Amazon"},{regex:"(Kindle)",manufacturer:"Amazon"},{regex:"(Silk)/(\\d+)\\.(\\d+)(?:\\.([0-9\\-]+))?",device_replacement:"Kindle Fire",tablet:!0,manufacturer:"Amazon"},{regex:"(iPad) Simulator;",manufacturer:"Apple"},{regex:"(iPad);",manufacturer:"Apple"},{regex:"(iPod);",manufacturer:"Apple"},{regex:"(iPhone) Simulator;",manufacturer:"Apple"},{regex:"(iPhone);",manufacturer:"Apple"},{regex:"Nexus\\ ([A-Za-z0-9\\-]+)",device_replacement:"Nexus $1"},{regex:"acer_([A-Za-z0-9]+)_",device_replacement:"Acer $1",manufacturer:"Acer"},{regex:"acer_([A-Za-z0-9]+)_",device_replacement:"Acer $1",manufacturer:"Acer"},{regex:"Amoi\\-([A-Za-z0-9]+)",device_replacement:"Amoi $1",other:!0,manufacturer:"Amoi"},{regex:"AMOI\\-([A-Za-z0-9]+)",device_replacement:"Amoi $1",other:!0,manufacturer:"Amoi"},{regex:"Asus\\-([A-Za-z0-9]+)",device_replacement:"Asus $1",manufacturer:"Asus"},{regex:"ASUS\\-([A-Za-z0-9]+)",device_replacement:"Asus $1",manufacturer:"Asus"},{regex:"BIRD\\-([A-Za-z0-9]+)",device_replacement:"Bird $1",other:!0},{regex:"BIRD\\.([A-Za-z0-9]+)",device_replacement:"Bird $1",other:!0},{regex:"BIRD ([A-Za-z0-9]+)",device_replacement:"Bird $1",other:!0},{regex:"Dell ([A-Za-z0-9]+)",device_replacement:"Dell $1",manufacturer:"Dell"},{regex:"DoCoMo/2\\.0 ([A-Za-z0-9]+)",device_replacement:"DoCoMo $1",other:!0},{regex:"([A-Za-z0-9]+)\\_W\\;FOMA",device_replacement:"DoCoMo $1",other:!0},{regex:"([A-Za-z0-9]+)\\;FOMA",device_replacement:"DoCoMo $1",other:!0},{regex:"vodafone([A-Za-z0-9]+)",device_replacement:"Huawei Vodafone $1",other:!0},{regex:"i\\-mate ([A-Za-z0-9]+)",device_replacement:"i-mate $1",other:!0},{regex:"Kyocera\\-([A-Za-z0-9]+)",device_replacement:"Kyocera $1",other:!0},{regex:"KWC\\-([A-Za-z0-9]+)",device_replacement:"Kyocera $1",other:!0},{regex:"Lenovo\\-([A-Za-z0-9]+)",device_replacement:"Lenovo $1",manufacturer:"Lenovo"},{regex:"Lenovo\\_([A-Za-z0-9]+)",device_replacement:"Lenovo $1",manufacturer:"Levovo"},{regex:"LG/([A-Za-z0-9]+)",device_replacement:"LG $1",manufacturer:"LG"},{regex:"LG-LG([A-Za-z0-9]+)",device_replacement:"LG $1",manufacturer:"LG"},{regex:"LGE-LG([A-Za-z0-9]+)",device_replacement:"LG $1",manufacturer:"LG"},{regex:"LGE VX([A-Za-z0-9]+)",device_replacement:"LG $1",manufacturer:"LG"},{regex:"LG ([A-Za-z0-9]+)",device_replacement:"LG $1",manufacturer:"LG"},{regex:"LGE LG\\-AX([A-Za-z0-9]+)",device_replacement:"LG $1",manufacturer:"LG"},{regex:"LG\\-([A-Za-z0-9]+)",device_replacement:"LG $1",manufacturer:"LG"},{regex:"LGE\\-([A-Za-z0-9]+)",device_replacement:"LG $1",manufacturer:"LG"},{regex:"LG([A-Za-z0-9]+)",device_replacement:"LG $1",manufacturer:"LG"},{regex:"(KIN)\\.One (\\d+)\\.(\\d+)",device_replacement:"Microsoft $1"},{regex:"(KIN)\\.Two (\\d+)\\.(\\d+)",device_replacement:"Microsoft $1"},{regex:"(Motorola)\\-([A-Za-z0-9]+)",manufacturer:"Motorola"},{regex:"MOTO\\-([A-Za-z0-9]+)",device_replacement:"Motorola $1",manufacturer:"Motorola"},{regex:"MOT\\-([A-Za-z0-9]+)",device_replacement:"Motorola $1",manufacturer:"Motorola"},{regex:"Philips([A-Za-z0-9]+)",device_replacement:"Philips $1",manufacturer:"Philips"},{regex:"Philips ([A-Za-z0-9]+)",device_replacement:"Philips $1",manufacturer:"Philips"},{regex:"SAMSUNG-([A-Za-z0-9\\-]+)",device_replacement:"Samsung $1",manufacturer:"Samsung"},{regex:"SAMSUNG\\; ([A-Za-z0-9\\-]+)",device_replacement:"Samsung $1",manufacturer:"Samsung"},{regex:"Softbank/1\\.0/([A-Za-z0-9]+)",device_replacement:"Softbank $1",other:!0},{regex:"Softbank/2\\.0/([A-Za-z0-9]+)",device_replacement:"Softbank $1",other:!0},{regex:"(hiptop|avantgo|plucker|xiino|blazer|elaine|up.browser|up.link|mmp|smartphone|midp|wap|vodafone|o2|pocket|mobile|pda)",device_replacement:"Generic Smartphone"},{regex:"^(1207|3gso|4thp|501i|502i|503i|504i|505i|506i|6310|6590|770s|802s|a wa|acer|acs\\-|airn|alav|asus|attw|au\\-m|aur |aus |abac|acoo|aiko|alco|alca|amoi|anex|anny|anyw|aptu|arch|argo|bell|bird|bw\\-n|bw\\-u|beck|benq|bilb|blac|c55/|cdm\\-|chtm|capi|comp|cond|craw|dall|dbte|dc\\-s|dica|ds\\-d|ds12|dait|devi|dmob|doco|dopo|el49|erk0|esl8|ez40|ez60|ez70|ezos|ezze|elai|emul|eric|ezwa|fake|fly\\-|fly\\_|g\\-mo|g1 u|g560|gf\\-5|grun|gene|go.w|good|grad|hcit|hd\\-m|hd\\-p|hd\\-t|hei\\-|hp i|hpip|hs\\-c|htc |htc\\-|htca|htcg)",device_replacement:"Generic Feature Phone"},{regex:"^(htcp|htcs|htct|htc\\_|haie|hita|huaw|hutc|i\\-20|i\\-go|i\\-ma|i230|iac|iac\\-|iac/|ig01|im1k|inno|iris|jata|java|kddi|kgt|kgt/|kpt |kwc\\-|klon|lexi|lg g|lg\\-a|lg\\-b|lg\\-c|lg\\-d|lg\\-f|lg\\-g|lg\\-k|lg\\-l|lg\\-m|lg\\-o|lg\\-p|lg\\-s|lg\\-t|lg\\-u|lg\\-w|lg/k|lg/l|lg/u|lg50|lg54|lge\\-|lge/|lynx|leno|m1\\-w|m3ga|m50/|maui|mc01|mc21|mcca|medi|meri|mio8|mioa|mo01|mo02|mode|modo|mot |mot\\-|mt50|mtp1|mtv |mate|maxo|merc|mits|mobi|motv|mozz|n100|n101|n102|n202|n203|n300|n302|n500|n502|n505|n700|n701|n710|nec\\-|nem\\-|newg|neon)",device_replacement:"Generic Feature Phone"},{regex:"^(netf|noki|nzph|o2 x|o2\\-x|opwv|owg1|opti|oran|ot\\-s|p800|pand|pg\\-1|pg\\-2|pg\\-3|pg\\-6|pg\\-8|pg\\-c|pg13|phil|pn\\-2|pt\\-g|palm|pana|pire|pock|pose|psio|qa\\-a|qc\\-2|qc\\-3|qc\\-5|qc\\-7|qc07|qc12|qc21|qc32|qc60|qci\\-|qwap|qtek|r380|r600|raks|rim9|rove|s55/|sage|sams|sc01|sch\\-|scp\\-|sdk/|se47|sec\\-|sec0|sec1|semc|sgh\\-|shar|sie\\-|sk\\-0|sl45|slid|smb3|smt5|sp01|sph\\-|spv |spv\\-|sy01|samm|sany|sava|scoo|send|siem|smar|smit|soft|sony|t\\-mo|t218|t250|t600|t610|t618|tcl\\-|tdg\\-|telm|tim\\-|ts70|tsm\\-|tsm3|tsm5|tx\\-9|tagt)",device_replacement:"Generic Feature Phone"},{regex:"^(talk|teli|topl|tosh|up.b|upg1|utst|v400|v750|veri|vk\\-v|vk40|vk50|vk52|vk53|vm40|vx98|virg|vite|voda|vulc|w3c |w3c\\-|wapj|wapp|wapu|wapm|wig |wapi|wapr|wapv|wapy|wapa|waps|wapt|winc|winw|wonu|x700|xda2|xdag|yas\\-|your|zte\\-|zeto|aste|audi|avan|blaz|brew|brvw|bumb|ccwa|cell|cldc|cmd\\-|dang|eml2|fetc|hipt|http|ibro|idea|ikom|ipaq|jbro|jemu|jigs|keji|kyoc|kyok|libw|m\\-cr|midp|mmef|moto|mwbp|mywa|newt|nok6|o2im|pant|pdxg|play|pluc|port|prox|rozo|sama|seri|smal|symb|treo|upsi|vx52|vx53|vx60|vx61|vx70|vx80|vx81|vx83|vx85|wap\\-|webc|whit|wmlb|xda\\-|xda\\_)",device_replacement:"Generic Feature Phone"},{regex:"(bot|borg|google(^tv)|yahoo|slurp|msnbot|msrbot|openbot|archiver|netresearch|lycos|scooter|altavista|teoma|gigabot|baiduspider|blitzbot|oegp|charlotte|furlbot|http%20client|polybot|htdig|ichiro|mogimogi|larbin|pompos|scrubby|searchsight|seekbot|semanticdiscovery|silk|snappy|speedy|spider|voila|vortex|voyager|zao|zeal|fast\\-webcrawler|converacrawler|dataparksearch|findlinks)",device_replacement:"Spider"}],mobile_browser_families:["Firefox Mobile","Opera Mobile","Opera Mini","Mobile Safari","webOS","IE Mobile","Playstation Portable","Nokia","Blackberry","Palm","Silk","Android","Maemo","Obigo","Netfront","AvantGo","Teleca","SEMC-Browser","Bolt","Iris","UP.Browser","Symphony","Minimo","Bunjaloo","Jasmine","Dolfin","Polaris","BREW","Chrome Mobile","Chrome Mobile iOS","UC Browser","Tizen Browser"]};e.parsers=["device_parsers","browser_parsers","os_parsers","mobile_os_families","mobile_browser_families"],e.types=["browser","os","device"],e.regexes=r||function(){var r={};return e.parsers.map(function(e){r[e]=[]}),r}(),e.families=function(){var r={};return e.types.map(function(e){r[e]=[]}),r}();var a=Array.prototype,o=(Object.prototype,Function.prototype,a.forEach);a.indexOf;var i=function(e,r){for(var a={},o=0;r.length>o&&!(a=r[o](e));o++);return a},n=function(e,r){t(e,function(e){t(r,function(r){delete e[r]})})},t=forEach=function(e,r,a){if(null!=e)if(o&&e.forEach===o)e.forEach(r,a);else if(e.length===+e.length)for(var i=0,n=e.length;n>i;i++)r.call(a,e[i],i,e);else for(var t in e)_.has(e,t)&&r.call(a,e[t],t,e)},l=function(e){return!(!e||e===undefined||null==e)},d=function(e){var r="";return e=e||{},l(e)&&l(e.major)&&(r+=e.major,l(e.minor)&&(r+="."+e.minor,l(e.patch)&&(r+="."+e.patch))),r},c=function(e){e=e||{};var r=d(e);return r&&(r=" "+r),e&&l(e.family)?e.family+r:""};return e.parse=function(r){var a=function(r){return e.regexes[r+"_parsers"].map(function(e){function a(r){var a=r.match(o);if(!a)return null;var t={};return t.family=(i?i.replace("$1",a[1]):a[1])||"other",t.major=parseInt(n?n:a[2])||null,t.minor=a[3]?parseInt(a[3]):null,t.patch=a[4]?parseInt(a[4]):null,t.tablet=e.tablet,t.man=e.manufacturer||null,t}var o=RegExp(e.regex),i=e[("browser"===r?"family":r)+"_replacement"],n=e.major_version_replacement;return a})},o=function(){},t=a("browser"),m=a("os"),p=a("device"),s=new o;s.source=r,s.browser=i(r,t),l(s.browser)?(s.browser.name=c(s.browser),s.browser.version=d(s.browser)):s.browser={},s.os=i(r,m),l(s.os)?(s.os.name=c(s.os),s.os.version=d(s.os)):s.os={},s.device=i(r,p),l(s.device)?(s.device.name=c(s.device),s.device.version=d(s.device)):s.device={tablet:!1,family:"Other"};var g={};return e.regexes.mobile_browser_families.map(function(e){g[e]=!0}),e.regexes.mobile_os_families.map(function(e){g[e]=!0}),s.device.type="Spider"===s.browser.family?"Spider":s.browser.tablet||s.os.tablet||s.device.tablet?"Tablet":g.hasOwnProperty(s.browser.family)?"Mobile":"Desktop",s.device.manufacturer=s.browser.man||s.os.man||s.device.man||null,n([s.browser,s.os,s.device],["tablet","man"]),s},e}();"undefined"!=typeof exports?("undefined"!=typeof module&&module.exports&&(exports=module.exports=r),exports.detect=r):e.detect=r,"function"==typeof define&&define.amd&&define(function(){return r})})(window);
\ No newline at end of file
diff --git a/freemius/README.md b/freemius/README.md
index 8260aff..cd292dd 100644
--- a/freemius/README.md
+++ b/freemius/README.md
@@ -280,3 +280,7 @@ The free version is the one that you should give your users to download. Therefo
Copyright (c) Freemius®, Inc.
Licensed under the GNU general public license (version 3).
+
+## Contributing
+
+Please see our [contributing guide](CONTRIBUTING.md).
diff --git a/freemius/assets/css/admin/account.css b/freemius/assets/css/admin/account.css
index b24edda..c9f5abd 100644
--- a/freemius/assets/css/admin/account.css
+++ b/freemius/assets/css/admin/account.css
@@ -1 +1 @@
-label.fs-tag,span.fs-tag{background:#ffba00;color:#fff;display:inline-block;border-radius:3px;padding:5px;font-size:11px;line-height:11px;vertical-align:baseline}label.fs-tag.fs-warn,span.fs-tag.fs-warn{background:#ffba00}label.fs-tag.fs-info,span.fs-tag.fs-info{background:#00a0d2}label.fs-tag.fs-success,span.fs-tag.fs-success{background:#46b450}label.fs-tag.fs-error,span.fs-tag.fs-error{background:#dc3232}.fs-notice[data-id=license_not_whitelabeled].success,.fs-notice[data-id=license_whitelabeled].success{color:inherit;border-left-color:#00a0d2}.fs-notice[data-id=license_not_whitelabeled].success label.fs-plugin-title,.fs-notice[data-id=license_whitelabeled].success label.fs-plugin-title{display:none}#fs_account .postbox,#fs_account .widefat{max-width:800px}#fs_account h3{font-size:1.3em;padding:12px 15px;margin:0 0 12px 0;line-height:1.4;border-bottom:1px solid #f1f1f1}#fs_account h3 .dashicons{width:26px;height:26px;font-size:1.3em}#fs_account i.dashicons{font-size:1.2em;height:1.2em;width:1.2em}#fs_account .dashicons{vertical-align:middle}#fs_account .fs-header-actions{position:absolute;top:17px;right:15px;font-size:.9em}#fs_account .fs-header-actions ul{margin:0}#fs_account .fs-header-actions li{float:left}#fs_account .fs-header-actions li form{display:inline-block}#fs_account .fs-header-actions li a{text-decoration:none}#fs_account_details .button-group{float:right}.rtl #fs_account .fs-header-actions{left:15px;right:auto}.fs-key-value-table{width:100%}.fs-key-value-table form{display:inline-block}.fs-key-value-table tr td:first-child{text-align:right}.fs-key-value-table tr td:first-child nobr{font-weight:bold}.fs-key-value-table tr td:first-child form{display:block}.fs-key-value-table tr td.fs-right{text-align:right}.fs-key-value-table tr.fs-odd{background:#ebebeb}.fs-key-value-table td,.fs-key-value-table th{padding:10px}.fs-key-value-table code{line-height:28px}.fs-key-value-table var,.fs-key-value-table code,.fs-key-value-table input[type=text]{color:#0073aa;font-size:16px;background:none}.fs-key-value-table input[type=text]{width:100%;font-weight:bold}.fs-field-beta_program label{margin-left:7px}label.fs-tag{background:#ffba00;color:#fff;display:inline-block;border-radius:3px;padding:5px;font-size:11px;line-height:11px;vertical-align:baseline}label.fs-tag.fs-warn{background:#ffba00}label.fs-tag.fs-success{background:#46b450}label.fs-tag.fs-error{background:#dc3232}#fs_sites .fs-scrollable-table .fs-table-body{max-height:200px;overflow:auto;border:1px solid #e5e5e5}#fs_sites .fs-scrollable-table .fs-table-body>table.widefat{border:none !important}#fs_sites .fs-scrollable-table .fs-main-column{width:100%}#fs_sites .fs-scrollable-table .fs-site-details td:first-of-type{text-align:right;color:gray;width:1px}#fs_sites .fs-scrollable-table .fs-site-details td:last-of-type{text-align:right}#fs_sites .fs-scrollable-table .fs-install-details table tr td{width:1px;white-space:nowrap}#fs_sites .fs-scrollable-table .fs-install-details table tr td:last-of-type{width:auto}#fs_addons h3{border:none;margin-bottom:0;padding:4px 5px}#fs_addons td{vertical-align:middle}#fs_addons thead{white-space:nowrap}#fs_addons td:first-child,#fs_addons th:first-child{text-align:left;font-weight:bold}#fs_addons td:last-child,#fs_addons th:last-child{text-align:right}#fs_addons th{font-weight:bold}#fs_billing_address{width:100%}#fs_billing_address tr td{width:50%;padding:5px}#fs_billing_address tr:first-of-type td{padding-top:0}#fs_billing_address span{font-weight:bold}#fs_billing_address input,#fs_billing_address select{display:block;width:100%;margin-top:5px}#fs_billing_address input::-moz-placeholder,#fs_billing_address select::-moz-placeholder{color:transparent;opacity:1}#fs_billing_address input:-ms-input-placeholder,#fs_billing_address select:-ms-input-placeholder{color:transparent}#fs_billing_address input::-webkit-input-placeholder,#fs_billing_address select::-webkit-input-placeholder{color:transparent}#fs_billing_address input.fs-read-mode,#fs_billing_address select.fs-read-mode{border-color:transparent;color:#777;border-bottom:1px dashed #ccc;padding-left:0;background:none}#fs_billing_address.fs-read-mode td span{display:none}#fs_billing_address.fs-read-mode input,#fs_billing_address.fs-read-mode select{border-color:transparent;color:#777;border-bottom:1px dashed #ccc;padding-left:0;background:none}#fs_billing_address.fs-read-mode input::-moz-placeholder,#fs_billing_address.fs-read-mode select::-moz-placeholder{color:#ccc;opacity:1}#fs_billing_address.fs-read-mode input:-ms-input-placeholder,#fs_billing_address.fs-read-mode select:-ms-input-placeholder{color:#ccc}#fs_billing_address.fs-read-mode input::-webkit-input-placeholder,#fs_billing_address.fs-read-mode select::-webkit-input-placeholder{color:#ccc}#fs_billing_address button{display:block;width:100%}@media screen and (max-width: 639px){#fs_account .fs-header-actions{position:static;padding:0 15px 12px 15px;margin:0 0 12px 0}#fs_account .fs-header-actions li{float:none;display:inline-block}#fs_account #fs_account_details{display:block}#fs_account #fs_account_details tbody,#fs_account #fs_account_details tr,#fs_account #fs_account_details td,#fs_account #fs_account_details th{display:block}#fs_account #fs_account_details tr td:first-child{text-align:left}#fs_account #fs_account_details tr td:nth-child(2){padding:0 12px}#fs_account #fs_account_details tr td:nth-child(2) code{margin:0;padding:0}#fs_account #fs_account_details tr td:nth-child(2) label{margin-left:0}#fs_account #fs_account_details tr td:nth-child(3){text-align:left}#fs_account #fs_account_details tr.fs-field-plan td:nth-child(2) .button-group{float:none;margin:12px 0}}
+label.fs-tag,span.fs-tag{background:#ffba00;border-radius:3px;color:#fff;display:inline-block;font-size:11px;line-height:11px;padding:5px;vertical-align:baseline}label.fs-tag.fs-warn,span.fs-tag.fs-warn{background:#ffba00}label.fs-tag.fs-info,span.fs-tag.fs-info{background:#00a0d2}label.fs-tag.fs-success,span.fs-tag.fs-success{background:#46b450}label.fs-tag.fs-error,span.fs-tag.fs-error{background:#dc3232}.fs-notice[data-id=license_not_whitelabeled].success,.fs-notice[data-id=license_whitelabeled].success{border-left-color:#00a0d2;color:inherit}.fs-notice[data-id=license_not_whitelabeled].success label.fs-plugin-title,.fs-notice[data-id=license_whitelabeled].success label.fs-plugin-title{display:none}#fs_account .postbox,#fs_account .widefat{max-width:800px}#fs_account h3{border-bottom:1px solid #f1f1f1;font-size:1.3em;line-height:1.4;margin:0 0 12px;padding:12px 15px}#fs_account h3 .dashicons{font-size:1.3em;height:26px;width:26px}#fs_account i.dashicons{font-size:1.2em;height:1.2em;width:1.2em}#fs_account .dashicons{vertical-align:middle}#fs_account .fs-header-actions{font-size:.9em;position:absolute;right:15px;top:17px}#fs_account .fs-header-actions ul{margin:0}#fs_account .fs-header-actions li{float:left}#fs_account .fs-header-actions li form{display:inline-block}#fs_account .fs-header-actions li a{text-decoration:none}#fs_account_details .button-group{float:right}.rtl #fs_account .fs-header-actions{left:15px;right:auto}.fs-key-value-table{width:100%}.fs-key-value-table form{display:inline-block}.fs-key-value-table tr td:first-child{text-align:right}.fs-key-value-table tr td:first-child nobr{font-weight:700}.fs-key-value-table tr td:first-child form{display:block}.fs-key-value-table tr td.fs-right{text-align:right}.fs-key-value-table tr.fs-odd{background:#ebebeb}.fs-key-value-table td,.fs-key-value-table th{padding:10px}.fs-key-value-table code{line-height:28px}.fs-key-value-table code,.fs-key-value-table input[type=text],.fs-key-value-table var{background:none;color:#0073aa;font-size:16px}.fs-key-value-table input[type=text]{font-weight:700;width:100%}.fs-field-beta_program label{margin-left:7px}label.fs-tag{border-radius:3px;color:#fff;display:inline-block;font-size:11px;line-height:11px;padding:5px;vertical-align:baseline}label.fs-tag,label.fs-tag.fs-warn{background:#ffba00}label.fs-tag.fs-success{background:#46b450}label.fs-tag.fs-error{background:#dc3232}#fs_sites .fs-scrollable-table .fs-table-body{border:1px solid #e5e5e5;max-height:200px;overflow:auto}#fs_sites .fs-scrollable-table .fs-table-body>table.widefat{border:none!important}#fs_sites .fs-scrollable-table .fs-main-column{width:100%}#fs_sites .fs-scrollable-table .fs-site-details td:first-of-type{color:gray;text-align:right;width:1px}#fs_sites .fs-scrollable-table .fs-site-details td:last-of-type{text-align:right}#fs_sites .fs-scrollable-table .fs-install-details table tr td{white-space:nowrap;width:1px}#fs_sites .fs-scrollable-table .fs-install-details table tr td:last-of-type{width:auto}#fs_addons h3{border:none;margin-bottom:0;padding:4px 5px}#fs_addons td{vertical-align:middle}#fs_addons thead{white-space:nowrap}#fs_addons td:first-child,#fs_addons th:first-child{font-weight:700;text-align:left}#fs_addons td:last-child,#fs_addons th:last-child{text-align:right}#fs_addons th{font-weight:700}#fs_billing_address{width:100%}#fs_billing_address tr td{padding:5px;width:50%}#fs_billing_address tr:first-of-type td{padding-top:0}#fs_billing_address span{font-weight:700}#fs_billing_address input,#fs_billing_address select{display:block;margin-top:5px;width:100%}#fs_billing_address input::-moz-placeholder,#fs_billing_address select::-moz-placeholder{color:transparent;opacity:1}#fs_billing_address input:-ms-input-placeholder,#fs_billing_address select:-ms-input-placeholder{color:transparent}#fs_billing_address input::-webkit-input-placeholder,#fs_billing_address select::-webkit-input-placeholder{color:transparent}#fs_billing_address input.fs-read-mode,#fs_billing_address select.fs-read-mode{background:none;border-color:transparent;border-bottom:1px dashed #ccc;color:#777;padding-left:0}#fs_billing_address.fs-read-mode td span{display:none}#fs_billing_address.fs-read-mode input,#fs_billing_address.fs-read-mode select{background:none;border-color:transparent;border-bottom:1px dashed #ccc;color:#777;padding-left:0}#fs_billing_address.fs-read-mode input::-moz-placeholder,#fs_billing_address.fs-read-mode select::-moz-placeholder{color:#ccc;opacity:1}#fs_billing_address.fs-read-mode input:-ms-input-placeholder,#fs_billing_address.fs-read-mode select:-ms-input-placeholder{color:#ccc}#fs_billing_address.fs-read-mode input::-webkit-input-placeholder,#fs_billing_address.fs-read-mode select::-webkit-input-placeholder{color:#ccc}#fs_billing_address button{display:block;width:100%}@media screen and (max-width:639px){#fs_account .fs-header-actions{margin:0 0 12px;padding:0 15px 12px;position:static}#fs_account .fs-header-actions li{display:inline-block;float:none}#fs_account #fs_account_details,#fs_account #fs_account_details tbody,#fs_account #fs_account_details td,#fs_account #fs_account_details th,#fs_account #fs_account_details tr{display:block}#fs_account #fs_account_details tr td:first-child{text-align:left}#fs_account #fs_account_details tr td:nth-child(2){padding:0 12px}#fs_account #fs_account_details tr td:nth-child(2) code{margin:0;padding:0}#fs_account #fs_account_details tr td:nth-child(2) label{margin-left:0}#fs_account #fs_account_details tr td:nth-child(3){text-align:left}#fs_account #fs_account_details tr.fs-field-plan td:nth-child(2) .button-group{float:none;margin:12px 0}}
\ No newline at end of file
diff --git a/freemius/assets/css/admin/add-ons.css b/freemius/assets/css/admin/add-ons.css
index dd71813..cce528f 100644
--- a/freemius/assets/css/admin/add-ons.css
+++ b/freemius/assets/css/admin/add-ons.css
@@ -1 +1 @@
-.fs-badge{position:absolute;top:10px;right:0;background:#71ae00;color:#fff;text-transform:uppercase;padding:5px 10px;-moz-border-radius:3px 0 0 3px;-webkit-border-radius:3px 0 0 3px;border-radius:3px 0 0 3px;font-weight:bold;border-right:0;-moz-box-shadow:0 2px 1px -1px rgba(0,0,0,.3);-webkit-box-shadow:0 2px 1px -1px rgba(0,0,0,.3);box-shadow:0 2px 1px -1px rgba(0,0,0,.3)}#fs_addons .fs-cards-list{list-style:none}#fs_addons .fs-cards-list .fs-card{float:left;height:152px;width:310px;padding:0;margin:0 0 30px 30px;font-size:14px;list-style:none;border:1px solid #ddd;cursor:pointer;position:relative}#fs_addons .fs-cards-list .fs-card .fs-overlay{position:absolute;left:0;right:0;bottom:0;top:0;z-index:9}#fs_addons .fs-cards-list .fs-card .fs-inner{background-color:#fff;overflow:hidden;height:100%;position:relative}#fs_addons .fs-cards-list .fs-card .fs-inner>ul{-moz-transition:all,.15s;-o-transition:all,.15s;-ms-transition:all,.15s;-webkit-transition:all,.15s;transition:all,.15s;left:0;right:0;top:0;position:absolute}#fs_addons .fs-cards-list .fs-card .fs-inner>ul>li{list-style:none;line-height:18px;padding:0 15px;width:100%;display:block;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}#fs_addons .fs-cards-list .fs-card .fs-inner .fs-card-banner{padding:0;margin:0;line-height:0;display:block;height:100px;background-repeat:repeat-x;background-size:100% 100%;-moz-transition:all,.15s;-o-transition:all,.15s;-ms-transition:all,.15s;-webkit-transition:all,.15s;transition:all,.15s}#fs_addons .fs-cards-list .fs-card .fs-inner .fs-card-banner .fs-badge.fs-installed-addon-badge{font-size:1.02em;line-height:1.3em}#fs_addons .fs-cards-list .fs-card .fs-inner .fs-title{margin:10px 0 0 0;height:18px;overflow:hidden;color:#000;white-space:nowrap;text-overflow:ellipsis;font-weight:bold}#fs_addons .fs-cards-list .fs-card .fs-inner .fs-offer{font-size:.9em}#fs_addons .fs-cards-list .fs-card .fs-inner .fs-description{background-color:#f9f9f9;padding:10px 15px 100px 15px;border-top:1px solid #eee;margin:0 0 10px 0;color:#777}#fs_addons .fs-cards-list .fs-card .fs-inner .fs-tag{position:absolute;top:10px;right:0px;background:#adff2f;display:block;padding:2px 10px;-moz-box-shadow:1px 1px 1px rgba(0,0,0,.3);-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.3);box-shadow:1px 1px 1px rgba(0,0,0,.3);text-transform:uppercase;font-size:.9em;font-weight:bold}#fs_addons .fs-cards-list .fs-card .fs-inner .fs-cta .button,#fs_addons .fs-cards-list .fs-card .fs-inner .fs-cta .button-group{position:absolute;top:112px;right:10px}@media screen and (min-width: 960px){#fs_addons .fs-cards-list .fs-card:hover .fs-overlay{border:2px solid #29abe1;margin-left:-1px;margin-top:-1px}#fs_addons .fs-cards-list .fs-card:hover .fs-inner ul{top:-100px}#fs_addons .fs-cards-list .fs-card:hover .fs-inner .fs-title,#fs_addons .fs-cards-list .fs-card:hover .fs-inner .fs-offer{color:#29abe1}}#TB_window,#TB_window iframe{width:821px !important}#plugin-information .fyi{width:266px !important}#plugin-information #section-holder{margin-right:299px;clear:none}#plugin-information #section-description h2,#plugin-information #section-description h3,#plugin-information #section-description p,#plugin-information #section-description b,#plugin-information #section-description i,#plugin-information #section-description blockquote,#plugin-information #section-description li,#plugin-information #section-description ul,#plugin-information #section-description ol{clear:none}#plugin-information #section-description iframe{max-width:100%}#plugin-information #section-description .fs-selling-points{padding-bottom:10px;border-bottom:1px solid #ddd}#plugin-information #section-description .fs-selling-points ul{margin:0}#plugin-information #section-description .fs-selling-points ul li{padding:0;list-style:none outside none}#plugin-information #section-description .fs-selling-points ul li i.dashicons{color:#71ae00;font-size:3em;vertical-align:middle;line-height:30px;float:left;margin:0 0 0 -15px}#plugin-information #section-description .fs-selling-points ul li h3{margin:1em 30px !important}#plugin-information #section-description .fs-screenshots:after{content:"";display:table;clear:both}#plugin-information #section-description .fs-screenshots ul{list-style:none;margin:0}#plugin-information #section-description .fs-screenshots ul li{width:225px;height:225px;float:left;margin-bottom:20px;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}#plugin-information #section-description .fs-screenshots ul li a{display:block;width:100%;height:100%;border:1px solid;-moz-box-shadow:1px 1px 1px rgba(0,0,0,.2);-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.2);box-shadow:1px 1px 1px rgba(0,0,0,.2);background-size:cover}#plugin-information #section-description .fs-screenshots ul li.odd{margin-right:20px}#plugin-information .plugin-information-pricing{margin:-16px;border-bottom:1px solid #ddd}#plugin-information .plugin-information-pricing .fs-plan h3{margin-top:0;padding:20px;font-size:16px}#plugin-information .plugin-information-pricing .fs-plan .nav-tab-wrapper{border-bottom:1px solid #ddd}#plugin-information .plugin-information-pricing .fs-plan .nav-tab-wrapper .nav-tab{cursor:pointer;position:relative;padding:0 10px;font-size:.9em}#plugin-information .plugin-information-pricing .fs-plan .nav-tab-wrapper .nav-tab label{text-transform:uppercase;color:green;background:#adff2f;position:absolute;left:-1px;right:-1px;bottom:100%;border:1px solid #006400;padding:2px;text-align:center;font-size:.9em;line-height:1em}#plugin-information .plugin-information-pricing .fs-plan .nav-tab-wrapper .nav-tab.nav-tab-active{cursor:default;background:#fffeec;border-bottom-color:#fffeec}#plugin-information .plugin-information-pricing .fs-plan.fs-single-cycle h3{background:#fffeec;margin:0;padding-bottom:0;color:#0073aa}#plugin-information .plugin-information-pricing .fs-plan.fs-single-cycle .nav-tab-wrapper,#plugin-information .plugin-information-pricing .fs-plan.fs-single-cycle .fs-billing-frequency{display:none}#plugin-information .plugin-information-pricing .fs-plan .fs-pricing-body{background:#fffeec;padding:20px}#plugin-information .plugin-information-pricing .fs-plan .button{width:100%;text-align:center;font-weight:bold;text-transform:uppercase;font-size:1.1em}#plugin-information .plugin-information-pricing .fs-plan label{white-space:nowrap}#plugin-information .plugin-information-pricing .fs-plan var{font-style:normal}#plugin-information .plugin-information-pricing .fs-plan .fs-billing-frequency,#plugin-information .plugin-information-pricing .fs-plan .fs-annual-discount{text-align:center;display:block;font-weight:bold;margin-bottom:10px;text-transform:uppercase;background:#f3f3f3;padding:2px;border:1px solid #ccc}#plugin-information .plugin-information-pricing .fs-plan .fs-annual-discount{text-transform:none;color:green;background:#adff2f}#plugin-information .plugin-information-pricing .fs-plan ul.fs-trial-terms{font-size:.9em}#plugin-information .plugin-information-pricing .fs-plan ul.fs-trial-terms i{float:left;margin:0 0 0 -15px}#plugin-information .plugin-information-pricing .fs-plan ul.fs-trial-terms li{margin:10px 0 0 0}#plugin-information #section-features .fs-features{margin:-20px -26px}#plugin-information #section-features table{width:100%;border-spacing:0;border-collapse:separate}#plugin-information #section-features table thead th{padding:10px 0}#plugin-information #section-features table thead .fs-price{color:#71ae00;font-weight:normal;display:block;text-align:center}#plugin-information #section-features table tbody td{border-top:1px solid #ccc;padding:10px 0;text-align:center;width:100px;color:#71ae00}#plugin-information #section-features table tbody td:first-child{text-align:left;width:auto;color:inherit;padding-left:26px}#plugin-information #section-features table tbody tr.fs-odd td{background:#fefefe}#plugin-information #section-features .dashicons-yes{width:30px;height:30px;font-size:30px}#fs_addons .fs-cards-list .fs-card .fs-inner .fs-dropdown .button-group .button,#plugin-information .fs-dropdown .button-group .button{position:relative;width:auto;top:0;right:0}#fs_addons .fs-cards-list .fs-card .fs-inner .fs-dropdown .button-group .button:focus,#plugin-information .fs-dropdown .button-group .button:focus{z-index:10}#fs_addons .fs-cards-list .fs-card .fs-inner .fs-dropdown .button-group .fs-dropdown-arrow,#plugin-information .fs-dropdown .button-group .fs-dropdown-arrow{border-top:6px solid #fff;border-right:4px solid transparent;border-left:4px solid transparent;top:12px;position:relative}#fs_addons .fs-cards-list .fs-card .fs-inner .fs-dropdown.active:not(.up) .button:not(.fs-dropdown-arrow-button),#plugin-information .fs-dropdown.active:not(.up) .button:not(.fs-dropdown-arrow-button){border-bottom-left-radius:0}#fs_addons .fs-cards-list .fs-card .fs-inner .fs-dropdown.active:not(.up) .fs-dropdown-arrow-button,#plugin-information .fs-dropdown.active:not(.up) .fs-dropdown-arrow-button{border-bottom-right-radius:0}#fs_addons .fs-cards-list .fs-card .fs-inner .fs-dropdown.active.up .button:not(.fs-dropdown-arrow-button),#plugin-information .fs-dropdown.active.up .button:not(.fs-dropdown-arrow-button){border-top-left-radius:0}#fs_addons .fs-cards-list .fs-card .fs-inner .fs-dropdown.active.up .fs-dropdown-arrow-button,#plugin-information .fs-dropdown.active.up .fs-dropdown-arrow-button{border-top-right-radius:0}#fs_addons .fs-cards-list .fs-card .fs-inner .fs-dropdown .fs-dropdown-list,#plugin-information .fs-dropdown .fs-dropdown-list{position:absolute;right:-1px;top:100%;margin-left:auto;padding:3px 0;border:1px solid #bfbfbf;background-color:#fff;z-index:1;width:230px;text-align:left;-moz-box-shadow:0px 2px 4px -1px rgba(0,0,0,.2),0px 4px 5px 0px rgba(0,0,0,.14),0px 1px 10px 0px rgba(0,0,0,.12);-webkit-box-shadow:0px 2px 4px -1px rgba(0,0,0,.2),0px 4px 5px 0px rgba(0,0,0,.14),0px 1px 10px 0px rgba(0,0,0,.12);box-shadow:0px 2px 4px -1px rgba(0,0,0,.2),0px 4px 5px 0px rgba(0,0,0,.14),0px 1px 10px 0px rgba(0,0,0,.12)}#fs_addons .fs-cards-list .fs-card .fs-inner .fs-dropdown .fs-dropdown-list li,#plugin-information .fs-dropdown .fs-dropdown-list li{margin:0}#fs_addons .fs-cards-list .fs-card .fs-inner .fs-dropdown .fs-dropdown-list li a,#plugin-information .fs-dropdown .fs-dropdown-list li a{display:block;padding:5px 10px;text-decoration:none;text-shadow:none}#fs_addons .fs-cards-list .fs-card .fs-inner .fs-dropdown .fs-dropdown-list li:hover,#plugin-information .fs-dropdown .fs-dropdown-list li:hover{background-color:#0074a3;color:#fff}#fs_addons .fs-cards-list .fs-card .fs-inner .fs-dropdown .fs-dropdown-list li:hover a,#plugin-information .fs-dropdown .fs-dropdown-list li:hover a{color:#fff}#fs_addons .fs-cards-list .fs-card .fs-inner .fs-dropdown:not(.up) .fs-dropdown-list,#plugin-information .fs-dropdown:not(.up) .fs-dropdown-list{-moz-border-radius:3px 0 3px 3px;-webkit-border-radius:3px 0 3px 3px;border-radius:3px 0 3px 3px}#fs_addons .fs-cards-list .fs-card .fs-inner .fs-dropdown.up .fs-dropdown-list,#plugin-information .fs-dropdown.up .fs-dropdown-list{-moz-border-radius:3px 3px 0 3px;-webkit-border-radius:3px 3px 0 3px;border-radius:3px 3px 0 3px}#plugin-information .fs-dropdown .button-group{width:100%}#plugin-information .fs-dropdown .button-group .button{float:none;font-size:14px;font-weight:normal;text-transform:none}#plugin-information .fs-dropdown .fs-dropdown-list{margin-top:1px}#plugin-information .fs-dropdown.up .fs-dropdown-list{top:auto;bottom:100%;margin-bottom:2px}#plugin-information.wp-core-ui .fs-pricing-body .fs-dropdown .button-group{text-align:center;display:table}#plugin-information.wp-core-ui .fs-pricing-body .fs-dropdown .button-group .button{display:table-cell}#plugin-information.wp-core-ui .fs-pricing-body .fs-dropdown .button-group .button:not(.fs-dropdown-arrow-button){left:1px;width:100%}#plugin-information-footer>.button,#plugin-information-footer .fs-dropdown{position:relative;top:3px}#plugin-information-footer>.button.left,#plugin-information-footer .fs-dropdown.left{float:left}#plugin-information-footer>.right,#plugin-information-footer .fs-dropdown{float:right}@media screen and (max-width: 961px){#fs_addons .fs-cards-list .fs-card{height:265px}}
+.fs-badge{background:#71ae00;border-radius:3px 0 0 3px;border-right:0;box-shadow:0 2px 1px -1px rgba(0,0,0,.3);color:#fff;font-weight:700;padding:5px 10px;position:absolute;right:0;text-transform:uppercase;top:10px}#fs_addons .fs-cards-list{list-style:none}#fs_addons .fs-cards-list .fs-card{border:1px solid #ddd;cursor:pointer;float:left;font-size:14px;height:152px;list-style:none;margin:0 0 30px 30px;padding:0;position:relative;width:310px}#fs_addons .fs-cards-list .fs-card .fs-overlay{bottom:0;left:0;position:absolute;right:0;top:0;z-index:9}#fs_addons .fs-cards-list .fs-card .fs-inner{background-color:#fff;height:100%;overflow:hidden;position:relative}#fs_addons .fs-cards-list .fs-card .fs-inner>ul{left:0;position:absolute;right:0;top:0;transition:all,.15s}#fs_addons .fs-cards-list .fs-card .fs-inner>ul>li{box-sizing:border-box;display:block;line-height:18px;list-style:none;padding:0 15px;width:100%}#fs_addons .fs-cards-list .fs-card .fs-inner .fs-card-banner{background-repeat:repeat-x;background-size:100% 100%;display:block;height:100px;line-height:0;margin:0;padding:0;transition:all,.15s}#fs_addons .fs-cards-list .fs-card .fs-inner .fs-card-banner .fs-badge.fs-installed-addon-badge{font-size:1.02em;line-height:1.3em}#fs_addons .fs-cards-list .fs-card .fs-inner .fs-title{color:#000;font-weight:700;height:18px;margin:10px 0 0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}#fs_addons .fs-cards-list .fs-card .fs-inner .fs-offer{font-size:.9em}#fs_addons .fs-cards-list .fs-card .fs-inner .fs-description{background-color:#f9f9f9;border-top:1px solid #eee;color:#777;margin:0 0 10px;padding:10px 15px 100px}#fs_addons .fs-cards-list .fs-card .fs-inner .fs-tag{background:#adff2f;box-shadow:1px 1px 1px rgba(0,0,0,.3);display:block;font-size:.9em;font-weight:700;padding:2px 10px;position:absolute;right:0;text-transform:uppercase;top:10px}#fs_addons .fs-cards-list .fs-card .fs-inner .fs-cta .button,#fs_addons .fs-cards-list .fs-card .fs-inner .fs-cta .button-group{position:absolute;right:10px;top:112px}@media screen and (min-width:960px){#fs_addons .fs-cards-list .fs-card:hover .fs-overlay{border:2px solid #29abe1;margin-left:-1px;margin-top:-1px}#fs_addons .fs-cards-list .fs-card:hover .fs-inner ul{top:-100px}#fs_addons .fs-cards-list .fs-card:hover .fs-inner .fs-offer,#fs_addons .fs-cards-list .fs-card:hover .fs-inner .fs-title{color:#29abe1}}#TB_window,#TB_window iframe{width:821px!important}#plugin-information .fyi{width:266px!important}#plugin-information #section-holder{clear:none;margin-right:299px}#plugin-information #section-description b,#plugin-information #section-description blockquote,#plugin-information #section-description h2,#plugin-information #section-description h3,#plugin-information #section-description i,#plugin-information #section-description li,#plugin-information #section-description ol,#plugin-information #section-description p,#plugin-information #section-description ul{clear:none}#plugin-information #section-description iframe{max-width:100%}#plugin-information #section-description .fs-selling-points{border-bottom:1px solid #ddd;padding-bottom:10px}#plugin-information #section-description .fs-selling-points ul{margin:0}#plugin-information #section-description .fs-selling-points ul li{list-style:none outside none;padding:0}#plugin-information #section-description .fs-selling-points ul li i.dashicons{color:#71ae00;float:left;font-size:3em;line-height:30px;margin:0 0 0 -15px;vertical-align:middle}#plugin-information #section-description .fs-selling-points ul li h3{margin:1em 30px!important}#plugin-information #section-description .fs-screenshots:after{clear:both;content:"";display:table}#plugin-information #section-description .fs-screenshots ul{list-style:none;margin:0}#plugin-information #section-description .fs-screenshots ul li{box-sizing:content-box;float:left;height:225px;margin-bottom:20px;width:225px}#plugin-information #section-description .fs-screenshots ul li a{background-size:cover;border:1px solid;box-shadow:1px 1px 1px rgba(0,0,0,.2);display:block;height:100%;width:100%}#plugin-information #section-description .fs-screenshots ul li.odd{margin-right:20px}#plugin-information .plugin-information-pricing{border-bottom:1px solid #ddd;margin:-16px}#plugin-information .plugin-information-pricing .fs-plan h3{font-size:16px;margin-top:0;padding:20px}#plugin-information .plugin-information-pricing .fs-plan .nav-tab-wrapper{border-bottom:1px solid #ddd}#plugin-information .plugin-information-pricing .fs-plan .nav-tab-wrapper .nav-tab{cursor:pointer;font-size:.9em;padding:0 10px;position:relative}#plugin-information .plugin-information-pricing .fs-plan .nav-tab-wrapper .nav-tab label{background:#adff2f;border:1px solid #006400;bottom:100%;color:green;font-size:.9em;left:-1px;line-height:1em;padding:2px;position:absolute;right:-1px;text-align:center;text-transform:uppercase}#plugin-information .plugin-information-pricing .fs-plan .nav-tab-wrapper .nav-tab.nav-tab-active{background:#fffeec;border-bottom-color:#fffeec;cursor:default}#plugin-information .plugin-information-pricing .fs-plan.fs-single-cycle h3{background:#fffeec;color:#0073aa;margin:0;padding-bottom:0}#plugin-information .plugin-information-pricing .fs-plan.fs-single-cycle .fs-billing-frequency,#plugin-information .plugin-information-pricing .fs-plan.fs-single-cycle .nav-tab-wrapper{display:none}#plugin-information .plugin-information-pricing .fs-plan .fs-pricing-body{background:#fffeec;padding:20px}#plugin-information .plugin-information-pricing .fs-plan .button{font-size:1.1em;font-weight:700;text-align:center;text-transform:uppercase;width:100%}#plugin-information .plugin-information-pricing .fs-plan label{white-space:nowrap}#plugin-information .plugin-information-pricing .fs-plan var{font-style:normal}#plugin-information .plugin-information-pricing .fs-plan .fs-annual-discount,#plugin-information .plugin-information-pricing .fs-plan .fs-billing-frequency{background:#f3f3f3;border:1px solid #ccc;display:block;font-weight:700;margin-bottom:10px;padding:2px;text-align:center;text-transform:uppercase}#plugin-information .plugin-information-pricing .fs-plan .fs-annual-discount{background:#adff2f;color:green;text-transform:none}#plugin-information .plugin-information-pricing .fs-plan ul.fs-trial-terms{font-size:.9em}#plugin-information .plugin-information-pricing .fs-plan ul.fs-trial-terms i{float:left;margin:0 0 0 -15px}#plugin-information .plugin-information-pricing .fs-plan ul.fs-trial-terms li{margin:10px 0 0}#plugin-information #section-features .fs-features{margin:-20px -26px}#plugin-information #section-features table{border-collapse:separate;border-spacing:0;width:100%}#plugin-information #section-features table thead th{padding:10px 0}#plugin-information #section-features table thead .fs-price{color:#71ae00;display:block;font-weight:400;text-align:center}#plugin-information #section-features table tbody td{border-top:1px solid #ccc;color:#71ae00;padding:10px 0;text-align:center;width:100px}#plugin-information #section-features table tbody td:first-child{color:inherit;padding-left:26px;text-align:left;width:auto}#plugin-information #section-features table tbody tr.fs-odd td{background:#fefefe}#plugin-information #section-features .dashicons-yes{font-size:30px;height:30px;width:30px}#fs_addons .fs-cards-list .fs-card .fs-inner .fs-dropdown .button-group .button,#plugin-information .fs-dropdown .button-group .button{position:relative;right:0;top:0;width:auto}#fs_addons .fs-cards-list .fs-card .fs-inner .fs-dropdown .button-group .button:focus,#plugin-information .fs-dropdown .button-group .button:focus{z-index:10}#fs_addons .fs-cards-list .fs-card .fs-inner .fs-dropdown .button-group .fs-dropdown-arrow,#plugin-information .fs-dropdown .button-group .fs-dropdown-arrow{border-left:4px solid transparent;border-right:4px solid transparent;border-top:6px solid #fff;position:relative;top:12px}#fs_addons .fs-cards-list .fs-card .fs-inner .fs-dropdown.active:not(.up) .button:not(.fs-dropdown-arrow-button),#plugin-information .fs-dropdown.active:not(.up) .button:not(.fs-dropdown-arrow-button){border-bottom-left-radius:0}#fs_addons .fs-cards-list .fs-card .fs-inner .fs-dropdown.active:not(.up) .fs-dropdown-arrow-button,#plugin-information .fs-dropdown.active:not(.up) .fs-dropdown-arrow-button{border-bottom-right-radius:0}#fs_addons .fs-cards-list .fs-card .fs-inner .fs-dropdown.active.up .button:not(.fs-dropdown-arrow-button),#plugin-information .fs-dropdown.active.up .button:not(.fs-dropdown-arrow-button){border-top-left-radius:0}#fs_addons .fs-cards-list .fs-card .fs-inner .fs-dropdown.active.up .fs-dropdown-arrow-button,#plugin-information .fs-dropdown.active.up .fs-dropdown-arrow-button{border-top-right-radius:0}#fs_addons .fs-cards-list .fs-card .fs-inner .fs-dropdown .fs-dropdown-list,#plugin-information .fs-dropdown .fs-dropdown-list{background-color:#fff;border:1px solid #bfbfbf;box-shadow:0 2px 4px -1px rgba(0,0,0,.2),0 4px 5px 0 rgba(0,0,0,.14),0 1px 10px 0 rgba(0,0,0,.12);margin-left:auto;padding:3px 0;position:absolute;right:-1px;text-align:left;top:100%;width:230px;z-index:1}#fs_addons .fs-cards-list .fs-card .fs-inner .fs-dropdown .fs-dropdown-list li,#plugin-information .fs-dropdown .fs-dropdown-list li{margin:0}#fs_addons .fs-cards-list .fs-card .fs-inner .fs-dropdown .fs-dropdown-list li a,#plugin-information .fs-dropdown .fs-dropdown-list li a{display:block;padding:5px 10px;text-decoration:none;text-shadow:none}#fs_addons .fs-cards-list .fs-card .fs-inner .fs-dropdown .fs-dropdown-list li:hover,#plugin-information .fs-dropdown .fs-dropdown-list li:hover{background-color:#0074a3;color:#fff}#fs_addons .fs-cards-list .fs-card .fs-inner .fs-dropdown .fs-dropdown-list li:hover a,#plugin-information .fs-dropdown .fs-dropdown-list li:hover a{color:#fff}#fs_addons .fs-cards-list .fs-card .fs-inner .fs-dropdown:not(.up) .fs-dropdown-list,#plugin-information .fs-dropdown:not(.up) .fs-dropdown-list{border-radius:3px 0 3px 3px}#fs_addons .fs-cards-list .fs-card .fs-inner .fs-dropdown.up .fs-dropdown-list,#plugin-information .fs-dropdown.up .fs-dropdown-list{border-radius:3px 3px 0 3px}#plugin-information .fs-dropdown .button-group{width:100%}#plugin-information .fs-dropdown .button-group .button{float:none;font-size:14px;font-weight:400;text-transform:none}#plugin-information .fs-dropdown .fs-dropdown-list{margin-top:1px}#plugin-information .fs-dropdown.up .fs-dropdown-list{bottom:100%;margin-bottom:2px;top:auto}#plugin-information.wp-core-ui .fs-pricing-body .fs-dropdown .button-group{display:table;text-align:center}#plugin-information.wp-core-ui .fs-pricing-body .fs-dropdown .button-group .button{display:table-cell}#plugin-information.wp-core-ui .fs-pricing-body .fs-dropdown .button-group .button:not(.fs-dropdown-arrow-button){left:1px;width:100%}#plugin-information-footer .fs-dropdown,#plugin-information-footer>.button{position:relative;top:3px}#plugin-information-footer .fs-dropdown.left,#plugin-information-footer>.button.left{float:left}#plugin-information-footer .fs-dropdown,#plugin-information-footer>.right{float:right}@media screen and (max-width:961px){#fs_addons .fs-cards-list .fs-card{height:265px}}
\ No newline at end of file
diff --git a/freemius/assets/css/admin/affiliation.css b/freemius/assets/css/admin/affiliation.css
index aae31ed..86c9250 100644
--- a/freemius/assets/css/admin/affiliation.css
+++ b/freemius/assets/css/admin/affiliation.css
@@ -1 +1 @@
-#fs_affiliation_content_wrapper #messages{margin-top:25px}#fs_affiliation_content_wrapper h3{font-size:24px;padding:0;margin-left:0}#fs_affiliation_content_wrapper ul li{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box;list-style-type:none}#fs_affiliation_content_wrapper ul li:before{content:"✓";margin-right:10px;font-weight:bold}#fs_affiliation_content_wrapper p:not(.description),#fs_affiliation_content_wrapper li,#fs_affiliation_content_wrapper label{font-size:16px !important;line-height:26px !important}#fs_affiliation_content_wrapper .button{margin-top:20px;margin-bottom:7px;line-height:35px;height:40px;font-size:16px}#fs_affiliation_content_wrapper .button#cancel_button{margin-right:5px}#fs_affiliation_content_wrapper form .input-container{margin-bottom:15px}#fs_affiliation_content_wrapper form .input-container .input-label{font-weight:bold;display:block;width:100%}#fs_affiliation_content_wrapper form .input-container.input-container-text label,#fs_affiliation_content_wrapper form .input-container.input-container-text input,#fs_affiliation_content_wrapper form .input-container.input-container-text textarea{display:block}#fs_affiliation_content_wrapper form .input-container #add_domain,#fs_affiliation_content_wrapper form .input-container .remove-domain{text-decoration:none;display:inline-block;margin-top:3px}#fs_affiliation_content_wrapper form .input-container #add_domain:focus,#fs_affiliation_content_wrapper form .input-container .remove-domain:focus{box-shadow:none}#fs_affiliation_content_wrapper form .input-container #add_domain.disabled,#fs_affiliation_content_wrapper form .input-container .remove-domain.disabled{color:#aaa;cursor:default}#fs_affiliation_content_wrapper form #extra_domains_container .description{margin-top:0;position:relative;top:-4px}#fs_affiliation_content_wrapper form #extra_domains_container .extra-domain-input-container{margin-bottom:15px}#fs_affiliation_content_wrapper form #extra_domains_container .extra-domain-input-container .domain{display:inline-block;margin-right:5px}#fs_affiliation_content_wrapper form #extra_domains_container .extra-domain-input-container .domain:last-of-type{margin-bottom:0}
+#fs_affiliation_content_wrapper #messages{margin-top:25px}#fs_affiliation_content_wrapper h3{font-size:24px;margin-left:0;padding:0}#fs_affiliation_content_wrapper ul li{box-sizing:border-box;list-style-type:none}#fs_affiliation_content_wrapper ul li:before{content:"✓";font-weight:700;margin-right:10px}#fs_affiliation_content_wrapper label,#fs_affiliation_content_wrapper li,#fs_affiliation_content_wrapper p:not(.description){font-size:16px!important;line-height:26px!important}#fs_affiliation_content_wrapper .button{font-size:16px;height:40px;line-height:35px;margin-bottom:7px;margin-top:20px}#fs_affiliation_content_wrapper .button#cancel_button{margin-right:5px}#fs_affiliation_content_wrapper form .input-container{margin-bottom:15px}#fs_affiliation_content_wrapper form .input-container .input-label{display:block;font-weight:700;width:100%}#fs_affiliation_content_wrapper form .input-container.input-container-text input,#fs_affiliation_content_wrapper form .input-container.input-container-text label,#fs_affiliation_content_wrapper form .input-container.input-container-text textarea{display:block}#fs_affiliation_content_wrapper form .input-container #add_domain,#fs_affiliation_content_wrapper form .input-container .remove-domain{display:inline-block;margin-top:3px;text-decoration:none}#fs_affiliation_content_wrapper form .input-container #add_domain:focus,#fs_affiliation_content_wrapper form .input-container .remove-domain:focus{box-shadow:none}#fs_affiliation_content_wrapper form .input-container #add_domain.disabled,#fs_affiliation_content_wrapper form .input-container .remove-domain.disabled{color:#aaa;cursor:default}#fs_affiliation_content_wrapper form #extra_domains_container .description{margin-top:0;position:relative;top:-4px}#fs_affiliation_content_wrapper form #extra_domains_container .extra-domain-input-container{margin-bottom:15px}#fs_affiliation_content_wrapper form #extra_domains_container .extra-domain-input-container .domain{display:inline-block;margin-right:5px}#fs_affiliation_content_wrapper form #extra_domains_container .extra-domain-input-container .domain:last-of-type{margin-bottom:0}
\ No newline at end of file
diff --git a/freemius/assets/css/admin/checkout.css b/freemius/assets/css/admin/checkout.css
index 56515d2..26d74ca 100644
--- a/freemius/assets/css/admin/checkout.css
+++ b/freemius/assets/css/admin/checkout.css
@@ -1 +1 @@
-@media screen and (max-width: 782px){#wpbody-content{padding-bottom:0 !important}}
+@media screen and (max-width:782px){#wpbody-content{padding-bottom:0!important}}
\ No newline at end of file
diff --git a/freemius/assets/css/admin/clone-resolution.css b/freemius/assets/css/admin/clone-resolution.css
index 8f48326..bb4b2f4 100644
--- a/freemius/assets/css/admin/clone-resolution.css
+++ b/freemius/assets/css/admin/clone-resolution.css
@@ -1 +1 @@
-.fs-notice[data-id^=clone_resolution_options_notice]{padding:0;color:inherit !important}.fs-notice[data-id^=clone_resolution_options_notice] .fs-notice-body{padding:0;margin-bottom:0}.fs-notice[data-id^=clone_resolution_options_notice] .fs-notice-header{padding:5px 10px}.fs-notice[data-id^=clone_resolution_options_notice] ol{margin-top:0;margin-bottom:0}.fs-notice[data-id^=clone_resolution_options_notice] .fs-clone-resolution-options-container{display:flex;flex-direction:row;padding:0 10px 10px}@media(max-width: 750px){.fs-notice[data-id^=clone_resolution_options_notice] .fs-clone-resolution-options-container{flex-direction:column}}.fs-notice[data-id^=clone_resolution_options_notice] .fs-clone-resolution-option{border:1px solid #ccc;padding:10px 10px 15px 10px;flex:auto;margin:5px}.fs-notice[data-id^=clone_resolution_options_notice] .fs-clone-resolution-option:first-child{margin-left:0}.fs-notice[data-id^=clone_resolution_options_notice] .fs-clone-resolution-option:last-child{margin-right:0}.fs-notice[data-id^=clone_resolution_options_notice] .fs-clone-resolution-option strong{font-size:1.2em;padding:2px;line-height:1.5em}.fs-notice[data-id^=clone_resolution_options_notice] a{text-decoration:none}.fs-notice[data-id^=clone_resolution_options_notice] .button{margin-right:10px}.rtl .fs-notice[data-id^=clone_resolution_options_notice] .button{margin-right:0;margin-left:10px}.fs-notice[data-id^=clone_resolution_options_notice] .fs-clone-documentation-container{padding:0 10px 15px}.fs-notice[data-id=temporary_duplicate_notice] #fs_clone_resolution_error_message{border:1px solid #d3135a;background:#fee;color:#d3135a;padding:10px}.fs-notice[data-id=temporary_duplicate_notice] ol{margin-top:0}
+.fs-notice[data-id^=clone_resolution_options_notice]{color:inherit!important;padding:0}.fs-notice[data-id^=clone_resolution_options_notice] .fs-notice-body{margin-bottom:0;padding:0}.fs-notice[data-id^=clone_resolution_options_notice] .fs-notice-header{padding:5px 10px}.fs-notice[data-id^=clone_resolution_options_notice] ol{margin-bottom:0;margin-top:0}.fs-notice[data-id^=clone_resolution_options_notice] .fs-clone-resolution-options-container{display:flex;flex-direction:row;padding:0 10px 10px}@media(max-width:750px){.fs-notice[data-id^=clone_resolution_options_notice] .fs-clone-resolution-options-container{flex-direction:column}}.fs-notice[data-id^=clone_resolution_options_notice] .fs-clone-resolution-option{border:1px solid #ccc;flex:auto;margin:5px;padding:10px 10px 15px}.fs-notice[data-id^=clone_resolution_options_notice] .fs-clone-resolution-option:first-child{margin-left:0}.fs-notice[data-id^=clone_resolution_options_notice] .fs-clone-resolution-option:last-child{margin-right:0}.fs-notice[data-id^=clone_resolution_options_notice] .fs-clone-resolution-option strong{font-size:1.2em;line-height:1.5em;padding:2px}.fs-notice[data-id^=clone_resolution_options_notice] a{text-decoration:none}.fs-notice[data-id^=clone_resolution_options_notice] .button{margin-right:10px}.rtl .fs-notice[data-id^=clone_resolution_options_notice] .button{margin-left:10px;margin-right:0}.fs-notice[data-id^=clone_resolution_options_notice] .fs-clone-documentation-container{padding:0 10px 15px}.fs-notice[data-id=temporary_duplicate_notice] #fs_clone_resolution_error_message{background:#fee;border:1px solid #d3135a;color:#d3135a;padding:10px}.fs-notice[data-id=temporary_duplicate_notice] ol{margin-top:0}.fs-notice[data-id=temporary_duplicate_notice] a{position:relative}.fs-notice[data-id=temporary_duplicate_notice] a:focus{box-shadow:none}.fs-notice[data-id=temporary_duplicate_notice] a.disabled{color:gray}.fs-notice[data-id=temporary_duplicate_notice] a .fs-ajax-spinner{bottom:0;left:8px;margin-left:100%;position:absolute;right:0;top:-1px}
\ No newline at end of file
diff --git a/freemius/assets/css/admin/common.css b/freemius/assets/css/admin/common.css
index 900103a..fae2810 100644
--- a/freemius/assets/css/admin/common.css
+++ b/freemius/assets/css/admin/common.css
@@ -1 +1 @@
-.fs-badge{position:absolute;top:10px;right:0;background:#71ae00;color:#fff;text-transform:uppercase;padding:5px 10px;-moz-border-radius:3px 0 0 3px;-webkit-border-radius:3px 0 0 3px;border-radius:3px 0 0 3px;font-weight:bold;border-right:0;-moz-box-shadow:0 2px 1px -1px rgba(0,0,0,.3);-webkit-box-shadow:0 2px 1px -1px rgba(0,0,0,.3);box-shadow:0 2px 1px -1px rgba(0,0,0,.3)}.theme-browser .theme .fs-premium-theme-badge-container{position:absolute;right:0;top:0}.theme-browser .theme .fs-premium-theme-badge-container .fs-badge{position:relative;top:0;margin-top:10px;text-align:center}.theme-browser .theme .fs-premium-theme-badge-container .fs-badge.fs-premium-theme-badge{font-size:1.1em}.theme-browser .theme .fs-premium-theme-badge-container .fs-badge.fs-beta-theme-badge{background:#00a0d2}.fs-switch{position:relative;display:inline-block;color:#ccc;text-shadow:0 1px 1px rgba(255,255,255,.8);height:18px;padding:6px 6px 5px 6px;border:1px solid #ccc;border:1px solid rgba(0,0,0,.2);background:#ececec;box-shadow:0 0 4px rgba(0,0,0,.1),inset 0 1px 3px 0 rgba(0,0,0,.1);cursor:pointer}.fs-switch span{display:inline-block;width:35px;text-transform:uppercase}.fs-switch .fs-toggle{position:absolute;top:1px;width:37px;height:25px;border:1px solid #ccc;border:1px solid rgba(0,0,0,.3);border-radius:4px;background:#fff;background-color:#fff;background-image:-webkit-gradient(linear, left top, left bottom, color-stop(0, #ececec), color-stop(1, #fff));background-image:-webkit-linear-gradient(top, #ececec, #fff);background-image:-moz-linear-gradient(top, #ececec, #fff);background-image:-ms-linear-gradient(top, #ececec, #fff);background-image:-o-linear-gradient(top, #ececec, #fff);background-image:linear-gradient(top, bottom, #ececec, #fff);box-shadow:inset 0 1px 0 0 rgba(255,255,255,.5);z-index:999;-moz-transition:.4s cubic-bezier(0.54, 1.6, 0.5, 1);-o-transition:.4s cubic-bezier(0.54, 1.6, 0.5, 1);-ms-transition:.4s cubic-bezier(0.54, 1.6, 0.5, 1);-webkit-transition:.4s cubic-bezier(0.54, 1.6, 0.5, 1);transition:.4s cubic-bezier(0.54, 1.6, 0.5, 1)}.fs-switch.fs-off .fs-toggle{left:2%}.fs-switch.fs-on .fs-toggle{left:54%}.fs-switch.fs-round{top:8px;padding:4px 25px;-moz-border-radius:24px;-webkit-border-radius:24px;border-radius:24px}.fs-switch.fs-round .fs-toggle{top:0;width:24px;height:24px;-moz-border-radius:24px;-webkit-border-radius:24px;border-radius:24px}.fs-switch.fs-round.fs-off .fs-toggle{left:-1px}.fs-switch.fs-round.fs-on{background:#0085ba}.fs-switch.fs-round.fs-on .fs-toggle{left:25px}.fs-switch.fs-small.fs-round{padding:1px 19px}.fs-switch.fs-small.fs-round .fs-toggle{top:0;width:18px;height:18px;-moz-border-radius:18px;-webkit-border-radius:18px;border-radius:18px}.fs-switch.fs-small.fs-round.fs-on .fs-toggle{left:19px}body.fs-loading,body.fs-loading *{cursor:wait !important}#fs_frame{line-height:0;font-size:0}.fs-full-size-wrapper{margin:40px 0 -65px -20px}@media(max-width: 600px){.fs-full-size-wrapper{margin:0 0 -65px -10px}}.fs-notice{position:relative}.fs-notice.fs-has-title{margin-bottom:30px !important}.fs-notice.success{color:green}.fs-notice.promotion{border-color:#00a0d2 !important;background-color:#f2fcff !important}.fs-notice .fs-notice-body{margin:.5em 0;padding:2px}.fs-notice .fs-close{cursor:pointer;color:#aaa;float:right}.fs-notice .fs-close:hover{color:#666}.fs-notice .fs-close>*{margin-top:7px;display:inline-block}.fs-notice label.fs-plugin-title{background:rgba(0,0,0,.3);color:#fff;padding:2px 10px;position:absolute;top:100%;bottom:auto;right:auto;-moz-border-radius:0 0 3px 3px;-webkit-border-radius:0 0 3px 3px;border-radius:0 0 3px 3px;left:10px;font-size:12px;font-weight:bold;cursor:auto}div.fs-notice.updated,div.fs-notice.success,div.fs-notice.promotion{display:block !important}#fs_connect .fs-error ol,#fs_connect .fs-error .fs-api-request-error-show-details-link,#fs_connect .fs-error .fs-api-request-error-details,.fs-modal .notice-error ol,.fs-modal .notice-error .fs-api-request-error-show-details-link,.fs-modal .notice-error .fs-api-request-error-details,.fs-notice.error ol,.fs-notice.error .fs-api-request-error-show-details-link,.fs-notice.error .fs-api-request-error-details{text-align:left}#fs_connect .fs-error ol,.fs-modal .notice-error ol,.fs-notice.error ol{list-style-type:disc}#fs_connect .fs-error .fs-api-request-error-show-details-link,.fs-modal .notice-error .fs-api-request-error-show-details-link,.fs-notice.error .fs-api-request-error-show-details-link{text-decoration:none;color:#2271b1;box-shadow:none}#fs_connect .fs-error .fs-api-request-error-details,.fs-modal .notice-error .fs-api-request-error-details,.fs-notice.error .fs-api-request-error-details{border:1px solid #ccc;padding:5px;overflow:auto;max-height:150px}.rtl .fs-notice .fs-close{float:left}.fs-secure-notice{position:fixed;top:32px;left:160px;right:0;background:#ebfdeb;padding:10px 20px;color:green;z-index:9999;-moz-box-shadow:0 2px 2px rgba(6,113,6,.3);-webkit-box-shadow:0 2px 2px rgba(6,113,6,.3);box-shadow:0 2px 2px rgba(6,113,6,.3);opacity:.95;filter:alpha(opacity=95)}.fs-secure-notice:hover{opacity:1;filter:alpha(opacity=100)}.fs-secure-notice a.fs-security-proof{color:green;text-decoration:none}@media screen and (max-width: 960px){.fs-secure-notice{left:36px}}@media screen and (max-width: 600px){.fs-secure-notice{display:none}}@media screen and (max-width: 1250px){#fs_promo_tab{display:none}}@media screen and (max-width: 782px){.fs-secure-notice{left:0;top:46px;text-align:center}}span.fs-submenu-item.fs-sub:before{content:"↳";padding:0 5px}.rtl span.fs-submenu-item.fs-sub:before{content:"↲"}.fs-submenu-item.pricing.upgrade-mode{color:#adff2f}.fs-submenu-item.pricing.trial-mode{color:#83e2ff}#adminmenu .update-plugins.fs-trial{background-color:#00b9eb}.fs-ajax-spinner{border:0;width:20px;height:20px;margin-right:5px;vertical-align:sub;display:inline-block;background:url("/wp-admin/images/wpspin_light-2x.gif");background-size:contain;margin-bottom:-2px}.wrap.fs-section h2{text-align:left}.plugins p.fs-upgrade-notice{border:0;background-color:#d54e21;padding:10px;color:#f9f9f9;margin-top:10px}
+.fs-badge{background:#71ae00;border-radius:3px 0 0 3px;border-right:0;box-shadow:0 2px 1px -1px rgba(0,0,0,.3);color:#fff;font-weight:700;padding:5px 10px;position:absolute;right:0;text-transform:uppercase;top:10px}.theme-browser .theme .fs-premium-theme-badge-container{position:absolute;right:0;top:0}.theme-browser .theme .fs-premium-theme-badge-container .fs-badge{margin-top:10px;position:relative;text-align:center;top:0}.theme-browser .theme .fs-premium-theme-badge-container .fs-badge.fs-premium-theme-badge{font-size:1.1em}.theme-browser .theme .fs-premium-theme-badge-container .fs-badge.fs-beta-theme-badge{background:#00a0d2}.fs-switch{background:#ececec;border:1px solid #ccc;border:1px solid rgba(0,0,0,.2);box-shadow:0 0 4px rgba(0,0,0,.1),inset 0 1px 3px 0 rgba(0,0,0,.1);color:#ccc;cursor:pointer;display:inline-block;height:18px;padding:6px 6px 5px;position:relative;text-shadow:0 1px 1px hsla(0,0%,100%,.8)}.fs-switch span{display:inline-block;text-transform:uppercase;width:35px}.fs-switch .fs-toggle{background-color:#fff;background-image:linear-gradient(180deg,#ececec,#fff);border:1px solid rgba(0,0,0,.3);border-radius:4px;box-shadow:inset 0 1px 0 0 hsla(0,0%,100%,.5);height:25px;position:absolute;top:1px;transition:.4s cubic-bezier(.54,1.6,.5,1);width:37px;z-index:999}.fs-switch.fs-off .fs-toggle{left:2%}.fs-switch.fs-on .fs-toggle{left:54%}.fs-switch.fs-round{border-radius:24px;padding:4px 25px;top:8px}.fs-switch.fs-round .fs-toggle{border-radius:24px;height:24px;top:0;width:24px}.fs-switch.fs-round.fs-off .fs-toggle{left:-1px}.fs-switch.fs-round.fs-on{background:#0085ba}.fs-switch.fs-round.fs-on .fs-toggle{left:25px}.fs-switch.fs-small.fs-round{padding:1px 19px}.fs-switch.fs-small.fs-round .fs-toggle{border-radius:18px;height:18px;top:0;width:18px}.fs-switch.fs-small.fs-round.fs-on .fs-toggle{left:19px}body.fs-loading,body.fs-loading *{cursor:wait!important}#fs_frame{font-size:0;line-height:0}.fs-full-size-wrapper{margin:40px 0 -65px -20px}@media(max-width:600px){.fs-full-size-wrapper{margin:0 0 -65px -10px}}.fs-notice{position:relative}.fs-notice.fs-has-title{margin-bottom:30px!important}.fs-notice.success{color:green}.fs-notice.promotion{background-color:#f2fcff!important;border-color:#00a0d2!important}.fs-notice .fs-notice-body{margin:.5em 0;padding:2px}.fs-notice .fs-close{color:#aaa;cursor:pointer;float:right}.fs-notice .fs-close:hover{color:#666}.fs-notice .fs-close>*{display:inline-block;margin-top:7px}.fs-notice label.fs-plugin-title{background:rgba(0,0,0,.3);border-radius:0 0 3px 3px;bottom:auto;color:#fff;cursor:auto;font-size:12px;font-weight:700;left:10px;padding:2px 10px;position:absolute;right:auto;top:100%}div.fs-notice.promotion,div.fs-notice.success,div.fs-notice.updated{display:block!important}#fs_connect .fs-error .fs-api-request-error-details,#fs_connect .fs-error .fs-api-request-error-show-details-link,#fs_connect .fs-error ol,.fs-modal .notice-error .fs-api-request-error-details,.fs-modal .notice-error .fs-api-request-error-show-details-link,.fs-modal .notice-error ol,.fs-notice.error .fs-api-request-error-details,.fs-notice.error .fs-api-request-error-show-details-link,.fs-notice.error ol{text-align:left}#fs_connect .fs-error ol,.fs-modal .notice-error ol,.fs-notice.error ol{list-style-type:disc}#fs_connect .fs-error .fs-api-request-error-show-details-link,.fs-modal .notice-error .fs-api-request-error-show-details-link,.fs-notice.error .fs-api-request-error-show-details-link{box-shadow:none;color:#2271b1;text-decoration:none}#fs_connect .fs-error .fs-api-request-error-details,.fs-modal .notice-error .fs-api-request-error-details,.fs-notice.error .fs-api-request-error-details{border:1px solid #ccc;max-height:150px;overflow:auto;padding:5px}.rtl .fs-notice .fs-close{float:left}.fs-secure-notice{background:#ebfdeb;box-shadow:0 2px 2px rgba(6,113,6,.3);color:green;filter:alpha(opacity=95);left:160px;opacity:.95;padding:10px 20px;position:fixed;right:0;top:32px;z-index:9999}.fs-secure-notice:hover{filter:alpha(opacity=100);opacity:1}.fs-secure-notice a.fs-security-proof{color:green;text-decoration:none}@media screen and (max-width:960px){.fs-secure-notice{left:36px}}@media screen and (max-width:600px){.fs-secure-notice{display:none}}@media screen and (max-width:1250px){#fs_promo_tab{display:none}}@media screen and (max-width:782px){.fs-secure-notice{left:0;text-align:center;top:46px}}span.fs-submenu-item.fs-sub:before{content:"↳";padding:0 5px}.rtl span.fs-submenu-item.fs-sub:before{content:"↲"}.fs-submenu-item.pricing.upgrade-mode{color:#adff2f}.fs-submenu-item.pricing.trial-mode{color:#83e2ff}#adminmenu .update-plugins.fs-trial{background-color:#00b9eb}.fs-ajax-spinner{background:url(/wp-admin/images/wpspin_light-2x.gif);background-size:contain;border:0;display:inline-block;height:20px;margin-bottom:-2px;margin-right:5px;vertical-align:sub;width:20px}.wrap.fs-section h2{text-align:left}.plugins p.fs-upgrade-notice{background-color:#d54e21;border:0;color:#f9f9f9;margin-top:10px;padding:10px}
\ No newline at end of file
diff --git a/freemius/assets/css/admin/connect.css b/freemius/assets/css/admin/connect.css
index 47a75d8..c73ec87 100644
--- a/freemius/assets/css/admin/connect.css
+++ b/freemius/assets/css/admin/connect.css
@@ -1 +1 @@
-.fs-tooltip-trigger{position:relative}.fs-tooltip-trigger:not(a){cursor:help}.fs-tooltip-trigger .dashicons{float:none !important}.fs-tooltip-trigger .fs-tooltip{opacity:0;visibility:hidden;-moz-transition:opacity .3s ease-in-out;-o-transition:opacity .3s ease-in-out;-ms-transition:opacity .3s ease-in-out;-webkit-transition:opacity .3s ease-in-out;transition:opacity .3s ease-in-out;position:absolute;background:rgba(0,0,0,.8);color:#fff !important;font-family:"arial",serif;font-size:12px;padding:10px;z-index:999999;bottom:100%;margin-bottom:5px;left:-17px;right:0;-moz-border-radius:5px;-webkit-border-radius:5px;border-radius:5px;-moz-box-shadow:1px 1px 1px rgba(0,0,0,.2);-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.2);box-shadow:1px 1px 1px rgba(0,0,0,.2);line-height:1.3em;font-weight:bold;text-align:left;text-transform:none !important}.rtl .fs-tooltip-trigger .fs-tooltip{text-align:right;left:auto;right:-17px}.fs-tooltip-trigger .fs-tooltip::after{content:" ";display:block;width:0;height:0;border-style:solid;border-width:5px 5px 0 5px;border-color:rgba(0,0,0,.8) transparent transparent transparent;position:absolute;top:100%;left:21px}.rtl .fs-tooltip-trigger .fs-tooltip::after{right:21px;left:auto}.fs-tooltip-trigger:hover .fs-tooltip{visibility:visible;opacity:1}#fs_connect{width:484px;margin:60px auto 20px auto}#fs_connect a{color:inherit}#fs_connect a:not(.button){text-decoration:underline}#fs_connect .fs-box-container{box-shadow:0 1px 2px rgba(0,0,0,.3);border-radius:3px;overflow:hidden;padding-top:40px;background:#f0f0f1}@media screen and (max-width: 483px){#fs_connect{width:auto;margin:30px 0 0 -10px}#fs_connect .fs-box-container{-moz-box-shadow:none;-webkit-box-shadow:none;box-shadow:none}}#fs_connect .fs-content{background:#fff;padding:30px 20px}#fs_connect .fs-content .fs-error{background:snow;color:#d3135a;border:1px solid #d3135a;-moz-box-shadow:0 1px 1px 0 rgba(0,0,0,.1);-webkit-box-shadow:0 1px 1px 0 rgba(0,0,0,.1);box-shadow:0 1px 1px 0 rgba(0,0,0,.1);text-align:center;padding:5px;margin-bottom:10px}#fs_connect .fs-content h2{line-height:1.5em}#fs_connect .fs-content p{margin:0;padding:0;font-size:1.2em}#fs_connect .fs-license-key-container{position:relative;width:280px;margin:10px auto 0 auto}#fs_connect .fs-license-key-container input{width:100%}#fs_connect .fs-license-key-container .dashicons{position:absolute;top:5px;right:5px}#fs_connect.require-license-key .fs-content{padding-bottom:10px}#fs_connect.require-license-key .fs-actions{border-top:none}#fs_connect.require-license-key .fs-sites-list-container td{cursor:pointer}#fs_connect #delegate_to_site_admins{margin-right:15px;float:right;height:26px;vertical-align:middle;line-height:37px;font-weight:bold;border-bottom:1px dashed;text-decoration:none}#fs_connect #delegate_to_site_admins.rtl{margin-left:15px;margin-right:0}#fs_connect .fs-actions{padding:10px 20px;background:#fff;border-width:1px 0;border-style:solid;border-color:#f1f1f1}#fs_connect .fs-actions .button{padding:0 10px 1px;line-height:35px;height:37px;font-size:16px;margin-bottom:0}#fs_connect .fs-actions .button .dashicons{font-size:37px;margin-left:-8px;margin-right:12px}#fs_connect .fs-actions .button.button-primary{padding-right:15px;padding-left:15px}#fs_connect .fs-actions .button.button-primary:after{content:" ➜"}#fs_connect .fs-actions .button.button-primary.fs-loading:after{content:""}#fs_connect .fs-actions .button.button-secondary{float:right}#fs_connect.fs-anonymous-disabled .fs-actions .button.button-primary{width:100%}#fs_connect .fs-permissions{padding:10px 20px;background:#fff;-moz-transition:background .5s ease;-o-transition:background .5s ease;-ms-transition:background .5s ease;-webkit-transition:background .5s ease;transition:background .5s ease}#fs_connect .fs-permissions .fs-license-sync-disclaimer{text-align:center;margin-top:0}#fs_connect .fs-permissions>.fs-trigger{font-size:.9em;text-decoration:none;text-align:center;display:block}#fs_connect .fs-permissions>.fs-trigger .fs-arrow::after{content:"→";width:20px;display:inline-block}#fs_connect .fs-permissions.fs-open>.fs-trigger .fs-arrow::after{content:"↓" !important}#fs_connect .fs-permissions ul li{padding-left:0;padding-right:0}@media screen and (max-width: 483px){#fs_connect .fs-permissions ul{height:auto;margin:20px}}#fs_connect .fs-freemium-licensing{padding:8px;background:#777;color:#fff}#fs_connect .fs-freemium-licensing p{text-align:center;display:block;margin:0;padding:0}#fs_connect .fs-freemium-licensing a{color:inherit;text-decoration:underline}#fs_connect .fs-header{padding:0;line-height:0;height:0;position:relative}#fs_connect .fs-header .fs-site-icon,#fs_connect .fs-header .fs-connect-logo{position:absolute;top:-8px;border-radius:50%}#fs_connect .fs-header .fs-site-icon{left:152px}#fs_connect .fs-header .fs-connect-logo{right:152px}#fs_connect .fs-header .fs-site-icon,#fs_connect .fs-header img,#fs_connect .fs-header object{width:50px;height:50px;border-radius:50%}#fs_connect .fs-header .fs-plugin-icon{position:absolute;overflow:hidden;top:-23px;left:50%;margin-left:-44px;border-radius:50%;z-index:1}#fs_connect .fs-header .fs-plugin-icon,#fs_connect .fs-header .fs-plugin-icon img{width:80px;height:80px}#fs_connect .fs-header .dashicons-wordpress-alt{font-size:40px;background:#01749a;color:#fff;width:40px;height:40px;padding:5px;border-radius:50%}#fs_connect .fs-header .dashicons-plus{position:absolute;top:50%;font-size:30px;margin-top:-10px;color:#bbb}#fs_connect .fs-header .dashicons-plus.fs-first{left:28%}#fs_connect .fs-header .dashicons-plus.fs-second{left:65%}#fs_connect .fs-header .fs-plugin-icon,#fs_connect .fs-header .fs-connect-logo,#fs_connect .fs-header .fs-site-icon{border:1px solid #efefef;padding:3px;background:#fff}#fs_connect .fs-terms{text-align:center;font-size:.85em;padding:10px 5px}#fs_connect .fs-terms,#fs_connect .fs-terms a{color:#999}#fs_connect .fs-terms a{text-decoration:none}.fs-multisite-options-container{margin-top:20px;border:1px solid #ccc;padding:5px}.fs-multisite-options-container a{text-decoration:none}.fs-multisite-options-container a:focus{box-shadow:none}.fs-multisite-options-container a.selected{font-weight:bold}.fs-multisite-options-container.fs-apply-on-all-sites{border:0 none;padding:0}.fs-multisite-options-container.fs-apply-on-all-sites .fs-all-sites-options{border-spacing:0}.fs-multisite-options-container.fs-apply-on-all-sites .fs-all-sites-options td:not(:first-child){display:none}.fs-multisite-options-container .fs-sites-list-container{display:none;overflow:auto}.fs-multisite-options-container .fs-sites-list-container table td{border-top:1px solid #ccc;padding:4px 2px}#fs_marketing_optin{display:none;margin-top:10px;border:1px solid #ccc;padding:10px;line-height:1.5em}#fs_marketing_optin .fs-message{display:block;margin-bottom:5px;font-size:1.05em;font-weight:600}#fs_marketing_optin.error{border:1px solid #d3135a;background:#fee}#fs_marketing_optin.error .fs-message{color:#d3135a}#fs_marketing_optin .fs-input-container{margin-top:5px}#fs_marketing_optin .fs-input-container label{margin-top:5px;display:block}#fs_marketing_optin .fs-input-container label input{float:left;margin:1px 0 0 0}#fs_marketing_optin .fs-input-container label:first-child{display:block;margin-bottom:2px}#fs_marketing_optin .fs-input-label{display:block;margin-left:20px}#fs_marketing_optin .fs-input-label .underlined{text-decoration:underline}.rtl #fs_marketing_optin .fs-input-container label input{float:right}.rtl #fs_marketing_optin .fs-input-label{margin-left:0;margin-right:20px}.rtl #fs_connect{border-radius:3px}.rtl #fs_connect .fs-actions{padding:10px 20px;background:#c0c7ca}.rtl #fs_connect .fs-actions .button .dashicons{font-size:37px;margin-left:-8px;margin-right:12px}.rtl #fs_connect .fs-actions .button.button-primary:after{content:" »"}.rtl #fs_connect .fs-actions .button.button-primary.fs-loading:after{content:""}.rtl #fs_connect .fs-actions .button.button-secondary{float:left}.rtl #fs_connect .fs-header .fs-site-icon{right:20px;left:auto}.rtl #fs_connect .fs-header .fs-connect-logo{right:auto;left:20px}.rtl #fs_connect .fs-permissions>.fs-trigger .fs-arrow::after{content:"←"}#fs_theme_connect_wrapper{position:fixed;top:0;height:100%;width:100%;z-index:99990;background:rgba(0,0,0,.75);text-align:center;overflow-y:auto}#fs_theme_connect_wrapper:before{content:"";display:inline-block;vertical-align:middle;height:100%}#fs_theme_connect_wrapper>button.close{color:#fff;cursor:pointer;height:40px;width:40px;position:absolute;right:0;border:0;background-color:transparent;top:32px}#fs_theme_connect_wrapper #fs_connect{top:0;text-align:left;display:inline-block;vertical-align:middle;margin-top:0;margin-bottom:20px}#fs_theme_connect_wrapper #fs_connect .fs-terms,#fs_theme_connect_wrapper #fs_connect .fs-terms a{color:#c5c5c5}.wp-pointer-content #fs_connect{margin:0;-moz-box-shadow:none;-webkit-box-shadow:none;box-shadow:none}.fs-opt-in-pointer .wp-pointer-content{padding:0}.fs-opt-in-pointer.wp-pointer-top .wp-pointer-arrow{border-bottom-color:#dfdfdf}.fs-opt-in-pointer.wp-pointer-top .wp-pointer-arrow-inner{border-bottom-color:#fafafa}.fs-opt-in-pointer.wp-pointer-bottom .wp-pointer-arrow{border-top-color:#dfdfdf}.fs-opt-in-pointer.wp-pointer-bottom .wp-pointer-arrow-inner{border-top-color:#fafafa}.fs-opt-in-pointer.wp-pointer-left .wp-pointer-arrow{border-right-color:#dfdfdf}.fs-opt-in-pointer.wp-pointer-left .wp-pointer-arrow-inner{border-right-color:#fafafa}.fs-opt-in-pointer.wp-pointer-right .wp-pointer-arrow{border-left-color:#dfdfdf}.fs-opt-in-pointer.wp-pointer-right .wp-pointer-arrow-inner{border-left-color:#fafafa}#license_issues_link{display:block;text-align:center;font-size:.9em;margin-top:10px}.fs-tooltip-trigger{position:relative}.fs-tooltip-trigger:not(a){cursor:help}.fs-tooltip-trigger .dashicons{float:none !important}.fs-tooltip-trigger .fs-tooltip{opacity:0;visibility:hidden;-moz-transition:opacity .3s ease-in-out;-o-transition:opacity .3s ease-in-out;-ms-transition:opacity .3s ease-in-out;-webkit-transition:opacity .3s ease-in-out;transition:opacity .3s ease-in-out;position:absolute;background:rgba(0,0,0,.8);color:#fff !important;font-family:"arial",serif;font-size:12px;padding:10px;z-index:999999;bottom:100%;margin-bottom:5px;left:-17px;right:0;-moz-border-radius:5px;-webkit-border-radius:5px;border-radius:5px;-moz-box-shadow:1px 1px 1px rgba(0,0,0,.2);-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.2);box-shadow:1px 1px 1px rgba(0,0,0,.2);line-height:1.3em;font-weight:bold;text-align:left;text-transform:none !important}.rtl .fs-tooltip-trigger .fs-tooltip{text-align:right;left:auto;right:-17px}.fs-tooltip-trigger .fs-tooltip::after{content:" ";display:block;width:0;height:0;border-style:solid;border-width:5px 5px 0 5px;border-color:rgba(0,0,0,.8) transparent transparent transparent;position:absolute;top:100%;left:21px}.rtl .fs-tooltip-trigger .fs-tooltip::after{right:21px;left:auto}.fs-tooltip-trigger:hover .fs-tooltip{visibility:visible;opacity:1}.fs-permissions .fs-permission.fs-disabled{color:#aaa}.fs-permissions .fs-permission.fs-disabled .fs-permission-description span{color:#aaa}.fs-permissions .fs-permission .fs-switch-feedback{position:absolute;right:15px;top:52px}.fs-permissions ul{height:0;overflow:hidden;margin:0}.fs-permissions ul li{padding:17px 15px;margin:0;position:relative}.fs-permissions ul li>i.dashicons{float:left;font-size:30px;width:30px;height:30px;padding:5px}.fs-permissions ul li .fs-switch{float:right}.fs-permissions ul li .fs-permission-description{margin-left:55px}.fs-permissions ul li .fs-permission-description span{font-size:14px;font-weight:500;color:#23282d}.fs-permissions ul li .fs-permission-description .fs-tooltip{font-size:13px;font-weight:bold}.fs-permissions ul li .fs-permission-description .fs-tooltip-trigger .dashicons{margin:-1px 2px 0 2px}.fs-permissions ul li .fs-permission-description p{margin:2px 0 0 0}.fs-permissions.fs-open{background:#fff}.fs-permissions.fs-open ul{overflow:initial;height:auto;margin:20px 0 10px 0}.fs-permissions .fs-switch-feedback .fs-ajax-spinner{margin-right:10px}.fs-permissions .fs-switch-feedback.success{color:#71ae00}.rtl .fs-permissions .fs-switch-feedback{right:auto;left:15px}.rtl .fs-permissions .fs-switch-feedback .fs-ajax-spinner{margin-left:10px;margin-right:0}.rtl .fs-permissions ul li .fs-permission-description{margin-right:55px;margin-left:0}.rtl .fs-permissions ul li .fs-switch{float:left}.rtl .fs-permissions ul li i.dashicons{float:right}
+#fs_connect{margin:60px auto 20px;width:484px}#fs_connect a{color:inherit}#fs_connect a:not(.button){text-decoration:underline}#fs_connect .fs-box-container{background:#f0f0f1;border-radius:3px;box-shadow:0 1px 2px rgba(0,0,0,.3);overflow:hidden;padding-top:40px}@media screen and (max-width:483px){#fs_connect{margin:30px 0 0 -10px;width:auto}#fs_connect .fs-box-container{box-shadow:none}}#fs_connect .fs-content{background:#fff;padding:30px 20px}#fs_connect .fs-content .fs-error{background:snow;border:1px solid #d3135a;box-shadow:0 1px 1px 0 rgba(0,0,0,.1);color:#d3135a;margin-bottom:10px;padding:5px;text-align:center}#fs_connect .fs-content h2{line-height:1.5em}#fs_connect .fs-content p{font-size:1.2em;margin:0;padding:0}#fs_connect .fs-license-key-container{margin:10px auto 0;position:relative;width:280px}#fs_connect .fs-license-key-container input{width:100%}#fs_connect .fs-license-key-container .dashicons{position:absolute;right:5px;top:5px}#fs_connect.require-license-key .fs-content{padding-bottom:10px}#fs_connect.require-license-key .fs-actions{border-top:none}#fs_connect.require-license-key .fs-sites-list-container td{cursor:pointer}#fs_connect #delegate_to_site_admins{border-bottom:1px dashed;float:right;font-weight:700;height:26px;line-height:37px;margin-right:15px;text-decoration:none;vertical-align:middle}#fs_connect #delegate_to_site_admins.rtl{margin-left:15px;margin-right:0}#fs_connect .fs-actions{background:#fff;border-color:#f1f1f1;border-style:solid;border-width:1px 0;padding:10px 20px}#fs_connect .fs-actions .button{font-size:16px;height:37px;line-height:35px;margin-bottom:0;padding:0 10px 1px}#fs_connect .fs-actions .button .dashicons{font-size:37px;margin-left:-8px;margin-right:12px}#fs_connect .fs-actions .button.button-primary{padding-left:15px;padding-right:15px}#fs_connect .fs-actions .button.button-primary:after{content:" ➜"}#fs_connect .fs-actions .button.button-primary.fs-loading:after{content:""}#fs_connect .fs-actions .button.button-secondary{float:right}#fs_connect.fs-anonymous-disabled .fs-actions .button.button-primary{width:100%}#fs_connect .fs-permissions{background:#fff;padding:10px 20px;transition:background .5s ease}#fs_connect .fs-permissions .fs-license-sync-disclaimer{margin-top:0;text-align:center}#fs_connect .fs-permissions>.fs-trigger{display:block;font-size:.9em;text-align:center;text-decoration:none}#fs_connect .fs-permissions>.fs-trigger .fs-arrow:after{content:"→";display:inline-block;width:20px}#fs_connect .fs-permissions.fs-open>.fs-trigger .fs-arrow:after{content:"↓"!important}#fs_connect .fs-permissions ul li{padding-left:0;padding-right:0}@media screen and (max-width:483px){#fs_connect .fs-permissions ul{height:auto;margin:20px}}#fs_connect .fs-freemium-licensing{background:#777;color:#fff;padding:8px}#fs_connect .fs-freemium-licensing p{display:block;margin:0;padding:0;text-align:center}#fs_connect .fs-freemium-licensing a{color:inherit;text-decoration:underline}#fs_connect .fs-header{height:0;line-height:0;padding:0;position:relative}#fs_connect .fs-header .fs-connect-logo,#fs_connect .fs-header .fs-site-icon{border-radius:50%;position:absolute;top:-8px}#fs_connect .fs-header .fs-site-icon{left:152px}#fs_connect .fs-header .fs-connect-logo{right:152px}#fs_connect .fs-header .fs-site-icon,#fs_connect .fs-header img,#fs_connect .fs-header object{border-radius:50%;height:50px;width:50px}#fs_connect .fs-header .fs-plugin-icon{border-radius:50%;left:50%;margin-left:-44px;overflow:hidden;position:absolute;top:-23px;z-index:1}#fs_connect .fs-header .fs-plugin-icon,#fs_connect .fs-header .fs-plugin-icon img{height:80px;width:80px}#fs_connect .fs-header .dashicons-wordpress-alt{background:#01749a;border-radius:50%;color:#fff;font-size:40px;height:40px;padding:5px;width:40px}#fs_connect .fs-header .dashicons-plus{color:#bbb;font-size:30px;margin-top:-10px;position:absolute;top:50%}#fs_connect .fs-header .dashicons-plus.fs-first{left:28%}#fs_connect .fs-header .dashicons-plus.fs-second{left:65%}#fs_connect .fs-header .fs-connect-logo,#fs_connect .fs-header .fs-plugin-icon,#fs_connect .fs-header .fs-site-icon{background:#fff;border:1px solid #efefef;padding:3px}#fs_connect .fs-terms{font-size:.85em;padding:10px 5px;text-align:center}#fs_connect .fs-terms,#fs_connect .fs-terms a{color:#999}#fs_connect .fs-terms a{text-decoration:none}.fs-multisite-options-container{border:1px solid #ccc;margin-top:20px;padding:5px}.fs-multisite-options-container a{text-decoration:none}.fs-multisite-options-container a:focus{box-shadow:none}.fs-multisite-options-container a.selected{font-weight:700}.fs-multisite-options-container.fs-apply-on-all-sites{border:0;padding:0}.fs-multisite-options-container.fs-apply-on-all-sites .fs-all-sites-options{border-spacing:0}.fs-multisite-options-container.fs-apply-on-all-sites .fs-all-sites-options td:not(:first-child){display:none}.fs-multisite-options-container .fs-sites-list-container{display:none;overflow:auto}.fs-multisite-options-container .fs-sites-list-container table td{border-top:1px solid #ccc;padding:4px 2px}#fs_marketing_optin{border:1px solid #ccc;display:none;line-height:1.5em;margin-top:10px;padding:10px}#fs_marketing_optin .fs-message{display:block;font-size:1.05em;font-weight:600;margin-bottom:5px}#fs_marketing_optin.error{background:#fee;border:1px solid #d3135a}#fs_marketing_optin.error .fs-message{color:#d3135a}#fs_marketing_optin .fs-input-container{margin-top:5px}#fs_marketing_optin .fs-input-container label{display:block;margin-top:5px}#fs_marketing_optin .fs-input-container label input{float:left;margin:1px 0 0}#fs_marketing_optin .fs-input-container label:first-child{display:block;margin-bottom:2px}#fs_marketing_optin .fs-input-label{display:block;margin-left:20px}#fs_marketing_optin .fs-input-label .underlined{text-decoration:underline}.rtl #fs_marketing_optin .fs-input-container label input{float:right}.rtl #fs_marketing_optin .fs-input-label{margin-left:0;margin-right:20px}.rtl #fs_connect{border-radius:3px}.rtl #fs_connect .fs-actions{background:#c0c7ca;padding:10px 20px}.rtl #fs_connect .fs-actions .button .dashicons{font-size:37px;margin-left:-8px;margin-right:12px}.rtl #fs_connect .fs-actions .button.button-primary:after{content:" »"}.rtl #fs_connect .fs-actions .button.button-primary.fs-loading:after{content:""}.rtl #fs_connect .fs-actions .button.button-secondary{float:left}.rtl #fs_connect .fs-header .fs-site-icon{left:auto;right:20px}.rtl #fs_connect .fs-header .fs-connect-logo{left:20px;right:auto}.rtl #fs_connect .fs-permissions>.fs-trigger .fs-arrow:after{content:"←"}#fs_theme_connect_wrapper{background:rgba(0,0,0,.75);height:100%;overflow-y:auto;position:fixed;text-align:center;top:0;width:100%;z-index:99990}#fs_theme_connect_wrapper:before{content:"";display:inline-block;height:100%;vertical-align:middle}#fs_theme_connect_wrapper>button.close{background-color:transparent;border:0;color:#fff;cursor:pointer;height:40px;position:absolute;right:0;top:32px;width:40px}#fs_theme_connect_wrapper #fs_connect{display:inline-block;margin-bottom:20px;margin-top:0;text-align:left;top:0;vertical-align:middle}#fs_theme_connect_wrapper #fs_connect .fs-terms,#fs_theme_connect_wrapper #fs_connect .fs-terms a{color:#c5c5c5}.wp-pointer-content #fs_connect{box-shadow:none;margin:0}.fs-opt-in-pointer .wp-pointer-content{padding:0}.fs-opt-in-pointer.wp-pointer-top .wp-pointer-arrow{border-bottom-color:#dfdfdf}.fs-opt-in-pointer.wp-pointer-top .wp-pointer-arrow-inner{border-bottom-color:#fafafa}.fs-opt-in-pointer.wp-pointer-bottom .wp-pointer-arrow{border-top-color:#dfdfdf}.fs-opt-in-pointer.wp-pointer-bottom .wp-pointer-arrow-inner{border-top-color:#fafafa}.fs-opt-in-pointer.wp-pointer-left .wp-pointer-arrow{border-right-color:#dfdfdf}.fs-opt-in-pointer.wp-pointer-left .wp-pointer-arrow-inner{border-right-color:#fafafa}.fs-opt-in-pointer.wp-pointer-right .wp-pointer-arrow{border-left-color:#dfdfdf}.fs-opt-in-pointer.wp-pointer-right .wp-pointer-arrow-inner{border-left-color:#fafafa}#license_issues_link{display:block;font-size:.9em;margin-top:10px;text-align:center}.fs-tooltip-trigger{position:relative}.fs-tooltip-trigger:not(a){cursor:help}.fs-tooltip-trigger .dashicons{float:none!important}.fs-tooltip-trigger .fs-tooltip{background:rgba(0,0,0,.8);border-radius:5px;bottom:100%;box-shadow:1px 1px 1px rgba(0,0,0,.2);color:#fff!important;font-family:arial,serif;font-size:12px;font-weight:700;left:-17px;line-height:1.3em;margin-bottom:5px;opacity:0;padding:10px;position:absolute;right:0;text-align:left;text-transform:none!important;transition:opacity .3s ease-in-out;visibility:hidden;z-index:999999}.rtl .fs-tooltip-trigger .fs-tooltip{left:auto;right:-17px;text-align:right}.fs-tooltip-trigger .fs-tooltip:after{border-color:rgba(0,0,0,.8) transparent transparent;border-style:solid;border-width:5px 5px 0;content:" ";display:block;height:0;left:21px;position:absolute;top:100%;width:0}.rtl .fs-tooltip-trigger .fs-tooltip:after{left:auto;right:21px}.fs-tooltip-trigger:hover .fs-tooltip{opacity:1;visibility:visible}.fs-permissions .fs-permission.fs-disabled,.fs-permissions .fs-permission.fs-disabled .fs-permission-description span{color:#aaa}.fs-permissions .fs-permission .fs-switch-feedback{position:absolute;right:15px;top:52px}.fs-permissions ul{height:0;margin:0;overflow:hidden}.fs-permissions ul li{margin:0;padding:17px 15px;position:relative}.fs-permissions ul li>i.dashicons{float:left;font-size:30px;height:30px;padding:5px;width:30px}.fs-permissions ul li .fs-switch{float:right}.fs-permissions ul li .fs-permission-description{margin-left:55px}.fs-permissions ul li .fs-permission-description span{color:#23282d;font-size:14px;font-weight:500}.fs-permissions ul li .fs-permission-description .fs-tooltip{font-size:13px;font-weight:700}.fs-permissions ul li .fs-permission-description .fs-tooltip-trigger .dashicons{margin:-1px 2px 0}.fs-permissions ul li .fs-permission-description p{margin:2px 0 0}.fs-permissions.fs-open{background:#fff}.fs-permissions.fs-open ul{height:auto;margin:20px 0 10px;overflow:initial}.fs-permissions .fs-switch-feedback .fs-ajax-spinner{margin-right:10px}.fs-permissions .fs-switch-feedback.success{color:#71ae00}.rtl .fs-permissions .fs-switch-feedback{left:15px;right:auto}.rtl .fs-permissions .fs-switch-feedback .fs-ajax-spinner{margin-left:10px;margin-right:0}.rtl .fs-permissions ul li .fs-permission-description{margin-left:0;margin-right:55px}.rtl .fs-permissions ul li .fs-switch{float:left}.rtl .fs-permissions ul li i.dashicons{float:right}
\ No newline at end of file
diff --git a/freemius/assets/css/admin/debug.css b/freemius/assets/css/admin/debug.css
index 3a2aadf..84d9404 100644
--- a/freemius/assets/css/admin/debug.css
+++ b/freemius/assets/css/admin/debug.css
@@ -1 +1 @@
-label.fs-tag,span.fs-tag{background:#ffba00;color:#fff;display:inline-block;border-radius:3px;padding:5px;font-size:11px;line-height:11px;vertical-align:baseline}label.fs-tag.fs-warn,span.fs-tag.fs-warn{background:#ffba00}label.fs-tag.fs-info,span.fs-tag.fs-info{background:#00a0d2}label.fs-tag.fs-success,span.fs-tag.fs-success{background:#46b450}label.fs-tag.fs-error,span.fs-tag.fs-error{background:#dc3232}.fs-switch-label{font-size:20px;line-height:31px;margin:0 5px}#fs_log_book table{font-family:Consolas,Monaco,monospace;font-size:12px}#fs_log_book table th{color:#ccc}#fs_log_book table tr{background:#232525}#fs_log_book table tr.alternate{background:#2b2b2b}#fs_log_book table tr td.fs-col--logger{color:#5a7435}#fs_log_book table tr td.fs-col--type{color:#ffc861}#fs_log_book table tr td.fs-col--function{color:#a7b7b1;font-weight:bold}#fs_log_book table tr td.fs-col--message,#fs_log_book table tr td.fs-col--message a{color:#9a73ac !important}#fs_log_book table tr td.fs-col--file{color:#d07922}#fs_log_book table tr td.fs-col--timestamp{color:#6596be}
+label.fs-tag,span.fs-tag{background:#ffba00;border-radius:3px;color:#fff;display:inline-block;font-size:11px;line-height:11px;padding:5px;vertical-align:baseline}label.fs-tag.fs-warn,span.fs-tag.fs-warn{background:#ffba00}label.fs-tag.fs-info,span.fs-tag.fs-info{background:#00a0d2}label.fs-tag.fs-success,span.fs-tag.fs-success{background:#46b450}label.fs-tag.fs-error,span.fs-tag.fs-error{background:#dc3232}.fs-switch-label{font-size:20px;line-height:31px;margin:0 5px}#fs_log_book table{font-family:Consolas,Monaco,monospace;font-size:12px}#fs_log_book table th{color:#ccc}#fs_log_book table tr{background:#232525}#fs_log_book table tr.alternate{background:#2b2b2b}#fs_log_book table tr td.fs-col--logger{color:#5a7435}#fs_log_book table tr td.fs-col--type{color:#ffc861}#fs_log_book table tr td.fs-col--function{color:#a7b7b1;font-weight:700}#fs_log_book table tr td.fs-col--message,#fs_log_book table tr td.fs-col--message a{color:#9a73ac!important}#fs_log_book table tr td.fs-col--file{color:#d07922}#fs_log_book table tr td.fs-col--timestamp{color:#6596be}
\ No newline at end of file
diff --git a/freemius/assets/css/admin/dialog-boxes.css b/freemius/assets/css/admin/dialog-boxes.css
index de7f829..c16515a 100644
--- a/freemius/assets/css/admin/dialog-boxes.css
+++ b/freemius/assets/css/admin/dialog-boxes.css
@@ -1 +1 @@
-.fs-modal{position:fixed;overflow:auto;height:100%;width:100%;top:0;z-index:100000;display:none;background:rgba(0,0,0,.6)}@media(min-width: 961px){.fs-modal{padding-left:160px}.rtl .fs-modal{padding-left:0;padding-right:160px}}.fs-modal .dashicons{vertical-align:middle}.fs-modal .fs-modal-dialog{background:transparent;position:absolute;left:50%;margin-left:-298px;padding-bottom:30px;top:-100%;z-index:100001;width:596px}@media(max-width: 650px){.fs-modal .fs-modal-dialog{margin-left:-50%;box-sizing:border-box;padding-left:10px;padding-right:10px;width:100%}.fs-modal .fs-modal-dialog .fs-modal-panel>h3>strong{font-size:1.3em}}.fs-modal.active{display:block}.fs-modal.active:before{display:block}.fs-modal.active .fs-modal-dialog{top:10%}.fs-modal.fs-success .fs-modal-header{border-bottom-color:#46b450}.fs-modal.fs-success .fs-modal-body{background-color:#f7fff7}.fs-modal.fs-warn .fs-modal-header{border-bottom-color:#ffb900}.fs-modal.fs-warn .fs-modal-body{background-color:#fff8e5}.fs-modal.fs-error .fs-modal-header{border-bottom-color:#dc3232}.fs-modal.fs-error .fs-modal-body{background-color:#ffeaea}.fs-modal .fs-modal-body,.fs-modal .fs-modal-footer{border:0;background:#fefefe;padding:20px}.fs-modal .fs-modal-header{border-bottom:#eee solid 1px;background:#fbfbfb;padding:15px 20px;position:relative;margin-bottom:-10px}.fs-modal .fs-modal-header h4{margin:0;padding:0;text-transform:uppercase;font-size:1.2em;font-weight:bold;color:#cacaca;text-shadow:1px 1px 1px #fff;letter-spacing:.6px;-webkit-font-smoothing:antialiased}.fs-modal .fs-modal-header .fs-close{position:absolute;right:10px;top:12px;cursor:pointer;color:#bbb;-moz-border-radius:20px;-webkit-border-radius:20px;border-radius:20px;padding:3px;-moz-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;-ms-transition:all .2s ease-in-out;-webkit-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.fs-modal .fs-modal-header .fs-close:hover{color:#fff;background:#aaa}.fs-modal .fs-modal-header .fs-close .dashicons,.fs-modal .fs-modal-header .fs-close:hover .dashicons{text-decoration:none}.fs-modal .fs-modal-body{border-bottom:0}.fs-modal .fs-modal-body p{font-size:14px}.fs-modal .fs-modal-body h2{font-size:20px;line-height:1.5em}.fs-modal .fs-modal-body>div{margin-top:10px}.fs-modal .fs-modal-body>div h2{font-weight:bold;font-size:20px;margin-top:0}.fs-modal .fs-modal-footer{border-top:#eee solid 1px;text-align:right}.fs-modal .fs-modal-footer>.button{margin:0 7px}.fs-modal .fs-modal-footer>.button:last-of-type{margin:0}.fs-modal .fs-modal-panel>.notice.inline{margin:0;display:none}.fs-modal .fs-modal-panel:not(.active){display:none}.rtl .fs-modal .fs-modal-header .fs-close{right:auto;left:20px}.rtl .fs-modal .fs-modal-footer{text-align:left}body.has-fs-modal{overflow:hidden}.fs-modal.fs-modal-deactivation-feedback .reason-input,.fs-modal.fs-modal-deactivation-feedback .internal-message{margin:3px 0 3px 22px}.fs-modal.fs-modal-deactivation-feedback .reason-input input,.fs-modal.fs-modal-deactivation-feedback .reason-input textarea,.fs-modal.fs-modal-deactivation-feedback .internal-message input,.fs-modal.fs-modal-deactivation-feedback .internal-message textarea{width:100%}.fs-modal.fs-modal-deactivation-feedback li.reason.has-internal-message .internal-message{border:1px solid #ccc;padding:7px;display:none}@media(max-width: 650px){.fs-modal.fs-modal-deactivation-feedback li.reason li.reason{margin-bottom:10px}.fs-modal.fs-modal-deactivation-feedback li.reason li.reason .reason-input,.fs-modal.fs-modal-deactivation-feedback li.reason li.reason .internal-message{margin-left:29px}.fs-modal.fs-modal-deactivation-feedback li.reason li.reason label{display:table}.fs-modal.fs-modal-deactivation-feedback li.reason li.reason label>span{display:table-cell;font-size:1.3em}}.fs-modal.fs-modal-deactivation-feedback .anonymous-feedback-label,.fs-modal.fs-modal-deactivation-feedback .feedback-from-snooze-label{float:left;line-height:30px}.rtl .fs-modal.fs-modal-deactivation-feedback .anonymous-feedback-label,.rtl .fs-modal.fs-modal-deactivation-feedback .feedback-from-snooze-label{float:right}.fs-modal.fs-modal-deactivation-feedback .fs-modal-panel{margin-top:0 !important}.fs-modal.fs-modal-deactivation-feedback .fs-modal-panel h3{margin-top:0;line-height:1.5em}#the-list .deactivate>.fs-slug{display:none}.fs-modal.fs-modal-subscription-cancellation .fs-price-increase-warning{color:red;font-weight:bold;padding:0 25px;margin-bottom:0}.fs-modal.fs-modal-subscription-cancellation ul.subscription-actions label input{float:left;top:5px;position:relative}.rtl .fs-modal.fs-modal-subscription-cancellation ul.subscription-actions label input{float:right}.fs-modal.fs-modal-subscription-cancellation ul.subscription-actions label span{display:block;margin-left:24px}.rtl .fs-modal.fs-modal-subscription-cancellation ul.subscription-actions label span{margin-left:0;margin-right:24px}.fs-modal.fs-modal-license-activation .fs-modal-body input.fs-license-key{width:100%}.fs-license-options-container table,.fs-license-options-container table select,.fs-license-options-container table .fs-available-license-key{width:100%}.fs-license-options-container table td:first-child{width:1%}.fs-license-options-container table .fs-other-license-key-container label{position:relative;top:6px;float:left;margin-right:5px}.fs-license-options-container table .fs-other-license-key-container div{overflow:hidden;width:auto;height:30px;display:block;top:2px;position:relative}.fs-license-options-container table .fs-other-license-key-container div input{margin:0}.fs-sites-list-container td{cursor:pointer}.fs-modal.fs-modal-user-change .fs-modal-body input#fs_other_email_address{width:100%}.fs-user-change-options-container table{width:100%;border-collapse:collapse}.fs-user-change-options-container table tr{display:block;margin-bottom:2px}.fs-user-change-options-container table .fs-email-address-container td{display:inline-block}.fs-user-change-options-container table .fs-email-address-container input[type=radio]{margin-bottom:0;margin-top:0}.fs-user-change-options-container table .fs-other-email-address-container{width:100%}.fs-user-change-options-container table .fs-other-email-address-container>div{display:table;width:100%}.fs-user-change-options-container table .fs-other-email-address-container>div label,.fs-user-change-options-container table .fs-other-email-address-container>div>div{display:table-cell}.fs-user-change-options-container table .fs-other-email-address-container>div label{width:1%;padding-left:3px;padding-right:3px}.fs-user-change-options-container table .fs-other-email-address-container>div>div{width:auto}.fs-user-change-options-container table .fs-other-email-address-container>div>div input{width:100%}.fs-modal.fs-modal-developer-license-debug-mode .fs-modal-body input.fs-license-or-user-key{width:100%}.fs-multisite-options-container{margin-top:20px;border:1px solid #ccc;padding:5px}.fs-multisite-options-container a{text-decoration:none}.fs-multisite-options-container a:focus{box-shadow:none}.fs-multisite-options-container a.selected{font-weight:bold}.fs-multisite-options-container.fs-apply-on-all-sites{border:0 none;padding:0}.fs-multisite-options-container.fs-apply-on-all-sites .fs-all-sites-options{border-spacing:0}.fs-multisite-options-container.fs-apply-on-all-sites .fs-all-sites-options td:not(:first-child){display:none}.fs-multisite-options-container .fs-sites-list-container{display:none;overflow:auto}.fs-multisite-options-container .fs-sites-list-container table td{border-top:1px solid #ccc;padding:4px 2px}.fs-modal.fs-modal-license-key-resend .email-address-container{overflow:hidden;padding-right:2px}.fs-modal.fs-modal-license-key-resend.fs-freemium input.email-address{width:300px}.fs-modal.fs-modal-license-key-resend.fs-freemium label{display:block;margin-bottom:10px}.fs-modal.fs-modal-license-key-resend.fs-premium input.email-address{width:100%}.fs-modal.fs-modal-license-key-resend.fs-premium .button-container{float:right;margin-left:7px}@media(max-width: 650px){.fs-modal.fs-modal-license-key-resend.fs-premium .button-container{margin-top:2px}}.rtl .fs-modal.fs-modal-license-key-resend .fs-modal-body .input-container>.email-address-container{padding-left:2px;padding-right:0}.rtl .fs-modal.fs-modal-license-key-resend .fs-modal-body .button-container{float:left;margin-right:7px;margin-left:0}a.show-license-resend-modal{margin-top:4px;display:inline-block}.fs-modal.fs-modal-email-address-update .fs-modal-body input[type=text]{width:100%}.fs-modal.fs-modal-email-address-update p{margin-bottom:0}.fs-modal.fs-modal-email-address-update ul{margin:1em .5em}.fs-modal.fs-modal-email-address-update ul li label span{float:left;margin-top:0}.fs-modal.fs-modal-email-address-update ul li label span:last-child{display:block;float:none;margin-left:20px}.fs-ajax-loader{position:relative;width:170px;height:20px;margin:auto}.fs-ajax-loader .fs-ajax-loader-bar{position:absolute;top:0;background-color:#0074a3;width:20px;height:20px;-webkit-animation-name:bounce_ajaxLoader;-moz-animation-name:bounce_ajaxLoader;-ms-animation-name:bounce_ajaxLoader;-o-animation-name:bounce_ajaxLoader;animation-name:bounce_ajaxLoader;-webkit-animation-duration:1.5s;-moz-animation-duration:1.5s;-ms-animation-duration:1.5s;-o-animation-duration:1.5s;animation-duration:1.5s;animation-iteration-count:infinite;-o-animation-iteration-count:infinite;-ms-animation-iteration-count:infinite;-webkit-animation-iteration-count:infinite;-moz-animation-iteration-count:infinite;-webkit-animation-direction:normal;-moz-animation-direction:normal;-ms-animation-direction:normal;-o-animation-direction:normal;animation-direction:normal;-moz-transform:.3;-o-transform:.3;-ms-transform:.3;-webkit-transform:.3;transform:.3}.fs-ajax-loader .fs-ajax-loader-bar-1{left:0px;animation-delay:0.6s;-o-animation-delay:0.6s;-ms-animation-delay:0.6s;-webkit-animation-delay:0.6s;-moz-animation-delay:0.6s}.fs-ajax-loader .fs-ajax-loader-bar-2{left:19px;animation-delay:0.75s;-o-animation-delay:0.75s;-ms-animation-delay:0.75s;-webkit-animation-delay:0.75s;-moz-animation-delay:0.75s}.fs-ajax-loader .fs-ajax-loader-bar-3{left:38px;animation-delay:0.9s;-o-animation-delay:0.9s;-ms-animation-delay:0.9s;-webkit-animation-delay:0.9s;-moz-animation-delay:0.9s}.fs-ajax-loader .fs-ajax-loader-bar-4{left:57px;animation-delay:1.05s;-o-animation-delay:1.05s;-ms-animation-delay:1.05s;-webkit-animation-delay:1.05s;-moz-animation-delay:1.05s}.fs-ajax-loader .fs-ajax-loader-bar-5{left:76px;animation-delay:1.2s;-o-animation-delay:1.2s;-ms-animation-delay:1.2s;-webkit-animation-delay:1.2s;-moz-animation-delay:1.2s}.fs-ajax-loader .fs-ajax-loader-bar-6{left:95px;animation-delay:1.35s;-o-animation-delay:1.35s;-ms-animation-delay:1.35s;-webkit-animation-delay:1.35s;-moz-animation-delay:1.35s}.fs-ajax-loader .fs-ajax-loader-bar-7{left:114px;animation-delay:1.5s;-o-animation-delay:1.5s;-ms-animation-delay:1.5s;-webkit-animation-delay:1.5s;-moz-animation-delay:1.5s}.fs-ajax-loader .fs-ajax-loader-bar-8{left:133px;animation-delay:1.65s;-o-animation-delay:1.65s;-ms-animation-delay:1.65s;-webkit-animation-delay:1.65s;-moz-animation-delay:1.65s}@-moz-keyframes bounce_ajaxLoader{0%{-moz-transform:scale(1);-o-transform:scale(1);-ms-transform:scale(1);-webkit-transform:scale(1);transform:scale(1);background-color:#0074a3}100%{-moz-transform:scale(0.3);-o-transform:scale(0.3);-ms-transform:scale(0.3);-webkit-transform:scale(0.3);transform:scale(0.3);background-color:#fff}}@-ms-keyframes bounce_ajaxLoader{0%{-moz-transform:scale(1);-o-transform:scale(1);-ms-transform:scale(1);-webkit-transform:scale(1);transform:scale(1);background-color:#0074a3}100%{-moz-transform:scale(0.3);-o-transform:scale(0.3);-ms-transform:scale(0.3);-webkit-transform:scale(0.3);transform:scale(0.3);background-color:#fff}}@-o-keyframes bounce_ajaxLoader{0%{-moz-transform:scale(1);-o-transform:scale(1);-ms-transform:scale(1);-webkit-transform:scale(1);transform:scale(1);background-color:#0074a3}100%{-moz-transform:scale(0.3);-o-transform:scale(0.3);-ms-transform:scale(0.3);-webkit-transform:scale(0.3);transform:scale(0.3);background-color:#fff}}@-webkit-keyframes bounce_ajaxLoader{0%{-moz-transform:scale(1);-o-transform:scale(1);-ms-transform:scale(1);-webkit-transform:scale(1);transform:scale(1);background-color:#0074a3}100%{-moz-transform:scale(0.3);-o-transform:scale(0.3);-ms-transform:scale(0.3);-webkit-transform:scale(0.3);transform:scale(0.3);background-color:#fff}}@keyframes bounce_ajaxLoader{0%{-moz-transform:scale(1);-o-transform:scale(1);-ms-transform:scale(1);-webkit-transform:scale(1);transform:scale(1);background-color:#0074a3}100%{-moz-transform:scale(0.3);-o-transform:scale(0.3);-ms-transform:scale(0.3);-webkit-transform:scale(0.3);transform:scale(0.3);background-color:#fff}}.fs-modal-auto-install #request-filesystem-credentials-form h2,.fs-modal-auto-install #request-filesystem-credentials-form .request-filesystem-credentials-action-buttons{display:none}.fs-modal-auto-install #request-filesystem-credentials-form input[type=password],.fs-modal-auto-install #request-filesystem-credentials-form input[type=email],.fs-modal-auto-install #request-filesystem-credentials-form input[type=text]{-webkit-appearance:none;padding:10px 10px 5px 10px;width:300px;max-width:100%}.fs-modal-auto-install #request-filesystem-credentials-form>div,.fs-modal-auto-install #request-filesystem-credentials-form label,.fs-modal-auto-install #request-filesystem-credentials-form fieldset{width:300px;max-width:100%;margin:0 auto;display:block}.button-primary.warn{box-shadow:0 1px 0 #d2593c;text-shadow:0 -1px 1px #d2593c,1px 0 1px #d2593c,0 1px 1px #d2593c,-1px 0 1px #d2593c;background:#f56a48;border-color:#ec6544 #d2593c #d2593c}.button-primary.warn:hover{background:#fd6d4a;border-color:#d2593c}.button-primary.warn:focus{box-shadow:0 1px 0 #dd6041,0 0 2px 1px #e4a796}.button-primary.warn:active{background:#dd6041;border-color:#d2593c;box-shadow:inset 0 2px 0 #d2593c}.button-primary.warn.disabled{color:#f5b3a1 !important;background:#e76444 !important;border-color:#d85e40 !important;text-shadow:0 -1px 0 rgba(0,0,0,.1) !important}
+.fs-modal{background:rgba(0,0,0,.6);display:none;height:100%;overflow:auto;position:fixed;top:0;width:100%;z-index:100000}@media(min-width:961px){.fs-modal{padding-left:160px}.rtl .fs-modal{padding-left:0;padding-right:160px}}.fs-modal .dashicons{vertical-align:middle}.fs-modal .fs-modal-dialog{background:transparent;left:50%;margin-left:-298px;padding-bottom:30px;position:absolute;top:-100%;width:596px;z-index:100001}@media(max-width:650px){.fs-modal .fs-modal-dialog{box-sizing:border-box;margin-left:-50%;padding-left:10px;padding-right:10px;width:100%}.fs-modal .fs-modal-dialog .fs-modal-panel>h3>strong{font-size:1.3em}}.fs-modal.active,.fs-modal.active:before{display:block}.fs-modal.active .fs-modal-dialog{top:10%}.fs-modal.fs-success .fs-modal-header{border-bottom-color:#46b450}.fs-modal.fs-success .fs-modal-body{background-color:#f7fff7}.fs-modal.fs-warn .fs-modal-header{border-bottom-color:#ffb900}.fs-modal.fs-warn .fs-modal-body{background-color:#fff8e5}.fs-modal.fs-error .fs-modal-header{border-bottom-color:#dc3232}.fs-modal.fs-error .fs-modal-body{background-color:#ffeaea}.fs-modal .fs-modal-body,.fs-modal .fs-modal-footer{background:#fefefe;border:0;padding:20px}.fs-modal .fs-modal-header{background:#fbfbfb;border-bottom:1px solid #eee;margin-bottom:-10px;padding:15px 20px;position:relative}.fs-modal .fs-modal-header h4{color:#cacaca;font-size:1.2em;font-weight:700;letter-spacing:.6px;margin:0;padding:0;text-shadow:1px 1px 1px #fff;text-transform:uppercase;-webkit-font-smoothing:antialiased}.fs-modal .fs-modal-header .fs-close{border-radius:20px;color:#bbb;cursor:pointer;padding:3px;position:absolute;right:10px;top:12px;transition:all .2s ease-in-out}.fs-modal .fs-modal-header .fs-close:hover{background:#aaa;color:#fff}.fs-modal .fs-modal-header .fs-close .dashicons,.fs-modal .fs-modal-header .fs-close:hover .dashicons{text-decoration:none}.fs-modal .fs-modal-body{border-bottom:0}.fs-modal .fs-modal-body p{font-size:14px}.fs-modal .fs-modal-body h2{font-size:20px;line-height:1.5em}.fs-modal .fs-modal-body>div{margin-top:10px}.fs-modal .fs-modal-body>div h2{font-size:20px;font-weight:700;margin-top:0}.fs-modal .fs-modal-footer{border-top:1px solid #eee;text-align:right}.fs-modal .fs-modal-footer>.button{margin:0 7px}.fs-modal .fs-modal-footer>.button:last-of-type{margin:0}.fs-modal .fs-modal-panel>.notice.inline{display:none;margin:0}.fs-modal .fs-modal-panel:not(.active){display:none}.rtl .fs-modal .fs-modal-header .fs-close{left:20px;right:auto}.rtl .fs-modal .fs-modal-footer{text-align:left}body.has-fs-modal{overflow:hidden}.fs-modal.fs-modal-deactivation-feedback .internal-message,.fs-modal.fs-modal-deactivation-feedback .reason-input{margin:3px 0 3px 22px}.fs-modal.fs-modal-deactivation-feedback .internal-message input,.fs-modal.fs-modal-deactivation-feedback .internal-message textarea,.fs-modal.fs-modal-deactivation-feedback .reason-input input,.fs-modal.fs-modal-deactivation-feedback .reason-input textarea{width:100%}.fs-modal.fs-modal-deactivation-feedback li.reason.has-internal-message .internal-message{border:1px solid #ccc;display:none;padding:7px}@media(max-width:650px){.fs-modal.fs-modal-deactivation-feedback li.reason li.reason{margin-bottom:10px}.fs-modal.fs-modal-deactivation-feedback li.reason li.reason .internal-message,.fs-modal.fs-modal-deactivation-feedback li.reason li.reason .reason-input{margin-left:29px}.fs-modal.fs-modal-deactivation-feedback li.reason li.reason label{display:table}.fs-modal.fs-modal-deactivation-feedback li.reason li.reason label>span{display:table-cell;font-size:1.3em}}.fs-modal.fs-modal-deactivation-feedback .anonymous-feedback-label,.fs-modal.fs-modal-deactivation-feedback .feedback-from-snooze-label{float:left;line-height:30px}.rtl .fs-modal.fs-modal-deactivation-feedback .anonymous-feedback-label,.rtl .fs-modal.fs-modal-deactivation-feedback .feedback-from-snooze-label{float:right}.fs-modal.fs-modal-deactivation-feedback .fs-modal-panel{margin-top:0!important}.fs-modal.fs-modal-deactivation-feedback .fs-modal-panel h3{line-height:1.5em;margin-top:0}#the-list .deactivate>.fs-slug{display:none}.fs-modal.fs-modal-subscription-cancellation .fs-price-increase-warning{color:red;font-weight:700;margin-bottom:0;padding:0 25px}.fs-modal.fs-modal-subscription-cancellation ul.subscription-actions label input{float:left;position:relative;top:5px}.rtl .fs-modal.fs-modal-subscription-cancellation ul.subscription-actions label input{float:right}.fs-modal.fs-modal-subscription-cancellation ul.subscription-actions label span{display:block;margin-left:24px}.rtl .fs-modal.fs-modal-subscription-cancellation ul.subscription-actions label span{margin-left:0;margin-right:24px}.fs-license-options-container table,.fs-license-options-container table .fs-available-license-key,.fs-license-options-container table select,.fs-modal.fs-modal-license-activation .fs-modal-body input.fs-license-key{width:100%}.fs-license-options-container table td:first-child{width:1%}.fs-license-options-container table .fs-other-license-key-container label{float:left;margin-right:5px;position:relative;top:6px}.fs-license-options-container table .fs-other-license-key-container div{display:block;height:30px;overflow:hidden;position:relative;top:2px;width:auto}.fs-license-options-container table .fs-other-license-key-container div input{margin:0}.fs-sites-list-container td{cursor:pointer}.fs-modal.fs-modal-user-change .fs-modal-body input#fs_other_email_address{width:100%}.fs-user-change-options-container table{border-collapse:collapse;width:100%}.fs-user-change-options-container table tr{display:block;margin-bottom:2px}.fs-user-change-options-container table .fs-email-address-container td{display:inline-block}.fs-user-change-options-container table .fs-email-address-container input[type=radio]{margin-bottom:0;margin-top:0}.fs-user-change-options-container table .fs-other-email-address-container{width:100%}.fs-user-change-options-container table .fs-other-email-address-container>div{display:table;width:100%}.fs-user-change-options-container table .fs-other-email-address-container>div label,.fs-user-change-options-container table .fs-other-email-address-container>div>div{display:table-cell}.fs-user-change-options-container table .fs-other-email-address-container>div label{padding-left:3px;padding-right:3px;width:1%}.fs-user-change-options-container table .fs-other-email-address-container>div>div{width:auto}.fs-modal.fs-modal-developer-license-debug-mode .fs-modal-body input.fs-license-or-user-key,.fs-user-change-options-container table .fs-other-email-address-container>div>div input{width:100%}.fs-multisite-options-container{border:1px solid #ccc;margin-top:20px;padding:5px}.fs-multisite-options-container a{text-decoration:none}.fs-multisite-options-container a:focus{box-shadow:none}.fs-multisite-options-container a.selected{font-weight:700}.fs-multisite-options-container.fs-apply-on-all-sites{border:0;padding:0}.fs-multisite-options-container.fs-apply-on-all-sites .fs-all-sites-options{border-spacing:0}.fs-multisite-options-container.fs-apply-on-all-sites .fs-all-sites-options td:not(:first-child){display:none}.fs-multisite-options-container .fs-sites-list-container{display:none;overflow:auto}.fs-multisite-options-container .fs-sites-list-container table td{border-top:1px solid #ccc;padding:4px 2px}.fs-modal.fs-modal-license-key-resend .email-address-container{overflow:hidden;padding-right:2px}.fs-modal.fs-modal-license-key-resend.fs-freemium input.email-address{width:300px}.fs-modal.fs-modal-license-key-resend.fs-freemium label{display:block;margin-bottom:10px}.fs-modal.fs-modal-license-key-resend.fs-premium input.email-address{width:100%}.fs-modal.fs-modal-license-key-resend.fs-premium .button-container{float:right;margin-left:7px}@media(max-width:650px){.fs-modal.fs-modal-license-key-resend.fs-premium .button-container{margin-top:2px}}.rtl .fs-modal.fs-modal-license-key-resend .fs-modal-body .input-container>.email-address-container{padding-left:2px;padding-right:0}.rtl .fs-modal.fs-modal-license-key-resend .fs-modal-body .button-container{float:left;margin-left:0;margin-right:7px}a.show-license-resend-modal{display:inline-block;margin-top:4px}.fs-modal.fs-modal-email-address-update .fs-modal-body input[type=text]{width:100%}.fs-modal.fs-modal-email-address-update p{margin-bottom:0}.fs-modal.fs-modal-email-address-update ul{margin:1em .5em}.fs-modal.fs-modal-email-address-update ul li label span{float:left;margin-top:0}.fs-modal.fs-modal-email-address-update ul li label span:last-child{display:block;float:none;margin-left:20px}.fs-ajax-loader{height:20px;margin:auto;position:relative;width:170px}.fs-ajax-loader .fs-ajax-loader-bar{animation-direction:normal;animation-duration:1.5s;animation-iteration-count:infinite;-o-animation-iteration-count:infinite;-ms-animation-iteration-count:infinite;-webkit-animation-iteration-count:infinite;-moz-animation-iteration-count:infinite;animation-name:bounce_ajaxLoader;background-color:#0074a3;height:20px;position:absolute;top:0;transform:.3;width:20px}.fs-ajax-loader .fs-ajax-loader-bar-1{animation-delay:.6s;-o-animation-delay:.6s;-ms-animation-delay:.6s;-webkit-animation-delay:.6s;-moz-animation-delay:.6s;left:0}.fs-ajax-loader .fs-ajax-loader-bar-2{animation-delay:.75s;-o-animation-delay:.75s;-ms-animation-delay:.75s;-webkit-animation-delay:.75s;-moz-animation-delay:.75s;left:19px}.fs-ajax-loader .fs-ajax-loader-bar-3{animation-delay:.9s;-o-animation-delay:.9s;-ms-animation-delay:.9s;-webkit-animation-delay:.9s;-moz-animation-delay:.9s;left:38px}.fs-ajax-loader .fs-ajax-loader-bar-4{animation-delay:1.05s;-o-animation-delay:1.05s;-ms-animation-delay:1.05s;-webkit-animation-delay:1.05s;-moz-animation-delay:1.05s;left:57px}.fs-ajax-loader .fs-ajax-loader-bar-5{animation-delay:1.2s;-o-animation-delay:1.2s;-ms-animation-delay:1.2s;-webkit-animation-delay:1.2s;-moz-animation-delay:1.2s;left:76px}.fs-ajax-loader .fs-ajax-loader-bar-6{animation-delay:1.35s;-o-animation-delay:1.35s;-ms-animation-delay:1.35s;-webkit-animation-delay:1.35s;-moz-animation-delay:1.35s;left:95px}.fs-ajax-loader .fs-ajax-loader-bar-7{animation-delay:1.5s;-o-animation-delay:1.5s;-ms-animation-delay:1.5s;-webkit-animation-delay:1.5s;-moz-animation-delay:1.5s;left:114px}.fs-ajax-loader .fs-ajax-loader-bar-8{animation-delay:1.65s;-o-animation-delay:1.65s;-ms-animation-delay:1.65s;-webkit-animation-delay:1.65s;-moz-animation-delay:1.65s;left:133px}@keyframes bounce_ajaxLoader{0%{background-color:#0074a3;transform:scale(1)}to{background-color:#fff;transform:scale(.3)}}.fs-modal-auto-install #request-filesystem-credentials-form .request-filesystem-credentials-action-buttons,.fs-modal-auto-install #request-filesystem-credentials-form h2{display:none}.fs-modal-auto-install #request-filesystem-credentials-form input[type=email],.fs-modal-auto-install #request-filesystem-credentials-form input[type=password],.fs-modal-auto-install #request-filesystem-credentials-form input[type=text]{-webkit-appearance:none;max-width:100%;padding:10px 10px 5px;width:300px}.fs-modal-auto-install #request-filesystem-credentials-form fieldset,.fs-modal-auto-install #request-filesystem-credentials-form label,.fs-modal-auto-install #request-filesystem-credentials-form>div{display:block;margin:0 auto;max-width:100%;width:300px}.button-primary.warn{background:#f56a48;border-color:#ec6544 #d2593c #d2593c;box-shadow:0 1px 0 #d2593c;text-shadow:0 -1px 1px #d2593c,1px 0 1px #d2593c,0 1px 1px #d2593c,-1px 0 1px #d2593c}.button-primary.warn:hover{background:#fd6d4a;border-color:#d2593c}.button-primary.warn:focus{box-shadow:0 1px 0 #dd6041,0 0 2px 1px #e4a796}.button-primary.warn:active{background:#dd6041;border-color:#d2593c;box-shadow:inset 0 2px 0 #d2593c}.button-primary.warn.disabled{background:#e76444!important;border-color:#d85e40!important;color:#f5b3a1!important;text-shadow:0 -1px 0 rgba(0,0,0,.1)!important}
\ No newline at end of file
diff --git a/freemius/assets/css/admin/gdpr-optin-notice.css b/freemius/assets/css/admin/gdpr-optin-notice.css
index fb934ff..836dcd1 100644
--- a/freemius/assets/css/admin/gdpr-optin-notice.css
+++ b/freemius/assets/css/admin/gdpr-optin-notice.css
@@ -1 +1 @@
-.fs-notice[data-id^=gdpr_optin_actions] .underlined{text-decoration:underline}.fs-notice[data-id^=gdpr_optin_actions] ul .button,.fs-notice[data-id^=gdpr_optin_actions] ul .action-description{vertical-align:middle}.fs-notice[data-id^=gdpr_optin_actions] ul .action-description{display:inline-block;margin-left:3px}
+.fs-notice[data-id^=gdpr_optin_actions] .underlined{text-decoration:underline}.fs-notice[data-id^=gdpr_optin_actions] ul .action-description,.fs-notice[data-id^=gdpr_optin_actions] ul .button{vertical-align:middle}.fs-notice[data-id^=gdpr_optin_actions] ul .action-description{display:inline-block;margin-left:3px}
\ No newline at end of file
diff --git a/freemius/assets/css/admin/optout.css b/freemius/assets/css/admin/optout.css
index 6b0d5e2..922c181 100644
--- a/freemius/assets/css/admin/optout.css
+++ b/freemius/assets/css/admin/optout.css
@@ -1 +1 @@
-.fs-tooltip-trigger{position:relative}.fs-tooltip-trigger:not(a){cursor:help}.fs-tooltip-trigger .dashicons{float:none !important}.fs-tooltip-trigger .fs-tooltip{opacity:0;visibility:hidden;-moz-transition:opacity .3s ease-in-out;-o-transition:opacity .3s ease-in-out;-ms-transition:opacity .3s ease-in-out;-webkit-transition:opacity .3s ease-in-out;transition:opacity .3s ease-in-out;position:absolute;background:rgba(0,0,0,.8);color:#fff !important;font-family:"arial",serif;font-size:12px;padding:10px;z-index:999999;bottom:100%;margin-bottom:5px;left:-17px;right:0;-moz-border-radius:5px;-webkit-border-radius:5px;border-radius:5px;-moz-box-shadow:1px 1px 1px rgba(0,0,0,.2);-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.2);box-shadow:1px 1px 1px rgba(0,0,0,.2);line-height:1.3em;font-weight:bold;text-align:left;text-transform:none !important}.rtl .fs-tooltip-trigger .fs-tooltip{text-align:right;left:auto;right:-17px}.fs-tooltip-trigger .fs-tooltip::after{content:" ";display:block;width:0;height:0;border-style:solid;border-width:5px 5px 0 5px;border-color:rgba(0,0,0,.8) transparent transparent transparent;position:absolute;top:100%;left:21px}.rtl .fs-tooltip-trigger .fs-tooltip::after{right:21px;left:auto}.fs-tooltip-trigger:hover .fs-tooltip{visibility:visible;opacity:1}.fs-permissions .fs-permission.fs-disabled{color:#aaa}.fs-permissions .fs-permission.fs-disabled .fs-permission-description span{color:#aaa}.fs-permissions .fs-permission .fs-switch-feedback{position:absolute;right:15px;top:52px}.fs-permissions ul{height:0;overflow:hidden;margin:0}.fs-permissions ul li{padding:17px 15px;margin:0;position:relative}.fs-permissions ul li>i.dashicons{float:left;font-size:30px;width:30px;height:30px;padding:5px}.fs-permissions ul li .fs-switch{float:right}.fs-permissions ul li .fs-permission-description{margin-left:55px}.fs-permissions ul li .fs-permission-description span{font-size:14px;font-weight:500;color:#23282d}.fs-permissions ul li .fs-permission-description .fs-tooltip{font-size:13px;font-weight:bold}.fs-permissions ul li .fs-permission-description .fs-tooltip-trigger .dashicons{margin:-1px 2px 0 2px}.fs-permissions ul li .fs-permission-description p{margin:2px 0 0 0}.fs-permissions.fs-open{background:#fff}.fs-permissions.fs-open ul{overflow:initial;height:auto;margin:20px 0 10px 0}.fs-permissions .fs-switch-feedback .fs-ajax-spinner{margin-right:10px}.fs-permissions .fs-switch-feedback.success{color:#71ae00}.rtl .fs-permissions .fs-switch-feedback{right:auto;left:15px}.rtl .fs-permissions .fs-switch-feedback .fs-ajax-spinner{margin-left:10px;margin-right:0}.rtl .fs-permissions ul li .fs-permission-description{margin-right:55px;margin-left:0}.rtl .fs-permissions ul li .fs-switch{float:left}.rtl .fs-permissions ul li i.dashicons{float:right}.fs-modal-opt-out .fs-modal-footer .fs-opt-out-button{line-height:30px;margin-right:10px}.fs-modal-opt-out .fs-permissions{margin-top:0 !important}.fs-modal-opt-out .fs-permissions .fs-permissions-section--header .fs-group-opt-out-button{float:right;line-height:1.1em}.fs-modal-opt-out .fs-permissions .fs-permissions-section--header .fs-switch-feedback{float:right;line-height:1.1em;margin-right:10px}.fs-modal-opt-out .fs-permissions .fs-permissions-section--header .fs-switch-feedback .fs-ajax-spinner{margin:-2px 0 0}.fs-modal-opt-out .fs-permissions .fs-permissions-section--header-title{font-size:1.1em;font-weight:600;text-transform:uppercase;display:block;line-height:1.1em;margin:.5em 0}.fs-modal-opt-out .fs-permissions .fs-permissions-section--desc{margin-top:0}.fs-modal-opt-out .fs-permissions hr{border:0;border-top:#eee solid 1px;margin:25px 0 20px 0}.fs-modal-opt-out .fs-permissions ul{border:1px solid #c3c4c7;border-radius:3px;margin:10px 0 0 0;box-shadow:0 1px 1px rgba(0,0,0,.04)}.fs-modal-opt-out .fs-permissions ul li{border-bottom:1px solid #d7dde1;border-left:4px solid #72aee6}.rtl .fs-modal-opt-out .fs-permissions ul li{border-left:none;border-right:4px solid #72aee6}.fs-modal-opt-out .fs-permissions ul li.fs-disabled{border-left-color:rgba(114,174,230,0)}.fs-modal-opt-out .fs-permissions ul li:last-child{border-bottom:none}
+.fs-tooltip-trigger{position:relative}.fs-tooltip-trigger:not(a){cursor:help}.fs-tooltip-trigger .dashicons{float:none!important}.fs-tooltip-trigger .fs-tooltip{background:rgba(0,0,0,.8);border-radius:5px;bottom:100%;box-shadow:1px 1px 1px rgba(0,0,0,.2);color:#fff!important;font-family:arial,serif;font-size:12px;font-weight:700;left:-17px;line-height:1.3em;margin-bottom:5px;opacity:0;padding:10px;position:absolute;right:0;text-align:left;text-transform:none!important;transition:opacity .3s ease-in-out;visibility:hidden;z-index:999999}.rtl .fs-tooltip-trigger .fs-tooltip{left:auto;right:-17px;text-align:right}.fs-tooltip-trigger .fs-tooltip:after{border-color:rgba(0,0,0,.8) transparent transparent;border-style:solid;border-width:5px 5px 0;content:" ";display:block;height:0;left:21px;position:absolute;top:100%;width:0}.rtl .fs-tooltip-trigger .fs-tooltip:after{left:auto;right:21px}.fs-tooltip-trigger:hover .fs-tooltip{opacity:1;visibility:visible}.fs-permissions .fs-permission.fs-disabled,.fs-permissions .fs-permission.fs-disabled .fs-permission-description span{color:#aaa}.fs-permissions .fs-permission .fs-switch-feedback{position:absolute;right:15px;top:52px}.fs-permissions ul{height:0;margin:0;overflow:hidden}.fs-permissions ul li{margin:0;padding:17px 15px;position:relative}.fs-permissions ul li>i.dashicons{float:left;font-size:30px;height:30px;padding:5px;width:30px}.fs-permissions ul li .fs-switch{float:right}.fs-permissions ul li .fs-permission-description{margin-left:55px}.fs-permissions ul li .fs-permission-description span{color:#23282d;font-size:14px;font-weight:500}.fs-permissions ul li .fs-permission-description .fs-tooltip{font-size:13px;font-weight:700}.fs-permissions ul li .fs-permission-description .fs-tooltip-trigger .dashicons{margin:-1px 2px 0}.fs-permissions ul li .fs-permission-description p{margin:2px 0 0}.fs-permissions.fs-open{background:#fff}.fs-permissions.fs-open ul{height:auto;margin:20px 0 10px;overflow:initial}.fs-permissions .fs-switch-feedback .fs-ajax-spinner{margin-right:10px}.fs-permissions .fs-switch-feedback.success{color:#71ae00}.rtl .fs-permissions .fs-switch-feedback{left:15px;right:auto}.rtl .fs-permissions .fs-switch-feedback .fs-ajax-spinner{margin-left:10px;margin-right:0}.rtl .fs-permissions ul li .fs-permission-description{margin-left:0;margin-right:55px}.rtl .fs-permissions ul li .fs-switch{float:left}.rtl .fs-permissions ul li i.dashicons{float:right}.fs-modal-opt-out .fs-modal-footer .fs-opt-out-button{line-height:30px;margin-right:10px}.fs-modal-opt-out .fs-permissions{margin-top:0!important}.fs-modal-opt-out .fs-permissions .fs-permissions-section--header .fs-group-opt-out-button{float:right;line-height:1.1em}.fs-modal-opt-out .fs-permissions .fs-permissions-section--header .fs-switch-feedback{float:right;line-height:1.1em;margin-right:10px}.fs-modal-opt-out .fs-permissions .fs-permissions-section--header .fs-switch-feedback .fs-ajax-spinner{margin:-2px 0 0}.fs-modal-opt-out .fs-permissions .fs-permissions-section--header-title{display:block;font-size:1.1em;font-weight:600;line-height:1.1em;margin:.5em 0;text-transform:uppercase}.fs-modal-opt-out .fs-permissions .fs-permissions-section--desc{margin-top:0}.fs-modal-opt-out .fs-permissions hr{border:0;border-top:1px solid #eee;margin:25px 0 20px}.fs-modal-opt-out .fs-permissions ul{border:1px solid #c3c4c7;border-radius:3px;box-shadow:0 1px 1px rgba(0,0,0,.04);margin:10px 0 0}.fs-modal-opt-out .fs-permissions ul li{border-bottom:1px solid #d7dde1;border-left:4px solid #72aee6}.rtl .fs-modal-opt-out .fs-permissions ul li{border-left:none;border-right:4px solid #72aee6}.fs-modal-opt-out .fs-permissions ul li.fs-disabled{border-left-color:rgba(114,174,230,0)}.fs-modal-opt-out .fs-permissions ul li:last-child{border-bottom:none}
\ No newline at end of file
diff --git a/freemius/assets/css/admin/plugins.css b/freemius/assets/css/admin/plugins.css
index 8d76fa3..a24b481 100644
--- a/freemius/assets/css/admin/plugins.css
+++ b/freemius/assets/css/admin/plugins.css
@@ -1 +1 @@
-label.fs-tag,span.fs-tag{background:#ffba00;color:#fff;display:inline-block;border-radius:3px;padding:5px;font-size:11px;line-height:11px;vertical-align:baseline}label.fs-tag.fs-warn,span.fs-tag.fs-warn{background:#ffba00}label.fs-tag.fs-info,span.fs-tag.fs-info{background:#00a0d2}label.fs-tag.fs-success,span.fs-tag.fs-success{background:#46b450}label.fs-tag.fs-error,span.fs-tag.fs-error{background:#dc3232}.wp-list-table.plugins .plugin-title span.fs-tag{display:inline-block;margin-left:5px;line-height:10px}
+label.fs-tag,span.fs-tag{background:#ffba00;border-radius:3px;color:#fff;display:inline-block;font-size:11px;line-height:11px;padding:5px;vertical-align:baseline}label.fs-tag.fs-warn,span.fs-tag.fs-warn{background:#ffba00}label.fs-tag.fs-info,span.fs-tag.fs-info{background:#00a0d2}label.fs-tag.fs-success,span.fs-tag.fs-success{background:#46b450}label.fs-tag.fs-error,span.fs-tag.fs-error{background:#dc3232}.wp-list-table.plugins .plugin-title span.fs-tag{display:inline-block;line-height:10px;margin-left:5px}
\ No newline at end of file
diff --git a/freemius/assets/css/customizer.css b/freemius/assets/css/customizer.css
index d59b381..a317b5b 100644
--- a/freemius/assets/css/customizer.css
+++ b/freemius/assets/css/customizer.css
@@ -1 +1 @@
-#fs_customizer_upsell .fs-customizer-plan{padding:10px 20px 20px 20px;border-radius:3px;background:#fff}#fs_customizer_upsell .fs-customizer-plan h2{position:relative;margin:0;line-height:2em;text-transform:uppercase}#fs_customizer_upsell .fs-customizer-plan h2 .button-link{top:-2px}#fs_customizer_upsell .fs-feature{position:relative}#fs_customizer_upsell .dashicons-yes{color:#0085ba;font-size:2em;vertical-align:bottom;margin-left:-7px;margin-right:10px}.rtl #fs_customizer_upsell .dashicons-yes{margin-left:10px;margin-right:-7px}#fs_customizer_upsell .dashicons-editor-help{color:#bbb;cursor:help}#fs_customizer_upsell .dashicons-editor-help .fs-feature-desc{opacity:0;visibility:hidden;-moz-transition:opacity .3s ease-in-out;-o-transition:opacity .3s ease-in-out;-ms-transition:opacity .3s ease-in-out;-webkit-transition:opacity .3s ease-in-out;transition:opacity .3s ease-in-out;position:absolute;background:#000;color:#fff;font-family:"arial",serif;font-size:12px;padding:10px;z-index:999999;bottom:100%;margin-bottom:5px;left:0;right:0;-moz-border-radius:5px;-webkit-border-radius:5px;border-radius:5px;-moz-box-shadow:1px 1px 1px rgba(0,0,0,.2);-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.2);box-shadow:1px 1px 1px rgba(0,0,0,.2);line-height:1.3em;font-weight:bold;text-align:left}.rtl #fs_customizer_upsell .dashicons-editor-help .fs-feature-desc{text-align:right}#fs_customizer_upsell .dashicons-editor-help .fs-feature-desc::after{content:" ";display:block;width:0;height:0;border-style:solid;border-width:5px 5px 0 5px;border-color:#000 transparent transparent transparent;position:absolute;top:100%;left:21px}.rtl #fs_customizer_upsell .dashicons-editor-help .fs-feature-desc::after{right:21px;left:auto}#fs_customizer_upsell .dashicons-editor-help:hover .fs-feature-desc{visibility:visible;opacity:1}#fs_customizer_upsell .button-primary{display:block;text-align:center;margin-top:10px}#fs_customizer_support{display:block !important}#fs_customizer_support .button{float:right}#fs_customizer_support .button-group{width:100%;display:block;margin-top:10px}#fs_customizer_support .button-group .button{float:none;width:50%;text-align:center}#customize-theme-controls #accordion-section-freemius_upsell{border-top:1px solid #0085ba !important;border-bottom:1px solid #0085ba !important}#customize-theme-controls #accordion-section-freemius_upsell h3.accordion-section-title{color:#fff;background-color:#0085ba;border-left:4px solid #0085ba;transition:.15s background-color ease-in-out,.15s border-color ease-in-out;outline:none;border-bottom:none !important}#customize-theme-controls #accordion-section-freemius_upsell h3.accordion-section-title:hover{background-color:#008ec2;border-left-color:#0073aa}#customize-theme-controls #accordion-section-freemius_upsell h3.accordion-section-title:after{color:#fff}#customize-theme-controls #accordion-section-freemius_upsell .rtl h3.accordion-section-title{border-left:none;border-right:4px solid #0085ba}#customize-theme-controls #accordion-section-freemius_upsell .rtl h3.accordion-section-title:hover{border-right-color:#0073aa}
+#fs_customizer_upsell .fs-customizer-plan{background:#fff;border-radius:3px;padding:10px 20px 20px}#fs_customizer_upsell .fs-customizer-plan h2{line-height:2em;margin:0;position:relative;text-transform:uppercase}#fs_customizer_upsell .fs-customizer-plan h2 .button-link{top:-2px}#fs_customizer_upsell .fs-feature{position:relative}#fs_customizer_upsell .dashicons-yes{color:#0085ba;font-size:2em;margin-left:-7px;margin-right:10px;vertical-align:bottom}.rtl #fs_customizer_upsell .dashicons-yes{margin-left:10px;margin-right:-7px}#fs_customizer_upsell .dashicons-editor-help{color:#bbb;cursor:help}#fs_customizer_upsell .dashicons-editor-help .fs-feature-desc{background:#000;border-radius:5px;bottom:100%;box-shadow:1px 1px 1px rgba(0,0,0,.2);color:#fff;font-family:arial,serif;font-size:12px;font-weight:700;left:0;line-height:1.3em;margin-bottom:5px;opacity:0;padding:10px;position:absolute;right:0;text-align:left;transition:opacity .3s ease-in-out;visibility:hidden;z-index:999999}.rtl #fs_customizer_upsell .dashicons-editor-help .fs-feature-desc{text-align:right}#fs_customizer_upsell .dashicons-editor-help .fs-feature-desc:after{border-color:#000 transparent transparent;border-style:solid;border-width:5px 5px 0;content:" ";display:block;height:0;left:21px;position:absolute;top:100%;width:0}.rtl #fs_customizer_upsell .dashicons-editor-help .fs-feature-desc:after{left:auto;right:21px}#fs_customizer_upsell .dashicons-editor-help:hover .fs-feature-desc{opacity:1;visibility:visible}#fs_customizer_upsell .button-primary{display:block;margin-top:10px;text-align:center}#fs_customizer_support{display:block!important}#fs_customizer_support .button{float:right}#fs_customizer_support .button-group{display:block;margin-top:10px;width:100%}#fs_customizer_support .button-group .button{float:none;text-align:center;width:50%}#customize-theme-controls #accordion-section-freemius_upsell{border-bottom:1px solid #0085ba!important;border-top:1px solid #0085ba!important}#customize-theme-controls #accordion-section-freemius_upsell h3.accordion-section-title{background-color:#0085ba;border-bottom:none!important;border-left:4px solid #0085ba;color:#fff;outline:none;transition:background-color .15s ease-in-out,border-color .15s ease-in-out}#customize-theme-controls #accordion-section-freemius_upsell h3.accordion-section-title:hover{background-color:#008ec2;border-left-color:#0073aa}#customize-theme-controls #accordion-section-freemius_upsell h3.accordion-section-title:after{color:#fff}#customize-theme-controls #accordion-section-freemius_upsell .rtl h3.accordion-section-title{border-left:none;border-right:4px solid #0085ba}#customize-theme-controls #accordion-section-freemius_upsell .rtl h3.accordion-section-title:hover{border-right-color:#0073aa}
\ No newline at end of file
diff --git a/freemius/assets/img/password-protected-premium.png b/freemius/assets/img/password-protected-premium.png
new file mode 100644
index 0000000..36c6a20
Binary files /dev/null and b/freemius/assets/img/password-protected-premium.png differ
diff --git a/freemius/assets/js/nojquery.ba-postmessage.js b/freemius/assets/js/nojquery.ba-postmessage.js
index aedbd81..d3414ff 100644
--- a/freemius/assets/js/nojquery.ba-postmessage.js
+++ b/freemius/assets/js/nojquery.ba-postmessage.js
@@ -25,116 +25,4 @@
* 5. The use of `$.isFunction` is replaced by a functionally-identical check.
* 6. The `$:nomunge` YUI option is no longer necessary.
*/
-
-function NoJQueryPostMessageMixin(postBinding, receiveBinding) {
-
- var setMessageCallback, unsetMessageCallback, currentMsgCallback,
- intervalId, lastHash, cacheBust = 1;
-
- if (window.postMessage) {
-
- if (window.addEventListener) {
- setMessageCallback = function(callback) {
- window.addEventListener('message', callback, false);
- }
-
- unsetMessageCallback = function(callback) {
- window.removeEventListener('message', callback, false);
- }
- } else {
- setMessageCallback = function(callback) {
- window.attachEvent('onmessage', callback);
- }
-
- unsetMessageCallback = function(callback) {
- window.detachEvent('onmessage', callback);
- }
- }
-
- this[postBinding] = function(message, targetUrl, target) {
- if (!targetUrl) {
- return;
- }
-
- // The browser supports window.postMessage, so call it with a targetOrigin
- // set appropriately, based on the targetUrl parameter.
- target.postMessage( message, targetUrl.replace( /([^:]+:\/\/[^\/]+).*/, '$1' ) );
- }
-
- // Since the browser supports window.postMessage, the callback will be
- // bound to the actual event associated with window.postMessage.
- this[receiveBinding] = function(callback, sourceOrigin, delay) {
- // Unbind an existing callback if it exists.
- if (currentMsgCallback) {
- unsetMessageCallback(currentMsgCallback);
- currentMsgCallback = null;
- }
-
- if (!callback) {
- return false;
- }
-
- // Bind the callback. A reference to the callback is stored for ease of
- // unbinding.
- currentMsgCallback = setMessageCallback(function(e) {
- switch(Object.prototype.toString.call(sourceOrigin)) {
- case '[object String]':
- if (sourceOrigin !== e.origin) {
- return false;
- }
- break;
- case '[object Function]':
- if (sourceOrigin(e.origin)) {
- return false;
- }
- break;
- }
-
- callback(e);
- });
- };
-
- } else {
-
- this[postBinding] = function(message, targetUrl, target) {
- if (!targetUrl) {
- return;
- }
-
- // The browser does not support window.postMessage, so set the location
- // of the target to targetUrl#message. A bit ugly, but it works! A cache
- // bust parameter is added to ensure that repeat messages trigger the
- // callback.
- target.location = targetUrl.replace( /#.*$/, '' ) + '#' + (+new Date) + (cacheBust++) + '&' + message;
- }
-
- // Since the browser sucks, a polling loop will be started, and the
- // callback will be called whenever the location.hash changes.
- this[receiveBinding] = function(callback, sourceOrigin, delay) {
- if (intervalId) {
- clearInterval(intervalId);
- intervalId = null;
- }
-
- if (callback) {
- delay = typeof sourceOrigin === 'number'
- ? sourceOrigin
- : typeof delay === 'number'
- ? delay
- : 100;
-
- intervalId = setInterval(function(){
- var hash = document.location.hash,
- re = /^#?\d+&/;
- if ( hash !== lastHash && re.test( hash ) ) {
- lastHash = hash;
- callback({ data: hash.replace( re, '' ) });
- }
- }, delay );
- }
- };
-
- }
-
- return this;
-}
\ No newline at end of file
+function NoJQueryPostMessageMixin(n,e){var t,i,o,s,a,r=1;return window.postMessage?(window.addEventListener?(t=function(n){window.addEventListener("message",n,!1)},i=function(n){window.removeEventListener("message",n,!1)}):(t=function(n){window.attachEvent("onmessage",n)},i=function(n){window.detachEvent("onmessage",n)}),this[n]=function(n,e,t){e&&t.postMessage(n,e.replace(/([^:]+:\/\/[^\/]+).*/,"$1"))},this[e]=function(n,e,s){if(o&&(i(o),o=null),!n)return!1;o=t((function(t){switch(Object.prototype.toString.call(e)){case"[object String]":if(e!==t.origin)return!1;break;case"[object Function]":if(e(t.origin))return!1}n(t)}))}):(this[n]=function(n,e,t){e&&(t.location=e.replace(/#.*$/,"")+"#"+ +new Date+r+++"&"+n)},this[e]=function(n,e,t){s&&(clearInterval(s),s=null),n&&(t="number"==typeof e?e:"number"==typeof t?t:100,s=setInterval((function(){var e=document.location.hash,t=/^#?\d+&/;e!==a&&t.test(e)&&(a=e,n({data:e.replace(t,"")}))}),t))}),this}
\ No newline at end of file
diff --git a/freemius/assets/js/postmessage.js b/freemius/assets/js/postmessage.js
index 9ec5d12..609cbee 100644
--- a/freemius/assets/js/postmessage.js
+++ b/freemius/assets/js/postmessage.js
@@ -1,135 +1 @@
-(function ($, undef) {
- var global = this;
-
- // Namespace.
- global.FS = global.FS || {};
-
- global.FS.PostMessage = function ()
- {
- var
- _is_child = false,
- _postman = new NoJQueryPostMessageMixin('postMessage', 'receiveMessage'),
- _callbacks = {},
- _base_url,
- _parent_url = decodeURIComponent(document.location.hash.replace(/^#/, '')),
- _parent_subdomain = _parent_url.substring(0, _parent_url.indexOf('/', ('https://' === _parent_url.substring(0, ('https://').length)) ? 8 : 7)),
- _init = function () {
- _postman.receiveMessage(function (e) {
- var data = JSON.parse(e.data);
-
- if (_callbacks[data.type]) {
- for (var i = 0; i < _callbacks[data.type].length; i++) {
- // Execute type callbacks.
- _callbacks[data.type][i](data.data);
- }
- }
- }, _base_url);
- },
- _hasParent = ('' !== _parent_url),
- $window = $(window),
- $html = $('html');
-
- return {
- init : function (url, iframes)
- {
- _base_url = url;
- _init();
-
- // Automatically receive forward messages.
- FS.PostMessage.receiveOnce('forward', function (data){
- window.location = data.url;
- });
-
- iframes = iframes || [];
-
- if (iframes.length > 0) {
- $window.on('scroll', function () {
- for (var i = 0; i < iframes.length; i++) {
- FS.PostMessage.postScroll(iframes[i]);
- }
- });
- }
- },
- init_child : function ()
- {
- this.init(_parent_subdomain);
-
- _is_child = true;
-
- // Post height of a child right after window is loaded.
- $(window).bind('load', function () {
- FS.PostMessage.postHeight();
-
- // Post message that window was loaded.
- FS.PostMessage.post('loaded');
- });
- },
- hasParent : function ()
- {
- return _hasParent;
- },
- postHeight : function (diff, wrapper) {
- diff = diff || 0;
- wrapper = wrapper || '#wrap_section';
- this.post('height', {
- height: diff + $(wrapper).outerHeight(true)
- });
- },
- postScroll : function (iframe) {
- this.post('scroll', {
- top: $window.scrollTop(),
- height: ($window.height() - parseFloat($html.css('paddingTop')) - parseFloat($html.css('marginTop')))
- }, iframe);
- },
- post : function (type, data, iframe)
- {
- console.debug('PostMessage.post', type);
-
- if (iframe)
- {
- // Post to iframe.
- _postman.postMessage(JSON.stringify({
- type: type,
- data: data
- }), iframe.src, iframe.contentWindow);
- }
- else {
- // Post to parent.
- _postman.postMessage(JSON.stringify({
- type: type,
- data: data
- }), _parent_url, window.parent);
- }
- },
- receive: function (type, callback)
- {
- console.debug('PostMessage.receive', type);
-
- if (undef === _callbacks[type])
- _callbacks[type] = [];
-
- _callbacks[type].push(callback);
- },
- receiveOnce: function (type, callback)
- {
- if (this.is_set(type))
- return;
-
- this.receive(type, callback);
- },
- // Check if any callbacks assigned to a specified message type.
- is_set: function (type)
- {
- return (undef != _callbacks[type]);
- },
- parent_url: function ()
- {
- return _parent_url;
- },
- parent_subdomain: function ()
- {
- return _parent_subdomain;
- }
- };
- }();
-})(jQuery);
\ No newline at end of file
+!function(e,t){var s,n,o,i,r,a,c,p,u=this;u.FS=u.FS||{},u.FS.PostMessage=(n=new NoJQueryPostMessageMixin("postMessage","receiveMessage"),o={},i=decodeURIComponent(document.location.hash.replace(/^#/,"")),r=i.substring(0,i.indexOf("/","https://"===i.substring(0,8)?8:7)),a=""!==i,c=e(window),p=e("html"),{init:function(e,t){s=e,n.receiveMessage((function(e){var t=JSON.parse(e.data);if(o[t.type])for(var s=0;s0&&c.on("scroll",(function(){for(var e=0;e_storage = FS_Storage::instance( $this->_module_type, $this->_slug );
+ // If not set or 24 hours have already passed from the last time it's set, set the last load timestamp to the current time.
+ if (
+ ! isset( $this->_storage->last_load_timestamp ) ||
+ $this->_storage->last_load_timestamp < ( time() - ( WP_FS__TIME_24_HOURS_IN_SEC ) )
+ ) {
+ $this->_storage->last_load_timestamp = time();
+ }
+
$this->_cache = FS_Cache_Manager::get_manager( WP_FS___OPTION_PREFIX . "cache_{$module_id}" );
$this->_logger = FS_Logger::get_logger( WP_FS__SLUG . '_' . $this->get_unique_affix(), WP_FS__DEBUG_SDK, WP_FS__ECHO_DEBUG_SDK );
@@ -1348,6 +1356,29 @@ function _plugins_loaded() {
}
}
+ function _run_garbage_collector() {
+ if ( true !== fs_get_optional_constant( 'WP_FS__ENABLE_GARBAGE_COLLECTOR', true ) ) {
+ return;
+ }
+
+ if ( ! $this->is_user_in_admin() ) {
+ return;
+ }
+
+ require_once WP_FS__DIR_INCLUDES . '/class-fs-lock.php';
+
+ $lock = new FS_Lock( 'garbage_collection' );
+
+ if ( $lock->is_locked() ) {
+ return;
+ }
+
+ // Create a 1-day lock.
+ $lock->lock( WP_FS__TIME_24_HOURS_IN_SEC );
+
+ FS_Garbage_Collector::instance()->clean();
+ }
+
/**
* Opens the support forum subemenu item in a new browser page.
*
@@ -1443,6 +1474,8 @@ private function register_constructor_hooks() {
}
}
+ add_action( 'plugins_loaded', array( &$this, '_run_garbage_collector' ) );
+
if ( ! self::is_ajax() ) {
if ( ! $this->is_addon() ) {
add_action( 'init', array( &$this, '_add_default_submenu_items' ), WP_FS__LOWEST_PRIORITY );
@@ -1531,8 +1564,8 @@ private function register_constructor_hooks() {
);
$this->add_filter( 'after_code_type_change', array( &$this, '_after_code_type_change' ) );
- add_action( 'admin_init', array( &$this, '_add_trial_notice' ) );
- add_action( 'admin_init', array( &$this, '_add_affiliate_program_notice' ) );
+ add_action( 'admin_init', array( &$this, '_add_trial_notice' ) ); // @phpstan-ignore-line
+ add_action( 'admin_init', array( &$this, '_add_affiliate_program_notice' ) ); // @phpstan-ignore-line
add_action( 'admin_enqueue_scripts', array( &$this, '_enqueue_common_css' ) );
/**
@@ -1642,7 +1675,7 @@ static function _remove_fs_updates_from_plugin_install_page( $updates, $transien
* @author Leo Fajardo (@leorw)
* @since 2.2.3
*
- * @return string
+ * @return void
*/
static function _prepend_fs_allow_updater_and_dialog_flag_url_param() {
$slug_basename_map = array();
@@ -3089,11 +3122,8 @@ private function is_matching_url( $sub_url, $url = '' ) {
return false;
}
- $url_params = array();
- parse_str( parse_url( $url, PHP_URL_QUERY ), $url_params );
-
- $sub_url_params = array();
- parse_str( parse_url( $sub_url, PHP_URL_QUERY ), $sub_url_params );
+ $url_params = fs_parse_url_params( $url );
+ $sub_url_params = fs_parse_url_params( $sub_url );
foreach ( $sub_url_params as $key => $val ) {
if ( ! isset( $url_params[ $key ] ) || $val != $url_params[ $key ] ) {
@@ -3492,6 +3522,28 @@ function is_clone( $only_if_manual_resolution_is_not_hidden = false ) {
* @return string
*/
static function get_unfiltered_site_url( $blog_id = null, $strip_protocol = false, $add_trailing_slash = false ) {
+ $url = ( ! is_multisite() && defined( 'WP_SITEURL' ) ) ? WP_SITEURL : self::get_site_url_from_wp_option( $blog_id );
+
+ if ( $strip_protocol ) {
+ $url = fs_strip_url_protocol( $url );
+ }
+
+ if ( $add_trailing_slash ) {
+ $url = trailingslashit( $url );
+ }
+
+ return $url;
+ }
+
+ /**
+ * @author Leo Fajardo (@leorw)
+ * @since 2.6.0
+ *
+ * @param int|null $blog_id
+ *
+ * @return string
+ */
+ private static function get_site_url_from_wp_option( $blog_id = null ) {
global $wp_filter;
$site_url_filters = array(
@@ -3518,14 +3570,6 @@ static function get_unfiltered_site_url( $blog_id = null, $strip_protocol = fals
}
}
- if ( $strip_protocol ) {
- $url = fs_strip_url_protocol( $url );
- }
-
- if ( $add_trailing_slash ) {
- $url = trailingslashit( $url );
- }
-
return $url;
}
@@ -4080,7 +4124,7 @@ private function should_turn_fs_on( $is_update = true ) {
$max = 100;
if ( function_exists( 'random_int' ) ) {
- $random = random_int( $min, $max );
+ $random = random_int( $min, $max ); // phpcs:ignore PHPCompatibility.FunctionUse.NewFunctions.random_intFound
} else {
$random = rand( $min, $max );
}
@@ -4399,7 +4443,22 @@ static function is_valid_email( $email ) {
}
// Get the UTF encoded domain name.
- $domain = idn_to_ascii( $parts[1] ) . '.';
+ /**
+ * @note - The check of `defined('...')` is there to account for PHP servers compiled with some older version of ICU where the constants are not defined.
+ * @author - @swashata
+ */
+ $is_new_idn_available = (
+ version_compare( PHP_VERSION, '5.6.40') > 0 &&
+ defined( 'IDNA_DEFAULT' ) &&
+ defined( 'INTL_IDNA_VARIANT_UTS46' )
+ );
+ if ( $is_new_idn_available ) {
+ $domain = idn_to_ascii( $parts[1], IDNA_DEFAULT, INTL_IDNA_VARIANT_UTS46 );
+ } else {
+ $domain = idn_to_ascii( $parts[1] ); // phpcs:ignore PHPCompatibility.ParameterValues.NewIDNVariantDefault.NotSet
+ }
+
+ $domain = $domain . '.';
return ( checkdnsrr( $domain, 'MX' ) || checkdnsrr( $domain, 'A' ) );
}
@@ -5615,19 +5674,17 @@ function _after_code_type_change() {
$this->_cache->expire( 'tabs_stylesheets' );
}
- if ( $this->is_registered() ) {
- if ( ! $this->is_addon() ) {
- add_action(
- is_admin() ? 'admin_init' : 'init',
- array( &$this, '_plugin_code_type_changed' )
- );
- }
+ if ( ! $this->is_addon() ) {
+ add_action(
+ is_admin() ? 'admin_init' : 'init',
+ array( &$this, '_plugin_code_type_changed' )
+ );
+ }
- if ( $this->is_premium() ) {
- // Purge cached payments after switching to the premium version.
- // @todo This logic doesn't handle purging the cache for serviceware module upgrade.
- $this->get_api_user_scope()->purge_cache( "/plugins/{$this->_module_id}/payments.json?include_addons=true" );
- }
+ if ( $this->is_registered() && $this->is_premium() ) {
+ // Purge cached payments after switching to the premium version.
+ // @todo This logic doesn't handle purging the cache for serviceware module upgrade.
+ $this->get_api_user_scope()->purge_cache( "/plugins/{$this->_module_id}/payments.json?include_addons=true" );
}
}
@@ -5691,8 +5748,10 @@ function _plugin_code_type_changed() {
}
}
- // Schedule code type changes event.
- $this->schedule_install_sync();
+ if ( $this->is_registered() ) {
+ // Schedule code type changes event.
+ $this->schedule_install_sync();
+ }
/**
* Unregister the uninstall hook for the other version of the plugin (with different code type) to avoid
@@ -7275,7 +7334,7 @@ function _enqueue_connect_essentials() {
wp_enqueue_script( 'jquery' );
wp_enqueue_script( 'json2' );
- fs_enqueue_local_script( 'postmessage', 'nojquery.ba-postmessage.min.js' );
+ fs_enqueue_local_script( 'postmessage', 'nojquery.ba-postmessage.js' );
fs_enqueue_local_script( 'fs-postmessage', 'postmessage.js' );
}
@@ -9990,7 +10049,7 @@ function _uninstall_plugin_event( $check_user = true ) {
* @param string $is_premium
* @param string $caller
*
- * @return string
+ * @return void
*/
function set_basename( $is_premium, $caller ) {
$basename = plugin_basename( $caller );
@@ -12416,7 +12475,7 @@ private function activate_license_on_many_installs(
$install_2_blog_map = array();
foreach ( $blog_2_install_map as $blog_id => $install ) {
- $params[] = array( 'id' => $install->id );
+ $params[] = array( 'id' => $install->id, 'url' => $install->url );
$install_2_blog_map[ $install->id ] = $blog_id;
}
@@ -13676,6 +13735,18 @@ function _activate_license_ajax_action() {
$license_key = trim( fs_request_get_raw( 'license_key' ) );
+ if ( empty( $license_key ) ) {
+ $license_id = trim( fs_request_get_raw( 'license_id' ) );
+
+ if ( FS_Plugin_License::is_valid_id( $license_id ) ) {
+ $license = $this->_get_license_by_id( $license_id, false );
+
+ if ( is_object( $license ) ) {
+ $license_key = $license->secret_key;
+ }
+ }
+ }
+
if ( empty( $license_key ) ) {
exit;
}
@@ -14080,15 +14151,21 @@ private function activate_license(
}
}
+ $is_connected = null;
+
if ( true !== $result && ! FS_Api::is_api_result_entity( $result ) ) {
if ( FS_Api::is_blocked( $result ) ) {
$result->error->message = $this->generate_api_blocked_notice_message_from_result( $result );
+
+ $is_connected = false;
}
$error = FS_Api::is_api_error_object( $result ) ?
$result->error->message :
var_export( $result, true );
} else {
+ $is_connected = true;
+
$fs->network_upgrade_mode_completed();
$fs->_user = $user;
@@ -14105,6 +14182,8 @@ private function activate_license(
$fs->get_parent_instance()->get_account_url() :
$fs->get_after_activation_url( 'after_connect_url' );
}
+
+ $fs->update_connectivity_info( $is_connected );
} else {
$next_page = $fs->opt_in(
false,
@@ -14762,9 +14841,15 @@ function _submit_affiliate_application() {
}
if ( ! $this->is_registered() ) {
+ $email_address = isset( $affiliate['email'] ) ? $affiliate['email'] : '';
+
+ if ( ! is_email( $email_address ) ) {
+ self::shoot_ajax_failure('Invalid email address.');
+ }
+
// Opt in but don't track usage.
$next_page = $this->opt_in(
- false,
+ $email_address,
false,
false,
false,
@@ -16697,7 +16782,7 @@ private static function decrypt_entity( FS_Entity $entity ) {
*
* @return FS_User|false
*/
- static function _get_user_by_email( $email ) {
+ public static function _get_user_by_email( $email ) {
self::$_static_logger->entrance();
$email = trim( strtolower( $email ) );
@@ -17871,7 +17956,7 @@ private function install_with_new_user(
* @param bool $trial_plan_id
* @param bool $redirect
*
- * @return string If redirect is `false`, returns the next page the user should be redirected to.
+ * @return void
*/
private function install_many_pending_with_user(
$user_id,
@@ -20730,7 +20815,7 @@ private function _fetch_newer_version( $plugin_id = false, $flush = true, $expir
*
* @return bool|FS_Plugin_Tag
*/
- function get_update( $plugin_id = false, $flush = true, $expiration = WP_FS__TIME_24_HOURS_IN_SEC, $newer_than = false ) {
+ function get_update( $plugin_id = false, $flush = true, $expiration = FS_Plugin_Updater::UPDATES_CHECK_CACHE_EXPIRATION, $newer_than = false ) {
$this->_logger->entrance();
if ( ! is_numeric( $plugin_id ) ) {
@@ -21262,7 +21347,9 @@ private function _sync_plugin_license(
/**
* Sync licenses. Pass the site's license ID so that the foreign licenses will be fetched if the license
* associated with that ID is not included in the user's licenses collection.
+ * Save previous value to manage remote license renewals.
*/
+ $was_license_expired_before_sync = is_object( $this->_license ) && $this->_license->is_expired();
$this->_sync_licenses(
$site->license_id,
( $is_context_single_site ?
@@ -21396,6 +21483,14 @@ private function _sync_plugin_license(
$plan_change = 'expired';
}
}
+ } else if ( $was_license_expired_before_sync ) {
+ /**
+ * If license was expired but it is not anymore.
+ *
+ *
+ * @author Daniele Alessandra (@danielealessandra)
+ */
+ $plan_change = 'extended';
}
}
@@ -21473,6 +21568,12 @@ private function _sync_plugin_license(
'license_expired',
) );
break;
+ case 'extended':
+ $this->_admin_notices->remove_sticky( array(
+ 'trial_expired',
+ 'license_expired',
+ ) );
+ break;
case 'changed':
$this->_admin_notices->add_sticky(
sprintf(
@@ -22383,7 +22484,7 @@ private function check_updates(
$background = false,
$plugin_id = false,
$flush = true,
- $expiration = WP_FS__TIME_24_HOURS_IN_SEC,
+ $expiration = FS_Plugin_Updater::UPDATES_CHECK_CACHE_EXPIRATION,
$newer_than = false
) {
$this->_logger->entrance();
@@ -23264,6 +23365,18 @@ private function _handle_account_edits() {
}
}
+ /**
+ * Adds CSS classes for the body tag in the admin.
+ *
+ * @param string $classes Space-separated string of class names.
+ *
+ * @return string $classes FS Admin body tag class names.
+ */
+ public function fs_addons_body_class( $classes ) {
+ $classes .= ' plugins-php';
+ return $classes;
+ }
+
/**
* Account page resources load.
*
@@ -23280,14 +23393,7 @@ function _account_page_load() {
if ( $this->has_addons() ) {
wp_enqueue_script( 'plugin-install' );
add_thickbox();
-
- function fs_addons_body_class( $classes ) {
- $classes .= ' plugins-php';
-
- return $classes;
- }
-
- add_filter( 'admin_body_class', 'fs_addons_body_class' );
+ add_filter( 'admin_body_class', array( $this, 'fs_addons_body_class' ) );
}
if ( $this->has_paid_plan() &&
@@ -23422,14 +23528,7 @@ function _addons_page_load() {
wp_enqueue_script( 'plugin-install' );
add_thickbox();
-
- function fs_addons_body_class( $classes ) {
- $classes .= ' plugins-php';
-
- return $classes;
- }
-
- add_filter( 'admin_body_class', 'fs_addons_body_class' );
+ add_filter( 'admin_body_class', array( $this, 'fs_addons_body_class' ) );
if ( ! $this->is_registered() && $this->is_org_repo_compliant() ) {
$this->_admin_notices->add(
@@ -24027,7 +24126,7 @@ function _add_trial_notice() {
if ( $this->is_registered() ) {
// If opted-in, override trial with up to date data from API.
- $trial_plans = FS_Plan_Manager::instance()->get_trial_plans( $this->_plans );
+ $trial_plans = FS_Plan_Manager::instance()->get_visible_trial_plans( $this->_plans );
$trial_plans_count = count( $trial_plans );
if ( 0 === $trial_plans_count ) {
@@ -25397,6 +25496,12 @@ function _add_tabs_before_content() {
return false;
}
+ $tabs_html = $this->get_tabs_html();
+
+ if ( empty( $tabs_html ) ) {
+ return false;
+ }
+
/**
* Enqueue the original stylesheets that are included in the
* theme settings page. That way, if the theme settings has
@@ -25411,7 +25516,7 @@ function _add_tabs_before_content() {
}
// Cut closing tag.
- echo substr( trim( $this->get_tabs_html() ), 0, - 6 );
+ echo substr( trim( $tabs_html ), 0, - 6 );
return true;
}
diff --git a/freemius/includes/class-fs-api.php b/freemius/includes/class-fs-api.php
index ef56fad..62fae1c 100644
--- a/freemius/includes/class-fs-api.php
+++ b/freemius/includes/class-fs-api.php
@@ -318,9 +318,12 @@ function get( $path = '/', $flush = false, $expiration = WP_FS__TIME_24_HOURS_IN
$flush = true;
}
- $cached_result = self::$_cache->get( $cache_key );
+ $has_valid_cache = self::$_cache->has_valid( $cache_key, $expiration );
+ $cached_result = $has_valid_cache ?
+ self::$_cache->get( $cache_key ) :
+ null;
- if ( $flush || ! self::$_cache->has_valid( $cache_key, $expiration ) ) {
+ if ( $flush || is_null( $cached_result ) ) {
$result = $this->call( $path );
if ( ! is_object( $result ) || isset( $result->error ) ) {
diff --git a/freemius/includes/class-fs-garbage-collector.php b/freemius/includes/class-fs-garbage-collector.php
new file mode 100644
index 0000000..a161170
--- /dev/null
+++ b/freemius/includes/class-fs-garbage-collector.php
@@ -0,0 +1,439 @@
+ Map of product slugs to their last load timestamp, only for products that are not active.
+ */
+ private $_gc_timestamp;
+
+ /**
+ * @var array> Map of product slugs to their data, as stored by the primary storage of `Freemius` class.
+ */
+ private $_storage_data;
+
+ function __construct( FS_Options $_accounts, $option_names, $type ) {
+ $this->_accounts = $_accounts;
+ $this->_options_names = $option_names;
+ $this->_type = $type;
+ $this->_plural_type = ( $type . 's' );
+ }
+
+ function clean() {
+ $this->_gc_timestamp = $this->_accounts->get_option( 'gc_timestamp', array() );
+ $this->_storage_data = $this->_accounts->get_option( $this->_type . '_data', array() );
+
+ $options = $this->load_options();
+ $has_updated_option = false;
+
+ $filtered_products = $this->get_filtered_products();
+ $products_to_clean = $filtered_products['products_to_clean'];
+ $active_products_by_id_map = $filtered_products['active_products_by_id_map'];
+
+ foreach( $products_to_clean as $product ) {
+ $slug = $product->slug;
+
+ // Clear the product's data.
+ foreach( $options as $option_name => $option ) {
+ $updated = false;
+
+ /**
+ * We expect to deal with only array like options here.
+ * @todo - Refactor this to create dedicated GC classes for every option, then we can make the code mode predictable.
+ * For example, depending on data integrity of `plugins` we can still miss something entirely in the `plugin_data` or vice-versa.
+ * A better algorithm is to iterate over all options individually in separate classes and check against primary storage to see if those can be garbage collected.
+ * But given the chance of data integrity issue is very low, we let this run for now and gather feedback.
+ */
+ if ( ! is_array( $option ) ) {
+ continue;
+ }
+
+ if ( array_key_exists( $slug, $option ) ) {
+ unset( $option[ $slug ] );
+ $updated = true;
+ } else if ( array_key_exists( "{$slug}:{$this->_type}", $option ) ) { /* admin_notices */
+ unset( $option[ "{$slug}:{$this->_type}" ] );
+ $updated = true;
+ } else if ( isset( $product->id ) && array_key_exists( $product->id, $option ) ) { /* all_licenses, add-ons, and id_slug_type_path_map */
+ $is_inactive_by_id = ! isset( $active_products_by_id_map[ $product->id ] );
+ $is_inactive_by_slug = (
+ 'id_slug_type_path_map' === $option_name &&
+ (
+ ! isset( $option[ $product->id ]['slug'] ) ||
+ $slug === $option[ $product->id ]['slug']
+ )
+ );
+
+ if ( $is_inactive_by_id || $is_inactive_by_slug ) {
+ unset( $option[ $product->id ] );
+ $updated = true;
+ }
+ } else if ( /* file_slug_map */
+ isset( $product->file ) &&
+ array_key_exists( $product->file, $option ) &&
+ $slug === $option[ $product->file ]
+ ) {
+ unset( $option[ $product->file ] );
+ $updated = true;
+ }
+
+ if ( $updated ) {
+ $this->_accounts->set_option( $option_name, $option );
+
+ $options[ $option_name ] = $option;
+
+ $has_updated_option = true;
+ }
+ }
+
+ // Clear the product's data from the primary storage.
+ if ( isset( $this->_storage_data[ $slug ] ) ) {
+ unset( $this->_storage_data[ $slug ] );
+ $has_updated_option = true;
+ }
+
+ // Clear from GC timestamp.
+ // @todo - This perhaps needs a separate garbage collector for all expired products. But the chance of left-over is very slim.
+ if ( isset( $this->_gc_timestamp[ $slug ] ) ) {
+ unset( $this->_gc_timestamp[ $slug ] );
+ $has_updated_option = true;
+ }
+ }
+
+ $this->_accounts->set_option( 'gc_timestamp', $this->_gc_timestamp );
+ $this->_accounts->set_option( $this->_type . '_data', $this->_storage_data );
+
+ return $has_updated_option;
+ }
+
+ private function get_all_option_names() {
+ return array_merge(
+ array(
+ 'admin_notices',
+ 'updates',
+ 'all_licenses',
+ 'addons',
+ 'id_slug_type_path_map',
+ 'file_slug_map',
+ ),
+ $this->_options_names
+ );
+ }
+
+ private function get_products() {
+ $products = $this->_accounts->get_option( $this->_plural_type, array() );
+
+ // Fill any missing product found in the primary storage.
+ // @todo - This wouldn't be needed if we use dedicated GC design for every options. The options themselves would provide such information.
+ foreach( $this->_storage_data as $slug => $product_data ) {
+ if ( ! isset( $products[ $slug ] ) ) {
+ $products[ $slug ] = (object) $product_data;
+ }
+
+ // This is needed to handle a scenario in which there are duplicate sets of data for the same product, but one of them needs to be removed.
+ $products[ $slug ] = clone $products[ $slug ];
+
+ // The reason for having the line above. This also handles a scenario in which the slug is either empty or not empty but incorrect.
+ $products[ $slug ]->slug = $slug;
+ }
+
+ $this->update_gc_timestamp( $products );
+
+ return $products;
+ }
+
+ private function get_filtered_products() {
+ $products_to_clean = array();
+ $active_products_by_id_map = array();
+
+ $products = $this->get_products();
+
+ foreach ( $products as $slug => $product_data ) {
+ if ( ! is_object( $product_data ) ) {
+ continue;
+ }
+
+ if ( $this->is_product_active( $slug ) ) {
+ $active_products_by_id_map[ $product_data->id ] = true;
+ continue;
+ }
+
+ $is_addon = ( ! empty( $product_data->parent_plugin_id ) );
+
+ if ( ! $is_addon ) {
+ $products_to_clean[] = $product_data;
+ } else {
+ /**
+ * If add-on, add to the beginning of the array so that add-ons are removed before their parent. This is to prevent an unexpected issue when an add-on exists but its parent was already removed.
+ */
+ array_unshift( $products_to_clean, $product_data );
+ }
+ }
+
+ return array(
+ 'products_to_clean' => $products_to_clean,
+ 'active_products_by_id_map' => $active_products_by_id_map,
+ );
+ }
+
+ /**
+ * @param string $slug
+ *
+ * @return bool
+ */
+ private function is_product_active( $slug ) {
+ $instances = Freemius::_get_all_instances();
+
+ foreach ( $instances as $instance ) {
+ if ( $instance->get_slug() === $slug ) {
+ return true;
+ }
+ }
+
+ $expiration_time = fs_get_optional_constant( 'WP_FS__GARBAGE_COLLECTOR_EXPIRATION_TIME_SECS', ( WP_FS__TIME_WEEK_IN_SEC * 4 ) );
+
+ if ( $this->get_last_load_timestamp( $slug ) > ( time() - $expiration_time ) ) {
+ // Last activation was within the last 4 weeks.
+ return true;
+ }
+
+ return false;
+ }
+
+ private function load_options() {
+ $options = array();
+ $option_names = $this->get_all_option_names();
+
+ foreach ( $option_names as $option_name ) {
+ $options[ $option_name ] = $this->_accounts->get_option( $option_name, array() );
+ }
+
+ return $options;
+ }
+
+ /**
+ * Updates the garbage collector timestamp, only if it was not already set by the product's primary storage.
+ *
+ * @param array $products
+ *
+ * @return void
+ */
+ private function update_gc_timestamp( $products ) {
+ foreach ($products as $slug => $product_data) {
+ if ( ! is_object( $product_data ) && ! is_array( $product_data ) ) {
+ continue;
+ }
+
+
+ // If the product is active, we don't need to update the gc_timestamp.
+ if ( isset( $this->_storage_data[ $slug ]['last_load_timestamp'] ) ) {
+ continue;
+ }
+
+ // First try to check if the product is present in the primary storage. If so update that.
+ if ( isset( $this->_storage_data[ $slug ] ) ) {
+ $this->_storage_data[ $slug ]['last_load_timestamp'] = time();
+ } else if ( ! isset( $this->_gc_timestamp[ $slug ] ) ) {
+ // If not, fallback to the gc_timestamp, but we don't want to update it more than once.
+ $this->_gc_timestamp[ $slug ] = time();
+ }
+ }
+ }
+
+ private function get_last_load_timestamp( $slug ) {
+ if ( isset( $this->_storage_data[ $slug ]['last_load_timestamp'] ) ) {
+ return $this->_storage_data[ $slug ]['last_load_timestamp'];
+ }
+
+ return isset( $this->_gc_timestamp[ $slug ] ) ?
+ $this->_gc_timestamp[ $slug ] :
+ // This should never happen, but if it does, let's assume the product is not expired.
+ time();
+ }
+ }
+
+ class FS_User_Garbage_Collector implements FS_I_Garbage_Collector {
+ private $_accounts;
+
+ private $_types;
+
+ function __construct( FS_Options $_accounts, array $types ) {
+ $this->_accounts = $_accounts;
+ $this->_types = $types;
+ }
+
+ function clean() {
+ $users = Freemius::get_all_users();
+
+ $user_has_install_map = $this->get_user_has_install_map();
+
+ if ( count( $users ) === count( $user_has_install_map ) ) {
+ return false;
+ }
+
+ $products_user_id_license_ids_map = $this->_accounts->get_option( 'user_id_license_ids_map', array() );
+
+ $has_updated_option = false;
+
+ foreach ( $users as $user_id => $user ) {
+ if ( ! isset( $user_has_install_map[ $user_id ] ) ) {
+ unset( $users[ $user_id ] );
+
+ foreach( $products_user_id_license_ids_map as $product_id => $user_id_license_ids_map ) {
+ unset( $user_id_license_ids_map[ $user_id ] );
+
+ if ( empty( $user_id_license_ids_map ) ) {
+ unset( $products_user_id_license_ids_map[ $product_id ] );
+ } else {
+ $products_user_id_license_ids_map[ $product_id ] = $user_id_license_ids_map;
+ }
+ }
+
+ $this->_accounts->set_option( 'users', $users );
+ $this->_accounts->set_option( 'user_id_license_ids_map', $products_user_id_license_ids_map );
+
+ $has_updated_option = true;
+ }
+ }
+
+ return $has_updated_option;
+ }
+
+ private function get_user_has_install_map() {
+ $user_has_install_map = array();
+
+ foreach ( $this->_types as $product_type ) {
+ $option_name = ( WP_FS__MODULE_TYPE_PLUGIN !== $product_type ) ?
+ "{$product_type}_sites" :
+ 'sites';
+
+ $installs = $this->_accounts->get_option( $option_name, array() );
+
+ foreach ( $installs as $install ) {
+ $user_has_install_map[ $install->user_id ] = true;
+ }
+ }
+
+ return $user_has_install_map;
+ }
+ }
+
+ // Main entry-level class.
+ class FS_Garbage_Collector implements FS_I_Garbage_Collector {
+ /**
+ * @var FS_Garbage_Collector
+ * @since 2.6.0
+ */
+ private static $_instance;
+
+ /**
+ * @return FS_Garbage_Collector
+ */
+ static function instance() {
+ if ( ! isset( self::$_instance ) ) {
+ self::$_instance = new self();
+ }
+
+ return self::$_instance;
+ }
+
+ #endregion
+
+ private function __construct() {
+ }
+
+ function clean() {
+ $_accounts = FS_Options::instance( WP_FS__ACCOUNTS_OPTION_NAME, true );
+
+ $products_cleaners = $this->get_product_cleaners( $_accounts );
+
+ $has_cleaned = false;
+
+ foreach ( $products_cleaners as $products_cleaner ) {
+ if ( $products_cleaner->clean() ) {
+ $has_cleaned = true;
+ }
+ }
+
+ if ( $has_cleaned ) {
+ $user_cleaner = new FS_User_Garbage_Collector(
+ $_accounts,
+ array_keys( $products_cleaners )
+ );
+
+ $user_cleaner->clean();
+ }
+
+ // @todo - We need a garbage collector for `all_plugins` and `active_plugins` (and variants of themes).
+
+ // Always store regardless of whether there were cleaned products or not since during the process, the logic may set the last load timestamp of some products.
+ $_accounts->store();
+ }
+
+ /**
+ * @param FS_Options $_accounts
+ *
+ * @return FS_I_Garbage_Collector[]
+ */
+ private function get_product_cleaners( FS_Options $_accounts ) {
+ /**
+ * @var FS_I_Garbage_Collector[] $products_cleaners
+ */
+ $products_cleaners = array();
+
+ $products_cleaners[ WP_FS__MODULE_TYPE_PLUGIN ] = new FS_Product_Garbage_Collector(
+ $_accounts,
+ array(
+ 'sites',
+ 'plans',
+ 'plugins',
+ ),
+ WP_FS__MODULE_TYPE_PLUGIN
+ );
+
+ $products_cleaners[ WP_FS__MODULE_TYPE_THEME ] = new FS_Product_Garbage_Collector(
+ $_accounts,
+ array(
+ 'theme_sites',
+ 'theme_plans',
+ 'themes',
+ ),
+ WP_FS__MODULE_TYPE_THEME
+ );
+
+ return $products_cleaners;
+ }
+ }
\ No newline at end of file
diff --git a/freemius/includes/class-fs-plugin-updater.php b/freemius/includes/class-fs-plugin-updater.php
index e904a08..65594b7 100644
--- a/freemius/includes/class-fs-plugin-updater.php
+++ b/freemius/includes/class-fs-plugin-updater.php
@@ -37,6 +37,8 @@ class FS_Plugin_Updater {
private static $_upgrade_basename = null;
+ const UPDATES_CHECK_CACHE_EXPIRATION = ( WP_FS__TIME_24_HOURS_IN_SEC / 24 );
+
#--------------------------------------------------------------------------------
#region Singleton
#--------------------------------------------------------------------------------
@@ -530,7 +532,7 @@ function pre_set_site_transient_update_plugins_filter( $transient_data ) {
$new_version = $this->_fs->get_update(
false,
fs_request_get_bool( 'force-check' ),
- WP_FS__TIME_24_HOURS_IN_SEC / 24,
+ FS_Plugin_Updater::UPDATES_CHECK_CACHE_EXPIRATION,
$current_plugin_version
);
@@ -709,12 +711,7 @@ function get_update_details( FS_Plugin_Tag $new_version ) {
* @return bool
*/
private function is_new_version_premium( FS_Plugin_Tag $new_version ) {
- $query_str = parse_url( $new_version->url, PHP_URL_QUERY );
- if ( empty( $query_str ) ) {
- return false;
- }
-
- parse_str( $query_str, $params );
+ $params = fs_parse_url_params( $new_version->url );
return ( isset( $params['is_premium'] ) && 'true' == $params['is_premium'] );
}
@@ -1193,7 +1190,7 @@ private static function get_tested_wp_version( $tested_up_to ) {
* @return object
*/
private function get_latest_download_details( $addon_id = false, $newer_than = false, $fetch_readme = true ) {
- return $this->_fs->_fetch_latest_version( $addon_id, true, WP_FS__TIME_24_HOURS_IN_SEC, $newer_than, $fetch_readme );
+ return $this->_fs->_fetch_latest_version( $addon_id, true, FS_Plugin_Updater::UPDATES_CHECK_CACHE_EXPIRATION, $newer_than, $fetch_readme );
}
/**
diff --git a/freemius/includes/class-fs-storage.php b/freemius/includes/class-fs-storage.php
index c89f473..74e46e7 100644
--- a/freemius/includes/class-fs-storage.php
+++ b/freemius/includes/class-fs-storage.php
@@ -359,6 +359,7 @@ private static function load_network_options_map() {
'is_network_activated' => self::OPTION_LEVEL_NETWORK,
'is_on' => self::OPTION_LEVEL_NETWORK,
'is_plugin_new_install' => self::OPTION_LEVEL_NETWORK,
+ 'last_load_timestamp' => self::OPTION_LEVEL_NETWORK,
'network_install_blog_id' => self::OPTION_LEVEL_NETWORK,
'pending_sites_info' => self::OPTION_LEVEL_NETWORK,
'plugin_last_version' => self::OPTION_LEVEL_NETWORK,
diff --git a/freemius/includes/debug/class-fs-debug-bar-panel.php b/freemius/includes/debug/class-fs-debug-bar-panel.php
index 0b7969d..c325561 100644
--- a/freemius/includes/debug/class-fs-debug-bar-panel.php
+++ b/freemius/includes/debug/class-fs-debug-bar-panel.php
@@ -10,55 +10,59 @@
exit;
}
- /**
- * Extends Debug Bar plugin by adding a panel to show all Freemius API requests.
- *
- * @author Vova Feldman (@svovaf)
- * @since 1.1.7.3
- *
- * Class Freemius_Debug_Bar_Panel
- */
- class Freemius_Debug_Bar_Panel extends Debug_Bar_Panel {
- function init() {
- $this->title( 'Freemius' );
- }
+ if ( class_exists( 'Debug_Bar_Panel' ) ) {
- static function requests_count() {
- if ( class_exists( 'Freemius_Api_WordPress' ) ) {
- $logger = Freemius_Api_WordPress::GetLogger();
- } else {
- $logger = array();
+ /**
+ * Extends Debug Bar plugin by adding a panel to show all Freemius API requests.
+ *
+ * @author Vova Feldman (@svovaf)
+ * @since 1.1.7.3
+ *
+ * Class Freemius_Debug_Bar_Panel
+ */
+ class Freemius_Debug_Bar_Panel extends Debug_Bar_Panel {
+
+ public function init() {
+ $this->title( 'Freemius' ); // @phpstan-ignore-line
}
- return number_format( count( $logger ) );
- }
+ public static function requests_count() {
+ if ( class_exists( 'Freemius_Api_WordPress' ) ) {
+ $logger = Freemius_Api_WordPress::GetLogger();
+ } else {
+ $logger = array();
+ }
- static function total_time() {
- if ( class_exists( 'Freemius_Api_WordPress' ) ) {
- $logger = Freemius_Api_WordPress::GetLogger();
- } else {
- $logger = array();
+ return number_format( count( $logger ) );
}
- $total_time = .0;
- foreach ( $logger as $l ) {
- $total_time += $l['total'];
- }
+ public static function total_time() {
+ if ( class_exists( 'Freemius_Api_WordPress' ) ) {
+ $logger = Freemius_Api_WordPress::GetLogger();
+ } else {
+ $logger = array();
+ }
- return number_format( 100 * $total_time, 2 ) . ' ' . fs_text_x_inline( 'ms', 'milliseconds' );
- }
+ $total_time = .0;
+ foreach ( $logger as $l ) {
+ $total_time += $l['total'];
+ }
+
+ return number_format( 100 * $total_time, 2 ) . ' ' . fs_text_x_inline( 'ms', 'milliseconds' );
+ }
- function render() {
- ?>
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+ is_lifetime() ) {
+ return false;
+ }
+
return ( WP_FS__TIME_24_HOURS_IN_SEC >= strtotime( $this->expiration ) - strtotime( $this->created ) );
}
diff --git a/freemius/includes/entities/class-fs-plugin-plan.php b/freemius/includes/entities/class-fs-plugin-plan.php
index 00a0d74..5bc6bc2 100644
--- a/freemius/includes/entities/class-fs-plugin-plan.php
+++ b/freemius/includes/entities/class-fs-plugin-plan.php
@@ -88,6 +88,10 @@ class FS_Plugin_Plan extends FS_Entity {
* @var bool Is featured plan.
*/
public $is_featured;
+ /**
+ * @var bool Is hidden plan.
+ */
+ public $is_hidden;
#endregion Properties
diff --git a/freemius/includes/entities/class-fs-site.php b/freemius/includes/entities/class-fs-site.php
index 19cca04..f9012d0 100644
--- a/freemius/includes/entities/class-fs-site.php
+++ b/freemius/includes/entities/class-fs-site.php
@@ -13,6 +13,7 @@
/**
* @property int $blog_id
*/
+ #[AllowDynamicProperties]
class FS_Site extends FS_Scope_Entity {
/**
* @var number
diff --git a/freemius/includes/fs-core-functions.php b/freemius/includes/fs-core-functions.php
index 3dddb40..d02dd3c 100644
--- a/freemius/includes/fs-core-functions.php
+++ b/freemius/includes/fs-core-functions.php
@@ -118,7 +118,7 @@ function fs_enqueue_local_style( $handle, $path, $deps = array(), $ver = false,
}
if ( ! function_exists( 'fs_enqueue_local_script' ) ) {
- function fs_enqueue_local_script( $handle, $path, $deps = array(), $ver = false, $in_footer = 'all' ) {
+ function fs_enqueue_local_script( $handle, $path, $deps = array(), $ver = false, $in_footer = true ) {
wp_enqueue_script( $handle, fs_asset_url( WP_FS__DIR_JS . '/' . trim( $path, '/' ) ), $deps, $ver, $in_footer );
}
}
@@ -588,6 +588,33 @@ function fs_nonce_url( $actionurl, $action = - 1, $name = '_wpnonce' ) {
}
}
+ if ( ! function_exists( 'fs_parse_url_params' ) ) {
+ /**
+ * Returns the query parameters of the given URL if there are any.
+ *
+ * @param string $url
+ * @param bool $html_entity_decode
+ *
+ * @return array Key value pair where key represents the parameter name and value represents the parameter value.
+ */
+ function fs_parse_url_params( $url, $html_entity_decode = false ) {
+ $query_str = parse_url( $url, PHP_URL_QUERY );
+ $url_params = array();
+
+ if ( empty( $query_str ) ) {
+ return $url_params;
+ }
+
+ if ( $html_entity_decode ) {
+ $query_str = html_entity_decode( $query_str );
+ }
+
+ parse_str( $query_str, $url_params );
+
+ return $url_params;
+ }
+ }
+
if ( ! function_exists( 'fs_starts_with' ) ) {
/**
* Check if string starts with.
@@ -1204,7 +1231,7 @@ function fs_esc_js_x_inline( $text, $context, $key = '', $slug = 'freemius' ) {
* @param string $key String key for overrides.
* @param string $slug Module slug for overrides.
*
- * @return string
+ * @return void
*/
function fs_esc_js_echo_x_inline( $text, $context, $key = '', $slug = 'freemius' ) {
echo esc_js( _fs_text_x_inline( $text, $context, $key, $slug ) );
@@ -1458,4 +1485,21 @@ function fs_apply_filter( $module_unique_affix, $tag, $value ) {
array_slice( $args, 2 ) )
);
}
- }
\ No newline at end of file
+ }
+
+ if ( ! function_exists( 'fs_get_optional_constant' ) ) {
+ /**
+ * Gets the value of an optional constant. If the constant is not defined, the default value will be returned.
+ *
+ * @author Swashata Ghosh (@swashata)
+ * @since 2.5.12.5
+ *
+ * @param string $constant_name
+ * @param mixed $default_value
+ *
+ * @return mixed
+ */
+ function fs_get_optional_constant( $constant_name, $default_value = null ) {
+ return defined( $constant_name ) ? constant( $constant_name ) : $default_value;
+ }
+ }
diff --git a/freemius/includes/fs-essential-functions.php b/freemius/includes/fs-essential-functions.php
index c744306..f463a0f 100644
--- a/freemius/includes/fs-essential-functions.php
+++ b/freemius/includes/fs-essential-functions.php
@@ -167,244 +167,252 @@ function fs_get_ip() {
}
}
- /**
- * Leverage backtrace to find caller plugin main file path.
- *
- * @author Vova Feldman (@svovaf)
- * @since 1.0.6
- *
- * @return string
- */
- function fs_find_caller_plugin_file() {
- /**
- * All the code below will be executed once on activation.
- * If the user changes the main plugin's file name, the file_exists()
- * will catch it.
- */
- if ( ! function_exists( 'get_plugins' ) ) {
- require_once ABSPATH . 'wp-admin/includes/plugin.php';
- }
+ if ( ! function_exists( 'fs_find_caller_plugin_file' ) ) {
+ /**
+ * Leverage backtrace to find caller plugin main file path.
+ *
+ * @author Vova Feldman (@svovaf)
+ * @since 1.0.6
+ *
+ * @return string
+ */
+ function fs_find_caller_plugin_file() {
+ /**
+ * All the code below will be executed once on activation.
+ * If the user changes the main plugin's file name, the file_exists()
+ * will catch it.
+ */
+ if ( ! function_exists( 'get_plugins' ) ) {
+ require_once ABSPATH . 'wp-admin/includes/plugin.php';
+ }
- $all_plugins = fs_get_plugins( true );
- $all_plugins_paths = array();
+ $all_plugins = fs_get_plugins( true );
+ $all_plugins_paths = array();
- // Get active plugin's main files real full names (might be symlinks).
- foreach ( $all_plugins as $relative_path => $data ) {
- $all_plugins_paths[] = fs_normalize_path( realpath( WP_PLUGIN_DIR . '/' . $relative_path ) );
- }
+ // Get active plugin's main files real full names (might be symlinks).
+ foreach ( $all_plugins as $relative_path => $data ) {
+ $all_plugins_paths[] = fs_normalize_path( realpath( WP_PLUGIN_DIR . '/' . $relative_path ) );
+ }
- $plugin_file = null;
- for ( $i = 1, $bt = debug_backtrace(), $len = count( $bt ); $i < $len; $i ++ ) {
- if ( empty( $bt[ $i ]['file'] ) ) {
- continue;
- }
+ $plugin_file = null;
+ for ( $i = 1, $bt = debug_backtrace(), $len = count( $bt ); $i < $len; $i ++ ) {
+ if ( empty( $bt[ $i ]['file'] ) ) {
+ continue;
+ }
- if ( in_array( fs_normalize_path( $bt[ $i ]['file'] ), $all_plugins_paths ) ) {
- $plugin_file = $bt[ $i ]['file'];
- break;
- }
- }
+ if ( in_array( fs_normalize_path( $bt[ $i ]['file'] ), $all_plugins_paths ) ) {
+ $plugin_file = $bt[ $i ]['file'];
+ break;
+ }
+ }
- if ( is_null( $plugin_file ) ) {
- // Throw an error to the developer in case of some edge case dev environment.
- wp_die(
- 'Freemius SDK couldn\'t find the plugin\'s main file. Please contact sdk@freemius.com with the current error.',
- 'Error',
- array( 'back_link' => true )
- );
- }
+ if ( is_null( $plugin_file ) ) {
+ // Throw an error to the developer in case of some edge case dev environment.
+ wp_die(
+ 'Freemius SDK couldn\'t find the plugin\'s main file. Please contact sdk@freemius.com with the current error.',
+ 'Error',
+ array( 'back_link' => true )
+ );
+ }
- return $plugin_file;
- }
+ return $plugin_file;
+ }
+ }
require_once dirname( __FILE__ ) . '/supplements/fs-essential-functions-1.1.7.1.php';
- /**
- * Update SDK newest version reference.
- *
- * @author Vova Feldman (@svovaf)
- * @since 1.1.6
- *
- * @param string $sdk_relative_path
- * @param string|bool $plugin_file
- *
- * @global $fs_active_plugins
- */
- function fs_update_sdk_newest_version( $sdk_relative_path, $plugin_file = false ) {
- /**
- * If there is a plugin running an older version of FS (1.2.1 or below), the `fs_update_sdk_newest_version()`
- * function in the older version will be used instead of this one. But since the older version is using
- * the `is_plugin_active` function to check if a plugin is active, passing the theme's `plugin_path` to the
- * `is_plugin_active` function will return false since the path is not a plugin path, so `in_activation` will be
- * `true` for theme modules and the upgrading of the SDK version to 1.2.2 or newer version will work fine.
- *
- * Future versions that will call this function will use the proper logic here instead of just relying on the
- * `is_plugin_active` function to fail for themes.
- *
- * @author Leo Fajardo (@leorw)
- * @since 1.2.2
- */
-
- global $fs_active_plugins;
-
- $newest_sdk = $fs_active_plugins->plugins[ $sdk_relative_path ];
-
- if ( ! is_string( $plugin_file ) ) {
- $plugin_file = plugin_basename( fs_find_caller_plugin_file() );
- }
-
- if ( ! isset( $newest_sdk->type ) || 'theme' !== $newest_sdk->type ) {
- if ( ! function_exists( 'is_plugin_active' ) ) {
- require_once ABSPATH . 'wp-admin/includes/plugin.php';
+ if ( ! function_exists( 'fs_update_sdk_newest_version' ) ) {
+ /**
+ * Update SDK newest version reference.
+ *
+ * @author Vova Feldman (@svovaf)
+ * @since 1.1.6
+ *
+ * @param string $sdk_relative_path
+ * @param string|bool $plugin_file
+ *
+ * @global $fs_active_plugins
+ */
+ function fs_update_sdk_newest_version( $sdk_relative_path, $plugin_file = false ) {
+ /**
+ * If there is a plugin running an older version of FS (1.2.1 or below), the `fs_update_sdk_newest_version()`
+ * function in the older version will be used instead of this one. But since the older version is using
+ * the `is_plugin_active` function to check if a plugin is active, passing the theme's `plugin_path` to the
+ * `is_plugin_active` function will return false since the path is not a plugin path, so `in_activation` will be
+ * `true` for theme modules and the upgrading of the SDK version to 1.2.2 or newer version will work fine.
+ *
+ * Future versions that will call this function will use the proper logic here instead of just relying on the
+ * `is_plugin_active` function to fail for themes.
+ *
+ * @author Leo Fajardo (@leorw)
+ * @since 1.2.2
+ */
+
+ global $fs_active_plugins;
+
+ $newest_sdk = $fs_active_plugins->plugins[ $sdk_relative_path ];
+
+ if ( ! is_string( $plugin_file ) ) {
+ $plugin_file = plugin_basename( fs_find_caller_plugin_file() );
}
- $in_activation = ( ! is_plugin_active( $plugin_file ) );
- } else {
- $theme = wp_get_theme();
- $in_activation = ( $newest_sdk->plugin_path == $theme->stylesheet );
- }
+ if ( ! isset( $newest_sdk->type ) || 'theme' !== $newest_sdk->type ) {
+ if ( ! function_exists( 'is_plugin_active' ) ) {
+ require_once ABSPATH . 'wp-admin/includes/plugin.php';
+ }
- $fs_active_plugins->newest = (object) array(
- 'plugin_path' => $plugin_file,
- 'sdk_path' => $sdk_relative_path,
- 'version' => $newest_sdk->version,
- 'in_activation' => $in_activation,
- 'timestamp' => time(),
- );
+ $in_activation = ( ! is_plugin_active( $plugin_file ) );
+ } else {
+ $theme = wp_get_theme();
+ $in_activation = ( $newest_sdk->plugin_path == $theme->stylesheet );
+ }
- // Update DB with latest SDK version and path.
- update_option( 'fs_active_plugins', $fs_active_plugins );
- }
+ $fs_active_plugins->newest = (object) array(
+ 'plugin_path' => $plugin_file,
+ 'sdk_path' => $sdk_relative_path,
+ 'version' => $newest_sdk->version,
+ 'in_activation' => $in_activation,
+ 'timestamp' => time(),
+ );
- /**
- * Reorder the plugins load order so the plugin with the newest Freemius SDK is loaded first.
- *
- * @author Vova Feldman (@svovaf)
- * @since 1.1.6
- *
- * @return bool Was plugin order changed. Return false if plugin was loaded first anyways.
- *
- * @global $fs_active_plugins
- */
- function fs_newest_sdk_plugin_first() {
- global $fs_active_plugins;
+ // Update DB with latest SDK version and path.
+ update_option( 'fs_active_plugins', $fs_active_plugins );
+ }
+ }
+ if ( ! function_exists( 'fs_newest_sdk_plugin_first' ) ) {
/**
- * @todo Multi-site network activated plugin are always loaded prior to site plugins so if there's a plugin activated in the network mode that has an older version of the SDK of another plugin which is site activated that has new SDK version, the fs-essential-functions.php will be loaded from the older SDK. Same thing about MU plugins (loaded even before network activated plugins).
+ * Reorder the plugins load order so the plugin with the newest Freemius SDK is loaded first.
+ *
+ * @author Vova Feldman (@svovaf)
+ * @since 1.1.6
+ *
+ * @return bool Was plugin order changed. Return false if plugin was loaded first anyways.
*
- * @link https://github.com/Freemius/wordpress-sdk/issues/26
+ * @global $fs_active_plugins
*/
+ function fs_newest_sdk_plugin_first() {
+ global $fs_active_plugins;
- $newest_sdk_plugin_path = $fs_active_plugins->newest->plugin_path;
+ /**
+ * @todo Multi-site network activated plugin are always loaded prior to site plugins so if there's a plugin activated in the network mode that has an older version of the SDK of another plugin which is site activated that has new SDK version, the fs-essential-functions.php will be loaded from the older SDK. Same thing about MU plugins (loaded even before network activated plugins).
+ *
+ * @link https://github.com/Freemius/wordpress-sdk/issues/26
+ */
- $active_plugins = get_option( 'active_plugins', array() );
- $updated_active_plugins = array( $newest_sdk_plugin_path );
+ $newest_sdk_plugin_path = $fs_active_plugins->newest->plugin_path;
- $plugin_found = false;
- $is_first_path = true;
+ $active_plugins = get_option( 'active_plugins', array() );
+ $updated_active_plugins = array( $newest_sdk_plugin_path );
- foreach ( $active_plugins as $key => $plugin_path ) {
- if ( $plugin_path === $newest_sdk_plugin_path ) {
- if ( $is_first_path ) {
- // if it's the first plugin already, no need to continue
- return false;
- }
+ $plugin_found = false;
+ $is_first_path = true;
- $plugin_found = true;
+ foreach ( $active_plugins as $key => $plugin_path ) {
+ if ( $plugin_path === $newest_sdk_plugin_path ) {
+ if ( $is_first_path ) {
+ // if it's the first plugin already, no need to continue
+ return false;
+ }
- // Skip the plugin (it is already added as the 1st item of $updated_active_plugins).
- continue;
- }
+ $plugin_found = true;
- $updated_active_plugins[] = $plugin_path;
+ // Skip the plugin (it is already added as the 1st item of $updated_active_plugins).
+ continue;
+ }
+
+ $updated_active_plugins[] = $plugin_path;
- if ( $is_first_path ) {
- $is_first_path = false;
+ if ( $is_first_path ) {
+ $is_first_path = false;
+ }
}
- }
- if ( $plugin_found ) {
- update_option( 'active_plugins', $updated_active_plugins );
+ if ( $plugin_found ) {
+ update_option( 'active_plugins', $updated_active_plugins );
- return true;
- }
+ return true;
+ }
- if ( is_multisite() ) {
- // Plugin is network active.
- $network_active_plugins = get_site_option( 'active_sitewide_plugins', array() );
+ if ( is_multisite() ) {
+ // Plugin is network active.
+ $network_active_plugins = get_site_option( 'active_sitewide_plugins', array() );
- if ( isset( $network_active_plugins[ $newest_sdk_plugin_path ] ) ) {
- reset( $network_active_plugins );
- if ( $newest_sdk_plugin_path === key( $network_active_plugins ) ) {
- // Plugin is already activated first on the network level.
- return false;
- } else {
- $time = $network_active_plugins[ $newest_sdk_plugin_path ];
+ if ( isset( $network_active_plugins[ $newest_sdk_plugin_path ] ) ) {
+ reset( $network_active_plugins );
+ if ( $newest_sdk_plugin_path === key( $network_active_plugins ) ) {
+ // Plugin is already activated first on the network level.
+ return false;
+ } else {
+ $time = $network_active_plugins[ $newest_sdk_plugin_path ];
- // Remove plugin from its current position.
- unset( $network_active_plugins[ $newest_sdk_plugin_path ] );
+ // Remove plugin from its current position.
+ unset( $network_active_plugins[ $newest_sdk_plugin_path ] );
- // Set it to be included first.
- $network_active_plugins = array( $newest_sdk_plugin_path => $time ) + $network_active_plugins;
+ // Set it to be included first.
+ $network_active_plugins = array( $newest_sdk_plugin_path => $time ) + $network_active_plugins;
- update_site_option( 'active_sitewide_plugins', $network_active_plugins );
+ update_site_option( 'active_sitewide_plugins', $network_active_plugins );
- return true;
+ return true;
+ }
}
}
- }
- return false;
+ return false;
+ }
}
- /**
- * Go over all Freemius SDKs in the system and find and "remember"
- * the newest SDK which is associated with an active plugin.
- *
- * @author Vova Feldman (@svovaf)
- * @since 1.1.6
- *
- * @global $fs_active_plugins
- */
- function fs_fallback_to_newest_active_sdk() {
- global $fs_active_plugins;
-
- /**
- * @var object $newest_sdk_data
- */
- $newest_sdk_data = null;
- $newest_sdk_path = null;
-
- foreach ( $fs_active_plugins->plugins as $sdk_relative_path => $data ) {
- if ( is_null( $newest_sdk_data ) || version_compare( $data->version, $newest_sdk_data->version, '>' )
- ) {
- // If plugin inactive or SDK starter file doesn't exist, remove SDK reference.
- if ( 'plugin' === $data->type ) {
- $is_module_active = is_plugin_active( $data->plugin_path );
- } else {
- $active_theme = wp_get_theme();
- $is_module_active = ( $data->plugin_path === $active_theme->get_template() );
- }
-
- $is_sdk_exists = file_exists( fs_normalize_path( WP_PLUGIN_DIR . '/' . $sdk_relative_path . '/start.php' ) );
-
- if ( ! $is_module_active || ! $is_sdk_exists ) {
- unset( $fs_active_plugins->plugins[ $sdk_relative_path ] );
-
- // No need to store the data since it will be stored in fs_update_sdk_newest_version()
- // or explicitly with update_option().
- } else {
- $newest_sdk_data = $data;
- $newest_sdk_path = $sdk_relative_path;
- }
- }
- }
+ if ( ! function_exists( 'fs_fallback_to_newest_active_sdk' ) ) {
+ /**
+ * Go over all Freemius SDKs in the system and find and "remember"
+ * the newest SDK which is associated with an active plugin.
+ *
+ * @author Vova Feldman (@svovaf)
+ * @since 1.1.6
+ *
+ * @global $fs_active_plugins
+ */
+ function fs_fallback_to_newest_active_sdk() {
+ global $fs_active_plugins;
+
+ /**
+ * @var object $newest_sdk_data
+ */
+ $newest_sdk_data = null;
+ $newest_sdk_path = null;
+
+ foreach ( $fs_active_plugins->plugins as $sdk_relative_path => $data ) {
+ if ( is_null( $newest_sdk_data ) || version_compare( $data->version, $newest_sdk_data->version, '>' )
+ ) {
+ // If plugin inactive or SDK starter file doesn't exist, remove SDK reference.
+ if ( 'plugin' === $data->type ) {
+ $is_module_active = is_plugin_active( $data->plugin_path );
+ } else {
+ $active_theme = wp_get_theme();
+ $is_module_active = ( $data->plugin_path === $active_theme->get_template() );
+ }
+
+ $is_sdk_exists = file_exists( fs_normalize_path( WP_PLUGIN_DIR . '/' . $sdk_relative_path . '/start.php' ) );
+
+ if ( ! $is_module_active || ! $is_sdk_exists ) {
+ unset( $fs_active_plugins->plugins[ $sdk_relative_path ] );
+
+ // No need to store the data since it will be stored in fs_update_sdk_newest_version()
+ // or explicitly with update_option().
+ } else {
+ $newest_sdk_data = $data;
+ $newest_sdk_path = $sdk_relative_path;
+ }
+ }
+ }
- if ( is_null( $newest_sdk_data ) ) {
- // Couldn't find any SDK reference.
- $fs_active_plugins = new stdClass();
- update_option( 'fs_active_plugins', $fs_active_plugins );
- } else {
- fs_update_sdk_newest_version( $newest_sdk_path, $newest_sdk_data->plugin_path );
- }
- }
\ No newline at end of file
+ if ( is_null( $newest_sdk_data ) ) {
+ // Couldn't find any SDK reference.
+ $fs_active_plugins = new stdClass();
+ update_option( 'fs_active_plugins', $fs_active_plugins );
+ } else {
+ fs_update_sdk_newest_version( $newest_sdk_path, $newest_sdk_data->plugin_path );
+ }
+ }
+ }
\ No newline at end of file
diff --git a/freemius/includes/fs-html-escaping-functions.php b/freemius/includes/fs-html-escaping-functions.php
index 29f30da..9384b59 100644
--- a/freemius/includes/fs-html-escaping-functions.php
+++ b/freemius/includes/fs-html-escaping-functions.php
@@ -17,6 +17,7 @@
*/
function fs_html_get_allowed_kses_list() {
$common_attributes = array(
+ 'id' => true,
'class' => true,
'style' => true,
'data-*' => true,
@@ -48,6 +49,7 @@ function fs_html_get_allowed_kses_list() {
'strong' => $common_attributes,
'u' => $common_attributes,
'b' => $common_attributes,
+ 'i' => $common_attributes,
'hr' => $common_attributes,
'span' => $common_attributes,
'p' => $common_attributes,
diff --git a/freemius/includes/fs-plugin-info-dialog.php b/freemius/includes/fs-plugin-info-dialog.php
index 3fbd113..8a79aff 100644
--- a/freemius/includes/fs-plugin-info-dialog.php
+++ b/freemius/includes/fs-plugin-info-dialog.php
@@ -238,7 +238,7 @@ function _get_addon_info_filter( $data, $action = '', $args = null ) {
$latest = $this->_fs->_fetch_latest_version(
$selected_addon->id,
true,
- WP_FS__TIME_24_HOURS_IN_SEC,
+ FS_Plugin_Updater::UPDATES_CHECK_CACHE_EXPIRATION,
$current_addon_version
);
@@ -838,12 +838,8 @@ private static function get_blog_status_url( $blog_id, $network_status_url, $sta
'install-plugin' :
'upgrade-plugin';
- $query = parse_url( $network_status_url, PHP_URL_QUERY );
- if ( empty( $query ) ) {
- return $network_status_url;
- }
+ $url_params = fs_parse_url_params( $network_status_url, true );
- parse_str( html_entity_decode( $query ), $url_params );
if ( empty( $url_params ) || ! isset( $url_params['plugin'] ) ) {
return $network_status_url;
}
diff --git a/freemius/includes/managers/class-fs-plan-manager.php b/freemius/includes/managers/class-fs-plan-manager.php
index 639de43..9beccea 100644
--- a/freemius/includes/managers/class-fs-plan-manager.php
+++ b/freemius/includes/managers/class-fs-plan-manager.php
@@ -108,6 +108,7 @@ function has_free_plan( $plans ) {
/**
* Find all plans that have trial.
+ * Since 2.6.2 call get_filtered_plan
*
* @author Vova Feldman (@svovaf)
* @since 1.0.9
@@ -117,20 +118,50 @@ function has_free_plan( $plans ) {
* @return FS_Plugin_Plan[]
*/
function get_trial_plans( $plans ) {
- $trial_plans = array();
+ return $this->get_filtered_plans( $plans, true );
+ }
- if ( is_array( $plans ) && 0 < count( $plans ) ) {
- /**
- * @var FS_Plugin_Plan[] $plans
- */
- for ( $i = 0, $len = count( $plans ); $i < $len; $i ++ ) {
- if ( $plans[ $i ]->has_trial() ) {
- $trial_plans[] = $plans[ $i ];
+ /**
+ * Find all plans that are not hidden and have trial.
+ *
+ * @author Daniele Alessandra (@danielealessandra)
+ *
+ * @param FS_Plugin_Plan[] $plans
+ *
+ * @return FS_Plugin_Plan[]
+ * @since 2.6.3
+ *
+ */
+ function get_visible_trial_plans( $plans ) {
+ return $this->get_filtered_plans( $plans, true, true );
+ }
+
+ /**
+ * Find all plans filtered by trial or visibility.
+ *
+ * @author Daniele Alessandra (@danielealessandra)
+ *
+ * @param FS_Plugin_Plan[] $plans
+ * @param boolean $should_have_trials
+ * @param boolean $should_be_visible
+ *
+ * @return FS_Plugin_Plan[]
+ * @since 2.6.3
+ *
+ */
+ function get_filtered_plans( $plans, $should_have_trials = false, $should_be_visible = false ) {
+ $filtered_plans = array();
+
+ if ( is_array( $plans ) && count( $plans ) > 0 ) {
+ foreach ( $plans as $plan ) {
+ if ( ( $should_have_trials && ! $plan->has_trial() ) || ( $should_be_visible && $plan->is_hidden ) ) {
+ continue;
}
+ $filtered_plans[] = $plan;
}
}
- return $trial_plans;
+ return $filtered_plans;
}
/**
diff --git a/freemius/includes/sdk/FreemiusWordPress.php b/freemius/includes/sdk/FreemiusWordPress.php
index efb9e0d..2403c90 100644
--- a/freemius/includes/sdk/FreemiusWordPress.php
+++ b/freemius/includes/sdk/FreemiusWordPress.php
@@ -473,8 +473,12 @@ private static function MakeStaticRequest(
*/
if ( filter_var( $matches[1], FILTER_VALIDATE_IP ) ) {
if ( strlen( inet_pton( $matches[1] ) ) === 16 ) {
-// error_log('Invalid IPv6 configuration on server, Please disable or get native IPv6 on your server.');
- // Hook to an action triggered just before cURL is executed to resolve the IP version to v4.
+ /**
+ * error_log('Invalid IPv6 configuration on server, Please disable or get native IPv6 on your server.');
+ * Hook to an action triggered just before cURL is executed to resolve the IP version to v4.
+ *
+ * @phpstan-ignore-next-line
+ */
add_action( 'http_api_curl', 'Freemius_Api_WordPress::CurlResolveToIPv4', 10, 1 );
// Re-run request.
diff --git a/freemius/languages/freemius-cs_CZ.mo b/freemius/languages/freemius-cs_CZ.mo
index 8dd3c06..dc311a4 100644
Binary files a/freemius/languages/freemius-cs_CZ.mo and b/freemius/languages/freemius-cs_CZ.mo differ
diff --git a/freemius/languages/freemius-da_DK.mo b/freemius/languages/freemius-da_DK.mo
index 07ffb83..c0b9378 100644
Binary files a/freemius/languages/freemius-da_DK.mo and b/freemius/languages/freemius-da_DK.mo differ
diff --git a/freemius/languages/freemius-de_DE.mo b/freemius/languages/freemius-de_DE.mo
index 2d951e9..dd85550 100644
Binary files a/freemius/languages/freemius-de_DE.mo and b/freemius/languages/freemius-de_DE.mo differ
diff --git a/freemius/languages/freemius-es_ES.mo b/freemius/languages/freemius-es_ES.mo
index 445e10d..963dfe3 100644
Binary files a/freemius/languages/freemius-es_ES.mo and b/freemius/languages/freemius-es_ES.mo differ
diff --git a/freemius/languages/freemius-fr_FR.mo b/freemius/languages/freemius-fr_FR.mo
index bc2889c..de90270 100644
Binary files a/freemius/languages/freemius-fr_FR.mo and b/freemius/languages/freemius-fr_FR.mo differ
diff --git a/freemius/languages/freemius-he_IL.mo b/freemius/languages/freemius-he_IL.mo
index 5b4b235..e848327 100644
Binary files a/freemius/languages/freemius-he_IL.mo and b/freemius/languages/freemius-he_IL.mo differ
diff --git a/freemius/languages/freemius-hu_HU.mo b/freemius/languages/freemius-hu_HU.mo
index bd75896..7448fe7 100644
Binary files a/freemius/languages/freemius-hu_HU.mo and b/freemius/languages/freemius-hu_HU.mo differ
diff --git a/freemius/languages/freemius-it_IT.mo b/freemius/languages/freemius-it_IT.mo
index 6646907..4348785 100644
Binary files a/freemius/languages/freemius-it_IT.mo and b/freemius/languages/freemius-it_IT.mo differ
diff --git a/freemius/languages/freemius-ja.mo b/freemius/languages/freemius-ja.mo
index 6acf2df..ff6b277 100644
Binary files a/freemius/languages/freemius-ja.mo and b/freemius/languages/freemius-ja.mo differ
diff --git a/freemius/languages/freemius-nl_NL.mo b/freemius/languages/freemius-nl_NL.mo
index b3024ef..37c9c5b 100644
Binary files a/freemius/languages/freemius-nl_NL.mo and b/freemius/languages/freemius-nl_NL.mo differ
diff --git a/freemius/languages/freemius-ru_RU.mo b/freemius/languages/freemius-ru_RU.mo
index c4982fd..c62ea8f 100644
Binary files a/freemius/languages/freemius-ru_RU.mo and b/freemius/languages/freemius-ru_RU.mo differ
diff --git a/freemius/languages/freemius-ta.mo b/freemius/languages/freemius-ta.mo
index 0fbe1eb..b355914 100644
Binary files a/freemius/languages/freemius-ta.mo and b/freemius/languages/freemius-ta.mo differ
diff --git a/freemius/languages/freemius-zh_CN.mo b/freemius/languages/freemius-zh_CN.mo
index 6ac0918..d4f4fda 100644
Binary files a/freemius/languages/freemius-zh_CN.mo and b/freemius/languages/freemius-zh_CN.mo differ
diff --git a/freemius/languages/freemius.pot b/freemius/languages/freemius.pot
index 3bdefb1..ff30eda 100644
--- a/freemius/languages/freemius.pot
+++ b/freemius/languages/freemius.pot
@@ -1,4 +1,4 @@
-# Copyright (C) 2023 freemius
+# Copyright (C) 2024 freemius
# This file is distributed under the same license as the freemius package.
msgid ""
msgstr ""
@@ -8,873 +8,881 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Language-Team: Freemius Team \n"
"Last-Translator: Vova Feldman \n"
+"POT-Creation-Date: 2024-04-22 10:16+0000\n"
"Report-Msgid-Bugs-To: https://github.com/Freemius/wordpress-sdk/issues\n"
"X-Poedit-Basepath: ..\n"
-"X-Poedit-KeywordsList: get_text_inline;fs_text_inline;fs_echo_inline;fs_esc_js_inline;fs_esc_attr_inline;fs_esc_attr_echo_inline;fs_esc_html_inline;fs_esc_html_echo_inline;get_text_x_inline:1,2c;fs_text_x_inline:1,2c;fs_echo_x_inline:1,2c;fs_esc_attr_x_inline:1,2c;fs_esc_js_x_inline:1,2c;fs_esc_js_echo_x_inline:1,2c;fs_esc_html_x_inline:1,2c;fs_esc_html_echo_x_inline:1,2c\n"
+"X-Poedit-KeywordsList: get_text_inline;get_text_x_inline:1,2c;$this->get_text_inline;$this->get_text_x_inline:1,2c;$this->_fs->get_text_inline;$this->_fs->get_text_x_inline:1,2c;$this->fs->get_text_inline;$this->fs->get_text_x_inline:1,2c;$fs->get_text_inline;$fs->get_text_x_inline:1,2c;$this->_parent->get_text_inline;$this->_parent->get_text_x_inline:1,2c;fs_text_inline;fs_echo_inline;fs_esc_js_inline;fs_esc_attr_inline;fs_esc_attr_echo_inline;fs_esc_html_inline;fs_esc_html_echo_inline;fs_text_x_inline:1,2c;fs_echo_x_inline:1,2c;fs_esc_attr_x_inline:1,2c;fs_esc_js_x_inline:1,2c;fs_esc_js_echo_x_inline:1,2c;fs_esc_html_x_inline:1,2c;fs_esc_html_echo_x_inline:1,2c\n"
"X-Poedit-SearchPath-0: .\n"
"X-Poedit-SearchPathExcluded-0: *.js\n"
"X-Poedit-SourceCharset: UTF-8\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-#: includes/class-freemius.php:1748, templates/account.php:947
+#: includes/class-freemius.php:1781, templates/account.php:943
msgid "An update to a Beta version will replace your installed version of %s with the latest Beta release - use with caution, and not on production sites. You have been warned."
msgstr ""
-#: includes/class-freemius.php:1755
+#: includes/class-freemius.php:1788
msgid "Would you like to proceed with the update?"
msgstr ""
-#: includes/class-freemius.php:1980
+#: includes/class-freemius.php:2013
msgid "Freemius SDK couldn't find the plugin's main file. Please contact sdk@freemius.com with the current error."
msgstr ""
-#: includes/class-freemius.php:1982, includes/fs-plugin-info-dialog.php:1517
+#: includes/class-freemius.php:2015, includes/fs-plugin-info-dialog.php:1513
msgid "Error"
msgstr ""
-#: includes/class-freemius.php:2428
+#: includes/class-freemius.php:2461
msgid "I found a better %s"
msgstr ""
-#: includes/class-freemius.php:2430
+#: includes/class-freemius.php:2463
msgid "What's the %s's name?"
msgstr ""
-#: includes/class-freemius.php:2436
+#: includes/class-freemius.php:2469
msgid "It's a temporary %s - I'm troubleshooting an issue"
msgstr ""
-#: includes/class-freemius.php:2438
+#: includes/class-freemius.php:2471
msgid "Deactivation"
msgstr ""
-#: includes/class-freemius.php:2439
+#: includes/class-freemius.php:2472
msgid "Theme Switch"
msgstr ""
-#: includes/class-freemius.php:2448, templates/forms/resend-key.php:24, templates/forms/user-change.php:29
+#: includes/class-freemius.php:2481, templates/forms/resend-key.php:24, templates/forms/user-change.php:29
msgid "Other"
msgstr ""
-#: includes/class-freemius.php:2456
+#: includes/class-freemius.php:2489
msgid "I no longer need the %s"
msgstr ""
-#: includes/class-freemius.php:2463
+#: includes/class-freemius.php:2496
msgid "I only needed the %s for a short period"
msgstr ""
-#: includes/class-freemius.php:2469
+#: includes/class-freemius.php:2502
msgid "The %s broke my site"
msgstr ""
-#: includes/class-freemius.php:2476
+#: includes/class-freemius.php:2509
msgid "The %s suddenly stopped working"
msgstr ""
-#: includes/class-freemius.php:2486
+#: includes/class-freemius.php:2519
msgid "I can't pay for it anymore"
msgstr ""
-#: includes/class-freemius.php:2488
+#: includes/class-freemius.php:2521
msgid "What price would you feel comfortable paying?"
msgstr ""
-#: includes/class-freemius.php:2494
+#: includes/class-freemius.php:2527
msgid "I don't like to share my information with you"
msgstr ""
-#: includes/class-freemius.php:2515
+#: includes/class-freemius.php:2548
msgid "The %s didn't work"
msgstr ""
-#: includes/class-freemius.php:2525
+#: includes/class-freemius.php:2558
msgid "I couldn't understand how to make it work"
msgstr ""
-#: includes/class-freemius.php:2533
+#: includes/class-freemius.php:2566
msgid "The %s is great, but I need specific feature that you don't support"
msgstr ""
-#: includes/class-freemius.php:2535
+#: includes/class-freemius.php:2568
msgid "What feature?"
msgstr ""
-#: includes/class-freemius.php:2539
+#: includes/class-freemius.php:2572
msgid "The %s is not working"
msgstr ""
-#: includes/class-freemius.php:2541
+#: includes/class-freemius.php:2574
msgid "Kindly share what didn't work so we can fix it for future users..."
msgstr ""
-#: includes/class-freemius.php:2545
+#: includes/class-freemius.php:2578
msgid "It's not what I was looking for"
msgstr ""
-#: includes/class-freemius.php:2547
+#: includes/class-freemius.php:2580
msgid "What you've been looking for?"
msgstr ""
-#: includes/class-freemius.php:2551
+#: includes/class-freemius.php:2584
msgid "The %s didn't work as expected"
msgstr ""
-#: includes/class-freemius.php:2553
+#: includes/class-freemius.php:2586
msgid "What did you expect?"
msgstr ""
-#: includes/class-freemius.php:3641, templates/debug.php:24
+#: includes/class-freemius.php:3685, templates/debug.php:24
msgid "Freemius Debug"
msgstr ""
-#: includes/class-freemius.php:4755
+#. translators: %s: License type (e.g. you have a professional license)
+#: includes/class-freemius.php:4828
msgid "You have purchased a %s license."
msgstr ""
-#: includes/class-freemius.php:4759
+#: includes/class-freemius.php:4832
msgid " The %s's %sdownload link%s, license key, and installation instructions have been sent to %s. If you can't find the email after 5 min, please check your spam box."
msgstr ""
-#: includes/class-freemius.php:4769, includes/class-freemius.php:21125, includes/class-freemius.php:24783
+#: includes/class-freemius.php:4842, includes/class-freemius.php:21174, includes/class-freemius.php:24859
msgctxt "interjection expressing joy or exuberance"
msgid "Yee-haw"
msgstr ""
-#: includes/class-freemius.php:4783
+#: includes/class-freemius.php:4856
msgctxt "addonX cannot run without pluginY"
msgid "%s cannot run without %s."
msgstr ""
-#: includes/class-freemius.php:4784
+#: includes/class-freemius.php:4857
msgctxt "addonX cannot run..."
msgid "%s cannot run without the plugin."
msgstr ""
-#: includes/class-freemius.php:4786, includes/class-freemius.php:5978, includes/class-freemius.php:13730, includes/class-freemius.php:14469, includes/class-freemius.php:18281, includes/class-freemius.php:18394, includes/class-freemius.php:18571, includes/class-freemius.php:20856, includes/class-freemius.php:21955, includes/class-freemius.php:22971, includes/class-freemius.php:23101, includes/class-freemius.php:23231, templates/add-ons.php:57
+#: includes/class-freemius.php:4859, includes/class-freemius.php:6051, includes/class-freemius.php:13828, includes/class-freemius.php:14575, includes/class-freemius.php:18330, includes/class-freemius.php:18443, includes/class-freemius.php:18620, includes/class-freemius.php:20905, includes/class-freemius.php:22020, includes/class-freemius.php:23036, includes/class-freemius.php:23166, includes/class-freemius.php:23309, templates/add-ons.php:57
msgctxt "exclamation"
msgid "Oops"
msgstr ""
-#: includes/class-freemius.php:5065
+#: includes/class-freemius.php:5138
msgid "There was an unexpected API error while processing your request. Please try again in a few minutes and if it still doesn't work, contact the %s's author with the following:"
msgstr ""
-#: includes/class-freemius.php:5645
+#. translators: %s: License type (e.g. you have a professional license)
+#: includes/class-freemius.php:5743
+msgid "You have a %s license."
+msgstr ""
+
+#: includes/class-freemius.php:5716
msgid "Premium %s version was successfully activated."
msgstr ""
-#: includes/class-freemius.php:5657, includes/class-freemius.php:7692
+#: includes/class-freemius.php:5728, includes/class-freemius.php:7765
msgctxt "Used to express elation, enthusiasm, or triumph (especially in electronic communication)."
msgid "W00t"
msgstr ""
-#: includes/class-freemius.php:5672
-msgid "You have a %s license."
-msgstr ""
-
-#: includes/class-freemius.php:5961
+#: includes/class-freemius.php:6034
msgid "%s free trial was successfully cancelled. Since the add-on is premium only it was automatically deactivated. If you like to use it in the future, you'll have to purchase a license."
msgstr ""
-#: includes/class-freemius.php:5965
+#: includes/class-freemius.php:6038
msgid "%s is a premium only add-on. You have to purchase a license first before activating the plugin."
msgstr ""
-#: includes/class-freemius.php:5974, templates/add-ons.php:186, templates/account/partials/addon.php:386
+#: includes/class-freemius.php:6047, templates/add-ons.php:186, templates/account/partials/addon.php:386
msgid "More information about %s"
msgstr ""
-#: includes/class-freemius.php:5975
+#: includes/class-freemius.php:6048
msgid "Purchase License"
msgstr ""
-#. translators: %3$s: action (e.g.: "start the trial" or "complete the opt-in")
-#: includes/class-freemius.php:6971
-msgid "You should receive a confirmation email for %1$s to your mailbox at %2$s. Please make sure you click the button in that email to %3$s."
-msgstr ""
-
-#: includes/class-freemius.php:6974
-msgid "start the trial"
-msgstr ""
-
-#: includes/class-freemius.php:6975, templates/connect.php:218
-msgid "complete the opt-in"
-msgstr ""
-
-#: includes/class-freemius.php:6977
-msgid "Thanks!"
-msgstr ""
-
#. translators: %3$s: What the user is expected to receive via email (e.g.: "the installation instructions" or "a license key")
-#: includes/class-freemius.php:6980
+#: includes/class-freemius.php:7053
msgid "You should receive %3$s for %1$s to your mailbox at %2$s in the next 5 minutes."
msgstr ""
-#: includes/class-freemius.php:6983
-msgctxt "Part of the message telling the user what they should receive via email."
-msgid "the installation instructions"
-msgstr ""
-
-#: includes/class-freemius.php:6989
+#: includes/class-freemius.php:7062
msgctxt "Part of the message telling the user what they should receive via email."
msgid "a license key"
msgstr ""
-#: includes/class-freemius.php:6997
+#. translators: %s: activation link (e.g.: Click here )
+#: includes/class-freemius.php:7070
msgid "%s to activate the license once you get it."
msgstr ""
-#: includes/class-freemius.php:7005
+#: includes/class-freemius.php:7078
msgctxt "Part of an activation link message."
msgid "Click here"
msgstr ""
-#: includes/class-freemius.php:7012
+#: includes/class-freemius.php:7056
+msgctxt "Part of the message telling the user what they should receive via email."
+msgid "the installation instructions"
+msgstr ""
+
+#: includes/class-freemius.php:7085
msgctxt "Part of the message that tells the user to check their spam folder for a specific email."
msgid "the product's support email address"
msgstr ""
-#: includes/class-freemius.php:7018
+#: includes/class-freemius.php:7091
msgid "If you didn't get the email, try checking your spam folder or search for emails from %4$s."
msgstr ""
-#: includes/class-freemius.php:7020
+#: includes/class-freemius.php:7093
msgid "Thanks for upgrading."
msgstr ""
-#: includes/class-freemius.php:7156
+#: includes/class-freemius.php:7044
+msgid "You should receive a confirmation email for %1$s to your mailbox at %2$s. Please make sure you click the button in that email to %3$s."
+msgstr ""
+
+#: includes/class-freemius.php:7047
+msgid "start the trial"
+msgstr ""
+
+#: includes/class-freemius.php:7048, templates/connect.php:209
+msgid "complete the opt-in"
+msgstr ""
+
+#: includes/class-freemius.php:7050
+msgid "Thanks!"
+msgstr ""
+
+#: includes/class-freemius.php:7229
msgid "You are just one step away - %s"
msgstr ""
-#: includes/class-freemius.php:7159
+#: includes/class-freemius.php:7232
msgctxt "%s - plugin name. As complete \"PluginX\" activation now"
msgid "Complete \"%s\" Activation Now"
msgstr ""
-#: includes/class-freemius.php:7241
+#: includes/class-freemius.php:7314
msgid "We made a few tweaks to the %s, %s"
msgstr ""
-#: includes/class-freemius.php:7245
+#: includes/class-freemius.php:7318
msgid "Opt in to make \"%s\" better!"
msgstr ""
-#: includes/class-freemius.php:7691
+#: includes/class-freemius.php:7764
msgid "The upgrade of %s was successfully completed."
msgstr ""
-#: includes/class-freemius.php:10441, includes/class-fs-plugin-updater.php:1100, includes/class-fs-plugin-updater.php:1315, includes/class-fs-plugin-updater.php:1322, templates/auto-installation.php:32
+#: includes/class-freemius.php:10527, includes/class-fs-plugin-updater.php:1097, includes/class-fs-plugin-updater.php:1319, includes/class-fs-plugin-updater.php:1312, templates/auto-installation.php:32
msgid "Add-On"
msgstr ""
-#: includes/class-freemius.php:10443, templates/account.php:411, templates/account.php:419, templates/debug.php:399, templates/debug.php:619
+#: includes/class-freemius.php:10529, templates/account.php:407, templates/account.php:415, templates/debug.php:399, templates/debug.php:619
msgid "Plugin"
msgstr ""
-#: includes/class-freemius.php:10444, templates/account.php:412, templates/account.php:420, templates/debug.php:399, templates/debug.php:619, templates/forms/deactivation/form.php:107
+#: includes/class-freemius.php:10530, templates/account.php:408, templates/account.php:416, templates/debug.php:399, templates/debug.php:619, templates/forms/deactivation/form.php:107
msgid "Theme"
msgstr ""
-#: includes/class-freemius.php:13549
+#: includes/class-freemius.php:13635
msgid "An unknown error has occurred while trying to toggle the license's white-label mode."
msgstr ""
-#: includes/class-freemius.php:13563
+#: includes/class-freemius.php:13649
msgid "Your %s license was flagged as white-labeled to hide sensitive information from the WP Admin (e.g. your email, license key, prices, billing address & invoices). If you ever wish to revert it back, you can easily do it through your %s. If this was a mistake you can also %s."
msgstr ""
-#: includes/class-freemius.php:13568, templates/account/partials/disconnect-button.php:84
+#: includes/class-freemius.php:13654, templates/account/partials/disconnect-button.php:84
msgid "User Dashboard"
msgstr ""
-#: includes/class-freemius.php:13569
+#: includes/class-freemius.php:13655
msgid "revert it now"
msgstr ""
-#: includes/class-freemius.php:13627
+#: includes/class-freemius.php:13713
msgid "An unknown error has occurred while trying to set the user's beta mode."
msgstr ""
-#: includes/class-freemius.php:13701
+#: includes/class-freemius.php:13799
msgid "Invalid new user ID or email address."
msgstr ""
-#: includes/class-freemius.php:13731
+#: includes/class-freemius.php:13829
msgid "Sorry, we could not complete the email update. Another user with the same email is already registered."
msgstr ""
-#: includes/class-freemius.php:13732
+#: includes/class-freemius.php:13830
msgid "If you would like to give up the ownership of the %s's account to %s click the Change Ownership button."
msgstr ""
-#: includes/class-freemius.php:13739
+#: includes/class-freemius.php:13837
msgid "Change Ownership"
msgstr ""
-#: includes/class-freemius.php:14336
+#: includes/class-freemius.php:14442
msgid "Invalid site details collection."
msgstr ""
-#: includes/class-freemius.php:14456
-msgid "We couldn't find your email address in the system, are you sure it's the right address?"
+#: includes/class-freemius.php:14564
+msgid "We can't see any active licenses associated with that email address, are you sure it's the right address?"
msgstr ""
-#: includes/class-freemius.php:14458
-msgid "We can't see any active licenses associated with that email address, are you sure it's the right address?"
+#: includes/class-freemius.php:14562
+msgid "We couldn't find your email address in the system, are you sure it's the right address?"
msgstr ""
-#: includes/class-freemius.php:14756
+#: includes/class-freemius.php:14868
msgid "Account is pending activation. Please check your email and click the link to activate your account and then submit the affiliate form again."
msgstr ""
-#: includes/class-freemius.php:14870, templates/forms/premium-versions-upgrade-handler.php:47
-msgid "Buy a license now"
+#: includes/class-freemius.php:14994, templates/forms/premium-versions-upgrade-handler.php:46
+msgid "Renew your license now"
msgstr ""
-#: includes/class-freemius.php:14882, templates/forms/premium-versions-upgrade-handler.php:46
-msgid "Renew your license now"
+#: includes/class-freemius.php:14982, templates/forms/premium-versions-upgrade-handler.php:47
+msgid "Buy a license now"
msgstr ""
-#: includes/class-freemius.php:14886
+#: includes/class-freemius.php:14998
msgid "%s to access version %s security & feature updates, and support."
msgstr ""
-#: includes/class-freemius.php:17621
+#: includes/class-freemius.php:17670
msgid "%s opt-in was successfully completed."
msgstr ""
-#: includes/class-freemius.php:17635
-msgid "Your account was successfully activated with the %s plan."
+#: includes/class-freemius.php:17694, includes/class-freemius.php:21631
+msgid "Your trial has been successfully started."
msgstr ""
-#: includes/class-freemius.php:17645, includes/class-freemius.php:21566
-msgid "Your trial has been successfully started."
+#: includes/class-freemius.php:17684
+msgid "Your account was successfully activated with the %s plan."
msgstr ""
-#: includes/class-freemius.php:18279, includes/class-freemius.php:18392, includes/class-freemius.php:18569
+#: includes/class-freemius.php:18328, includes/class-freemius.php:18441, includes/class-freemius.php:18618
msgid "Couldn't activate %s."
msgstr ""
-#: includes/class-freemius.php:18280, includes/class-freemius.php:18393, includes/class-freemius.php:18570
+#: includes/class-freemius.php:18329, includes/class-freemius.php:18442, includes/class-freemius.php:18619
msgid "Please contact us with the following message:"
msgstr ""
-#: includes/class-freemius.php:18389, templates/forms/data-debug-mode.php:162
+#: includes/class-freemius.php:18438, templates/forms/data-debug-mode.php:162
msgid "An unknown error has occurred."
msgstr ""
-#: includes/class-freemius.php:18931, includes/class-freemius.php:24339
+#: includes/class-freemius.php:18980, includes/class-freemius.php:24415
msgid "Upgrade"
msgstr ""
-#: includes/class-freemius.php:18937
-msgid "Start Trial"
+#: includes/class-freemius.php:18988
+msgid "Pricing"
msgstr ""
-#: includes/class-freemius.php:18939
-msgid "Pricing"
+#: includes/class-freemius.php:18986
+msgid "Start Trial"
msgstr ""
-#: includes/class-freemius.php:19019, includes/class-freemius.php:19021
+#: includes/class-freemius.php:19068, includes/class-freemius.php:19070
msgid "Affiliation"
msgstr ""
-#: includes/class-freemius.php:19049, includes/class-freemius.php:19051, templates/account.php:264, templates/debug.php:366
+#: includes/class-freemius.php:19098, includes/class-freemius.php:19100, templates/account.php:260, templates/debug.php:366
msgid "Account"
msgstr ""
-#: includes/class-freemius.php:19065, includes/class-freemius.php:19067, includes/customizer/class-fs-customizer-support-section.php:60
+#: includes/class-freemius.php:19114, includes/class-freemius.php:19116, includes/customizer/class-fs-customizer-support-section.php:60
msgid "Contact Us"
msgstr ""
-#: includes/class-freemius.php:19078, includes/class-freemius.php:19080, includes/class-freemius.php:24353, templates/account.php:134, templates/account/partials/addon.php:49
+#: includes/class-freemius.php:19127, includes/class-freemius.php:19129, includes/class-freemius.php:24429, templates/account.php:130, templates/account/partials/addon.php:49
msgid "Add-Ons"
msgstr ""
-#: includes/class-freemius.php:19114
+#: includes/class-freemius.php:19163
msgctxt "ASCII arrow left icon"
msgid "←"
msgstr ""
-#: includes/class-freemius.php:19114
+#: includes/class-freemius.php:19163
msgctxt "ASCII arrow right icon"
msgid "➤"
msgstr ""
-#: includes/class-freemius.php:19116, templates/pricing.php:110
+#: includes/class-freemius.php:19165, templates/pricing.php:110
msgctxt "noun"
msgid "Pricing"
msgstr ""
-#: includes/class-freemius.php:19329, includes/customizer/class-fs-customizer-support-section.php:67
+#: includes/class-freemius.php:19378, includes/customizer/class-fs-customizer-support-section.php:67
msgid "Support Forum"
msgstr ""
-#: includes/class-freemius.php:20350
+#: includes/class-freemius.php:20399
msgid "Your email has been successfully verified - you are AWESOME!"
msgstr ""
-#: includes/class-freemius.php:20351
+#: includes/class-freemius.php:20400
msgctxt "a positive response"
msgid "Right on"
msgstr ""
-#: includes/class-freemius.php:20857
+#: includes/class-freemius.php:20906
msgid "seems like the key you entered doesn't match our records."
msgstr ""
-#: includes/class-freemius.php:20881
+#: includes/class-freemius.php:20930
msgid "Debug mode was successfully enabled and will be automatically disabled in 60 min. You can also disable it earlier by clicking the \"Stop Debug\" link."
msgstr ""
-#: includes/class-freemius.php:21116
+#: includes/class-freemius.php:21165
msgid "Your %s Add-on plan was successfully upgraded."
msgstr ""
-#: includes/class-freemius.php:21118
+#. translators: %s:product name, e.g. Facebook add-on was successfully...
+#: includes/class-freemius.php:21167
msgid "%s Add-on was successfully purchased."
msgstr ""
-#: includes/class-freemius.php:21121
+#: includes/class-freemius.php:21170
msgid "Download the latest version"
msgstr ""
-#: includes/class-freemius.php:21239
+#: includes/class-freemius.php:21288
msgid "It seems like one of the authentication parameters is wrong. Update your Public Key, Secret Key & User ID, and try again."
msgstr ""
-#: includes/class-freemius.php:21239, includes/class-freemius.php:21636, includes/class-freemius.php:21737, includes/class-freemius.php:21824
+#: includes/class-freemius.php:21288, includes/class-freemius.php:21701, includes/class-freemius.php:21802, includes/class-freemius.php:21889
msgid "Error received from the server:"
msgstr ""
-#: includes/class-freemius.php:21470, includes/class-freemius.php:21742, includes/class-freemius.php:21795, includes/class-freemius.php:21902
+#: includes/class-freemius.php:21529, includes/class-freemius.php:21807, includes/class-freemius.php:21860, includes/class-freemius.php:21967
msgctxt "something somebody says when they are thinking about what you have just said."
msgid "Hmm"
msgstr ""
-#: includes/class-freemius.php:21483
+#: includes/class-freemius.php:21542
msgid "It looks like you are still on the %s plan. If you did upgrade or change your plan, it's probably an issue on our side - sorry."
msgstr ""
-#: includes/class-freemius.php:21484, templates/account.php:136, templates/add-ons.php:250, templates/account/partials/addon.php:51
+#: includes/class-freemius.php:21543, templates/account.php:132, templates/add-ons.php:250, templates/account/partials/addon.php:51
msgctxt "trial period"
msgid "Trial"
msgstr ""
-#: includes/class-freemius.php:21489
+#: includes/class-freemius.php:21548
msgid "I have upgraded my account but when I try to Sync the License, the plan remains %s."
msgstr ""
-#: includes/class-freemius.php:21493, includes/class-freemius.php:21545
+#: includes/class-freemius.php:21552, includes/class-freemius.php:21610
msgid "Please contact us here"
msgstr ""
-#: includes/class-freemius.php:21515
+#: includes/class-freemius.php:21580
msgid "Your plan was successfully changed to %s."
msgstr ""
-#: includes/class-freemius.php:21531
+#: includes/class-freemius.php:21596
msgid "Your license has expired. You can still continue using the free %s forever."
msgstr ""
-#: includes/class-freemius.php:21533
+#. translators: %1$s: product title; %2$s, %3$s: wrapping HTML anchor element; %4$s: 'plugin', 'theme', or 'add-on'.
+#: includes/class-freemius.php:21598
msgid "Your license has expired. %1$sUpgrade now%2$s to continue using the %3$s without interruptions."
msgstr ""
-#: includes/class-freemius.php:21541
+#: includes/class-freemius.php:21606
msgid "Your license has been cancelled. If you think it's a mistake, please contact support."
msgstr ""
-#: includes/class-freemius.php:21554
+#: includes/class-freemius.php:21619
msgid "Your license has expired. You can still continue using all the %s features, but you'll need to renew your license to continue getting updates and support."
msgstr ""
-#: includes/class-freemius.php:21580
+#: includes/class-freemius.php:21645
msgid "Your free trial has expired. You can still continue using all our free features."
msgstr ""
-#: includes/class-freemius.php:21582
+#. translators: %1$s: product title; %2$s, %3$s: wrapping HTML anchor element; %4$s: 'plugin', 'theme', or 'add-on'.
+#: includes/class-freemius.php:21647
msgid "Your free trial has expired. %1$sUpgrade now%2$s to continue using the %3$s without interruptions."
msgstr ""
-#: includes/class-freemius.php:21628
+#: includes/class-freemius.php:21693
msgid "Your server is blocking the access to Freemius' API, which is crucial for %1$s synchronization. Please contact your host to whitelist the following domains:%2$s"
msgstr ""
-#: includes/class-freemius.php:21630
+#: includes/class-freemius.php:21695
msgid "Show error details"
msgstr ""
-#: includes/class-freemius.php:21733
+#: includes/class-freemius.php:21798
msgid "It looks like the license could not be activated."
msgstr ""
-#: includes/class-freemius.php:21775
+#: includes/class-freemius.php:21840
msgid "Your license was successfully activated."
msgstr ""
-#: includes/class-freemius.php:21799
+#: includes/class-freemius.php:21864
msgid "It looks like your site currently doesn't have an active license."
msgstr ""
-#: includes/class-freemius.php:21823
+#: includes/class-freemius.php:21888
msgid "It looks like the license deactivation failed."
msgstr ""
-#: includes/class-freemius.php:21852
+#: includes/class-freemius.php:21917
msgid "Your %s license was successfully deactivated."
msgstr ""
-#: includes/class-freemius.php:21853
+#: includes/class-freemius.php:21918
msgid "Your license was successfully deactivated, you are back to the %s plan."
msgstr ""
-#: includes/class-freemius.php:21856
+#: includes/class-freemius.php:21921
msgid "O.K"
msgstr ""
-#: includes/class-freemius.php:21909
+#: includes/class-freemius.php:21974
msgid "Seems like we are having some temporary issue with your subscription cancellation. Please try again in few minutes."
msgstr ""
-#: includes/class-freemius.php:21918
+#: includes/class-freemius.php:21983
msgid "Your subscription was successfully cancelled. Your %s plan license will expire in %s."
msgstr ""
-#: includes/class-freemius.php:21960
+#: includes/class-freemius.php:22025
msgid "You are already running the %s in a trial mode."
msgstr ""
-#: includes/class-freemius.php:21971
+#: includes/class-freemius.php:22036
msgid "You already utilized a trial before."
msgstr ""
-#: includes/class-freemius.php:21985
-msgid "Plan %s do not exist, therefore, can't start a trial."
+#: includes/class-freemius.php:22072
+msgid "None of the %s's plans supports a trial period."
msgstr ""
-#: includes/class-freemius.php:21996
-msgid "Plan %s does not support a trial period."
+#: includes/class-freemius.php:22050
+msgid "Plan %s do not exist, therefore, can't start a trial."
msgstr ""
-#: includes/class-freemius.php:22007
-msgid "None of the %s's plans supports a trial period."
+#: includes/class-freemius.php:22061
+msgid "Plan %s does not support a trial period."
msgstr ""
-#: includes/class-freemius.php:22056
+#: includes/class-freemius.php:22121
msgid "It looks like you are not in trial mode anymore so there's nothing to cancel :)"
msgstr ""
-#: includes/class-freemius.php:22092
+#: includes/class-freemius.php:22157
msgid "Seems like we are having some temporary issue with your trial cancellation. Please try again in few minutes."
msgstr ""
-#: includes/class-freemius.php:22111
+#: includes/class-freemius.php:22176
msgid "Your %s free trial was successfully cancelled."
msgstr ""
-#: includes/class-freemius.php:22438
-msgid "Version %s was released."
+#: includes/class-freemius.php:22520
+msgid "Seems like you got the latest release."
msgstr ""
-#: includes/class-freemius.php:22438
-msgid "Please download %s."
+#: includes/class-freemius.php:22521
+msgid "You are all good!"
msgstr ""
-#: includes/class-freemius.php:22445
-msgid "the latest %s version here"
+#: includes/class-freemius.php:22503
+msgid "Version %s was released."
msgstr ""
-#: includes/class-freemius.php:22450
-msgid "New"
+#: includes/class-freemius.php:22503
+msgid "Please download %s."
msgstr ""
-#: includes/class-freemius.php:22455
-msgid "Seems like you got the latest release."
+#: includes/class-freemius.php:22510
+msgid "the latest %s version here"
msgstr ""
-#: includes/class-freemius.php:22456
-msgid "You are all good!"
+#: includes/class-freemius.php:22515
+msgid "New"
msgstr ""
-#: includes/class-freemius.php:22859
+#: includes/class-freemius.php:22924
msgid "Verification mail was just sent to %s. If you can't find it after 5 min, please check your spam box."
msgstr ""
-#: includes/class-freemius.php:22999
+#: includes/class-freemius.php:23064
msgid "Site successfully opted in."
msgstr ""
-#: includes/class-freemius.php:23000, includes/class-freemius.php:24049
+#: includes/class-freemius.php:23065, includes/class-freemius.php:24125
msgid "Awesome"
msgstr ""
-#: includes/class-freemius.php:23016
+#: includes/class-freemius.php:23091
+msgid "Diagnostic data will no longer be sent from %s to %s."
+msgstr ""
+
+#: includes/class-freemius.php:23081
msgid "Sharing diagnostic data with %s helps to provide functionality that's more relevant to your website, avoid WordPress or PHP version incompatibilities that can break your website, and recognize which languages & regions the plugin should be translated and tailored to."
msgstr ""
-#: includes/class-freemius.php:23017
+#: includes/class-freemius.php:23082
msgid "Thank you!"
msgstr ""
-#: includes/class-freemius.php:23026
-msgid "Diagnostic data will no longer be sent from %s to %s."
+#: includes/class-freemius.php:23251
+msgid "A confirmation email was just sent to %s. You must confirm the update within the next 4 hours. If you cannot find the email, please check your spam folder."
msgstr ""
-#: includes/class-freemius.php:23181
+#: includes/class-freemius.php:23249
msgid "A confirmation email was just sent to %s. The email owner must confirm the update within the next 4 hours."
msgstr ""
-#: includes/class-freemius.php:23183
-msgid "A confirmation email was just sent to %s. You must confirm the update within the next 4 hours. If you cannot find the email, please check your spam folder."
-msgstr ""
-
-#: includes/class-freemius.php:23190
+#: includes/class-freemius.php:23263
msgid "Thanks for confirming the ownership change. An email was just sent to %s for final approval."
msgstr ""
-#: includes/class-freemius.php:23195
+#: includes/class-freemius.php:23269
msgid "%s is the new owner of the account."
msgstr ""
-#: includes/class-freemius.php:23197
+#: includes/class-freemius.php:23271
msgctxt "as congratulations"
msgid "Congrats"
msgstr ""
-#: includes/class-freemius.php:23214
-msgid "Please provide your full name."
+#: includes/class-freemius.php:23293
+msgid "Your name was successfully updated."
msgstr ""
-#: includes/class-freemius.php:23219
-msgid "Your name was successfully updated."
+#: includes/class-freemius.php:23288
+msgid "Please provide your full name."
msgstr ""
-#: includes/class-freemius.php:23280
+#. translators: %s: User's account property (e.g. email address, name)
+#: includes/class-freemius.php:23358
msgid "You have successfully updated your %s."
msgstr ""
-#: includes/class-freemius.php:23339
+#: includes/class-freemius.php:23422
msgid "Is this your client's site? %s if you wish to hide sensitive info like your email, license key, prices, billing address & invoices from the WP Admin."
msgstr ""
-#: includes/class-freemius.php:23342
+#: includes/class-freemius.php:23425
msgid "Click here"
msgstr ""
-#: includes/class-freemius.php:23379, includes/class-freemius.php:23376
+#: includes/class-freemius.php:23462
msgid "Bundle"
msgstr ""
-#: includes/class-freemius.php:23459
+#: includes/class-freemius.php:23535
msgid "Just letting you know that the add-ons information of %s is being pulled from an external server."
msgstr ""
-#: includes/class-freemius.php:23460
+#: includes/class-freemius.php:23536
msgctxt "advance notice of something that will need attention."
msgid "Heads up"
msgstr ""
-#: includes/class-freemius.php:24089
+#: includes/class-freemius.php:24165
msgctxt "exclamation"
msgid "Hey"
msgstr ""
-#: includes/class-freemius.php:24089
+#: includes/class-freemius.php:24165
msgid "How do you like %s so far? Test all our %s premium features with a %d-day free trial."
msgstr ""
-#: includes/class-freemius.php:24097
+#: includes/class-freemius.php:24173
msgid "No commitment for %s days - cancel anytime!"
msgstr ""
-#: includes/class-freemius.php:24098
+#: includes/class-freemius.php:24174
msgid "No credit card required"
msgstr ""
-#: includes/class-freemius.php:24105, templates/forms/trial-start.php:53
+#: includes/class-freemius.php:24181, templates/forms/trial-start.php:53
msgctxt "call to action"
msgid "Start free trial"
msgstr ""
-#: includes/class-freemius.php:24182
+#: includes/class-freemius.php:24258
msgid "Hey there, did you know that %s has an affiliate program? If you like the %s you can become our ambassador and earn some cash!"
msgstr ""
-#: includes/class-freemius.php:24191
+#: includes/class-freemius.php:24267
msgid "Learn more"
msgstr ""
-#: includes/class-freemius.php:24377, templates/account.php:573, templates/account.php:725, templates/connect.php:221, templates/connect.php:447, includes/managers/class-fs-clone-manager.php:1295, templates/forms/license-activation.php:27, templates/account/partials/addon.php:326
+#: includes/class-freemius.php:24453, templates/account.php:569, templates/account.php:721, templates/connect.php:212, templates/connect.php:440, includes/managers/class-fs-clone-manager.php:1295, templates/forms/license-activation.php:27, templates/account/partials/addon.php:326
msgid "Activate License"
msgstr ""
-#: includes/class-freemius.php:24378, templates/account.php:667, templates/account.php:724, templates/account/partials/addon.php:327, templates/account/partials/site.php:273
+#: includes/class-freemius.php:24454, templates/account.php:663, templates/account.php:720, templates/account/partials/addon.php:327, templates/account/partials/site.php:273
msgid "Change License"
msgstr ""
-#: includes/class-freemius.php:24485, templates/account/partials/site.php:170
-msgid "Opt Out"
-msgstr ""
-
-#: includes/class-freemius.php:24487, includes/class-freemius.php:24493, templates/account/partials/site.php:49, templates/account/partials/site.php:170
+#: includes/class-freemius.php:24569, includes/class-freemius.php:24563, templates/account/partials/site.php:49, templates/account/partials/site.php:170
msgid "Opt In"
msgstr ""
-#: includes/class-freemius.php:24728
-msgid " The paid version of %1$s is already installed. Please activate it to start benefiting the %2$s features. %3$s"
-msgstr ""
-
-#: includes/class-freemius.php:24738
-msgid "Activate %s features"
+#: includes/class-freemius.php:24561, templates/account/partials/site.php:170
+msgid "Opt Out"
msgstr ""
-#: includes/class-freemius.php:24751
+#: includes/class-freemius.php:24827
msgid "Please follow these steps to complete the upgrade"
msgstr ""
-#: includes/class-freemius.php:24755
+#. translators: %s: Plan title
+#: includes/class-freemius.php:24831
msgid "Download the latest %s version"
msgstr ""
-#: includes/class-freemius.php:24759
+#: includes/class-freemius.php:24835
msgid "Upload and activate the downloaded version"
msgstr ""
-#: includes/class-freemius.php:24761
+#: includes/class-freemius.php:24837
msgid "How to upload and activate?"
msgstr ""
-#: includes/class-freemius.php:24796
+#: includes/class-freemius.php:24804
+msgid " The paid version of %1$s is already installed. Please activate it to start benefiting the %2$s features. %3$s"
+msgstr ""
+
+#: includes/class-freemius.php:24814
+msgid "Activate %s features"
+msgstr ""
+
+#: includes/class-freemius.php:24872
msgid "Your plan was successfully upgraded."
msgstr ""
-#: includes/class-freemius.php:24797
+#: includes/class-freemius.php:24873
msgid "Your plan was successfully activated."
msgstr ""
-#: includes/class-freemius.php:24927
+#: includes/class-freemius.php:25003
msgid "%sClick here%s to choose the sites where you'd like to activate the license on."
msgstr ""
-#: includes/class-freemius.php:25096
+#: includes/class-freemius.php:25172
msgid "Auto installation only works for opted-in users."
msgstr ""
-#: includes/class-freemius.php:25106, includes/class-freemius.php:25139, includes/class-fs-plugin-updater.php:1294, includes/class-fs-plugin-updater.php:1308
+#: includes/class-freemius.php:25182, includes/class-freemius.php:25215, includes/class-fs-plugin-updater.php:1291, includes/class-fs-plugin-updater.php:1305
msgid "Invalid module ID."
msgstr ""
-#: includes/class-freemius.php:25115, includes/class-fs-plugin-updater.php:1330
+#: includes/class-freemius.php:25223, includes/class-fs-plugin-updater.php:1326
+msgid "Premium add-on version already installed."
+msgstr ""
+
+#: includes/class-freemius.php:25191, includes/class-fs-plugin-updater.php:1327
msgid "Premium version already active."
msgstr ""
-#: includes/class-freemius.php:25122
+#: includes/class-freemius.php:25198
msgid "You do not have a valid license to access the premium version."
msgstr ""
-#: includes/class-freemius.php:25129
+#: includes/class-freemius.php:25205
msgid "Plugin is a \"Serviceware\" which means it does not have a premium code version."
msgstr ""
-#: includes/class-freemius.php:25147, includes/class-fs-plugin-updater.php:1329
-msgid "Premium add-on version already installed."
-msgstr ""
-
-#: includes/class-freemius.php:25501
+#: includes/class-freemius.php:25583
msgid "View paid features"
msgstr ""
-#: includes/class-freemius.php:25805
-msgid "Thank you so much for using %s and its add-ons!"
+#: includes/class-freemius.php:25898
+msgid "Thank you so much for using our products!"
msgstr ""
-#: includes/class-freemius.php:25806
-msgid "Thank you so much for using %s!"
+#: includes/class-freemius.php:25899
+msgid "You've already opted-in to our usage-tracking, which helps us keep improving them."
msgstr ""
-#: includes/class-freemius.php:25812
-msgid "You've already opted-in to our usage-tracking, which helps us keep improving the %s."
+#: includes/class-freemius.php:25918
+msgid "%s and its add-ons"
msgstr ""
-#: includes/class-freemius.php:25816
-msgid "Thank you so much for using our products!"
+#: includes/class-freemius.php:25927
+msgid "Products"
msgstr ""
-#: includes/class-freemius.php:25817
-msgid "You've already opted-in to our usage-tracking, which helps us keep improving them."
+#: includes/class-freemius.php:25887
+msgid "Thank you so much for using %s and its add-ons!"
msgstr ""
-#: includes/class-freemius.php:25836
-msgid "%s and its add-ons"
+#: includes/class-freemius.php:25888
+msgid "Thank you so much for using %s!"
msgstr ""
-#: includes/class-freemius.php:25845
-msgid "Products"
+#: includes/class-freemius.php:25894
+msgid "You've already opted-in to our usage-tracking, which helps us keep improving the %s."
msgstr ""
-#: includes/class-freemius.php:25852, templates/connect.php:322
+#: includes/class-freemius.php:25934, templates/connect.php:313
msgid "Yes"
msgstr ""
-#: includes/class-freemius.php:25853, templates/connect.php:323
+#: includes/class-freemius.php:25935, templates/connect.php:314
msgid "send me security & feature updates, educational content and offers."
msgstr ""
-#: includes/class-freemius.php:25854, templates/connect.php:328
+#: includes/class-freemius.php:25936, templates/connect.php:319
msgid "No"
msgstr ""
-#: includes/class-freemius.php:25856, templates/connect.php:330
+#: includes/class-freemius.php:25938, templates/connect.php:321
msgid "do %sNOT%s send me security & feature updates, educational content and offers."
msgstr ""
-#: includes/class-freemius.php:25866
+#: includes/class-freemius.php:25948
msgid "Due to the new %sEU General Data Protection Regulation (GDPR)%s compliance requirements it is required that you provide your explicit consent, again, confirming that you are onboard :-)"
msgstr ""
-#: includes/class-freemius.php:25868, templates/connect.php:337
+#: includes/class-freemius.php:25950, templates/connect.php:328
msgid "Please let us know if you'd like us to contact you for security & feature updates, educational content, and occasional offers:"
msgstr ""
-#: includes/class-freemius.php:26158
+#: includes/class-freemius.php:26240
msgid "License key is empty."
msgstr ""
-#: includes/class-fs-plugin-updater.php:210, templates/forms/premium-versions-upgrade-handler.php:57
+#: includes/class-fs-plugin-updater.php:212, templates/forms/premium-versions-upgrade-handler.php:57
msgid "Renew license"
msgstr ""
-#: includes/class-fs-plugin-updater.php:215, templates/forms/premium-versions-upgrade-handler.php:58
+#: includes/class-fs-plugin-updater.php:217, templates/forms/premium-versions-upgrade-handler.php:58
msgid "Buy license"
msgstr ""
-#: includes/class-fs-plugin-updater.php:335, includes/class-fs-plugin-updater.php:368
+#: includes/class-fs-plugin-updater.php:370, includes/class-fs-plugin-updater.php:337
msgid "There is a %s of %s available."
msgstr ""
-#: includes/class-fs-plugin-updater.php:337, includes/class-fs-plugin-updater.php:373
+#: includes/class-fs-plugin-updater.php:375, includes/class-fs-plugin-updater.php:339
msgid "new Beta version"
msgstr ""
-#: includes/class-fs-plugin-updater.php:338, includes/class-fs-plugin-updater.php:374
+#: includes/class-fs-plugin-updater.php:376, includes/class-fs-plugin-updater.php:340
msgid "new version"
msgstr ""
-#: includes/class-fs-plugin-updater.php:397
+#: includes/class-fs-plugin-updater.php:399
msgid "Important Upgrade Notice:"
msgstr ""
-#: includes/class-fs-plugin-updater.php:1359
+#: includes/class-fs-plugin-updater.php:1356
msgid "Installing plugin: %s"
msgstr ""
-#: includes/class-fs-plugin-updater.php:1400
+#: includes/class-fs-plugin-updater.php:1397
msgid "Unable to connect to the filesystem. Please confirm your credentials."
msgstr ""
-#: includes/class-fs-plugin-updater.php:1582
+#: includes/class-fs-plugin-updater.php:1579
msgid "The remote plugin package does not contain a folder with the desired slug and renaming did not work."
msgstr ""
@@ -887,24 +895,25 @@ msgctxt "verb"
msgid "Purchase"
msgstr ""
+#. translators: %s: N-days trial
#: includes/fs-plugin-info-dialog.php:547
msgid "Start my free %s"
msgstr ""
-#: includes/fs-plugin-info-dialog.php:745
-msgid "Install Free Version Update Now"
+#: includes/fs-plugin-info-dialog.php:755
+msgid "Install Free Version Now"
msgstr ""
-#: includes/fs-plugin-info-dialog.php:746, templates/account.php:656
-msgid "Install Update Now"
+#: includes/fs-plugin-info-dialog.php:756, templates/add-ons.php:323, templates/auto-installation.php:111, templates/account/partials/addon.php:423, templates/account/partials/addon.php:370
+msgid "Install Now"
msgstr ""
-#: includes/fs-plugin-info-dialog.php:755
-msgid "Install Free Version Now"
+#: includes/fs-plugin-info-dialog.php:745
+msgid "Install Free Version Update Now"
msgstr ""
-#: includes/fs-plugin-info-dialog.php:756, templates/add-ons.php:323, templates/auto-installation.php:111, templates/account/partials/addon.php:370, templates/account/partials/addon.php:423
-msgid "Install Now"
+#: includes/fs-plugin-info-dialog.php:746, templates/account.php:652
+msgid "Install Update Now"
msgstr ""
#: includes/fs-plugin-info-dialog.php:772
@@ -912,558 +921,569 @@ msgctxt "as download latest version"
msgid "Download Latest Free Version"
msgstr ""
-#: includes/fs-plugin-info-dialog.php:773, templates/account.php:114, templates/add-ons.php:37, templates/account/partials/addon.php:30
+#: includes/fs-plugin-info-dialog.php:773, templates/account.php:110, templates/add-ons.php:37, templates/account/partials/addon.php:30
msgctxt "as download latest version"
msgid "Download Latest"
msgstr ""
-#: includes/fs-plugin-info-dialog.php:788, templates/add-ons.php:329, templates/account/partials/addon.php:361, templates/account/partials/addon.php:417
+#: includes/fs-plugin-info-dialog.php:788, templates/add-ons.php:329, templates/account/partials/addon.php:417, templates/account/partials/addon.php:361
msgid "Activate this add-on"
msgstr ""
-#: includes/fs-plugin-info-dialog.php:790, templates/connect.php:444
+#: includes/fs-plugin-info-dialog.php:790, templates/connect.php:437
msgid "Activate Free Version"
msgstr ""
-#: includes/fs-plugin-info-dialog.php:791, templates/account.php:138, templates/add-ons.php:330, templates/account/partials/addon.php:53
+#: includes/fs-plugin-info-dialog.php:791, templates/account.php:134, templates/add-ons.php:330, templates/account/partials/addon.php:53
msgid "Activate"
msgstr ""
-#: includes/fs-plugin-info-dialog.php:1003
+#: includes/fs-plugin-info-dialog.php:999
msgctxt "Plugin installer section title"
msgid "Description"
msgstr ""
-#: includes/fs-plugin-info-dialog.php:1004
+#: includes/fs-plugin-info-dialog.php:1000
msgctxt "Plugin installer section title"
msgid "Installation"
msgstr ""
-#: includes/fs-plugin-info-dialog.php:1005
+#: includes/fs-plugin-info-dialog.php:1001
msgctxt "Plugin installer section title"
msgid "FAQ"
msgstr ""
-#: includes/fs-plugin-info-dialog.php:1006, templates/plugin-info/description.php:55
+#: includes/fs-plugin-info-dialog.php:1002, templates/plugin-info/description.php:55
msgid "Screenshots"
msgstr ""
-#: includes/fs-plugin-info-dialog.php:1007
+#: includes/fs-plugin-info-dialog.php:1003
msgctxt "Plugin installer section title"
msgid "Changelog"
msgstr ""
-#: includes/fs-plugin-info-dialog.php:1008
+#: includes/fs-plugin-info-dialog.php:1004
msgctxt "Plugin installer section title"
msgid "Reviews"
msgstr ""
-#: includes/fs-plugin-info-dialog.php:1009
+#: includes/fs-plugin-info-dialog.php:1005
msgctxt "Plugin installer section title"
msgid "Other Notes"
msgstr ""
-#: includes/fs-plugin-info-dialog.php:1024
+#: includes/fs-plugin-info-dialog.php:1020
msgctxt "Plugin installer section title"
msgid "Features & Pricing"
msgstr ""
-#: includes/fs-plugin-info-dialog.php:1034
+#: includes/fs-plugin-info-dialog.php:1030
msgid "Plugin Install"
msgstr ""
-#: includes/fs-plugin-info-dialog.php:1106
+#: includes/fs-plugin-info-dialog.php:1102
msgctxt "e.g. Professional Plan"
msgid "%s Plan"
msgstr ""
-#: includes/fs-plugin-info-dialog.php:1132
+#: includes/fs-plugin-info-dialog.php:1128
msgctxt "e.g. the best product"
msgid "Best"
msgstr ""
-#: includes/fs-plugin-info-dialog.php:1138, includes/fs-plugin-info-dialog.php:1158
+#: includes/fs-plugin-info-dialog.php:1134, includes/fs-plugin-info-dialog.php:1154
msgctxt "as every month"
msgid "Monthly"
msgstr ""
-#: includes/fs-plugin-info-dialog.php:1141
+#: includes/fs-plugin-info-dialog.php:1137
msgctxt "as once a year"
msgid "Annual"
msgstr ""
-#: includes/fs-plugin-info-dialog.php:1144
+#: includes/fs-plugin-info-dialog.php:1140
msgid "Lifetime"
msgstr ""
-#: includes/fs-plugin-info-dialog.php:1158, includes/fs-plugin-info-dialog.php:1160, includes/fs-plugin-info-dialog.php:1162
+#: includes/fs-plugin-info-dialog.php:1154, includes/fs-plugin-info-dialog.php:1156, includes/fs-plugin-info-dialog.php:1158
msgctxt "e.g. billed monthly"
msgid "Billed %s"
msgstr ""
-#: includes/fs-plugin-info-dialog.php:1160
+#: includes/fs-plugin-info-dialog.php:1156
msgctxt "as once a year"
msgid "Annually"
msgstr ""
-#: includes/fs-plugin-info-dialog.php:1162
+#: includes/fs-plugin-info-dialog.php:1158
msgctxt "as once a year"
msgid "Once"
msgstr ""
-#: includes/fs-plugin-info-dialog.php:1168
+#: includes/fs-plugin-info-dialog.php:1164
msgid "Single Site License"
msgstr ""
-#: includes/fs-plugin-info-dialog.php:1170
+#: includes/fs-plugin-info-dialog.php:1166
msgid "Unlimited Licenses"
msgstr ""
-#: includes/fs-plugin-info-dialog.php:1172
+#: includes/fs-plugin-info-dialog.php:1168
msgid "Up to %s Sites"
msgstr ""
-#: includes/fs-plugin-info-dialog.php:1182, templates/plugin-info/features.php:82
+#: includes/fs-plugin-info-dialog.php:1178, templates/plugin-info/features.php:82
msgctxt "as monthly period"
msgid "mo"
msgstr ""
-#: includes/fs-plugin-info-dialog.php:1189, templates/plugin-info/features.php:80
+#: includes/fs-plugin-info-dialog.php:1185, templates/plugin-info/features.php:80
msgctxt "as annual period"
msgid "year"
msgstr ""
-#: includes/fs-plugin-info-dialog.php:1243
+#: includes/fs-plugin-info-dialog.php:1239
msgctxt "noun"
msgid "Price"
msgstr ""
-#: includes/fs-plugin-info-dialog.php:1291
+#. translators: %s: Discount (e.g. discount of $5 or 10%)
+#: includes/fs-plugin-info-dialog.php:1287
msgid "Save %s"
msgstr ""
-#: includes/fs-plugin-info-dialog.php:1301
+#: includes/fs-plugin-info-dialog.php:1297
msgid "No commitment for %s - cancel anytime"
msgstr ""
-#: includes/fs-plugin-info-dialog.php:1304
+#: includes/fs-plugin-info-dialog.php:1300
msgid "After your free %s, pay as little as %s"
msgstr ""
-#: includes/fs-plugin-info-dialog.php:1315
+#: includes/fs-plugin-info-dialog.php:1311
msgid "Details"
msgstr ""
-#: includes/fs-plugin-info-dialog.php:1319, templates/account.php:125, templates/debug.php:232, templates/debug.php:269, templates/debug.php:518, templates/account/partials/addon.php:41
+#: includes/fs-plugin-info-dialog.php:1315, templates/account.php:121, templates/debug.php:232, templates/debug.php:269, templates/debug.php:518, templates/account/partials/addon.php:41
msgctxt "product version"
msgid "Version"
msgstr ""
-#: includes/fs-plugin-info-dialog.php:1326
+#: includes/fs-plugin-info-dialog.php:1322
msgctxt "as the plugin author"
msgid "Author"
msgstr ""
-#: includes/fs-plugin-info-dialog.php:1333
+#: includes/fs-plugin-info-dialog.php:1329
msgid "Last Updated"
msgstr ""
-#: includes/fs-plugin-info-dialog.php:1338, templates/account.php:544
+#. translators: %s: time period (e.g. "2 hours" ago)
+#: includes/fs-plugin-info-dialog.php:1334, templates/account.php:540
msgctxt "x-ago"
msgid "%s ago"
msgstr ""
-#: includes/fs-plugin-info-dialog.php:1347
+#: includes/fs-plugin-info-dialog.php:1343
msgid "Requires WordPress Version"
msgstr ""
-#: includes/fs-plugin-info-dialog.php:1350, includes/fs-plugin-info-dialog.php:1370
+#. translators: %s: Version number.
+#: includes/fs-plugin-info-dialog.php:1346, includes/fs-plugin-info-dialog.php:1366
msgid "%s or higher"
msgstr ""
-#: includes/fs-plugin-info-dialog.php:1358
+#: includes/fs-plugin-info-dialog.php:1354
msgid "Compatible up to"
msgstr ""
-#: includes/fs-plugin-info-dialog.php:1366
+#: includes/fs-plugin-info-dialog.php:1362
msgid "Requires PHP Version"
msgstr ""
-#: includes/fs-plugin-info-dialog.php:1379
+#: includes/fs-plugin-info-dialog.php:1375
msgid "Downloaded"
msgstr ""
-#: includes/fs-plugin-info-dialog.php:1383
+#. translators: %s: 1 or One (Number of times downloaded)
+#: includes/fs-plugin-info-dialog.php:1379
msgid "%s time"
msgstr ""
-#: includes/fs-plugin-info-dialog.php:1385
+#. translators: %s: Number of times downloaded
+#: includes/fs-plugin-info-dialog.php:1381
msgid "%s times"
msgstr ""
-#: includes/fs-plugin-info-dialog.php:1396
+#: includes/fs-plugin-info-dialog.php:1392
msgid "WordPress.org Plugin Page"
msgstr ""
-#: includes/fs-plugin-info-dialog.php:1405
+#: includes/fs-plugin-info-dialog.php:1401
msgid "Plugin Homepage"
msgstr ""
-#: includes/fs-plugin-info-dialog.php:1414, includes/fs-plugin-info-dialog.php:1498
+#: includes/fs-plugin-info-dialog.php:1410, includes/fs-plugin-info-dialog.php:1494
msgid "Donate to this plugin"
msgstr ""
-#: includes/fs-plugin-info-dialog.php:1421
+#: includes/fs-plugin-info-dialog.php:1417
msgid "Average Rating"
msgstr ""
-#: includes/fs-plugin-info-dialog.php:1428
+#: includes/fs-plugin-info-dialog.php:1424
msgid "based on %s"
msgstr ""
-#: includes/fs-plugin-info-dialog.php:1432
+#. translators: %s: 1 or One
+#: includes/fs-plugin-info-dialog.php:1428
msgid "%s rating"
msgstr ""
-#: includes/fs-plugin-info-dialog.php:1434
+#. translators: %s: Number larger than 1
+#: includes/fs-plugin-info-dialog.php:1430
msgid "%s ratings"
msgstr ""
-#: includes/fs-plugin-info-dialog.php:1449
+#. translators: %s: 1 or One
+#: includes/fs-plugin-info-dialog.php:1445
msgid "%s star"
msgstr ""
-#: includes/fs-plugin-info-dialog.php:1451
+#. translators: %s: Number larger than 1
+#: includes/fs-plugin-info-dialog.php:1447
msgid "%s stars"
msgstr ""
-#: includes/fs-plugin-info-dialog.php:1463
+#. translators: %s: # of stars (e.g. 5 stars)
+#: includes/fs-plugin-info-dialog.php:1459
msgid "Click to see reviews that provided a rating of %s"
msgstr ""
-#: includes/fs-plugin-info-dialog.php:1476
+#: includes/fs-plugin-info-dialog.php:1472
msgid "Contributors"
msgstr ""
-#: includes/fs-plugin-info-dialog.php:1517
+#: includes/fs-plugin-info-dialog.php:1513
msgid "This plugin requires a newer version of PHP."
msgstr ""
-#: includes/fs-plugin-info-dialog.php:1526
+#. translators: %s: URL to Update PHP page.
+#: includes/fs-plugin-info-dialog.php:1522
msgid "Click here to learn more about updating PHP ."
msgstr ""
-#: includes/fs-plugin-info-dialog.php:1540, includes/fs-plugin-info-dialog.php:1542
+#: includes/fs-plugin-info-dialog.php:1538, includes/fs-plugin-info-dialog.php:1536
msgid "Warning"
msgstr ""
-#: includes/fs-plugin-info-dialog.php:1540
-msgid "This plugin has not been tested with your current version of WordPress."
+#: includes/fs-plugin-info-dialog.php:1538
+msgid "This plugin has not been marked as compatible with your version of WordPress."
msgstr ""
-#: includes/fs-plugin-info-dialog.php:1542
-msgid "This plugin has not been marked as compatible with your version of WordPress."
+#: includes/fs-plugin-info-dialog.php:1536
+msgid "This plugin has not been tested with your current version of WordPress."
msgstr ""
-#: includes/fs-plugin-info-dialog.php:1561
+#: includes/fs-plugin-info-dialog.php:1557
msgid "Paid add-on must be deployed to Freemius."
msgstr ""
-#: includes/fs-plugin-info-dialog.php:1562
+#: includes/fs-plugin-info-dialog.php:1558
msgid "Add-on must be deployed to WordPress.org or Freemius."
msgstr ""
-#: includes/fs-plugin-info-dialog.php:1583
-msgid "Newer Version (%s) Installed"
+#: includes/fs-plugin-info-dialog.php:1587
+msgid "Latest Version Installed"
msgstr ""
-#: includes/fs-plugin-info-dialog.php:1584
-msgid "Newer Free Version (%s) Installed"
+#: includes/fs-plugin-info-dialog.php:1588
+msgid "Latest Free Version Installed"
msgstr ""
-#: includes/fs-plugin-info-dialog.php:1591
-msgid "Latest Version Installed"
+#: includes/fs-plugin-info-dialog.php:1579
+msgid "Newer Version (%s) Installed"
msgstr ""
-#: includes/fs-plugin-info-dialog.php:1592
-msgid "Latest Free Version Installed"
+#: includes/fs-plugin-info-dialog.php:1580
+msgid "Newer Free Version (%s) Installed"
msgstr ""
-#: templates/account.php:115, templates/forms/subscription-cancellation.php:96, templates/account/partials/addon.php:31, templates/account/partials/site.php:313
+#: templates/account.php:111, templates/forms/subscription-cancellation.php:96, templates/account/partials/addon.php:31, templates/account/partials/site.php:313
msgid "Downgrading your plan"
msgstr ""
-#: templates/account.php:116, templates/forms/subscription-cancellation.php:97, templates/account/partials/addon.php:32, templates/account/partials/site.php:314
+#: templates/account.php:112, templates/forms/subscription-cancellation.php:97, templates/account/partials/addon.php:32, templates/account/partials/site.php:314
msgid "Cancelling the subscription"
msgstr ""
#. translators: %1$s: Either 'Downgrading your plan' or 'Cancelling the subscription'
-#: templates/account.php:118, templates/forms/subscription-cancellation.php:99, templates/account/partials/site.php:316
+#: templates/account.php:114, templates/forms/subscription-cancellation.php:99, templates/account/partials/addon.php:34, templates/account/partials/site.php:316
msgid "%1$s will immediately stop all future recurring payments and your %2$s plan license will expire in %3$s."
msgstr ""
-#: templates/account.php:119, templates/forms/subscription-cancellation.php:100, templates/account/partials/addon.php:35, templates/account/partials/site.php:317
+#: templates/account.php:115, templates/forms/subscription-cancellation.php:100, templates/account/partials/addon.php:35, templates/account/partials/site.php:317
msgid "Please note that we will not be able to grandfather outdated pricing for renewals/new subscriptions after a cancellation. If you choose to renew the subscription manually in the future, after a price increase, which typically occurs once a year, you will be charged the updated price."
msgstr ""
-#: templates/account.php:120, templates/forms/subscription-cancellation.php:106, templates/account/partials/addon.php:36
+#: templates/account.php:116, templates/forms/subscription-cancellation.php:106, templates/account/partials/addon.php:36
msgid "Cancelling the trial will immediately block access to all premium features. Are you sure?"
msgstr ""
-#: templates/account.php:121, templates/forms/subscription-cancellation.php:101, templates/account/partials/addon.php:37, templates/account/partials/site.php:318
+#: templates/account.php:117, templates/forms/subscription-cancellation.php:101, templates/account/partials/addon.php:37, templates/account/partials/site.php:318
msgid "You can still enjoy all %s features but you will not have access to %s security & feature updates, nor support."
msgstr ""
-#: templates/account.php:122, templates/forms/subscription-cancellation.php:102, templates/account/partials/addon.php:38, templates/account/partials/site.php:319
+#: templates/account.php:118, templates/forms/subscription-cancellation.php:102, templates/account/partials/addon.php:38, templates/account/partials/site.php:319
msgid "Once your license expires you can still use the Free version but you will NOT have access to the %s features."
msgstr ""
#. translators: %s: Plan title (e.g. "Professional")
-#: templates/account.php:124, templates/account/partials/activate-license-button.php:31, templates/account/partials/addon.php:40
+#: templates/account.php:120, templates/account/partials/activate-license-button.php:31, templates/account/partials/addon.php:40
msgid "Activate %s Plan"
msgstr ""
#. translators: %s: Time period (e.g. Auto renews in "2 months")
-#: templates/account.php:127, templates/account/partials/addon.php:43, templates/account/partials/site.php:293
+#: templates/account.php:123, templates/account/partials/addon.php:43, templates/account/partials/site.php:293
msgid "Auto renews in %s"
msgstr ""
#. translators: %s: Time period (e.g. Expires in "2 months")
-#: templates/account.php:129, templates/account/partials/addon.php:45, templates/account/partials/site.php:295
+#: templates/account.php:125, templates/account/partials/addon.php:45, templates/account/partials/site.php:295
msgid "Expires in %s"
msgstr ""
-#: templates/account.php:130
+#: templates/account.php:126
msgctxt "as synchronize license"
msgid "Sync License"
msgstr ""
-#: templates/account.php:131, templates/account/partials/addon.php:46
+#: templates/account.php:127, templates/account/partials/addon.php:46
msgid "Cancel Trial"
msgstr ""
-#: templates/account.php:132, templates/account/partials/addon.php:47
+#: templates/account.php:128, templates/account/partials/addon.php:47
msgid "Change Plan"
msgstr ""
-#: templates/account.php:133, templates/account/partials/addon.php:48
+#: templates/account.php:129, templates/account/partials/addon.php:48
msgctxt "verb"
msgid "Upgrade"
msgstr ""
-#: templates/account.php:135, templates/account/partials/addon.php:50, templates/account/partials/site.php:320
+#: templates/account.php:131, templates/account/partials/addon.php:50, templates/account/partials/site.php:320
msgctxt "verb"
msgid "Downgrade"
msgstr ""
-#: templates/account.php:137, templates/add-ons.php:246, templates/plugin-info/features.php:72, templates/account/partials/addon.php:52, templates/account/partials/site.php:33
+#: templates/account.php:133, templates/add-ons.php:246, templates/plugin-info/features.php:72, templates/account/partials/addon.php:52, templates/account/partials/site.php:33
msgid "Free"
msgstr ""
-#: templates/account.php:139, templates/debug.php:412, includes/customizer/class-fs-customizer-upsell-control.php:110, templates/account/partials/addon.php:54
+#: templates/account.php:135, templates/debug.php:412, includes/customizer/class-fs-customizer-upsell-control.php:110, templates/account/partials/addon.php:54
msgctxt "as product pricing plan"
msgid "Plan"
msgstr ""
-#: templates/account.php:140
+#: templates/account.php:136
msgid "Bundle Plan"
msgstr ""
-#: templates/account.php:272
+#: templates/account.php:268
msgid "Free Trial"
msgstr ""
-#: templates/account.php:283
+#: templates/account.php:279
msgid "Account Details"
msgstr ""
-#: templates/account.php:290, templates/forms/data-debug-mode.php:33
-msgid "Start Debug"
+#: templates/account.php:288
+msgid "Stop Debug"
msgstr ""
-#: templates/account.php:292
-msgid "Stop Debug"
+#: templates/account.php:286, templates/forms/data-debug-mode.php:33
+msgid "Start Debug"
msgstr ""
-#: templates/account.php:299
+#: templates/account.php:295
msgid "Billing & Invoices"
msgstr ""
-#: templates/account.php:322, templates/account/partials/addon.php:236, templates/account/partials/deactivate-license-button.php:35
+#: templates/account.php:318, templates/account/partials/addon.php:236, templates/account/partials/deactivate-license-button.php:35
msgid "Deactivate License"
msgstr ""
-#: templates/account.php:345, templates/forms/subscription-cancellation.php:125
+#: templates/account.php:341, templates/forms/subscription-cancellation.php:125
msgid "Are you sure you want to proceed?"
msgstr ""
-#: templates/account.php:345, templates/account/partials/addon.php:260
+#: templates/account.php:341, templates/account/partials/addon.php:260
msgid "Cancel Subscription"
msgstr ""
-#: templates/account.php:374, templates/account/partials/addon.php:345
+#: templates/account.php:370, templates/account/partials/addon.php:345
msgctxt "as synchronize"
msgid "Sync"
msgstr ""
-#: templates/account.php:389, templates/debug.php:575
+#: templates/account.php:385, templates/debug.php:575
msgid "Name"
msgstr ""
-#: templates/account.php:395, templates/debug.php:576
+#: templates/account.php:391, templates/debug.php:576
msgid "Email"
msgstr ""
-#: templates/account.php:402, templates/debug.php:410, templates/debug.php:625
+#: templates/account.php:398, templates/debug.php:410, templates/debug.php:625
msgid "User ID"
msgstr ""
-#: templates/account.php:420, templates/account.php:738, templates/account.php:789, templates/debug.php:267, templates/debug.php:404, templates/debug.php:515, templates/debug.php:574, templates/debug.php:623, templates/debug.php:702, templates/account/payments.php:35, templates/debug/logger.php:21
+#: templates/account.php:416, templates/account.php:734, templates/account.php:785, templates/debug.php:267, templates/debug.php:404, templates/debug.php:515, templates/debug.php:574, templates/debug.php:623, templates/debug.php:702, templates/account/payments.php:35, templates/debug/logger.php:21
msgid "ID"
msgstr ""
-#: templates/account.php:427
+#: templates/account.php:423
msgid "Site ID"
msgstr ""
-#: templates/account.php:430
+#: templates/account.php:426
msgid "No ID"
msgstr ""
-#: templates/account.php:435, templates/debug.php:274, templates/debug.php:413, templates/debug.php:519, templates/debug.php:578, templates/account/partials/site.php:228
+#: templates/account.php:431, templates/debug.php:274, templates/debug.php:413, templates/debug.php:519, templates/debug.php:578, templates/account/partials/site.php:228
msgid "Public Key"
msgstr ""
-#: templates/account.php:441, templates/debug.php:414, templates/debug.php:520, templates/debug.php:579, templates/account/partials/site.php:241
+#: templates/account.php:437, templates/debug.php:414, templates/debug.php:520, templates/debug.php:579, templates/account/partials/site.php:241
msgid "Secret Key"
msgstr ""
-#: templates/account.php:444
+#: templates/account.php:440
msgctxt "as secret encryption key missing"
msgid "No Secret"
msgstr ""
-#: templates/account.php:471, templates/account/partials/site.php:120, templates/account/partials/site.php:122
-msgid "Trial"
+#: templates/account.php:494, templates/debug.php:631, templates/account/partials/site.php:262
+msgid "License Key"
msgstr ""
-#: templates/account.php:498, templates/debug.php:631, templates/account/partials/site.php:262
-msgid "License Key"
+#: templates/account.php:467, templates/account/partials/site.php:122, templates/account/partials/site.php:120
+msgid "Trial"
msgstr ""
-#: templates/account.php:529
+#: templates/account.php:525
msgid "Join the Beta program"
msgstr ""
-#: templates/account.php:535
+#: templates/account.php:531
msgid "not verified"
msgstr ""
-#: templates/account.php:544, templates/account/partials/addon.php:195
-msgid "Expired"
+#: templates/account.php:600
+msgid "Free version"
msgstr ""
-#: templates/account.php:602
+#: templates/account.php:598
msgid "Premium version"
msgstr ""
-#: templates/account.php:604
-msgid "Free version"
+#: templates/account.php:540, templates/account/partials/addon.php:195
+msgid "Expired"
msgstr ""
-#: templates/account.php:616
+#: templates/account.php:612
msgid "Verify Email"
msgstr ""
-#: templates/account.php:630
-msgid "Download %s Version"
+#: templates/account.php:689, templates/forms/user-change.php:27
+msgid "Change User"
msgstr ""
-#: templates/account.php:646
-msgid "Download Paid Version"
+#: templates/account.php:676
+msgid "What is your %s?"
msgstr ""
-#: templates/account.php:664, templates/account.php:927, templates/account/partials/site.php:250, templates/account/partials/site.php:272
+#: templates/account.php:684, templates/account/billing.php:21
msgctxt "verb"
-msgid "Show"
+msgid "Edit"
msgstr ""
-#: templates/account.php:680
-msgid "What is your %s?"
+#: templates/account.php:660, templates/account.php:923, templates/account/partials/site.php:250, templates/account/partials/site.php:272
+msgctxt "verb"
+msgid "Show"
msgstr ""
-#: templates/account.php:688, templates/account/billing.php:21
-msgctxt "verb"
-msgid "Edit"
+#: templates/account.php:626
+msgid "Download %s Version"
msgstr ""
-#: templates/account.php:693, templates/forms/user-change.php:27
-msgid "Change User"
+#: templates/account.php:642
+msgid "Download Paid Version"
msgstr ""
-#: templates/account.php:717
+#: templates/account.php:713
msgid "Sites"
msgstr ""
-#: templates/account.php:730
+#: templates/account.php:726
msgid "Search by address"
msgstr ""
-#: templates/account.php:739, templates/debug.php:407
+#: templates/account.php:735, templates/debug.php:407
msgid "Address"
msgstr ""
-#: templates/account.php:740
+#: templates/account.php:736
msgid "License"
msgstr ""
-#: templates/account.php:741
+#: templates/account.php:737
msgid "Plan"
msgstr ""
-#: templates/account.php:792
+#: templates/account.php:788
msgctxt "as software license"
msgid "License"
msgstr ""
-#: templates/account.php:921
+#: templates/account.php:917
msgctxt "verb"
msgid "Hide"
msgstr ""
-#: templates/account.php:943, templates/forms/data-debug-mode.php:31, templates/forms/deactivation/form.php:358, templates/forms/deactivation/form.php:389
+#: templates/account.php:939, templates/forms/data-debug-mode.php:31, templates/forms/deactivation/form.php:358, templates/forms/deactivation/form.php:389
msgid "Processing"
msgstr ""
-#: templates/account.php:946
+#: templates/account.php:942
msgid "Get updates for bleeding edge Beta versions of %s."
msgstr ""
-#: templates/account.php:1004
+#: templates/account.php:1000
msgid "Cancelling %s"
msgstr ""
-#: templates/account.php:1004, templates/account.php:1021, templates/forms/subscription-cancellation.php:27, templates/forms/deactivation/form.php:178
+#: templates/account.php:1000, templates/account.php:1017, templates/forms/subscription-cancellation.php:27, templates/forms/deactivation/form.php:178
msgid "trial"
msgstr ""
-#: templates/account.php:1019, templates/forms/deactivation/form.php:195
+#: templates/account.php:1015, templates/forms/deactivation/form.php:195
msgid "Cancelling %s..."
msgstr ""
-#: templates/account.php:1022, templates/forms/subscription-cancellation.php:28, templates/forms/deactivation/form.php:179
+#: templates/account.php:1018, templates/forms/subscription-cancellation.php:28, templates/forms/deactivation/form.php:179
msgid "subscription"
msgstr ""
-#: templates/account.php:1036
+#: templates/account.php:1032
msgid "Deactivating your license will block all premium features, but will enable activating the license on another site. Are you sure you want to proceed?"
msgstr ""
-#: templates/account.php:1110
+#: templates/account.php:1106
msgid "Disabling white-label mode"
msgstr ""
-#: templates/account.php:1111
+#: templates/account.php:1107
msgid "Enabling white-label mode"
msgstr ""
@@ -1489,11 +1509,12 @@ msgctxt "installed add-on"
msgid "Installed"
msgstr ""
-#: templates/admin-notice.php:13, templates/forms/license-activation.php:243, templates/forms/resend-key.php:80
+#: templates/admin-notice.php:17, templates/forms/license-activation.php:245, templates/forms/resend-key.php:80
msgctxt "as close a window"
msgid "Dismiss"
msgstr ""
+#. translators: %s: Number of seconds
#: templates/auto-installation.php:45
msgid "%s sec"
msgstr ""
@@ -1523,143 +1544,144 @@ msgid "PCI compliant"
msgstr ""
#. translators: %s: name (e.g. Hey John,)
-#: templates/connect.php:127
+#: templates/connect.php:118
msgctxt "greeting"
msgid "Hey %s,"
msgstr ""
-#: templates/connect.php:187
-msgid "Never miss an important update"
+#. translators: %1$s: plugin name (e.g., "Awesome Plugin"); %2$s: version (e.g., "1.2.3")
+#: templates/connect.php:186
+msgid "Thank you for updating to %1$s v%2$s!"
msgstr ""
-#: templates/connect.php:195
-msgid "Thank you for updating to %1$s v%2$s!"
+#: templates/connect.php:178
+msgid "Never miss an important update"
msgstr ""
-#: templates/connect.php:205
+#: templates/connect.php:196
msgid "Allow & Continue"
msgstr ""
-#: templates/connect.php:209
-msgid "Re-send activation email"
+#. translators: %s: module type (plugin, theme, or add-on)
+#: templates/connect.php:236
+msgid "We have introduced this opt-in so you never miss an important update and help us make the %s more compatible with your site and better at doing what you need it to."
msgstr ""
-#: templates/connect.php:213
-msgid "Thanks %s!"
+#: templates/connect.php:238
+msgid "Opt in to get email notifications for security & feature updates, educational content, and occasional offers, and to share some basic WordPress environment info."
msgstr ""
-#: templates/connect.php:214
-msgid "You should receive a confirmation email for %s to your mailbox at %s. Please make sure you click the button in that email to %s."
+#: templates/connect.php:241
+msgid "If you skip this, that's okay! %1$s will still work just fine."
msgstr ""
-#: templates/connect.php:225
-msgid "Welcome to %s! To get started, please enter your license key:"
+#: templates/connect.php:227
+msgid "Opt in to get email notifications for security & feature updates, educational content, and occasional offers, and to share some basic WordPress environment info. This will help us make the %s more compatible with your site and better at doing what you need it to."
msgstr ""
-#: templates/connect.php:236
-msgid "Opt in to get email notifications for security & feature updates, educational content, and occasional offers, and to share some basic WordPress environment info. This will help us make the %s more compatible with your site and better at doing what you need it to."
+#: templates/connect.php:216
+msgid "Welcome to %s! To get started, please enter your license key:"
msgstr ""
-#. translators: %s: module type (plugin, theme, or add-on)
-#: templates/connect.php:245
-msgid "We have introduced this opt-in so you never miss an important update and help us make the %s more compatible with your site and better at doing what you need it to."
+#: templates/connect.php:200
+msgid "Re-send activation email"
msgstr ""
-#: templates/connect.php:247
-msgid "Opt in to get email notifications for security & feature updates, educational content, and occasional offers, and to share some basic WordPress environment info."
+#: templates/connect.php:204
+msgid "Thanks %s!"
msgstr ""
-#: templates/connect.php:250
-msgid "If you skip this, that's okay! %1$s will still work just fine."
+#: templates/connect.php:205
+msgid "You should receive a confirmation email for %s to your mailbox at %s. Please make sure you click the button in that email to %s."
msgstr ""
-#: templates/connect.php:280
+#: templates/connect.php:271
msgid "We're excited to introduce the Freemius network-level integration."
msgstr ""
-#: templates/connect.php:283
+#: templates/connect.php:285
+msgid "During the update process we detected %s site(s) in the network that are still pending your attention."
+msgstr ""
+
+#: templates/connect.php:274
msgid "During the update process we detected %d site(s) that are still pending license activation."
msgstr ""
-#: templates/connect.php:285
+#: templates/connect.php:276
msgid "If you'd like to use the %s on those sites, please enter your license key below and click the activation button."
msgstr ""
-#: templates/connect.php:287
+#: templates/connect.php:278
msgid "%s's paid features"
msgstr ""
-#: templates/connect.php:292
+#: templates/connect.php:283
msgid "Alternatively, you can skip it for now and activate the license later, in your %s's network-level Account page."
msgstr ""
-#: templates/connect.php:294
-msgid "During the update process we detected %s site(s) in the network that are still pending your attention."
-msgstr ""
-
-#: templates/connect.php:303, templates/forms/data-debug-mode.php:35, templates/forms/license-activation.php:42
+#: templates/connect.php:294, templates/forms/data-debug-mode.php:35, templates/forms/license-activation.php:42
msgid "License key"
msgstr ""
-#: templates/connect.php:306, templates/forms/license-activation.php:22
+#: templates/connect.php:297, templates/forms/license-activation.php:22
msgid "Can't find your license key?"
msgstr ""
-#: templates/connect.php:369, templates/connect.php:693, templates/forms/deactivation/retry-skip.php:20
+#: templates/connect.php:360, templates/connect.php:690, templates/forms/deactivation/retry-skip.php:20
msgctxt "verb"
msgid "Skip"
msgstr ""
-#: templates/connect.php:372
+#: templates/connect.php:363
msgid "Delegate to Site Admins"
msgstr ""
-#: templates/connect.php:372
+#: templates/connect.php:363
msgid "If you click it, this decision will be delegated to the sites administrators."
msgstr ""
-#: templates/connect.php:399
+#: templates/connect.php:392
msgid "License issues?"
msgstr ""
-#: templates/connect.php:423
-msgid "For delivery of security & feature updates, and license management, %s needs to"
-msgstr ""
-
-#: templates/connect.php:428
+#: templates/connect.php:421
msgid "This will allow %s to"
msgstr ""
-#: templates/connect.php:443
-msgid "Don't have a license key?"
+#: templates/connect.php:416
+msgid "For delivery of security & feature updates, and license management, %s needs to"
msgstr ""
-#: templates/connect.php:446
+#: templates/connect.php:439
msgid "Have a license key?"
msgstr ""
-#: templates/connect.php:454
+#: templates/connect.php:436
+msgid "Don't have a license key?"
+msgstr ""
+
+#: templates/connect.php:447
msgid "Freemius is our licensing and software updates engine"
msgstr ""
-#: templates/connect.php:457
+#: templates/connect.php:450
msgid "Privacy Policy"
msgstr ""
-#: templates/connect.php:459
-msgid "License Agreement"
+#: templates/connect.php:455
+msgid "Terms of Service"
msgstr ""
-#: templates/connect.php:459
-msgid "Terms of Service"
+#: templates/connect.php:453
+msgid "License Agreement"
msgstr ""
-#: templates/connect.php:879
+#: templates/connect.php:876
msgctxt "as in the process of sending an email"
msgid "Sending email"
msgstr ""
-#: templates/connect.php:880
+#: templates/connect.php:877
msgctxt "as activating plugin"
msgid "Activating"
msgstr ""
@@ -1808,6 +1830,7 @@ msgstr ""
msgid "Simulate Network Upgrade"
msgstr ""
+#. translators: %s: 'plugin' or 'theme'
#: templates/debug.php:398
msgid "%s Installs"
msgstr ""
@@ -1919,6 +1942,7 @@ msgstr ""
msgid "Timestamp"
msgstr ""
+#. translators: %s: Page name
#: templates/secure-https-header.php:28
msgid "Secure HTTPS %s page, running from an external domain"
msgstr ""
@@ -1927,7 +1951,7 @@ msgstr ""
msgid "Support"
msgstr ""
-#: includes/debug/class-fs-debug-bar-panel.php:48, templates/debug/api-calls.php:54, templates/debug/logger.php:62
+#: includes/debug/class-fs-debug-bar-panel.php:51, templates/debug/api-calls.php:54, templates/debug/logger.php:62
msgctxt "milliseconds"
msgid "ms"
msgstr ""
@@ -1948,10 +1972,6 @@ msgstr ""
msgid "products"
msgstr ""
-#: includes/managers/class-fs-clone-manager.php:1205
-msgid "%1$s has been placed into safe mode because we noticed that %2$s is an exact copy of %3$s."
-msgstr ""
-
#: includes/managers/class-fs-clone-manager.php:1211
msgid "The products below have been placed into safe mode because we noticed that %2$s is an exact copy of %3$s:%1$s"
msgstr ""
@@ -1960,6 +1980,10 @@ msgstr ""
msgid "The products below have been placed into safe mode because we noticed that %2$s is an exact copy of these sites:%3$s%1$s"
msgstr ""
+#: includes/managers/class-fs-clone-manager.php:1205
+msgid "%1$s has been placed into safe mode because we noticed that %2$s is an exact copy of %3$s."
+msgstr ""
+
#: includes/managers/class-fs-clone-manager.php:1238
msgid "the above-mentioned sites"
msgstr ""
@@ -2062,6 +2086,7 @@ msgstr ""
msgid "Homepage URL & title, WP & PHP versions, and site language"
msgstr ""
+#. translators: %s: 'Plugin' or 'Theme'
#: includes/managers/class-fs-permission-manager.php:195
msgid "To provide additional functionality that's relevant to your website, avoid WordPress or PHP version incompatibilities that can break your website, and recognize which languages & regions the %s should be translated and tailored to."
msgstr ""
@@ -2070,6 +2095,7 @@ msgstr ""
msgid "View Basic %s Info"
msgstr ""
+#. translators: %s: 'Plugin' or 'Theme'
#: includes/managers/class-fs-permission-manager.php:210
msgid "Current %s & SDK versions, and if active or uninstalled"
msgstr ""
@@ -2078,9 +2104,7 @@ msgstr ""
msgid "View License Essentials"
msgstr ""
-#: includes/managers/class-fs-permission-manager.php:262
-msgstr ""
-
+#. translators: %s: 'Plugin' or 'Theme'
#: includes/managers/class-fs-permission-manager.php:272
msgid "To let you manage & control where the license is activated and ensure %s security & feature updates are only delivered to websites you authorize."
msgstr ""
@@ -2089,6 +2113,7 @@ msgstr ""
msgid "View %s State"
msgstr ""
+#. translators: %s: 'Plugin' or 'Theme'
#: includes/managers/class-fs-permission-manager.php:287
msgid "Is active, deactivated, or uninstalled"
msgstr ""
@@ -2109,6 +2134,7 @@ msgstr ""
msgid "WordPress & PHP versions, site language & title"
msgstr ""
+#. translators: %s: 'Plugin' or 'Theme'
#: includes/managers/class-fs-permission-manager.php:330
msgid "To avoid breaking your website due to WordPress or PHP version incompatibilities, and recognize which languages & regions the %s should be translated and tailored to."
msgstr ""
@@ -2308,143 +2334,143 @@ msgstr ""
msgid "Next"
msgstr ""
-#: templates/forms/affiliation.php:83
+#: templates/forms/affiliation.php:86
msgid "Non-expiring"
msgstr ""
-#: templates/forms/affiliation.php:86
+#: templates/forms/affiliation.php:89
msgid "Apply to become an affiliate"
msgstr ""
-#: templates/forms/affiliation.php:108
-msgid "Your affiliate application for %s has been accepted! Log in to your affiliate area at: %s."
+#: templates/forms/affiliation.php:137
+msgid "Due to violation of our affiliation terms, we decided to temporarily block your affiliation account. If you have any questions, please contact support."
msgstr ""
-#: templates/forms/affiliation.php:123
-msgid "Thank you for applying for our affiliate program, we'll review your details during the next 14 days and will get back to you with further information."
+#: templates/forms/affiliation.php:134
+msgid "Thank you for applying for our affiliate program, unfortunately, we've decided at this point to reject your application. Please try again in 30 days."
msgstr ""
-#: templates/forms/affiliation.php:126
+#: templates/forms/affiliation.php:131
msgid "Your affiliation account was temporarily suspended."
msgstr ""
-#: templates/forms/affiliation.php:129
-msgid "Thank you for applying for our affiliate program, unfortunately, we've decided at this point to reject your application. Please try again in 30 days."
+#: templates/forms/affiliation.php:128
+msgid "Thank you for applying for our affiliate program, we'll review your details during the next 14 days and will get back to you with further information."
msgstr ""
-#: templates/forms/affiliation.php:132
-msgid "Due to violation of our affiliation terms, we decided to temporarily block your affiliation account. If you have any questions, please contact support."
+#: templates/forms/affiliation.php:113
+msgid "Your affiliate application for %s has been accepted! Log in to your affiliate area at: %s."
msgstr ""
-#: templates/forms/affiliation.php:145
+#: templates/forms/affiliation.php:150
msgid "Like the %s? Become our ambassador and earn cash ;-)"
msgstr ""
-#: templates/forms/affiliation.php:146
+#: templates/forms/affiliation.php:151
msgid "Refer new customers to our %s and earn %s commission on each successful sale you refer!"
msgstr ""
-#: templates/forms/affiliation.php:149
+#: templates/forms/affiliation.php:154
msgid "Program Summary"
msgstr ""
-#: templates/forms/affiliation.php:151
+#: templates/forms/affiliation.php:156
msgid "%s commission when a customer purchases a new license."
msgstr ""
-#: templates/forms/affiliation.php:153
+#: templates/forms/affiliation.php:158
msgid "Get commission for automated subscription renewals."
msgstr ""
-#: templates/forms/affiliation.php:156
+#: templates/forms/affiliation.php:161
msgid "%s tracking cookie after the first visit to maximize earnings potential."
msgstr ""
-#: templates/forms/affiliation.php:159
+#: templates/forms/affiliation.php:164
msgid "Unlimited commissions."
msgstr ""
-#: templates/forms/affiliation.php:161
+#: templates/forms/affiliation.php:166
msgid "%s minimum payout amount."
msgstr ""
-#: templates/forms/affiliation.php:162
+#: templates/forms/affiliation.php:167
msgid "Payouts are in USD and processed monthly via PayPal."
msgstr ""
-#: templates/forms/affiliation.php:163
+#: templates/forms/affiliation.php:168
msgid "As we reserve 30 days for potential refunds, we only pay commissions that are older than 30 days."
msgstr ""
-#: templates/forms/affiliation.php:166
+#: templates/forms/affiliation.php:171
msgid "Affiliate"
msgstr ""
-#: templates/forms/affiliation.php:169, templates/forms/resend-key.php:23
+#: templates/forms/affiliation.php:174, templates/forms/resend-key.php:23
msgid "Email address"
msgstr ""
-#: templates/forms/affiliation.php:173
+#: templates/forms/affiliation.php:178
msgid "Full name"
msgstr ""
-#: templates/forms/affiliation.php:177
+#: templates/forms/affiliation.php:182
msgid "PayPal account email address"
msgstr ""
-#: templates/forms/affiliation.php:181
+#: templates/forms/affiliation.php:186
msgid "Where are you going to promote the %s?"
msgstr ""
-#: templates/forms/affiliation.php:183
+#: templates/forms/affiliation.php:188
msgid "Enter the domain of your website or other websites from where you plan to promote the %s."
msgstr ""
-#: templates/forms/affiliation.php:185
+#: templates/forms/affiliation.php:190
msgid "Add another domain"
msgstr ""
-#: templates/forms/affiliation.php:189
+#: templates/forms/affiliation.php:194
msgid "Extra Domains"
msgstr ""
-#: templates/forms/affiliation.php:190
+#: templates/forms/affiliation.php:195
msgid "Extra domains where you will be marketing the product from."
msgstr ""
-#: templates/forms/affiliation.php:200
+#: templates/forms/affiliation.php:205
msgid "Promotion methods"
msgstr ""
-#: templates/forms/affiliation.php:203
+#: templates/forms/affiliation.php:208
msgid "Social media (Facebook, Twitter, etc.)"
msgstr ""
-#: templates/forms/affiliation.php:207
+#: templates/forms/affiliation.php:212
msgid "Mobile apps"
msgstr ""
-#: templates/forms/affiliation.php:211
+#: templates/forms/affiliation.php:216
msgid "Website, email, and social media statistics (optional)"
msgstr ""
-#: templates/forms/affiliation.php:214
+#: templates/forms/affiliation.php:219
msgid "Please feel free to provide any relevant website or social media statistics, e.g. monthly unique site visits, number of email subscribers, followers, etc. (we will keep this information confidential)."
msgstr ""
-#: templates/forms/affiliation.php:218
+#: templates/forms/affiliation.php:223
msgid "How will you promote us?"
msgstr ""
-#: templates/forms/affiliation.php:221
+#: templates/forms/affiliation.php:226
msgid "Please provide details on how you intend to promote %s (please be as specific as possible)."
msgstr ""
-#: templates/forms/affiliation.php:233, templates/forms/resend-key.php:22, templates/account/partials/disconnect-button.php:92
+#: templates/forms/affiliation.php:238, templates/forms/resend-key.php:22, templates/forms/subscription-cancellation.php:142, templates/account/partials/disconnect-button.php:92
msgid "Cancel"
msgstr ""
-#: templates/forms/affiliation.php:235
+#: templates/forms/affiliation.php:240
msgid "Become an affiliate"
msgstr ""
@@ -2525,10 +2551,14 @@ msgstr ""
msgid "Agree & Activate License"
msgstr ""
-#: templates/forms/license-activation.php:204
+#: templates/forms/license-activation.php:206
msgid "Associate with the license owner's account."
msgstr ""
+#: templates/forms/optout.php:104
+msgid "Keep automatic updates"
+msgstr ""
+
#: templates/forms/optout.php:44
msgid "Communication"
msgstr ""
@@ -2549,10 +2579,6 @@ msgstr ""
msgid "Extensions"
msgstr ""
-#: templates/forms/optout.php:104
-msgid "Keep automatic updates"
-msgstr ""
-
#: templates/forms/premium-versions-upgrade-handler.php:40
msgid "There is a new version of %s available."
msgstr ""
@@ -2614,10 +2640,12 @@ msgstr ""
msgid "Cancel %s & Proceed"
msgstr ""
+#. translators: %1$s: Number of trial days; %2$s: Plan name;
#: templates/forms/trial-start.php:22
msgid "You are 1-click away from starting your %1$s-day free trial of the %2$s plan."
msgstr ""
+#. translators: %s: Link to freemius.com
#: templates/forms/trial-start.php:28
msgid "For compliance with the WordPress.org guidelines, before we start the trial we ask that you opt in with your user and non-sensitive site information, allowing the %s to periodically send data to %s to check for version updates and to validate your trial."
msgstr ""
@@ -2646,14 +2674,6 @@ msgstr ""
msgid "Beta"
msgstr ""
-#: templates/partials/network-activation.php:32
-msgid "Activate license on all sites in the network."
-msgstr ""
-
-#: templates/partials/network-activation.php:33
-msgid "Apply on all sites in the network."
-msgstr ""
-
#: templates/partials/network-activation.php:36
msgid "Activate license on all pending sites."
msgstr ""
@@ -2662,6 +2682,14 @@ msgstr ""
msgid "Apply on all pending sites."
msgstr ""
+#: templates/partials/network-activation.php:32
+msgid "Activate license on all sites in the network."
+msgstr ""
+
+#: templates/partials/network-activation.php:33
+msgid "Apply on all sites in the network."
+msgstr ""
+
#: templates/partials/network-activation.php:45, templates/partials/network-activation.php:79
msgid "allow"
msgstr ""
@@ -2674,7 +2702,7 @@ msgstr ""
msgid "skip"
msgstr ""
-#: templates/plugin-info/description.php:72, templates/plugin-info/screenshots.php:31
+#: templates/plugin-info/description.php:67, templates/plugin-info/screenshots.php:26
msgid "Click to view full-size screenshot %d"
msgstr ""
@@ -2695,27 +2723,24 @@ msgstr ""
msgid "Last license"
msgstr ""
-#. translators: %1$s: Either 'Downgrading your plan' or 'Cancelling the subscription'
-#: templates/account/partials/addon.php:34
-msgid "%1$s will immediately stop all future recurring payments and your %s plan license will expire in %s."
+#: templates/account/partials/addon.php:200
+msgid "No expiration"
msgstr ""
#: templates/account/partials/addon.php:190
msgid "Cancelled"
msgstr ""
-#: templates/account/partials/addon.php:200
-msgid "No expiration"
+#. translators: %s is replaced with the website's homepage address.
+#: templates/account/partials/disconnect-button.php:78
+msgid "Disconnecting the website will permanently remove %s from your User Dashboard's account."
msgstr ""
#: templates/account/partials/disconnect-button.php:74
msgid "By disconnecting the website, previously shared diagnostic data about %1$s will be deleted and no longer visible to %2$s."
msgstr ""
-#: templates/account/partials/disconnect-button.php:78
-msgid "Disconnecting the website will permanently remove %s from your User Dashboard's account."
-msgstr ""
-
+#. translators: %1$s is replaced by the paid plan name, %2$s is replaced with an anchor link with the text "User Dashboard".
#: templates/account/partials/disconnect-button.php:84
msgid "If you wish to cancel your %1$s plan's subscription instead, please navigate to the %2$s and cancel it there."
msgstr ""
diff --git a/freemius/require.php b/freemius/require.php
index c1f8366..cc194d2 100644
--- a/freemius/require.php
+++ b/freemius/require.php
@@ -19,6 +19,8 @@
require_once WP_FS__DIR_INCLUDES . '/class-fs-logger.php';
require_once WP_FS__DIR_INCLUDES . '/debug/debug-bar-start.php';
+ require_once WP_FS__DIR_INCLUDES . '/class-fs-garbage-collector.php';
+
// require_once WP_FS__DIR_INCLUDES . '/managers/class-fs-abstract-manager.php';
require_once WP_FS__DIR_INCLUDES . '/managers/class-fs-option-manager.php';
require_once WP_FS__DIR_INCLUDES . '/managers/class-fs-gdpr-manager.php';
diff --git a/freemius/start.php b/freemius/start.php
index 096f510..dbe49e9 100644
--- a/freemius/start.php
+++ b/freemius/start.php
@@ -15,7 +15,7 @@
*
* @var string
*/
- $this_sdk_version = '2.5.10';
+ $this_sdk_version = '2.7.2';
#region SDK Selection Logic --------------------------------------------------------------------
@@ -46,6 +46,34 @@
*/
$file_path = fs_normalize_path( __FILE__ );
$fs_root_path = dirname( $file_path );
+
+ // @todo: Remove this code after a few months when WP 6.3 usage is low enough.
+ global $wp_version;
+
+ if (
+ ! function_exists( 'wp_get_current_user' ) &&
+ /**
+ * `get_stylesheet()` will rely on `wp_get_current_user()` when it is being filtered by `theme-previews.php`. That happens only when the site editor is loaded or when the site editor is sending REST requests.
+ * @see theme-previews.php:wp_get_theme_preview_path()
+ *
+ * @todo This behavior is already fixed in the core (WP 6.3.2+), and this code can be removed after a few months when WP 6.3 usage is low enough.
+ * @since WP 6.3.0
+ */
+ version_compare( $wp_version, '6.3', '>=' ) &&
+ version_compare( $wp_version, '6.3.1', '<=' ) &&
+ (
+ 'site-editor.php' === basename( $_SERVER['SCRIPT_FILENAME'] ) ||
+ (
+ function_exists( 'wp_is_json_request' ) &&
+ wp_is_json_request() &&
+ ! empty( $_GET['wp_theme_preview'] )
+ )
+ )
+ ) {
+ // Requiring this file since the call to get_stylesheet() below can trigger a call to wp_get_current_user() when previewing a theme.
+ require_once ABSPATH . 'wp-includes/pluggable.php';
+ }
+
/**
* Get the themes directory where the active theme is located (not passing the stylesheet will make WordPress
* assume that the themes directory is inside `wp-content`.
diff --git a/freemius/templates/account.php b/freemius/templates/account.php
index ca27d07..d7f0642 100644
--- a/freemius/templates/account.php
+++ b/freemius/templates/account.php
@@ -22,8 +22,8 @@
* @var FS_Plugin_Tag $update
*/
$update = $fs->has_release_on_freemius() ?
- $fs->get_update( false, false, WP_FS__TIME_24_HOURS_IN_SEC / 24 ) :
- null;
+ $fs->get_update( false, false ) :
+ null;
if ( is_object($update) ) {
/**
diff --git a/freemius/templates/account/partials/addon.php b/freemius/templates/account/partials/addon.php
index e6d5657..9cc8e27 100644
--- a/freemius/templates/account/partials/addon.php
+++ b/freemius/templates/account/partials/addon.php
@@ -31,7 +31,7 @@
$downgrading_plan_text = fs_text_inline( 'Downgrading your plan', 'downgrading-plan', $slug );
$cancelling_subscription_text = fs_text_inline( 'Cancelling the subscription', 'cancelling-subscription', $slug );
/* translators: %1$s: Either 'Downgrading your plan' or 'Cancelling the subscription' */
- $downgrade_x_confirm_text = fs_text_inline( '%1$s will immediately stop all future recurring payments and your %s plan license will expire in %s.', 'downgrade-x-confirm', $slug );
+ $downgrade_x_confirm_text = fs_text_inline( '%1$s will immediately stop all future recurring payments and your %2$s plan license will expire in %3$s.', 'downgrade-x-confirm', $slug );
$prices_increase_text = fs_text_inline( 'Please note that we will not be able to grandfather outdated pricing for renewals/new subscriptions after a cancellation. If you choose to renew the subscription manually in the future, after a price increase, which typically occurs once a year, you will be charged the updated price.', 'pricing-increase-warning', $slug );
$cancel_trial_confirm_text = fs_text_inline( 'Cancelling the trial will immediately block access to all premium features. Are you sure?', 'cancel-trial-confirm', $slug );
$after_downgrade_non_blocking_text = fs_text_inline( 'You can still enjoy all %s features but you will not have access to %s security & feature updates, nor support.', 'after-downgrade-non-blocking', $slug );
@@ -240,19 +240,19 @@
true
);
- $human_readable_license_expiration = human_time_diff( time(), strtotime( $license->expiration ) );
- $downgrade_confirmation_message = sprintf(
- $downgrade_x_confirm_text,
- ( $fs_addon->is_only_premium() ? $cancelling_subscription_text : $downgrading_plan_text ),
- $plan->title,
- $human_readable_license_expiration
- );
-
$after_downgrade_message = ! $license->is_block_features ?
sprintf( $after_downgrade_non_blocking_text, $plan->title, $fs_addon->get_module_label( true ) ) :
sprintf( $after_downgrade_blocking_text, $plan->title );
if ( ! $license->is_lifetime() && $is_active_subscription ) {
+ $human_readable_license_expiration = human_time_diff( time(), strtotime( $license->expiration ) );
+ $downgrade_confirmation_message = sprintf(
+ $downgrade_x_confirm_text,
+ ( $fs_addon->is_only_premium() ? $cancelling_subscription_text : $downgrading_plan_text ),
+ $plan->title,
+ $human_readable_license_expiration
+ );
+
$buttons[] = fs_ui_get_action_button(
$fs->get_id(),
'account',
diff --git a/freemius/templates/checkout.php b/freemius/templates/checkout.php
index 3e8da51..e43d842 100644
--- a/freemius/templates/checkout.php
+++ b/freemius/templates/checkout.php
@@ -39,7 +39,7 @@
wp_enqueue_script( 'jquery' );
wp_enqueue_script( 'json2' );
- fs_enqueue_local_script( 'postmessage', 'nojquery.ba-postmessage.min.js' );
+ fs_enqueue_local_script( 'postmessage', 'nojquery.ba-postmessage.js' );
fs_enqueue_local_script( 'fs-postmessage', 'postmessage.js' );
fs_enqueue_local_style( 'fs_common', '/admin/common.css' );
diff --git a/freemius/templates/clone-resolution-js.php b/freemius/templates/clone-resolution-js.php
index e8f4e9b..358a602 100644
--- a/freemius/templates/clone-resolution-js.php
+++ b/freemius/templates/clone-resolution-js.php
@@ -55,22 +55,32 @@
beforeSend: function() {
$body.css( { cursor: 'wait' } );
- $cloneResolutionNotice.find( '.button' ).addClass( 'disabled' );
+ $this.addClass( 'disabled' );
+
+ if ( $this.attr( 'id' ) === 'fs_temporary_duplicate_license_activation_link' ) {
+ $this.append( ' ' );
+ }
$( window ).on( 'beforeunload', beforeUnload );
},
success : function( resultObj ) {
$( window ).off( 'beforeunload', beforeUnload );
- if ( resultObj.data.redirect_url && '' !== resultObj.data.redirect_url ) {
+ if (
+ resultObj.data &&
+ resultObj.data.redirect_url &&
+ '' !== resultObj.data.redirect_url
+ ) {
window.location = resultObj.data.redirect_url;
} else {
window.location.reload();
}
},
- error : function() {
+ complete : function() {
$body.css( { cursor: cursor } );
- $cloneResolutionNotice.find( '.button' ).removeClass( 'disabled' );
+ $this.removeClass( 'disabled' );
+
+ $this.parent().find( '.fs-ajax-spinner' ).remove();
}
} );
} );
diff --git a/freemius/templates/contact.php b/freemius/templates/contact.php
index 5fdd6e3..79495ef 100644
--- a/freemius/templates/contact.php
+++ b/freemius/templates/contact.php
@@ -39,7 +39,7 @@
wp_enqueue_script( 'jquery' );
wp_enqueue_script( 'json2' );
- fs_enqueue_local_script( 'postmessage', 'nojquery.ba-postmessage.min.js' );
+ fs_enqueue_local_script( 'postmessage', 'nojquery.ba-postmessage.js' );
fs_enqueue_local_script( 'fs-postmessage', 'postmessage.js' );
fs_enqueue_local_style( 'fs_checkout', '/admin/common.css' );
diff --git a/freemius/templates/forms/affiliation.php b/freemius/templates/forms/affiliation.php
index 30a6181..a053d2d 100644
--- a/freemius/templates/forms/affiliation.php
+++ b/freemius/templates/forms/affiliation.php
@@ -69,10 +69,13 @@
$promotion_method_mobile_apps = in_array( 'mobile_apps', $promotion_methods );
}
} else {
- $current_user = Freemius::_get_current_wp_user();
- $full_name = trim( $current_user->user_firstname . ' ' . $current_user->user_lastname );
- $email_address = $current_user->user_email;
- $domain = Freemius::get_unfiltered_site_url( null, true );
+ if ( ! is_object( $user ) ) {
+ $current_user = Freemius::_get_current_wp_user();
+ $full_name = trim( $current_user->user_firstname . ' ' . $current_user->user_lastname );
+ $email_address = $current_user->user_email;
+ }
+
+ $domain = Freemius::get_unfiltered_site_url( null, true );
}
$affiliate_tracking = 30;
diff --git a/freemius/templates/forms/license-activation.php b/freemius/templates/forms/license-activation.php
index 2217c36..e1153db 100644
--- a/freemius/templates/forms/license-activation.php
+++ b/freemius/templates/forms/license-activation.php
@@ -52,8 +52,9 @@
if ( $is_network_activation ) {
$all_sites = Freemius::get_sites();
- $subsite_data_by_install_id = array();
- $install_url_by_install_id = array();
+ $all_site_details = array();
+ $subsite_url_by_install_id = array();
+ $install_url_by_install_id = array();
foreach ( $all_sites as $site ) {
$site_details = $fs->get_site_info( $site );
@@ -66,9 +67,9 @@
$install = $fs->get_install_by_blog_id($blog_id);
if ( is_object( $install ) ) {
- if ( isset( $subsite_data_by_install_id[ $install->id ] ) ) {
- $clone_subsite_data = $subsite_data_by_install_id[ $install->id ];
- $clone_install_url = $install_url_by_install_id[ $install->id ];
+ if ( isset( $subsite_url_by_install_id[ $install->id ] ) ) {
+ $clone_subsite_url = $subsite_url_by_install_id[ $install->id ];
+ $clone_install_url = $install_url_by_install_id[ $install->id ];
if (
/**
@@ -77,7 +78,7 @@
* @author Leo Fajardo (@leorw)
* @since 2.5.0
*/
- fs_strip_url_protocol( untrailingslashit( $clone_install_url ) ) === fs_strip_url_protocol( untrailingslashit( $clone_subsite_data['url'] ) ) ||
+ fs_strip_url_protocol( untrailingslashit( $clone_install_url ) ) === fs_strip_url_protocol( untrailingslashit( $clone_subsite_url ) ) ||
fs_strip_url_protocol( untrailingslashit( $install->url ) ) !== fs_strip_url_protocol( untrailingslashit( $site_details['url'] ) )
) {
continue;
@@ -88,15 +89,17 @@
$site_details['license_id'] = $install->license_id;
}
- $subsite_data_by_install_id[ $install->id ] = $site_details;
- $install_url_by_install_id[ $install->id ] = $install->url;
+ $subsite_url_by_install_id[ $install->id ] = $site_details['url'];
+ $install_url_by_install_id[ $install->id ] = $install->url;
}
+
+ $all_site_details[] = $site_details;
}
if ( $is_network_activation ) {
$vars = array(
'id' => $fs->get_id(),
- 'sites' => array_values( $subsite_data_by_install_id ),
+ 'sites' => $all_site_details,
'require_license_key' => true
);
@@ -148,7 +151,7 @@
$license->get_html_escaped_masked_secret_key()
);
- $license_input_html .= "{$label} ";
+ $license_input_html .= "{$label} ";
}
$license_input_html .= '';
@@ -175,7 +178,6 @@ class="fs-available-license-key"
type="text"
value="{$value}"
data-id="{$available_license->id}"
- data-license-key="{$available_license->secret_key}"
data-left="{$available_license->left()}"
readonly />
HTML;
@@ -559,17 +561,17 @@ function registerEventHandlers() {
return;
}
- var
- licenseKey = '';
+ var licenseKey = '',
+ licenseID = '';
if ( hasLicenseTypes ) {
if ( isOtherLicenseKeySelected() ) {
licenseKey = $otherLicenseKey.val();
} else {
if ( ! hasLicensesDropdown ) {
- licenseKey = $availableLicenseKey.data( 'license-key' );
+ licenseID = $availableLicenseKey.data( 'id' );
} else {
- licenseKey = $licensesDropdown.val();
+ licenseID = $licensesDropdown.val();
}
}
} else {
@@ -578,17 +580,22 @@ function registerEventHandlers() {
disableActivateLicenseButton();
- if (0 === licenseKey.length) {
+ if ( 0 === licenseID.length && 0 === licenseKey.length ) {
return;
}
var data = {
action : 'get_ajax_action( 'activate_license' ) ?>',
security : 'get_ajax_security( 'activate_license' ) ?>',
- license_key: licenseKey,
module_id : 'get_id() ?>'
};
+ if ( licenseID.length > 0 ) {
+ data.license_id = licenseID;
+ } else {
+ data.license_key = licenseKey;
+ }
+
if ( isNetworkActivation ) {
var
sites = [];
diff --git a/freemius/templates/forms/subscription-cancellation.php b/freemius/templates/forms/subscription-cancellation.php
index 2a1d591..7a02fde 100644
--- a/freemius/templates/forms/subscription-cancellation.php
+++ b/freemius/templates/forms/subscription-cancellation.php
@@ -139,7 +139,7 @@
+ ' '
+ ' '
+ ' '
+ '
'
@@ -194,7 +194,7 @@ function registerEventHandlers() {
$modal.find('.fs-price-increase-warning').show();
} else {
- $primaryButton.html( );
+ $primaryButton.html( );
$modal.find('.fs-price-increase-warning').hide();
}
@@ -271,7 +271,7 @@ function showMessage(message) {
function updateButtonLabels() {
$modal.find('.button-primary').text( );
- $modal.find('.button-secondary').text( );
+ $modal.find('.button-secondary').text( );
}
})( jQuery );
\ No newline at end of file
diff --git a/freemius/templates/powered-by.php b/freemius/templates/powered-by.php
index fc10b0b..e925b0c 100644
--- a/freemius/templates/powered-by.php
+++ b/freemius/templates/powered-by.php
@@ -36,7 +36,7 @@
if ( ! $fs->is_whitelabeled() && ! $fs->apply_filters( 'hide_freemius_powered_by', false ) ) {
wp_enqueue_script( 'jquery' );
wp_enqueue_script( 'json2' );
- fs_enqueue_local_script( 'postmessage', 'nojquery.ba-postmessage.min.js' );
+ fs_enqueue_local_script( 'postmessage', 'nojquery.ba-postmessage.js' );
fs_enqueue_local_script( 'fs-postmessage', 'postmessage.js' );
?>
diff --git a/freemius/templates/pricing.php b/freemius/templates/pricing.php
index 842e4fe..05879a5 100644
--- a/freemius/templates/pricing.php
+++ b/freemius/templates/pricing.php
@@ -39,7 +39,7 @@
wp_enqueue_script( 'jquery' );
wp_enqueue_script( 'json2' );
- fs_enqueue_local_script( 'postmessage', 'nojquery.ba-postmessage.min.js' );
+ fs_enqueue_local_script( 'postmessage', 'nojquery.ba-postmessage.js' );
fs_enqueue_local_script( 'fs-postmessage', 'postmessage.js' );
fs_enqueue_local_style( 'fs_common', '/admin/common.css' );
diff --git a/includes/activity-report-email/class-password-protected-activity-logs.php b/includes/activity-report-email/class-password-protected-activity-logs.php
new file mode 100644
index 0000000..17f6903
--- /dev/null
+++ b/includes/activity-report-email/class-password-protected-activity-logs.php
@@ -0,0 +1,241 @@
+prefix . self::$table;
+ $used_password_col = maybe_add_column(
+ $table_name,
+ 'used_password',
+ 'ALTER TABLE ' . $table_name . ' ADD `used_password` VARCHAR ( 255 ) NULL AFTER `status`'
+ );
+ $password_id_col = maybe_add_column(
+ $table_name,
+ 'password_id',
+ 'ALTER TABLE ' . $table_name . ' ADD `password_id` VARCHAR( 255 ) NULL AFTER `id`'
+ );
+ $object_type_col = maybe_add_column(
+ $table_name,
+ 'object_type',
+ 'ALTER TABLE ' . $table_name . ' ADD `object_type` VARCHAR( 255 ) NULL AFTER `status`'
+ );
+
+ if ( $used_password_col && $password_id_col && $object_type_col ) {
+ update_option( 'pp_activity_logs_db_updated', true );
+ }
+ }
+ }
+
+ /**
+ * Method get_items
+ *
+ * @return array|object|stdClass[]|null
+ */
+ public static function get_items() {
+
+ global $wpdb;
+ $table_name = $wpdb->prefix . self::$table;
+
+ $search_term = self::check_for_search();
+ $filter = self::check_for_filter();
+ $timestamp = self::get_time_from_keyword( $filter );
+
+
+ if( $filter != NULL && !empty( $timestamp ) )
+ $query = " WHERE `created_at` BETWEEN " . reset( $timestamp ) . " AND " . end( $timestamp );
+ else
+ $query = "";
+
+ if( $search_term == NULL ) {
+ $search = $query . " ORDER BY `id` DESC";
+ } else {
+ $query = empty($query) ? '' : str_replace( "WHERE", "and", $query );
+ $search = "WHERE CONCAT_WS( ' ', `ip`, `browser`, `status` ) LIKE '%$search_term%'" . $query;
+ }
+
+ $logs = $wpdb->get_results(
+ " SELECT * FROM $table_name " . $search,
+ ARRAY_A
+ );
+
+ if( !is_wp_error( $logs ) && count( $logs ) > 0 )
+ return $logs;
+ else
+ return array();
+ }
+
+ /**
+ * Method add_item
+ *
+ * @param $request $request
+ *
+ * @return bool|int|mysqli_result|null
+ */
+ public static function add_item( $request ) {
+ global $wpdb;
+ $table_name = $wpdb->prefix . self::$table;
+
+ $data = array(
+ 'ip' => $request['ip'],
+ 'browser' => $request['browser'],
+ 'status' => $request['status'],
+ 'created_at' => $request['created_at'],
+ 'used_password' => $request['used_password'],
+ 'password_id' => $request['password_id'],
+ 'object_type' => $request['object_type'],
+ );
+ $format = array( '%s', '%s', '%s', '%s' );
+ return $wpdb->insert( $table_name, $data, $format );
+ }
+
+ /**
+ * delete_item
+ *
+ * @param mixed $id
+ *
+ * @return bool|int|mysqli_result|null
+ */
+ public static function delete_item( $id ) {
+ global $wpdb;
+
+ return $wpdb->delete(
+ $wpdb->prefix . self::$table,
+ ['id' => $id],
+ ['%d']
+ );
+ }
+
+ /**
+ * delete_items
+ *
+ * @param mixed $ids
+ */
+ public static function delete_items( $ids ) {
+ global $wpdb;
+
+ $table_name = $wpdb->prefix . self::$table;
+ $wpdb->query( "DELETE FROM `{$table_name}` WHERE ID IN( $ids )" );
+ }
+
+ /**
+ * delete_all_items
+ */
+ public static function delete_all_items() {
+ global $wpdb;
+ $table_name = $wpdb->prefix . self::$table;
+ $wpdb->query("TRUNCATE TABLE $table_name");
+ }
+
+ /**
+ * check_for_search
+ *
+ * @return string|null
+ */
+ public static function check_for_search() {
+ if( isset( $_POST['s'] ) ) {
+ if ( ! isset( $_POST['search_activity_logs_nonce'] ) || ! wp_verify_nonce( $_POST['search_activity_logs_nonce'], 'password_protected_search_activity_logs' ) ) {
+ wp_die('Sorry, your nonce did not verify.');
+ }
+ return trim( sanitize_text_field( $_POST['s'] ) );
+
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * check_for_filter
+ *
+ * @return string|null
+ */
+ public static function check_for_filter() {
+ if( isset( $_GET['show_logs'] ) ) {
+
+ $nonce = sanitize_text_field( $_GET['_wpnonce'] );
+ if( ! wp_verify_nonce( $nonce, 'activity-logs-filter' ) ) {
+ wp_die( __( 'Security check: Your nonce did not verify!', 'password-protected-pro' ) );
+ } else {
+ return sanitize_text_field( $_GET['show_logs'] );
+ }
+ }
+ return null;
+ }
+
+ /**
+ * get_time_from_keyword
+ *
+ * @param mixed $keyword
+ *
+ * @return array
+ */
+ public static function get_time_from_keyword( $keyword = '' ) {
+
+ $today = strtotime( date( 'Y-m-d' ) . ' midnight', self::$now );
+ $todays_date = date( 'd', self::$now );
+ $weekday = date( 'w', self::$now );
+ $result = array();
+
+ $keyword = strtolower( (string) $keyword );
+
+ // Today
+ if ( $keyword === 'today' ) {
+ $result[] = $today;
+ $result[] = self::$now;
+ }
+
+ // Yesterday
+ elseif ( $keyword === 'yesterday' ) {
+ $result[] = strtotime( '-1 day midnight', self::$now );
+ $result[] = strtotime( 'today midnight', self::$now );
+ }
+
+ // This week
+ elseif ( $keyword === 'thisweek' ) {
+
+ $thisweek = strtotime( '-' . ( $weekday+1 ) . ' days midnight', self::$now );
+ if ( get_option( 'start_of_week' ) == $weekday )
+ $thisweek = $today;
+
+ $result[] = $thisweek;
+ $result[] = self::$now;
+
+ }
+
+ // This month
+ elseif ( $keyword === 'thismonth' ) {
+ $result[] = strtotime( date( 'Y-m-01' ) . ' midnight', self::$now );
+ $result[] = self::$now;
+ }
+
+ return $result;
+
+ }
+ }
+}
+
+new Password_Protected_Activity_Logs();
\ No newline at end of file
diff --git a/includes/activity-report-email/class-password-protected-activity-report-settings.php b/includes/activity-report-email/class-password-protected-activity-report-settings.php
new file mode 100644
index 0000000..e8c8b25
--- /dev/null
+++ b/includes/activity-report-email/class-password-protected-activity-report-settings.php
@@ -0,0 +1,223 @@
+prefix . 'pp_activity_logs';
+ $charset_collate = $wpdb->get_charset_collate();
+ if ( ! function_exists( 'maybe_create_table' ) ) {
+ require_once ABSPATH . 'wp-admin/includes/upgrade.php';
+ }
+
+ $sql = 'CREATE TABLE `' . $table_name . '` (
+ `id` MEDIUMINT ( 9 ) NOT NULL AUTO_INCREMENT,
+ `ip` VARCHAR ( 55 ) NOT NULL,
+ `browser` TEXT NOT NULL,
+ `status` TINYTEXT NOT NULL,
+ `created_at` VARCHAR ( 55 ) NOT NULL,
+ PRIMARY KEY ( `id` )
+ ) ' . $charset_collate . ';';
+
+ maybe_create_table( $table_name, $sql );
+ update_option( 'password_protected_1.5_update_database', true );
+ }
+ }
+
+ public function settings_fields() {
+ register_setting(
+ 'password_protected_activity_report',
+ 'password_protected_activity_report_enable',
+ array(
+ 'sanitize_callback' => array( $this, 'sanitize_report_fields' ),
+ )
+ );
+
+ add_settings_section(
+ 'password_protected_activity_report',
+ __( 'Password Activity Report via Email', 'password-protected' ),
+ '__return_null',
+ 'admin.php?page=password-protected&tab=activity-report',
+ array()
+ );
+
+ add_settings_field(
+ 'password_protected_activity_report',
+ __( 'Enable Activity Report', 'password-protected' ),
+ array( $this, 'activity_report_field_callback' ),
+ 'admin.php?page=password-protected&tab=activity-report',
+ 'password_protected_activity_report',
+ array(
+ 'label_for' => 'password_protected_activity_report',
+ )
+ );
+ }
+
+ public function sanitize_report_fields( $fields ) {
+ if ( empty( $fields ) ) {
+ return 'no';
+ }
+
+ return $fields;
+ }
+
+ public function activity_report_field_callback( $args ) {
+ $checked = get_option( 'password_protected_activity_report_enable', 'no' );
+ $checked = 'yes' === $checked ? 'checked' : '';
+ echo '
+
+
+
+
+
+
+
+ ' . __( 'Enable this option to receive weekly activity report on your email.', 'password-protected' ) . '
+
+
';
+ }
+
+ public function add_activity_report_tab( $tabs ) {
+ $tabs['activity-report'] = __( 'Activity Report', 'password-protected' );
+ return $tabs;
+ }
+
+ public function activity_report() {
+ echo '
';
+ }
+
+ public function success_attempt( $form_type, $password, $password_id ) {
+ $this->log_password_attempt( "Success", $form_type, $password, $password_id );
+ }
+
+ public function failure_attempt( $form_type, $password, $password_id ) {
+ $this->log_password_attempt( "Failure", $form_type, $password, $password_id );
+ }
+
+ public function login_enqueue_scripts() {
+ global $Password_Protected;
+ wp_enqueue_script( 'password-protected-detect', PASSWORD_PROTECTED_URL . 'assets/js/detect.min.js', array( 'jquery' ), $Password_Protected->version, true );
+ wp_enqueue_script( 'password-protected-compatibility', PASSWORD_PROTECTED_URL . 'assets/js/compatibility.js', array( 'password-protected-detect' ), $Password_Protected->version, true );
+ }
+
+ public function add_new_field_after_password_field() {
+ echo '
';
+ }
+
+ private function log_password_attempt( $success_or_failure, $form_type, $password, $password_id ) {
+ $log = $this->prepare_entry_log();
+ extract( $log );
+ Password_Protected_Activity_Logs::add_item(
+ array(
+ 'ip' => $IP,
+ 'browser' => $browser,
+ 'status' => $success_or_failure,
+ 'created_at' => current_time( "timestamp" ),
+ 'password_id' => $password_id,
+ 'object_type' => $form_type,
+ 'used_password' => $password,
+ )
+ );
+ }
+
+ private function prepare_entry_log() {
+ $IP = self::get_client_ip();
+ $browser = self::get_browser();
+ return compact( 'IP', 'browser' );
+ }
+
+ public static function get_client_ip() {
+ $ipaddress = 'UNKNOWN';
+ $keys = array(
+ 'HTTP_CLIENT_IP',
+ 'HTTP_X_FORWARDED_FOR',
+ 'HTTP_X_FORWARDED',
+ 'HTTP_FORWARDED_FOR',
+ 'HTTP_FORWARDED',
+ 'REMOTE_ADDR',
+ );
+
+ foreach ( $keys as $key ) {
+ if ( isset( $_SERVER[ $key ] ) ) {
+ $ipaddress = sanitize_text_field( wp_unslash( $_SERVER[ $key ] ) );
+ break;
+ }
+ }
+
+ if ( '::1' === $ipaddress ) {
+ $ipaddress = '127.0.1.6';
+ }
+
+ return $ipaddress;
+ }
+
+ public static function get_browser() {
+ if ( isset( $_POST['password_protected_user_agent'] ) ) {
+ return sanitize_text_field( wp_unslash( $_POST['password_protected_user_agent'] ) );
+ }
+
+ return 'UNKNOWN';
+ }
+
+ public static function is_activity_report_enabled() {
+ return 'yes' === get_option( 'password_protected_activity_report_enable', 'no' );
+ }
+
+ public static function get_report_interval() {
+ $interval = apply_filters( 'password_protected_activity_report_interval', 7 );
+ if ( ! $interval ) {
+ $interval = 7;
+ }
+
+ $day_into_seconds = 60*60*24;
+ return $day_into_seconds * $interval;
+ }
+
+ public static function get_instance() {
+ if ( is_null( self::$instance ) ) {
+ self::$instance = new self();
+ }
+
+ return self::$instance;
+ }
+ }
+}
+
+Password_protected_Activity_Report_Settings::get_instance();
diff --git a/includes/activity-report-email/class-password-protected-send-email-notification.php b/includes/activity-report-email/class-password-protected-send-email-notification.php
new file mode 100644
index 0000000..511b2f1
--- /dev/null
+++ b/includes/activity-report-email/class-password-protected-send-email-notification.php
@@ -0,0 +1,90 @@
+ Password_protected_Activity_Report_Settings::get_report_interval(),
+ 'display' => __( 'Password Protected Email Notification Interval', 'password-protected' ),
+ );
+ return $schedules;
+ }
+
+ public function init_cron() {
+ if ( ! wp_next_scheduled( 'password_protected_email_notification_hook' ) ) {
+ wp_schedule_event( time(), 'password_protected_email_notification', 'password_protected_email_notification_hook' );
+ }
+ }
+
+ public function send_email_notification() {
+ global $wpdb;
+ $timestamps = Password_Protected_Activity_Logs::get_time_from_keyword( 'thisweek' );
+ $sql = 'SELECT
+ SUM( IF ( `status` = %s, 1, 0 ) ) as success,
+ SUM( IF ( `status` = %s, 1, 0 ) ) as failed
+ FROM %i WHERE created_at between %d and %d;';
+ $sql = $wpdb->prepare( $sql, 'Success', 'Failure', $wpdb->prefix . 'pp_activity_logs', $timestamps[0], $timestamps[1] );
+ $results = $wpdb->get_row( $sql, ARRAY_A );
+
+ $success_attempts =
+ $failed_attempts = 0;
+ if ( is_array( $results ) ) {
+ if ( isset( $results['success'] ) ) {
+ $success_attempts = absint( $results['success'] );
+ }
+
+ if ( isset( $results['failed'] ) ) {
+ $failed_attempts = absint( $results['failed'] );
+ }
+ }
+
+ $total_attempts = $success_attempts + $failed_attempts;
+
+ $template = $this->get_template( $success_attempts, $failed_attempts, $total_attempts, $timestamps );
+ $headers = $this->get_html_headers();
+ $subject = sprintf(
+ '[ %s, %s ]',
+ get_bloginfo( 'name' ),
+ __( 'Password Protected Activity Log Notification', 'password-protected' )
+ );
+
+ return wp_mail( get_option( 'admin_email' ), $subject, $template, $headers );
+ }
+
+ private function get_template( $success, $failed, $total, $time ) {
+ ob_start();
+ require_once PASSWORD_PROTECTED_DIR . 'templates/emails/activity-notification.php';
+ return ob_get_clean();
+ }
+ private function get_html_headers() {
+ $headers = array(
+ 'Content-type: text/html',
+ );
+
+ return implode( "\r\n", apply_filters( 'password_protected_email_headers', $headers ) );
+ }
+
+ public static function get_instance() {
+ if ( is_null( self::$instance ) ) {
+ self::$instance = new self();
+ }
+
+ return self::$instance;
+ }
+ }
+}
+
+Password_Protected_Send_Email_Notification::get_instance();
+
+#F03B3E, #04AA5E, #4685EC, #CA1329, #FBBA40
\ No newline at end of file
diff --git a/includes/freemius.php b/includes/freemius.php
index 65b1a3b..2c94465 100644
--- a/includes/freemius.php
+++ b/includes/freemius.php
@@ -33,6 +33,7 @@ function pp_free_fs() {
'menu' => array(
'slug' => 'password-protected',
'support' => false,
+ 'contact' => false,
),
)
);
diff --git a/password-protected.php b/password-protected.php
index a66a307..d8fe5aa 100644
--- a/password-protected.php
+++ b/password-protected.php
@@ -3,10 +3,10 @@
Plugin Name: Password Protected
Plugin URI: https://wordpress.org/plugins/password-protected/
Description: A very simple way to quickly password protect your WordPress site with a single password. Please note: This plugin does not restrict access to uploaded files and images and does not work with some caching setups.
-Version: 2.6.5.1
-Author: WPExperts
+Version: 2.7.2
+Author: Password Protected
Text Domain: password-protected
-Author URI: https://passwordwp.com/
+Author URI: https://passwordprotectedwp.com/
License: GPLv2
*/
/*
@@ -40,7 +40,7 @@
class Password_Protected {
- var $version = '2.6.5.1';
+ var $version = '2.7.2';
var $admin = null;
var $errors = null;
var $admin_caching = null;
@@ -62,7 +62,7 @@ public function __construct() {
add_action( 'init', array( $this, 'maybe_process_logout' ), 1 );
add_action( 'init', array( $this, 'maybe_process_login' ), 1 );
add_action( 'wp', array( $this, 'disable_feeds' ) );
- add_action( 'template_redirect', array( $this, 'maybe_show_login' ), -1 );
+ add_action( 'template_redirect', array( $this, 'maybe_show_login' ), -10 );
add_filter( 'pre_option_password_protected_status', array( $this, 'allow_feeds' ) );
add_filter( 'pre_option_password_protected_status', array( $this, 'allow_administrators' ) );
add_filter( 'pre_option_password_protected_status', array( $this, 'allow_users' ) );
@@ -99,6 +99,7 @@ public function __construct() {
new Password_Protected_reCAPTCHA();
include_once dirname( __FILE__ ) . '/includes/transient-functions.php';
+ include_once dirname( __FILE__ ) . '/includes/activity-report-email/class-password-protected-activity-report-settings.php';
}
/**
@@ -314,10 +315,13 @@ public function maybe_process_login() {
$default_password = get_option( 'password_protected_password' );
$auth = false;
+ $p_id = 0;
if ( empty( $default_password ) ) {
- $auth = $this->password_protected_check_pro_password( $password_protected_pwd );
+ $authentication = $this->password_protected_check_pro_password( $password_protected_pwd );
+ $auth = $authentication['auth'];
+ $p_id = $authentication['p_id'];
} else {
@@ -327,7 +331,9 @@ public function maybe_process_login() {
if ( ! $auth ) {
- $auth = $this->password_protected_check_pro_password( $password_protected_pwd );
+ $authentication = $this->password_protected_check_pro_password( $password_protected_pwd );
+ $auth = $authentication['auth'];
+ $p_id = $authentication['p_id'];
}
}
@@ -336,13 +342,13 @@ public function maybe_process_login() {
if( count( @$this->errors->errors ) > 0 ) return;
- $this->password_protected_process_login( $auth );
+ $this->password_protected_process_login( $auth, $password_protected_pwd, $p_id );
}
}
- private function password_protected_process_login( bool $auth ) {
+ public function password_protected_process_login( bool $auth, $requested_password, $password_id ) {
if( $auth )
$throttle = apply_filters( 'password_protected_check_for_throttling', true );
@@ -350,7 +356,7 @@ private function password_protected_process_login( bool $auth ) {
if( $auth && $throttle ) {
- do_action( 'password_protected_success_login_attempt' );
+ do_action( 'password_protected_success_login_attempt', 'global', $requested_password, $password_id );
$remember = isset( $_REQUEST['password_protected_rememberme'] ) ? boolval( $_REQUEST['password_protected_rememberme'] ) : false;
if ( ! $this->allow_remember_me() ) {
@@ -359,7 +365,7 @@ private function password_protected_process_login( bool $auth ) {
$this->set_auth_cookie( $remember );
$redirect_to = isset( $_REQUEST['redirect_to'] ) ? esc_url($_REQUEST['redirect_to']) : '';
- $redirect_to = apply_filters( 'password_protected_login_redirect', $redirect_to );
+ $redirect_to = apply_filters( 'password_protected_login_redirect', $redirect_to, $requested_password );
if ( ! empty( $redirect_to ) ) {
$this->safe_redirect( remove_query_arg( 'password-protected', $redirect_to ) );
@@ -372,7 +378,7 @@ private function password_protected_process_login( bool $auth ) {
exit;
}
} else {
- do_action( 'password_protected_failure_login_attempt' );
+ do_action( 'password_protected_failure_login_attempt', 'global', $requested_password, $password_id );
// ... otherwise incorrect password
$this->clear_auth_cookie();
@@ -390,12 +396,12 @@ private function password_protected_process_login( bool $auth ) {
* @param mixed $requested_password
* @return void
*/
- private function password_protected_check_pro_password( $requested_password ) {
+ public function password_protected_check_pro_password( $requested_password ) {
$pro_passwords = apply_filters( 'password_protected_passwords', array() );
$pro_passwords = array_filter( $pro_passwords );
-
$auth = false;
+ $p_id = 0;
if( is_array( $pro_passwords ) && count( $pro_passwords ) > 0 ) {
@@ -404,7 +410,7 @@ private function password_protected_check_pro_password( $requested_password ) {
if ( ( hash_equals( $p, $this->encrypt_password( $requested_password ) ) && $pro_passwords != '' ) || apply_filters( 'password_protected_process_login', false, $requested_password ) ) {
$auth = apply_filters( 'password_protected_login_password_matched', $p, $this->errors );
-
+ $p_id = $i;
break;
}
@@ -417,7 +423,10 @@ private function password_protected_check_pro_password( $requested_password ) {
}
- return $auth;
+ return array(
+ 'auth' => $auth,
+ 'p_id' => $p_id,
+ );
}
/**
@@ -611,7 +620,7 @@ public function get_hashed_password() {
* @param string $scheme Cookie scheme.
* @return boolean Validation successful?
*/
- public function validate_auth_cookie( $cookie = '', $scheme = '' ) {
+ public function validate_auth_cookie( $cookie = '', $scheme = '', $hashed_password = '' ) {
if ( ! $cookie_elements = $this->parse_auth_cookie( $cookie, $scheme ) ) {
do_action( 'password_protected_auth_cookie_malformed', $cookie, $scheme );
@@ -633,7 +642,10 @@ public function validate_auth_cookie( $cookie = '', $scheme = '' ) {
return false;
}
- $key = md5( $this->get_site_id() . $this->get_hashed_password() . '|' . $expiration );
+ if ( empty( $hashed_password ) ) {
+ $hashed_password = $this->get_hashed_password();
+ }
+ $key = md5( $this->get_site_id() . $hashed_password . '|' . $expiration ); // need to modify
$hash = hash_hmac( 'md5', $this->get_site_id() . '|' . $expiration, $key );
if ( $hmac != $hash ) {
@@ -656,9 +668,12 @@ public function validate_auth_cookie( $cookie = '', $scheme = '' ) {
* @param string $scheme Cookie scheme.
* @return string Cookie.
*/
- public function generate_auth_cookie( $expiration, $scheme = 'auth' ) {
+ public function generate_auth_cookie( $expiration, $scheme = 'auth', $hashed_password = '' ) {
- $key = md5( $this->get_site_id() . $this->get_hashed_password() . '|' . $expiration );
+ if ( empty( $hashed_password ) ) {
+ $hashed_password = $this->get_hashed_password();
+ }
+ $key = md5( $this->get_site_id() . $hashed_password . '|' . $expiration ); // need to modify
$hash = hash_hmac( 'md5', $this->get_site_id() . '|' . $expiration, $key );
$cookie = $this->get_site_id() . '|' . $expiration . '|' . $hash;
@@ -841,7 +856,7 @@ public function login_messages() {
}
if ( ! empty( $errors ) ) {
- echo '
' . apply_filters( 'password_protected_login_errors', $errors ) . "
\n";
+ echo '
' . apply_filters( 'password_protected_login_errors', $errors ) . "
\n";
}
if ( ! empty( $messages ) ) {
echo '
' . apply_filters( 'password_protected_login_messages', $messages ) . "
\n";
@@ -921,14 +936,25 @@ static function is_plugin_supported() {
* @return WP_Error|boolean
*/
public function only_allow_logged_in_rest_access( $access ) {
+ if ( $this->is_active() ) {
+ if ( is_user_logged_in() ) {
+ global $current_user;
+ if ( $current_user->has_cap( 'edit_posts' ) || $current_user->has_cap( 'edit_pages' ) ) {
+ return $access;
+ }
+ }
+
+ if ( $this->is_user_logged_in() ) {
+ return $access;
+ }
- // If user is not logged in
- if ( $this->is_active() && ! $this->is_user_logged_in() && ! is_user_logged_in() && ! (bool) get_option( 'password_protected_rest' ) ) {
+ if ( get_option( 'password_protected_rest' ) ) {
+ return $access;
+ }
return new WP_Error( 'rest_cannot_access', __( 'Only authenticated users can access the REST API.', 'password-protected' ), array( 'status' => rest_authorization_required_code() ) );
}
return $access;
-
}
/**
@@ -937,8 +963,9 @@ public function only_allow_logged_in_rest_access( $access ) {
*/
public function password_protected_above_password_field() {
$text = get_option('password_protected_text_above_password');
- if( !empty($text) )
- echo '
' . esc_attr( $text ) . '
';
+ if( ! empty( $text ) ) {
+ echo '
' . wp_kses_post( $text ) . '
';
+ }
}
/**
@@ -947,8 +974,9 @@ public function password_protected_above_password_field() {
*/
public function password_protected_below_password_field() {
$text = get_option('password_protected_text_below_password');
- if( !empty($text) )
- echo '
' . esc_attr( $text ) . '
';
+ if( ! empty( $text ) ) {
+ echo '
' . wp_kses_post( $text ) . '
';
+ }
}
}
diff --git a/readme.txt b/readme.txt
index 03d3b6c..d268e41 100644
--- a/readme.txt
+++ b/readme.txt
@@ -1,85 +1,223 @@
-=== Password Protected - Ultimate Plugin to Password Protect Your WordPress Content with Ease ===
+=== Password Protected - Ultimate Plugin to Protect WordPress Site, Pages & WooCommerce Store ===
Contributors: wpexpertsio
Tags: password, maintenance mode, coming soon page, password protect, login
Requires at least: 4.6
-Tested up to: 6.4.1
+Tested up to: 6.5.3
Requires PHP: 5.6
-Stable tag: 2.6.5.1
+Stable tag: 2.7.2
License: GPLv2 or later
-The ultimate password protection plugin that protects your WordPress site with a single password.
+Protect your WordPress site, pages, posts, WooCommerce products, and categories with single or multiple passwords.
== Description ==
[Live Demo](https://tastewp.com/new/?pre-installed-plugin-slug=password-protected)
-Password Protected for WordPress allows you to secure your website with a single password. The ultimate password protection plugin protects your WordPress categories, posts, products, and more with the simplest of ease.
+Do you want to password protect your WordPress site to secure WordPress pages, posts, categories, etc? If so, then you need to install ✨**the Password Protected plugin**✨.
-Password Protected does not protect images or uploaded files, so if you enter an exact URL of an image file, it will still be accessible.
+Password Protected is a robust password protection plugin for WordPress that empowers you to secure your WordPress categories, posts, WooCommerce products, and even WordPress login (wp-admin) page with unparalleled ease.
-= Password Protected Features =
+Additionally, you can secure the password protected screen from WordPress attacks such as a WordPress brute force attack with the limit login feature.
-* Easy to set up - Password protect your WordPress site with a single password.
-* Set a description - Display text (description or instructions) above or below the password field.
-* reCaptcha v2/v3 - You can enable Google reCAPTCHA v2 or V3 to increase bot security measures.
-* Allow administrators - Option to allow administrators access without entering the password.
-* Allow logged-in users - Option to give logged-in users access to the website.
-* Allow RSS Feeds - Option to allow access to feeds.
-* Allow Rest API Access - Allow admin to access pages and posts.
-* Customization – Customize the password-protected screen, including the background, font, logo, and colors (using [Login Designer](https://wp.org/plugins/login-designer))
-> Please note, this plugin works by setting a cookie to allow access to the site. If you are using a caching plugin or web hosting such as WP Engine that has in-built caching, you will need to configure the caching service to be disabled if the Password Protected cookie is set.
+Therefore, the [Password Protected WordPress plugin](https://passwordprotectedwp.com/) ensures comprehensive security, covering everything from WordPress pages to WooCommerce products, all with a user-friendly interface.
-= Password Protected Pro =
-[Password Protected Pro](https://passwordwp.com/pricing/?utm_source=wp_org&utm_medium=readme) is a [Kinsta recommended plugin](https://kinsta.com/blog/password-protect-wordpress-site/) that offers powerful features that will take your WordPress website password protected to the next level.
+== Why Do You Need to Password Protect WordPress Site? ==
-* Exclude page posts & post types - Option to exclude specific pages and post types from password protection.
-* Limit login attempts - Limit the user’s attempts to enter a password for a specified interval.
-* Lockdown time - Set a time (in minutes) during which users can not enter the password after their login attempts are limited.
-* Usage limits - Set a usage limit after which a password can not be used.
-* Status control - You can change the status of the password (Active, Deactivated, Expired).
-* Manage multiple passwords - Edit, activate, deactivate, or delete passwords (individual or bulk action).
-* Set Expiry Dates - Options to select the expiry date for specific passwords
-* Activity Log Reports - View the Activity Logs of each user, including their IP address, browser, status, date, and time of password attempts.
-* Priority Support - Our team of support professionals will make sure to handle your queries on high priority.
+With the rapidly rising number of cyber threats, having an effective WordPress security system for your website is essential.
-= Detect hackers and bots from abusing password protection with reCAPTCHA =
-Google reCAPTCHA v2 or v3 empowers your WordPress website to prevent password abuse against automated software, bots, hackers, etc. This anti-spam tool will allow any real user to access your website easily.
+Whether you're a blogger, a business owner, or a developer, protecting sensitive information and controlling who can access the content you have created is essential. This is where the Password Protected plugin comes in.
-= Password protect any post type =
-You can include or exclude any post type from password protection. All of this can be done from the back end using a single password.
+**For example**, imagine you're a photographer showcasing your portfolio. By using the Password Protect WordPress plugin, you can share your work securely with potential clients. Simply password protect your portfolio page, and only those with the password can view it. It's an easy way to keep your photos private until you're ready to share them publicly.
-= Password protect your WordPress site with a single password =
-Password Protected has the ability to secure your entire website with a single password. Everything from pages to posts will also be protected.
-= Display password protected content in RSS feeds =
-You can allow RSS feeds to show a login page after which user accessing the feed can view the password protected content. Disabling the option will restrict any user's access to the website even if the RSS feed is public.
+### What Makes the Password Protected Plugin Stand Out! 😎
-= Password usage limits and complexities =
-Limits users from entering the password using Password Protected’s Usage Limit counter. Password greater than that limit can not be applicable on the login page.
+Wouldn't you like to have WordPress password protection that gives you peace of mind and immense security for your WordPress site❓
-Usage limits can also be restricted by setting a password expiry from the calendar settings. This prevents users from re-using any given password. Regular password changes mitigate the risk of any security breach.
+Here are some of the features of the password protect WordPress plugin that gives so much control over your WordPress content protection while protecting your site from unauthorized access.
-Limiting password attempts prevents security issues like the Brute Force attack, where hackers keep trying to guess your password until they get it right. A complimentary solution to this feature is the Lockdown Timer, which resets the user’s right to log in after exceeding their login attempt limit.
-= Monitor and review activity logs for Password Protected =
-Password Protected’s Activity Log is similar to an audit log that gives you a record of the events that have taken place on your website. To provide you with a better understanding, here is a list of the details you will find in the activity log:
+== ⚡ Password Protect Entire WordPress Site With These Features: ==
-* Filter options for passwords used in a specific range (All-time, Today, Yesterday, This Week, This Month)
-* IP addresses of the system from where the passwords were attempted.
-* Country names from where the passwords were attempted.
-* Browser names where the password was attempted.
-* Status of the password attempts (successful or failed)
+**✅ Complete Site Protection —💯% FREE**
-The admin can also perform the search operation on the activity log. You can search by IP, Country, Browser, and Status. For e.g., searching Success will search all the passwords with successful attempts, and searching Failure will search all the orders with failed attempts.
+Want to protect your entire WordPress site? Password Protected plugin makes it easy!
+
+With a single master password, password protect entire WordPress site to prevent unauthorized access. Also, set how long you want to use the password, define protected permission, and much more.
+
+**✅ Passwordless Admin Access**
+
+As an admin, you probably don't want the hassle of entering additional passwords to access your site. Right?
+
+Don't worry. With the Password Protected plugin, you can simplify the login process for administrators with Passwordless Admin Access. This time-saving functionality enhances efficiency and security by eliminating the need for administrators to manage passwords or risk exposure to unauthorized access attempts.
+
+**✅ Add Google Recaptcha**
+
+Make your password protected screen more secure by integrating Google reCaptcha. The plugin supports both Google reCAPTCHA v2 and v3.
+
+Google reCAPTCHA prevents automated bots and spam by presenting users with challenges that only humans can solve, such as identifying objects in images or solving puzzles.
+
+**✅ IP Address Whitelisting**
+
+You can specify which IP addresses can access password protected content with IP Address Whitelisting.
+
+This feature adds an extra layer of security by preventing unauthorized access from IP addresses not included on the whitelist so that only approved users can access protected content.
+
+**✅ Specific Post/Page Protection**
+
+Do you have premium content or sensitive information that you want to restrict access to? With the Password Protected plugin, you can easily password protect WordPress pages or posts so that only authorized users can view them. This feature allows you to offer exclusive content to subscribers or conduct private testing before publication.
+
+Check out our guide on how to [password protect WordPress page](https://passwordprotectedwp.com/wordpress-password-protect-page/) the right way.
+
+**✅ User Role Whitelisting**
+
+If you are looking for simplified access control based on user roles. The User Role Whitelisting is the solution you need. By whitelisting certain user roles for your WordPress site, such as administrators, editors, or subscribers, you can ensure that authorized users can view protected content without entering a password.
+
+**✅ WP-Admin Protection**
+
+Password protect wp-login (WordPress admin login page) against unauthorized access. This feature adds an extra layer of security by requiring a password to access the WP-admin dashboard, giving you greater protection against unauthorized login attempts and a [WordPress brute force attack](https://passwordprotectedwp.com/wordpress-brute-force-attack/).
+
+When you password protect WordPress login page (WP-admin area), it prevents unauthorized users from accessing sensitive site settings, user data, and administrative functions. This is particularly important for sites with multiple administrators or contributors, as it helps prevent unauthorized changes to site settings or content.
+
+**✅ Password Attempt Activity Report (Weekly)**
+
+Gain valuable insights into user interactions with your protected content through our exclusive Password Attempt Activity Report. This report will provide a comprehensive overview of login attempts, including successful and failed tries, browsers utilized, and recent activity logs. Whether using the Free or Pro version, this report enables you to track login attempts and user activity efficiently.
+
+**✅ Custom Post Type Protection**
+
+Extend your site's security beyond standard posts and pages. Password Protected plugin allows you to secure any custom post type, such as portfolios, testimonials, or products. The feature is extremely useful for businesses or creatives looking to share proprietary content or offer exclusive access to certain areas of their site.
+
+**✅ Category/Taxonomy Protection**
+
+Password protect WordPress categories to take control of your site's organization and access. Using single or multiple passwords, you can lock specific categories or taxonomies, along with related post tags.
+
+This functionality is ideal for websites with diverse content categories or membership tiers. By restricting access to certain categories, you can create exclusive areas for different user groups or offer premium content to subscribers.
+
+**✅ Certain Page/Posts Exclusions**
+
+Maintain flexibility in your WordPress site's accessibility by excluding specific pages, posts, and post types from password protection. Whether it's your homepage, contact page, or landing page, you can ensure that certain content remains accessible to all visitors while securing entire website content with a password.
+
+**✅ Limit Login Attempts**
+
+Set up a limit for login attempts to protect your WordPress password protected screen against the most common WordPress attacks, such as brute force attacks. The Password Protected [limit login attempts](https://passwordprotectedwp.com/limit-login-attempts/) feature is a proactive measure that mitigates the risk of unauthorized access and strengthens overall site security.
+
+**✅ Password Expiration and Usage Limit**
+
+If you want to password protect WordPress pages/posts for a certain period, set expiration dates and impose usage limits to restrict the number of times a user can use the password. This will make your site more secure and make it easier to manage user access.
+
+**✅ Bypass URL**
+
+Want to share password protected content with someone without sharing the password? The Bypass URL feature enables you to do just that. You can create unique URLs that remain accessible to the users without requiring a password.
+
+**✅ Detailed Activity Logs**
+
+Stay informed and vigilant with detailed activity logs for every password attempt. This feature provides comprehensive insights into site activity, including IP addresses, dates, times, and login statuses, so you can easily monitor and review user interactions.
+
+**✅ Lock Screen Customization**
+
+Make a lasting impression on visitors with a personalized and professional lock screen. With our Login Designer plugin, you can customize the appearance of your password-protected screen to align with your brand identity and aesthetics.
+
+With options to customize the background, logo, and other elements of the lock screen, you can create a cohesive and visually appealing experience for users seeking access to your protected content.
+
+**✅ Multiple Password Management**
+
+Experience unmatched flexibility and control over access permissions with Multiple Password Management. You can create unlimited passwords for any lock screen. It is also easy to activate or deactivate multiple passwords for various purposes, from testing to membership management.
+
+== 🎉 5 Key Reasons Why You Should Opt for Password Protected Pro ==
+
+⚡ **Reason #1: Boost Your WordPress Site's Security With Ease**
+
+Upgrade your site's security with [Password Protected Pro](https://passwordprotectedwp.com/pricing/?utm_source=wp_org&utm_medium=readme) and get comprehensive password protection.
+
+Easily password protect WordPress website. From specific page/post protection to WP-Admin protection and user role whitelisting, Password Protected Pro empowers you to easily secure your site against unauthorized access.
+
+With intuitive password management features like multiple password management and detailed activity logs, maintaining security protocols becomes a seamless task, allowing you to focus on your core business objectives without compromising on protection.
+
+⚡ **Reason #2: Better User Experience and Accessibility**
+
+Unlock unparalleled flexibility in access control with Password Protected Pro's advanced features. Whether you're offering exclusive content to subscribers or conducting private testing before publication, specific page/post protection ensures that only authorized users can access sensitive information.
+
+Meanwhile, features like Bypass URLs and certain page/post exclusions allow you to maintain accessibility for public-facing content, striking the perfect balance between security and user experience.
+
+⚡ **Reason #3: Gain Valuable Insights and Oversight**
+
+Stay informed and vigilant with Password Protected Pro's weekly comprehensive activity reporting and logging capabilities. With the password attempt activity report, including detailed activity logs, you gain valuable insights into user interactions, login attempts, and site activity.
+
+This actionable data enables you to monitor access patterns, detect potential security threats, and optimize your access control strategy accordingly.
+
+By leveraging this insight, you can proactively enhance site security, mitigate risks, and ensure compliance with privacy regulations, fostering trust and confidence among your user base.
+
+⚡ **Reason #4: Simplified Password Management and Administration**
+
+Automate password management with Password Protected Pro's user-friendly interface and intuitive tools.
+
+With features like password expiration and usage limits, limit login attempts, and passwordless admin access, you can automate routine tasks, reduce administrative overhead, and ensure a smooth user experience.
+
+With simplified access control and administration, Password Protected Pro frees up your valuable time and resources so you can focus on your core business objectives while maintaining the highest standards of security and compliance.
+
+⚡ **Reason #5: Easy Membership Management**
+
+If you manage a membership site or subscription-based platform, Password Protected Pro offers the features you need to provide exclusive access to your users to maximize revenue.
+
+With features like user role whitelisting and multiple password management, you can conveniently control access permissions for your WordPress content. By simplifying [WordPress content protection](https://passwordprotectedwp.com/content-locking-in-wordpress/) and ensuring seamless access for paying members, you can enhance user experience, retain subscribers, and drive sustained revenue growth.
+
+== 🎉 Use Cases for WordPress Password Protection ==
+
+⚡ **Use Case #1: Offer Premium Content to Your Subscribers**
+
+Unlock the potential of your premium content by offering exclusive access to subscribers with Password Protected plugin. You can securely share articles, e-books, podcasts, and reports while tracking password usage and preventing unauthorized sharing.
+
+With the ability to generate multiple passwords, you can ensure that only paying subscribers enjoy your valuable content.
+
+⚡ **Use Case #2: Give Clients Exclusive Access to Your Portfolio**
+
+Securely showcase your portfolio to clients with Password Protected, safeguarding your work from unauthorized access. Generate unique passwords for each client, ensuring personalized access while impressing them with a custom lock screen.
+
+With Password Protected, you can maintain confidentiality and professionalism while sharing your creative endeavors.
+
+⚡ **Use Case #3: Keep Under Maintenance Pages Private**
+
+Maintain confidentiality and control over your unfinished website pages with Password Protected plugin. If you are working on a new website or updating existing pages, you can password protect entire WordPress site or specific pages.
+
+Generate temporary passwords with limited usage, providing secure access to administrators while keeping your work private until it's ready for public viewing.
+
+⚡ **Use Case #4: Create a Private Family Blog**
+
+Set up a secure and private space for your family to connect and share precious moments. Post family photos, videos, stories, and updates without worrying about unauthorized access.
+
+With the [Password Protected](https://passwordprotectedwp.com/) plugin, you can generate unique passwords for each family member and friend, ensuring that only those you trust can access your family blog.
+
+⚡ **Use Case #5: Provide Exclusive Access to Virtual Events**
+
+Host exclusive virtual events and password-protect your site pages/posts with Password Protected. Generate unique passwords for each participant and customize the lock screen to enhance professionalism.
+
+By offering exclusive access to virtual events, you can increase membership and engagement while providing a secure and memorable experience for participants.
+
+⚡ **Use Case #6: Create Member-Only WooCommerce Products**
+
+Get more sales and customer loyalty by offering member-only WooCommerce products with Password Protected. Securely password protect WooCommerce products or categories, assigning multiple passwords for different offerings.
+
+Whether it's special deals, discounts, or bonuses, the Password Protected plugin enables you to offer exclusive products to your valued members, driving sales and fostering a sense of exclusivity.
+
+Check out our detailed guide on how to [password protect WooCommerce products](https://passwordprotectedwp.com/password-protect-woocommerce-products/) and [WooCommerce shop page](https://passwordprotectedwp.com/password-protect-woocommerce-shop-page/).
+
+== Need Help? Get Expert Assistance ==
+
+Can't figure out how to implement password protection for your WordPress site? We've got you covered around the clock.
+
+Whether it's troubleshooting technical issues, setting up password protection, or exploring advanced features, our dedicated support team is here to assist you every step of the way.
+
+So, don't hesitate to [reach out for prompt and reliable guidance](https://objectsws.atlassian.net/servicedesk/customer/portal/18). Contact us now to experience smooth and hassle-free service 😀.
+
+== Documentation and support ==
+
+👉 To learn more, check out Password Protected [Technical Documentation](https://passwordprotectedwp.com/documentation/?utm_source=wp_org&utm_medium=readme)
+
+👉 Open a support ticket [here](https://objectsws.atlassian.net/servicedesk/customer/portal/18).
-= Documentation and support =
-* Password Protected [Technical Documentation](https://passwordwp.com/documentation/?utm_source=wp_org&utm_medium=readme)
-* You can open a support ticket [here](https://objectsws.atlassian.net/servicedesk/customer/portal/18)
-= Translations =
-If you would like to translate this plugin, you can easily contribute to the [Translating WordPress](https://translate.wordpress.org/projects/wp-plugins/password-protected/) page. The stable plugin needs to be 95% translated for a language file to be available to download/update via WordPress.
== Installation ==
@@ -95,9 +233,6 @@ If you are upgrading manually via FTP rather that through the WordPress automati
== Frequently Asked Questions ==
-= How can I change the WordPress logo to a different image? =
-Install and configure the [Login Logo](https://wordpress.org/plugins/login-logo/) plugin by Mark Jaquith or the [Uber Login Logo](https://wordpress.org/plugins/uber-login-logo/) plugin. This will change the logo on your password entry page AND also your admin login page.
-
= How can I enable feeds while the site is password protected? =
In the settings, check the 'Allow Feeds' checkbox.
@@ -116,9 +251,6 @@ If you go to your WordPress admin login page `/wp-login.php` and it shows the ad
If the admin login screen insteads shows the Password Protected field, you will need to access your site via SFTP/SSH and delete the Password Protected plugin folder in the plugins folder `wp-content/plugins/password-protected`.
-= How can I redirect to a different domain name when logging out? =
-If passing a redirect URL using 'redirect_to' when logging out you need you may need to use the [allowed domain names](https://codex.wordpress.org/Plugin_API/Filter_Reference/allowed_redirect_hosts) filter to allow redirecting to an external domain.
-
= Where can I report bugs and issues? =
Please log issues and bugs on the plugin's [GitHub page](https://github.com/benhuson/password-protected/issues).
You can also submit suggested enhancements if you like.
@@ -131,13 +263,46 @@ If you would like to translate this plugin you can easily contribute at the [Tra
== Screenshots ==
-1. Login page perfectly mimicks the WordPress login.
-2. Login page with reCaptcha v3
-3. Login page with reCaptcha v2
-4. Password Protected general settings page.
-4. Password Protected advanced settings page.
+1. Enable complete sitewide protection, whitelist IP address, and allow passwordless access.
+2. Exclude pages, posts, and post types from protection.
+3. Enable and create a bypass URL to get password free access with that link.
+4. Create and manage multiple passwords for your protected site and content.
+5. Enable and password protect specific or all pages, posts, and post types.
+6. Enable and select user roles that should be whitelisted.
+7. Google reCaptcha v2 and v3 settings.
+8. The protected screen perfectly mimics the WordPress login.
+9. The protected screen with reCaptcha v3.
+10. The protected screen with reCaptcha v2.
+11. Password Protect your WP login/WP admin.
+12. Limit password attempts to enhance your WordPress site protection.
+13. Stay informed with detailed activity logs for every password attempt.
+14. Gain valuable insights through our exclusive Password Attempt Activity Report.
+
== Changelog ==
+= 2.7.2 =
+- Fix: Updated depreciated PHP function to make it compatible with the latest PHP version.
+- Added: Login designer compatibility banner.
+- Improvement: Implement few UI tweaks.
+
+= 2.7.1 =
+- Fixed - Disabled activity report by default.
+
+= 2.7 =
+- New: Added Password Activity Report to provide weekly insights on access attempts to your protected sites.
+- New: Added Categoric Tabs and Sub-Tabs User Interface for easy navigation and better user experience.
+
+= 2.6.8 =
+- Fix: Gutenberg compatibility issue fixed - REST API was getting blocked
+
+= 2.6.7 =
+- Security: Patched two security improvements suggested by Wordfence team.
+- Fix: Updated depreciated PHP function to make it compatible with the latest PHP version.
+- Compatibility: Improved compatibility with Elementor.
+
+= 2.6.6 =
+- Improvement - Added support for HTML in the above and bottom text displayed in the password screen.
+
= 2.6.5.1 =
- Ensured seamless compatibility with the latest WordPress version
@@ -205,7 +370,7 @@ If you would like to translate this plugin you can easily contribute at the [Tra
- Update Portuguese translation. Props [Jonathan Hult](https://github.com/jhult).
- Update Russian translation. Props [Alexey Chumakov](https://github.com/achumakov).
-= 2.2.4 =
+= 2.2.4 =
- Check that `$_SERVER['REMOTE_ADDR']` is set.
= 2.2.3 =
diff --git a/templates/emails/activity-notification.php b/templates/emails/activity-notification.php
new file mode 100644
index 0000000..fb425fd
--- /dev/null
+++ b/templates/emails/activity-notification.php
@@ -0,0 +1,225 @@
+
+
+>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ' . get_option( 'admin_email' ) . '' );
+ ?>
+
+
+ ' . esc_attr( gmdate( 'd-M', $time[0] ) ). '',
+ '' . esc_attr( gmdate( 'd-M', $time[1] ) ) . ' ',
+ );
+ ?>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ' . esc_attr( get_bloginfo( 'name' ) ) . ''
+ );
+ ?>
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/theme/password-protected-login.php b/theme/password-protected-login.php
index 3f3beb3..f6193b6 100644
--- a/theme/password-protected-login.php
+++ b/theme/password-protected-login.php
@@ -133,7 +133,7 @@ function wp_login_viewport_meta() {
-
+
allow_remember_me() ) : ?>