LiteSpeed Cache - Version 2.0

Version Description

  • Mar 7 2018 =
  • [NEW FEATURE] Image Optimization Added level up guidance.
  • [REFACTOR] Image Optimization Refactored Image Optimization class.
  • [IAPI] Image Optimization New European Image Optimization server (EU2).
  • [IMPROVEMENT] Image Optimization Manual pull action continues pulling until complete.
  • [IMPROVEMENT] CDN Multiple CDNs can now be randomized for a single resource.
  • [IMPROVEMENT] Image Optimization Improved compatibility of long src images.
  • [IMPROVEMENT] Image Optimization Reduced runtime load.
  • [IMPROVEMENT] Image Optimization Avoid potential loss/reset of notified images status when pulling.
  • [IMPROVEMENT] Image Optimization Avoid duplicated optimization for multiple records in Media that have the same image source.
  • [IMPROVEMENT] Image Optimization Fixed issue where phantom images continued to show in not-yet-requested queue.
  • [BUGFIX] Core Improved compatibility when upgrading outside of WP Admin. (@jikatal @TylorB)
  • [BUGFIX] Crawler Improved HTTP/2 compatibility to avoid erroneous blacklisting.
  • [BUGFIX] Crawler Changing Delay setting will use server variable for min value validation if set.
  • [UPDATE] Crawler Added HTTP/2 protocol switch in the Crawler settings.
  • [UPDATE] Removed unnecessary translation strings.
  • [GUI] Display translated role group name string instead of English values. (@Richard Hordern)
  • [GUI] Added Join LiteSpeed Slack link.
  • [GUI] Import / Export Cosmetic changes to Import Settings file field.
  • [INTEGRATION] Improved compatibility with WPML Media for Image Optimization. (@szmigieldesign)
Download this release

Release Info

Developer LiteSpeedTech
Plugin Icon 128x128 LiteSpeed Cache
Version 2.0
Comparing to
See all releases

Code changes from version 1.9.1.1 to 2.0

Files changed (61) hide show
  1. admin/admin-api.class.php +18 -18
  2. admin/litespeed-cache-admin-display.class.php +76 -0
  3. admin/litespeed-cache-admin-error.class.php +0 -7
  4. admin/litespeed-cache-admin-settings.class.php +30 -11
  5. admin/litespeed-cache-admin.class.php +18 -20
  6. admin/tpl/image_optimization.php +79 -20
  7. admin/tpl/inc/admin_footer.php +14 -12
  8. admin/tpl/manage/manage_purge.php +1 -1
  9. admin/tpl/setting/settings_advanced.php +2 -2
  10. admin/tpl/setting/settings_cdn.php +43 -21
  11. admin/tpl/setting/settings_crawler.php +24 -8
  12. admin/tpl/setting/settings_esi.php +2 -2
  13. admin/tpl/setting/settings_excludes.php +4 -4
  14. admin/tpl/setting/settings_inc.cache_browser.php +1 -1
  15. admin/tpl/setting/settings_inc.cache_favicon.php +1 -1
  16. admin/tpl/setting/settings_inc.cache_mobile.php +2 -2
  17. admin/tpl/setting/settings_inc.cache_object.php +18 -18
  18. admin/tpl/setting/settings_inc.cache_resources.php +1 -1
  19. admin/tpl/setting/settings_inc.exclude_cookies.php +1 -1
  20. admin/tpl/setting/settings_inc.exclude_useragent.php +1 -1
  21. admin/tpl/setting/settings_inc.media_webp.php +1 -1
  22. admin/tpl/setting/settings_media.php +1 -1
  23. admin/tpl/setting/settings_optimize.php +2 -2
  24. admin/tpl/setting/settings_purge.php +1 -1
  25. admin/tpl/setting/settings_tuning.php +9 -9
  26. admin/tpl/settings.php +5 -2
  27. cli/litespeed-cache-cli-admin.class.php +2 -0
  28. css/iziModal.min.css +6 -0
  29. css/litespeed.css +142 -30
  30. inc/activation.class.php +10 -0
  31. inc/cdn.class.php +37 -2
  32. inc/config.class.php +16 -5
  33. inc/crawler.class.php +2 -0
  34. inc/data.class.php +149 -17
  35. inc/data_structure/img_optm.sql +20 -0
  36. inc/data_structure/optm.sql +8 -0
  37. inc/gui.class.php +6 -4
  38. inc/img_optm.class.php +1640 -0
  39. inc/import.class.php +1 -1
  40. inc/litespeed-cache.class.php +11 -1
  41. inc/litespeed.autoload.php +2 -0
  42. inc/media.class.php +4 -1247
  43. inc/router.class.php +17 -15
  44. inc/task.class.php +2 -2
  45. inc/vary.class.php +13 -13
  46. includes/litespeed-cache-activation.class.php +10 -0
  47. includes/litespeed-cache-cdn.class.php +37 -2
  48. includes/litespeed-cache-config.class.php +16 -5
  49. includes/litespeed-cache-crawler.class.php +2 -0
  50. includes/litespeed-cache-gui.class.php +6 -4
  51. includes/litespeed-cache-router.class.php +17 -15
  52. includes/litespeed-cache-task.class.php +2 -2
  53. includes/litespeed-cache-vary.class.php +13 -13
  54. includes/litespeed-cache.class.php +11 -1
  55. includes/litespeed.autoload.php +2 -0
  56. js/iziModal.min.js +6 -0
  57. languages/litespeed-cache.pot +337 -309
  58. lib/litespeed/litespeed-crawler.class.php +44 -7
  59. litespeed-cache.php +1 -1
  60. readme.txt +30 -6
  61. thirdparty/lscwp-3rd-woocommerce.cls.php +1 -1
admin/admin-api.class.php CHANGED
@@ -79,16 +79,16 @@ class LiteSpeed_Cache_Admin_API
79
 
80
  switch ( LiteSpeed_Cache_Router::verify_type() ) {
81
  case self::TYPE_NOTIFY_IMG :
82
- LiteSpeed_Cache_Media::get_instance()->notify_img() ;
83
  break ;
84
 
85
  case self::TYPE_CHECK_IMG :
86
  $instance->validate_lsserver() ;
87
- LiteSpeed_Cache_Media::get_instance()->check_img() ;
88
  break ;
89
 
90
  case self::TYPE_IMG_DESTROY_CALLBACK :
91
- LiteSpeed_Cache_Media::get_instance()->img_optimize_destroy_callback() ;
92
  break ;
93
 
94
  default:
@@ -143,7 +143,7 @@ class LiteSpeed_Cache_Admin_API
143
  private function _request_callback()
144
  {
145
  $key_hash = get_option( self::DB_API_KEY_HASH ) ;
146
- LiteSpeed_Cache_Log::debug( 'IAPI __callback request hash: ' . $key_hash ) ;
147
  exit( $key_hash ) ;
148
  }
149
 
@@ -157,7 +157,7 @@ class LiteSpeed_Cache_Admin_API
157
  public static function sapi_valiate_passive_callback()
158
  {
159
  if ( empty( $_REQUEST[ 'hash' ] ) ) {
160
- LiteSpeed_Cache_Log::debug( 'IAPI __callback bypassed passive check' ) ;
161
  return false ;
162
  }
163
  $instance = self::get_instance() ;
@@ -166,7 +166,7 @@ class LiteSpeed_Cache_Admin_API
166
  $key_hash = get_option( self::DB_API_KEY_HASH ) ;
167
  $hash_check = md5( $key_hash ) === $_REQUEST[ 'hash' ] ;
168
 
169
- LiteSpeed_Cache_Log::debug( 'IAPI __callback hash check ' . $key_hash . ': ' . ( $hash_check ? 'passed' : 'failed' ) ) ;
170
 
171
  return $hash_check ;
172
  }
@@ -184,18 +184,18 @@ class LiteSpeed_Cache_Admin_API
184
 
185
  // don't have auth_key yet
186
  if ( ! $instance->_iapi_key ) {
187
- LiteSpeed_Cache_Log::debug( 'IAPI __callback aggressive check failed: No init key' ) ;
188
  return false ;
189
  }
190
 
191
  // Once client has auth_key, each time when callback to check, need to carry on this key
192
  if ( empty( $_REQUEST[ 'auth_key' ] ) ) {
193
- LiteSpeed_Cache_Log::debug( 'IAPI __callback aggressive check failed: lack of auth_key' ) ;
194
  return false ;
195
  }
196
 
197
  $res = md5( $instance->_iapi_key ) === $_REQUEST[ 'auth_key' ] ;
198
- LiteSpeed_Cache_Log::debug( 'IAPI __callback aggressive auth_key check: ' . ( $res ? 'passed' : 'failed' ) ) ;
199
  return $res ;
200
  }
201
 
@@ -234,7 +234,7 @@ class LiteSpeed_Cache_Admin_API
234
 
235
  // Check if get key&server correctly
236
  if ( empty( $json[ 'auth_key' ] ) ) {
237
- LiteSpeed_Cache_Log::debug( 'IAPI request key failed: ', $json ) ;
238
  $msg = sprintf( __( 'IAPI Error %s', 'litespeed-cache' ), $json ) ;
239
  LiteSpeed_Cache_Admin_Display::error( $msg ) ;
240
  return ;
@@ -242,7 +242,7 @@ class LiteSpeed_Cache_Admin_API
242
 
243
  // store data into option locally
244
  update_option( self::DB_API_KEY, $json[ 'auth_key' ] ) ;
245
- LiteSpeed_Cache_Log::debug( 'IAPI applied auth_key' ) ;
246
 
247
  $this->_iapi_key = $json[ 'auth_key' ] ;
248
  }
@@ -256,7 +256,7 @@ class LiteSpeed_Cache_Admin_API
256
  private function _reset_key()
257
  {
258
  delete_option( self::DB_API_KEY ) ;
259
- LiteSpeed_Cache_Log::debug( 'IAPI delete auth_key' ) ;
260
 
261
  $msg = __( 'Reset IAPI key successfully.', 'litespeed-cache' ) ;
262
  LiteSpeed_Cache_Admin_Display::succeed( $msg ) ;
@@ -281,7 +281,7 @@ class LiteSpeed_Cache_Admin_API
281
 
282
  $url = $server . '/' . $action ;
283
 
284
- LiteSpeed_Cache_Log::debug( 'IAPI posting to : ' . $url ) ;
285
 
286
  $param = array(
287
  'auth_key' => $this->_iapi_key,
@@ -297,7 +297,7 @@ class LiteSpeed_Cache_Admin_API
297
 
298
  if ( is_wp_error( $response ) ) {
299
  $error_message = $response->get_error_message() ;
300
- LiteSpeed_Cache_Log::debug( 'IAPI failed to post: ' . $error_message ) ;
301
  return $error_message ;
302
  }
303
 
@@ -305,12 +305,12 @@ class LiteSpeed_Cache_Admin_API
305
  $json = json_decode( $response[ 'body' ], true ) ;
306
 
307
  if ( ! is_array( $json ) ) {
308
- LiteSpeed_Cache_Log::debug( 'IAPI failed to decode post json: ' . $response[ 'body' ] ) ;
309
  return $response[ 'body' ] ;
310
  }
311
 
312
  if ( ! empty( $json[ '_err' ] ) ) {
313
- LiteSpeed_Cache_Log::debug( 'IAPI _err: ' . $json[ '_err' ] ) ;
314
  $msg = __( 'Failed to communicate with LiteSpeed image server', 'litespeed-cache' ) . ': ' . $json[ '_err' ] ;
315
  $msg .= $this->_parse_link( $json ) ;
316
  LiteSpeed_Cache_Admin_Display::error( $msg ) ;
@@ -318,7 +318,7 @@ class LiteSpeed_Cache_Admin_API
318
  }
319
 
320
  if ( ! empty( $json[ '_info' ] ) ) {
321
- LiteSpeed_Cache_Log::debug( 'IAPI _info: ' . $json[ '_info' ] ) ;
322
  $msg = __( 'Message from LiteSpeed image server', 'litespeed-cache' ) . ': ' . $json[ '_info' ] ;
323
  $msg .= $this->_parse_link( $json ) ;
324
  LiteSpeed_Cache_Admin_Display::info( $msg ) ;
@@ -326,7 +326,7 @@ class LiteSpeed_Cache_Admin_API
326
  }
327
 
328
  if ( ! empty( $json[ '_note' ] ) ) {
329
- LiteSpeed_Cache_Log::debug( 'IAPI _note: ' . $json[ '_note' ] ) ;
330
  $msg = __( 'Message from LiteSpeed image server', 'litespeed-cache' ) . ': ' . $json[ '_note' ] ;
331
  $msg .= $this->_parse_link( $json ) ;
332
  LiteSpeed_Cache_Admin_Display::note( $msg ) ;
79
 
80
  switch ( LiteSpeed_Cache_Router::verify_type() ) {
81
  case self::TYPE_NOTIFY_IMG :
82
+ LiteSpeed_Cache_Img_Optm::get_instance()->notify_img() ;
83
  break ;
84
 
85
  case self::TYPE_CHECK_IMG :
86
  $instance->validate_lsserver() ;
87
+ LiteSpeed_Cache_Img_Optm::get_instance()->check_img() ;
88
  break ;
89
 
90
  case self::TYPE_IMG_DESTROY_CALLBACK :
91
+ LiteSpeed_Cache_Img_Optm::get_instance()->img_optimize_destroy_callback() ;
92
  break ;
93
 
94
  default:
143
  private function _request_callback()
144
  {
145
  $key_hash = get_option( self::DB_API_KEY_HASH ) ;
146
+ LiteSpeed_Cache_Log::debug( '[IAPI] __callback request hash: ' . $key_hash ) ;
147
  exit( $key_hash ) ;
148
  }
149
 
157
  public static function sapi_valiate_passive_callback()
158
  {
159
  if ( empty( $_REQUEST[ 'hash' ] ) ) {
160
+ LiteSpeed_Cache_Log::debug( '[IAPI] __callback bypassed passive check' ) ;
161
  return false ;
162
  }
163
  $instance = self::get_instance() ;
166
  $key_hash = get_option( self::DB_API_KEY_HASH ) ;
167
  $hash_check = md5( $key_hash ) === $_REQUEST[ 'hash' ] ;
168
 
169
+ LiteSpeed_Cache_Log::debug( '[IAPI] __callback hash check ' . $key_hash . ': ' . ( $hash_check ? 'passed' : 'failed' ) ) ;
170
 
171
  return $hash_check ;
172
  }
184
 
185
  // don't have auth_key yet
186
  if ( ! $instance->_iapi_key ) {
187
+ LiteSpeed_Cache_Log::debug( '[IAPI] __callback aggressive check failed: No init key' ) ;
188
  return false ;
189
  }
190
 
191
  // Once client has auth_key, each time when callback to check, need to carry on this key
192
  if ( empty( $_REQUEST[ 'auth_key' ] ) ) {
193
+ LiteSpeed_Cache_Log::debug( '[IAPI] __callback aggressive check failed: lack of auth_key' ) ;
194
  return false ;
195
  }
196
 
197
  $res = md5( $instance->_iapi_key ) === $_REQUEST[ 'auth_key' ] ;
198
+ LiteSpeed_Cache_Log::debug( '[IAPI] __callback aggressive auth_key check: ' . ( $res ? 'passed' : 'failed' ) ) ;
199
  return $res ;
200
  }
201
 
234
 
235
  // Check if get key&server correctly
236
  if ( empty( $json[ 'auth_key' ] ) ) {
237
+ LiteSpeed_Cache_Log::debug( '[IAPI] request key failed: ', $json ) ;
238
  $msg = sprintf( __( 'IAPI Error %s', 'litespeed-cache' ), $json ) ;
239
  LiteSpeed_Cache_Admin_Display::error( $msg ) ;
240
  return ;
242
 
243
  // store data into option locally
244
  update_option( self::DB_API_KEY, $json[ 'auth_key' ] ) ;
245
+ LiteSpeed_Cache_Log::debug( '[IAPI] applied auth_key' ) ;
246
 
247
  $this->_iapi_key = $json[ 'auth_key' ] ;
248
  }
256
  private function _reset_key()
257
  {
258
  delete_option( self::DB_API_KEY ) ;
259
+ LiteSpeed_Cache_Log::debug( '[IAPI] delete auth_key' ) ;
260
 
261
  $msg = __( 'Reset IAPI key successfully.', 'litespeed-cache' ) ;
262
  LiteSpeed_Cache_Admin_Display::succeed( $msg ) ;
281
 
282
  $url = $server . '/' . $action ;
283
 
284
+ LiteSpeed_Cache_Log::debug( '[IAPI] posting to : ' . $url ) ;
285
 
286
  $param = array(
287
  'auth_key' => $this->_iapi_key,
297
 
298
  if ( is_wp_error( $response ) ) {
299
  $error_message = $response->get_error_message() ;
300
+ LiteSpeed_Cache_Log::debug( '[IAPI] failed to post: ' . $error_message ) ;
301
  return $error_message ;
302
  }
303
 
305
  $json = json_decode( $response[ 'body' ], true ) ;
306
 
307
  if ( ! is_array( $json ) ) {
308
+ LiteSpeed_Cache_Log::debug( '[IAPI] failed to decode post json: ' . $response[ 'body' ] ) ;
309
  return $response[ 'body' ] ;
310
  }
311
 
312
  if ( ! empty( $json[ '_err' ] ) ) {
313
+ LiteSpeed_Cache_Log::debug( '[IAPI] _err: ' . $json[ '_err' ] ) ;
314
  $msg = __( 'Failed to communicate with LiteSpeed image server', 'litespeed-cache' ) . ': ' . $json[ '_err' ] ;
315
  $msg .= $this->_parse_link( $json ) ;
316
  LiteSpeed_Cache_Admin_Display::error( $msg ) ;
318
  }
319
 
320
  if ( ! empty( $json[ '_info' ] ) ) {
321
+ LiteSpeed_Cache_Log::debug( '[IAPI] _info: ' . $json[ '_info' ] ) ;
322
  $msg = __( 'Message from LiteSpeed image server', 'litespeed-cache' ) . ': ' . $json[ '_info' ] ;
323
  $msg .= $this->_parse_link( $json ) ;
324
  LiteSpeed_Cache_Admin_Display::info( $msg ) ;
326
  }
327
 
328
  if ( ! empty( $json[ '_note' ] ) ) {
329
+ LiteSpeed_Cache_Log::debug( '[IAPI] _note: ' . $json[ '_note' ] ) ;
330
  $msg = __( 'Message from LiteSpeed image server', 'litespeed-cache' ) . ': ' . $json[ '_note' ] ;
331
  $msg .= $this->_parse_link( $json ) ;
332
  LiteSpeed_Cache_Admin_Display::note( $msg ) ;
admin/litespeed-cache-admin-display.class.php CHANGED
@@ -71,6 +71,15 @@ class LiteSpeed_Cache_Admin_Display
71
  add_action('admin_enqueue_scripts', array($this, 'check_messages')) ;// We can do this bcos admin_notices hook is after admin_enqueue_scripts hook in wp-admin/admin-header.php
72
  }
73
 
 
 
 
 
 
 
 
 
 
74
  // add menus ( Also check for mu-plugins)
75
  if ( $is_network_admin && ( is_plugin_active_for_network( LSCWP_BASENAME ) || defined( 'LSCWP_MU_PLUGIN' ) ) ) {
76
  add_action('network_admin_menu', array($this, 'register_admin_menu')) ;
@@ -931,6 +940,73 @@ class LiteSpeed_Cache_Admin_Display
931
  . '</a>' ;
932
  }
933
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
934
  /**
935
  * Get the current instance object.
936
  *
71
  add_action('admin_enqueue_scripts', array($this, 'check_messages')) ;// We can do this bcos admin_notices hook is after admin_enqueue_scripts hook in wp-admin/admin-header.php
72
  }
73
 
74
+ /**
75
+ * In case this is called outside the admin page
76
+ * @see https://codex.wordpress.org/Function_Reference/is_plugin_active_for_network
77
+ * @since 2.0
78
+ */
79
+ if ( ! function_exists( 'is_plugin_active_for_network' ) ) {
80
+ require_once( ABSPATH . '/wp-admin/includes/plugin.php' ) ;
81
+ }
82
+
83
  // add menus ( Also check for mu-plugins)
84
  if ( $is_network_admin && ( is_plugin_active_for_network( LSCWP_BASENAME ) || defined( 'LSCWP_MU_PLUGIN' ) ) ) {
85
  add_action('network_admin_menu', array($this, 'register_admin_menu')) ;
940
  . '</a>' ;
941
  }
942
 
943
+ /**
944
+ * Return groups string
945
+ *
946
+ * @since 2.0
947
+ * @access public
948
+ */
949
+ public static function print_plural( $num, $kind = 'group' )
950
+ {
951
+ if ( $num > 1 ) {
952
+ switch ( $kind ) {
953
+ case 'group' :
954
+ return sprintf( __( '%s groups', 'litespeed-cache' ), $num ) ;
955
+
956
+ case 'image' :
957
+ return sprintf( __( '%s images', 'litespeed-cache' ), $num ) ;
958
+
959
+ default:
960
+ return $num ;
961
+ }
962
+
963
+ }
964
+
965
+ switch ( $kind ) {
966
+ case 'group' :
967
+ return sprintf( __( '%s group', 'litespeed-cache' ), $num ) ;
968
+
969
+ case 'image' :
970
+ return sprintf( __( '%s image', 'litespeed-cache' ), $num ) ;
971
+
972
+ default:
973
+ return $num ;
974
+ }
975
+ }
976
+
977
+ /**
978
+ * Return guidance html
979
+ *
980
+ * @since 2.0
981
+ * @access public
982
+ */
983
+ public static function guidance( $title, $steps, $current_step )
984
+ {
985
+ if ( $current_step === 'done' ) {
986
+ $current_step = count( $steps ) + 1 ;
987
+ }
988
+
989
+ $percentage = ' (' . floor( ( $current_step - 1 ) * 100 / count( $steps ) ) . '%)' ;
990
+
991
+ $html = '<div class="litespeed-guide">'
992
+ . '<h2>' . $title . $percentage . '</h2>'
993
+ . '<ol>' ;
994
+ foreach ( $steps as $k => $v ) {
995
+ $step = $k + 1 ;
996
+ if ( $current_step > $step ) {
997
+ $html .= '<li class="litespeed-guide-done">' ;
998
+ }
999
+ else {
1000
+ $html .= '<li>' ;
1001
+ }
1002
+ $html .= $v . '</li>' ;
1003
+ }
1004
+
1005
+ $html .= '</ol></div>' ;
1006
+
1007
+ return $html ;
1008
+ }
1009
+
1010
  /**
1011
  * Get the current instance object.
1012
  *
admin/litespeed-cache-admin-error.class.php CHANGED
@@ -41,7 +41,6 @@ class LiteSpeed_Cache_Admin_Error
41
  const E_SETTING_CUSTOM_SITEMAP_READ = 3030 ;
42
  const E_SETTING_CUSTOM_SITEMAP_PARSE = 3031 ;
43
 
44
- const E_SETTING_NUMERIC = 3500 ;
45
  const E_SETTING_CAT = 3510 ;
46
  const E_SETTING_TAG = 3520 ;
47
  const E_SETTING_LC = 3530 ; // login cookie setting
@@ -155,12 +154,6 @@ class LiteSpeed_Cache_Admin_Error
155
  return __('Can not parse custom sitemap xml file: %s.', 'litespeed-cache') . ' '
156
  . sprintf(__('Please make sure the file is xml format and the %s extension is installed on the server.', 'litespeed-cache'), 'php-xml') ;
157
 
158
- // Admin settings with expected parameters for message.
159
- case self::E_SETTING_NUMERIC:
160
- // %1 is the name of the option, %2 is the minimum integer allowed.
161
- return __('%1$s must be an integer between %2$d and %3$d',
162
- 'litespeed-cache') ;
163
-
164
  case self::E_SETTING_CAT:
165
  // %s is the category attempted to be added.
166
  return __('Removed category "%s" from list, ID does not exist.',
41
  const E_SETTING_CUSTOM_SITEMAP_READ = 3030 ;
42
  const E_SETTING_CUSTOM_SITEMAP_PARSE = 3031 ;
43
 
 
44
  const E_SETTING_CAT = 3510 ;
45
  const E_SETTING_TAG = 3520 ;
46
  const E_SETTING_LC = 3530 ; // login cookie setting
154
  return __('Can not parse custom sitemap xml file: %s.', 'litespeed-cache') . ' '
155
  . sprintf(__('Please make sure the file is xml format and the %s extension is installed on the server.', 'litespeed-cache'), 'php-xml') ;
156
 
 
 
 
 
 
 
157
  case self::E_SETTING_CAT:
158
  // %s is the category attempted to be added.
159
  return __('Removed category "%s" from list, ID does not exist.',
admin/litespeed-cache-admin-settings.class.php CHANGED
@@ -16,8 +16,6 @@ class LiteSpeed_Cache_Admin_Settings
16
  private $_options ;
17
  private $_err ;
18
 
19
- private $_err_msg_numeric ;
20
-
21
  private $_max_int = 2147483647 ;
22
 
23
  /**
@@ -28,7 +26,21 @@ class LiteSpeed_Cache_Admin_Settings
28
  */
29
  private function __construct()
30
  {
31
- $this->_err_msg_numeric = LiteSpeed_Cache_Admin_Display::get_error( LiteSpeed_Cache_Admin_Error::E_SETTING_NUMERIC ) ;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
32
  }
33
 
34
  /**
@@ -343,14 +355,14 @@ class LiteSpeed_Cache_Admin_Settings
343
  LiteSpeed_Cache_Config::OPID_PRIVATE_TTL => array( __( 'Default Private Cache', 'litespeed-cache' ), 60, 3600 ),
344
  LiteSpeed_Cache_Config::OPID_FRONT_PAGE_TTL => array( __( 'Default Front Page', 'litespeed-cache' ), 30, $this->_max_int ),
345
  LiteSpeed_Cache_Config::OPID_FEED_TTL => array( __( 'Feed', 'litespeed-cache' ), 0, $this->_max_int, 30 ),
346
- LiteSpeed_Cache_Config::OPID_404_TTL => array( __( '404', 'litespeed-cache' ), 0, $this->_max_int, 30 ),
347
- LiteSpeed_Cache_Config::OPID_403_TTL => array( __( '403', 'litespeed-cache' ), 0, $this->_max_int, 30 ),
348
- LiteSpeed_Cache_Config::OPID_500_TTL => array( __( '500', 'litespeed-cache' ), 0, $this->_max_int, 30 ),
349
  ) ;
350
  foreach ( $ids as $id => $v ) {
351
  list( $desc, $min, $max ) = $v ;
352
  if ( ! $this->_check_ttl( $this->_input, $id, $min, $max ) ) {
353
- $this->_err[] = sprintf( $this->_err_msg_numeric, $desc, $min, $max ) ;
354
  }
355
  else {
356
  if ( ! empty( $v[ 3 ] ) && $this->_input[ $id ] < $v[ 3 ] ) {
@@ -841,7 +853,7 @@ class LiteSpeed_Cache_Admin_Settings
841
 
842
  $id = LiteSpeed_Cache_Config::OPID_LOG_FILE_SIZE ;
843
  if ( ! $this->_check_ttl( $this->_input, $id, 3, 3000 ) ) {
844
- $this->_err[] = sprintf( $this->_err_msg_numeric, __( 'Log File Size Limit', 'litespeed-cache' ), 3, 3000 ) ;
845
  }
846
  else {
847
  $this->_options[ $id ] = $this->_input[ $id ] ;
@@ -881,6 +893,7 @@ class LiteSpeed_Cache_Admin_Settings
881
  LiteSpeed_Cache_Config::CRWL_PAGES,
882
  LiteSpeed_Cache_Config::CRWL_CATS,
883
  LiteSpeed_Cache_Config::CRWL_TAGS,
 
884
  ) ;
885
  foreach ( $ids as $id ) {
886
  $this->_options[ $id ] = self::parse_onoff( $this->_input, $id ) ;
@@ -906,8 +919,14 @@ class LiteSpeed_Cache_Admin_Settings
906
  }
907
  $this->_options[ $id ] = $this->_input[ $id ] ;
908
 
 
 
 
 
 
 
909
  $ids = array(
910
- LiteSpeed_Cache_Config::CRWL_USLEEP => array( __( 'Delay', 'litespeed-cache' ), 0, 30000 ),
911
  LiteSpeed_Cache_Config::CRWL_RUN_DURATION => array( __( 'Run Duration', 'litespeed-cache' ), 0, $this->_max_int ),
912
  LiteSpeed_Cache_Config::CRWL_RUN_INTERVAL => array( __( 'Cron Interval', 'litespeed-cache' ), 60, $this->_max_int ),
913
  LiteSpeed_Cache_Config::CRWL_CRAWL_INTERVAL => array( __( 'Whole Interval', 'litespeed-cache' ), 0, $this->_max_int ),
@@ -916,7 +935,7 @@ class LiteSpeed_Cache_Admin_Settings
916
  foreach ( $ids as $id => $v ) {
917
  list( $desc, $min, $max ) = $v ;
918
  if ( ! $this->_check_ttl( $this->_input, $id, $min, $max ) ) {
919
- $this->_err[] = sprintf( $this->_err_msg_numeric, $desc, $min, $max ) ;
920
  }
921
  else {
922
  $this->_options[ $id ] = $this->_input[ $id ] ;
@@ -989,7 +1008,7 @@ class LiteSpeed_Cache_Admin_Settings
989
  foreach ( $ids as $id => $v ) {
990
  list( $desc, $min, $max ) = $v ;
991
  if ( ! $this->_check_ttl( $this->_input, $id, $min, $max ) ) {
992
- $this->_err[] = sprintf( $this->_err_msg_numeric, $desc, $min, $max ) ;
993
  }
994
  else {
995
  $new_options[ $id ] = $this->_input[ $id ] ;
16
  private $_options ;
17
  private $_err ;
18
 
 
 
19
  private $_max_int = 2147483647 ;
20
 
21
  /**
26
  */
27
  private function __construct()
28
  {
29
+ }
30
+
31
+ /**
32
+ * Display err msg for ttl
33
+ *
34
+ * @since 2.0
35
+ * @access private
36
+ */
37
+ private function _show_ttl_err( $desc, $min, $max )
38
+ {
39
+ if ( ! $max ) {
40
+ return sprintf( __( '%1$s must be an integer larger than %2$d', 'litespeed-cache' ), $desc, $min ) ;
41
+ }
42
+
43
+ return sprintf( __( '%1$s must be an integer between %2$d and %3$d', 'litespeed-cache' ), $desc, $min, $max ) ;
44
  }
45
 
46
  /**
355
  LiteSpeed_Cache_Config::OPID_PRIVATE_TTL => array( __( 'Default Private Cache', 'litespeed-cache' ), 60, 3600 ),
356
  LiteSpeed_Cache_Config::OPID_FRONT_PAGE_TTL => array( __( 'Default Front Page', 'litespeed-cache' ), 30, $this->_max_int ),
357
  LiteSpeed_Cache_Config::OPID_FEED_TTL => array( __( 'Feed', 'litespeed-cache' ), 0, $this->_max_int, 30 ),
358
+ LiteSpeed_Cache_Config::OPID_404_TTL => array( '404', 0, $this->_max_int, 30 ),
359
+ LiteSpeed_Cache_Config::OPID_403_TTL => array( '403', 0, $this->_max_int, 30 ),
360
+ LiteSpeed_Cache_Config::OPID_500_TTL => array( '500', 0, $this->_max_int, 30 ),
361
  ) ;
362
  foreach ( $ids as $id => $v ) {
363
  list( $desc, $min, $max ) = $v ;
364
  if ( ! $this->_check_ttl( $this->_input, $id, $min, $max ) ) {
365
+ $this->_err[] = $this->_show_ttl_err( $desc, $min, $max ) ;
366
  }
367
  else {
368
  if ( ! empty( $v[ 3 ] ) && $this->_input[ $id ] < $v[ 3 ] ) {
853
 
854
  $id = LiteSpeed_Cache_Config::OPID_LOG_FILE_SIZE ;
855
  if ( ! $this->_check_ttl( $this->_input, $id, 3, 3000 ) ) {
856
+ $this->_err[] = $this->_show_ttl_err( __( 'Log File Size Limit', 'litespeed-cache' ), 3, 3000 ) ;
857
  }
858
  else {
859
  $this->_options[ $id ] = $this->_input[ $id ] ;
893
  LiteSpeed_Cache_Config::CRWL_PAGES,
894
  LiteSpeed_Cache_Config::CRWL_CATS,
895
  LiteSpeed_Cache_Config::CRWL_TAGS,
896
+ LiteSpeed_Cache_Config::CRWL_HTTP2,
897
  ) ;
898
  foreach ( $ids as $id ) {
899
  $this->_options[ $id ] = self::parse_onoff( $this->_input, $id ) ;
919
  }
920
  $this->_options[ $id ] = $this->_input[ $id ] ;
921
 
922
+ $usleep_min = 0 ;
923
+ $usleep_max = 30000 ;
924
+ if ( ! empty( $_SERVER[ LiteSpeed_Cache_Config::ENV_CRAWLER_USLEEP ] ) ) {
925
+ $usleep_min = $_SERVER[ LiteSpeed_Cache_Config::ENV_CRAWLER_USLEEP ] ;
926
+ $usleep_max = null ;
927
+ }
928
  $ids = array(
929
+ LiteSpeed_Cache_Config::CRWL_USLEEP => array( __( 'Delay', 'litespeed-cache' ), $usleep_min, $usleep_max ),
930
  LiteSpeed_Cache_Config::CRWL_RUN_DURATION => array( __( 'Run Duration', 'litespeed-cache' ), 0, $this->_max_int ),
931
  LiteSpeed_Cache_Config::CRWL_RUN_INTERVAL => array( __( 'Cron Interval', 'litespeed-cache' ), 60, $this->_max_int ),
932
  LiteSpeed_Cache_Config::CRWL_CRAWL_INTERVAL => array( __( 'Whole Interval', 'litespeed-cache' ), 0, $this->_max_int ),
935
  foreach ( $ids as $id => $v ) {
936
  list( $desc, $min, $max ) = $v ;
937
  if ( ! $this->_check_ttl( $this->_input, $id, $min, $max ) ) {
938
+ $this->_err[] = $this->_show_ttl_err( $desc, $min, $max ) ;
939
  }
940
  else {
941
  $this->_options[ $id ] = $this->_input[ $id ] ;
1008
  foreach ( $ids as $id => $v ) {
1009
  list( $desc, $min, $max ) = $v ;
1010
  if ( ! $this->_check_ttl( $this->_input, $id, $min, $max ) ) {
1011
+ $this->_err[] = $this->_show_ttl_err( $desc, $min, $max ) ;
1012
  }
1013
  else {
1014
  $new_options[ $id ] = $this->_input[ $id ] ;
admin/litespeed-cache-admin.class.php CHANGED
@@ -34,10 +34,6 @@ class LiteSpeed_Cache_Admin
34
 
35
  $this->config = LiteSpeed_Cache_Config::get_instance() ;
36
 
37
- if ( ! function_exists( 'is_plugin_active_for_network' ) ) {
38
- require_once( ABSPATH . '/wp-admin/includes/plugin.php' ) ;//todo: check if needed
39
- }
40
-
41
  // initialize admin actions
42
  add_action( 'admin_init', array( $this, 'admin_init' ) ) ;
43
  // add link to plugin list page
@@ -239,29 +235,31 @@ class LiteSpeed_Cache_Admin
239
  * @access public
240
  * @global string $pagenow
241
  */
242
- public static function redirect()
243
  {
244
  global $pagenow ;
245
  $qs = '' ;
246
-
247
- if ( ! empty($_GET) ) {
248
- if ( isset($_GET[LiteSpeed_Cache::ACTION_KEY]) ) {
249
- unset($_GET[LiteSpeed_Cache::ACTION_KEY]) ;
 
 
 
 
 
 
 
250
  }
251
- if ( isset($_GET[LiteSpeed_Cache::NONCE_NAME]) ) {
252
- unset($_GET[LiteSpeed_Cache::NONCE_NAME]) ;
253
  }
254
- if ( ! empty($_GET) ) {
255
- $qs = '?' . http_build_query($_GET) ;
256
  }
257
  }
258
- if ( is_network_admin() ) {
259
- $url = network_admin_url($pagenow . $qs) ;
260
- }
261
- else {
262
- $url = admin_url($pagenow . $qs) ;
263
- }
264
- wp_redirect($url) ;
265
  exit() ;
266
  }
267
 
34
 
35
  $this->config = LiteSpeed_Cache_Config::get_instance() ;
36
 
 
 
 
 
37
  // initialize admin actions
38
  add_action( 'admin_init', array( $this, 'admin_init' ) ) ;
39
  // add link to plugin list page
235
  * @access public
236
  * @global string $pagenow
237
  */
238
+ public static function redirect( $url = false )
239
  {
240
  global $pagenow ;
241
  $qs = '' ;
242
+ if ( ! $url ) {
243
+ if ( ! empty( $_GET ) ) {
244
+ if ( isset( $_GET[ LiteSpeed_Cache::ACTION_KEY ] ) ) {
245
+ unset( $_GET[ LiteSpeed_Cache::ACTION_KEY ] ) ;
246
+ }
247
+ if ( isset( $_GET[ LiteSpeed_Cache::NONCE_NAME ] ) ) {
248
+ unset( $_GET[ LiteSpeed_Cache::NONCE_NAME ] ) ;
249
+ }
250
+ if ( ! empty( $_GET ) ) {
251
+ $qs = '?' . http_build_query( $_GET ) ;
252
+ }
253
  }
254
+ if ( is_network_admin() ) {
255
+ $url = network_admin_url( $pagenow . $qs ) ;
256
  }
257
+ else {
258
+ $url = admin_url( $pagenow . $qs ) ;
259
  }
260
  }
261
+
262
+ wp_redirect( $url ) ;
 
 
 
 
 
263
  exit() ;
264
  }
265
 
admin/tpl/image_optimization.php CHANGED
@@ -1,12 +1,15 @@
1
  <?php
2
  if ( ! defined( 'WPINC' ) ) die ;
3
 
4
- $media = LiteSpeed_Cache_Media::get_instance() ;
 
5
 
6
- $img_count = $media->img_count() ;
7
- $optm_summary = $media->summary_info() ;
8
 
9
- list( $last_run, $is_running ) = $media->cron_running( false ) ;
 
 
 
10
 
11
  $_optm_summary_list = array(
12
  'level' => array(
@@ -40,6 +43,24 @@ $_optm_summary_list = array(
40
  ),
41
  ) ;
42
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
43
 
44
  include_once LSCWP_DIR . "admin/tpl/inc/banner_promo.php" ;
45
  ?>
@@ -58,6 +79,10 @@ include_once LSCWP_DIR . "admin/tpl/inc/banner_promo.php" ;
58
 
59
  <div class="litespeed-wrap">
60
  <div class="litespeed-body">
 
 
 
 
61
  <h3 class="litespeed-title"><?php echo __('Optimization Summary', 'litespeed-cache') ; ?></h3>
62
 
63
  <?php foreach ( $_optm_summary_list as $k => $v ) : ?>
@@ -87,8 +112,8 @@ include_once LSCWP_DIR . "admin/tpl/inc/banner_promo.php" ;
87
  <?php endif ; ?>
88
  <?php endforeach ; ?>
89
 
90
- <a href="<?php echo LiteSpeed_Cache_Utility::build_url( LiteSpeed_Cache::ACTION_MEDIA, LiteSpeed_Cache_Media::TYPE_SYNC_DATA ) ; ?>" class="litespeed-btn-success">
91
- <?php echo __( 'Update Reduction Status', 'litespeed-cache' ) ; ?>
92
  </a>
93
  <span class="litespeed-desc">
94
  <?php echo __( 'This will communicate with LiteSpeed\'s Image Optimization Server and retrieve the most recent status.', 'litespeed-cache' ) ; ?>
@@ -100,19 +125,35 @@ include_once LSCWP_DIR . "admin/tpl/inc/banner_promo.php" ;
100
  <span class="litespeed-desc"><?php echo __('Beta Version', 'litespeed-cache') ; ?></span>
101
  </h3>
102
 
103
- <p><?php echo sprintf( __( '<a %s>Image groups</a> total', 'litespeed-cache'), 'href="https://www.litespeedtech.com/support/wiki/doku.php/litespeed_wiki:cache:lscwp:image-optimization:image-groups" target="_blank"' ) ; ?>: <b><?php echo $img_count[ 'total_img' ] ; ?></b></p>
104
- <p><?php echo __('Image groups not yet requested', 'litespeed-cache') ; ?>: <b><?php echo $img_count[ 'total_not_requested' ] ; ?></b></p>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
105
  <?php if ( $img_count[ 'total_not_requested' ] ) : ?>
106
  <?php if ( empty( $optm_summary[ 'level' ] ) ) : ?>
107
  <a href="#" class="litespeed-btn-default disabled">
108
  <?php echo __( 'Send Optimization Request', 'litespeed-cache' ) ; ?>
109
  </a>
110
  <span class="litespeed-desc">
111
- <?php echo sprintf( __( 'Please press the %s button before sending a new request.', 'litespeed-cache' ), __( 'Update Reduction Status', 'litespeed-cache' ) ) ; ?>
112
  </span>
113
  <a href="https://www.litespeedtech.com/support/wiki/doku.php/litespeed_wiki:cache:lscwp:image-optimization#image_optimization_in_litespeed_cache_for_wordpress" target="_blank"><?php echo __('Learn More', 'litespeed-cache') ; ?></a>
114
  <?php else : ?>
115
- <a href="<?php echo LiteSpeed_Cache_Utility::build_url( LiteSpeed_Cache::ACTION_MEDIA, LiteSpeed_Cache_Media::TYPE_IMG_OPTIMIZE ) ; ?>" class="litespeed-btn-success">
116
  <?php echo __( 'Send Optimization Request', 'litespeed-cache' ) ; ?>
117
  </a>
118
  <span class="litespeed-desc">
@@ -125,17 +166,31 @@ include_once LSCWP_DIR . "admin/tpl/inc/banner_promo.php" ;
125
  <hr />
126
 
127
  <p>
128
- <?php echo __('Image groups requested', 'litespeed-cache') ; ?>: <b><?php echo $img_count[ 'total_requested' ] ; ?></b>
 
 
 
 
 
 
 
 
 
 
 
 
129
  </p>
130
- <p><?php echo __('Image groups failed to optimize', 'litespeed-cache') ; ?>: <b><?php echo $img_count[ 'total_err' ] ; ?></b></p>
131
  <p class="litespeed-desc">
132
  <?php echo __( 'After LiteSpeed\'s Image Optimization Server finishes optimization, it will notify your site to pull the optimized images.', 'litespeed-cache' ) ; ?>
133
  <?php echo __( 'This process is automatic.', 'litespeed-cache' ) ; ?>
134
  </p>
135
  <p>
136
- <?php echo __('Image groups notified to pull', 'litespeed-cache') ; ?>: <b><?php echo $img_count[ 'total_server_finished' ] ; ?></b>
 
 
 
137
  <?php if ( $img_count[ 'total_server_finished' ] && ! $is_running ) : ?>
138
- <a href="<?php echo LiteSpeed_Cache_Utility::build_url( LiteSpeed_Cache::ACTION_MEDIA, LiteSpeed_Cache_Media::TYPE_IMG_PULL ) ; ?>" class="litespeed-btn-success">
139
  <?php echo __( 'Pull Images', 'litespeed-cache' ) ; ?>
140
  </a>
141
  <span class="litespeed-desc">
@@ -148,7 +203,11 @@ include_once LSCWP_DIR . "admin/tpl/inc/banner_promo.php" ;
148
  </span>
149
  <?php endif ; ?>
150
  </p>
151
- <p><?php echo __('Image groups optimized and pulled', 'litespeed-cache') ; ?>: <b><?php echo $img_count[ 'total_pulled' ] ; ?></b></p>
 
 
 
 
152
  <p><a href="https://www.litespeedtech.com/support/wiki/doku.php/litespeed_wiki:cache:lscwp:image-optimization#image_optimization_in_litespeed_cache_for_wordpress" target="_blank"><?php echo __('Learn More', 'litespeed-cache') ; ?></a></p>
153
 
154
  <hr />
@@ -162,7 +221,7 @@ include_once LSCWP_DIR . "admin/tpl/inc/banner_promo.php" ;
162
 
163
  <br />
164
 
165
- <a href="<?php echo LiteSpeed_Cache_Utility::build_url( LiteSpeed_Cache::ACTION_MEDIA, LiteSpeed_Cache_Media::TYPE_IMG_BATCH_SWITCH_ORI ) ; ?>" class="litespeed-btn-danger">
166
  <?php echo __( 'Undo Optimization', 'litespeed-cache' ) ; ?>
167
  </a>
168
  <span class="litespeed-desc">
@@ -171,7 +230,7 @@ include_once LSCWP_DIR . "admin/tpl/inc/banner_promo.php" ;
171
 
172
  <br />
173
 
174
- <a href="<?php echo LiteSpeed_Cache_Utility::build_url( LiteSpeed_Cache::ACTION_MEDIA, LiteSpeed_Cache_Media::TYPE_IMG_BATCH_SWITCH_OPTM ) ; ?>" class="litespeed-btn-warning">
175
  <?php echo __( 'Re-do Optimization', 'litespeed-cache' ) ; ?>
176
  </a>
177
  <span class="litespeed-desc">
@@ -183,7 +242,7 @@ include_once LSCWP_DIR . "admin/tpl/inc/banner_promo.php" ;
183
  <?php echo sprintf( __( 'Results can be checked in <a %s>Media Library</a>.', 'litespeed-cache' ), 'href="upload.php?mode=list"' ) ; ?>
184
  </p>
185
 
186
- <a href="<?php echo LiteSpeed_Cache_Utility::build_url( LiteSpeed_Cache::ACTION_MEDIA, LiteSpeed_Cache_Media::TYPE_IMG_OPTIMIZE_RESCAN ) ; ?>" class="litespeed-btn-success">
187
  <?php echo __( 'Send New Thumbnail Requests', 'litespeed-cache' ) ; ?>
188
  </a>
189
  <span class="litespeed-desc">
@@ -199,13 +258,13 @@ include_once LSCWP_DIR . "admin/tpl/inc/banner_promo.php" ;
199
  </span>
200
 
201
  <br />
202
- <a href="<?php echo LiteSpeed_Cache_Utility::build_url( LiteSpeed_Cache::ACTION_MEDIA, LiteSpeed_Cache_Media::TYPE_IMG_OPTIMIZE_DESTROY ) ; ?>" class="litespeed-btn-danger">
203
  <?php echo __( 'Destroy All Optimization Data!', 'litespeed-cache' ) ; ?>
204
  </a>
205
  <span class="litespeed-desc">
206
  <?php echo __( 'Remove all previous image optimization requests/results, revert completed optimizations, and delete all optimization files.', 'litespeed-cache' ) ; ?>
207
  <font class="litespeed-warning">
208
- <?php echo __('NOTE:', 'litespeed-cache'); ?>
209
  <?php echo sprintf( __( 'If there are unfinished requests in progress, the requests\' credits will NOT be recovered.', 'litespeed-cache' ), 'jQuery', __( 'JS Combine', 'litespeed-cache' ) ) ; ?>
210
  </font>
211
 
1
  <?php
2
  if ( ! defined( 'WPINC' ) ) die ;
3
 
4
+ // Update table data for upgrading
5
+ LiteSpeed_Cache_Data::get_instance() ;
6
 
7
+ $img_optm = LiteSpeed_Cache_Img_Optm::get_instance() ;
 
8
 
9
+ $img_count = $img_optm->img_count() ;
10
+ $optm_summary = $img_optm->summary_info() ;
11
+
12
+ list( $last_run, $is_running ) = $img_optm->cron_running( false ) ;
13
 
14
  $_optm_summary_list = array(
15
  'level' => array(
43
  ),
44
  ) ;
45
 
46
+ // Guidance check
47
+ $current_step = false ;
48
+ if ( empty( $optm_summary[ 'level' ] ) || $optm_summary[ 'level' ] < 2 ) {
49
+ $current_step = $img_optm->get_guidance_pos() ;
50
+ }
51
+ $guidance_steps = array(
52
+ sprintf( __( 'Click the %s button.', 'litespeed-cache' ), '<font class="litespeed-success">' . __( 'Update Status', 'litespeed-cache' ) . '</font>' ),
53
+ sprintf( __( 'Click the %s button.', 'litespeed-cache' ), '<font class="litespeed-success">' . __( 'Send Optimization Request', 'litespeed-cache' ) . '</font>' ),
54
+ sprintf( __( 'Click the %s button or wait for the cron job to finish the pull action.', 'litespeed-cache' ), '<font class="litespeed-success">' . __( 'Pull Images', 'litespeed-cache' ) . '</font>' ),
55
+ __( 'Repeat the above steps until you have leveled up.', 'litespeed-cache' )
56
+ ) ;
57
+
58
+ if ( ! empty( $img_count[ 'total_img' ] ) ) {
59
+ $finished_percentage = 100 - floor( $img_count[ 'total_not_requested' ] * 100 / $img_count[ 'total_img' ] ) ;
60
+ }
61
+ else {
62
+ $finished_percentage = 0 ;
63
+ }
64
 
65
  include_once LSCWP_DIR . "admin/tpl/inc/banner_promo.php" ;
66
  ?>
79
 
80
  <div class="litespeed-wrap">
81
  <div class="litespeed-body">
82
+ <?php if ( $current_step ) : ?>
83
+ <?php echo LiteSpeed_Cache_Admin_Display::guidance( __( 'How to Level Up', 'litespeed-cache' ), $guidance_steps, $current_step ) ; ?>
84
+ <?php endif ; ?>
85
+
86
  <h3 class="litespeed-title"><?php echo __('Optimization Summary', 'litespeed-cache') ; ?></h3>
87
 
88
  <?php foreach ( $_optm_summary_list as $k => $v ) : ?>
112
  <?php endif ; ?>
113
  <?php endforeach ; ?>
114
 
115
+ <a href="<?php echo LiteSpeed_Cache_Utility::build_url( LiteSpeed_Cache::ACTION_IMG_OPTM, LiteSpeed_Cache_Img_Optm::TYPE_SYNC_DATA ) ; ?>" class="litespeed-btn-success">
116
+ <?php echo __( 'Update Status', 'litespeed-cache' ) ; ?>
117
  </a>
118
  <span class="litespeed-desc">
119
  <?php echo __( 'This will communicate with LiteSpeed\'s Image Optimization Server and retrieve the most recent status.', 'litespeed-cache' ) ; ?>
125
  <span class="litespeed-desc"><?php echo __('Beta Version', 'litespeed-cache') ; ?></span>
126
  </h3>
127
 
128
+ <div class="litespeed-block-tiny">
129
+ <div class="litespeed-col-auto">
130
+ <?php echo LiteSpeed_Cache_GUI::pie( $finished_percentage, 100, true ) ; ?>
131
+ </div>
132
+
133
+ <div class="litespeed-col-auto">
134
+ <p>
135
+ <?php echo __( 'Images total', 'litespeed-cache') ; ?>:
136
+ <b><?php echo LiteSpeed_Cache_Admin_Display::print_plural( $img_count[ 'total_img' ] ) ; ?></b>
137
+ <a href="https://www.litespeedtech.com/support/wiki/doku.php/litespeed_wiki:cache:lscwp:image-optimization:image-groups" target="_blank" class="litespeed-desc litespeed-left20"><?php echo __( 'What is a group?', 'litespeed-cache') ; ?></a>
138
+ </p>
139
+ <p>
140
+ <?php echo __('Images not yet requested', 'litespeed-cache') ; ?>:
141
+ <b><?php echo LiteSpeed_Cache_Admin_Display::print_plural( $img_count[ 'total_not_requested' ] ) ; ?></b>
142
+ </p>
143
+ </div>
144
+ </div>
145
+
146
  <?php if ( $img_count[ 'total_not_requested' ] ) : ?>
147
  <?php if ( empty( $optm_summary[ 'level' ] ) ) : ?>
148
  <a href="#" class="litespeed-btn-default disabled">
149
  <?php echo __( 'Send Optimization Request', 'litespeed-cache' ) ; ?>
150
  </a>
151
  <span class="litespeed-desc">
152
+ <?php echo sprintf( __( 'Please press the %s button before sending a new request.', 'litespeed-cache' ), __( 'Update Status', 'litespeed-cache' ) ) ; ?>
153
  </span>
154
  <a href="https://www.litespeedtech.com/support/wiki/doku.php/litespeed_wiki:cache:lscwp:image-optimization#image_optimization_in_litespeed_cache_for_wordpress" target="_blank"><?php echo __('Learn More', 'litespeed-cache') ; ?></a>
155
  <?php else : ?>
156
+ <a href="<?php echo LiteSpeed_Cache_Utility::build_url( LiteSpeed_Cache::ACTION_IMG_OPTM, LiteSpeed_Cache_Img_Optm::TYPE_IMG_OPTIMIZE ) ; ?>" class="litespeed-btn-success">
157
  <?php echo __( 'Send Optimization Request', 'litespeed-cache' ) ; ?>
158
  </a>
159
  <span class="litespeed-desc">
166
  <hr />
167
 
168
  <p>
169
+ <?php echo __('Images requested', 'litespeed-cache') ; ?>:
170
+ <b><?php echo LiteSpeed_Cache_Admin_Display::print_plural( $img_count[ 'total_requested_groups' ] ) ; ?></b>
171
+ (<b><?php echo LiteSpeed_Cache_Admin_Display::print_plural( $img_count[ 'total_requested' ], 'image' ) ; ?></b>)
172
+ </p>
173
+ <p>
174
+ <?php echo __('Images failed to optimize', 'litespeed-cache') ; ?>:
175
+ <b><?php echo LiteSpeed_Cache_Admin_Display::print_plural( $img_count[ 'total_err_groups' ] ) ; ?></b>
176
+ (<b><?php echo LiteSpeed_Cache_Admin_Display::print_plural( $img_count[ 'total_err' ], 'image' ) ; ?></b>)
177
+ </p>
178
+ <p>
179
+ <?php echo __('Image files missing', 'litespeed-cache') ; ?>:
180
+ <b><?php echo LiteSpeed_Cache_Admin_Display::print_plural( $img_count[ 'total_miss_groups' ] ) ; ?></b>
181
+ (<b><?php echo LiteSpeed_Cache_Admin_Display::print_plural( $img_count[ 'total_miss' ], 'image' ) ; ?></b>)
182
  </p>
 
183
  <p class="litespeed-desc">
184
  <?php echo __( 'After LiteSpeed\'s Image Optimization Server finishes optimization, it will notify your site to pull the optimized images.', 'litespeed-cache' ) ; ?>
185
  <?php echo __( 'This process is automatic.', 'litespeed-cache' ) ; ?>
186
  </p>
187
  <p>
188
+ <?php echo __('Images notified to pull', 'litespeed-cache') ; ?>:
189
+ <b><?php echo LiteSpeed_Cache_Admin_Display::print_plural( $img_count[ 'total_server_finished_groups' ] ) ; ?></b>
190
+ (<b><?php echo LiteSpeed_Cache_Admin_Display::print_plural( $img_count[ 'total_server_finished' ], 'image' ) ; ?></b>)
191
+
192
  <?php if ( $img_count[ 'total_server_finished' ] && ! $is_running ) : ?>
193
+ <a href="<?php echo LiteSpeed_Cache_Utility::build_url( LiteSpeed_Cache::ACTION_IMG_OPTM, LiteSpeed_Cache_Img_Optm::TYPE_IMG_PULL ) ; ?>" class="litespeed-btn-success">
194
  <?php echo __( 'Pull Images', 'litespeed-cache' ) ; ?>
195
  </a>
196
  <span class="litespeed-desc">
203
  </span>
204
  <?php endif ; ?>
205
  </p>
206
+ <p>
207
+ <?php echo __('Images optimized and pulled', 'litespeed-cache') ; ?>:
208
+ <b><?php echo LiteSpeed_Cache_Admin_Display::print_plural( $img_count[ 'total_pulled_groups' ] ) ; ?></b>
209
+ (<b><?php echo LiteSpeed_Cache_Admin_Display::print_plural( $img_count[ 'total_pulled' ], 'image' ) ; ?></b>)
210
+ </p>
211
  <p><a href="https://www.litespeedtech.com/support/wiki/doku.php/litespeed_wiki:cache:lscwp:image-optimization#image_optimization_in_litespeed_cache_for_wordpress" target="_blank"><?php echo __('Learn More', 'litespeed-cache') ; ?></a></p>
212
 
213
  <hr />
221
 
222
  <br />
223
 
224
+ <a href="<?php echo LiteSpeed_Cache_Utility::build_url( LiteSpeed_Cache::ACTION_IMG_OPTM, LiteSpeed_Cache_Img_Optm::TYPE_IMG_BATCH_SWITCH_ORI ) ; ?>" class="litespeed-btn-danger">
225
  <?php echo __( 'Undo Optimization', 'litespeed-cache' ) ; ?>
226
  </a>
227
  <span class="litespeed-desc">
230
 
231
  <br />
232
 
233
+ <a href="<?php echo LiteSpeed_Cache_Utility::build_url( LiteSpeed_Cache::ACTION_IMG_OPTM, LiteSpeed_Cache_Img_Optm::TYPE_IMG_BATCH_SWITCH_OPTM ) ; ?>" class="litespeed-btn-warning">
234
  <?php echo __( 'Re-do Optimization', 'litespeed-cache' ) ; ?>
235
  </a>
236
  <span class="litespeed-desc">
242
  <?php echo sprintf( __( 'Results can be checked in <a %s>Media Library</a>.', 'litespeed-cache' ), 'href="upload.php?mode=list"' ) ; ?>
243
  </p>
244
 
245
+ <a href="<?php echo LiteSpeed_Cache_Utility::build_url( LiteSpeed_Cache::ACTION_IMG_OPTM, LiteSpeed_Cache_Img_Optm::TYPE_IMG_OPTIMIZE_RESCAN ) ; ?>" class="litespeed-btn-success">
246
  <?php echo __( 'Send New Thumbnail Requests', 'litespeed-cache' ) ; ?>
247
  </a>
248
  <span class="litespeed-desc">
258
  </span>
259
 
260
  <br />
261
+ <a href="<?php echo LiteSpeed_Cache_Utility::build_url( LiteSpeed_Cache::ACTION_IMG_OPTM, LiteSpeed_Cache_Img_Optm::TYPE_IMG_OPTIMIZE_DESTROY ) ; ?>" class="litespeed-btn-danger">
262
  <?php echo __( 'Destroy All Optimization Data!', 'litespeed-cache' ) ; ?>
263
  </a>
264
  <span class="litespeed-desc">
265
  <?php echo __( 'Remove all previous image optimization requests/results, revert completed optimizations, and delete all optimization files.', 'litespeed-cache' ) ; ?>
266
  <font class="litespeed-warning">
267
+ <?php echo __('NOTE', 'litespeed-cache'); ?>:
268
  <?php echo sprintf( __( 'If there are unfinished requests in progress, the requests\' credits will NOT be recovered.', 'litespeed-cache' ), 'jQuery', __( 'JS Combine', 'litespeed-cache' ) ) ; ?>
269
  </font>
270
 
admin/tpl/inc/admin_footer.php CHANGED
@@ -1,19 +1,21 @@
1
  <?php
2
  if (!defined('WPINC')) die;
3
 
 
 
 
 
 
 
 
 
 
 
4
 
5
- $rate_us = sprintf(__('Rate <strong>LiteSpeed Cache</strong> with %s on WordPress.org if you like us!', 'litespeed-cache'),
6
- '<a href="https://wordpress.org/support/plugin/litespeed-cache/reviews/?filter=5#new-post" rel="noopener noreferer" target="_blank">&#10030;&#10030;&#10030;&#10030;&#10030;</a>'
7
- );
8
- $questions = sprintf(__('If there are any questions that are not answered in the <a %s>FAQs</a>, do not hesitate to ask them on the <a %s>support forum</a>.', 'litespeed-cache'),
9
- 'href="https://www.litespeedtech.com/support/wiki/doku.php/litespeed_wiki:cache:lscwp" target="_blank"',
10
- 'href="https://wordpress.org/support/plugin/litespeed-cache" rel="noopener noreferrer" target="_blank"');
11
  // Change the footer text
12
- if ( !is_multisite()
13
- || is_network_admin())
14
- {
15
- $footer_text = $rate_us . ' ' . $questions;
16
  }
17
- else{
18
- $footer_text = $questions;
19
  }
1
  <?php
2
  if (!defined('WPINC')) die;
3
 
4
+ // &#10030;&#10030;&#10030;&#10030;&#10030;
5
+ $rate_us = '<a href="https://wordpress.org/support/plugin/litespeed-cache/reviews/?filter=5#new-post" rel="noopener noreferer" target="_blank">'
6
+ . sprintf( __( 'Rate %s on %s', 'litespeed-cache' ), '<strong>' . __( 'LiteSpeed Cache', 'litespeed-cache' ) . '</strong>', 'WordPress.org' )
7
+ . '</a>' ;
8
+
9
+ $wiki = '<a href="https://www.litespeedtech.com/support/wiki/doku.php/litespeed_wiki:cache:lscwp" target="_blank">' . __( 'Read LiteSpeed Wiki', 'litespeed-cache' ) . '</a>' ;
10
+
11
+ $forum = '<a href="https://wordpress.org/support/plugin/litespeed-cache" target="_blank">' . __( 'Visit LSCWP support forum', 'litespeed-cache' ) . '</a>' ;
12
+
13
+ $community = '<a href="https://goo.gl/FG9S4N" target="_blank">' . __( 'Join LiteSpeed Slack community', 'litespeed-cache' ) . '</a>' ;
14
 
 
 
 
 
 
 
15
  // Change the footer text
16
+ if ( ! is_multisite() || is_network_admin() ) {
17
+ $footer_text = $rate_us . ' | ' . $wiki . ' | ' . $forum . ' | ' . $community ;
 
 
18
  }
19
+ else {
20
+ $footer_text = $wiki . ' | ' . $forum . ' | ' . $community ;
21
  }
admin/tpl/manage/manage_purge.php CHANGED
@@ -100,7 +100,7 @@ if ( ! is_multisite() || is_network_admin() ) {
100
  <?php foreach ( $_panels as $v ): ?>
101
 
102
  <?php if ( ! empty( $v[ 'newline' ] ) ) : ?>
103
- <div class='litespeed-child-col-br'></div>
104
  <?php endif; ?>
105
 
106
  <a class="litespeed-panel"
100
  <?php foreach ( $_panels as $v ): ?>
101
 
102
  <?php if ( ! empty( $v[ 'newline' ] ) ) : ?>
103
+ <div class='litespeed-col-br'></div>
104
  <?php endif; ?>
105
 
106
  <a class="litespeed-panel"
admin/tpl/setting/settings_advanced.php CHANGED
@@ -47,7 +47,7 @@ if (!defined('WPINC')) die;
47
  <?php echo __( 'When a vistor hovers over a page link, preload that page. This will speed up the visit to that link.', 'litespeed-cache' ) ; ?>
48
  <a href="https://www.litespeedtech.com/support/wiki/doku.php/litespeed_wiki:cache:lscwp:configuration:advanced#instant_click" target="_blank"><?php echo __('Learn More', 'litespeed-cache') ; ?></a>
49
  <br /><font class="litespeed-danger">
50
- <?php echo __('NOTE:', 'litespeed-cache'); ?>
51
  <?php echo __('This will generate extra requests to the server, which will increase server load.', 'litespeed-cache'); ?>
52
  </font>
53
 
@@ -65,7 +65,7 @@ if (!defined('WPINC')) die;
65
  <a href="https://www.litespeedtech.com/support/wiki/doku.php/litespeed_wiki:cache:lscwp:configuration:advanced#favicon" target="_blank"><?php echo __('Learn More', 'litespeed-cache') ; ?></a>
66
 
67
  </div>
68
- <div class="litespeed-cdn-mapping-block">
69
  <div class='litespeed-cdn-mapping-col1'>
70
  <h4><?php echo __( 'Frontend Favicon File', 'litespeed-cache' ) ; ?></h4>
71
 
47
  <?php echo __( 'When a vistor hovers over a page link, preload that page. This will speed up the visit to that link.', 'litespeed-cache' ) ; ?>
48
  <a href="https://www.litespeedtech.com/support/wiki/doku.php/litespeed_wiki:cache:lscwp:configuration:advanced#instant_click" target="_blank"><?php echo __('Learn More', 'litespeed-cache') ; ?></a>
49
  <br /><font class="litespeed-danger">
50
+ <?php echo __('NOTE', 'litespeed-cache'); ?>:
51
  <?php echo __('This will generate extra requests to the server, which will increase server load.', 'litespeed-cache'); ?>
52
  </font>
53
 
65
  <a href="https://www.litespeedtech.com/support/wiki/doku.php/litespeed_wiki:cache:lscwp:configuration:advanced#favicon" target="_blank"><?php echo __('Learn More', 'litespeed-cache') ; ?></a>
66
 
67
  </div>
68
+ <div class="litespeed-block">
69
  <div class='litespeed-cdn-mapping-col1'>
70
  <h4><?php echo __( 'Frontend Favicon File', 'litespeed-cache' ) ; ?></h4>
71
 
admin/tpl/setting/settings_cdn.php CHANGED
@@ -41,7 +41,7 @@ if ( ! $cdn_mapping ) {
41
  <td>
42
  <?php foreach ( $cdn_mapping as $v ) : ?>
43
 
44
- <div class="litespeed-cdn-mapping-block" data-litespeed-cdn-mapping="1">
45
  <div class='litespeed-cdn-mapping-col1'>
46
  <h4><?php echo __( 'CDN URL', 'litespeed-cache' ) ; ?>
47
  <button type="button" class="litespeed-btn-danger" data-litespeed-cdn-mapping-del="1">X</button>
@@ -94,8 +94,8 @@ if ( ! $cdn_mapping ) {
94
  <p><button type="button" class="litespeed-btn-success litespeed-btn-tiny" id="litespeed-cdn-mapping-add">+</button></p>
95
 
96
  <div class="litespeed-warning">
97
- <?php echo __('NOTE:', 'litespeed-cache'); ?>
98
- <?php echo __( 'If multiple CDN paths are configured with the same settings, the last one will override the others.', 'litespeed-cache' ) ; ?>
99
  </div>
100
 
101
  <div class="litespeed-desc">
@@ -157,13 +157,13 @@ if ( ! $cdn_mapping ) {
157
  <?php echo $this->build_radio(
158
  LiteSpeed_Cache_Config::OPID_CDN_REMOTE_JQUERY,
159
  LiteSpeed_Cache_Config::VAL_ON,
160
- __( 'Google', 'litespeed-cache' )
161
  ) ; ?>
162
 
163
  <?php echo $this->build_radio(
164
  LiteSpeed_Cache_Config::OPID_CDN_REMOTE_JQUERY,
165
  LiteSpeed_Cache_Config::VAL_ON2,
166
- __( 'Cdnjs', 'litespeed-cache' )
167
  ) ; ?>
168
  </div>
169
  <div class="litespeed-desc">
@@ -177,30 +177,52 @@ if ( ! $cdn_mapping ) {
177
  <td>
178
  <?php $this->build_switch( LiteSpeed_Cache_Config::OPID_CDN_QUIC ) ; ?>
179
  <div class="litespeed-desc">
180
- <?php echo __( 'Use Quic Cloud API functionality.', 'litespeed-cache' ) ; ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
181
  <?php echo sprintf( __( 'This can be managed from <a %2$s>%1$s</a>.', 'litespeed-cache' ), '<b>' . __( 'Manage', 'litespeed-cache' ) . '</b> -&gt; <b>' . __( 'CDN', 'litespeed-cache' ) . '</b>', 'href="admin.php?page=lscache-dash#cdn"' ) ; ?>
182
  </div>
183
- <div class="litespeed-cdn-mapping-block">
184
- <div class='litespeed-child-col'>
185
  <h4><?php echo __( 'Email Address', 'litespeed-cache' ) ; ?></h4>
186
 
187
  <?php $this->build_input( LiteSpeed_Cache_Config::OPID_CDN_QUIC_EMAIL ) ; ?>
188
  <div class="litespeed-desc">
189
- <?php echo __( 'Your Email address on Quic Cloud.', 'litespeed-cache' ) ; ?>
190
  </div>
191
  </div>
192
 
193
- <div class='litespeed-child-col'>
194
  <h4><?php echo __( 'User API Key', 'litespeed-cache' ) ; ?></h4>
195
 
196
  <?php $this->build_input( LiteSpeed_Cache_Config::OPID_CDN_QUIC_KEY ) ; ?>
197
  <div class="litespeed-desc">
198
- <?php echo __( 'Your API key is used to access Quic Cloud APIs.', 'litespeed-cache' ) ; ?>
199
- <?php echo sprintf( __( 'Get it from <a %s>Quic Cloud</a>.', 'litespeed-cache' ), 'href="https://quic.cloud/dashboard" target="_blank"' ) ; ?>
200
  </div>
201
  </div>
202
 
203
- <div class='litespeed-child-col'>
204
  <h4><?php echo __( 'Site Domain', 'litespeed-cache' ) ; ?></h4>
205
 
206
  <?php
@@ -220,30 +242,30 @@ if ( ! $cdn_mapping ) {
220
  <td>
221
  <?php $this->build_switch( LiteSpeed_Cache_Config::OPID_CDN_CLOUDFLARE ) ; ?>
222
  <div class="litespeed-desc">
223
- <?php echo __( 'Use Cloudflare API functionality.', 'litespeed-cache' ) ; ?>
224
  <?php echo sprintf( __( 'This can be managed from <a %2$s>%1$s</a>.', 'litespeed-cache' ), '<b>' . __( 'Manage', 'litespeed-cache' ) . '</b> -&gt; <b>' . __( 'CDN', 'litespeed-cache' ) . '</b>', 'href="admin.php?page=lscache-dash#cdn"' ) ; ?>
225
  </div>
226
- <div class="litespeed-cdn-mapping-block">
227
- <div class='litespeed-child-col'>
228
  <h4><?php echo __( 'Email Address', 'litespeed-cache' ) ; ?></h4>
229
 
230
  <?php $this->build_input( LiteSpeed_Cache_Config::OPID_CDN_CLOUDFLARE_EMAIL ) ; ?>
231
  <div class="litespeed-desc">
232
- <?php echo __( 'Your Email address on Cloudflare.', 'litespeed-cache' ) ; ?>
233
  </div>
234
  </div>
235
 
236
- <div class='litespeed-child-col'>
237
  <h4><?php echo __( 'Global API Key', 'litespeed-cache' ) ; ?></h4>
238
 
239
  <?php $this->build_input( LiteSpeed_Cache_Config::OPID_CDN_CLOUDFLARE_KEY ) ; ?>
240
  <div class="litespeed-desc">
241
- <?php echo __( 'Your API key is used to access Cloudflare APIs.', 'litespeed-cache' ) ; ?>
242
- <?php echo sprintf( __( 'Get it from <a %s>Cloudflare account</a>.', 'litespeed-cache' ), 'href="https://www.cloudflare.com/a/profile" target="_blank"' ) ; ?>
243
  </div>
244
  </div>
245
 
246
- <div class='litespeed-child-col'>
247
  <h4><?php echo __( 'Domain', 'litespeed-cache' ) ; ?></h4>
248
 
249
  <?php
41
  <td>
42
  <?php foreach ( $cdn_mapping as $v ) : ?>
43
 
44
+ <div class="litespeed-block" data-litespeed-cdn-mapping="1">
45
  <div class='litespeed-cdn-mapping-col1'>
46
  <h4><?php echo __( 'CDN URL', 'litespeed-cache' ) ; ?>
47
  <button type="button" class="litespeed-btn-danger" data-litespeed-cdn-mapping-del="1">X</button>
94
  <p><button type="button" class="litespeed-btn-success litespeed-btn-tiny" id="litespeed-cdn-mapping-add">+</button></p>
95
 
96
  <div class="litespeed-warning">
97
+ <?php echo __('NOTE', 'litespeed-cache'); ?>:
98
+ <?php echo __( 'To randomize CDN hostname, define multiple hostnames for the same resources.', 'litespeed-cache' ) ; ?>
99
  </div>
100
 
101
  <div class="litespeed-desc">
157
  <?php echo $this->build_radio(
158
  LiteSpeed_Cache_Config::OPID_CDN_REMOTE_JQUERY,
159
  LiteSpeed_Cache_Config::VAL_ON,
160
+ 'Google'
161
  ) ; ?>
162
 
163
  <?php echo $this->build_radio(
164
  LiteSpeed_Cache_Config::OPID_CDN_REMOTE_JQUERY,
165
  LiteSpeed_Cache_Config::VAL_ON2,
166
+ 'Cdnjs'
167
  ) ; ?>
168
  </div>
169
  <div class="litespeed-desc">
177
  <td>
178
  <?php $this->build_switch( LiteSpeed_Cache_Config::OPID_CDN_QUIC ) ; ?>
179
  <div class="litespeed-desc">
180
+ <?php echo sprintf( __( 'Use %s API functionality.', 'litespeed-cache' ), 'Quic Cloud' ) ; ?>
181
+
182
+ <a id='litespeed_modal_href' href="<?php echo LiteSpeed_Cache_Utility::build_url( LiteSpeed_Cache::ACTION_QUIC_CLOUD ) ; ?>">
183
+ <?php if ( ! empty( $_options[ LiteSpeed_Cache_Config::OPID_CDN_QUIC_EMAIL ] ) ) : ?>
184
+ Login API
185
+ <?php else : ?>
186
+ Free Register!
187
+ <?php endif ; ?>
188
+ </a>
189
+
190
+ <link rel="stylesheet" href="<?php echo LSWCP_PLUGIN_URL ; ?>css/iziModal.min.css">
191
+ <script type="text/javascript" src="<?php echo LSWCP_PLUGIN_URL ; ?>js/iziModal.min.js"></script>
192
+ <div id="litespeed_modal"></div>
193
+ <script type="text/javascript">
194
+ var litespeed_modal = jQuery("#litespeed_modal").iziModal({iframe: true});
195
+ jQuery("#litespeed_modal_href").click(function(event) {
196
+ event.preventDefault();
197
+ litespeed_modal.iziModal('open', event);
198
+ });;
199
+ </script>
200
+ <?php
201
+
202
+ ?>
203
  <?php echo sprintf( __( 'This can be managed from <a %2$s>%1$s</a>.', 'litespeed-cache' ), '<b>' . __( 'Manage', 'litespeed-cache' ) . '</b> -&gt; <b>' . __( 'CDN', 'litespeed-cache' ) . '</b>', 'href="admin.php?page=lscache-dash#cdn"' ) ; ?>
204
  </div>
205
+ <div class="litespeed-block">
206
+ <div class='litespeed-col'>
207
  <h4><?php echo __( 'Email Address', 'litespeed-cache' ) ; ?></h4>
208
 
209
  <?php $this->build_input( LiteSpeed_Cache_Config::OPID_CDN_QUIC_EMAIL ) ; ?>
210
  <div class="litespeed-desc">
211
+ <?php echo sprintf( __( 'Your Email address on %s.', 'litespeed-cache' ), 'Quic Cloud' ) ; ?>
212
  </div>
213
  </div>
214
 
215
+ <div class='litespeed-col'>
216
  <h4><?php echo __( 'User API Key', 'litespeed-cache' ) ; ?></h4>
217
 
218
  <?php $this->build_input( LiteSpeed_Cache_Config::OPID_CDN_QUIC_KEY ) ; ?>
219
  <div class="litespeed-desc">
220
+ <?php echo sprintf( __( 'Your API key is used to access %s APIs.', 'litespeed-cache' ), 'Quic Cloud' ) ; ?>
221
+ <?php echo sprintf( __( 'Get it from <a %1$s>%2$s</a>.', 'litespeed-cache' ), 'href="https://quic.cloud/dashboard" target="_blank"', 'Quic Cloud' ) ; ?>
222
  </div>
223
  </div>
224
 
225
+ <div class='litespeed-col'>
226
  <h4><?php echo __( 'Site Domain', 'litespeed-cache' ) ; ?></h4>
227
 
228
  <?php
242
  <td>
243
  <?php $this->build_switch( LiteSpeed_Cache_Config::OPID_CDN_CLOUDFLARE ) ; ?>
244
  <div class="litespeed-desc">
245
+ <?php echo sprintf( __( 'Use %s API functionality.', 'litespeed-cache' ), 'Cloudflare' ) ; ?>
246
  <?php echo sprintf( __( 'This can be managed from <a %2$s>%1$s</a>.', 'litespeed-cache' ), '<b>' . __( 'Manage', 'litespeed-cache' ) . '</b> -&gt; <b>' . __( 'CDN', 'litespeed-cache' ) . '</b>', 'href="admin.php?page=lscache-dash#cdn"' ) ; ?>
247
  </div>
248
+ <div class="litespeed-block">
249
+ <div class='litespeed-col'>
250
  <h4><?php echo __( 'Email Address', 'litespeed-cache' ) ; ?></h4>
251
 
252
  <?php $this->build_input( LiteSpeed_Cache_Config::OPID_CDN_CLOUDFLARE_EMAIL ) ; ?>
253
  <div class="litespeed-desc">
254
+ <?php echo sprintf( __( 'Your Email address on %s.', 'litespeed-cache' ), 'Cloudflare' ) ; ?>
255
  </div>
256
  </div>
257
 
258
+ <div class='litespeed-col'>
259
  <h4><?php echo __( 'Global API Key', 'litespeed-cache' ) ; ?></h4>
260
 
261
  <?php $this->build_input( LiteSpeed_Cache_Config::OPID_CDN_CLOUDFLARE_KEY ) ; ?>
262
  <div class="litespeed-desc">
263
+ <?php echo sprintf( __( 'Your API key is used to access %s APIs.', 'litespeed-cache' ), 'Cloudflare' ) ; ?>
264
+ <?php echo sprintf( __( 'Get it from <a %1$s>%2$s</a>.', 'litespeed-cache' ), 'href="https://www.cloudflare.com/a/profile" target="_blank"', 'Cloudflare' ) ; ?>
265
  </div>
266
  </div>
267
 
268
+ <div class='litespeed-col'>
269
  <h4><?php echo __( 'Domain', 'litespeed-cache' ) ; ?></h4>
270
 
271
  <?php
admin/tpl/setting/settings_crawler.php CHANGED
@@ -135,6 +135,22 @@ if ( !defined('WPINC') ) die;
135
  </td>
136
  </tr>
137
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
138
  <tr>
139
  <th><?php echo __('Custom Sitemap', 'litespeed-cache'); ?></th>
140
  <td>
@@ -149,31 +165,31 @@ if ( !defined('WPINC') ) die;
149
  <tr>
150
  <th><?php echo __('Sitemap Generation', 'litespeed-cache'); ?></th>
151
  <td>
152
- <div class="litespeed-cdn-mapping-block">
153
  <div class='litespeed-cdn-mapping-col2'>
154
  <div class="litespeed-row">
155
- <div class="litespeed-child-col-inc"><?php echo __( 'Include Posts', 'litespeed-cache' ) ; ?></div>
156
  <?php
157
  $this->build_toggle( LiteSpeed_Cache_Config::CRWL_POSTS ) ;
158
  ?>
159
  </div>
160
 
161
  <div class="litespeed-row">
162
- <div class="litespeed-child-col-inc"><?php echo __( 'Include Pages', 'litespeed-cache' ) ; ?></div>
163
  <?php
164
  $this->build_toggle( LiteSpeed_Cache_Config::CRWL_PAGES ) ;
165
  ?>
166
  </div>
167
 
168
  <div class="litespeed-row">
169
- <div class="litespeed-child-col-inc"><?php echo __( 'Include Categories', 'litespeed-cache' ) ; ?></div>
170
  <?php
171
  $this->build_toggle( LiteSpeed_Cache_Config::CRWL_CATS ) ;
172
  ?>
173
  </div>
174
 
175
  <div class="litespeed-row">
176
- <div class="litespeed-child-col-inc"><?php echo __( 'Include Tags', 'litespeed-cache' ) ; ?></div>
177
  <?php
178
  $this->build_toggle( LiteSpeed_Cache_Config::CRWL_TAGS ) ;
179
  ?>
@@ -181,7 +197,7 @@ if ( !defined('WPINC') ) die;
181
 
182
  </div>
183
 
184
- <div class='litespeed-child-col-auto'>
185
  <h4><?php echo __('Exclude Custom Post Types', 'litespeed-cache'); ?></h4>
186
 
187
  <?php $this->build_textarea( LiteSpeed_Cache_Config::CRWL_EXCLUDES_CPT, 40 ) ; ?>
@@ -191,7 +207,7 @@ if ( !defined('WPINC') ) die;
191
  </div>
192
  </div>
193
 
194
- <div class='litespeed-child-col-auto'>
195
  <div class="litespeed-callout-warning">
196
  <h4><?php echo __('Available Custom Post Type','litespeed-cache'); ?></h4>
197
  <p>
@@ -200,7 +216,7 @@ if ( !defined('WPINC') ) die;
200
  </div>
201
  </div>
202
 
203
- <div class='litespeed-child-col-auto'>
204
  <h4><?php echo __('Order links by', 'litespeed-cache'); ?></h4>
205
 
206
  <div class="litespeed-switch">
135
  </td>
136
  </tr>
137
 
138
+ <tr>
139
+ <th><?php echo __( 'HTTP/2 Crawl', 'litespeed-cache' ) ; ?></th>
140
+ <td>
141
+ <?php $this->build_switch( LiteSpeed_Cache_Config::CRWL_HTTP2 ) ; ?>
142
+ <div class="litespeed-desc">
143
+ <?php echo __( 'Crawl using the HTTP/2 protocal.', 'litespeed-cache' ) ; ?>
144
+ <?php echo __( 'Current curl HTTP/2 extension status', 'litespeed-cache' ) ; ?>:
145
+ <?php if ( defined( 'CURL_HTTP_VERSION_2' ) ) : ?>
146
+ <font class="litespeed-warning"><?php echo __( 'Enabled', 'litespeed-cache' ) ; ?></font>
147
+ <?php else : ?>
148
+ <font class="litespeed-warning"><?php echo __( 'Disabled', 'litespeed-cache' ) ; ?></font>
149
+ <?php endif ; ?>
150
+ </div>
151
+ </td>
152
+ </tr>
153
+
154
  <tr>
155
  <th><?php echo __('Custom Sitemap', 'litespeed-cache'); ?></th>
156
  <td>
165
  <tr>
166
  <th><?php echo __('Sitemap Generation', 'litespeed-cache'); ?></th>
167
  <td>
168
+ <div class="litespeed-block">
169
  <div class='litespeed-cdn-mapping-col2'>
170
  <div class="litespeed-row">
171
+ <div class="litespeed-col-inc"><?php echo __( 'Include Posts', 'litespeed-cache' ) ; ?></div>
172
  <?php
173
  $this->build_toggle( LiteSpeed_Cache_Config::CRWL_POSTS ) ;
174
  ?>
175
  </div>
176
 
177
  <div class="litespeed-row">
178
+ <div class="litespeed-col-inc"><?php echo __( 'Include Pages', 'litespeed-cache' ) ; ?></div>
179
  <?php
180
  $this->build_toggle( LiteSpeed_Cache_Config::CRWL_PAGES ) ;
181
  ?>
182
  </div>
183
 
184
  <div class="litespeed-row">
185
+ <div class="litespeed-col-inc"><?php echo __( 'Include Categories', 'litespeed-cache' ) ; ?></div>
186
  <?php
187
  $this->build_toggle( LiteSpeed_Cache_Config::CRWL_CATS ) ;
188
  ?>
189
  </div>
190
 
191
  <div class="litespeed-row">
192
+ <div class="litespeed-col-inc"><?php echo __( 'Include Tags', 'litespeed-cache' ) ; ?></div>
193
  <?php
194
  $this->build_toggle( LiteSpeed_Cache_Config::CRWL_TAGS ) ;
195
  ?>
197
 
198
  </div>
199
 
200
+ <div class='litespeed-col-auto'>
201
  <h4><?php echo __('Exclude Custom Post Types', 'litespeed-cache'); ?></h4>
202
 
203
  <?php $this->build_textarea( LiteSpeed_Cache_Config::CRWL_EXCLUDES_CPT, 40 ) ; ?>
207
  </div>
208
  </div>
209
 
210
+ <div class='litespeed-col-auto'>
211
  <div class="litespeed-callout-warning">
212
  <h4><?php echo __('Available Custom Post Type','litespeed-cache'); ?></h4>
213
  <p>
216
  </div>
217
  </div>
218
 
219
+ <div class='litespeed-col-auto'>
220
  <h4><?php echo __('Order links by', 'litespeed-cache'); ?></h4>
221
 
222
  <div class="litespeed-switch">
admin/tpl/setting/settings_esi.php CHANGED
@@ -66,9 +66,9 @@ if ( ! defined( 'WPINC' ) ) die ;
66
  <th><?php echo __('Vary Group', 'litespeed-cache'); ?></th>
67
  <td>
68
  <table class="litespeed-vary-table"><tbody>
69
- <?php foreach ( $roles as $role ): ?>
70
  <tr>
71
- <td class='litespeed-vary-title'><?php echo $role ; ?></td>
72
  <td class='litespeed-vary-val'>
73
  <input type="text" class="litespeed-input-short"
74
  name="<?php echo LiteSpeed_Cache_Config::VARY_GROUP ; ?>[<?php echo $role ; ?>]"
66
  <th><?php echo __('Vary Group', 'litespeed-cache'); ?></th>
67
  <td>
68
  <table class="litespeed-vary-table"><tbody>
69
+ <?php foreach ( $roles as $role => $title ): ?>
70
  <tr>
71
+ <td class='litespeed-vary-title'><?php echo $title ; ?></td>
72
  <td class='litespeed-vary-val'>
73
  <input type="text" class="litespeed-input-short"
74
  name="<?php echo LiteSpeed_Cache_Config::VARY_GROUP ; ?>[<?php echo $role ; ?>]"
admin/tpl/setting/settings_excludes.php CHANGED
@@ -60,7 +60,7 @@ if ( ! defined( 'WPINC' ) ) die ;
60
  </i>
61
  </div>
62
  <div class="litespeed-callout-warning">
63
- <h4><?php echo __('NOTE:', 'litespeed-cache'); ?></h4>
64
  <ol>
65
  <li><?php echo __('If the category slug is not found, the category will be removed from the list on save.', 'litespeed-cache'); ?></li>
66
  <li><?php echo sprintf(__('To exclude %1$s, insert %2$s.', 'litespeed-cache'),
@@ -98,7 +98,7 @@ if ( ! defined( 'WPINC' ) ) die ;
98
  </i>
99
  </div>
100
  <div class="litespeed-callout-warning">
101
- <h4><?php echo __('NOTE:', 'litespeed-cache'); ?></h4>
102
  <ol>
103
  <li><?php echo __('If the tag slug is not found, the tag will be removed from the list on save.', 'litespeed-cache'); ?></li>
104
  <li><?php echo sprintf(__('To exclude %1$s, insert %2$s.', 'litespeed-cache'),
@@ -123,8 +123,8 @@ if ( ! defined( 'WPINC' ) ) die ;
123
  <tr>
124
  <th><?php echo __('Do Not Cache Roles', 'litespeed-cache'); ?></th>
125
  <td>
126
- <?php foreach ( $roles as $role ): ?>
127
- <?php $this->build_checkbox( LiteSpeed_Cache_Config::EXCLUDE_CACHE_ROLES . "][", $role, $this->config->in_exclude_cache_roles( $role ), $role ) ; ?>
128
  <?php endforeach; ?>
129
  <div class="litespeed-desc">
130
  <?php echo __( 'Selected roles will be excluded from cache.', 'litespeed-cache' ) ; ?>
60
  </i>
61
  </div>
62
  <div class="litespeed-callout-warning">
63
+ <h4><?php echo __('NOTE', 'litespeed-cache'); ?>:</h4>
64
  <ol>
65
  <li><?php echo __('If the category slug is not found, the category will be removed from the list on save.', 'litespeed-cache'); ?></li>
66
  <li><?php echo sprintf(__('To exclude %1$s, insert %2$s.', 'litespeed-cache'),
98
  </i>
99
  </div>
100
  <div class="litespeed-callout-warning">
101
+ <h4><?php echo __('NOTE', 'litespeed-cache'); ?>:</h4>
102
  <ol>
103
  <li><?php echo __('If the tag slug is not found, the tag will be removed from the list on save.', 'litespeed-cache'); ?></li>
104
  <li><?php echo sprintf(__('To exclude %1$s, insert %2$s.', 'litespeed-cache'),
123
  <tr>
124
  <th><?php echo __('Do Not Cache Roles', 'litespeed-cache'); ?></th>
125
  <td>
126
+ <?php foreach ( $roles as $role => $title ): ?>
127
+ <?php $this->build_checkbox( LiteSpeed_Cache_Config::EXCLUDE_CACHE_ROLES . "][", $title, $this->config->in_exclude_cache_roles( $role ), $role ) ; ?>
128
  <?php endforeach; ?>
129
  <div class="litespeed-desc">
130
  <?php echo __( 'Selected roles will be excluded from cache.', 'litespeed-cache' ) ; ?>
admin/tpl/setting/settings_inc.cache_browser.php CHANGED
@@ -9,7 +9,7 @@ if ( ! defined( 'WPINC' ) ) die ;
9
  <div class="litespeed-desc">
10
  <?php echo __( 'Browser caching stores static files locally in the user\'s browser. Turn on this setting to reduce repeated requests for static files.', 'litespeed-cache' ) ; ?>
11
  <br /><font class="litespeed-warning">
12
- <?php echo __('NOTE:', 'litespeed-cache'); ?>
13
  <?php echo __('This setting will edit the .htaccess file.', 'litespeed-cache'); ?>
14
  </font>
15
  <br /><?php echo sprintf( __( 'You can turn on browser caching in server admin too. <a %s>Learn more about LiteSpeed browser cache setting</a>.', 'litespeed-cache' ), 'href="https://www.litespeedtech.com/support/wiki/doku.php/litespeed_wiki:cache:lscwp:browser_cache" target="_blank"' ) ; ?>
9
  <div class="litespeed-desc">
10
  <?php echo __( 'Browser caching stores static files locally in the user\'s browser. Turn on this setting to reduce repeated requests for static files.', 'litespeed-cache' ) ; ?>
11
  <br /><font class="litespeed-warning">
12
+ <?php echo __('NOTE', 'litespeed-cache'); ?>:
13
  <?php echo __('This setting will edit the .htaccess file.', 'litespeed-cache'); ?>
14
  </font>
15
  <br /><?php echo sprintf( __( 'You can turn on browser caching in server admin too. <a %s>Learn more about LiteSpeed browser cache setting</a>.', 'litespeed-cache' ), 'href="https://www.litespeedtech.com/support/wiki/doku.php/litespeed_wiki:cache:lscwp:browser_cache" target="_blank"' ) ; ?>
admin/tpl/setting/settings_inc.cache_favicon.php CHANGED
@@ -10,7 +10,7 @@ if (!defined('WPINC')) die;
10
  <?php echo __('favicon.ico is requested on most pages.', 'litespeed-cache'); ?>
11
  <?php echo __('Caching this resource may improve server performance by avoiding unnecessary PHP calls.', 'litespeed-cache'); ?>
12
  <br /><font class="litespeed-warning">
13
- <?php echo __('NOTE:', 'litespeed-cache'); ?>
14
  <?php echo __('This setting will edit the .htaccess file.', 'litespeed-cache'); ?>
15
  </font>
16
  </div>
10
  <?php echo __('favicon.ico is requested on most pages.', 'litespeed-cache'); ?>
11
  <?php echo __('Caching this resource may improve server performance by avoiding unnecessary PHP calls.', 'litespeed-cache'); ?>
12
  <br /><font class="litespeed-warning">
13
+ <?php echo __('NOTE', 'litespeed-cache'); ?>:
14
  <?php echo __('This setting will edit the .htaccess file.', 'litespeed-cache'); ?>
15
  </font>
16
  </div>
admin/tpl/setting/settings_inc.cache_mobile.php CHANGED
@@ -14,7 +14,7 @@ if (!defined('WPINC')) die;
14
  <?php echo __('When enabled, mobile views will be cached separately.', 'litespeed-cache'); ?>
15
  <?php echo __('A site built with responsive design does not need to check this.', 'litespeed-cache'); ?>
16
  <br /><font class="litespeed-warning">
17
- <?php echo __( 'NOTE:', 'litespeed-cache' ) ; ?>
18
  <?php echo __( 'This setting will edit the .htaccess file.', 'litespeed-cache' ) ; ?>
19
  </font>
20
  </div>
@@ -63,7 +63,7 @@ if (!defined('WPINC')) die;
63
  <br />
64
  <?php echo sprintf( __( 'The default list WordPress uses is %s', 'litespeed-cache' ), "<code>$wp_default_mobile</code>" ) ; ?>
65
  <br /><font class="litespeed-warning">
66
- <?php echo __( 'NOTE:', 'litespeed-cache' ) ; ?>
67
  <?php echo sprintf( __( 'If %1$s is %2$s, then %3$s must be populated!', 'litespeed-cache' ), '<code>' . __('Cache Mobile', 'litespeed-cache') . '</code>', '<code>' . __('ON', 'litespeed-cache') . '</code>', '<code>' . __('List of Mobile User Agents', 'litespeed-cache') . '</code>' ) ; ?>
68
  </font>
69
  </div>
14
  <?php echo __('When enabled, mobile views will be cached separately.', 'litespeed-cache'); ?>
15
  <?php echo __('A site built with responsive design does not need to check this.', 'litespeed-cache'); ?>
16
  <br /><font class="litespeed-warning">
17
+ <?php echo __( 'NOTE', 'litespeed-cache' ) ; ?>:
18
  <?php echo __( 'This setting will edit the .htaccess file.', 'litespeed-cache' ) ; ?>
19
  </font>
20
  </div>
63
  <br />
64
  <?php echo sprintf( __( 'The default list WordPress uses is %s', 'litespeed-cache' ), "<code>$wp_default_mobile</code>" ) ; ?>
65
  <br /><font class="litespeed-warning">
66
+ <?php echo __( 'NOTE', 'litespeed-cache' ) ; ?>:
67
  <?php echo sprintf( __( 'If %1$s is %2$s, then %3$s must be populated!', 'litespeed-cache' ), '<code>' . __('Cache Mobile', 'litespeed-cache') . '</code>', '<code>' . __('ON', 'litespeed-cache') . '</code>', '<code>' . __('List of Mobile User Agents', 'litespeed-cache') . '</code>' ) ; ?>
68
  </font>
69
  </div>
admin/tpl/setting/settings_inc.cache_object.php CHANGED
@@ -32,8 +32,8 @@ $hide_redis_options = LiteSpeed_Cache::config( LiteSpeed_Cache_Config::OPID_CACH
32
  <?php echo __( 'Use object cache functionality.', 'litespeed-cache' ) ; ?>
33
  <a href="https://www.litespeedtech.com/support/wiki/doku.php/litespeed_wiki:cache:lscwp:configuration:cache:object_cache" target="_blank"><?php echo __('Learn More', 'litespeed-cache') ; ?></a>
34
  </div>
35
- <div class="litespeed-cdn-mapping-block">
36
- <div class='litespeed-child-col-auto'>
37
  <h4><?php echo __( 'Method', 'litespeed-cache' ) ; ?></h4>
38
 
39
  <div class="litespeed-switch">
@@ -42,7 +42,7 @@ $hide_redis_options = LiteSpeed_Cache::config( LiteSpeed_Cache_Config::OPID_CACH
42
  </div>
43
  </div>
44
 
45
- <div class='litespeed-child-col-auto'>
46
  <h4><?php echo __( 'Host', 'litespeed-cache' ) ; ?></h4>
47
 
48
  <?php $this->build_input( LiteSpeed_Cache_Config::OPID_CACHE_OBJECT_HOST ) ; ?>
@@ -51,13 +51,13 @@ $hide_redis_options = LiteSpeed_Cache::config( LiteSpeed_Cache_Config::OPID_CACH
51
  </div>
52
  </div>
53
 
54
- <div class='litespeed-child-col-auto'>
55
  <h4><?php echo __( 'Port', 'litespeed-cache' ) ; ?></h4>
56
 
57
  <?php $this->build_input( LiteSpeed_Cache_Config::OPID_CACHE_OBJECT_PORT, 'litespeed-input-short2' ) ; ?>
58
  </div>
59
 
60
- <div class='litespeed-child-col-auto'>
61
  <h4><?php echo __( 'Default Object Lifetime', 'litespeed-cache' ) ; ?></h4>
62
 
63
  <?php $this->build_input( LiteSpeed_Cache_Config::OPID_CACHE_OBJECT_LIFE, 'litespeed-input-short2' ) ; ?> <?php echo __( 'seconds', 'litespeed-cache' ) ; ?>
@@ -66,7 +66,7 @@ $hide_redis_options = LiteSpeed_Cache::config( LiteSpeed_Cache_Config::OPID_CACH
66
  </div>
67
  </div>
68
 
69
- <div class='litespeed-child-col-auto'>
70
  <h4><?php echo __( 'Status', 'litespeed-cache' ) ; ?></h4>
71
 
72
  <?php echo sprintf( __( '%s Extension', 'litespeed-cache' ), 'Memcached' ) ; ?>: <?php echo $mem_enabled ; ?><br />
@@ -75,9 +75,9 @@ $hide_redis_options = LiteSpeed_Cache::config( LiteSpeed_Cache_Config::OPID_CACH
75
  <a href="https://www.litespeedtech.com/support/wiki/doku.php/litespeed_wiki:cache:lscwp:configuration:cache:object_cache#how_to_debug" target="_blank"><?php echo __('Learn More', 'litespeed-cache') ; ?></a>
76
  </div>
77
 
78
- <div class='litespeed-child-col-br'></div>
79
 
80
- <div class='litespeed-child-col-auto <?php echo $hide_mem_options ; ?>' data="litespeed-mem-divs">
81
  <h4><?php echo __( 'Username', 'litespeed-cache' ) ; ?></h4>
82
 
83
  <?php $this->build_input( LiteSpeed_Cache_Config::OPID_CACHE_OBJECT_USER ) ; ?>
@@ -86,7 +86,7 @@ $hide_redis_options = LiteSpeed_Cache::config( LiteSpeed_Cache_Config::OPID_CACH
86
  </div>
87
  </div>
88
 
89
- <div class='litespeed-child-col-auto'>
90
  <h4><?php echo __( 'Password', 'litespeed-cache' ) ; ?></h4>
91
 
92
  <?php $this->build_input( LiteSpeed_Cache_Config::OPID_CACHE_OBJECT_PSWD ) ; ?>
@@ -95,7 +95,7 @@ $hide_redis_options = LiteSpeed_Cache::config( LiteSpeed_Cache_Config::OPID_CACH
95
  </div>
96
  </div>
97
 
98
- <div class='litespeed-child-col-auto <?php echo $hide_redis_options ; ?>' data="litespeed-redis-divs">
99
  <h4><?php echo __( 'Redis Database ID', 'litespeed-cache' ) ; ?></h4>
100
 
101
  <?php $this->build_input( LiteSpeed_Cache_Config::OPID_CACHE_OBJECT_DB_ID, 'litespeed-input-short' ) ; ?>
@@ -104,9 +104,9 @@ $hide_redis_options = LiteSpeed_Cache::config( LiteSpeed_Cache_Config::OPID_CACH
104
  </div>
105
  </div>
106
 
107
- <div class='litespeed-child-col-br'></div>
108
 
109
- <div class='litespeed-child-col-auto'>
110
  <h4><?php echo __( 'Global Groups', 'litespeed-cache' ) ; ?></h4>
111
  <?php $this->build_textarea2( LiteSpeed_Cache_Config::ITEM_OBJECT_GLOBAL_GROUPS, 30 ) ; ?>
112
  <div class="litespeed-desc">
@@ -115,7 +115,7 @@ $hide_redis_options = LiteSpeed_Cache::config( LiteSpeed_Cache_Config::OPID_CACH
115
  </div>
116
  </div>
117
 
118
- <div class='litespeed-child-col-auto'>
119
  <h4><?php echo __( 'Do Not Cache Groups', 'litespeed-cache' ) ; ?></h4>
120
  <?php $this->build_textarea2( LiteSpeed_Cache_Config::ITEM_OBJECT_NON_PERSISTENT_GROUPS, 30 ) ; ?>
121
  <div class="litespeed-desc">
@@ -123,16 +123,16 @@ $hide_redis_options = LiteSpeed_Cache::config( LiteSpeed_Cache_Config::OPID_CACH
123
  </div>
124
  </div>
125
 
126
- <div class='litespeed-child-col-auto'>
127
  <div class="litespeed-row">
128
- <div class="litespeed-child-col-inc"><?php echo __( 'Persistent Connection', 'litespeed-cache' ) ; ?></div>
129
  <?php $this->build_toggle( LiteSpeed_Cache_Config::OPID_CACHE_OBJECT_PERSISTENT ) ; ?>
130
  </div>
131
  <div class="litespeed-desc">
132
  <?php echo __( 'Use keep-alive connections to speed up cache operations.', 'litespeed-cache' ) ; ?>
133
  </div>
134
  <div class="litespeed-row litespeed-top30">
135
- <div class="litespeed-child-col-inc"><?php echo __( 'Cache Wp-Admin', 'litespeed-cache' ) ; ?></div>
136
  <?php $this->build_toggle( LiteSpeed_Cache_Config::OPID_CACHE_OBJECT_ADMIN ) ; ?>
137
  </div>
138
  <div class="litespeed-desc">
@@ -140,9 +140,9 @@ $hide_redis_options = LiteSpeed_Cache::config( LiteSpeed_Cache_Config::OPID_CACH
140
  </div>
141
  </div>
142
 
143
- <div class='litespeed-child-col-auto'>
144
  <div class="litespeed-row">
145
- <div class="litespeed-child-col-inc"><?php echo __( 'Store Transients', 'litespeed-cache' ) ; ?></div>
146
  <?php $this->build_toggle( LiteSpeed_Cache_Config::OPID_CACHE_OBJECT_TRANSIENTS ) ; ?>
147
  </div>
148
  <div class="litespeed-desc">
32
  <?php echo __( 'Use object cache functionality.', 'litespeed-cache' ) ; ?>
33
  <a href="https://www.litespeedtech.com/support/wiki/doku.php/litespeed_wiki:cache:lscwp:configuration:cache:object_cache" target="_blank"><?php echo __('Learn More', 'litespeed-cache') ; ?></a>
34
  </div>
35
+ <div class="litespeed-block">
36
+ <div class='litespeed-col-auto'>
37
  <h4><?php echo __( 'Method', 'litespeed-cache' ) ; ?></h4>
38
 
39
  <div class="litespeed-switch">
42
  </div>
43
  </div>
44
 
45
+ <div class='litespeed-col-auto'>
46
  <h4><?php echo __( 'Host', 'litespeed-cache' ) ; ?></h4>
47
 
48
  <?php $this->build_input( LiteSpeed_Cache_Config::OPID_CACHE_OBJECT_HOST ) ; ?>
51
  </div>
52
  </div>
53
 
54
+ <div class='litespeed-col-auto'>
55
  <h4><?php echo __( 'Port', 'litespeed-cache' ) ; ?></h4>
56
 
57
  <?php $this->build_input( LiteSpeed_Cache_Config::OPID_CACHE_OBJECT_PORT, 'litespeed-input-short2' ) ; ?>
58
  </div>
59
 
60
+ <div class='litespeed-col-auto'>
61
  <h4><?php echo __( 'Default Object Lifetime', 'litespeed-cache' ) ; ?></h4>
62
 
63
  <?php $this->build_input( LiteSpeed_Cache_Config::OPID_CACHE_OBJECT_LIFE, 'litespeed-input-short2' ) ; ?> <?php echo __( 'seconds', 'litespeed-cache' ) ; ?>
66
  </div>
67
  </div>
68
 
69
+ <div class='litespeed-col-auto'>
70
  <h4><?php echo __( 'Status', 'litespeed-cache' ) ; ?></h4>
71
 
72
  <?php echo sprintf( __( '%s Extension', 'litespeed-cache' ), 'Memcached' ) ; ?>: <?php echo $mem_enabled ; ?><br />
75
  <a href="https://www.litespeedtech.com/support/wiki/doku.php/litespeed_wiki:cache:lscwp:configuration:cache:object_cache#how_to_debug" target="_blank"><?php echo __('Learn More', 'litespeed-cache') ; ?></a>
76
  </div>
77
 
78
+ <div class='litespeed-col-br'></div>
79
 
80
+ <div class='litespeed-col-auto <?php echo $hide_mem_options ; ?>' data="litespeed-mem-divs">
81
  <h4><?php echo __( 'Username', 'litespeed-cache' ) ; ?></h4>
82
 
83
  <?php $this->build_input( LiteSpeed_Cache_Config::OPID_CACHE_OBJECT_USER ) ; ?>
86
  </div>
87
  </div>
88
 
89
+ <div class='litespeed-col-auto'>
90
  <h4><?php echo __( 'Password', 'litespeed-cache' ) ; ?></h4>
91
 
92
  <?php $this->build_input( LiteSpeed_Cache_Config::OPID_CACHE_OBJECT_PSWD ) ; ?>
95
  </div>
96
  </div>
97
 
98
+ <div class='litespeed-col-auto <?php echo $hide_redis_options ; ?>' data="litespeed-redis-divs">
99
  <h4><?php echo __( 'Redis Database ID', 'litespeed-cache' ) ; ?></h4>
100
 
101
  <?php $this->build_input( LiteSpeed_Cache_Config::OPID_CACHE_OBJECT_DB_ID, 'litespeed-input-short' ) ; ?>
104
  </div>
105
  </div>
106
 
107
+ <div class='litespeed-col-br'></div>
108
 
109
+ <div class='litespeed-col-auto'>
110
  <h4><?php echo __( 'Global Groups', 'litespeed-cache' ) ; ?></h4>
111
  <?php $this->build_textarea2( LiteSpeed_Cache_Config::ITEM_OBJECT_GLOBAL_GROUPS, 30 ) ; ?>
112
  <div class="litespeed-desc">
115
  </div>
116
  </div>
117
 
118
+ <div class='litespeed-col-auto'>
119
  <h4><?php echo __( 'Do Not Cache Groups', 'litespeed-cache' ) ; ?></h4>
120
  <?php $this->build_textarea2( LiteSpeed_Cache_Config::ITEM_OBJECT_NON_PERSISTENT_GROUPS, 30 ) ; ?>
121
  <div class="litespeed-desc">
123
  </div>
124
  </div>
125
 
126
+ <div class='litespeed-col-auto'>
127
  <div class="litespeed-row">
128
+ <div class="litespeed-col-inc"><?php echo __( 'Persistent Connection', 'litespeed-cache' ) ; ?></div>
129
  <?php $this->build_toggle( LiteSpeed_Cache_Config::OPID_CACHE_OBJECT_PERSISTENT ) ; ?>
130
  </div>
131
  <div class="litespeed-desc">
132
  <?php echo __( 'Use keep-alive connections to speed up cache operations.', 'litespeed-cache' ) ; ?>
133
  </div>
134
  <div class="litespeed-row litespeed-top30">
135
+ <div class="litespeed-col-inc"><?php echo __( 'Cache Wp-Admin', 'litespeed-cache' ) ; ?></div>
136
  <?php $this->build_toggle( LiteSpeed_Cache_Config::OPID_CACHE_OBJECT_ADMIN ) ; ?>
137
  </div>
138
  <div class="litespeed-desc">
140
  </div>
141
  </div>
142
 
143
+ <div class='litespeed-col-auto'>
144
  <div class="litespeed-row">
145
+ <div class="litespeed-col-inc"><?php echo __( 'Store Transients', 'litespeed-cache' ) ; ?></div>
146
  <?php $this->build_toggle( LiteSpeed_Cache_Config::OPID_CACHE_OBJECT_TRANSIENTS ) ; ?>
147
  </div>
148
  <div class="litespeed-desc">
admin/tpl/setting/settings_inc.cache_resources.php CHANGED
@@ -11,7 +11,7 @@ if (!defined('WPINC')) die;
11
  <?php echo __('Some themes and plugins add resources via a PHP request.', 'litespeed-cache'); ?>
12
  <?php echo __('Caching these pages may improve server performance by avoiding unnecessary PHP calls.', 'litespeed-cache'); ?>
13
  <br /><font class="litespeed-warning">
14
- <?php echo __('NOTE:', 'litespeed-cache'); ?>
15
  <?php echo __('This setting will edit the .htaccess file.', 'litespeed-cache'); ?>
16
  </font>
17
  </div>
11
  <?php echo __('Some themes and plugins add resources via a PHP request.', 'litespeed-cache'); ?>
12
  <?php echo __('Caching these pages may improve server performance by avoiding unnecessary PHP calls.', 'litespeed-cache'); ?>
13
  <br /><font class="litespeed-warning">
14
+ <?php echo __('NOTE', 'litespeed-cache'); ?>:
15
  <?php echo __('This setting will edit the .htaccess file.', 'litespeed-cache'); ?>
16
  </font>
17
  </div>
admin/tpl/setting/settings_inc.exclude_cookies.php CHANGED
@@ -19,7 +19,7 @@ if ( ! defined( 'WPINC' ) ) die ;
19
  <?php echo __('One per line.', 'litespeed-cache'); ?>
20
  </i>
21
  <br /><font class="litespeed-warning">
22
- <?php echo __('NOTE:', 'litespeed-cache'); ?>
23
  <?php echo __('This setting will edit the .htaccess file.', 'litespeed-cache'); ?>
24
  </font>
25
  </div>
19
  <?php echo __('One per line.', 'litespeed-cache'); ?>
20
  </i>
21
  <br /><font class="litespeed-warning">
22
+ <?php echo __('NOTE', 'litespeed-cache'); ?>:
23
  <?php echo __('This setting will edit the .htaccess file.', 'litespeed-cache'); ?>
24
  </font>
25
  </div>
admin/tpl/setting/settings_inc.exclude_useragent.php CHANGED
@@ -18,7 +18,7 @@ if (!defined('WPINC')) die;
18
  <?php echo sprintf( __( 'Spaces should have a backslash in front of them, %s.', 'litespeed-cache' ), '<code>\</code>' ) ; ?>
19
  </i>
20
  <br /><font class="litespeed-warning">
21
- <?php echo __('NOTE:', 'litespeed-cache'); ?>
22
  <?php echo __('This setting will edit the .htaccess file.', 'litespeed-cache'); ?>
23
  </font>
24
  </div>
18
  <?php echo sprintf( __( 'Spaces should have a backslash in front of them, %s.', 'litespeed-cache' ), '<code>\</code>' ) ; ?>
19
  </i>
20
  <br /><font class="litespeed-warning">
21
+ <?php echo __('NOTE', 'litespeed-cache'); ?>:
22
  <?php echo __('This setting will edit the .htaccess file.', 'litespeed-cache'); ?>
23
  </font>
24
  </div>
admin/tpl/setting/settings_inc.media_webp.php CHANGED
@@ -9,7 +9,7 @@ if ( ! defined( 'WPINC' ) ) die ;
9
  <div class="litespeed-desc">
10
  <?php echo sprintf( __( 'Significantly improve load time by replacing images with their optimized %s versions.', 'litespeed-cache' ), '.webp' ) ; ?>
11
  <br /><font class="litespeed-warning">
12
- <?php echo __('NOTE:', 'litespeed-cache'); ?>
13
  <?php echo __('This setting will edit the .htaccess file.', 'litespeed-cache'); ?>
14
  </font>
15
  </div>
9
  <div class="litespeed-desc">
10
  <?php echo sprintf( __( 'Significantly improve load time by replacing images with their optimized %s versions.', 'litespeed-cache' ), '.webp' ) ; ?>
11
  <br /><font class="litespeed-warning">
12
+ <?php echo __('NOTE', 'litespeed-cache'); ?>:
13
  <?php echo __('This setting will edit the .htaccess file.', 'litespeed-cache'); ?>
14
  </font>
15
  </div>
admin/tpl/setting/settings_media.php CHANGED
@@ -33,7 +33,7 @@ if ( ! defined( 'WPINC' ) ) die ;
33
  <?php echo __( 'Both full URLs and partial strings can be used.', 'litespeed-cache' ) ; ?>
34
  <?php echo __('One per line.', 'litespeed-cache'); ?>
35
  <br /><font class="litespeed-success">
36
- <?php echo __('API:', 'litespeed-cache'); ?>
37
  <?php echo sprintf( __( 'Filter %s is supported.', 'litespeed-cache' ), '<code>litespeed_cache_media_lazy_img_excludes</code>' ) ; ?>
38
  <?php echo sprintf( __( 'Elements with attribute %s in html code will be excluded.', 'litespeed-cache' ), '<code>data-no-lazy="1"</code>' ) ; ?>
39
  </font>
33
  <?php echo __( 'Both full URLs and partial strings can be used.', 'litespeed-cache' ) ; ?>
34
  <?php echo __('One per line.', 'litespeed-cache'); ?>
35
  <br /><font class="litespeed-success">
36
+ <?php echo __('API', 'litespeed-cache'); ?>:
37
  <?php echo sprintf( __( 'Filter %s is supported.', 'litespeed-cache' ), '<code>litespeed_cache_media_lazy_img_excludes</code>' ) ; ?>
38
  <?php echo sprintf( __( 'Elements with attribute %s in html code will be excluded.', 'litespeed-cache' ), '<code>data-no-lazy="1"</code>' ) ; ?>
39
  </font>
admin/tpl/setting/settings_optimize.php CHANGED
@@ -134,7 +134,7 @@ if ( ! defined( 'WPINC' ) ) die ;
134
  <?php echo __( 'Optimize CSS delivery. This will load Google Fonts asynchronously too.', 'litespeed-cache' ) ; ?>
135
  <?php echo __( 'This can improve your speed score in services like Pingdom, GTmetrix and PageSpeed.', 'litespeed-cache' ) ; ?>
136
  <br /><font class="litespeed-success">
137
- <?php echo __('API:', 'litespeed-cache'); ?>
138
  <?php echo sprintf( __( 'Elements with attribute %s in html code will be excluded.', 'litespeed-cache' ), '<code>data-no-async="1"</code>' ) ; ?>
139
  </font>
140
  </div>
@@ -159,7 +159,7 @@ if ( ! defined( 'WPINC' ) ) die ;
159
  <div class="litespeed-desc">
160
  <?php echo sprintf( __( 'Improve compatibility with inline JS by preventing jQuery optimization. (Recommended Setting: %s)', 'litespeed-cache' ), __( 'ON', 'litespeed-cache' ) ) ; ?>
161
  <br /><font class="litespeed-warning">
162
- <?php echo __('NOTE:', 'litespeed-cache'); ?>
163
  <?php echo sprintf( __( 'If there is any JS error related to %1$s when enabled %2$s, please try this option.', 'litespeed-cache' ), 'jQuery', __( 'JS Combine', 'litespeed-cache' ) ) ; ?>
164
  </font>
165
  </div>
134
  <?php echo __( 'Optimize CSS delivery. This will load Google Fonts asynchronously too.', 'litespeed-cache' ) ; ?>
135
  <?php echo __( 'This can improve your speed score in services like Pingdom, GTmetrix and PageSpeed.', 'litespeed-cache' ) ; ?>
136
  <br /><font class="litespeed-success">
137
+ <?php echo __('API', 'litespeed-cache'); ?>:
138
  <?php echo sprintf( __( 'Elements with attribute %s in html code will be excluded.', 'litespeed-cache' ), '<code>data-no-async="1"</code>' ) ; ?>
139
  </font>
140
  </div>
159
  <div class="litespeed-desc">
160
  <?php echo sprintf( __( 'Improve compatibility with inline JS by preventing jQuery optimization. (Recommended Setting: %s)', 'litespeed-cache' ), __( 'ON', 'litespeed-cache' ) ) ; ?>
161
  <br /><font class="litespeed-warning">
162
+ <?php echo __('NOTE', 'litespeed-cache'); ?>:
163
  <?php echo sprintf( __( 'If there is any JS error related to %1$s when enabled %2$s, please try this option.', 'litespeed-cache' ), 'jQuery', __( 'JS Combine', 'litespeed-cache' ) ) ; ?>
164
  </font>
165
  </div>
admin/tpl/setting/settings_purge.php CHANGED
@@ -48,7 +48,7 @@ $breakArr = array(
48
  <th><?php echo __('Auto Purge Rules For Publish/Update', 'litespeed-cache'); ?></th>
49
  <td>
50
  <div class="litespeed-callout-warning">
51
- <h4><?php echo __('Note:', 'litespeed-cache'); ?></h4>
52
  <i>
53
  <?php echo __('Select "All" if there are dynamic widgets linked to posts on pages other than the front or home pages.', 'litespeed-cache'); ?><br />
54
  <?php echo __('Other checkboxes will be ignored.', 'litespeed-cache'); ?><br />
48
  <th><?php echo __('Auto Purge Rules For Publish/Update', 'litespeed-cache'); ?></th>
49
  <td>
50
  <div class="litespeed-callout-warning">
51
+ <h4><?php echo __('Note', 'litespeed-cache'); ?></h4>:
52
  <i>
53
  <?php echo __('Select "All" if there are dynamic widgets linked to posts on pages other than the front or home pages.', 'litespeed-cache'); ?><br />
54
  <?php echo __('Other checkboxes will be ignored.', 'litespeed-cache'); ?><br />
admin/tpl/setting/settings_tuning.php CHANGED
@@ -17,11 +17,11 @@ if ( ! defined( 'WPINC' ) ) die ;
17
  <?php echo __( 'Load combined CSS files before other CSS files.', 'litespeed-cache' ) ; ?>
18
  <?php echo sprintf( __( 'Set to %s by default.', 'litespeed-cache' ), __( 'OFF', 'litespeed-cache' ) ) ; ?>
19
  <br /><font class="litespeed-warning">
20
- <?php echo __('NOTE:', 'litespeed-cache'); ?>
21
  <?php echo sprintf( __( 'Only set to %s when changing the order of combined and uncombined CSS is needed.', 'litespeed-cache'), __( 'ON', 'litespeed-cache' ) ) ; ?>
22
  </font>
23
  <br /><font class="litespeed-success">
24
- <?php echo __('API:', 'litespeed-cache'); ?>
25
  <?php echo sprintf( __( 'Elements with attribute %s in html code will be excluded from moving to top.', 'litespeed-cache' ), '<code>data-optimized="0"</code>' ) ; ?>
26
  </font>
27
  </div>
@@ -37,7 +37,7 @@ if ( ! defined( 'WPINC' ) ) die ;
37
  <?php echo __( 'Both full URLs and partial strings can be used.', 'litespeed-cache' ) ; ?>
38
  <?php echo __('One per line.', 'litespeed-cache'); ?>
39
  <br /><font class="litespeed-success">
40
- <?php echo __('API:', 'litespeed-cache'); ?>
41
  <?php echo sprintf( __( 'Filter %s is supported.', 'litespeed-cache' ), '<code>litespeed_cache_optimize_css_excludes</code>' ) ; ?>
42
  <?php echo sprintf( __( 'Elements with attribute %s in html code will be excluded.', 'litespeed-cache' ), '<code>data-no-optimize="1"</code>' ) ; ?>
43
  </font>
@@ -53,11 +53,11 @@ if ( ! defined( 'WPINC' ) ) die ;
53
  <?php echo __( 'Load combined JS files before other JS files.', 'litespeed-cache' ) ; ?>
54
  <?php echo sprintf( __( 'Set to %s by default.', 'litespeed-cache' ), __( 'OFF', 'litespeed-cache' ) ) ; ?>
55
  <br /><font class="litespeed-warning">
56
- <?php echo __('NOTE:', 'litespeed-cache'); ?>
57
  <?php echo sprintf( __( 'Only set to %s when changing the order of combined and uncombined JS is needed.', 'litespeed-cache'), __( 'ON', 'litespeed-cache' ) ) ; ?>
58
  </font>
59
  <br /><font class="litespeed-success">
60
- <?php echo __('API:', 'litespeed-cache'); ?>
61
  <?php echo sprintf( __( 'Elements with attribute %s in html code will be excluded from moving to top/bottom.', 'litespeed-cache' ), '<code>data-optimized="0"</code>' ) ; ?>
62
  </font>
63
  </div>
@@ -73,7 +73,7 @@ if ( ! defined( 'WPINC' ) ) die ;
73
  <?php echo __( 'Both full URLs and partial strings can be used.', 'litespeed-cache' ) ; ?>
74
  <?php echo __('One per line.', 'litespeed-cache'); ?>
75
  <br /><font class="litespeed-success">
76
- <?php echo __('API:', 'litespeed-cache'); ?>
77
  <?php echo sprintf( __( 'Filter %s is supported.', 'litespeed-cache' ), '<code>litespeed_cache_optimize_js_excludes</code>' ) ; ?>
78
  <?php echo sprintf( __( 'Elements with attribute %s in html code will be excluded.', 'litespeed-cache' ), '<code>data-no-optimize="1"</code>' ) ; ?>
79
  </font>
@@ -145,7 +145,7 @@ if ( ! defined( 'WPINC' ) ) die ;
145
  <?php echo __( 'Both full URLs and partial strings can be used.', 'litespeed-cache' ) ; ?>
146
  <?php echo __('One per line.', 'litespeed-cache'); ?>
147
  <br /><font class="litespeed-success">
148
- <?php echo __('API:', 'litespeed-cache'); ?>
149
  <?php echo sprintf( __( 'Filter %s is supported.', 'litespeed-cache' ), '<code>litespeed_optm_js_defer_exc</code>' ) ; ?>
150
  <?php echo sprintf( __( 'Elements with attribute %s in html code will be excluded.', 'litespeed-cache' ), '<code>data-no-defer="1"</code>' ) ; ?>
151
  </font>
@@ -180,8 +180,8 @@ if ( ! defined( 'WPINC' ) ) die ;
180
  <tr>
181
  <th><?php echo __('Role Excludes', 'litespeed-cache'); ?></th>
182
  <td>
183
- <?php foreach ( $roles as $role ): ?>
184
- <?php $this->build_checkbox( LiteSpeed_Cache_Config::EXCLUDE_OPTIMIZATION_ROLES . "][", $role, $this->config->in_exclude_optimization_roles( $role ), $role ) ; ?>
185
  <?php endforeach; ?>
186
  <div class="litespeed-desc">
187
  <?php echo __( 'Selected roles will be excluded from all optimizations.', 'litespeed-cache' ) ; ?>
17
  <?php echo __( 'Load combined CSS files before other CSS files.', 'litespeed-cache' ) ; ?>
18
  <?php echo sprintf( __( 'Set to %s by default.', 'litespeed-cache' ), __( 'OFF', 'litespeed-cache' ) ) ; ?>
19
  <br /><font class="litespeed-warning">
20
+ <?php echo __('NOTE', 'litespeed-cache'); ?>:
21
  <?php echo sprintf( __( 'Only set to %s when changing the order of combined and uncombined CSS is needed.', 'litespeed-cache'), __( 'ON', 'litespeed-cache' ) ) ; ?>
22
  </font>
23
  <br /><font class="litespeed-success">
24
+ <?php echo __('API', 'litespeed-cache'); ?>:
25
  <?php echo sprintf( __( 'Elements with attribute %s in html code will be excluded from moving to top.', 'litespeed-cache' ), '<code>data-optimized="0"</code>' ) ; ?>
26
  </font>
27
  </div>
37
  <?php echo __( 'Both full URLs and partial strings can be used.', 'litespeed-cache' ) ; ?>
38
  <?php echo __('One per line.', 'litespeed-cache'); ?>
39
  <br /><font class="litespeed-success">
40
+ <?php echo __('API', 'litespeed-cache'); ?>:
41
  <?php echo sprintf( __( 'Filter %s is supported.', 'litespeed-cache' ), '<code>litespeed_cache_optimize_css_excludes</code>' ) ; ?>
42
  <?php echo sprintf( __( 'Elements with attribute %s in html code will be excluded.', 'litespeed-cache' ), '<code>data-no-optimize="1"</code>' ) ; ?>
43
  </font>
53
  <?php echo __( 'Load combined JS files before other JS files.', 'litespeed-cache' ) ; ?>
54
  <?php echo sprintf( __( 'Set to %s by default.', 'litespeed-cache' ), __( 'OFF', 'litespeed-cache' ) ) ; ?>
55
  <br /><font class="litespeed-warning">
56
+ <?php echo __('NOTE', 'litespeed-cache'); ?>:
57
  <?php echo sprintf( __( 'Only set to %s when changing the order of combined and uncombined JS is needed.', 'litespeed-cache'), __( 'ON', 'litespeed-cache' ) ) ; ?>
58
  </font>
59
  <br /><font class="litespeed-success">
60
+ <?php echo __('API', 'litespeed-cache'); ?>:
61
  <?php echo sprintf( __( 'Elements with attribute %s in html code will be excluded from moving to top/bottom.', 'litespeed-cache' ), '<code>data-optimized="0"</code>' ) ; ?>
62
  </font>
63
  </div>
73
  <?php echo __( 'Both full URLs and partial strings can be used.', 'litespeed-cache' ) ; ?>
74
  <?php echo __('One per line.', 'litespeed-cache'); ?>
75
  <br /><font class="litespeed-success">
76
+ <?php echo __('API', 'litespeed-cache'); ?>:
77
  <?php echo sprintf( __( 'Filter %s is supported.', 'litespeed-cache' ), '<code>litespeed_cache_optimize_js_excludes</code>' ) ; ?>
78
  <?php echo sprintf( __( 'Elements with attribute %s in html code will be excluded.', 'litespeed-cache' ), '<code>data-no-optimize="1"</code>' ) ; ?>
79
  </font>
145
  <?php echo __( 'Both full URLs and partial strings can be used.', 'litespeed-cache' ) ; ?>
146
  <?php echo __('One per line.', 'litespeed-cache'); ?>
147
  <br /><font class="litespeed-success">
148
+ <?php echo __('API', 'litespeed-cache'); ?>:
149
  <?php echo sprintf( __( 'Filter %s is supported.', 'litespeed-cache' ), '<code>litespeed_optm_js_defer_exc</code>' ) ; ?>
150
  <?php echo sprintf( __( 'Elements with attribute %s in html code will be excluded.', 'litespeed-cache' ), '<code>data-no-defer="1"</code>' ) ; ?>
151
  </font>
180
  <tr>
181
  <th><?php echo __('Role Excludes', 'litespeed-cache'); ?></th>
182
  <td>
183
+ <?php foreach ( $roles as $role => $title ): ?>
184
+ <?php $this->build_checkbox( LiteSpeed_Cache_Config::EXCLUDE_OPTIMIZATION_ROLES . "][", $title, $this->config->in_exclude_optimization_roles( $role ), $role ) ; ?>
185
  <?php endforeach; ?>
186
  <div class="litespeed-desc">
187
  <?php echo __( 'Selected roles will be excluded from all optimizations.', 'litespeed-cache' ) ; ?>
admin/tpl/settings.php CHANGED
@@ -80,9 +80,12 @@ global $wp_roles ;
80
  if ( !isset( $wp_roles ) ) {
81
  $wp_roles = new WP_Roles() ;
82
  }
83
- $roles = array_keys( $wp_roles->roles ) ;
84
 
85
- sort( $roles ) ;
 
 
 
 
86
 
87
  include_once LSCWP_DIR . "admin/tpl/inc/banner_promo.php" ;
88
 
80
  if ( !isset( $wp_roles ) ) {
81
  $wp_roles = new WP_Roles() ;
82
  }
 
83
 
84
+ $roles = array() ;
85
+ foreach ( $wp_roles->roles as $k => $v ) {
86
+ $roles[ $k ] = $v[ 'name' ] ;
87
+ }
88
+ ksort( $roles ) ;
89
 
90
  include_once LSCWP_DIR . "admin/tpl/inc/banner_promo.php" ;
91
 
cli/litespeed-cache-cli-admin.class.php CHANGED
@@ -31,6 +31,7 @@ class LiteSpeed_Cache_Cli_Admin
31
  LiteSpeed_Cache_Config::CRWL_PAGES,
32
  LiteSpeed_Cache_Config::CRWL_CATS,
33
  LiteSpeed_Cache_Config::CRWL_TAGS,
 
34
  LiteSpeed_Cache_Config::CRWL_CRON_ACTIVE,
35
  LiteSpeed_Cache_Config::OPID_DEBUG_LEVEL,
36
  LiteSpeed_Cache_Config::OPID_HEARTBEAT,
@@ -144,6 +145,7 @@ class LiteSpeed_Cache_Cli_Admin
144
  case LiteSpeed_Cache_Config::CRWL_PAGES:
145
  case LiteSpeed_Cache_Config::CRWL_CATS:
146
  case LiteSpeed_Cache_Config::CRWL_TAGS:
 
147
  case LiteSpeed_Cache_Config::CRWL_CRON_ACTIVE:
148
  case LiteSpeed_Cache_Config::OPID_DEBUG_LEVEL:
149
  case LiteSpeed_Cache_Config::OPID_HEARTBEAT:
31
  LiteSpeed_Cache_Config::CRWL_PAGES,
32
  LiteSpeed_Cache_Config::CRWL_CATS,
33
  LiteSpeed_Cache_Config::CRWL_TAGS,
34
+ LiteSpeed_Cache_Config::CRWL_HTTP2,
35
  LiteSpeed_Cache_Config::CRWL_CRON_ACTIVE,
36
  LiteSpeed_Cache_Config::OPID_DEBUG_LEVEL,
37
  LiteSpeed_Cache_Config::OPID_HEARTBEAT,
145
  case LiteSpeed_Cache_Config::CRWL_PAGES:
146
  case LiteSpeed_Cache_Config::CRWL_CATS:
147
  case LiteSpeed_Cache_Config::CRWL_TAGS:
148
+ case LiteSpeed_Cache_Config::CRWL_HTTP2:
149
  case LiteSpeed_Cache_Config::CRWL_CRON_ACTIVE:
150
  case LiteSpeed_Cache_Config::OPID_DEBUG_LEVEL:
151
  case LiteSpeed_Cache_Config::OPID_HEARTBEAT:
css/iziModal.min.css ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
1
+ /*
2
+ * iziModal | v1.5.1
3
+ * http://izimodal.marcelodolce.com
4
+ * by Marcelo Dolce.
5
+ */
6
+ .iziModal{display:none;position:fixed;top:0;bottom:0;left:0;right:0;margin:auto;background:#fff;box-shadow:0 0 8px rgba(0,0,0,.3);transition:margin-top .3s ease,height .3s ease;transform:translateZ(0)}.iziModal *{-webkit-font-smoothing:antialiased}.iziModal::after{content:'';width:100%;height:0;opacity:0;position:absolute;left:0;bottom:0;z-index:1;background:-moz-linear-gradient(top,transparent 0%,rgba(0,0,0,.35) 100%);background:-webkit-gradient(linear,left top,left bottom,color-stop(0%,transparent),color-stop(100%,rgba(0,0,0,.35)));background:-webkit-linear-gradient(top,transparent 0%,rgba(0,0,0,.35) 100%);background:-o-linear-gradient(top,transparent 0%,rgba(0,0,0,.35) 100%);background:-ms-linear-gradient(top,transparent 0%,rgba(0,0,0,.35) 100%);background:linear-gradient(to bottom,transparent 0%,rgba(0,0,0,.35) 100%);filter:progid:DXImageTransform.Microsoft.gradient( startColorstr='#00000000', endColorstr='#59000000',GradientType=0 );transition:height .3s ease-in-out,opacity .3s ease-in-out;pointer-events:none}.iziModal.hasShadow::after{height:30px;opacity:1}.iziModal .iziModal-progressbar{position:absolute;left:0;top:0;width:100%;z-index:1}.iziModal .iziModal-progressbar>div{height:2px;width:100%}.iziModal .iziModal-header{background:#88a0b9;padding:14px 18px 15px;box-shadow:inset 0 -10px 15px -12px rgba(0,0,0,.3),0 0 0 #555;overflow:hidden;position:relative;z-index:10}.iziModal .iziModal-header-icon{font-size:40px;color:rgba(255,255,255,.5);padding:0 15px 0 0;margin:0;float:left}.iziModal .iziModal-header-title{color:#fff;font-size:18px;font-weight:600;line-height:1.3}.iziModal .iziModal-header-subtitle{color:rgba(255,255,255,.6);font-size:12px;line-height:1.45}.iziModal .iziModal-header-subtitle,.iziModal .iziModal-header-title{display:block;margin:0;padding:0;font-family:'Lato',Arial;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;text-align:left}.iziModal .iziModal-header-buttons{position:absolute;top:50%;right:10px;margin:-17px 0 0}.iziModal .iziModal-button{display:block;float:right;z-index:2;outline:0;height:34px;width:34px;border:0;padding:0;margin:0;opacity:.3;border-radius:50%;transition:transform .5s cubic-bezier(.16,.81,.32,1),opacity .5s ease;background-size:67%!important;-webkit-tap-highlight-color:transparent}.iziModal .iziModal-button-close{background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACwAAAAsCAYAAAAehFoBAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyhpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNi1jMTMyIDc5LjE1OTI4NCwgMjAxNi8wNC8xOS0xMzoxMzo0MCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTUuNSAoV2luZG93cykiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6ODZCQkIzQ0I0RTg0MTFFNjlBODI4QTFBRTRBMkFCMDQiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6ODZCQkIzQ0M0RTg0MTFFNjlBODI4QTFBRTRBMkFCMDQiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo4NkJCQjNDOTRFODQxMUU2OUE4MjhBMUFFNEEyQUIwNCIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDo4NkJCQjNDQTRFODQxMUU2OUE4MjhBMUFFNEEyQUIwNCIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PsgTJLcAAALJSURBVHja3JnLS1VBHMfvQ7g9dBXRRrwEFRciAhMi1JRW1aIHVEIYEkW0iVpUhOD/ICK6cFMgSbUpC6VFkQa9NtpjkauriRY9Noa3pHT8/mIODMM5Or85o87pC5/NPf5mvmc8M7+Z36SFEKkY2gj2gUawF2wHW8A6+fwv+A6KYAQMg+dg2rbDtKXhGnAaHJIms4zYz9J4HxgAf1g9k2EGteAhWBBuNApaQNrUg6nRTaAbzIuV0RCocWW4DoyJlVcJXI5ruFk2tJqi/2TWxvA5sXbqA2Ucw01i7dVjargazAo/dE33p6/DlAheg50pP0SJpwG8CH7IaH/Q5pFZUhnoArkwwwVwJeWfdoMLYYZvqG+yTGo9CerAoIWBT+A4qAdPDWOugwo1NVcxJtpFZRLkwH3GJCqCghJfxVjnz1JMMMKnwAbGRAg0B5rAA4O4CblZ+qj8tkBjZthvSzDCtFIMM0ZpQhslk5Eej4jpZ/T7G+ygwG1ghrk+jjNMFy1eMPJzpOAzlou6iWmXZkm91EBHjEwUZXoQTDk2SxqhRh7HTJ9hpstB3rFZ0ldq6J2DnB9m2rXZfxOPlrX1DrJRXiaBXSHPaMHvB0cd9JPLpBImMvzLQTuUFA6A9yHPfoIjhsllOc1l5N4grtmDWgYrl5+JTUZcSjNkeMyxWdpA3ZN72IJj01OJTByJS82J2/wQVxmB5y1HK8x0JWMf/kzdD98FJcY5S51gdwyTQl6eUAraspo27PeWXgy8afim0+CELAwOWHyH9EkdkyWwJ4Yxk6BCP+bTm48anutWW5dAp34IpbW03UOzb0FPVEHbx0LKfvAyqpAyKw97JU8Mt6pml6rAJ6oY6Eu5NfvfF7QTeWWQyEsZr6694lwsNoPD8mKRo29gCNwGj7gXi7aGA1EBcY+8vq0GW8FmJb3Pgx9gEnwAr8Ab8MW2w0UBBgAVyyyaohV7ewAAAABJRU5ErkJggg==) no-repeat 50% 50%}.iziModal .iziModal-button-fullscreen{background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACwAAAAsCAYAAAAehFoBAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyhpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNi1jMTMyIDc5LjE1OTI4NCwgMjAxNi8wNC8xOS0xMzoxMzo0MCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTUuNSAoV2luZG93cykiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6RTBBOUI4RUM0RTg0MTFFNjk0NTY4NUNFRkZFNEFEQzIiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6RTBBOUI4RUQ0RTg0MTFFNjk0NTY4NUNFRkZFNEFEQzIiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDpFMEE5QjhFQTRFODQxMUU2OTQ1Njg1Q0VGRkU0QURDMiIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDpFMEE5QjhFQjRFODQxMUU2OTQ1Njg1Q0VGRkU0QURDMiIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PrQO6gAAAANmSURBVHjazJlbSBRRGMd3x92i0ForRRMiKiUoX4ouiFlJkRVBDxW9GJERwUasvdRT9FD00osRQtAFqegGBUHRBY0uaCVKEkSRpVR0tSwrQtp1+p/4Bk7D7M45M/Ot/uGHu+Psmf+c+eY753wnbJpmyIfGgvmgiv6WgkKQBwzwE3wBr0AnuAta6ZgnhT0aFuY2ghoyGdH4bS+4Dc6CZjCkdWVhWIPF4JoZnB6CDToeVE8sBidNPt0E5UEZrgG9Jr8GwHa/huMgaWZXDSDsxfBuc/jUBAwdw3Fz+NWoang5SJkjQwm7P3seLqQEX2LLfgfBdZcMORMcBqNDwekPqASP0uXhpjR3Ok0x/fUw9HIHGGVdw5DuRtzJpgxDsJui2qOWmuaAOuuLbHivz4YLwLgQj/aAXNmwuItlHhtbA7pAG5jEZHgKWCcbrhUTIY+NPQVjqFFObbYMi/hc6aOhl2AJ9TKnFoIyYXgemKEzJQXVVkyR3oFVzKZFuqw2qHdyFPKhrHPgMoWC3fRjRtNVVg+7SR5IiqmXxUt60cG0CK/vTIZniZVCmcKJF0C3ZNjKBqvJ9Hrwm46tsN1EkCoRQ/M3fBjvs6GrYAvdwHEfGcd1qBaGkwoxrKI+xjz83yJ0iLFHApd46X4xX+M+WECh4lepCNUIcpnMijrEWtAvTRHrbOd8FZNG8uA2Nf0hpmwtjBPwpQ5T0GPS/+tBAZhIq+b3Lu09EyHRwRgO+0C+7dhWcII+PwCf6Sk/Aa9d2vtn+A7nyASugJiD6YSDQcOlvVbxiCaAN8xrs3sgprBiac/QhlhnzjUo6JuZM0UlDS5FPtoQIdNlPYJTWUihFaDex+9Pg6T1KHJAJ2NI7ASllA28hEQ/KJIXoSlwgKlnh+jFe+GjLtwIPtjfyktUt+UaUZWqvw7H3oJD1peI7eQdoF1xWa+zQikHH13OmwqmOxxP0EiZtgK/DRwNuIcHwSeXc2K01WAPhbhKBb5hBNTVbskVH7fqpZGhbJUNtYF83fqwQSXPbOsGjb6etwx2gcEsmT3iFAZeNmUqaMeHSz2qu0k6W15Rqsx3B2i0D+xXGAHTFrRVlEeFuVoqH+ku6VNUbDkPzlAtg30nVK66i8rRIjAbTKaSQVQyN0DD6nOqcLZQld9TLfmvAAMAeMcvp3eCFqQAAAAASUVORK5CYII=) no-repeat 50% 50%}.iziModal.isFullscreen .iziModal-button-fullscreen{background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACwAAAAsCAYAAAAehFoBAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyhpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNi1jMTMyIDc5LjE1OTI4NCwgMjAxNi8wNC8xOS0xMzoxMzo0MCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTUuNSAoV2luZG93cykiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6MkFFRTU5NDA0RTg1MTFFNjk0NEZFQzBGMkVBMDYyRDkiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6MkFFRTU5NDE0RTg1MTFFNjk0NEZFQzBGMkVBMDYyRDkiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDoyQUVFNTkzRTRFODUxMUU2OTQ0RkVDMEYyRUEwNjJEOSIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDoyQUVFNTkzRjRFODUxMUU2OTQ0RkVDMEYyRUEwNjJEOSIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PuDFfX8AAANASURBVHjazJlZSBVRGMfHcWlB0xZM68GKukQLYaGkmEUR2EsvRfQS+BSJPUQE+lTR8hqIZY8hFS0ERVCRoW3gpUApghYpszLTVnCB3O70/+K7MAwzc78Z58z4hx8XzpzvzJ+Zc+d85ztphmFoU9BsUAoq+XcFyAc5QAfD4BfoBp3gCWjnNl9K82mYzO0FVWwyw0NsD3gIroBWkPB0ZzLsgc3grhGcnoE9XjxIOxaCC4Y6tYC1QRmuAj2Geg2CA1M1XAsmjHDVANL8GK4zolMz0L0YrjWiV5PU8HYw6TBIf8imD6UynA96HYKPg3mgMUTDY6DUzXCzQ+AxSz+r6QEQZz4HbLoDZNkZrnAIoOlRZjN1Gk3XS0zty/gTFaRq7Ay3uAR8BcU2ps/z9QJTWw74HrDhTyDbbHg9SKQI+sb9rKa3mV8ZmAt+KJjP1TS+zinFPkqEUqQdBeAOKLa0UwIzpqlXtcYpIKWIO4RBZPoRKNfC10YQI8MlYLkwaAB8ABsiMDwDbKU8dgtIFwRMgJ3guRadKpNPWBMa7tOi1WoyHJPuTsC4oN+IQsOLM3gPJlEWqOE/neMGBqwDeYoMz6G8c0I4h6eFyHBC8A2eVoaH8JutaPwuUA/+uvSht1sHKgTjTWZwjUCVYdrK3xT0iwkND+lc5FClUQ9fINHCRYY7FBrWPSz5Er2lAR9H9P+hpfYGl64OCmPadQ7ojcDwOJetysBMQX/6mrWS4d+cIoYtMnAEnBT2fwVeJufYxZBMFoKFlrajQtOX/uczvEtIB50Kdgn1lt3JGdANltjsXE64jPMnuQ1LPuFJcFrBE11gzQXAUnAPFNk86esO4zSBfmu5lVa9toCf8DC4Ba6C22DEdO01KDLdP5fLr1Z94X2ibV1ilWVQ1XrDpvPAU4c+u1KVqvaHXI7q43ltp3PSYmDDNCgGPrCUD1wN6y5lqzAUN89baX1Y55Jn2LrPRUffRwaHwWhIZs/aTQM/hzLlDp+coPRReprk5cgrkyvz7wM0+hOcAvOlPvwcLNIp526ux1H5aJbHeFpVX4Br4LLXWoffk9CkVnLlaBNYAxaBXJBpMjfIy+o7EAdtfIyb8HPDfwIMAM1WPs8F9tcxAAAAAElFTkSuQmCC) no-repeat 50% 50%}.iziModal .iziModal-button-close:hover{transform:rotate(180deg)}.iziModal .iziModal-button:hover{opacity:.8}.iziModal .iziModal-header.iziModal-noSubtitle{height:auto;padding:10px 15px 12px}.iziModal .iziModal-header.iziModal-noSubtitle .iziModal-header-icon{font-size:23px;padding-right:13px}.iziModal .iziModal-header.iziModal-noSubtitle .iziModal-header-title{font-size:15px;margin:3px 0 0;font-weight:400}.iziModal .iziModal-header.iziModal-noSubtitle .iziModal-header-buttons{right:6px;margin:-16px 0 0}.iziModal .iziModal-header.iziModal-noSubtitle .iziModal-button{height:30px;width:30px}.iziModal-rtl{direction:rtl}.iziModal-rtl .iziModal-header{padding:14px 18px 15px 40px}.iziModal-rtl .iziModal-header-icon{float:right;padding:0 0 0 15px}.iziModal-rtl .iziModal-header-buttons{right:initial;left:10px}.iziModal-rtl .iziModal-button{float:left}.iziModal-rtl .iziModal-header-subtitle,.iziModal-rtl .iziModal-header-title{text-align:right;font-family:Tahoma,'Lato',Arial;font-weight:500}.iziModal-rtl .iziModal-header.iziModal-noSubtitle{padding:10px 15px 12px 40px}.iziModal-rtl .iziModal-header.iziModal-noSubtitle .iziModal-header-icon{padding:0 0 0 13px}.iziModal.iziModal-light .iziModal-header-icon{color:rgba(0,0,0,.5)}.iziModal.iziModal-light .iziModal-header-title{color:#000}.iziModal.iziModal-light .iziModal-header-subtitle{color:rgba(0,0,0,.6)}.iziModal.iziModal-light .iziModal-button-close{background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACwAAAAsCAYAAAAehFoBAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA4JpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNi1jMTM4IDc5LjE1OTgyNCwgMjAxNi8wOS8xNC0wMTowOTowMSAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDoyQTU1RUZDNzRFODQxMUU2ODAxOEUwQzg0QjBDQjI3OSIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDo1NEM4MTU1MEI4QUExMUU2QjNGOEVBMjg4OTRBRTg2NyIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDo0RTNFNENDMkI4QUExMUU2QjNGOEVBMjg4OTRBRTg2NyIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ0MgMjAxNyAoTWFjaW50b3NoKSI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOjZjYzMwMmE1LWFlMjEtNDI3ZS1hMmE4LTJlYjhlMmZlY2E3NSIgc3RSZWY6ZG9jdW1lbnRJRD0iYWRvYmU6ZG9jaWQ6cGhvdG9zaG9wOjdmYmU3NGE3LTAxMDUtMTE3YS1hYmM3LWEzNWNkOWU1Yzc4NyIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/Po24QssAAANtSURBVHja3JlJaBRBFIa7ZxyTSXADHUkikuAawZNLEOOGGrwJQYko8R4RBQ+OICoqghJQUVwPYjzFY0QUBQU1kogoKO6CG0pcIwbiNibj/8JraNvu6Xo9NTOtP3xzSKe6/65+Ve9VlWlkp2IwGUwFE0E5GA4G8/U+0APegWfgHrgPuq0bpNNp0QPNgEYngHlgGpuMCNp2s+kr4BYM/8ql4WqwHEzP4mXteg7awOW0YlerPnQIaARLNBl1ikLlBDw/1WF4ClgHKozc6idogekz2RheANbaBlE+dB4chfF+qeHF3LOF0FWwF6b7nBe8RvecApolzQVr3C64GR4H1huFV51pmvV+hikRbABFRji0GqarMxluAGON8CgKmmA65mZ4DFhqhE9VPP//ZXgZiCmm1t1gI6XWAAY+gF0gCe4qtqlHL8fthkeBWsXGreA6eMgPviEw+x5sBZ3gAdjPCcNPI8Fsu+FawUCzz40psEfRNJndBl7b/pZmVLTQMkzJo0bQSys43iWm3cxS+DUJOmoSwqKCRmEZWKkYv6RSMBPc5lqXRGm0A1Q6XiaT2aSwo8jrK/qZwZlFIlXTusxa6iXDddTdARpnMj2ek9AWjWYH7h/lubcs4A28THdyAdOl0ezAmKNBNyLLiT0Btjti9zuHg06zpJKIprohwXNypcu1OIdGjYbnxCLGPyYy/EPDfejzbwYvXK59AzuFGdFLKTL8WYNZ59RVzGESJCNm0teI40E6zNIA2wSaA2REP32iaW0omKXRbJKTUVyYEVV0J8oxvEiQmiUZrFSz6XNkuJe3nBKCelaSbjOZrhLsd1BInYxweSeJq9YA6dYtuZCBI4JZ6jGW/W+sebhd0DAaMIO5mTYFW1+X6GeQ7TO3W0WyQj3cw0ulBg4nSUbcAY7zPVYp7ip95FXOH29Hb35AOPjypWMIh7PORSjFZVsIzdKW7AWvfYnTVNWHyCytHw+jd1Nehqks3KepvtChUzD7yGvE2/cduqxldQF1EWZb/PbWLF3jAVgo0WrlkN+c6hSd+rzlaSuaR7O0oX0wyIa2pVAdGaj0HCUVOqIq4dVwrg5lmmG2w+8f/9tjL6foYHE+Gy8Xtv3CPUpf7WauDxadKuIwoeNbOmoYDYbZ0ns/1wxUC7ykigs8sS/LpEe3vwUYALiKDDDSgEiSAAAAAElFTkSuQmCC) no-repeat 50% 50%}.iziModal.iziModal-light .iziModal-button-fullscreen{background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACwAAAAsCAYAAAAehFoBAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA4JpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNi1jMTM4IDc5LjE1OTgyNCwgMjAxNi8wOS8xNC0wMTowOTowMSAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDpEQTg1NTA2NTRFODQxMUU2OTQ0N0VERjY2Q0M5ODYwRCIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDo0RTNFNENCQkI4QUExMUU2QjNGOEVBMjg4OTRBRTg2NyIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDo0RTNFNENCQUI4QUExMUU2QjNGOEVBMjg4OTRBRTg2NyIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ0MgMjAxNyAoTWFjaW50b3NoKSI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOjFlNTQwYzczLTVhZmEtNDJlYi04YzJlLWMwMzFlYmFiYmIyNiIgc3RSZWY6ZG9jdW1lbnRJRD0iYWRvYmU6ZG9jaWQ6cGhvdG9zaG9wOmVkYmRiMzM1LTAxMDUtMTE3YS1hYmM3LWEzNWNkOWU1Yzc4NyIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PvIicdUAAAOvSURBVHjaxJlZbA1hFMe/qaItUUsspakg1laJ7UUisQuRvvTFA15sQSRCLBFrQryhHqxNHxEPtaQ8CCUkIrVVRbVBJdZYSrXVonr9/3pGxnTunZk78/X+k1+aO+1899/vnnvO+c4YKpi6ghEgW34OBD1BKjBAM6gH78Fz8BhUyrW/ikQivt7QiNMozU0DE8RkJx/3fgCPwA1QHvHp2K/hHJAPJqpwVA2K4flW2IZ7gyVgptKjh6AQxl+GYZi7uRr0U3rVBIpg+nIQwwvACpCkOk4XwYlosR3LMGN1qUqMroGDTqaNGDu7SiVWl+D3iP2i00c9HqxUidd8wzDy3HY4HRwCfWzXz4L7Lm+QKfHeOUTTLWAzdro6muH1YIbDjculWrmpUEM2YYXcCNMt9pAYE8WsWYLdlAxaNYTGMDDHKYYXBVy4B0jTFM/5iOcUc1fM/2JcnItNAYtBNzGtQ33BVHDV3OHpARqhV6CLLKpTs8yQYHxOCrDQO7AV1Gg2PBJhMYiGh4MMnx1eLkixXKsFuzSbZrrMpeGxHnqFFtvrTWCbhILd9AuNpnPMHXaTtZD0kl1mRdwSxXSjJsNZfONjcmqIJR5p3lp6Y+sXrAzsBz/lNXvmtZYMFKbqafi0pKQgKpOSPhmsC5BxXEs1Fz4fUr/7TWMe/q9bC2s3tJs1Df/Q/B5PwAZwJYS1WpPlo0zRZJZziL2gQU7I1GyHL7QSD26taVOytI26DpinxKypApvpk+C6dHlMnXskbUbT1yTpN3WJHWB327UCS3hUoc+tA/VyxP/ost5rGq7QWZnAdoe0eZgnYweDbgmgkoafgk8aTfNgsMNmmqfhC+Czj3V4T3mSBH255kxB0ztd4tNNDJkas2CUdkAKHQ3yAtxfijj/bdb7Cumyhmoyexzcs6Qwv2qUbPKvJDOtnNFklrF3R5qneA2XYHe/2A+ht1Xb3FZXRY1XTAjFTgtxJ45qKtWDpZK1g6dhIQuvBzjcy8FgQ6y8Nw+sCdnwL1Dn8jdMe6m2a+3ma9ESNUdOC1VixSH3bnPiYyraswnO0fqDIQkyW8WmCWab7b+I9TCF3+x0j2e+MPUA7LPGrVfD1F3VNsrPVR0zhS8BB5x21muzYa1Sy1Tb4y4d4qOwIi9Pk/wcj1gV50p5zQjJKAsJH8KcY4vpdYrjV0w9HMxxHjfKNpfwdMyRNuAmyy2M1vq5OegBNFMmR9lSHDizSLPMJGjuO2BZfSOtLKvpMylUvh/d/hFgAOH4+ibxGTZuAAAAAElFTkSuQmCC) no-repeat 50% 50%}.iziModal.iziModal-light.isFullscreen .iziModal-button-fullscreen{background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACwAAAAsCAYAAAAehFoBAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA3BpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNi1jMTM4IDc5LjE1OTgyNCwgMjAxNi8wOS8xNC0wMTowOTowMSAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDoyRUUxMkYxODRFODUxMUU2Qjc3RDk0MUUzMzJDRjBEOCIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDo0RTNFNENCRkI4QUExMUU2QjNGOEVBMjg4OTRBRTg2NyIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDo0RTNFNENCRUI4QUExMUU2QjNGOEVBMjg4OTRBRTg2NyIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ0MgMjAxNyAoTWFjaW50b3NoKSI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOjgzM2MwOWZiLWJjOTEtNGVlZS05MDM1LTRkMmU2ZmE1ZjBmMiIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDoyRUUxMkYxODRFODUxMUU2Qjc3RDk0MUUzMzJDRjBEOCIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/Pv1Q9Z8AAAOXSURBVHjaxJlLbA1RGMfPjIs+EvoIRYt4FVUl2EkkRTxKUqQbG0SEho2FjUQ8YtEICbEgTdFYeK1KaGvVeoUltyStt0UlNE17aWhV2+v/9X5XJpMzc8/0zpn5kl+aO3Nm7r/fnPu9xhDp2URQDJbw3xkgB2QCAwyAPvANfARvQDsfG7V4PO7pC40xCiVxa8AKFjnOw7VdoA08BtG4R8VeBZeCKrBS+GPvQAM0P/NbcB7YBdYJPfYKXIXwL34IJm8eBFOFXusH9RDdnI7gLWA/MEVwdh/UOe1tN8G0V3eLcKwFXJCJNl08G5ZYsrWgWnZCJng5OOBwo1iAoisMw6hMJXgyOOywVW7xj+9BgKL3QHSxm+C9IF9y4U2GMlStRPQP8Jbp9lFwhJwE0RHrgaSV8N6xG238l7Zjtfx3K58/Bd7zsWngIqdnP2we2ACa7B7e6RL6joK5EtHNfL7b5u1Bn7dGFbycYRVM/8WyFJnuJK+z2iVwzFrMcF1h+Cx4ClhtFVyu8CW54ITE01EwFMAPcH1SMJWIqxQvItE1YHEIsXkhtkUhCV4ApiteFOPadn4IgseDMooSSxVrhWFwmkvCsKw06WGhKLhHhGuzSHChh9pZ5cc1oFFwfoTTsWrWqQCvXdZQEpkDsjUJziSv3Qu43k3LTA1BXqvRY/4DMjTd/yu4niJVm9wslCjcb4QE/9Qo+Al44baAmgpKCIqC+01OBLrsr8/de8zkiYwuUxWSq7iuM8JhantIqfYItkOepKBysnbycIfPXYKqURL6DhaBCQrrKcZHTa5loyEIJgHXwG3F9TQV+pxMGK0BiaTHn2OLEjcURbdi7XBSMO3jTxoEjtg+7wDnhG3spSD6F3hk7Tjoxnc0CJ5k+5wFCrhplYl2mmI24nyvvWumAE9z2zIfBW8WifnxIHc2yb6xiHtEoms0/hlGtpAPHCkgNDjFyZngPN88COvkPpEe+XGHbFcD7z53C+ybwKEAo0UPZ8QCybkmiL3sNvkheygSI08RYOSQiaUhd52sUpIZLWwJsYqkkdcZeHfIS66nc9XcZQRpNBY7C7F9Yy1OtonErDgSgNhGcEXmWa/VFA1O9onE6y4dRqGtXuVtkpf2iDy8EVR6GLykMnrsNFC867QF0hH8v3MVicFcuYdKy56uqQx4SukWQj3NOtJtQIt4ckSvbmdziMqy7HcS9xv0cn/Xwdn0A1drnl/d/hNgAGQa6Lgarp6BAAAAAElFTkSuQmCC) no-repeat 50% 50%}.iziModal .iziModal-loader{background:#fff url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNDQiIGhlaWdodD0iNDQiIHZpZXdCb3g9IjAgMCA0NCA0NCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiBzdHJva2U9IiM5OTkiPiAgICA8ZyBmaWxsPSJub25lIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiIHN0cm9rZS13aWR0aD0iMiI+ICAgICAgICA8Y2lyY2xlIGN4PSIyMiIgY3k9IjIyIiByPSIxIj4gICAgICAgICAgICA8YW5pbWF0ZSBhdHRyaWJ1dGVOYW1lPSJyIiAgICAgICAgICAgICAgICBiZWdpbj0iMHMiIGR1cj0iMS40cyIgICAgICAgICAgICAgICAgdmFsdWVzPSIxOyAyMCIgICAgICAgICAgICAgICAgY2FsY01vZGU9InNwbGluZSIgICAgICAgICAgICAgICAga2V5VGltZXM9IjA7IDEiICAgICAgICAgICAgICAgIGtleVNwbGluZXM9IjAuMTY1LCAwLjg0LCAwLjQ0LCAxIiAgICAgICAgICAgICAgICByZXBlYXRDb3VudD0iaW5kZWZpbml0ZSIgLz4gICAgICAgICAgICA8YW5pbWF0ZSBhdHRyaWJ1dGVOYW1lPSJzdHJva2Utb3BhY2l0eSIgICAgICAgICAgICAgICAgYmVnaW49IjBzIiBkdXI9IjEuNHMiICAgICAgICAgICAgICAgIHZhbHVlcz0iMTsgMCIgICAgICAgICAgICAgICAgY2FsY01vZGU9InNwbGluZSIgICAgICAgICAgICAgICAga2V5VGltZXM9IjA7IDEiICAgICAgICAgICAgICAgIGtleVNwbGluZXM9IjAuMywgMC42MSwgMC4zNTUsIDEiICAgICAgICAgICAgICAgIHJlcGVhdENvdW50PSJpbmRlZmluaXRlIiAvPiAgICAgICAgPC9jaXJjbGU+ICAgICAgICA8Y2lyY2xlIGN4PSIyMiIgY3k9IjIyIiByPSIxIj4gICAgICAgICAgICA8YW5pbWF0ZSBhdHRyaWJ1dGVOYW1lPSJyIiAgICAgICAgICAgICAgICBiZWdpbj0iLTAuOXMiIGR1cj0iMS40cyIgICAgICAgICAgICAgICAgdmFsdWVzPSIxOyAyMCIgICAgICAgICAgICAgICAgY2FsY01vZGU9InNwbGluZSIgICAgICAgICAgICAgICAga2V5VGltZXM9IjA7IDEiICAgICAgICAgICAgICAgIGtleVNwbGluZXM9IjAuMTY1LCAwLjg0LCAwLjQ0LCAxIiAgICAgICAgICAgICAgICByZXBlYXRDb3VudD0iaW5kZWZpbml0ZSIgLz4gICAgICAgICAgICA8YW5pbWF0ZSBhdHRyaWJ1dGVOYW1lPSJzdHJva2Utb3BhY2l0eSIgICAgICAgICAgICAgICAgYmVnaW49Ii0wLjlzIiBkdXI9IjEuNHMiICAgICAgICAgICAgICAgIHZhbHVlcz0iMTsgMCIgICAgICAgICAgICAgICAgY2FsY01vZGU9InNwbGluZSIgICAgICAgICAgICAgICAga2V5VGltZXM9IjA7IDEiICAgICAgICAgICAgICAgIGtleVNwbGluZXM9IjAuMywgMC42MSwgMC4zNTUsIDEiICAgICAgICAgICAgICAgIHJlcGVhdENvdW50PSJpbmRlZmluaXRlIiAvPiAgICAgICAgPC9jaXJjbGU+ICAgIDwvZz48L3N2Zz4=) no-repeat 50% 50%;position:absolute;left:0;right:0;top:0;bottom:0;z-index:9}.iziModal .iziModal-content-loader{background:url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNDQiIGhlaWdodD0iNDQiIHZpZXdCb3g9IjAgMCA0NCA0NCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiBzdHJva2U9IiM5OTkiPiAgICA8ZyBmaWxsPSJub25lIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiIHN0cm9rZS13aWR0aD0iMiI+ICAgICAgICA8Y2lyY2xlIGN4PSIyMiIgY3k9IjIyIiByPSIxIj4gICAgICAgICAgICA8YW5pbWF0ZSBhdHRyaWJ1dGVOYW1lPSJyIiAgICAgICAgICAgICAgICBiZWdpbj0iMHMiIGR1cj0iMS40cyIgICAgICAgICAgICAgICAgdmFsdWVzPSIxOyAyMCIgICAgICAgICAgICAgICAgY2FsY01vZGU9InNwbGluZSIgICAgICAgICAgICAgICAga2V5VGltZXM9IjA7IDEiICAgICAgICAgICAgICAgIGtleVNwbGluZXM9IjAuMTY1LCAwLjg0LCAwLjQ0LCAxIiAgICAgICAgICAgICAgICByZXBlYXRDb3VudD0iaW5kZWZpbml0ZSIgLz4gICAgICAgICAgICA8YW5pbWF0ZSBhdHRyaWJ1dGVOYW1lPSJzdHJva2Utb3BhY2l0eSIgICAgICAgICAgICAgICAgYmVnaW49IjBzIiBkdXI9IjEuNHMiICAgICAgICAgICAgICAgIHZhbHVlcz0iMTsgMCIgICAgICAgICAgICAgICAgY2FsY01vZGU9InNwbGluZSIgICAgICAgICAgICAgICAga2V5VGltZXM9IjA7IDEiICAgICAgICAgICAgICAgIGtleVNwbGluZXM9IjAuMywgMC42MSwgMC4zNTUsIDEiICAgICAgICAgICAgICAgIHJlcGVhdENvdW50PSJpbmRlZmluaXRlIiAvPiAgICAgICAgPC9jaXJjbGU+ICAgICAgICA8Y2lyY2xlIGN4PSIyMiIgY3k9IjIyIiByPSIxIj4gICAgICAgICAgICA8YW5pbWF0ZSBhdHRyaWJ1dGVOYW1lPSJyIiAgICAgICAgICAgICAgICBiZWdpbj0iLTAuOXMiIGR1cj0iMS40cyIgICAgICAgICAgICAgICAgdmFsdWVzPSIxOyAyMCIgICAgICAgICAgICAgICAgY2FsY01vZGU9InNwbGluZSIgICAgICAgICAgICAgICAga2V5VGltZXM9IjA7IDEiICAgICAgICAgICAgICAgIGtleVNwbGluZXM9IjAuMTY1LCAwLjg0LCAwLjQ0LCAxIiAgICAgICAgICAgICAgICByZXBlYXRDb3VudD0iaW5kZWZpbml0ZSIgLz4gICAgICAgICAgICA8YW5pbWF0ZSBhdHRyaWJ1dGVOYW1lPSJzdHJva2Utb3BhY2l0eSIgICAgICAgICAgICAgICAgYmVnaW49Ii0wLjlzIiBkdXI9IjEuNHMiICAgICAgICAgICAgICAgIHZhbHVlcz0iMTsgMCIgICAgICAgICAgICAgICAgY2FsY01vZGU9InNwbGluZSIgICAgICAgICAgICAgICAga2V5VGltZXM9IjA7IDEiICAgICAgICAgICAgICAgIGtleVNwbGluZXM9IjAuMywgMC42MSwgMC4zNTUsIDEiICAgICAgICAgICAgICAgIHJlcGVhdENvdW50PSJpbmRlZmluaXRlIiAvPiAgICAgICAgPC9jaXJjbGU+ICAgIDwvZz48L3N2Zz4=) no-repeat 50% 50%}.iziModal .iziModal-content:after,.iziModal .iziModal-content:before{content:'';display:table}.iziModal .iziModal-content:after{clear:both}.iziModal .iziModal-content{zoom:1;width:100%;-webkit-overflow-scrolling:touch}.iziModal .iziModal-wrap{width:100%;position:relative;-webkit-overflow-scrolling:touch;overflow-scrolling:touch}.iziModal .iziModal-iframe{border:0;margin:0 0 -6px;width:100%;transition:height .3s ease}.iziModal-overlay{display:block;position:fixed;top:0;left:0;height:100%;width:100%}.iziModal-navigate{position:fixed;left:0;right:0;top:0;bottom:0;pointer-events:none}.iziModal-navigate-caption{position:absolute;left:10px;top:10px;color:#fff;line-height:16px;font-size:9px;font-family:'Lato',Arial;letter-spacing:.1em;text-indent:0;text-align:center;width:70px;padding:5px 0;text-transform:uppercase;display:none}.iziModal-navigate-caption::after,.iziModal-navigate-caption::before{position:absolute;top:2px;width:20px;height:20px;text-align:center;line-height:14px;font-size:12px;content:'';background-size:100%!important}.iziModal-navigate-caption:before{left:0;background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACwAAAAoCAYAAACFFRgXAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA4ZpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNi1jMTMyIDc5LjE1OTI4NCwgMjAxNi8wNC8xOS0xMzoxMzo0MCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDoyNmFjNjAyMy04OWU0LWE0NDAtYmMxMy1kOTA5MTQ3MmYzYjAiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6NDREQ0YwRjA1MzQzMTFFNkE5NUNDRDkyQzEwMzM5RTMiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6NDREQ0YwRUY1MzQzMTFFNkE5NUNDRDkyQzEwMzM5RTMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTUuNSAoV2luZG93cykiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDpmNmM0Nzk3Ni1mNzE3LTk5NDAtYTgyYS1mNTdjNmNiYmU0NWMiIHN0UmVmOmRvY3VtZW50SUQ9ImFkb2JlOmRvY2lkOnBob3Rvc2hvcDowZGVmYTEyZC01MzM0LTExZTYtYWRkYi04Y2NmYjI5ZTAxNjYiLz4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz7oo0ptAAACWklEQVR42uyZTWsTYRSFZybxo4kWk5g2NC5qTAU3Kq30A9udi1oXolV/hWuhv6R/Q6utioi4LbbVFHemamlRU0OCEk0wZjwXzwtDoBDopHMHcuFJMplZnLm5ue+589qu61qeOApyYAjEgG0FEyLqN/gKiqBuTtgewWlwCZw056xgwwirgU3wxSv4NJgCUV5YBRXQDEhsBJwCSSauBVZFdJRlIJk9Av7wbj577jDIOENtRmPVwcsw6KfAAvikRKzEDlhnhuU/lRPBWaa9wsxqC6ndPX7OiOA4D8qW3vjO9z7H0w3+KhZstNmOFbLoCQ6DYGmL+bAInmGfLFC4asFXwRJIgB+goVmw+I7HXO+/gevGnGgUPEGxktkSmAMbWmt4HDwBKS6XN1jDKrvEFYoVK7oLroE3h93Woh1eNwqWafJ/gQV65vM+ail34mc6EZwBK2CAx8fAIjjeBYMzDT4cVHCEXtRbRvEu/Nr9HCIOnGGp15vgEec9KYn74B0nAT/CZnv86FcNvwK3wENwAjwAs2Bbs5d4CW5zir0AXvv8p+tKH34B5lkW4h2egRHtbu05uMMHHWfB0zC4NRF5l09kzvE4rd2tyUJyjy4tz7akZqXbL8QETbJ/FsMgWOJtb6brCQ5YsBsC8Uab63DVkkgqFpzie93h8OhScFah2LTHi5ccWroaLd5l6//+hpYQoWP05LKqFs2WQYbTsNxAi+5fxpWmdfh7HS7XhwSzG+H3a2JnvZsyktmLbdOFhpDMvrf4sN1u2/aK0cwMcmYLcturweceW+CnOfFPgAEA8uWFFylBJYoAAAAASUVORK5CYII=) no-repeat 50% 50%}.iziModal-navigate-caption:after{right:0;background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACwAAAAoCAYAAACFFRgXAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAZdEVYdFNvZnR3YXJlAEFkb2JlIEltYWdlUmVhZHlxyWU8AAADhmlUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4gPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNS42LWMxMzIgNzkuMTU5Mjg0LCAyMDE2LzA0LzE5LTEzOjEzOjQwICAgICAgICAiPiA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPiA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyIgeG1wTU06T3JpZ2luYWxEb2N1bWVudElEPSJ4bXAuZGlkOjI2YWM2MDIzLTg5ZTQtYTQ0MC1iYzEzLWQ5MDkxNDcyZjNiMCIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDo0NERDRjBGMDUzNDMxMUU2QTk1Q0NEOTJDMTAzMzlFMyIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDo0NERDRjBFRjUzNDMxMUU2QTk1Q0NEOTJDMTAzMzlFMyIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ0MgMjAxNS41IChXaW5kb3dzKSI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOmY2YzQ3OTc2LWY3MTctOTk0MC1hODJhLWY1N2M2Y2JiZTQ1YyIgc3RSZWY6ZG9jdW1lbnRJRD0iYWRvYmU6ZG9jaWQ6cGhvdG9zaG9wOjBkZWZhMTJkLTUzMzQtMTFlNi1hZGRiLThjY2ZiMjllMDE2NiIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PuijSm0AAAKbSURBVFhH7ZnJj0xRGEerzFoIMTaCZmOIedhaiJj55yz8DaYdNhIJEUMQbCTG3rQ02hDSiEY553XdTpHS3nv96taV9ElO6lVt6peb7933fffVG41GrYW5uBaX4EysYzcw1Fd8hc/wM2a0Bl6Nm3BW9i0dDPsQX/olBF6FO72AH/gG3+N3jL3KBpqGC3ERTsGfeAsHDTyHi71oCXzBe/gaU2A5bscZOIxXTb8OLQNX9i6mElYsg/voqruwfQb2BhODWgqpMYDv0NLsNXC4yd42P1PEwNJj4HBTWdipErLVDfxfMRm408QMvBu3jV6WJ1Zg9/rbeBOP+UNZYgX+iE/Rp+lpPIKliBXYB9IhtPNy3z/T/F6YmDXsChvyBc7Gs3gACxEzsDzBg9iPPXgO92NuYgeWx2h3+AhtaM7jPsyF7aV37XR8gNZYO/pwKY51+xPkG27Fk2joT3gCr2A7NuJ6HMkTeAPadlp3VeMChF7G0P6X3dmfjAXOUxIj6LZkv1ylNuStDZejkL+PS96ScFzRqnDAtI5PoTefvbg7iNNOOwqVRCfYghdxBbpHH8Y7+DcKlUTV7MLLaNghPIrjhf2N2IF34AVcjE44hrXHyE3MwE6/loEzpEcIlqKjeyFiBe7FS+he/gENewMLEyuwXdo8dGWP43UsRazA9g7uDNbwNX8oS8watlsz+ISIGbgSJgN3GgOHlnFq8zNFQraGgT1iFc9iUyU0XsMGHhy9zh6XbvCp4ZuBBWglDBj4OdqLeu0+uRJTwMZ+Dbp/e21P3m97yWe2snsw1LTHmz5C/9lQdwhfGbiq89GwvrrwUT4UAouhN6MzloTRpVuEYI5O9urZYXtrYPGQw2OlZegM163QhrJMfWVgyTq0Qq32C/N7uPz9OknWAAAAAElFTkSuQmCC) no-repeat 50% 50%}.iziModal-navigate>button{position:fixed;bottom:0;top:0;border:0;height:100%;width:84px;background-size:100%!important;cursor:pointer;padding:0;opacity:.2;transition:opacity .3s ease;pointer-events:all;margin:0;outline:0}.iziModal-navigate>button:hover{opacity:1}.iziModal-navigate-prev{left:50%;background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAALwAAAC8CAYAAADCScSrAAAACXBIWXMAAAsTAAALEwEAmpwYAAA5sGlUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4KPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNS42LWMxMzIgNzkuMTU5Mjg0LCAyMDE2LzA0LzE5LTEzOjEzOjQwICAgICAgICAiPgogICA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPgogICAgICA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIgogICAgICAgICAgICB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIKICAgICAgICAgICAgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiCiAgICAgICAgICAgIHhtbG5zOnN0RXZ0PSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VFdmVudCMiCiAgICAgICAgICAgIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyIKICAgICAgICAgICAgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIgogICAgICAgICAgICB4bWxuczpwaG90b3Nob3A9Imh0dHA6Ly9ucy5hZG9iZS5jb20vcGhvdG9zaG9wLzEuMC8iCiAgICAgICAgICAgIHhtbG5zOnRpZmY9Imh0dHA6Ly9ucy5hZG9iZS5jb20vdGlmZi8xLjAvIgogICAgICAgICAgICB4bWxuczpleGlmPSJodHRwOi8vbnMuYWRvYmUuY29tL2V4aWYvMS4wLyI+CiAgICAgICAgIDx4bXBNTTpPcmlnaW5hbERvY3VtZW50SUQ+eG1wLmRpZDo2NDkyYzcxMy05ZDM0LTZlNGQtYmUwNi1hMDMyY2Q4NDVjNGU8L3htcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD4KICAgICAgICAgPHhtcE1NOkRvY3VtZW50SUQ+eG1wLmRpZDo1QjIzMUMxODU3RjcxMUU2ODUzRkRBRjE5RDhDQjZBRDwveG1wTU06RG9jdW1lbnRJRD4KICAgICAgICAgPHhtcE1NOkluc3RhbmNlSUQ+eG1wLmlpZDpjZmMwNzVmNC1kODA3LWI0NDMtYWIwYS02YWVhZjRjMDgxZWE8L3htcE1NOkluc3RhbmNlSUQ+CiAgICAgICAgIDx4bXBNTTpEZXJpdmVkRnJvbSByZGY6cGFyc2VUeXBlPSJSZXNvdXJjZSI+CiAgICAgICAgICAgIDxzdFJlZjppbnN0YW5jZUlEPnhtcC5paWQ6NjQ5MmM3MTMtOWQzNC02ZTRkLWJlMDYtYTAzMmNkODQ1YzRlPC9zdFJlZjppbnN0YW5jZUlEPgogICAgICAgICAgICA8c3RSZWY6ZG9jdW1lbnRJRD54bXAuZGlkOjY0OTJjNzEzLTlkMzQtNmU0ZC1iZTA2LWEwMzJjZDg0NWM0ZTwvc3RSZWY6ZG9jdW1lbnRJRD4KICAgICAgICAgPC94bXBNTTpEZXJpdmVkRnJvbT4KICAgICAgICAgPHhtcE1NOkhpc3Rvcnk+CiAgICAgICAgICAgIDxyZGY6U2VxPgogICAgICAgICAgICAgICA8cmRmOmxpIHJkZjpwYXJzZVR5cGU9IlJlc291cmNlIj4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OmFjdGlvbj5zYXZlZDwvc3RFdnQ6YWN0aW9uPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6aW5zdGFuY2VJRD54bXAuaWlkOmNmYzA3NWY0LWQ4MDctYjQ0My1hYjBhLTZhZWFmNGMwODFlYTwvc3RFdnQ6aW5zdGFuY2VJRD4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OndoZW4+MjAxNi0wOC0wMVQxMTo1ODowNC0wMzowMDwvc3RFdnQ6d2hlbj4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OnNvZnR3YXJlQWdlbnQ+QWRvYmUgUGhvdG9zaG9wIENDIDIwMTUuNSAoV2luZG93cyk8L3N0RXZ0OnNvZnR3YXJlQWdlbnQ+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDpjaGFuZ2VkPi88L3N0RXZ0OmNoYW5nZWQ+CiAgICAgICAgICAgICAgIDwvcmRmOmxpPgogICAgICAgICAgICA8L3JkZjpTZXE+CiAgICAgICAgIDwveG1wTU06SGlzdG9yeT4KICAgICAgICAgPHhtcDpDcmVhdG9yVG9vbD5BZG9iZSBQaG90b3Nob3AgQ0MgMjAxNS41IChXaW5kb3dzKTwveG1wOkNyZWF0b3JUb29sPgogICAgICAgICA8eG1wOkNyZWF0ZURhdGU+MjAxNi0wOC0wMVQwOTo0MDo1Ni0wMzowMDwveG1wOkNyZWF0ZURhdGU+CiAgICAgICAgIDx4bXA6TW9kaWZ5RGF0ZT4yMDE2LTA4LTAxVDExOjU4OjA0LTAzOjAwPC94bXA6TW9kaWZ5RGF0ZT4KICAgICAgICAgPHhtcDpNZXRhZGF0YURhdGU+MjAxNi0wOC0wMVQxMTo1ODowNC0wMzowMDwveG1wOk1ldGFkYXRhRGF0ZT4KICAgICAgICAgPGRjOmZvcm1hdD5pbWFnZS9wbmc8L2RjOmZvcm1hdD4KICAgICAgICAgPHBob3Rvc2hvcDpDb2xvck1vZGU+MzwvcGhvdG9zaG9wOkNvbG9yTW9kZT4KICAgICAgICAgPHRpZmY6T3JpZW50YXRpb24+MTwvdGlmZjpPcmllbnRhdGlvbj4KICAgICAgICAgPHRpZmY6WFJlc29sdXRpb24+NzIwMDAwLzEwMDAwPC90aWZmOlhSZXNvbHV0aW9uPgogICAgICAgICA8dGlmZjpZUmVzb2x1dGlvbj43MjAwMDAvMTAwMDA8L3RpZmY6WVJlc29sdXRpb24+CiAgICAgICAgIDx0aWZmOlJlc29sdXRpb25Vbml0PjI8L3RpZmY6UmVzb2x1dGlvblVuaXQ+CiAgICAgICAgIDxleGlmOkNvbG9yU3BhY2U+NjU1MzU8L2V4aWY6Q29sb3JTcGFjZT4KICAgICAgICAgPGV4aWY6UGl4ZWxYRGltZW5zaW9uPjE4ODwvZXhpZjpQaXhlbFhEaW1lbnNpb24+CiAgICAgICAgIDxleGlmOlBpeGVsWURpbWVuc2lvbj4xODg8L2V4aWY6UGl4ZWxZRGltZW5zaW9uPgogICAgICA8L3JkZjpEZXNjcmlwdGlvbj4KICAgPC9yZGY6UkRGPgo8L3g6eG1wbWV0YT4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAKPD94cGFja2V0IGVuZD0idyI/PvAvv7QAAAAgY0hSTQAAeiUAAICDAAD5/wAAgOkAAHUwAADqYAAAOpgAABdvkl/FRgAAAmdJREFUeNrs1LsJQkEQhtH/mtmBgQ8QA7tQK1e7MBBBMbADwzUZEyuQveeDCXbD4TBDay3SWJpYgYCXgJeAl4CXgJeAl4CXgJeAl4CXgJeAF/AS8BLwEvAS8BLwEvAS8BLwEvAS8BLwAl4CXgJeAl4CXv/WJskpyQJ4jQH7Mcmu0C+BV+/Y5/VeF/oV8Ood+7dpDfDqHvsrySHJBXjBDrxgB16wAy/YgRfswAt24AU78IIdeMEOPOywAw+7gIcdeMEOvGAHXrADL9iBF+zAC3bgBTvwsMMOPOwCHnYBD7uAhx14wQ68YAdesAMv2IEX7MDDDjvwsAt42AU87AIedgEPu4CHXcDDDrxgB16wAw877MDDDjvwsAt42AU87AIedgEPu4CHXcDDLuBhB16wAw877MDDLuBhF/CwC3jYBTzsAh52AQ+7gIddwEtjB3+tS/78+Z/V5d9iATz0Ah56AQ+9gIdewEMv4KEX8NALeOgFPPQCHnoBDz3wgh54QQ889NADDz30wEMv4KEX8NALeOgFPPQCHnoBD72Ahx54QQ+8oAde0AMv6IEX9MBDDz3w0EMPPPQCHnoBD72Ah17AQw+8FUAPvKAHXtADL+iBF/TAC3rgBT3wgh546KEHHnrogYdewEMv4KEHXtADL+iBF/TAC3rgBT3wgh54QQ+8oAde0AMv6IGHHnrgoU/yrgFe3aO/JdknuQOv3tGfC/tjjEsYWmsoyIWXgJeAl4CXgJeAl4CXgJeAl4CXgJeAF/AS8BLwEvAS8BLwEvAS8BLwEvAS8BLwAl4CXgJeAl4CXvqnPgAAAP//AwCEcoCBRabYzAAAAABJRU5ErkJggg==) no-repeat 50% 50%}.iziModal-navigate-next{right:50%;background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAALwAAAC8CAYAAADCScSrAAAACXBIWXMAAB3SAAAd0gEUasEwAAA7pGlUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4KPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNS42LWMxMzIgNzkuMTU5Mjg0LCAyMDE2LzA0LzE5LTEzOjEzOjQwICAgICAgICAiPgogICA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPgogICAgICA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIgogICAgICAgICAgICB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iCiAgICAgICAgICAgIHhtbG5zOmRjPSJodHRwOi8vcHVybC5vcmcvZGMvZWxlbWVudHMvMS4xLyIKICAgICAgICAgICAgeG1sbnM6cGhvdG9zaG9wPSJodHRwOi8vbnMuYWRvYmUuY29tL3Bob3Rvc2hvcC8xLjAvIgogICAgICAgICAgICB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIKICAgICAgICAgICAgeG1sbnM6c3RFdnQ9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZUV2ZW50IyIKICAgICAgICAgICAgeG1sbnM6dGlmZj0iaHR0cDovL25zLmFkb2JlLmNvbS90aWZmLzEuMC8iCiAgICAgICAgICAgIHhtbG5zOmV4aWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20vZXhpZi8xLjAvIj4KICAgICAgICAgPHhtcDpDcmVhdG9yVG9vbD5BZG9iZSBQaG90b3Nob3AgQ0MgMjAxNS41IChXaW5kb3dzKTwveG1wOkNyZWF0b3JUb29sPgogICAgICAgICA8eG1wOkNyZWF0ZURhdGU+MjAxNi0wOC0wMVQwOTo0MDoxNC0wMzowMDwveG1wOkNyZWF0ZURhdGU+CiAgICAgICAgIDx4bXA6TW9kaWZ5RGF0ZT4yMDE2LTA4LTAxVDExOjU4OjEyLTAzOjAwPC94bXA6TW9kaWZ5RGF0ZT4KICAgICAgICAgPHhtcDpNZXRhZGF0YURhdGU+MjAxNi0wOC0wMVQxMTo1ODoxMi0wMzowMDwveG1wOk1ldGFkYXRhRGF0ZT4KICAgICAgICAgPGRjOmZvcm1hdD5pbWFnZS9wbmc8L2RjOmZvcm1hdD4KICAgICAgICAgPHBob3Rvc2hvcDpDb2xvck1vZGU+MzwvcGhvdG9zaG9wOkNvbG9yTW9kZT4KICAgICAgICAgPHhtcE1NOkluc3RhbmNlSUQ+eG1wLmlpZDphZjljN2Q2MC00MTg2LWE3NGQtYTBiMS1mMGU5ODUwYzg2ZGY8L3htcE1NOkluc3RhbmNlSUQ+CiAgICAgICAgIDx4bXBNTTpEb2N1bWVudElEPnhtcC5kaWQ6NjQ5MmM3MTMtOWQzNC02ZTRkLWJlMDYtYTAzMmNkODQ1YzRlPC94bXBNTTpEb2N1bWVudElEPgogICAgICAgICA8eG1wTU06T3JpZ2luYWxEb2N1bWVudElEPnhtcC5kaWQ6NjQ5MmM3MTMtOWQzNC02ZTRkLWJlMDYtYTAzMmNkODQ1YzRlPC94bXBNTTpPcmlnaW5hbERvY3VtZW50SUQ+CiAgICAgICAgIDx4bXBNTTpIaXN0b3J5PgogICAgICAgICAgICA8cmRmOlNlcT4KICAgICAgICAgICAgICAgPHJkZjpsaSByZGY6cGFyc2VUeXBlPSJSZXNvdXJjZSI+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDphY3Rpb24+Y3JlYXRlZDwvc3RFdnQ6YWN0aW9uPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6aW5zdGFuY2VJRD54bXAuaWlkOjY0OTJjNzEzLTlkMzQtNmU0ZC1iZTA2LWEwMzJjZDg0NWM0ZTwvc3RFdnQ6aW5zdGFuY2VJRD4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OndoZW4+MjAxNi0wOC0wMVQwOTo0MDoxNC0wMzowMDwvc3RFdnQ6d2hlbj4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OnNvZnR3YXJlQWdlbnQ+QWRvYmUgUGhvdG9zaG9wIENDIDIwMTUuNSAoV2luZG93cyk8L3N0RXZ0OnNvZnR3YXJlQWdlbnQ+CiAgICAgICAgICAgICAgIDwvcmRmOmxpPgogICAgICAgICAgICAgICA8cmRmOmxpIHJkZjpwYXJzZVR5cGU9IlJlc291cmNlIj4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OmFjdGlvbj5zYXZlZDwvc3RFdnQ6YWN0aW9uPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6aW5zdGFuY2VJRD54bXAuaWlkOjAxNjJjMmE3LWZmMjYtYzE0ZC05Yjg4LTc2MGM2NzAxYjYzNzwvc3RFdnQ6aW5zdGFuY2VJRD4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OndoZW4+MjAxNi0wOC0wMVQxMTo1MTowNy0wMzowMDwvc3RFdnQ6d2hlbj4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OnNvZnR3YXJlQWdlbnQ+QWRvYmUgUGhvdG9zaG9wIENDIDIwMTUuNSAoV2luZG93cyk8L3N0RXZ0OnNvZnR3YXJlQWdlbnQ+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDpjaGFuZ2VkPi88L3N0RXZ0OmNoYW5nZWQ+CiAgICAgICAgICAgICAgIDwvcmRmOmxpPgogICAgICAgICAgICAgICA8cmRmOmxpIHJkZjpwYXJzZVR5cGU9IlJlc291cmNlIj4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OmFjdGlvbj5zYXZlZDwvc3RFdnQ6YWN0aW9uPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6aW5zdGFuY2VJRD54bXAuaWlkOmFmOWM3ZDYwLTQxODYtYTc0ZC1hMGIxLWYwZTk4NTBjODZkZjwvc3RFdnQ6aW5zdGFuY2VJRD4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OndoZW4+MjAxNi0wOC0wMVQxMTo1ODoxMi0wMzowMDwvc3RFdnQ6d2hlbj4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OnNvZnR3YXJlQWdlbnQ+QWRvYmUgUGhvdG9zaG9wIENDIDIwMTUuNSAoV2luZG93cyk8L3N0RXZ0OnNvZnR3YXJlQWdlbnQ+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDpjaGFuZ2VkPi88L3N0RXZ0OmNoYW5nZWQ+CiAgICAgICAgICAgICAgIDwvcmRmOmxpPgogICAgICAgICAgICA8L3JkZjpTZXE+CiAgICAgICAgIDwveG1wTU06SGlzdG9yeT4KICAgICAgICAgPHRpZmY6T3JpZW50YXRpb24+MTwvdGlmZjpPcmllbnRhdGlvbj4KICAgICAgICAgPHRpZmY6WFJlc29sdXRpb24+MTkzOTAzNi8xMDAwMDwvdGlmZjpYUmVzb2x1dGlvbj4KICAgICAgICAgPHRpZmY6WVJlc29sdXRpb24+MTkzOTAzNi8xMDAwMDwvdGlmZjpZUmVzb2x1dGlvbj4KICAgICAgICAgPHRpZmY6UmVzb2x1dGlvblVuaXQ+MjwvdGlmZjpSZXNvbHV0aW9uVW5pdD4KICAgICAgICAgPGV4aWY6Q29sb3JTcGFjZT42NTUzNTwvZXhpZjpDb2xvclNwYWNlPgogICAgICAgICA8ZXhpZjpQaXhlbFhEaW1lbnNpb24+MTg4PC9leGlmOlBpeGVsWERpbWVuc2lvbj4KICAgICAgICAgPGV4aWY6UGl4ZWxZRGltZW5zaW9uPjE4ODwvZXhpZjpQaXhlbFlEaW1lbnNpb24+CiAgICAgIDwvcmRmOkRlc2NyaXB0aW9uPgogICA8L3JkZjpSREY+CjwveDp4bXBtZXRhPgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgIAo8P3hwYWNrZXQgZW5kPSJ3Ij8+nbt1mgAAACBjSFJNAAB6JQAAgIMAAPn/AACA6QAAdTAAAOpgAAA6mAAAF2+SX8VGAAACQklEQVR42uzSsQ3CQAAEQTdiOyGg/wrciJ0QUMYSECEKAP3PSdvAaZZqkWbJCQJeAl4CXgJeAl4CXgJeAl4CXgJeAl4CXsBLwEvAS8BLwEvAS8BLwEvAS8BLwEvAC3gJeAl4CXgJ+D9vrY7qBgLwo7dVZ+89oAd+5Pbq6nPQAz9s9+rZ96AHHnoBD72Ah17AQy/goRfw0At46AU89AIeegEPvYCHHnhBD7ygBx566IGHHnrgoRfw0At46AU89AIeegEPvYCHXsBDL+ChB17QAy/ogRf0wAt64KGHHnjooQceegEPvYCHXsBDL+ChF/DQAy/ogRf0wAt64AU98IIeeEEPvKAHXtADDz30wEPvI+ChF/DQAy/ogRf0wAt64AU98IIeeEEPvKAHXtADL+iBF/TAC3rgoZ8ePRDAAy/YgRfswAt24AU78IIdeMEOvGAHXrADL9iBhx124GEX8LADL9iBF+zAC3bgBTvwgh14wQ68YAcedtiBh13Awy7gYRfwsAMv2IEX7MALduAFO/CCHXjYYQcedgEPu4CHXcDDLuBhF/CwA+8E2IEX7MALduAFO/Cwww487AIedgEPu4CHXcDDLuBhF/CwC3jYgRfswMMOO/CwC3jYBTzsAh52AQ+7gIddwMMu4GEX8LBravB7dcEO/Ext1Qk78DO1VgfswEvAS8BLwEvAS8BLwEvAS8BLwEvAS8ALeAl4CXgJeAl4CXgJeAl4CXgJeAl4CXgBLwEvAS8BLwEvAS/9shcAAAD//wMAtAygvJrkwJUAAAAASUVORK5CYII=) no-repeat 50% 50%}.iziModal.isAttachedTop .iziModal-header{border-top-left-radius:0;border-top-right-radius:0}.iziModal.isAttachedTop{margin-top:0!important;margin-bottom:auto!important;border-top-left-radius:0!important;border-top-right-radius:0!important}.iziModal.isAttachedBottom{margin-top:auto!important;margin-bottom:0!important;border-bottom-left-radius:0!important;border-bottom-right-radius:0!important}.iziModal.isFullscreen{max-width:100%!important;margin:0!important;height:100%!important}.iziModal.isAttached,.iziModal.isFullscreen{border-radius:0!important}.iziModal.hasScroll .iziModal-wrap{overflow-y:auto;overflow-x:hidden}html.iziModal-isAttached,html.iziModal-isOverflow{overflow:hidden}html.iziModal-isAttached body,html.iziModal-isOverflow body{overflow-y:scroll;position:relative}.iziModal ::-webkit-scrollbar{overflow:visible;height:7px;width:7px}.iziModal ::-webkit-scrollbar-thumb{background-color:rgba(0,0,0,.2);background-clip:padding-box;border:solid transparent;border-width:0;min-height:28px;padding:100px 0 0;box-shadow:inset 1px 1px 0 rgba(0,0,0,.1),inset 0 -1px 0 rgba(0,0,0,.07)}.iziModal ::-webkit-scrollbar-thumb:active{background-color:rgba(0,0,0,.4)}.iziModal ::-webkit-scrollbar-button{height:0;width:0}.iziModal ::-webkit-scrollbar-track{background-clip:padding-box;border:solid transparent;border-width:0 0 0 2px}.iziModal.transitionIn .iziModal-header{-webkit-animation:iziM-slideDown .7s cubic-bezier(.7,0,.3,1);-moz-animation:iziM-slideDown .7s cubic-bezier(.7,0,.3,1);animation:iziM-slideDown .7s cubic-bezier(.7,0,.3,1)}.iziModal.transitionIn .iziModal-header .iziModal-header-icon{-webkit-animation:iziM-revealIn 1s cubic-bezier(.16,.81,.32,1) both;-moz-animation:iziM-revealIn 1s cubic-bezier(.16,.81,.32,1) both;animation:iziM-revealIn 1s cubic-bezier(.16,.81,.32,1) both}.iziModal.transitionIn .iziModal-header .iziModal-header-subtitle,.iziModal.transitionIn .iziModal-header .iziModal-header-title{-webkit-animation:iziM-slideIn 1s cubic-bezier(.16,.81,.32,1) both;-moz-animation:iziM-slideIn 1s cubic-bezier(.16,.81,.32,1) both;animation:iziM-slideIn 1s cubic-bezier(.16,.81,.32,1) both}.iziModal.transitionIn .iziModal-header .iziModal-button{-webkit-animation:iziM-revealIn 1.2s cubic-bezier(.7,0,.3,1);-moz-animation:iziM-revealIn 1.2s cubic-bezier(.7,0,.3,1);animation:iziM-revealIn 1.2s cubic-bezier(.7,0,.3,1)}.iziModal.transitionIn .iziModal-iframe,.iziModal.transitionIn .iziModal-wrap{-webkit-animation:iziM-fadeIn 1.3s;-moz-animation:iziM-fadeIn 1.3s;animation:iziM-fadeIn 1.3s}.iziModal.transitionIn .iziModal-header{-webkit-animation-delay:0s;-moz-animation:0s;animation-delay:0s}.iziModal.transitionIn .iziModal-header .iziModal-header-icon,.iziModal.transitionIn .iziModal-header .iziModal-header-title{-webkit-animation-delay:.4s;-moz-animation:.4s;animation-delay:.4s}.iziModal.transitionIn .iziModal-header .iziModal-header-subtitle{-webkit-animation-delay:.5s;-moz-animation:.5s;animation-delay:.5s}.iziModal.transitionOut .iziModal-header,.iziModal.transitionOut .iziModal-header *{transition:none!important}.iziModal .fadeOut,.iziModal-navigate.fadeOut,.iziModal-overlay.fadeOut,.iziModal.fadeOut{-webkit-animation:iziM-fadeOut .5s;-moz-animation:iziM-fadeOut .5s;animation:iziM-fadeOut .5s;animation-fill-mode:forwards}.iziModal .fadeIn,.iziModal-navigate.fadeIn,.iziModal-overlay.fadeIn,.iziModal.fadeIn{-webkit-animation:iziM-fadeIn .5s;-moz-animation:iziM-fadeIn .5s;animation:iziM-fadeIn .5s}.iziModal-overlay.comingIn,.iziModal.comingIn{-webkit-animation:iziM-comingIn .5s ease;-moz-animation:iziM-comingIn .5s ease;animation:iziM-comingIn .5s ease}.iziModal-overlay.comingOut,.iziModal.comingOut{-webkit-animation:iziM-comingOut .5s cubic-bezier(.16,.81,.32,1);-moz-animation:iziM-comingOut .5s cubic-bezier(.16,.81,.32,1);animation:iziM-comingOut .5s cubic-bezier(.16,.81,.32,1);animation-fill-mode:forwards}.iziModal-overlay.bounceInDown,.iziModal.bounceInDown{-webkit-animation:iziM-bounceInDown .7s ease;animation:iziM-bounceInDown .7s ease}.iziModal-overlay.bounceOutDown,.iziModal.bounceOutDown{-webkit-animation:iziM-bounceOutDown .7s ease;animation:iziM-bounceOutDown .7s ease}.iziModal-overlay.bounceInUp,.iziModal.bounceInUp{-webkit-animation:iziM-bounceInUp .7s ease;animation:iziM-bounceInUp .7s ease}.iziModal-overlay.bounceOutUp,.iziModal.bounceOutUp{-webkit-animation:iziM-bounceOutUp .7s ease;animation:iziM-bounceOutUp .7s ease}.iziModal-overlay.fadeInDown,.iziModal.fadeInDown{-webkit-animation:iziM-fadeInDown .7s cubic-bezier(.16,.81,.32,1);animation:iziM-fadeInDown .7s cubic-bezier(.16,.81,.32,1)}.iziModal-overlay.fadeOutDown,.iziModal.fadeOutDown{-webkit-animation:iziM-fadeOutDown .5s ease;animation:iziM-fadeOutDown .5s ease}.iziModal-overlay.fadeInUp,.iziModal.fadeInUp{-webkit-animation:iziM-fadeInUp .7s cubic-bezier(.16,.81,.32,1);animation:iziM-fadeInUp .7s cubic-bezier(.16,.81,.32,1)}.iziModal-overlay.fadeOutUp,.iziModal.fadeOutUp{-webkit-animation:iziM-fadeOutUp .5s ease;animation:iziM-fadeOutUp .5s ease}.iziModal-overlay.fadeInLeft,.iziModal.fadeInLeft{-webkit-animation:iziM-fadeInLeft .7s cubic-bezier(.16,.81,.32,1);animation:iziM-fadeInLeft .7s cubic-bezier(.16,.81,.32,1)}.iziModal-overlay.fadeOutLeft,.iziModal.fadeOutLeft{-webkit-animation:iziM-fadeOutLeft .5s ease;animation:iziM-fadeOutLeft .5s ease}.iziModal-overlay.fadeInRight,.iziModal.fadeInRight{-webkit-animation:iziM-fadeInRight .7s cubic-bezier(.16,.81,.32,1);animation:iziM-fadeInRight .7s cubic-bezier(.16,.81,.32,1)}.iziModal-overlay.fadeOutRight,.iziModal.fadeOutRight{-webkit-animation:iziM-fadeOutRight .5s ease;animation:iziM-fadeOutRight .5s ease}.iziModal-overlay.flipInX,.iziModal.flipInX{-webkit-animation:iziM-flipInX .7s ease;animation:iziM-flipInX .7s ease}.iziModal-overlay.flipOutX,.iziModal.flipOutX{-webkit-animation:iziM-flipOutX .7s ease;animation:iziM-flipOutX .7s ease}@-webkit-keyframes iziM-comingIn{0%{opacity:0;transform:scale(.9) translateY(-20px) perspective(600px) rotateX(10deg)}to{opacity:1;transform:scale(1) translateY(0) perspective(600px) rotateX(0)}}@-moz-keyframes iziM-comingIn{0%{opacity:0;transform:scale(.9) translateY(-20px) perspective(600px) rotateX(10deg)}to{opacity:1;transform:scale(1) translateY(0) perspective(600px) rotateX(0)}}@keyframes iziM-comingIn{0%{opacity:0;transform:scale(.9) translateY(-20px) perspective(600px) rotateX(10deg)}to{opacity:1;transform:scale(1) translateY(0) perspective(600px) rotateX(0)}}@-webkit-keyframes iziM-comingOut{0%{opacity:1;transform:scale(1)}to{opacity:0;transform:scale(.9)}}@-moz-keyframes iziM-comingOut{0%{opacity:1;transform:scale(1)}to{opacity:0;transform:scale(.9)}}@keyframes iziM-comingOut{0%{opacity:1;transform:scale(1)}to{opacity:0;transform:scale(.9)}}@-webkit-keyframes iziM-fadeOut{0%{opacity:1}to{opacity:0}}@-moz-keyframes iziM-fadeOut{0%{opacity:1}to{opacity:0}}@keyframes iziM-fadeOut{0%{opacity:1}to{opacity:0}}@-webkit-keyframes iziM-fadeIn{0%{opacity:0}to{opacity:1}}@-moz-keyframes iziM-fadeIn{0%{opacity:0}to{opacity:1}}@keyframes iziM-fadeIn{0%{opacity:0}to{opacity:1}}@-webkit-keyframes iziM-slideIn{0%{opacity:0;-webkit-transform:translateX(50px)}to{opacity:1;-webkit-transform:translateX(0)}}@-moz-keyframes iziM-slideIn{0%{opacity:0;-moz-transform:translateX(50px)}to{opacity:1;-moz-transform:translateX(0)}}@keyframes iziM-slideIn{0%{opacity:0;transform:translateX(50px)}to{opacity:1;transform:translateX(0)}}@-webkit-keyframes iziM-slideDown{0%{opacity:0;-webkit-transform:scale(1,0) translateY(-40px);-webkit-transform-origin:center top}}@-moz-keyframes iziM-slideDown{0%{opacity:0;-moz-transform:scale(1,0) translateY(-40px);-moz-transform-origin:center top}}@keyframes iziM-slideDown{0%{opacity:0;transform:scale(1,0) translateY(-40px);transform-origin:center top}}@-webkit-keyframes iziM-revealIn{0%{opacity:0;-webkit-transform:scale3d(.3,.3,1)}}@-moz-keyframes iziM-revealIn{0%{opacity:0;-moz-transform:scale3d(.3,.3,1)}}@keyframes iziM-revealIn{0%{opacity:0;transform:scale3d(.3,.3,1)}}@-webkit-keyframes iziM-bounceInDown{0%,60%,75%,90%,to{-webkit-animation-timing-function:cubic-bezier(.215,.61,.355,1);animation-timing-function:cubic-bezier(.215,.61,.355,1)}0%{opacity:0;-webkit-transform:translate3d(0,-1000px,0);transform:translate3d(0,-1000px,0)}60%{opacity:1;-webkit-transform:translate3d(0,25px,0);transform:translate3d(0,25px,0)}75%{-webkit-transform:translate3d(0,-10px,0);transform:translate3d(0,-10px,0)}90%{-webkit-transform:translate3d(0,5px,0);transform:translate3d(0,5px,0)}to{-webkit-transform:none;transform:none}}@keyframes iziM-bounceInDown{0%,60%,75%,90%,to{-webkit-animation-timing-function:cubic-bezier(.215,.61,.355,1);animation-timing-function:cubic-bezier(.215,.61,.355,1)}0%{opacity:0;-webkit-transform:translate3d(0,-1000px,0);transform:translate3d(0,-1000px,0)}60%{opacity:1;-webkit-transform:translate3d(0,25px,0);transform:translate3d(0,25px,0)}75%{-webkit-transform:translate3d(0,-10px,0);transform:translate3d(0,-10px,0)}90%{-webkit-transform:translate3d(0,5px,0);transform:translate3d(0,5px,0)}to{-webkit-transform:none;transform:none}}@-webkit-keyframes iziM-bounceOutDown{20%{-webkit-transform:translate3d(0,10px,0);transform:translate3d(0,10px,0)}40%,45%{opacity:1;-webkit-transform:translate3d(0,-20px,0);transform:translate3d(0,-20px,0)}to{opacity:0;-webkit-transform:translate3d(0,1000px,0);transform:translate3d(0,1000px,0)}}@keyframes iziM-bounceOutDown{20%{-webkit-transform:translate3d(0,10px,0);transform:translate3d(0,10px,0)}40%,45%{opacity:1;-webkit-transform:translate3d(0,-20px,0);transform:translate3d(0,-20px,0)}to{opacity:0;-webkit-transform:translate3d(0,1000px,0);transform:translate3d(0,1000px,0)}}@-webkit-keyframes iziM-bounceInUp{0%,60%,75%,90%,to{-webkit-animation-timing-function:cubic-bezier(.215,.61,.355,1);animation-timing-function:cubic-bezier(.215,.61,.355,1)}0%{opacity:0;-webkit-transform:translate3d(0,1000px,0);transform:translate3d(0,1000px,0)}60%{opacity:1;-webkit-transform:translate3d(0,-20px,0);transform:translate3d(0,-20px,0)}75%{-webkit-transform:translate3d(0,10px,0);transform:translate3d(0,10px,0)}90%{-webkit-transform:translate3d(0,-5px,0);transform:translate3d(0,-5px,0)}to{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}@keyframes iziM-bounceInUp{0%,60%,75%,90%,to{-webkit-animation-timing-function:cubic-bezier(.215,.61,.355,1);animation-timing-function:cubic-bezier(.215,.61,.355,1)}0%{opacity:0;-webkit-transform:translate3d(0,1000px,0);transform:translate3d(0,1000px,0)}60%{opacity:1;-webkit-transform:translate3d(0,-20px,0);transform:translate3d(0,-20px,0)}75%{-webkit-transform:translate3d(0,10px,0);transform:translate3d(0,10px,0)}90%{-webkit-transform:translate3d(0,-5px,0);transform:translate3d(0,-5px,0)}to{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}@-webkit-keyframes iziM-bounceOutUp{20%{-webkit-transform:translate3d(0,-10px,0);transform:translate3d(0,-10px,0)}40%,45%{opacity:1;-webkit-transform:translate3d(0,20px,0);transform:translate3d(0,20px,0)}to{opacity:0;-webkit-transform:translate3d(0,-2000px,0);transform:translate3d(0,-2000px,0)}}@keyframes iziM-bounceOutUp{20%{-webkit-transform:translate3d(0,-10px,0);transform:translate3d(0,-10px,0)}40%,45%{opacity:1;-webkit-transform:translate3d(0,20px,0);transform:translate3d(0,20px,0)}to{opacity:0;-webkit-transform:translate3d(0,-1000px,0);transform:translate3d(0,-1000px,0)}}@-webkit-keyframes iziM-fadeInDown{0%{opacity:0;-webkit-transform:translate3d(0,-100px,0);transform:translate3d(0,-100px,0)}to{opacity:1;-webkit-transform:none;transform:none}}@keyframes iziM-fadeInDown{0%{opacity:0;-webkit-transform:translate3d(0,-100px,0);transform:translate3d(0,-100px,0)}to{opacity:1;-webkit-transform:none;transform:none}}@-webkit-keyframes iziM-fadeOutDown{0%{opacity:1}to{opacity:0;-webkit-transform:translate3d(0,100px,0);transform:translate3d(0,100px,0)}}@keyframes iziM-fadeOutDown{0%{opacity:1}to{opacity:0;-webkit-transform:translate3d(0,100px,0);transform:translate3d(0,100px,0)}}@-webkit-keyframes iziM-fadeInUp{0%{opacity:0;-webkit-transform:translate3d(0,100px,0);transform:translate3d(0,100px,0)}to{opacity:1;-webkit-transform:none;transform:none}}@keyframes iziM-fadeInUp{0%{opacity:0;-webkit-transform:translate3d(0,100px,0);transform:translate3d(0,100px,0)}to{opacity:1;-webkit-transform:none;transform:none}}@-webkit-keyframes iziM-fadeOutUp{0%{opacity:1}to{opacity:0;-webkit-transform:translate3d(0,-100px,0);transform:translate3d(0,-100px,0)}}@keyframes iziM-fadeOutUp{0%{opacity:1}to{opacity:0;-webkit-transform:translate3d(0,-100px,0);transform:translate3d(0,-100px,0)}}@-webkit-keyframes iziM-fadeInLeft{0%{opacity:0;-webkit-transform:translate3d(-200px,0,0);transform:translate3d(-200px,0,0)}to{opacity:1;-webkit-transform:none;transform:none}}@keyframes iziM-fadeInLeft{0%{opacity:0;-webkit-transform:translate3d(-200px,0,0);transform:translate3d(-200px,0,0)}to{opacity:1;-webkit-transform:none;transform:none}}@-webkit-keyframes iziM-fadeOutLeft{0%{opacity:1}to{opacity:0;-webkit-transform:translate3d(-200px,0,0);transform:translate3d(-200px,0,0)}}@keyframes iziM-fadeOutLeft{0%{opacity:1}to{opacity:0;-webkit-transform:translate3d(-200px,0,0);transform:translate3d(-200px,0,0)}}@-webkit-keyframes iziM-fadeInRight{0%{opacity:0;-webkit-transform:translate3d(200px,0,0);transform:translate3d(200px,0,0)}to{opacity:1;-webkit-transform:none;transform:none}}@keyframes iziM-fadeInRight{0%{opacity:0;-webkit-transform:translate3d(200px,0,0);transform:translate3d(200px,0,0)}to{opacity:1;-webkit-transform:none;transform:none}}@-webkit-keyframes iziM-fadeOutRight{0%{opacity:1}to{opacity:0;-webkit-transform:translate3d(200px,0,0);transform:translate3d(200px,0,0)}}@keyframes iziM-fadeOutRight{0%{opacity:1}to{opacity:0;-webkit-transform:translate3d(200px,0,0);transform:translate3d(200px,0,0)}}@-webkit-keyframes iziM-flipInX{0%{-webkit-transform:perspective(400px) rotateX(60deg);opacity:0}40%{-webkit-transform:perspective(400px) rotateX(-10deg)}70%{-webkit-transform:perspective(400px) rotateX(10deg)}to{-webkit-transform:perspective(400px) rotateX(0deg);opacity:1}}@keyframes iziM-flipInX{0%{transform:perspective(400px) rotateX(60deg);opacity:0}40%{transform:perspective(400px) rotateX(-10deg)}70%{transform:perspective(400px) rotateX(10deg)}to{transform:perspective(400px) rotateX(0deg);opacity:1}}@-webkit-keyframes iziM-flipOutX{0%{-webkit-transform:perspective(400px);transform:perspective(400px)}30%{-webkit-transform:perspective(400px) rotate3d(1,0,0,-20deg);transform:perspective(400px) rotate3d(1,0,0,-20deg);opacity:1}to{-webkit-transform:perspective(400px) rotate3d(1,0,0,40deg);transform:perspective(400px) rotate3d(1,0,0,40deg);opacity:0}}@keyframes iziM-flipOutX{0%{-webkit-transform:perspective(400px);transform:perspective(400px)}30%{-webkit-transform:perspective(400px) rotate3d(1,0,0,-20deg);transform:perspective(400px) rotate3d(1,0,0,-20deg);opacity:1}to{-webkit-transform:perspective(400px) rotate3d(1,0,0,40deg);transform:perspective(400px) rotate3d(1,0,0,40deg);opacity:0}}
css/litespeed.css CHANGED
@@ -3,6 +3,15 @@
3
  content: '[' attr(litespeed-accesskey) '] ';
4
  }
5
 
 
 
 
 
 
 
 
 
 
6
  .litespeed-row {
7
  display: block;
8
  margin-top: 5px;
@@ -45,6 +54,7 @@
45
  margin-top: 30px;
46
  }
47
 
 
48
  .litespeed-left20 {
49
  margin-left: 20px;
50
  }
@@ -143,10 +153,13 @@ h3 .litespeed-learn-more {
143
  overflow: auto;
144
  padding: 10px 15px 15px 15px;
145
  position: relative;
146
- border-top: none;
147
  color: #264d73;
148
  }
149
 
 
 
 
 
150
  .litespeed-body code{
151
  color: #998c85 ;
152
  background-color: #dde9f5;
@@ -186,6 +199,7 @@ h3 .litespeed-learn-more {
186
  display: table;
187
  padding-right: 50px;
188
  padding-left: 3px;
 
189
  }
190
 
191
  .litespeed-title a,
@@ -388,6 +402,7 @@ h3 .litespeed-learn-more {
388
  }
389
 
390
  /********************************* btn *******************************/
 
391
  .litespeed-wrap [class*="litespeed-btn-"],
392
  [class*="litespeed-btn-"] {
393
  padding: 5px 10px;
@@ -404,6 +419,7 @@ h3 .litespeed-learn-more {
404
  height: initial;
405
  }
406
 
 
407
  .litespeed-wrap [class*="litespeed-btn-"]:hover,
408
  [class*="litespeed-btn-"]:hover {
409
  font-weight: 400;
@@ -413,6 +429,7 @@ h3 .litespeed-learn-more {
413
  box-shadow: none;
414
  }
415
 
 
416
  .litespeed-wrap .litespeed-btn-danger,
417
  .litespeed-btn-danger {
418
  color: #cc3d6a;
@@ -422,11 +439,13 @@ h3 .litespeed-learn-more {
422
  box-shadow: 0 0 0 1px rgba(204, 61, 106, 0.25);
423
  }
424
 
 
425
  .litespeed-wrap .litespeed-btn-danger:hover,
426
  .litespeed-btn-danger:hover {
427
  background: #cc3d6a;
428
  }
429
 
 
430
  .litespeed-wrap .litespeed-btn-warning,
431
  .litespeed-btn-warning {
432
  color: #e59544;
@@ -436,11 +455,13 @@ h3 .litespeed-learn-more {
436
  box-shadow: 0 0 0 1px rgba(230, 150, 69, 0.25);
437
  }
438
 
 
439
  .litespeed-wrap .litespeed-btn-warning:hover,
440
  .litespeed-btn-warning:hover {
441
  background: #e59544;
442
  }
443
 
 
444
  .litespeed-wrap .litespeed-btn-success,
445
  .litespeed-btn-success {
446
  color: #36b0b0;
@@ -450,11 +471,13 @@ h3 .litespeed-learn-more {
450
  box-shadow: 0 0 0 1px rgba(54, 176, 176, 0.25);
451
  }
452
 
 
453
  .litespeed-wrap .litespeed-btn-success:hover,
454
  .litespeed-btn-success:hover {
455
  background: #36b0b0;
456
  }
457
 
 
458
  .litespeed-wrap .litespeed-btn-primary,
459
  .litespeed-btn-primary {
460
  color: #538ac6;
@@ -464,12 +487,14 @@ h3 .litespeed-learn-more {
464
  box-shadow: 0 0 0 1px rgba(83, 138, 198, 0.25);
465
  }
466
 
 
467
  .litespeed-wrap .litespeed-btn-primary:hover,
468
  .litespeed-btn-primary:hover {
469
  background: #538ac6;
470
  border-color: #538ac6;
471
  }
472
 
 
473
  .litespeed-wrap .litespeed-btn-default,
474
  .litespeed-btn-default {
475
  color: #a7a7a7;
@@ -479,11 +504,13 @@ h3 .litespeed-learn-more {
479
  box-shadow: 0 0 0 1px rgba(158, 158, 158, 0.25);
480
  }
481
 
 
482
  .litespeed-wrap .litespeed-btn-default:hover,
483
  .litespeed-btn-default:hover {
484
  background: #a7a7a7;
485
  }
486
 
 
487
  .litespeed-wrap .litespeed-btn-default.disabled:hover,
488
  .litespeed-btn-default.disabled:hover {
489
  color: #a7a7a7;
@@ -496,6 +523,7 @@ h3 .litespeed-learn-more {
496
  border-color: #adadad;
497
  }
498
 
 
499
  .litespeed-wrap .litespeed-btn-xs,
500
  .litespeed-btn-xs {
501
  padding: 1px 8px;
@@ -505,6 +533,7 @@ h3 .litespeed-learn-more {
505
  min-width: 100px;
506
  }
507
 
 
508
  .litespeed-wrap .litespeed-btn-tiny,
509
  .litespeed-btn-tiny {
510
  padding: 1px 8px;
@@ -1233,12 +1262,9 @@ g.litespeed-pie_info text{
1233
  text-anchor: middle;
1234
  }
1235
 
1236
- /********************************* multiple cdn mapping styling *******************************/
1237
- [data-litespeed-cdn-mapping]:first-child [data-litespeed-cdn-mapping-del]{
1238
- display: none;
1239
- }
1240
-
1241
- .litespeed-cdn-mapping-block {
1242
  border: 1px dotted #6699cc;
1243
  border-radius:5px;
1244
  display: flex;
@@ -1247,6 +1273,37 @@ g.litespeed-pie_info text{
1247
  margin-bottom: 5px;
1248
  }
1249
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1250
  .litespeed-cdn-mapping-col1 {
1251
  flex: 0 0 35%;
1252
  padding-left: 17px;
@@ -1299,28 +1356,6 @@ g.litespeed-pie_info text{
1299
  margin-right: 10px;
1300
  }
1301
 
1302
- .litespeed-child-col{
1303
- flex: 0 0 30%;
1304
- padding-left: 17px;
1305
- }
1306
-
1307
- .litespeed-child-col-auto{
1308
- padding-left: 17px;
1309
- }
1310
-
1311
- .litespeed-child-col-br{
1312
- flex: 0 0 100% ;
1313
- border-top: 1px dotted #6699cc;
1314
- }
1315
-
1316
- .litespeed-child-col-inc{
1317
- display: inline-block;
1318
- margin-top: 16px ;
1319
- min-width: 150px ;
1320
- font-weight: bold;
1321
- }
1322
-
1323
-
1324
  /********************************* toggle *******************************/
1325
 
1326
  .litespeed-toggle {
@@ -1475,7 +1510,77 @@ g.litespeed-pie_info text{
1475
  top: -7px ;
1476
  }
1477
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1478
  /********************************* todo *******************************/
 
1479
  /* input field */
1480
  .litespeed-textarea {
1481
  width: 60% ;
@@ -1527,7 +1632,9 @@ g.litespeed-pie_info text{
1527
  margin-top: 0;
1528
  }
1529
 
1530
- .litespeed-body input,.litespeed-body textarea {
 
 
1531
  border: 1px solid #6699cc;
1532
  border-radius: 3px;
1533
  background: #fff;
@@ -1537,6 +1644,7 @@ g.litespeed-pie_info text{
1537
  font-family: "Open Sans", Arial, sans-serif;
1538
  }
1539
 
 
1540
  .litespeed-regular-text {
1541
  padding-left: 5px;
1542
  width: 25em;
@@ -1544,6 +1652,10 @@ g.litespeed-pie_info text{
1544
  font-family: "Open Sans", Arial, sans-serif;
1545
  }
1546
 
 
 
 
 
1547
  .litespeed-input-long {
1548
  width: 99%;
1549
  }
3
  content: '[' attr(litespeed-accesskey) '] ';
4
  }
5
 
6
+ .litespeed-modal{
7
+ margin-top: -8px;
8
+ }
9
+
10
+ .litespeed-modal .litespeed-progress{
11
+ margin-left: -8px;
12
+ margin-right: -8px;
13
+ }
14
+
15
  .litespeed-row {
16
  display: block;
17
  margin-top: 5px;
54
  margin-top: 30px;
55
  }
56
 
57
+ .litespeed-wrap .litespeed-left20,
58
  .litespeed-left20 {
59
  margin-left: 20px;
60
  }
153
  overflow: auto;
154
  padding: 10px 15px 15px 15px;
155
  position: relative;
 
156
  color: #264d73;
157
  }
158
 
159
+ .litespeed-header + .litespeed-body {
160
+ border-top: none;
161
+ }
162
+
163
  .litespeed-body code{
164
  color: #998c85 ;
165
  background-color: #dde9f5;
199
  display: table;
200
  padding-right: 50px;
201
  padding-left: 3px;
202
+ padding-bottom: 3px;
203
  }
204
 
205
  .litespeed-title a,
402
  }
403
 
404
  /********************************* btn *******************************/
405
+ .litespeed [class*="litespeed-btn-"],
406
  .litespeed-wrap [class*="litespeed-btn-"],
407
  [class*="litespeed-btn-"] {
408
  padding: 5px 10px;
419
  height: initial;
420
  }
421
 
422
+ .litespeed [class*="litespeed-btn-"]:hover,
423
  .litespeed-wrap [class*="litespeed-btn-"]:hover,
424
  [class*="litespeed-btn-"]:hover {
425
  font-weight: 400;
429
  box-shadow: none;
430
  }
431
 
432
+ .litespeed .litespeed-btn-danger,
433
  .litespeed-wrap .litespeed-btn-danger,
434
  .litespeed-btn-danger {
435
  color: #cc3d6a;
439
  box-shadow: 0 0 0 1px rgba(204, 61, 106, 0.25);
440
  }
441
 
442
+ .litespeed .litespeed-btn-danger:hover,
443
  .litespeed-wrap .litespeed-btn-danger:hover,
444
  .litespeed-btn-danger:hover {
445
  background: #cc3d6a;
446
  }
447
 
448
+ .litespeed .litespeed-btn-warning,
449
  .litespeed-wrap .litespeed-btn-warning,
450
  .litespeed-btn-warning {
451
  color: #e59544;
455
  box-shadow: 0 0 0 1px rgba(230, 150, 69, 0.25);
456
  }
457
 
458
+ .litespeed .litespeed-btn-warning:hover,
459
  .litespeed-wrap .litespeed-btn-warning:hover,
460
  .litespeed-btn-warning:hover {
461
  background: #e59544;
462
  }
463
 
464
+ .litespeed .litespeed-btn-success,
465
  .litespeed-wrap .litespeed-btn-success,
466
  .litespeed-btn-success {
467
  color: #36b0b0;
471
  box-shadow: 0 0 0 1px rgba(54, 176, 176, 0.25);
472
  }
473
 
474
+ .litespeed .litespeed-btn-success:hover,
475
  .litespeed-wrap .litespeed-btn-success:hover,
476
  .litespeed-btn-success:hover {
477
  background: #36b0b0;
478
  }
479
 
480
+ .litespeed .litespeed-btn-primary,
481
  .litespeed-wrap .litespeed-btn-primary,
482
  .litespeed-btn-primary {
483
  color: #538ac6;
487
  box-shadow: 0 0 0 1px rgba(83, 138, 198, 0.25);
488
  }
489
 
490
+ .litespeed .litespeed-btn-primary:hover,
491
  .litespeed-wrap .litespeed-btn-primary:hover,
492
  .litespeed-btn-primary:hover {
493
  background: #538ac6;
494
  border-color: #538ac6;
495
  }
496
 
497
+ .litespeed .litespeed-btn-default,
498
  .litespeed-wrap .litespeed-btn-default,
499
  .litespeed-btn-default {
500
  color: #a7a7a7;
504
  box-shadow: 0 0 0 1px rgba(158, 158, 158, 0.25);
505
  }
506
 
507
+ .litespeed .litespeed-btn-default:hover,
508
  .litespeed-wrap .litespeed-btn-default:hover,
509
  .litespeed-btn-default:hover {
510
  background: #a7a7a7;
511
  }
512
 
513
+ .litespeed .litespeed-btn-default.disabled:hover,
514
  .litespeed-wrap .litespeed-btn-default.disabled:hover,
515
  .litespeed-btn-default.disabled:hover {
516
  color: #a7a7a7;
523
  border-color: #adadad;
524
  }
525
 
526
+ .litespeed .litespeed-btn-xs,
527
  .litespeed-wrap .litespeed-btn-xs,
528
  .litespeed-btn-xs {
529
  padding: 1px 8px;
533
  min-width: 100px;
534
  }
535
 
536
+ .litespeed .litespeed-btn-tiny,
537
  .litespeed-wrap .litespeed-btn-tiny,
538
  .litespeed-btn-tiny {
539
  padding: 1px 8px;
1262
  text-anchor: middle;
1263
  }
1264
 
1265
+ /********************************* block and columns *******************************/
1266
+ .litespeed-block,
1267
+ .litespeed-block-tiny {
 
 
 
1268
  border: 1px dotted #6699cc;
1269
  border-radius:5px;
1270
  display: flex;
1273
  margin-bottom: 5px;
1274
  }
1275
 
1276
+ .litespeed-block-tiny {
1277
+ max-width: 670px ;
1278
+ }
1279
+
1280
+ .litespeed-col{
1281
+ flex: 0 0 30%;
1282
+ padding-left: 17px;
1283
+ }
1284
+
1285
+ .litespeed-col-auto{
1286
+ padding-left: 17px;
1287
+ }
1288
+
1289
+ .litespeed-col-br{
1290
+ flex: 0 0 100% ;
1291
+ border-top: 1px dotted #6699cc;
1292
+ }
1293
+
1294
+ .litespeed-col-inc{
1295
+ display: inline-block;
1296
+ margin-top: 16px ;
1297
+ min-width: 150px ;
1298
+ font-weight: bold;
1299
+ }
1300
+
1301
+
1302
+ /********************************* multiple cdn mapping styling *******************************/
1303
+ [data-litespeed-cdn-mapping]:first-child [data-litespeed-cdn-mapping-del]{
1304
+ display: none;
1305
+ }
1306
+
1307
  .litespeed-cdn-mapping-col1 {
1308
  flex: 0 0 35%;
1309
  padding-left: 17px;
1356
  margin-right: 10px;
1357
  }
1358
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1359
  /********************************* toggle *******************************/
1360
 
1361
  .litespeed-toggle {
1510
  top: -7px ;
1511
  }
1512
 
1513
+ /********************************* Progress bar *******************************/
1514
+ .litespeed-progress-bar {
1515
+ display: -webkit-box;
1516
+ display: -ms-flexbox;
1517
+ display: flex;
1518
+ -webkit-box-orient: vertical;
1519
+ -webkit-box-direction: normal;
1520
+ -ms-flex-direction: column;
1521
+ flex-direction: column;
1522
+ -webkit-box-pack: center;
1523
+ -ms-flex-pack: center;
1524
+ justify-content: center;
1525
+ color: #fff;
1526
+ text-align: center;
1527
+ background-color: #007bff;
1528
+ transition: width .6s ease;
1529
+ }
1530
+
1531
+ .litespeed-progress {
1532
+ display: -webkit-box;
1533
+ display: -ms-flexbox;
1534
+ display: flex;
1535
+ height: 2px;
1536
+ overflow: hidden;
1537
+ font-size: .75rem;
1538
+ background-color: #e9ecef;
1539
+ }
1540
+
1541
+ /********************************* form input *******************************/
1542
+ input.litespeed-input[type="file"]{
1543
+ padding: 9px ;
1544
+ min-width: 500px ;
1545
+ }
1546
+
1547
+ /********************************* guidance *******************************/
1548
+ .litespeed-guide {
1549
+ border:1px solid #73b38d;
1550
+ max-width: 50%;
1551
+ padding: 20px;
1552
+ }
1553
+
1554
+ .litespeed-guide h2 {
1555
+ color: #73b38d;
1556
+ border-bottom:1px solid #73b38d;
1557
+ display: table;
1558
+ padding-right: 50px;
1559
+ padding-left: 3px;
1560
+ padding-bottom: 3px;
1561
+ }
1562
+
1563
+ .litespeed-guide li {
1564
+ font-size: 15px;
1565
+ line-height: 30px;
1566
+ margin: 10px 10px 10px 16px ;
1567
+ }
1568
+
1569
+ .litespeed-guide li.litespeed-guide-done:before{
1570
+ content: '\2713' ;
1571
+ font-size: 26px ;
1572
+ color: #73b38d ;
1573
+ margin-left: -37px ;
1574
+ margin-right: 18px ;
1575
+ opacity: 1 ;
1576
+ }
1577
+
1578
+ .litespeed-guide li.litespeed-guide-done {
1579
+ opacity: .9 ;
1580
+ }
1581
+
1582
  /********************************* todo *******************************/
1583
+
1584
  /* input field */
1585
  .litespeed-textarea {
1586
  width: 60% ;
1632
  margin-top: 0;
1633
  }
1634
 
1635
+ .litespeed input,
1636
+ .litespeed-body input,
1637
+ .litespeed-body textarea {
1638
  border: 1px solid #6699cc;
1639
  border-radius: 3px;
1640
  background: #fff;
1644
  font-family: "Open Sans", Arial, sans-serif;
1645
  }
1646
 
1647
+ .litespeed .litespeed-regular-text,
1648
  .litespeed-regular-text {
1649
  padding-left: 5px;
1650
  width: 25em;
1652
  font-family: "Open Sans", Arial, sans-serif;
1653
  }
1654
 
1655
+ .litespeed .litespeed-input-large {
1656
+ font-size: 20px ;
1657
+ }
1658
+
1659
  .litespeed-input-long {
1660
  width: 99%;
1661
  }
inc/activation.class.php CHANGED
@@ -119,6 +119,16 @@ class LiteSpeed_Cache_Activation
119
  $count++ ;
120
  }
121
  }
 
 
 
 
 
 
 
 
 
 
122
  if ( is_plugin_active_for_network( LSCWP_BASENAME ) ) {
123
  $count++ ;
124
  }
119
  $count++ ;
120
  }
121
  }
122
+
123
+ /**
124
+ * In case this is called outside the admin page
125
+ * @see https://codex.wordpress.org/Function_Reference/is_plugin_active_for_network
126
+ * @since 2.0
127
+ */
128
+ if ( ! function_exists( 'is_plugin_active_for_network' ) ) {
129
+ require_once( ABSPATH . '/wp-admin/includes/plugin.php' ) ;
130
+ }
131
+
132
  if ( is_plugin_active_for_network( LSCWP_BASENAME ) ) {
133
  $count++ ;
134
  }
inc/cdn.class.php CHANGED
@@ -80,21 +80,29 @@ class LiteSpeed_Cache_CDN
80
  }
81
  $this_url = $v[ LiteSpeed_Cache_Config::ITEM_CDN_MAPPING_URL ] ;
82
  $this_host = parse_url( $this_url, PHP_URL_HOST ) ;
 
83
  foreach ( $mapping_to_check as $to_check ) {
84
  if ( $v[ $to_check ] ) {
85
  LiteSpeed_Cache_Log::debug2( 'CDN: mapping ' . $to_check . ' -> ' . $this_url ) ;
86
- $this->cfg_cdn_mapping[ $to_check ] = $this_url ;
 
 
 
87
  if ( ! in_array( $this_host, $this->cdn_mapping_hosts ) ) {
88
  $this->cdn_mapping_hosts[] = $this_host ;
89
  }
90
  }
91
  }
 
92
  if ( $v[ LiteSpeed_Cache_Config::ITEM_CDN_MAPPING_FILETYPE ] ) {
93
  $filetypes = array_map( 'trim', explode( "\n", $v[ LiteSpeed_Cache_Config::ITEM_CDN_MAPPING_FILETYPE ] ) ) ;
94
  foreach ( $filetypes as $v2 ) {
95
  if ( $v2 ) {
96
  $this->cfg_cdn_mapping[ LiteSpeed_Cache_Config::ITEM_CDN_MAPPING_FILETYPE ] = true ;
97
- $this->cfg_cdn_mapping[ $v2 ] = $this_url ;
 
 
 
98
  if ( ! in_array( $this_host, $this->cdn_mapping_hosts ) ) {
99
  $this->cdn_mapping_hosts[] = $this_host ;
100
  }
@@ -141,6 +149,28 @@ class LiteSpeed_Cache_CDN
141
 
142
  }
143
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
144
  /**
145
  * Handle all request actions from main cls
146
  *
@@ -515,6 +545,11 @@ class LiteSpeed_Cache_CDN
515
  $final_url = $this->cfg_cdn_mapping[ $postfix ] ;
516
  }
517
 
 
 
 
 
 
518
  // Now lets replace CDN url
519
  if ( strpos( $this->cfg_url_ori, '*' ) !== false ) {
520
  $url = preg_replace( '#' . $scheme . $this->cfg_url_ori . '#iU', $final_url, $url ) ;
80
  }
81
  $this_url = $v[ LiteSpeed_Cache_Config::ITEM_CDN_MAPPING_URL ] ;
82
  $this_host = parse_url( $this_url, PHP_URL_HOST ) ;
83
+ // Check img/css/js
84
  foreach ( $mapping_to_check as $to_check ) {
85
  if ( $v[ $to_check ] ) {
86
  LiteSpeed_Cache_Log::debug2( 'CDN: mapping ' . $to_check . ' -> ' . $this_url ) ;
87
+
88
+ // If filetype to url is one to many, make url be an array
89
+ $this->_append_cdn_mapping( $to_check, $this_url ) ;
90
+
91
  if ( ! in_array( $this_host, $this->cdn_mapping_hosts ) ) {
92
  $this->cdn_mapping_hosts[] = $this_host ;
93
  }
94
  }
95
  }
96
+ // Check file types
97
  if ( $v[ LiteSpeed_Cache_Config::ITEM_CDN_MAPPING_FILETYPE ] ) {
98
  $filetypes = array_map( 'trim', explode( "\n", $v[ LiteSpeed_Cache_Config::ITEM_CDN_MAPPING_FILETYPE ] ) ) ;
99
  foreach ( $filetypes as $v2 ) {
100
  if ( $v2 ) {
101
  $this->cfg_cdn_mapping[ LiteSpeed_Cache_Config::ITEM_CDN_MAPPING_FILETYPE ] = true ;
102
+
103
+ // If filetype to url is one to many, make url be an array
104
+ $this->_append_cdn_mapping( $v2, $this_url ) ;
105
+
106
  if ( ! in_array( $this_host, $this->cdn_mapping_hosts ) ) {
107
  $this->cdn_mapping_hosts[] = $this_host ;
108
  }
149
 
150
  }
151
 
152
+ /**
153
+ * Associate all filetypes with url
154
+ *
155
+ * @since 2.0
156
+ * @access private
157
+ */
158
+ private function _append_cdn_mapping( $filetype, $url )
159
+ {
160
+ // If filetype to url is one to many, make url be an array
161
+ if ( empty( $this->cfg_cdn_mapping[ $filetype ] ) ) {
162
+ $this->cfg_cdn_mapping[ $filetype ] = $url ;
163
+ }
164
+ elseif ( is_array( $this->cfg_cdn_mapping[ $filetype ] ) ) {
165
+ // Append url to filetype
166
+ $this->cfg_cdn_mapping[ $filetype ][] = $url ;
167
+ }
168
+ else {
169
+ // Convert cfg_cdn_mapping from string to array
170
+ $this->cfg_cdn_mapping[ $filetype ] = array( $this->cfg_cdn_mapping[ $filetype ], $url ) ;
171
+ }
172
+ }
173
+
174
  /**
175
  * Handle all request actions from main cls
176
  *
545
  $final_url = $this->cfg_cdn_mapping[ $postfix ] ;
546
  }
547
 
548
+ // If filetype to url is one to many, need to random one
549
+ if ( is_array( $final_url ) ) {
550
+ $final_url = $final_url[ mt_rand( 0, count( $final_url ) - 1 ) ] ;
551
+ }
552
+
553
  // Now lets replace CDN url
554
  if ( strpos( $this->cfg_url_ori, '*' ) !== false ) {
555
  $url = preg_replace( '#' . $scheme . $this->cfg_url_ori . '#iU', $final_url, $url ) ;
inc/config.class.php CHANGED
@@ -21,7 +21,7 @@ class LiteSpeed_Cache_Config
21
  const ITEM_OPTM_CSS = 'litespeed-optm-css' ;// separate critical css that should be stored in option table
22
  const ITEM_OPTM_JS_DEFER_EXC = 'litespeed-optm-js-defer-excludes' ;
23
  const ITEM_MEDIA_LAZY_IMG_EXC = 'litespeed-media-lazy-img-excludes' ;
24
- const ITEM_MEDIA_NEED_PULL = 'litespeed-media-need-pull' ;
25
  const ITEM_ENV_REF = 'litespeed-env-ref' ;
26
  const ITEM_CACHE_DROP_QS = 'litespeed-cache-drop_qs' ;
27
  const ITEM_CDN_MAPPING = 'litespeed-cache-cdn_mapping' ;
@@ -35,6 +35,7 @@ class LiteSpeed_Cache_Config
35
 
36
  const ITEM_SETTING_MODE = 'litespeed-setting-mode' ;
37
  const ITEM_CRAWLER_HASH = 'litespeed-crawler-hash' ;
 
38
 
39
  // Server variables
40
  const ENV_CRAWLER_USLEEP = 'CRAWLER_USLEEP' ;
@@ -200,6 +201,7 @@ class LiteSpeed_Cache_Config
200
  const CRWL_LOAD_LIMIT = 'crawler_load_limit' ;
201
  const CRWL_DOMAIN_IP = 'crawler_domain_ip' ;
202
  const CRWL_CUSTOM_SITEMAP = 'crawler_custom_sitemap' ;
 
203
 
204
  const CRWL_CRON_ACTIVE = 'crawler_cron_active' ;
205
 
@@ -271,12 +273,17 @@ class LiteSpeed_Cache_Config
271
  {
272
  $site_options = get_site_option( self::OPTION_NAME ) ;
273
 
274
- if ( ! function_exists('is_plugin_active_for_network') ) { // todo: check if needed
275
- require_once(ABSPATH . '/wp-admin/includes/plugin.php') ;
276
- }
277
-
278
  $options = get_option( self::OPTION_NAME, $this->get_default_options() ) ;
279
 
 
 
 
 
 
 
 
 
 
280
  // If don't have site options
281
  if ( ! $site_options || ! is_array( $site_options ) || ! is_plugin_active_for_network( 'litespeed-cache/litespeed-cache.php' ) ) {
282
  if ( $options[ self::OPID_ENABLED_RADIO ] === self::VAL_ON2 ) { // Default to cache on
@@ -661,6 +668,7 @@ class LiteSpeed_Cache_Config
661
  self::CRWL_DOMAIN_IP => '',
662
  self::CRWL_CUSTOM_SITEMAP => '',
663
  self::CRWL_CRON_ACTIVE => false,
 
664
  ) ;
665
 
666
  if ( LSWCP_ESI_SUPPORT ) {
@@ -891,6 +899,9 @@ class LiteSpeed_Cache_Config
891
  define( 'LSWCP_EMPTYCACHE', true ) ;// clear all sites caches
892
  LiteSpeed_Cache_Purge::purge_all() ;
893
  LiteSpeed_Cache_Log::debug( "Config: plugin_upgrade option changed = $res" ) ;
 
 
 
894
  }
895
 
896
  /**
21
  const ITEM_OPTM_CSS = 'litespeed-optm-css' ;// separate critical css that should be stored in option table
22
  const ITEM_OPTM_JS_DEFER_EXC = 'litespeed-optm-js-defer-excludes' ;
23
  const ITEM_MEDIA_LAZY_IMG_EXC = 'litespeed-media-lazy-img-excludes' ;
24
+ const ITEM_IMG_OPTM_NEED_PULL = 'litespeed-media-need-pull' ;
25
  const ITEM_ENV_REF = 'litespeed-env-ref' ;
26
  const ITEM_CACHE_DROP_QS = 'litespeed-cache-drop_qs' ;
27
  const ITEM_CDN_MAPPING = 'litespeed-cache-cdn_mapping' ;
35
 
36
  const ITEM_SETTING_MODE = 'litespeed-setting-mode' ;
37
  const ITEM_CRAWLER_HASH = 'litespeed-crawler-hash' ;
38
+ const ITEM_GUIDE = 'litespeed-guide' ; // Array of each guidance tag as key, step as val
39
 
40
  // Server variables
41
  const ENV_CRAWLER_USLEEP = 'CRAWLER_USLEEP' ;
201
  const CRWL_LOAD_LIMIT = 'crawler_load_limit' ;
202
  const CRWL_DOMAIN_IP = 'crawler_domain_ip' ;
203
  const CRWL_CUSTOM_SITEMAP = 'crawler_custom_sitemap' ;
204
+ const CRWL_HTTP2 = 'crawler_http2' ;
205
 
206
  const CRWL_CRON_ACTIVE = 'crawler_cron_active' ;
207
 
273
  {
274
  $site_options = get_site_option( self::OPTION_NAME ) ;
275
 
 
 
 
 
276
  $options = get_option( self::OPTION_NAME, $this->get_default_options() ) ;
277
 
278
+ /**
279
+ * In case this is called outside the admin page
280
+ * @see https://codex.wordpress.org/Function_Reference/is_plugin_active_for_network
281
+ * @since 2.0
282
+ */
283
+ if ( ! function_exists( 'is_plugin_active_for_network' ) ) {
284
+ require_once( ABSPATH . '/wp-admin/includes/plugin.php' ) ;
285
+ }
286
+
287
  // If don't have site options
288
  if ( ! $site_options || ! is_array( $site_options ) || ! is_plugin_active_for_network( 'litespeed-cache/litespeed-cache.php' ) ) {
289
  if ( $options[ self::OPID_ENABLED_RADIO ] === self::VAL_ON2 ) { // Default to cache on
668
  self::CRWL_DOMAIN_IP => '',
669
  self::CRWL_CUSTOM_SITEMAP => '',
670
  self::CRWL_CRON_ACTIVE => false,
671
+ self::CRWL_HTTP2 => true,
672
  ) ;
673
 
674
  if ( LSWCP_ESI_SUPPORT ) {
899
  define( 'LSWCP_EMPTYCACHE', true ) ;// clear all sites caches
900
  LiteSpeed_Cache_Purge::purge_all() ;
901
  LiteSpeed_Cache_Log::debug( "Config: plugin_upgrade option changed = $res" ) ;
902
+
903
+ // Update img_optm table data for upgrading
904
+ LiteSpeed_Cache_Data::get_instance() ;
905
  }
906
 
907
  /**
inc/crawler.class.php CHANGED
@@ -384,6 +384,8 @@ class LiteSpeed_Cache_Crawler
384
  $crawler->set_base_url($this->_home_url) ;
385
  $crawler->set_run_duration($options[LiteSpeed_Cache_Config::CRWL_RUN_DURATION]) ;
386
 
 
 
387
  /**
388
  * Limit delay to use server setting
389
  * @since 1.8.3
384
  $crawler->set_base_url($this->_home_url) ;
385
  $crawler->set_run_duration($options[LiteSpeed_Cache_Config::CRWL_RUN_DURATION]) ;
386
 
387
+ $crawler->set_http2( $options[ LiteSpeed_Cache_Config::CRWL_HTTP2 ] ) ;
388
+
389
  /**
390
  * Limit delay to use server setting
391
  * @since 1.8.3
inc/data.class.php CHANGED
@@ -15,9 +15,11 @@ class LiteSpeed_Cache_Data
15
  private static $_instance ;
16
 
17
  const TB_OPTIMIZER = 'litespeed_optimizer' ;
 
18
 
19
  private $_charset_collate ;
20
  private $_tb_optm ;
 
21
 
22
  /**
23
  * Init
@@ -33,8 +35,21 @@ class LiteSpeed_Cache_Data
33
  $this->_charset_collate = $wpdb->get_charset_collate() ;
34
 
35
  $this->_tb_optm = $wpdb->base_prefix . self::TB_OPTIMIZER ;
 
36
 
37
- $this->_optm_sync() ;
 
 
 
 
 
 
 
 
 
 
 
 
38
  }
39
 
40
  /**
@@ -61,13 +76,136 @@ class LiteSpeed_Cache_Data
61
  return $wpdb->get_var( "SHOW TABLES LIKE '$instance->_tb_optm'" ) ;
62
  }
63
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
64
  /**
65
  * Create optimizer table
66
  *
67
  * @since 1.3.1
68
  * @access private
69
  */
70
- private function _optm_sync()
71
  {
72
  if ( defined( 'LITESPEED_DID_' . __FUNCTION__ ) ) {
73
  return ;
@@ -76,32 +214,26 @@ class LiteSpeed_Cache_Data
76
 
77
  global $wpdb ;
78
 
79
- LiteSpeed_Cache_Log::debug2( 'Data: Checking optm table' ) ;
80
 
81
  // Check if table exists first
82
  if ( $wpdb->get_var( "SHOW TABLES LIKE '$this->_tb_optm'" ) ) {
83
- LiteSpeed_Cache_Log::debug2( 'Data: Existed' ) ;
84
  return ;
85
  }
86
 
87
- LiteSpeed_Cache_Log::debug( 'Data: Creating optm table' ) ;
88
 
89
  $sql = sprintf(
90
- 'CREATE TABLE IF NOT EXISTS `%1$s` (
91
- `id` int(11) NOT NULL AUTO_INCREMENT,
92
- `hash_name` varchar(60) NOT NULL COMMENT "hash.filetype",
93
- `src` text NOT NULL COMMENT "full url array set",
94
- `dateline` int(11) NOT NULL,
95
- `refer` varchar(255) NOT NULL COMMENT "The container page url",
96
- PRIMARY KEY (`id`),
97
- UNIQUE KEY `hash_name` (`hash_name`),
98
- KEY `dateline` (`dateline`)
99
- ) %2$s;',
100
  $this->_tb_optm,
101
  $this->_charset_collate
102
  ) ;
103
 
104
- $wpdb->query( $sql ) ;
 
 
 
105
 
106
  // Move data from wp_options to here
107
  $hashes = get_option( 'litespeed-cache-optimized' ) ;
@@ -169,7 +301,7 @@ class LiteSpeed_Cache_Data
169
  $sql = $wpdb->prepare( 'SELECT src FROM `' . $this->_tb_optm . '` WHERE `hash_name` = %s', $filename ) ;
170
  $res = $wpdb->get_var( $sql ) ;
171
 
172
- LiteSpeed_Cache_Log::debug2( 'Data: Loaded hash2src ' . $res ) ;
173
 
174
  $res = unserialize( $res ) ;
175
 
15
  private static $_instance ;
16
 
17
  const TB_OPTIMIZER = 'litespeed_optimizer' ;
18
+ const TB_IMG_OPTM = 'litespeed_img_optm' ;
19
 
20
  private $_charset_collate ;
21
  private $_tb_optm ;
22
+ private $_tb_img_optm ;
23
 
24
  /**
25
  * Init
35
  $this->_charset_collate = $wpdb->get_charset_collate() ;
36
 
37
  $this->_tb_optm = $wpdb->base_prefix . self::TB_OPTIMIZER ;
38
+ $this->_tb_img_optm = $wpdb->base_prefix . self::TB_IMG_OPTM ;
39
 
40
+ $this->_create_tb_img_optm() ;
41
+ $this->_create_tb_html_optm() ;
42
+ }
43
+
44
+ /**
45
+ * Get img_optm table name
46
+ *
47
+ * @since 2.0
48
+ * @access public
49
+ */
50
+ public static function get_tb_img_optm()
51
+ {
52
+ return self::get_instance()->_tb_img_optm ;
53
  }
54
 
55
  /**
76
  return $wpdb->get_var( "SHOW TABLES LIKE '$instance->_tb_optm'" ) ;
77
  }
78
 
79
+ /**
80
+ * Get data structure of one table
81
+ *
82
+ * @since 2.0
83
+ * @access private
84
+ */
85
+ private function _get_data_structure( $tb )
86
+ {
87
+ return Litespeed_File::read( LSCWP_DIR . 'inc/data_structure/' . $tb . '.sql' ) ;
88
+ }
89
+
90
+ /**
91
+ * Drop table img_optm
92
+ *
93
+ * @since 2.0
94
+ * @access private
95
+ */
96
+ public function delete_tb_img_optm()
97
+ {
98
+ global $wpdb ;
99
+
100
+ if ( ! $wpdb->get_var( "SHOW TABLES LIKE '$this->_tb_img_optm'" ) ) {
101
+ return ;
102
+ }
103
+
104
+ LiteSpeed_Cache_Log::debug( '[Data] Deleting img_optm table' ) ;
105
+
106
+ $q = "DROP TABLE IF EXISTS $this->_tb_img_optm" ;
107
+ $wpdb->query( $q ) ;
108
+
109
+ delete_option( $this->_tb_img_optm ) ;
110
+ }
111
+
112
+ /**
113
+ * Create img optm table and sync data from wp_postmeta
114
+ *
115
+ * @since 2.0
116
+ * @access private
117
+ */
118
+ private function _create_tb_img_optm()
119
+ {
120
+ if ( defined( 'LITESPEED_DID_' . __FUNCTION__ ) ) {
121
+ return ;
122
+ }
123
+ define( 'LITESPEED_DID_' . __FUNCTION__, true ) ;
124
+
125
+ global $wpdb ;
126
+
127
+ LiteSpeed_Cache_Log::debug2( '[Data] Checking img_optm table' ) ;
128
+
129
+ // Check if table exists first
130
+ if ( $wpdb->get_var( "SHOW TABLES LIKE '$this->_tb_img_optm'" ) ) {
131
+ LiteSpeed_Cache_Log::debug2( '[Data] Existed' ) ;
132
+ // return ;
133
+ }
134
+ else {
135
+ LiteSpeed_Cache_Log::debug( '[Data] Creating img_optm table' ) ;
136
+
137
+ $sql = sprintf(
138
+ 'CREATE TABLE IF NOT EXISTS `%1$s` (' . $this->_get_data_structure( 'img_optm' ) . ') %2$s;',
139
+ $this->_tb_img_optm,
140
+ $this->_charset_collate // 'DEFAULT CHARSET=utf8'
141
+ ) ;
142
+
143
+ $res = $wpdb->query( $sql ) ;
144
+ if ( $res !== true ) {
145
+ LiteSpeed_Cache_Log::debug( '[Data] Warning: Creating img_optm table failed!', $sql ) ;
146
+ }
147
+
148
+ // Clear OC to avoid get `_tb_img_optm` from option failed
149
+ if ( defined( 'LSCWP_OBJECT_CACHE' ) ) {
150
+ LiteSpeed_Cache_Object::get_instance()->flush() ;
151
+ }
152
+
153
+ }
154
+
155
+ // Table version only exists after all old data migrated
156
+ $ver = get_option( $this->_tb_img_optm ) ;
157
+ if ( $ver && LiteSpeed_Cache_API::v( $ver ) ) {
158
+ return ;
159
+ }
160
+
161
+ // Migrate data from `wp_postmeta` to `wp_litespeed_img_optm`
162
+ $mids_to_del = array() ;
163
+ $q = "SELECT * FROM $wpdb->postmeta WHERE meta_key = %s ORDER BY meta_id" ;
164
+ $meta_value_list = $wpdb->get_results( $wpdb->prepare( $q, array( LiteSpeed_Cache_Img_Optm::DB_IMG_OPTIMIZE_DATA ) ) ) ;
165
+ if ( $meta_value_list ) {
166
+ $max_k = count( $meta_value_list ) - 1 ;
167
+ foreach ( $meta_value_list as $k => $v ) {
168
+ $md52src_list = unserialize( $v->meta_value ) ;
169
+ foreach ( $md52src_list as $md5 => $v2 ) {
170
+ $f = array(
171
+ 'post_id' => $v->post_id,
172
+ 'optm_status' => $v2[ 1 ],
173
+ 'src' => $v2[ 0 ],
174
+ 'srcpath_md5' => md5( $v2[ 0 ] ),
175
+ 'src_md5' => $md5,
176
+ 'server' => $v2[ 2 ],
177
+ ) ;
178
+ $wpdb->replace( $this->_tb_img_optm, $f ) ;
179
+ }
180
+ $mids_to_del[] = $v->meta_id ;
181
+
182
+ // Delete from postmeta
183
+ if ( count( $mids_to_del ) > 100 || $k == $max_k ) {
184
+ $q = "DELETE FROM $wpdb->postmeta WHERE meta_id IN ( " . implode( ',', array_fill( 0, count( $mids_to_del ), '%s' ) ) . " ) " ;
185
+ $wpdb->query( $wpdb->prepare( $q, $mids_to_del ) ) ;
186
+
187
+ $mids_to_del = array() ;
188
+ }
189
+ }
190
+
191
+ LiteSpeed_Cache_Log::debug( '[Data] img_optm inserted records: ' . $k ) ;
192
+ }
193
+
194
+ $q = "DELETE FROM $wpdb->postmeta WHERE meta_key = %s" ;
195
+ $rows = $wpdb->query( $wpdb->prepare( $q, LiteSpeed_Cache_Img_Optm::DB_IMG_OPTIMIZE_STATUS ) ) ;
196
+ LiteSpeed_Cache_Log::debug( '[Data] img_optm delete optm_status records: ' . $rows ) ;
197
+
198
+ // Record tb version
199
+ update_option( $this->_tb_img_optm, LiteSpeed_Cache::PLUGIN_VERSION ) ;
200
+ }
201
+
202
  /**
203
  * Create optimizer table
204
  *
205
  * @since 1.3.1
206
  * @access private
207
  */
208
+ private function _create_tb_html_optm()
209
  {
210
  if ( defined( 'LITESPEED_DID_' . __FUNCTION__ ) ) {
211
  return ;
214
 
215
  global $wpdb ;
216
 
217
+ LiteSpeed_Cache_Log::debug2( '[Data] Checking html optm table' ) ;
218
 
219
  // Check if table exists first
220
  if ( $wpdb->get_var( "SHOW TABLES LIKE '$this->_tb_optm'" ) ) {
221
+ LiteSpeed_Cache_Log::debug2( '[Data] Existed' ) ;
222
  return ;
223
  }
224
 
225
+ LiteSpeed_Cache_Log::debug( '[Data] Creating html optm table' ) ;
226
 
227
  $sql = sprintf(
228
+ 'CREATE TABLE IF NOT EXISTS `%1$s` (' . $this->_get_data_structure( 'optm' ) . ') %2$s;',
 
 
 
 
 
 
 
 
 
229
  $this->_tb_optm,
230
  $this->_charset_collate
231
  ) ;
232
 
233
+ $res = $wpdb->query( $sql ) ;
234
+ if ( $res !== true ) {
235
+ LiteSpeed_Cache_Log::debug( '[Data] Warning: Creating html optm table failed!' ) ;
236
+ }
237
 
238
  // Move data from wp_options to here
239
  $hashes = get_option( 'litespeed-cache-optimized' ) ;
301
  $sql = $wpdb->prepare( 'SELECT src FROM `' . $this->_tb_optm . '` WHERE `hash_name` = %s', $filename ) ;
302
  $res = $wpdb->get_var( $sql ) ;
303
 
304
+ LiteSpeed_Cache_Log::debug2( '[Data] Loaded hash2src ' . $res ) ;
305
 
306
  $res = unserialize( $res ) ;
307
 
inc/data_structure/img_optm.sql ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
2
+ `post_id` bigint(20) unsigned NOT NULL DEFAULT '0',
3
+ `optm_status` varchar(255) NOT NULL DEFAULT '',
4
+ `src` varchar(1000) NOT NULL DEFAULT '',
5
+ `srcpath_md5` varchar(128) NOT NULL DEFAULT '',
6
+ `src_md5` varchar(128) NOT NULL DEFAULT '',
7
+ `server` varchar(255) NOT NULL DEFAULT '',
8
+ `root_id` int(11) NOT NULL DEFAULT '0',
9
+ `src_filesize` int(11) NOT NULL DEFAULT '0',
10
+ `target_filesize` int(11) NOT NULL DEFAULT '0',
11
+ `target_saved` int(11) NOT NULL DEFAULT '0',
12
+ `webp_filesize` int(11) NOT NULL DEFAULT '0',
13
+ `webp_saved` int(11) NOT NULL DEFAULT '0',
14
+ PRIMARY KEY (`id`),
15
+ UNIQUE KEY `post_id_2` (`post_id`,`srcpath_md5`),
16
+ KEY `post_id` (`post_id`),
17
+ KEY `optm_status` (`optm_status`),
18
+ KEY `root_id` (`root_id`),
19
+ KEY `src_md5` (`src_md5`),
20
+ KEY `srcpath_md5` (`srcpath_md5`)
inc/data_structure/optm.sql ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
1
+ `id` int(11) NOT NULL AUTO_INCREMENT,
2
+ `hash_name` varchar(60) NOT NULL COMMENT "hash.filetype",
3
+ `src` text NOT NULL COMMENT "full url array set",
4
+ `dateline` int(11) NOT NULL,
5
+ `refer` varchar(255) NOT NULL COMMENT "The container page url",
6
+ PRIMARY KEY (`id`),
7
+ UNIQUE KEY `hash_name` (`hash_name`),
8
+ KEY `dateline` (`dateline`)
inc/gui.class.php CHANGED
@@ -79,15 +79,17 @@ class LiteSpeed_Cache_GUI
79
  *
80
  * @since 1.6.6
81
  */
82
- public static function pie( $percent, $width = 50 )
83
  {
 
 
 
 
84
  return "
85
  <svg class='litespeed-pie' viewbox='0 0 33.83098862 33.83098862' width='$width' height='$width' xmlns='http://www.w3.org/2000/svg'>
86
  <circle class='litespeed-pie_bg' />
87
  <circle class='litespeed-pie_circle' stroke-dasharray='$percent,100' />
88
- <g class='litespeed-pie_info'>
89
- <text x='16.91549431' y='15.5'>$percent%</text>
90
- </g>
91
  </svg>
92
  ";
93
 
79
  *
80
  * @since 1.6.6
81
  */
82
+ public static function pie( $percent, $width = 50, $finished_tick = false )
83
  {
84
+ $percentage = '<text x="16.91549431" y="15.5">' . $percent . '%</text>' ;
85
+ if ( $percent == 100 && $finished_tick ) {
86
+ $percentage = '<text x="16.91549431" y="15.5" fill="#73b38d">&#x2713</text>' ;
87
+ }
88
  return "
89
  <svg class='litespeed-pie' viewbox='0 0 33.83098862 33.83098862' width='$width' height='$width' xmlns='http://www.w3.org/2000/svg'>
90
  <circle class='litespeed-pie_bg' />
91
  <circle class='litespeed-pie_circle' stroke-dasharray='$percent,100' />
92
+ <g class='litespeed-pie_info'>$percentage</g>
 
 
93
  </svg>
94
  ";
95
 
inc/img_optm.class.php ADDED
@@ -0,0 +1,1640 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * The class to optimize image.
5
+ *
6
+ * @since 2.0
7
+ * @package LiteSpeed_Cache
8
+ * @subpackage LiteSpeed_Cache/inc
9
+ * @author LiteSpeed Technologies <info@litespeedtech.com>
10
+ */
11
+
12
+ class LiteSpeed_Cache_Img_Optm
13
+ {
14
+ private static $_instance ;
15
+
16
+ const TYPE_SYNC_DATA = 'sync_data' ;
17
+ const TYPE_IMG_OPTIMIZE = 'img_optm' ;
18
+ const TYPE_IMG_OPTIMIZE_RESCAN = 'img_optm_rescan' ;
19
+ const TYPE_IMG_OPTIMIZE_DESTROY = 'img_optm_destroy' ;
20
+ const TYPE_IMG_PULL = 'img_pull' ;
21
+ const TYPE_IMG_BATCH_SWITCH_ORI = 'img_optm_batch_switch_ori' ;
22
+ const TYPE_IMG_BATCH_SWITCH_OPTM = 'img_optm_batch_switch_optm' ;
23
+
24
+ const ITEM_IMG_OPTM_CRON_RUN = 'litespeed-img_optm_cron_run' ; // last cron running time
25
+
26
+ const DB_IMG_OPTIMIZE_DESTROY = 'litespeed-optimize-destroy' ;
27
+ const DB_IMG_OPTIMIZE_DATA = 'litespeed-optimize-data' ;
28
+ const DB_IMG_OPTIMIZE_STATUS = 'litespeed-optimize-status' ;
29
+ const DB_IMG_OPTIMIZE_STATUS_REQUESTED = 'requested' ;
30
+ const DB_IMG_OPTIMIZE_STATUS_NOTIFIED = 'notified' ;
31
+ const DB_IMG_OPTIMIZE_STATUS_PULLED = 'pulled' ;
32
+ const DB_IMG_OPTIMIZE_STATUS_FAILED = 'failed' ;
33
+ const DB_IMG_OPTIMIZE_STATUS_MISS = 'miss' ;
34
+ const DB_IMG_OPTIMIZE_STATUS_ERR = 'err' ;
35
+ const DB_IMG_OPTIMIZE_SIZE = 'litespeed-optimize-size' ;
36
+
37
+ const DB_IMG_OPTM_SUMMARY = 'litespeed_img_optm_summary' ;
38
+
39
+ private $wp_upload_dir ;
40
+ private $tmp_pid ;
41
+ private $tmp_path ;
42
+ private $_img_in_queue = array() ;
43
+ private $_img_duplicated_in_queue = array() ;
44
+ private $_missed_img_in_queue = array() ;
45
+ private $_img_srcpath_md5_array = array() ;
46
+ private $_img_total = 0 ;
47
+ private $_table_img_optm ;
48
+ private $_cron_ran = false ;
49
+
50
+ /**
51
+ * Init
52
+ *
53
+ * @since 2.0
54
+ * @access private
55
+ */
56
+ private function __construct()
57
+ {
58
+ LiteSpeed_Cache_Log::debug2( 'ImgOptm init' ) ;
59
+
60
+ $this->wp_upload_dir = wp_upload_dir() ;
61
+ $this->_table_img_optm = LiteSpeed_Cache_Data::get_tb_img_optm() ;
62
+ }
63
+
64
+ /**
65
+ * Sync data from litespeed IAPI server
66
+ *
67
+ * @since 1.6.5
68
+ * @access private
69
+ */
70
+ private function _sync_data()
71
+ {
72
+ $json = LiteSpeed_Cache_Admin_API::post( LiteSpeed_Cache_Admin_API::IAPI_ACTION_MEDIA_SYNC_DATA ) ;
73
+
74
+ if ( ! is_array( $json ) ) {
75
+ LiteSpeed_Cache_Log::debug( '[Img_Optm] Failed to post to LiteSpeed IAPI server ', $json ) ;
76
+ $msg = __( 'Failed to communicate with LiteSpeed IAPI server', 'litespeed-cache' ) . ': ' . $json ;
77
+ LiteSpeed_Cache_Admin_Display::error( $msg ) ;
78
+ return ;
79
+ }
80
+
81
+ if ( ! empty( $json ) ) {
82
+ update_option( self::DB_IMG_OPTM_SUMMARY, $json ) ;
83
+ }
84
+
85
+ $msg = __( 'Communicated with LiteSpeed Image Optimization Server successfully.', 'litespeed-cache' ) ;
86
+ LiteSpeed_Cache_Admin_Display::succeed( $msg ) ;
87
+
88
+ // Update guidance
89
+ if ( ! empty( $json[ 'level' ] ) && $json[ 'level' ] > 1 ) {
90
+ $this->_update_guidance_pos( 'done' ) ;
91
+ }
92
+ elseif ( $this->get_guidance_pos() == 1 ) {
93
+ $this->_update_guidance_pos( 2 ) ;
94
+ }
95
+
96
+ LiteSpeed_Cache_Admin::redirect() ;
97
+
98
+ }
99
+
100
+ /**
101
+ * Push raw img to LiteSpeed IAPI server
102
+ *
103
+ * @since 1.6
104
+ * @access private
105
+ */
106
+ private function _request_optm()
107
+ {
108
+ global $wpdb ;
109
+
110
+ $_credit = (int) $this->summary_info( 'credit' ) ;
111
+ $credit_recovered = (int) $this->summary_info( 'credit_recovered' ) ;
112
+
113
+
114
+ LiteSpeed_Cache_Log::debug( '[Img_Optm] preparing images to push' ) ;
115
+
116
+ // Get images
117
+ $q = "SELECT b.post_id, b.meta_value
118
+ FROM $wpdb->posts a
119
+ LEFT JOIN $wpdb->postmeta b ON b.post_id = a.ID
120
+ LEFT JOIN $this->_table_img_optm c ON c.post_id = a.ID
121
+ WHERE a.post_type = 'attachment'
122
+ AND a.post_status = 'inherit'
123
+ AND a.post_mime_type IN ('image/jpeg', 'image/png')
124
+ AND b.meta_key = '_wp_attachment_metadata'
125
+ AND c.id IS NULL
126
+ ORDER BY a.ID DESC
127
+ LIMIT %d
128
+ " ;
129
+ $q = $wpdb->prepare( $q, apply_filters( 'litespeed_img_optimize_max_rows', 100 ) ) ;
130
+
131
+ $img_set = array() ;
132
+ $list = $wpdb->get_results( $q ) ;
133
+ if ( ! $list ) {
134
+ $msg = __( 'No image found.', 'litespeed-cache' ) ;
135
+ LiteSpeed_Cache_Admin_Display::succeed( $msg ) ;
136
+
137
+ LiteSpeed_Cache_Log::debug( '[Img_Optm] optimize bypass: no image found' ) ;
138
+ return ;
139
+ }
140
+
141
+ LiteSpeed_Cache_Log::debug( '[Img_Optm] found images: ' . count( $list ) ) ;
142
+
143
+ foreach ( $list as $v ) {
144
+
145
+ $meta_value = $this->_parse_wp_meta_value( $v ) ;
146
+ if ( ! $meta_value ) {
147
+ continue ;
148
+ }
149
+
150
+ /**
151
+ * Only send 500 images one time
152
+ * @since 1.6.3
153
+ * @since 1.6.5 use credit limit
154
+ */
155
+ $num_will_incease = 1 ;
156
+ if ( ! empty( $meta_value[ 'sizes' ] ) ) {
157
+ $num_will_incease += count( $meta_value[ 'sizes' ] ) ;
158
+ }
159
+ if ( $this->_img_total + $num_will_incease > $_credit ) {
160
+ if ( ! $this->_img_total ) {
161
+ $msg = sprintf( __( 'Number of images in one image group (%s) exceeds the credit (%s)', 'litespeed-cache' ), $num_will_incease, $_credit ) ;
162
+ LiteSpeed_Cache_Admin_Display::error( $msg ) ;
163
+ }
164
+ LiteSpeed_Cache_Log::debug( '[Img_Optm] img request hit limit: [total] ' . $this->_img_total . " \t[add] $num_will_incease \t[credit] $_credit" ) ;
165
+ break ;
166
+ }
167
+ /**
168
+ * Check if need to test run ( new user only allow 1 group at first time)
169
+ * @since 1.6.6.1
170
+ */
171
+ if ( $this->_img_total && ! $credit_recovered ) {
172
+ LiteSpeed_Cache_Log::debug( '[Img_Optm] test run only allow 1 group ' ) ;
173
+ break ;
174
+ }
175
+
176
+ // push orig image to queue
177
+ $this->tmp_pid = $v->post_id ;
178
+ $this->tmp_path = pathinfo( $meta_value[ 'file' ], PATHINFO_DIRNAME ) . '/' ;
179
+ $this->_img_queue( $meta_value, true ) ;
180
+ if ( ! empty( $meta_value[ 'sizes' ] ) ) {
181
+ array_map( array( $this, '_img_queue' ), $meta_value[ 'sizes' ] ) ;
182
+ }
183
+ }
184
+
185
+ // Save missed images into img_optm
186
+ $this->_save_missed_into_img_optm() ;
187
+
188
+ if ( empty( $this->_img_in_queue ) ) {
189
+ $msg = __( 'No image found.', 'litespeed-cache' ) ;
190
+ LiteSpeed_Cache_Admin_Display::succeed( $msg ) ;
191
+
192
+ LiteSpeed_Cache_Log::debug( '[Img_Optm] optimize bypass: empty _img_in_queue' ) ;
193
+ return ;
194
+ }
195
+
196
+ // Filtered from existing data
197
+ $this->_filter_existing_src() ;
198
+
199
+ /**
200
+ * Filter same src in $this->_img_in_queue
201
+ *
202
+ * 1. Save them to tmp array $this->_img_duplicated_in_queue
203
+ * 2. Remove them from $this->_img_in_queue
204
+ * 3. After inserted $this->_img_in_queue into img_optm, insert $this->_img_duplicated_in_queue into img_optm with root_id
205
+ */
206
+ $this->_filter_duplicated_src() ;
207
+
208
+ if ( empty( $this->_img_in_queue ) ) {
209
+ $msg = __( 'Optimized successfully.', 'litespeed-cache' ) ;
210
+ LiteSpeed_Cache_Admin_Display::succeed( $msg ) ;
211
+ return ;
212
+ }
213
+
214
+ $total_groups = count( $this->_img_in_queue ) ;
215
+ LiteSpeed_Cache_Log::debug( '[Img_Optm] prepared images to push: groups ' . $total_groups . ' images ' . $this->_img_total ) ;
216
+
217
+ // Push to LiteSpeed IAPI server
218
+ $json = $this->_push_img_in_queue_to_iapi() ;
219
+ if ( $json === null ) {
220
+ return ;
221
+ }
222
+ $pids = $json[ 'pids' ] ;
223
+
224
+ $data_to_add = array() ;
225
+ foreach ( $pids as $pid ) {
226
+ foreach ( $this->_img_in_queue[ $pid ] as $md5 => $src_data ) {
227
+ $data_to_add[] = $pid ;
228
+ $data_to_add[] = self::DB_IMG_OPTIMIZE_STATUS_REQUESTED ;
229
+ $data_to_add[] = $src_data[ 'src' ] ;
230
+ $data_to_add[] = $src_data[ 'srcpath_md5' ] ;
231
+ $data_to_add[] = $md5 ;
232
+ $data_to_add[] = $src_data[ 'src_filesize' ] ;
233
+ }
234
+ }
235
+ $this->_insert_img_optm( $data_to_add ) ;
236
+
237
+ // Insert duplicated data
238
+ if ( $this->_img_duplicated_in_queue ) {
239
+ // Generate root_id from inserted ones
240
+ $srcpath_md5_to_search = array() ;
241
+ foreach ( $this->_img_duplicated_in_queue as $v ) {
242
+ $srcpath_md5_to_search[] = $v[ 'info' ][ 'srcpath_md5' ] ;
243
+ }
244
+ $existing_img_list = $this->_select_img_by_root_srcpath( $srcpath_md5_to_search ) ;
245
+
246
+ $data_to_add = array() ;
247
+ foreach ( $this->_img_duplicated_in_queue as $v ) {
248
+ $existing_info = $existing_img_list[ $v[ 'info' ][ 'srcpath_md5' ] ] ;
249
+
250
+ $data_to_add[] = $v[ 'pid' ] ;
251
+ $data_to_add[] = $existing_info[ 'status' ] ;
252
+ $data_to_add[] = $existing_info[ 'src' ] ;
253
+ $data_to_add[] = $existing_info[ 'srcpath_md5' ] ;
254
+ $data_to_add[] = $existing_info[ 'src_md5' ] ;
255
+ $data_to_add[] = $existing_info[ 'src_filesize' ] ;
256
+ $data_to_add[] = $existing_info[ 'id' ] ;
257
+ }
258
+ $this->_insert_img_optm( $data_to_add, 'post_id, optm_status, src, srcpath_md5, src_md5, src_filesize, root_id' ) ;
259
+ }
260
+
261
+ $accepted_groups = count( $pids ) ;
262
+ $accepted_imgs = $json[ 'total' ] ;
263
+
264
+ $placeholder1 = LiteSpeed_Cache_Admin_Display::print_plural( $total_groups ) . ' (' . LiteSpeed_Cache_Admin_Display::print_plural( $this->_img_total, 'image' ) . ')' ;
265
+ $placeholder2 = LiteSpeed_Cache_Admin_Display::print_plural( $accepted_groups ) . ' (' . LiteSpeed_Cache_Admin_Display::print_plural( $accepted_imgs, 'image' ) . ')' ;
266
+ $msg = sprintf( __( 'Pushed %1$s to LiteSpeed optimization server, accepted %2$s.', 'litespeed-cache' ), $placeholder1, $placeholder2 ) ;
267
+ LiteSpeed_Cache_Admin_Display::succeed( $msg ) ;
268
+
269
+ // Update credit info
270
+ if ( isset( $json[ 'credit' ] ) ) {
271
+ $this->_update_credit( $json[ 'credit' ] ) ;
272
+ }
273
+
274
+ // Update guidance
275
+ if ( $this->get_guidance_pos() == 2 ) {
276
+ $this->_update_guidance_pos( 3 ) ;
277
+ }
278
+
279
+ }
280
+
281
+ /**
282
+ * Insert data into table img_optm
283
+ *
284
+ * @since 2.0
285
+ * @access private
286
+ */
287
+ private function _insert_img_optm( $data, $fields = 'post_id, optm_status, src, srcpath_md5, src_md5, src_filesize' )
288
+ {
289
+ global $wpdb ;
290
+
291
+ $division = substr_count( $fields, ',' ) + 1 ;
292
+
293
+ $q = "REPLACE INTO $this->_table_img_optm ( $fields ) VALUES " ;
294
+
295
+ // Add placeholder
296
+ $q .= $this->_chunk_placeholder( $data, $division ) ;
297
+
298
+ // Store data
299
+ $wpdb->query( $wpdb->prepare( $q, $data ) ) ;
300
+ }
301
+
302
+ /**
303
+ * Get all root img data by srcpath_md5
304
+ *
305
+ * @since 2.0
306
+ * @access private
307
+ */
308
+ private function _select_img_by_root_srcpath( $srcpath_md5_to_search )
309
+ {
310
+ global $wpdb ;
311
+
312
+ $existing_img_list = array() ;
313
+
314
+ $srcpath_md5_to_search = array_unique( $srcpath_md5_to_search ) ;
315
+
316
+ $q = "SELECT * FROM $this->_table_img_optm WHERE root_id=0 AND srcpath_md5 IN ( " . implode( ',', array_fill( 0, count( $srcpath_md5_to_search ), '%s' ) ) . " )" ;
317
+ $tmp = $wpdb->get_results( $wpdb->prepare( $q, $srcpath_md5_to_search ) ) ;
318
+ foreach ( $tmp as $v ) {
319
+ $existing_img_list[ $v->srcpath_md5 ] = array(
320
+ 'id' => $v->id,
321
+ 'status' => $v->optm_status,
322
+ 'pid' => $v->post_id,
323
+ 'src' => $v->src,
324
+ 'srcpath_md5' => $v->srcpath_md5,
325
+ 'src_md5' => $v->src_md5,
326
+ 'src_filesize' => $v->src_filesize,
327
+ ) ;
328
+ }
329
+
330
+ return $existing_img_list ;
331
+ }
332
+
333
+ /**
334
+ * Handle existing same src path images
335
+ *
336
+ * @since 2.0
337
+ * @access private
338
+ */
339
+ private function _filter_existing_src()
340
+ {
341
+ global $wpdb ;
342
+ // var_dump($this->_img_in_queue);
343
+ // var_dump($this->_img_srcpath_md5_array);
344
+ $existing_img_list = $this->_select_img_by_root_srcpath( $this->_img_srcpath_md5_array ) ;
345
+ // var_dump($existing_img_list);
346
+ // Handle existing same src data
347
+ $existing_img_optm = array() ;
348
+ $size_to_store = array() ;// pulled images need to update `wp_postmeta` size info
349
+ foreach ( $this->_img_in_queue as $pid => $img_list ) {
350
+ $changed = false ;
351
+ foreach ( $img_list as $md5 => $v ) {
352
+ if ( array_key_exists( $v[ 'srcpath_md5' ], $existing_img_list ) ) {
353
+ $existing_info = $existing_img_list[ $v[ 'srcpath_md5' ] ] ;
354
+
355
+ // Insert into img_optm table directly
356
+ $existing_img_optm[] = $pid ;
357
+ $existing_img_optm[] = $existing_info[ 'status' ] ;
358
+ $existing_img_optm[] = $existing_info[ 'src' ] ;
359
+ $existing_img_optm[] = $existing_info[ 'srcpath_md5' ] ;
360
+ $existing_img_optm[] = $existing_info[ 'src_md5' ] ;
361
+ $existing_img_optm[] = $existing_info[ 'src_filesize' ] ;
362
+ $existing_img_optm[] = $existing_info[ 'id' ] ;
363
+
364
+ // Bypass IAPI posting by removing from img_in_queue
365
+ unset( $this->_img_in_queue[ $pid ][ $md5 ] ) ;
366
+
367
+ // Size info exists. Prepare size info for `wp_postmeta`
368
+ // Only pulled images have size_info
369
+ if ( $existing_info[ 'status' ] == self::DB_IMG_OPTIMIZE_STATUS_PULLED ) {
370
+ $size_to_store[ $pid ] = $existing_info[ 'pid' ] ;
371
+ }
372
+
373
+ LiteSpeed_Cache_Log::debug( '[Img_Optm] Existing pulled [pid] ' . $pid . " \t\t\t[status] " . $existing_info[ 'status' ] . " \t\t\t[src] " . $v[ 'src' ] ) ;
374
+
375
+ $changed = true ;
376
+ }
377
+ }
378
+
379
+ if ( $changed ) {
380
+ if ( empty( $this->_img_in_queue[ $pid ] ) ) {
381
+ unset( $this->_img_in_queue[ $pid ] ) ;
382
+ }
383
+ }
384
+
385
+ }
386
+ // var_dump($this->_img_in_queue);
387
+ // var_dump($existing_img_list);
388
+ // var_dump($existing_img_optm);//exit;
389
+ // Existing img needs to be inserted separately
390
+ if ( $existing_img_optm ) {
391
+ $this->_insert_img_optm( $existing_img_optm, 'post_id, optm_status, src, srcpath_md5, src_md5, src_filesize, root_id' ) ;
392
+ }
393
+
394
+ // These post_meta in key need to update size info to same as post_meta in val
395
+ if ( $size_to_store ) {
396
+ // Get current data
397
+ $pids = array_unique( $size_to_store ) ;
398
+
399
+ LiteSpeed_Cache_Log::debug( '[Img_Optm] Existing size info root pids', $pids ) ;
400
+
401
+ // NOTE: Separate this query while not using LEFT JOIN in SELECT * FROM $this->_table_img_optm in previous query to lower db load
402
+ $q = "SELECT * FROM $wpdb->postmeta WHERE meta_key = %s AND post_id IN ( " . implode( ',', array_fill( 0, count( $pids ), '%s' ) ) . " )" ;
403
+ $tmp = $wpdb->get_results( $wpdb->prepare( $q, array_merge( array( self::DB_IMG_OPTIMIZE_SIZE ), $pids ) ) ) ;
404
+ $existing_sizes = array() ;
405
+ foreach ( $tmp as $v ) {
406
+ $existing_sizes[ $v->post_id ] = $v->meta_value ;
407
+ }
408
+
409
+ // Get existing new data
410
+ $size_to_store_pids = array_keys( $size_to_store ) ;
411
+ $q = "SELECT * FROM $wpdb->postmeta WHERE meta_key = %s AND post_id IN ( " . implode( ',', array_fill( 0, count( $size_to_store_pids ), '%s' ) ) . " )" ;
412
+ $tmp = $wpdb->get_results( $wpdb->prepare( $q, array_merge( array( self::DB_IMG_OPTIMIZE_SIZE ), $size_to_store_pids ) ) ) ;
413
+ $q_to_update = "UPDATE $wpdb->postmeta SET meta_value = %s WHERE meta_id = %d" ;
414
+ $size_to_update_pids = array() ;
415
+ foreach ( $tmp as $v ) {
416
+ $size_to_update_pids[] = $v->post_id ;
417
+ $from_pid = $size_to_store[ $v->post_id ] ;
418
+ // Update existing data ( Replaced with existing size info wholly )
419
+ $wpdb->query( $wpdb->prepare( $q_to_update, array( $existing_sizes[ $from_pid ], $v->meta_id ) ) ) ;
420
+
421
+ LiteSpeed_Cache_Log::debug( '[Img_Optm] Updated optm_size info [pid] ' . $v->post_id . " \t\t\t[from_pid] " . $from_pid ) ;
422
+ }
423
+
424
+ // Insert new size info
425
+ $size_to_insert_pids = array_diff( $size_to_store_pids, $size_to_update_pids ) ;
426
+ $q = "INSERT INTO $wpdb->postmeta ( post_id, meta_key, meta_value ) VALUES " ;
427
+ $data = array() ;
428
+ foreach ( $size_to_insert_pids as $pid ) {
429
+ $data[] = $pid ;
430
+ $data[] = self::DB_IMG_OPTIMIZE_SIZE ;
431
+ $data[] = $existing_sizes[ $size_to_store[ $pid ] ] ;
432
+ }
433
+
434
+ // Add placeholder
435
+ $q .= $this->_chunk_placeholder( $data, 3 ) ;
436
+
437
+ // Store data
438
+ $wpdb->query( $wpdb->prepare( $q, $data ) ) ;
439
+
440
+ LiteSpeed_Cache_Log::debug( '[Img_Optm] Inserted optm_size info [total] ' . count( $size_to_insert_pids ) ) ;
441
+
442
+ }
443
+
444
+ }
445
+
446
+ /**
447
+ * Filter duplicated src in $this->_img_in_queue
448
+ *
449
+ * @since 2.0
450
+ * @access private
451
+ */
452
+ private function _filter_duplicated_src()
453
+ {
454
+ $srcpath_md5_list = array() ;
455
+ $total_img_duplicated = 0 ;
456
+ $total_pid_unset = 0 ;
457
+ foreach ( $this->_img_in_queue as $pid => $img_list ) {
458
+ foreach ( $img_list as $md5 => $v ) {
459
+ if ( in_array( $v[ 'srcpath_md5' ], $srcpath_md5_list ) ) {
460
+ $this->_img_duplicated_in_queue[] = array(
461
+ 'pid' => $pid,
462
+ 'info' => $v,
463
+ ) ;
464
+
465
+ $total_img_duplicated ++ ;
466
+
467
+ unset( $this->_img_in_queue[ $pid ][ $md5 ] ) ;
468
+
469
+ continue ;
470
+ }
471
+
472
+ $srcpath_md5_list[ $pid . '.' . $md5 ] = $v[ 'srcpath_md5' ] ;
473
+
474
+ }
475
+
476
+ if ( empty( $this->_img_in_queue[ $pid ] ) ) {
477
+ unset( $this->_img_in_queue[ $pid ] ) ;
478
+ $total_pid_unset ++ ;
479
+ }
480
+ }
481
+
482
+ if ( $this->_img_duplicated_in_queue ) {
483
+ LiteSpeed_Cache_Log::debug( '[Img_Optm] Found duplicated src [total_img_duplicated] ' . $total_img_duplicated . ' [total_pid_unset] ' . $total_pid_unset ) ;
484
+ }
485
+ }
486
+
487
+ /**
488
+ * Generate placeholder for an array to query
489
+ *
490
+ * @since 2.0
491
+ * @access private
492
+ */
493
+ private function _chunk_placeholder( $data, $division )
494
+ {
495
+ $q = implode( ',', array_map(
496
+ function( $el ) { return '(' . implode( ',', $el ) . ')' ; },
497
+ array_chunk( array_fill( 0, count( $data ), '%s' ), $division )
498
+ ) ) ;
499
+
500
+ return $q ;
501
+ }
502
+
503
+ /**
504
+ * Saved non-existed images into img_optm
505
+ *
506
+ * @since 2.0
507
+ * @access private
508
+ */
509
+ private function _save_missed_into_img_optm()
510
+ {
511
+ if ( ! $this->_missed_img_in_queue ) {
512
+ return ;
513
+ }
514
+ LiteSpeed_Cache_Log::debug( '[Img_Optm] Missed img need to save [total] ' . count( $this->_missed_img_in_queue ) ) ;
515
+
516
+ $data_to_add = array() ;
517
+ foreach ( $this->_missed_img_in_queue as $src_data ) {
518
+ $data_to_add[] = $src_data[ 'pid' ] ;
519
+ $data_to_add[] = self::DB_IMG_OPTIMIZE_STATUS_MISS ;
520
+ $data_to_add[] = $src_data[ 'src' ] ;
521
+ $data_to_add[] = $src_data[ 'srcpath_md5' ] ;
522
+ }
523
+ $this->_insert_img_optm( $data_to_add, 'post_id, optm_status, src, srcpath_md5' ) ;
524
+ }
525
+
526
+ /**
527
+ * Add a new img to queue which will be pushed to LiteSpeed
528
+ *
529
+ * @since 1.6
530
+ * @access private
531
+ */
532
+ private function _img_queue( $meta_value, $ori_file = false )
533
+ {
534
+ if ( empty( $meta_value[ 'file' ] ) || empty( $meta_value[ 'width' ] ) || empty( $meta_value[ 'height' ] ) ) {
535
+ LiteSpeed_Cache_Log::debug2( '[Img_Optm] bypass image due to lack of file/w/h: pid ' . $this->tmp_pid, $meta_value ) ;
536
+ return ;
537
+ }
538
+
539
+ if ( ! $ori_file ) {
540
+ $meta_value[ 'file' ] = $this->tmp_path . $meta_value[ 'file' ] ;
541
+ }
542
+
543
+ // check file exists or not
544
+ $real_file = $this->wp_upload_dir[ 'basedir' ] . '/' . $meta_value[ 'file' ] ;
545
+ if ( ! file_exists( $real_file ) ) {
546
+ $this->_missed_img_in_queue[] = array(
547
+ 'pid' => $this->tmp_pid,
548
+ 'src' => $meta_value[ 'file' ],
549
+ 'srcpath_md5' => md5( $meta_value[ 'file' ] ),
550
+ ) ;
551
+ LiteSpeed_Cache_Log::debug2( '[Img_Optm] bypass image due to file not exist: pid ' . $this->tmp_pid . ' ' . $real_file ) ;
552
+ return ;
553
+ }
554
+
555
+ LiteSpeed_Cache_Log::debug2( '[Img_Optm] adding image: pid ' . $this->tmp_pid ) ;
556
+
557
+ $img_info = array(
558
+ 'url' => $this->wp_upload_dir[ 'baseurl' ] . '/' . $meta_value[ 'file' ],
559
+ 'src' => $meta_value[ 'file' ], // not needed in LiteSpeed sapi, just leave for local storage after post
560
+ 'width' => $meta_value[ 'width' ],
561
+ 'height' => $meta_value[ 'height' ],
562
+ 'mime_type' => ! empty( $meta_value[ 'mime-type' ] ) ? $meta_value[ 'mime-type' ] : '' ,
563
+ 'srcpath_md5' => md5( $meta_value[ 'file' ] ),
564
+ 'src_filesize' => filesize( $real_file ),
565
+ ) ;
566
+ $md5 = md5_file( $real_file ) ;
567
+
568
+ if ( empty( $this->_img_in_queue[ $this->tmp_pid ] ) ) {
569
+ $this->_img_in_queue[ $this->tmp_pid ] = array() ;
570
+ }
571
+ $this->_img_in_queue[ $this->tmp_pid ][ $md5 ] = $img_info ;
572
+ $this->_img_total ++ ;
573
+
574
+ // Build existing data checking array
575
+ $this->_img_srcpath_md5_array[] = $img_info[ 'srcpath_md5' ] ;
576
+ }
577
+
578
+ /**
579
+ * Push img to LiteSpeed IAPI server
580
+ *
581
+ * @since 1.6.7
582
+ * @access private
583
+ */
584
+ private function _push_img_in_queue_to_iapi()
585
+ {
586
+ $data = array(
587
+ 'list' => $this->_img_in_queue,
588
+ 'webp_only' => LiteSpeed_Cache::config( LiteSpeed_Cache_Config::OPID_MEDIA_IMG_WEBP_ONLY ),
589
+ 'keep_exif' => LiteSpeed_Cache::config( LiteSpeed_Cache_Config::OPID_MEDIA_IMG_EXIF ),
590
+ 'webp_lossless' => LiteSpeed_Cache::config( LiteSpeed_Cache_Config::OPID_MEDIA_IMG_WEBP_LOSSLESS ),
591
+ ) ;
592
+
593
+ // Push to LiteSpeed IAPI server
594
+ $json = LiteSpeed_Cache_Admin_API::post( LiteSpeed_Cache_Admin_API::IAPI_ACTION_REQUEST_OPTIMIZE, LiteSpeed_Cache_Utility::arr2str( $data ) ) ;
595
+
596
+ if ( $json === null ) {// admin_api will handle common err
597
+ return null ;
598
+ }
599
+
600
+ if ( ! is_array( $json ) ) {
601
+ LiteSpeed_Cache_Log::debug( '[Img_Optm] Failed to post to LiteSpeed IAPI server ', $json ) ;
602
+ $msg = sprintf( __( 'Failed to push to LiteSpeed IAPI server: %s', 'litespeed-cache' ), $json ) ;
603
+ LiteSpeed_Cache_Admin_Display::error( $msg ) ;
604
+ return null ;
605
+ }
606
+
607
+ // Check data format
608
+ if ( empty( $json[ 'pids' ] ) || ! is_array( $json[ 'pids' ] ) ) {
609
+ LiteSpeed_Cache_Log::debug( '[Img_Optm] Failed to parse data from LiteSpeed IAPI server ', $json[ 'pids' ] ) ;
610
+ $msg = sprintf( __( 'Failed to parse data from LiteSpeed IAPI server: %s', 'litespeed-cache' ), $json[ 'pids' ] ) ;
611
+ LiteSpeed_Cache_Admin_Display::error( $msg ) ;
612
+ return null ;
613
+ }
614
+
615
+ LiteSpeed_Cache_Log::debug( '[Img_Optm] Returned data from LiteSpeed IAPI server count: ' . count( $json[ 'pids' ] ) ) ;
616
+
617
+ return $json ;
618
+
619
+ }
620
+
621
+ /**
622
+ * LiteSpeed Child server notify Client img status changed
623
+ *
624
+ * @since 1.6
625
+ * @since 1.6.5 Added err/request status free switch
626
+ * @access public
627
+ */
628
+ public function notify_img()
629
+ {
630
+ global $wpdb ;
631
+
632
+ list( $notified_data, $server, $status ) = $this->_parse_notify_data() ;
633
+
634
+ $pids = array_keys( $notified_data ) ;
635
+
636
+ $q = "SELECT * FROM $this->_table_img_optm WHERE post_id IN ( " . implode( ',', array_fill( 0, count( $pids ), '%d' ) ) . " ) AND optm_status != %s" ;
637
+ $list = $wpdb->get_results( $wpdb->prepare( $q, array_merge( $pids, array( self::DB_IMG_OPTIMIZE_STATUS_PULLED ) ) ) ) ;
638
+
639
+ $need_pull = false ;
640
+ $last_log_pid = 0 ;
641
+
642
+ foreach ( $list as $v ) {
643
+ if ( ! in_array( $v->src_md5, $notified_data[ $v->post_id ] ) ) {
644
+ // This image is not in notifcation
645
+ continue ;
646
+ }
647
+
648
+ // Save data
649
+ $q = "UPDATE $this->_table_img_optm SET optm_status = %s, server = %s WHERE id = %d" ;
650
+ $wpdb->query( $wpdb->prepare( $q, array( $status, $server, $v->id ) ) ) ;
651
+
652
+ $pid_log = $last_log_pid == $v->post_id ? '.' : $v->post_id ;
653
+ LiteSpeed_Cache_Log::debug( '[Img_Optm] notify_img [status] ' . $status . " \t\t[pid] " . $pid_log . " \t\t[id] " . $v->id ) ;
654
+ $last_log_pid = $v->post_id ;
655
+
656
+ if ( $status == self::DB_IMG_OPTIMIZE_STATUS_NOTIFIED ) {
657
+ $need_pull = true ;
658
+ }
659
+ }
660
+
661
+ if ( $need_pull ) {
662
+ update_option( LiteSpeed_Cache_Config::ITEM_IMG_OPTM_NEED_PULL, self::DB_IMG_OPTIMIZE_STATUS_NOTIFIED ) ;
663
+ }
664
+
665
+ // redo count err
666
+
667
+ echo json_encode( array( 'count' => count( $notified_data ) ) ) ;
668
+ exit() ;
669
+ }
670
+
671
+ /**
672
+ * parse LiteSpeed IAPI server data
673
+ *
674
+ * @since 1.6.5
675
+ * @access public
676
+ */
677
+ private function _parse_notify_data()
678
+ {
679
+ $notified_data = unserialize( base64_decode( $_POST[ 'data' ] ) ) ;
680
+ if ( empty( $notified_data ) || ! is_array( $notified_data ) ) {
681
+ LiteSpeed_Cache_Log::debug( '[Img_Optm] notify exit: no notified data' ) ;
682
+ exit( json_encode( 'no notified data' ) ) ;
683
+ }
684
+
685
+ if ( empty( $_POST[ 'server' ] ) || substr( $_POST[ 'server' ], -21 ) !== 'api.litespeedtech.com' ) {
686
+ LiteSpeed_Cache_Log::debug( '[Img_Optm] notify exit: no/wrong server' ) ;
687
+ exit( json_encode( 'no/wrong server' ) ) ;
688
+ }
689
+
690
+ $_allowed_status = array( self::DB_IMG_OPTIMIZE_STATUS_NOTIFIED, self::DB_IMG_OPTIMIZE_STATUS_ERR, self::DB_IMG_OPTIMIZE_STATUS_REQUESTED ) ;
691
+
692
+ if ( empty( $_POST[ 'status' ] ) || ! in_array( $_POST[ 'status' ], $_allowed_status ) ) {
693
+ LiteSpeed_Cache_Log::debug( '[Img_Optm] notify exit: no/wrong status' ) ;
694
+ exit( json_encode( 'no/wrong status' ) ) ;
695
+ }
696
+
697
+ return array( $notified_data, $_POST[ 'server' ], $_POST[ 'status' ] ) ;
698
+ }
699
+
700
+ /**
701
+ * Pull optimized img
702
+ *
703
+ * @since 1.6
704
+ * @access public
705
+ */
706
+ public static function pull_optimized_img()
707
+ {
708
+ LiteSpeed_Cache_Log::debug( '[Img_Optm] Cron pull_optimized_img started' ) ;
709
+ $instance = self::get_instance() ;
710
+ $instance->_pull_optimized_img() ;
711
+ }
712
+
713
+ /**
714
+ * Pull optimized img
715
+ *
716
+ * @since 1.6
717
+ * @access private
718
+ */
719
+ private function _pull_optimized_img()
720
+ {
721
+ if ( $this->cron_running() ) {
722
+ LiteSpeed_Cache_Log::debug( '[Img_Optm] fetch cron is running' ) ;
723
+ return ;
724
+ }
725
+
726
+ global $wpdb ;
727
+
728
+ $q = "SELECT a.*, b.meta_id as b_meta_id, b.meta_value AS b_optm_info
729
+ FROM $this->_table_img_optm a
730
+ LEFT JOIN $wpdb->postmeta b ON b.post_id = a.post_id AND b.meta_key = %s
731
+ WHERE a.root_id = 0 AND a.optm_status = %s ORDER BY a.id LIMIT 1" ;
732
+ $_q = $wpdb->prepare( $q, array( self::DB_IMG_OPTIMIZE_SIZE, self::DB_IMG_OPTIMIZE_STATUS_NOTIFIED ) ) ;
733
+
734
+ $webp_only = LiteSpeed_Cache::config( LiteSpeed_Cache_Config::OPID_MEDIA_IMG_WEBP_ONLY ) ;
735
+
736
+ // pull 10 images each time
737
+ for ( $i=0 ; $i < 10 ; $i++ ) {
738
+ $row_img = $wpdb->get_row( $_q ) ;
739
+ if ( ! $row_img ) {
740
+ // No image
741
+ break ;
742
+ }
743
+
744
+ /**
745
+ * Update cron timestamp to avoid duplicated running
746
+ * @since 1.6.2
747
+ */
748
+ $this->_update_cron_running() ;
749
+
750
+ // Default optm info array
751
+ $optm_info = array(
752
+ 'ori_total' => 0,
753
+ 'ori_saved' => 0,
754
+ 'webp_total' => 0,
755
+ 'webp_saved' => 0,
756
+ ) ;
757
+ if ( ! empty( $row_img->b_meta_id ) ) {
758
+ $optm_info = array_merge( $optm_info, unserialize( $row_img->b_optm_info ) ) ;
759
+ }
760
+
761
+ // send fetch request
762
+ LiteSpeed_Cache_Log::debug( '[Img_Optm] Connecting IAPI server for [pid] ' . $row_img->post_id . ' [src_md5]' . $row_img->src_md5 ) ;
763
+ $server = $row_img->server ;
764
+ $data = array(
765
+ 'pid' => $row_img->post_id,
766
+ 'src_md5' => $row_img->src_md5,
767
+ ) ;
768
+ $json = LiteSpeed_Cache_Admin_API::post( LiteSpeed_Cache_Admin_API::IAPI_ACTION_PULL_IMG, $data, $server ) ;
769
+ if ( empty( $json[ 'webp' ] ) ) {
770
+ LiteSpeed_Cache_Log::debug( '[Img_Optm] Failed to pull optimized img: ', $json ) ;
771
+ return ;
772
+ }
773
+
774
+ $local_file = $this->wp_upload_dir[ 'basedir' ] . '/' . $row_img->src ;
775
+
776
+ /**
777
+ * Use wp orignal get func to avoid allow_url_open off issue
778
+ * @since 1.6.5
779
+ */
780
+ // Fetch webp image
781
+ $response = wp_remote_get( $json[ 'webp' ], array( 'timeout' => 15 ) ) ;
782
+ if ( is_wp_error( $response ) ) {
783
+ $error_message = $response->get_error_message() ;
784
+ LiteSpeed_Cache_Log::debug( 'IAPI failed to pull image: ' . $error_message ) ;
785
+ return ;
786
+ }
787
+
788
+ file_put_contents( $local_file . '.webp', $response[ 'body' ] ) ;
789
+
790
+ if ( ! file_exists( $local_file . '.webp' ) ) {
791
+ return ;
792
+ }
793
+
794
+ // Unknown issue
795
+ if ( md5_file( $local_file . '.webp' ) !== $json[ 'webp_md5' ] ) {
796
+ LiteSpeed_Cache_Log::debug( '[Img_Optm] Failed to pull optimized img WebP: file md5 dismatch, server md5: ' . $json[ 'webp_md5' ] ) ;
797
+
798
+ // update status to failed
799
+ $q = "UPDATE $this->_table_img_optm SET optm_status = %s WHERE id = %d " ;
800
+ $wpdb->query( $wpdb->prepare( $q, array( self::DB_IMG_OPTIMIZE_STATUS_FAILED, $row_img->id ) ) ) ;
801
+ // Update child images
802
+ $q = "UPDATE $this->_table_img_optm SET optm_status = %s WHERE root_id = %d " ;
803
+ $wpdb->query( $wpdb->prepare( $q, array( self::DB_IMG_OPTIMIZE_STATUS_FAILED, $row_img->id ) ) ) ;
804
+
805
+ // Notify server to update status
806
+ LiteSpeed_Cache_Admin_API::post( LiteSpeed_Cache_Admin_API::IAPI_ACTION_PULL_IMG_FAILED, $data, $server ) ;
807
+
808
+ return ;// exit from running pull process
809
+ }
810
+
811
+ $ori_size = $row_img->src_filesize ?: filesize( $local_file ) ;
812
+
813
+ // log webp file saved size summary
814
+ $webp_size = filesize( $local_file . '.webp' ) ;
815
+ $webp_saved = $ori_size - $webp_size ;
816
+ if ( $webp_saved > 0 ) {
817
+ $optm_info[ 'webp_total' ] += $ori_size ;
818
+ $optm_info[ 'webp_saved' ] += $webp_saved ;
819
+ }
820
+ else {
821
+ $webp_saved = 0 ;
822
+ }
823
+
824
+ LiteSpeed_Cache_Log::debug( '[Img_Optm] Pulled optimized img WebP: ' . $local_file . '.webp' ) ;
825
+
826
+ // Fetch optimized image itself
827
+ $target_size = 0 ;
828
+ $target_saved = 0 ;
829
+ if ( ! $webp_only && ! empty( $json[ 'target_file' ] ) ) {
830
+
831
+ // Fetch failed, unkown issue, return
832
+ // NOTE: if this failed more than 5 times, next time fetching webp will touch err limit on server side, whole image will be failed
833
+ $response = wp_remote_get( $json[ 'target_file' ], array( 'timeout' => 15 ) ) ;
834
+ if ( is_wp_error( $response ) ) {
835
+ $error_message = $response->get_error_message() ;
836
+ LiteSpeed_Cache_Log::debug( 'IAPI failed to pull image: ' . $error_message ) ;
837
+ return ;
838
+ }
839
+
840
+ file_put_contents( $local_file . '.tmp', $response[ 'body' ] ) ;
841
+ // Unknown issue
842
+ if ( md5_file( $local_file . '.tmp' ) !== $json[ 'target_md5' ] ) {
843
+ LiteSpeed_Cache_Log::debug( '[Img_Optm] Failed to pull optimized img iteself: file md5 dismatch, server md5: ' . $json[ 'target_md5' ] ) ;
844
+
845
+ // update status to failed
846
+ $q = "UPDATE $this->_table_img_optm SET optm_status = %s WHERE id = %d " ;
847
+ $wpdb->query( $wpdb->prepare( $q, array( self::DB_IMG_OPTIMIZE_STATUS_FAILED, $row_img->id ) ) ) ;
848
+ // Update child images
849
+ $q = "UPDATE $this->_table_img_optm SET optm_status = %s WHERE root_id = %d " ;
850
+ $wpdb->query( $wpdb->prepare( $q, array( self::DB_IMG_OPTIMIZE_STATUS_FAILED, $row_img->id ) ) ) ;
851
+
852
+ // Notify server to update status
853
+ LiteSpeed_Cache_Admin_API::post( LiteSpeed_Cache_Admin_API::IAPI_ACTION_PULL_IMG_FAILED, $data, $server ) ;
854
+
855
+ return ; // exit from running pull process
856
+ }
857
+
858
+ // log webp file saved size summary
859
+ $target_size = filesize( $local_file . '.tmp' ) ;
860
+ $target_saved = $ori_size - $target_size ;
861
+ if ( $target_saved > 0 ) {
862
+ $optm_info[ 'ori_total' ] += $ori_size ;
863
+ $optm_info[ 'ori_saved' ] += $target_saved ;
864
+ }
865
+ else {
866
+ $target_saved = 0 ;
867
+ }
868
+
869
+ // Backup ori img
870
+ $extension = pathinfo( $local_file, PATHINFO_EXTENSION ) ;
871
+ $bk_file = substr( $local_file, 0, -strlen( $extension ) ) . 'bk.' . $extension ;
872
+ rename( $local_file, $bk_file ) ;
873
+
874
+ // Replace ori img
875
+ rename( $local_file . '.tmp', $local_file ) ;
876
+
877
+ LiteSpeed_Cache_Log::debug( '[Img_Optm] Pulled optimized img: ' . $local_file ) ;
878
+ }
879
+
880
+ LiteSpeed_Cache_Log::debug2( '[Img_Optm] Update _table_img_optm record [id] ' . $row_img->id ) ;
881
+
882
+ // Update pulled status
883
+ $q = "UPDATE $this->_table_img_optm SET optm_status = %s, target_filesize = %d, target_saved = %d, webp_filesize = %d, webp_saved = %d WHERE id = %d " ;
884
+ $wpdb->query( $wpdb->prepare( $q, array( self::DB_IMG_OPTIMIZE_STATUS_PULLED, $target_size, $target_saved, $webp_size, $webp_saved, $row_img->id ) ) ) ;
885
+
886
+ // Update child images
887
+ $q = "UPDATE $this->_table_img_optm SET optm_status = %s, target_filesize = %d, target_saved = %d, webp_filesize = %d, webp_saved = %d WHERE root_id = %d " ;
888
+ $child_count = $wpdb->query( $wpdb->prepare( $q, array( self::DB_IMG_OPTIMIZE_STATUS_PULLED, $target_size, $target_saved, $webp_size, $webp_saved, $row_img->id ) ) ) ;
889
+
890
+ /**
891
+ * Update size saved info
892
+ * @since 1.6.5
893
+ */
894
+ $optm_info = serialize( $optm_info ) ;
895
+ if ( ! empty( $row_img->b_meta_id ) ) {
896
+ $q = "UPDATE $wpdb->postmeta SET meta_value = %s WHERE meta_id = %d " ;
897
+ $wpdb->query( $wpdb->prepare( $q, array( $optm_info, $row_img->b_meta_id ) ) ) ;
898
+ }
899
+ else {
900
+ LiteSpeed_Cache_Log::debug( '[Img_Optm] New size info [pid] ' . $row_img->post_id ) ;
901
+ $q = "INSERT INTO $wpdb->postmeta ( post_id, meta_key, meta_value ) VALUES ( %d, %s, %s )" ;
902
+ $wpdb->query( $wpdb->prepare( $q, array( $row_img->post_id, self::DB_IMG_OPTIMIZE_SIZE, $optm_info ) ) ) ;
903
+ }
904
+
905
+ // Update size saved info of child images
906
+ if ( $child_count ) {
907
+ LiteSpeed_Cache_Log::debug( '[Img_Optm] Proceed child images [total] ' . $child_count ) ;
908
+
909
+ $q = "SELECT a.*, b.meta_id as b_meta_id
910
+ FROM $this->_table_img_optm a
911
+ LEFT JOIN $wpdb->postmeta b ON b.post_id = a.post_id AND b.meta_key = %s
912
+ WHERE a.root_id = %d GROUP BY a.post_id" ;
913
+ $pids = array() ;
914
+ $tmp = $wpdb->get_results( $wpdb->prepare( $q, array( self::DB_IMG_OPTIMIZE_SIZE, $row_img->id ) ) ) ;
915
+ $pids_to_update = array() ;
916
+ $pids_data_to_insert = array() ;
917
+ foreach ( $tmp as $v ) {
918
+ if ( $v->b_meta_id ) {
919
+ $pids_to_update[] = $v->post_id ;
920
+ }
921
+ else {
922
+ $pids_data_to_insert[] = $v->post_id ;
923
+ $pids_data_to_insert[] = self::DB_IMG_OPTIMIZE_SIZE ;
924
+ $pids_data_to_insert[] = $optm_info ;
925
+ }
926
+ }
927
+
928
+ // Update these size_info
929
+ if ( $pids_to_update ) {
930
+ $pids_to_update = array_unique( $pids_to_update ) ;
931
+ LiteSpeed_Cache_Log::debug( '[Img_Optm] Update child group size_info [total] ' . count( $pids_to_update ) ) ;
932
+
933
+ $q = "UPDATE $wpdb->postmeta SET meta_value = %s WHERE meta_key = %s AND post_id IN ( " . implode( ',', array_fill( 0, count( $pids_to_update ), '%d' ) ) . " )" ;
934
+ $wpdb->query( $wpdb->prepare( $q, array_merge( array( $optm_info, self::DB_IMG_OPTIMIZE_SIZE ), $pids_to_update ) ) ) ;
935
+ }
936
+
937
+ // Insert these size_info
938
+ if ( $pids_data_to_insert ) {
939
+ LiteSpeed_Cache_Log::debug( '[Img_Optm] Insert child group size_info [total] ' . ( count( $pids_data_to_insert ) / 3 ) ) ;
940
+
941
+ $q = "INSERT INTO $wpdb->postmeta ( post_id, meta_key, meta_value ) VALUES " ;
942
+ // Add placeholder
943
+ $q .= $this->_chunk_placeholder( $pids_data_to_insert, 3 ) ;
944
+ $wpdb->query( $wpdb->prepare( $q, $pids_data_to_insert ) ) ;
945
+ }
946
+ }
947
+ }
948
+
949
+ // Update guidance
950
+ if ( $this->get_guidance_pos() == 3 ) {
951
+ $this->_update_guidance_pos( 4 ) ;
952
+ }
953
+
954
+ // Check if there is still task in queue
955
+ $q = "SELECT * FROM $this->_table_img_optm WHERE root_id = 0 AND optm_status = %s LIMIT 1" ;
956
+ $tmp = $wpdb->get_row( $wpdb->prepare( $q, self::DB_IMG_OPTIMIZE_STATUS_NOTIFIED ) ) ;
957
+ if ( $tmp ) {
958
+ LiteSpeed_Cache_Log::debug( '[Img_Optm] Task in queue, to be continued...' ) ;
959
+ return 'to_be_continued' ;
960
+ }
961
+
962
+ // If all pulled, update tag to done
963
+ LiteSpeed_Cache_Log::debug( '[Img_Optm] Marked pull status to all pulled' ) ;
964
+ update_option( LiteSpeed_Cache_Config::ITEM_IMG_OPTM_NEED_PULL, self::DB_IMG_OPTIMIZE_STATUS_PULLED ) ;
965
+ }
966
+
967
+ /**
968
+ * Check if need to do a pull for optimized img
969
+ *
970
+ * @since 1.6
971
+ * @access public
972
+ */
973
+ public static function check_need_pull()
974
+ {
975
+ $tag = get_option( LiteSpeed_Cache_Config::ITEM_IMG_OPTM_NEED_PULL ) ;
976
+ return defined( 'DOING_CRON' ) && $tag && $tag === self::DB_IMG_OPTIMIZE_STATUS_NOTIFIED ;
977
+ }
978
+
979
+ /**
980
+ * Show an image's optm status
981
+ *
982
+ * @since 1.6.5
983
+ * @access public
984
+ */
985
+ public function check_img()
986
+ {
987
+ $pid = $_POST[ 'data' ] ;
988
+
989
+ LiteSpeed_Cache_Log::debug( '[Img_Optm] Check image [ID] ' . $pid ) ;
990
+
991
+ $data = array() ;
992
+
993
+ $data[ 'img_count' ] = $this->img_count() ;
994
+
995
+ $data[ '_wp_attached_file' ] = get_post_meta( $pid, '_wp_attached_file', true ) ;
996
+ $data[ '_wp_attachment_metadata' ] = get_post_meta( $pid, '_wp_attachment_metadata', true ) ;
997
+
998
+ // Get img_optm data
999
+ $q = "SELECT * FROM $this->_table_img_optm WHERE post_id = %d" ;
1000
+ $list = $wpdb->get_results( $wpdb->prepare( $q, $pid ) ) ;
1001
+ $img_data = array() ;
1002
+ if ( $list ) {
1003
+ foreach ( $list as $v ) {
1004
+ $img_data[] = array(
1005
+ 'id' => $v->id,
1006
+ 'optm_status' => $v->optm_status,
1007
+ 'src' => $v->src,
1008
+ 'srcpath_md5' => $v->srcpath_md5,
1009
+ 'src_md5' => $v->src_md5,
1010
+ 'server' => $v->server,
1011
+ ) ;
1012
+ }
1013
+ }
1014
+ $data[ 'img_data' ] = $img_data ;
1015
+
1016
+ echo json_encode( $data ) ;
1017
+ exit;
1018
+ }
1019
+
1020
+ /**
1021
+ * Parse wp's meta value
1022
+ *
1023
+ * @since 1.6.7
1024
+ * @access private
1025
+ */
1026
+ private function _parse_wp_meta_value( $v )
1027
+ {
1028
+ if ( ! $v->meta_value ) {
1029
+ LiteSpeed_Cache_Log::debug( '[Img_Optm] bypassed parsing meta due to no meta_value: pid ' . $v->post_id ) ;
1030
+ return false ;
1031
+ }
1032
+
1033
+ try {
1034
+ $meta_value = unserialize( $v->meta_value ) ;
1035
+ }
1036
+ catch ( \Exception $e ) {
1037
+ LiteSpeed_Cache_Log::debug( '[Img_Optm] bypassed parsing meta due to meta_value not json: pid ' . $v->post_id ) ;
1038
+ return false ;
1039
+ }
1040
+
1041
+ if ( empty( $meta_value[ 'file' ] ) ) {
1042
+ LiteSpeed_Cache_Log::debug( '[Img_Optm] bypassed parsing meta due to no ori file: pid ' . $v->post_id ) ;
1043
+ return false ;
1044
+ }
1045
+
1046
+ return $meta_value ;
1047
+ }
1048
+
1049
+ /**
1050
+ * Send destroy all requests cmd to LiteSpeed IAPI server and get the link to finish it ( avoid click by mistake )
1051
+ *
1052
+ * @since 1.6.7
1053
+ * @access private
1054
+ */
1055
+ private function _img_optimize_destroy()
1056
+ {
1057
+ LiteSpeed_Cache_Log::debug( '[Img_Optm] sending DESTROY cmd to LiteSpeed IAPI' ) ;
1058
+
1059
+ // Mark request time to avoid duplicated request
1060
+ update_option( self::DB_IMG_OPTIMIZE_DESTROY, time() ) ;
1061
+
1062
+ // Push to LiteSpeed IAPI server
1063
+ $json = LiteSpeed_Cache_Admin_API::post( LiteSpeed_Cache_Admin_API::IAPI_ACTION_REQUEST_DESTROY ) ;
1064
+
1065
+ // confirm link will be displayed by Admin_API automatically
1066
+ if ( is_array( $json ) && $json ) {
1067
+ LiteSpeed_Cache_Log::debug( '[Img_Optm] cmd result', $json ) ;
1068
+ }
1069
+
1070
+ }
1071
+
1072
+ /**
1073
+ * Callback from LiteSpeed IAPI server to destroy all optm data
1074
+ *
1075
+ * @since 1.6.7
1076
+ * @access private
1077
+ */
1078
+ public function img_optimize_destroy_callback()
1079
+ {
1080
+ global $wpdb ;
1081
+ LiteSpeed_Cache_Log::debug( '[Img_Optm] excuting DESTROY process' ) ;
1082
+
1083
+ $request_time = get_option( self::DB_IMG_OPTIMIZE_DESTROY ) ;
1084
+ if ( time() - $request_time > 300 ) {
1085
+ LiteSpeed_Cache_Log::debug( '[Img_Optm] terminate DESTROY process due to timeout' ) ;
1086
+ exit( 'Destroy callback timeout ( 300 seconds )' ) ;
1087
+ }
1088
+
1089
+ // Start deleting files
1090
+ $q = "SELECT * FROM $this->_table_img_optm WHERE optm_status = %s" ;
1091
+ $list = $wpdb->get_results( $wpdb->prepare( $q, self::DB_IMG_OPTIMIZE_STATUS_PULLED ) ) ;
1092
+ foreach ( $list as $v ) {
1093
+ $local_file = $this->wp_upload_dir[ 'basedir' ] . '/' . $v->src ;
1094
+
1095
+ // del webp
1096
+ file_exists( $local_file . '.webp' ) && unlink( $local_file . '.webp' ) ;
1097
+ file_exists( $local_file . '.optm.webp' ) && unlink( $local_file . '.optm.webp' ) ;
1098
+
1099
+ $extension = pathinfo( $local_file, PATHINFO_EXTENSION ) ;
1100
+ $local_filename = substr( $local_file, 0, - strlen( $extension ) - 1 ) ;
1101
+ $bk_file = $local_filename . '.bk.' . $extension ;
1102
+ $bk_optm_file = $local_filename . '.bk.optm.' . $extension ;
1103
+
1104
+ // del optimized ori
1105
+ if ( file_exists( $bk_file ) ) {
1106
+ unlink( $local_file ) ;
1107
+ rename( $bk_file, $local_file ) ;
1108
+ }
1109
+ file_exists( $bk_optm_file ) && unlink( $bk_optm_file ) ;
1110
+ }
1111
+
1112
+ // Delete optm info
1113
+ $q = "DELETE FROM $wpdb->postmeta WHERE meta_key LIKE 'litespeed-optimize%'" ;
1114
+ $wpdb->query( $q ) ;
1115
+
1116
+ // Delete img_optm table
1117
+ LiteSpeed_Cache_Data::get_instance()->delete_tb_img_optm() ;
1118
+
1119
+ // Clear credit info
1120
+ delete_option( self::DB_IMG_OPTM_SUMMARY ) ;
1121
+
1122
+ $this->_update_guidance_pos( 1 ) ;
1123
+
1124
+ exit( 'ok' ) ;
1125
+ }
1126
+
1127
+ /**
1128
+ * Resend requested img to LiteSpeed IAPI server
1129
+ *
1130
+ * @since 1.6.7
1131
+ * @access private
1132
+ */
1133
+ private function _img_optimize_rescan()
1134
+ {return;
1135
+ LiteSpeed_Cache_Log::debug( '[Img_Optm] resend requested images' ) ;
1136
+
1137
+ $_credit = (int) $this->summary_info( 'credit' ) ;
1138
+
1139
+ global $wpdb ;
1140
+
1141
+ $q = "SELECT a.post_id, a.meta_value, b.meta_id as bmeta_id, c.meta_id as cmeta_id, c.meta_value as cmeta_value
1142
+ FROM $wpdb->postmeta a
1143
+ LEFT JOIN $wpdb->postmeta b ON b.post_id = a.post_id
1144
+ LEFT JOIN $wpdb->postmeta c ON c.post_id = a.post_id
1145
+ WHERE a.meta_key = '_wp_attachment_metadata'
1146
+ AND b.meta_key = %s
1147
+ AND c.meta_key = %s
1148
+ LIMIT %d
1149
+ " ;
1150
+ $limit_rows = apply_filters( 'litespeed_img_optm_resend_rows', 300 ) ;
1151
+ $list = $wpdb->get_results( $wpdb->prepare( $q, array( self::DB_IMG_OPTIMIZE_STATUS, self::DB_IMG_OPTIMIZE_DATA, $limit_rows ) ) ) ;
1152
+ if ( ! $list ) {
1153
+ LiteSpeed_Cache_Log::debug( '[Img_Optm] resend request bypassed: no image found' ) ;
1154
+ $msg = __( 'No image found.', 'litespeed-cache' ) ;
1155
+ LiteSpeed_Cache_Admin_Display::error( $msg ) ;
1156
+ return ;
1157
+ }
1158
+
1159
+ // meta list
1160
+ $optm_data_list = array() ;
1161
+ $optm_data_pid2mid_list = array() ;
1162
+
1163
+ foreach ( $list as $v ) {
1164
+ // wp meta
1165
+ $meta_value = $this->_parse_wp_meta_value( $v ) ;
1166
+ if ( ! $meta_value ) {
1167
+ continue ;
1168
+ }
1169
+ if ( empty( $meta_value[ 'sizes' ] ) ) {
1170
+ continue ;
1171
+ }
1172
+
1173
+ $optm_data_pid2mid_list[ $v->post_id ] = array( 'status_mid' => $v->bmeta_id, 'data_mid' => $v->cmeta_id ) ;
1174
+
1175
+ // prepare for pushing
1176
+ $this->tmp_pid = $v->post_id ;
1177
+ $this->tmp_path = pathinfo( $meta_value[ 'file' ], PATHINFO_DIRNAME ) . '/' ;
1178
+
1179
+ // ls optimized meta
1180
+ $optm_meta = $optm_data_list[ $v->post_id ] = unserialize( $v->cmeta_value ) ;
1181
+ $optm_list = array() ;
1182
+ foreach ( $optm_meta as $md5 => $optm_row ) {
1183
+ $optm_list[] = $optm_row[ 0 ] ;
1184
+ // only do for requested/notified img
1185
+ // if ( ! in_array( $optm_row[ 1 ], array( self::DB_IMG_OPTIMIZE_STATUS_NOTIFIED, self::DB_IMG_OPTIMIZE_STATUS_REQUESTED ) ) ) {
1186
+ // continue ;
1187
+ // }
1188
+ }
1189
+
1190
+ // check if there is new files from wp meta
1191
+ $img_queue = array() ;
1192
+ foreach ( $meta_value[ 'sizes' ] as $v2 ) {
1193
+ $curr_file = $this->tmp_path . $v2[ 'file' ] ;
1194
+
1195
+ // new child file OR not finished yet
1196
+ if ( ! in_array( $curr_file, $optm_list ) ) {
1197
+ $img_queue[] = $v2 ;
1198
+ }
1199
+ }
1200
+
1201
+ // nothing to add
1202
+ if ( ! $img_queue ) {
1203
+ continue ;
1204
+ }
1205
+
1206
+ $num_will_incease = count( $img_queue ) ;
1207
+ if ( $this->_img_total + $num_will_incease > $_credit ) {
1208
+ LiteSpeed_Cache_Log::debug( '[Img_Optm] resend img request hit limit: [total] ' . $this->_img_total . " \t[add] $num_will_incease \t[credit] $_credit" ) ;
1209
+ break ;
1210
+ }
1211
+
1212
+ foreach ( $img_queue as $v2 ) {
1213
+ $this->_img_queue( $v2 ) ;
1214
+ }
1215
+ }
1216
+
1217
+ // push to LiteSpeed IAPI server
1218
+ if ( empty( $this->_img_in_queue ) ) {
1219
+ $msg = __( 'No image found.', 'litespeed-cache' ) ;
1220
+ LiteSpeed_Cache_Admin_Display::succeed( $msg ) ;
1221
+ return ;
1222
+ }
1223
+
1224
+ $total_groups = count( $this->_img_in_queue ) ;
1225
+ LiteSpeed_Cache_Log::debug( '[Img_Optm] prepared images to push: groups ' . $total_groups . ' images ' . $this->_img_total ) ;
1226
+
1227
+ // Push to LiteSpeed IAPI server
1228
+ $json = $this->_push_img_in_queue_to_iapi() ;
1229
+ if ( $json === null ) {
1230
+ return ;
1231
+ }
1232
+ // Returned data is the requested and notifed images
1233
+ $pids = $json[ 'pids' ] ;
1234
+
1235
+ $q = "UPDATE $wpdb->postmeta SET meta_value = %s WHERE meta_id = %d" ;
1236
+
1237
+ // Update data
1238
+ foreach ( $pids as $pid ) {
1239
+ $md52src_list = $optm_data_list[ $pid ] ;
1240
+
1241
+ foreach ( $this->_img_in_queue[ $pid ] as $md5 => $src_data ) {
1242
+ $md52src_list[ $md5 ] = array( $src_data[ 'src' ], self::DB_IMG_OPTIMIZE_STATUS_REQUESTED ) ;
1243
+ }
1244
+
1245
+ $new_status = $this->_get_status_by_meta_data( $md52src_list, self::DB_IMG_OPTIMIZE_STATUS_REQUESTED ) ;
1246
+
1247
+ $md52src_list = serialize( $md52src_list ) ;
1248
+
1249
+ // Store data
1250
+ $wpdb->query( $wpdb->prepare( $q, array( $new_status, $optm_data_pid2mid_list[ $pid ][ 'status_mid' ] ) ) ) ;
1251
+ $wpdb->query( $wpdb->prepare( $q, array( $md52src_list, $optm_data_pid2mid_list[ $pid ][ 'data_mid' ] ) ) ) ;
1252
+ }
1253
+
1254
+ $accepted_groups = count( $pids ) ;
1255
+ $accepted_imgs = $json[ 'total' ] ;
1256
+
1257
+ $msg = sprintf( __( 'Pushed %1$s groups with %2$s images to LiteSpeed optimization server, accepted %3$s groups with %4$s images.', 'litespeed-cache' ), $total_groups, $this->_img_total, $accepted_groups, $accepted_imgs ) ;
1258
+ LiteSpeed_Cache_Admin_Display::succeed( $msg ) ;
1259
+
1260
+ // Update credit info
1261
+ if ( isset( $json[ 'credit' ] ) ) {
1262
+ $this->_update_credit( $json[ 'credit' ] ) ;
1263
+ }
1264
+
1265
+ }
1266
+
1267
+ /**
1268
+ * Update client credit info
1269
+ *
1270
+ * @since 1.6.5
1271
+ * @access private
1272
+ */
1273
+ private function _update_credit( $credit )
1274
+ {
1275
+ $summary = get_option( self::DB_IMG_OPTM_SUMMARY, array() ) ;
1276
+ $summary[ 'credit' ] = $credit ;
1277
+
1278
+ update_option( self::DB_IMG_OPTM_SUMMARY, $summary ) ;
1279
+ }
1280
+
1281
+ /**
1282
+ * Get optm summary
1283
+ *
1284
+ * @since 1.6.5
1285
+ * @access public
1286
+ */
1287
+ public function summary_info( $field = false )
1288
+ {
1289
+ $optm_summary = get_option( self::DB_IMG_OPTM_SUMMARY, array() ) ;
1290
+
1291
+ if ( ! $field ) {
1292
+ return $optm_summary ;
1293
+ }
1294
+ return ! empty( $optm_summary[ $field ] ) ? $optm_summary[ $field ] : 0 ;
1295
+ }
1296
+
1297
+ /**
1298
+ * Count images
1299
+ *
1300
+ * @since 1.6
1301
+ * @access public
1302
+ */
1303
+ public function img_count()
1304
+ {
1305
+ global $wpdb ;
1306
+ $q = "SELECT count(*)
1307
+ FROM $wpdb->posts a
1308
+ LEFT JOIN $wpdb->postmeta b ON b.post_id = a.ID
1309
+ WHERE a.post_type = 'attachment'
1310
+ AND a.post_status = 'inherit'
1311
+ AND a.post_mime_type IN ('image/jpeg', 'image/png')
1312
+ AND b.meta_key = '_wp_attachment_metadata'
1313
+ " ;
1314
+ // $q = "SELECT count(*) FROM $wpdb->posts WHERE post_type = 'attachment' AND post_status = 'inherit' AND post_mime_type IN ('image/jpeg', 'image/png') " ;
1315
+ $total_img = $wpdb->get_var( $q ) ;
1316
+
1317
+ $q = "SELECT count(*)
1318
+ FROM $wpdb->posts a
1319
+ LEFT JOIN $wpdb->postmeta b ON b.post_id = a.ID
1320
+ LEFT JOIN $this->_table_img_optm c ON c.post_id = a.ID
1321
+ WHERE a.post_type = 'attachment'
1322
+ AND a.post_status = 'inherit'
1323
+ AND a.post_mime_type IN ('image/jpeg', 'image/png')
1324
+ AND b.meta_key = '_wp_attachment_metadata'
1325
+ AND c.id IS NULL
1326
+ " ;
1327
+ $total_not_requested = $wpdb->get_var( $q ) ;
1328
+
1329
+ // images count from img_optm table
1330
+ $q_groups = "SELECT count(distinct post_id) FROM $this->_table_img_optm WHERE optm_status = %s" ;
1331
+ $q = "SELECT count(*) FROM $this->_table_img_optm WHERE optm_status = %s" ;
1332
+ $total_requested_groups = $wpdb->get_var( $wpdb->prepare( $q_groups, self::DB_IMG_OPTIMIZE_STATUS_REQUESTED ) ) ;
1333
+ $total_requested = $wpdb->get_var( $wpdb->prepare( $q, self::DB_IMG_OPTIMIZE_STATUS_REQUESTED ) ) ;
1334
+ $total_server_finished_groups = $wpdb->get_var( $wpdb->prepare( $q_groups, self::DB_IMG_OPTIMIZE_STATUS_NOTIFIED ) ) ;
1335
+ $total_server_finished = $wpdb->get_var( $wpdb->prepare( $q, self::DB_IMG_OPTIMIZE_STATUS_NOTIFIED ) ) ;
1336
+ $total_pulled_groups = $wpdb->get_var( $wpdb->prepare( $q_groups, self::DB_IMG_OPTIMIZE_STATUS_PULLED ) ) ;
1337
+ $total_pulled = $wpdb->get_var( $wpdb->prepare( $q, self::DB_IMG_OPTIMIZE_STATUS_PULLED ) ) ;
1338
+ $total_err_groups = $wpdb->get_var( $wpdb->prepare( $q_groups, self::DB_IMG_OPTIMIZE_STATUS_ERR ) ) ;
1339
+ $total_err = $wpdb->get_var( $wpdb->prepare( $q, self::DB_IMG_OPTIMIZE_STATUS_ERR ) ) ;
1340
+ $total_miss_groups = $wpdb->get_var( $wpdb->prepare( $q_groups, self::DB_IMG_OPTIMIZE_STATUS_MISS ) ) ;
1341
+ $total_miss = $wpdb->get_var( $wpdb->prepare( $q, self::DB_IMG_OPTIMIZE_STATUS_MISS ) ) ;
1342
+
1343
+ return array(
1344
+ 'total_img' => $total_img,
1345
+ 'total_not_requested' => $total_not_requested,
1346
+ 'total_requested_groups' => $total_requested_groups,
1347
+ 'total_requested' => $total_requested,
1348
+ 'total_err_groups' => $total_err_groups,
1349
+ 'total_err' => $total_err,
1350
+ 'total_miss_groups' => $total_miss_groups,
1351
+ 'total_miss' => $total_miss,
1352
+ 'total_server_finished_groups' => $total_server_finished_groups,
1353
+ 'total_server_finished' => $total_server_finished,
1354
+ 'total_pulled_groups' => $total_pulled_groups,
1355
+ 'total_pulled' => $total_pulled,
1356
+ ) ;
1357
+ }
1358
+
1359
+ /**
1360
+ * Check if fetch cron is running
1361
+ *
1362
+ * @since 1.6.2
1363
+ * @access public
1364
+ */
1365
+ public function cron_running( $bool_res = true )
1366
+ {
1367
+ $last_run = get_option( self::ITEM_IMG_OPTM_CRON_RUN ) ;
1368
+
1369
+ $is_running = $last_run && time() - $last_run < 120 ;
1370
+
1371
+ if ( $bool_res ) {
1372
+ return $is_running ;
1373
+ }
1374
+
1375
+ return array( $last_run, $is_running ) ;
1376
+ }
1377
+
1378
+ /**
1379
+ * Update fetch cron timestamp tag
1380
+ *
1381
+ * @since 1.6.2
1382
+ * @access private
1383
+ */
1384
+ private function _update_cron_running( $done = false )
1385
+ {
1386
+ $ts = time() ;
1387
+
1388
+ if ( $done ) {
1389
+ // Only update cron tag when its from the active running cron
1390
+ if ( $this->_cron_ran ) {
1391
+ // Rollback for next running
1392
+ $ts -= 120 ;
1393
+ }
1394
+ else {
1395
+ return ;
1396
+ }
1397
+ }
1398
+
1399
+ update_option( self::ITEM_IMG_OPTM_CRON_RUN, $ts ) ;
1400
+
1401
+ $this->_cron_ran = true ;
1402
+ }
1403
+
1404
+ /**
1405
+ * Batch switch images to ori/optm version
1406
+ *
1407
+ * @since 1.6.2
1408
+ * @access private
1409
+ */
1410
+ private function _batch_switch( $type )
1411
+ {
1412
+ global $wpdb ;
1413
+ $q = "SELECT * FROM $this->_table_img_optm WHERE optm_status = %s" ;
1414
+ $list = $wpdb->get_results( $wpdb->prepare( $q, self::DB_IMG_OPTIMIZE_STATUS_PULLED ) ) ;
1415
+
1416
+ $i = 0 ;
1417
+ foreach ( $list as $v ) {
1418
+ $local_file = $this->wp_upload_dir[ 'basedir' ] . '/' . $v->src ;
1419
+
1420
+ $extension = pathinfo( $local_file, PATHINFO_EXTENSION ) ;
1421
+ $local_filename = substr( $local_file, 0, - strlen( $extension ) - 1 ) ;
1422
+ $bk_file = $local_filename . '.bk.' . $extension ;
1423
+ $bk_optm_file = $local_filename . '.bk.optm.' . $extension ;
1424
+
1425
+ // switch to ori
1426
+ if ( $type === self::TYPE_IMG_BATCH_SWITCH_ORI ) {
1427
+ if ( ! file_exists( $bk_file ) ) {
1428
+ continue ;
1429
+ }
1430
+
1431
+ $i ++ ;
1432
+
1433
+ rename( $local_file, $bk_optm_file ) ;
1434
+ rename( $bk_file, $local_file ) ;
1435
+ }
1436
+ // switch to optm
1437
+ elseif ( $type === self::TYPE_IMG_BATCH_SWITCH_OPTM ) {
1438
+ if ( ! file_exists( $bk_optm_file ) ) {
1439
+ continue ;
1440
+ }
1441
+
1442
+ $i ++ ;
1443
+
1444
+ rename( $local_file, $bk_file ) ;
1445
+ rename( $bk_optm_file, $local_file ) ;
1446
+ }
1447
+ }
1448
+
1449
+ LiteSpeed_Cache_Log::debug( '[Img_Optm] batch switched images total: ' . $i ) ;
1450
+
1451
+ }
1452
+
1453
+ /**
1454
+ * Switch image between original one and optimized one
1455
+ *
1456
+ * @since 1.6.2
1457
+ * @access private
1458
+ */
1459
+ private function _switch_optm_file( $type )
1460
+ {
1461
+ $pid = substr( $type, 4 ) ;
1462
+ $switch_type = substr( $type, 0, 4 ) ;
1463
+
1464
+ global $wpdb ;
1465
+ $q = "SELECT * FROM $this->_table_img_optm WHERE optm_status = %s AND post_id = %d" ;
1466
+ $list = $wpdb->get_results( $wpdb->prepare( $q, array( self::DB_IMG_OPTIMIZE_STATUS_PULLED, $pid ) ) ) ;
1467
+
1468
+ $msg = 'Unknown Msg' ;
1469
+
1470
+ foreach ( $list as $v ) {
1471
+ $local_file = $this->wp_upload_dir[ 'basedir' ] . '/' . $v->src ;
1472
+
1473
+ // to switch webp file
1474
+ if ( $switch_type === 'webp' ) {
1475
+ if ( file_exists( $local_file . '.webp' ) ) {
1476
+ rename( $local_file . '.webp', $local_file . '.optm.webp' ) ;
1477
+ LiteSpeed_Cache_Log::debug( '[Img_Optm] Disabled WebP: ' . $local_file ) ;
1478
+
1479
+ $msg = __( 'Disabled WebP file successfully.', 'litespeed-cache' ) ;
1480
+ }
1481
+ elseif ( file_exists( $local_file . '.optm.webp' ) ) {
1482
+ rename( $local_file . '.optm.webp', $local_file . '.webp' ) ;
1483
+ LiteSpeed_Cache_Log::debug( '[Img_Optm] Enable WebP: ' . $local_file ) ;
1484
+
1485
+ $msg = __( 'Enabled WebP file successfully.', 'litespeed-cache' ) ;
1486
+ }
1487
+ }
1488
+ // to switch original file
1489
+ else {
1490
+ $extension = pathinfo( $local_file, PATHINFO_EXTENSION ) ;
1491
+ $local_filename = substr( $local_file, 0, - strlen( $extension ) - 1 ) ;
1492
+ $bk_file = $local_filename . '.bk.' . $extension ;
1493
+ $bk_optm_file = $local_filename . '.bk.optm.' . $extension ;
1494
+
1495
+ // revert ori back
1496
+ if ( file_exists( $bk_file ) ) {
1497
+ rename( $local_file, $bk_optm_file ) ;
1498
+ rename( $bk_file, $local_file ) ;
1499
+ LiteSpeed_Cache_Log::debug( '[Img_Optm] Restore original img: ' . $bk_file ) ;
1500
+
1501
+ $msg = __( 'Restored original file successfully.', 'litespeed-cache' ) ;
1502
+ }
1503
+ elseif ( file_exists( $bk_optm_file ) ) {
1504
+ rename( $local_file, $bk_file ) ;
1505
+ rename( $bk_optm_file, $local_file ) ;
1506
+ LiteSpeed_Cache_Log::debug( '[Img_Optm] Switch to optm img: ' . $local_file ) ;
1507
+
1508
+ $msg = __( 'Switched to optimized file successfully.', 'litespeed-cache' ) ;
1509
+ }
1510
+
1511
+ }
1512
+ }
1513
+
1514
+ LiteSpeed_Cache_Admin_Display::add_notice( LiteSpeed_Cache_Admin_Display::NOTICE_GREEN, $msg ) ;
1515
+ }
1516
+
1517
+ /**
1518
+ * Handle all request actions from main cls
1519
+ *
1520
+ * @since 2.0
1521
+ * @access public
1522
+ */
1523
+ public static function handler()
1524
+ {
1525
+ $instance = self::get_instance() ;
1526
+
1527
+ $type = LiteSpeed_Cache_Router::verify_type() ;
1528
+
1529
+ switch ( $type ) {
1530
+ case self::TYPE_SYNC_DATA :
1531
+ $instance->_sync_data() ;
1532
+ break ;
1533
+
1534
+ case self::TYPE_IMG_OPTIMIZE :
1535
+ $instance->_request_optm() ;
1536
+ break ;
1537
+
1538
+ case self::TYPE_IMG_OPTIMIZE_RESCAN :
1539
+ $instance->_img_optimize_rescan() ;
1540
+ break ;
1541
+
1542
+ case self::TYPE_IMG_OPTIMIZE_DESTROY :
1543
+ $instance->_img_optimize_destroy() ;
1544
+ break ;
1545
+
1546
+ case self::TYPE_IMG_PULL :
1547
+ LiteSpeed_Cache_Log::debug( 'ImgOptm: Manually running Cron pull_optimized_img' ) ;
1548
+ $result = $instance->_pull_optimized_img( true ) ;
1549
+ // Manually running needs to roll back timestamp for next running
1550
+ $instance->_update_cron_running( true ) ;
1551
+
1552
+ // Check if need to self redirect
1553
+ if ( $result === 'to_be_continued' ) {
1554
+ $link = LiteSpeed_Cache_Utility::build_url( LiteSpeed_Cache::ACTION_IMG_OPTM, LiteSpeed_Cache_Img_Optm::TYPE_IMG_PULL ) ;
1555
+ LiteSpeed_Cache_Admin::redirect( html_entity_decode( $link ) ) ;
1556
+ }
1557
+ break ;
1558
+
1559
+ /**
1560
+ * Batch switch
1561
+ * @since 1.6.3
1562
+ */
1563
+ case self::TYPE_IMG_BATCH_SWITCH_ORI :
1564
+ case self::TYPE_IMG_BATCH_SWITCH_OPTM :
1565
+ $instance->_batch_switch( $type ) ;
1566
+ break ;
1567
+
1568
+ case substr( $type, 0, 4 ) === 'webp' :
1569
+ case substr( $type, 0, 4 ) === 'orig' :
1570
+ $instance->_switch_optm_file( $type ) ;
1571
+ break ;
1572
+
1573
+ default:
1574
+ break ;
1575
+ }
1576
+
1577
+ LiteSpeed_Cache_Admin::redirect() ;
1578
+ }
1579
+
1580
+ /**
1581
+ * Get the current guidance step
1582
+ *
1583
+ * @since 2.0
1584
+ * @access public
1585
+ */
1586
+ public function get_guidance_pos()
1587
+ {
1588
+ $guide_status = get_option( LiteSpeed_Cache_Config::ITEM_GUIDE ) ;
1589
+
1590
+ $current_step = 'done' ;
1591
+ if ( ! $guide_status || empty( $guide_status[ 'img_optm' ] ) || $guide_status[ 'img_optm' ] !== 'done' ) {
1592
+ $current_step = empty( $guide_status[ 'img_optm' ] ) ? 1 : $guide_status[ 'img_optm' ] ;
1593
+ }
1594
+
1595
+ return $current_step ;
1596
+ }
1597
+
1598
+ /**
1599
+ * Update current guidance step
1600
+ *
1601
+ * @since 2.0
1602
+ * @access private
1603
+ */
1604
+ private function _update_guidance_pos( $pos )
1605
+ {
1606
+ $guide_status = get_option( LiteSpeed_Cache_Config::ITEM_GUIDE ) ;
1607
+
1608
+ if ( ! $guide_status ) {
1609
+ $guide_status = array() ;
1610
+ }
1611
+
1612
+ if ( ! empty( $guide_status[ 'img_optm' ] ) && $guide_status[ 'img_optm' ] == $pos ) {
1613
+ LiteSpeed_Cache_Log::debug2( '[Img_Optm] _update_guidance_pos: bypassed due to same pos [step] ' . $pos ) ;
1614
+ return ;
1615
+ }
1616
+
1617
+ $guide_status[ 'img_optm' ] = $pos ;
1618
+
1619
+ LiteSpeed_Cache_Log::debug( '[Img_Optm] _update_guidance_pos [step] ' . $pos ) ;
1620
+
1621
+ update_option( LiteSpeed_Cache_Config::ITEM_GUIDE, $guide_status ) ;
1622
+ }
1623
+
1624
+ /**
1625
+ * Get the current instance object.
1626
+ *
1627
+ * @since 2.0
1628
+ * @access public
1629
+ * @return Current class instance.
1630
+ */
1631
+ public static function get_instance()
1632
+ {
1633
+ if ( ! isset( self::$_instance ) ) {
1634
+ self::$_instance = new self() ;
1635
+ }
1636
+
1637
+ return self::$_instance ;
1638
+ }
1639
+
1640
+ }
inc/import.class.php CHANGED
@@ -36,7 +36,7 @@ class LiteSpeed_Cache_Import
36
  LiteSpeed_Cache_Config::ITEM_OPTM_CSS,
37
  LiteSpeed_Cache_Config::ITEM_OPTM_JS_DEFER_EXC,
38
  LiteSpeed_Cache_Config::ITEM_MEDIA_LAZY_IMG_EXC,
39
- LiteSpeed_Cache_Config::ITEM_MEDIA_NEED_PULL,
40
  LiteSpeed_Cache_Config::ITEM_ENV_REF,
41
  LiteSpeed_Cache_Config::ITEM_CACHE_DROP_QS,
42
  LiteSpeed_Cache_Config::ITEM_CDN_MAPPING,
36
  LiteSpeed_Cache_Config::ITEM_OPTM_CSS,
37
  LiteSpeed_Cache_Config::ITEM_OPTM_JS_DEFER_EXC,
38
  LiteSpeed_Cache_Config::ITEM_MEDIA_LAZY_IMG_EXC,
39
+ LiteSpeed_Cache_Config::ITEM_IMG_OPTM_NEED_PULL,
40
  LiteSpeed_Cache_Config::ITEM_ENV_REF,
41
  LiteSpeed_Cache_Config::ITEM_CACHE_DROP_QS,
42
  LiteSpeed_Cache_Config::ITEM_CDN_MAPPING,
inc/litespeed-cache.class.php CHANGED
@@ -19,7 +19,7 @@ class LiteSpeed_Cache
19
  private static $_instance ;
20
 
21
  const PLUGIN_NAME = 'litespeed-cache' ;
22
- const PLUGIN_VERSION = '1.9.1.1' ;
23
 
24
  const PAGE_EDIT_HTACCESS = 'lscache-edit-htaccess' ;
25
 
@@ -47,6 +47,7 @@ class LiteSpeed_Cache
47
  const ACTION_CRAWLER_CRON_ENABLE = 'crawler-cron-enable' ;
48
  const ACTION_DO_CRAWL = 'do-crawl' ;
49
  const ACTION_BLACKLIST_SAVE = 'blacklist-save' ;
 
50
 
51
  const ACTION_FRONT_PURGE = 'front-purge' ;
52
  const ACTION_FRONT_EXCLUDE = 'front-exclude' ;
@@ -57,6 +58,7 @@ class LiteSpeed_Cache
57
  const ACTION_IMPORT = 'import' ;
58
  const ACTION_PURGE = 'purge' ;
59
  const ACTION_MEDIA = 'media' ;
 
60
  const ACTION_IAPI = 'iapi' ;
61
  const ACTION_CDN = 'cdn' ;
62
  const ACTION_REPORT = 'report' ;
@@ -328,6 +330,10 @@ class LiteSpeed_Cache
328
  $msg = LiteSpeed_Cache_Media::handler() ;
329
  break ;
330
 
 
 
 
 
331
  case LiteSpeed_Cache::ACTION_PURGE:
332
  $msg = LiteSpeed_Cache_Purge::handler() ;
333
  break ;
@@ -352,6 +358,10 @@ class LiteSpeed_Cache
352
  $msg = LiteSpeed_Cache_Import::handler() ;
353
  break ;
354
 
 
 
 
 
355
  default:
356
  break ;
357
  }
19
  private static $_instance ;
20
 
21
  const PLUGIN_NAME = 'litespeed-cache' ;
22
+ const PLUGIN_VERSION = '2.0' ;
23
 
24
  const PAGE_EDIT_HTACCESS = 'lscache-edit-htaccess' ;
25
 
47
  const ACTION_CRAWLER_CRON_ENABLE = 'crawler-cron-enable' ;
48
  const ACTION_DO_CRAWL = 'do-crawl' ;
49
  const ACTION_BLACKLIST_SAVE = 'blacklist-save' ;
50
+ const ACTION_QUIC_CLOUD = 'quic_cloud' ;
51
 
52
  const ACTION_FRONT_PURGE = 'front-purge' ;
53
  const ACTION_FRONT_EXCLUDE = 'front-exclude' ;
58
  const ACTION_IMPORT = 'import' ;
59
  const ACTION_PURGE = 'purge' ;
60
  const ACTION_MEDIA = 'media' ;
61
+ const ACTION_IMG_OPTM = 'img_optm' ;
62
  const ACTION_IAPI = 'iapi' ;
63
  const ACTION_CDN = 'cdn' ;
64
  const ACTION_REPORT = 'report' ;
330
  $msg = LiteSpeed_Cache_Media::handler() ;
331
  break ;
332
 
333
+ case LiteSpeed_Cache::ACTION_IMG_OPTM:
334
+ $msg = LiteSpeed_Cache_Img_Optm::handler() ;
335
+ break ;
336
+
337
  case LiteSpeed_Cache::ACTION_PURGE:
338
  $msg = LiteSpeed_Cache_Purge::handler() ;
339
  break ;
358
  $msg = LiteSpeed_Cache_Import::handler() ;
359
  break ;
360
 
361
+ case LiteSpeed_Cache::ACTION_QUIC_CLOUD:
362
+ $msg = LiteSpeed_Cache_QUIC_CLOUD::handler() ;
363
+ break ;
364
+
365
  default:
366
  break ;
367
  }
inc/litespeed.autoload.php CHANGED
@@ -34,11 +34,13 @@ if ( !function_exists('_litespeed_autoload') ) {
34
  'LiteSpeed_Cache_ESI' => 'inc/esi.class.php',
35
  'LiteSpeed_Cache_GUI' => 'inc/gui.class.php',
36
  'LiteSpeed_Cache_Import' => 'inc/import.class.php',
 
37
  'LiteSpeed_Cache_Log' => 'inc/log.class.php',
38
  'LiteSpeed_Cache_Media' => 'inc/media.class.php',
39
  'LiteSpeed_Cache_Object' => 'inc/object.class.php',
40
  'LiteSpeed_Cache_Optimize' => 'inc/optimize.class.php',
41
  'LiteSpeed_Cache_Optimizer' => 'inc/optimizer.class.php',
 
42
  'LiteSpeed_Cache_Purge' => 'inc/purge.class.php',
43
  'LiteSpeed_Cache_Router' => 'inc/router.class.php',
44
  'LiteSpeed_Cache_Tag' => 'inc/tag.class.php',
34
  'LiteSpeed_Cache_ESI' => 'inc/esi.class.php',
35
  'LiteSpeed_Cache_GUI' => 'inc/gui.class.php',
36
  'LiteSpeed_Cache_Import' => 'inc/import.class.php',
37
+ 'LiteSpeed_Cache_Img_Optm' => 'inc/img_optm.class.php',
38
  'LiteSpeed_Cache_Log' => 'inc/log.class.php',
39
  'LiteSpeed_Cache_Media' => 'inc/media.class.php',
40
  'LiteSpeed_Cache_Object' => 'inc/object.class.php',
41
  'LiteSpeed_Cache_Optimize' => 'inc/optimize.class.php',
42
  'LiteSpeed_Cache_Optimizer' => 'inc/optimizer.class.php',
43
+ 'LiteSpeed_Cache_QUIC_CLOUD' => 'inc/quic_cloud.class.php',
44
  'LiteSpeed_Cache_Purge' => 'inc/purge.class.php',
45
  'LiteSpeed_Cache_Router' => 'inc/router.class.php',
46
  'LiteSpeed_Cache_Tag' => 'inc/tag.class.php',
inc/media.class.php CHANGED
@@ -16,33 +16,8 @@ class LiteSpeed_Cache_Media
16
 
17
  const LAZY_LIB = '/min/lazyload.js' ;
18
 
19
- const TYPE_SYNC_DATA = 'sync_data' ;
20
- const TYPE_IMG_OPTIMIZE = 'img_optm' ;
21
- const TYPE_IMG_OPTIMIZE_RESCAN = 'img_optm_rescan' ;
22
- const TYPE_IMG_OPTIMIZE_DESTROY = 'img_optm_destroy' ;
23
- const TYPE_IMG_PULL = 'img_pull' ;
24
- const TYPE_IMG_BATCH_SWITCH_ORI = 'img_optm_batch_switch_ori' ;
25
- const TYPE_IMG_BATCH_SWITCH_OPTM = 'img_optm_batch_switch_optm' ;
26
- const OPT_CRON_RUN = 'litespeed-img_optm_cron_run' ; // last cron running time
27
-
28
- const DB_IMG_OPTIMIZE_DESTROY = 'litespeed-optimize-destroy' ;
29
- const DB_IMG_OPTIMIZE_DATA = 'litespeed-optimize-data' ;
30
- const DB_IMG_OPTIMIZE_STATUS = 'litespeed-optimize-status' ;
31
- const DB_IMG_OPTIMIZE_STATUS_REQUESTED = 'requested' ;
32
- const DB_IMG_OPTIMIZE_STATUS_NOTIFIED = 'notified' ;
33
- const DB_IMG_OPTIMIZE_STATUS_PULLED = 'pulled' ;
34
- const DB_IMG_OPTIMIZE_STATUS_FAILED = 'failed' ;
35
- const DB_IMG_OPTIMIZE_STATUS_ERR = 'err' ;
36
- const DB_IMG_OPTIMIZE_SIZE = 'litespeed-optimize-size' ;
37
-
38
- const DB_IMG_OPTM_SUMMARY = 'litespeed_img_optm_summary' ;
39
-
40
  private $content ;
41
  private $wp_upload_dir ;
42
- private $tmp_pid ;
43
- private $tmp_path ;
44
- private $_img_in_queue = array() ;
45
- private $_img_total = 0 ;
46
 
47
  private $cfg_img_webp ;
48
 
@@ -111,7 +86,7 @@ class LiteSpeed_Cache_Media
111
  */
112
  public function after_admin_init()
113
  {
114
- if ( get_option( LiteSpeed_Cache_Config::ITEM_MEDIA_NEED_PULL ) ) {
115
  add_filter( 'manage_media_columns', array( $this, 'media_row_title' ) ) ;
116
  add_filter( 'manage_media_custom_column', array( $this, 'media_row_actions' ), 10, 2 ) ;
117
  }
@@ -144,7 +119,7 @@ class LiteSpeed_Cache_Media
144
 
145
  $local_file = get_attached_file( $post_id ) ;
146
 
147
- $link = LiteSpeed_Cache_Utility::build_url( LiteSpeed_Cache::ACTION_MEDIA, 'webp' . $post_id ) ;
148
  $desc = false ;
149
  $cls = 'litespeed-icon-media-webp' ;
150
  $cls_webp = '' ;
@@ -167,7 +142,7 @@ class LiteSpeed_Cache_Media
167
  $bk_file = substr( $local_file, 0, -strlen( $extension ) ) . 'bk.' . $extension ;
168
  $bk_optm_file = substr( $local_file, 0, -strlen( $extension ) ) . 'bk.optm.' . $extension ;
169
 
170
- $link = LiteSpeed_Cache_Utility::build_url( LiteSpeed_Cache::ACTION_MEDIA, 'orig' . $post_id ) ;
171
  $desc = false ;
172
  $cls = 'litespeed-icon-media-optm' ;
173
  $cls_ori = '' ;
@@ -187,7 +162,7 @@ class LiteSpeed_Cache_Media
187
  }
188
 
189
  $info_webp = '' ;
190
- $size_meta = get_post_meta( $post_id, self::DB_IMG_OPTIMIZE_SIZE, true ) ;
191
  if ( $size_meta && ! empty ( $size_meta[ 'webp_saved' ] ) ) {
192
  $percent = ceil( $size_meta[ 'webp_saved' ] * 100 / $size_meta[ 'webp_total' ] ) ;
193
  $pie_webp = LiteSpeed_Cache_GUI::pie( $percent, 30 ) ;
@@ -208,143 +183,6 @@ class LiteSpeed_Cache_Media
208
  echo "<p class='litespeed-media-p $cls_webp'>$info_webp $link_webp</p><p class='litespeed-media-p $cls_ori'>$info_ori $link_ori</p>" ;
209
  }
210
 
211
- /**
212
- * Batch switch images to ori/optm version
213
- *
214
- * @since 1.6.2
215
- * @access private
216
- */
217
- private function _batch_switch( $type )
218
- {
219
- global $wpdb ;
220
- $q = "SELECT meta_value
221
- FROM $wpdb->postmeta
222
- WHERE meta_key = %s
223
- " ;
224
- $cond = array( self::DB_IMG_OPTIMIZE_DATA ) ;
225
- $meta_value_lists = $wpdb->get_results( $wpdb->prepare( $q, $cond ) ) ;
226
-
227
- $i = 0 ;
228
- foreach ( $meta_value_lists as $v ) {
229
- $meta_value_list = unserialize( $v->meta_value ) ;
230
-
231
- foreach ( $meta_value_list as $v2 ) {
232
- if ( $v2[ 1 ] !== 'pulled' ) {
233
- continue ;
234
- }
235
-
236
- $src = $v2[ 0 ] ;
237
- $local_file = $this->wp_upload_dir[ 'basedir' ] . '/' . $src ;
238
-
239
- $extension = pathinfo( $local_file, PATHINFO_EXTENSION ) ;
240
- $local_filename = substr( $local_file, 0, - strlen( $extension ) - 1 ) ;
241
- $bk_file = $local_filename . '.bk.' . $extension ;
242
- $bk_optm_file = $local_filename . '.bk.optm.' . $extension ;
243
-
244
- // switch to ori
245
- if ( $type === self::TYPE_IMG_BATCH_SWITCH_ORI ) {
246
- if ( ! file_exists( $bk_file ) ) {
247
- continue ;
248
- }
249
-
250
- $i ++ ;
251
-
252
- rename( $local_file, $bk_optm_file ) ;
253
- rename( $bk_file, $local_file ) ;
254
- }
255
- // switch to optm
256
- elseif ( $type === self::TYPE_IMG_BATCH_SWITCH_OPTM ) {
257
- if ( ! file_exists( $bk_optm_file ) ) {
258
- continue ;
259
- }
260
-
261
- $i ++ ;
262
-
263
- rename( $local_file, $bk_file ) ;
264
- rename( $bk_optm_file, $local_file ) ;
265
- }
266
-
267
- }
268
- }
269
-
270
- LiteSpeed_Cache_Log::debug( 'Media: batch switched images total: ' . $i ) ;
271
-
272
- }
273
-
274
- /**
275
- * Switch image between original one and optimized one
276
- *
277
- * @since 1.6.2
278
- * @access private
279
- */
280
- private function _switch_optm_file( $type )
281
- {
282
- $pid = substr( $type, 4 ) ;
283
- $switch_type = substr( $type, 0, 4 ) ;
284
-
285
- global $wpdb ;
286
- $q = "SELECT meta_value
287
- FROM $wpdb->postmeta
288
- WHERE post_id = %d AND meta_key = %s
289
- " ;
290
- $cond = array( $pid, self::DB_IMG_OPTIMIZE_DATA ) ;
291
- $meta_value_list = $wpdb->get_var( $wpdb->prepare( $q, $cond ) ) ;
292
- $meta_value_list = unserialize( $meta_value_list ) ;
293
-
294
- $msg = 'Unknown Msg' ;
295
-
296
- foreach ( $meta_value_list as $v ) {
297
- if ( $v[ 1 ] !== 'pulled' ) {
298
- continue ;
299
- }
300
-
301
- $src = $v[ 0 ] ;
302
- $local_file = $this->wp_upload_dir[ 'basedir' ] . '/' . $src ;
303
-
304
- // to switch webp file
305
- if ( $switch_type === 'webp' ) {
306
- if ( file_exists( $local_file . '.webp' ) ) {
307
- rename( $local_file . '.webp', $local_file . '.optm.webp' ) ;
308
- LiteSpeed_Cache_Log::debug( 'Media: Disabled WebP: ' . $local_file ) ;
309
-
310
- $msg = __( 'Disabled WebP file successfully.', 'litespeed-cache' ) ;
311
- }
312
- elseif ( file_exists( $local_file . '.optm.webp' ) ) {
313
- rename( $local_file . '.optm.webp', $local_file . '.webp' ) ;
314
- LiteSpeed_Cache_Log::debug( 'Media: Enable WebP: ' . $local_file ) ;
315
-
316
- $msg = __( 'Enabled WebP file successfully.', 'litespeed-cache' ) ;
317
- }
318
- }
319
- // to switch original file
320
- else {
321
- $extension = pathinfo( $local_file, PATHINFO_EXTENSION ) ;
322
- $local_filename = substr( $local_file, 0, - strlen( $extension ) - 1 ) ;
323
- $bk_file = $local_filename . '.bk.' . $extension ;
324
- $bk_optm_file = $local_filename . '.bk.optm.' . $extension ;
325
-
326
- // revert ori back
327
- if ( file_exists( $bk_file ) ) {
328
- rename( $local_file, $bk_optm_file ) ;
329
- rename( $bk_file, $local_file ) ;
330
- LiteSpeed_Cache_Log::debug( 'Media: Restore original img: ' . $bk_file ) ;
331
-
332
- $msg = __( 'Restored original file successfully.', 'litespeed-cache' ) ;
333
- }
334
- elseif ( file_exists( $bk_optm_file ) ) {
335
- rename( $local_file, $bk_file ) ;
336
- rename( $bk_optm_file, $local_file ) ;
337
- LiteSpeed_Cache_Log::debug( 'Media: Switch to optm img: ' . $local_file ) ;
338
-
339
- $msg = __( 'Switched to optimized file successfully.', 'litespeed-cache' ) ;
340
- }
341
-
342
- }
343
- }
344
-
345
- LiteSpeed_Cache_Admin_Display::add_notice( LiteSpeed_Cache_Admin_Display::NOTICE_GREEN, $msg ) ;
346
- }
347
-
348
  /**
349
  * Get wp size info
350
  *
@@ -420,34 +258,6 @@ class LiteSpeed_Cache_Media
420
  }
421
  }
422
 
423
- /**
424
- * Sync data from litespeed IAPI server
425
- *
426
- * @since 1.6.5
427
- * @access private
428
- */
429
- private function _sync_data()
430
- {
431
- $json = LiteSpeed_Cache_Admin_API::post( LiteSpeed_Cache_Admin_API::IAPI_ACTION_MEDIA_SYNC_DATA ) ;
432
-
433
- if ( ! is_array( $json ) ) {
434
- LiteSpeed_Cache_Log::debug( 'Media: Failed to post to LiteSpeed IAPI server ', $json ) ;
435
- $msg = __( 'Failed to communicate with LiteSpeed IAPI server', 'litespeed-cache' ) . ': ' . $json ;
436
- LiteSpeed_Cache_Admin_Display::error( $msg ) ;
437
- return ;
438
- }
439
-
440
- if ( ! empty( $json ) ) {
441
- update_option( self::DB_IMG_OPTM_SUMMARY, $json ) ;
442
- }
443
-
444
- $msg = __( 'Communicated with LiteSpeed Image Optimization Server successfully.', 'litespeed-cache' ) ;
445
- LiteSpeed_Cache_Admin_Display::succeed( $msg ) ;
446
-
447
- LiteSpeed_Cache_Admin::redirect() ;
448
-
449
- }
450
-
451
  /**
452
  * Handle all request actions from main cls
453
  *
@@ -461,41 +271,6 @@ class LiteSpeed_Cache_Media
461
  $type = LiteSpeed_Cache_Router::verify_type() ;
462
 
463
  switch ( $type ) {
464
- /**
465
- * Batch switch
466
- * @since 1.6.3
467
- */
468
- case self::TYPE_IMG_BATCH_SWITCH_ORI :
469
- case self::TYPE_IMG_BATCH_SWITCH_OPTM :
470
- $instance->_batch_switch( $type ) ;
471
- break ;
472
-
473
- case self::TYPE_SYNC_DATA :
474
- $instance->_sync_data() ;
475
- break ;
476
-
477
- case self::TYPE_IMG_OPTIMIZE :
478
- $instance->_img_optimize() ;
479
- break ;
480
-
481
- case self::TYPE_IMG_OPTIMIZE_RESCAN :
482
- $instance->_img_optimize_rescan() ;
483
- break ;
484
-
485
- case self::TYPE_IMG_OPTIMIZE_DESTROY :
486
- $instance->_img_optimize_destroy() ;
487
- break ;
488
-
489
- case self::TYPE_IMG_PULL :
490
- LiteSpeed_Cache_Log::debug( 'Media: Manually running Cron pull_optimized_img' ) ;
491
- $instance->_pull_optimized_img() ;
492
- break ;
493
-
494
- case substr( $type, 0, 4 ) === 'webp' :
495
- case substr( $type, 0, 4 ) === 'orig' :
496
- $instance->_switch_optm_file( $type ) ;
497
- break ;
498
-
499
  default:
500
  break ;
501
  }
@@ -503,1024 +278,6 @@ class LiteSpeed_Cache_Media
503
  LiteSpeed_Cache_Admin::redirect() ;
504
  }
505
 
506
- /**
507
- * Check if fetch cron is running
508
- *
509
- * @since 1.6.2
510
- * @access public
511
- */
512
- public function cron_running( $bool_res = true )
513
- {
514
- $last_run = get_option( self::OPT_CRON_RUN ) ;
515
-
516
- $is_running = $last_run && time() - $last_run <= 120 ;
517
-
518
- if ( $bool_res ) {
519
- return $is_running ;
520
- }
521
-
522
- return array( $last_run, $is_running ) ;
523
- }
524
-
525
- /**
526
- * Update fetch cron timestamp tag
527
- *
528
- * @since 1.6.2
529
- * @access private
530
- */
531
- private function _update_cron_running()
532
- {
533
- update_option( self::OPT_CRON_RUN, time() ) ;
534
- }
535
-
536
- /**
537
- * Pull optimized img
538
- *
539
- * @since 1.6
540
- * @access public
541
- */
542
- public static function pull_optimized_img()
543
- {
544
- LiteSpeed_Cache_Log::debug( 'Media: Cron pull_optimized_img started' ) ;
545
- $instance = self::get_instance() ;
546
- $instance->_pull_optimized_img() ;
547
- }
548
-
549
- /**
550
- * Pull optimized img
551
- *
552
- * @since 1.6
553
- * @access private
554
- */
555
- private function _pull_optimized_img()
556
- {
557
- if ( $this->cron_running() ) {
558
- LiteSpeed_Cache_Log::debug( 'Media: fetch cron is running' ) ;
559
- return ;
560
- }
561
-
562
- global $wpdb ;
563
-
564
- $q = "SELECT a.meta_id, a.post_id, b.meta_id as bmeta_id, b.meta_value, c.meta_id as cmeta_id, c.meta_value as cmeta_value
565
- FROM $wpdb->postmeta a
566
- LEFT JOIN $wpdb->postmeta b ON b.post_id = a.post_id
567
- LEFT JOIN $wpdb->postmeta c ON c.post_id = a.post_id AND c.meta_key = %s
568
- WHERE a.meta_key = %s AND a.meta_value = %s AND b.meta_key = %s
569
- ORDER BY a.post_id DESC
570
- LIMIT 1
571
- " ;
572
- $cond = array( self::DB_IMG_OPTIMIZE_SIZE, self::DB_IMG_OPTIMIZE_STATUS, self::DB_IMG_OPTIMIZE_STATUS_NOTIFIED, self::DB_IMG_OPTIMIZE_DATA ) ;
573
- $query = $wpdb->prepare( $q, $cond ) ;
574
-
575
- $webp_only = LiteSpeed_Cache::config( LiteSpeed_Cache_Config::OPID_MEDIA_IMG_WEBP_ONLY ) ;
576
-
577
- for ( $i=0 ; $i < 10 ; $i++ ) {
578
- $meta_value_row = $wpdb->get_row( $query ) ;
579
-
580
- if ( ! $meta_value_row ) {
581
- break ;
582
- }
583
-
584
- $meta_value = unserialize( $meta_value_row->meta_value ) ;
585
-
586
- if ( $meta_value_row->cmeta_value ) {
587
- $cmeta_value = unserialize( $meta_value_row->cmeta_value ) ;
588
- }
589
- else {
590
- $cmeta_value = array(
591
- 'ori_total' => 0,
592
- 'ori_saved' => 0,
593
- 'webp_total' => 0,
594
- 'webp_saved' => 0,
595
- ) ;
596
- }
597
-
598
- // Start fetching
599
- foreach ( $meta_value as $md5 => $v2 ) {
600
-
601
- /**
602
- * Update cron timestamp to avoid duplicated running
603
- * @since 1.6.2
604
- */
605
- $this->_update_cron_running() ;
606
-
607
- if ( $v2[ 1 ] === self::DB_IMG_OPTIMIZE_STATUS_NOTIFIED ) {
608
- $server = $v2[ 2 ] ;
609
- // send fetch request
610
- $data = array(
611
- 'pid' => $meta_value_row->post_id,
612
- 'src_md5' => $md5,
613
- 'meta' => $meta_value_row->meta_value,
614
- ) ;
615
- $json = LiteSpeed_Cache_Admin_API::post( LiteSpeed_Cache_Admin_API::IAPI_ACTION_PULL_IMG, $data, $server ) ;
616
- if ( empty( $json[ 'webp' ] ) ) {
617
- LiteSpeed_Cache_Log::debug( 'Media: Failed to pull optimized img: ', $json ) ;
618
- return ;
619
- }
620
-
621
- $local_file = $this->wp_upload_dir[ 'basedir' ] . '/' . $v2[ 0 ] ;
622
- $ori_size = filesize( $local_file ) ;
623
-
624
- /**
625
- * Use wp orignal get func to avoid allow_url_open off issue
626
- * @since 1.6.5
627
- */
628
- // Fetch webp image
629
- $response = wp_remote_get( $json[ 'webp' ], array( 'timeout' => 15 ) ) ;
630
- if ( is_wp_error( $response ) ) {
631
- $error_message = $response->get_error_message() ;
632
- LiteSpeed_Cache_Log::debug( 'IAPI failed to pull image: ' . $error_message ) ;
633
- return ;
634
- }
635
-
636
- file_put_contents( $local_file . '.webp', $response[ 'body' ] ) ;
637
-
638
- if ( ! file_exists( $local_file . '.webp' ) ) {
639
- return ;
640
- }
641
-
642
- // Unknown issue
643
- if ( md5_file( $local_file . '.webp' ) !== $json[ 'webp_md5' ] ) {
644
- LiteSpeed_Cache_Log::debug( 'Media: Failed to pull optimized img WebP: file md5 dismatch, server md5: ' . $json[ 'webp_md5' ] ) ;
645
-
646
- // update status to failed
647
- $meta_value[ $md5 ][ 1 ] = self::DB_IMG_OPTIMIZE_STATUS_FAILED ;
648
- $q = "UPDATE $wpdb->postmeta SET meta_value = %s WHERE meta_id = %d ";
649
- $wpdb->query( $wpdb->prepare( $q, array( serialize( $meta_value ), $meta_value_row->bmeta_id ) ) ) ;
650
-
651
- // Notify server to update status
652
- LiteSpeed_Cache_Admin_API::post( LiteSpeed_Cache_Admin_API::IAPI_ACTION_PULL_IMG_FAILED, $data, $server ) ;
653
-
654
- return ;// exit from running pull process
655
- }
656
-
657
- // log webp file saved size summary
658
- $saved = $ori_size - filesize( $local_file . '.webp' ) ;
659
- if ( $saved > 0 ) {
660
- $cmeta_value[ 'webp_total' ] += $ori_size ;
661
- $cmeta_value[ 'webp_saved' ] += $saved ;
662
- }
663
-
664
- LiteSpeed_Cache_Log::debug( 'Media: Pulled optimized img WebP: ' . $local_file . '.webp' ) ;
665
-
666
- // Fetch optimized image itself
667
- if ( ! $webp_only && ! empty( $json[ 'target_file' ] ) ) {
668
-
669
- // Fetch failed, unkown issue, return
670
- // NOTE: if this failed more than 5 times, next time fetching webp will touch err limit on server side, whole image will be failed
671
- $response = wp_remote_get( $json[ 'target_file' ], array( 'timeout' => 15 ) ) ;
672
- if ( is_wp_error( $response ) ) {
673
- $error_message = $response->get_error_message() ;
674
- LiteSpeed_Cache_Log::debug( 'IAPI failed to pull image: ' . $error_message ) ;
675
- return ;
676
- }
677
-
678
- file_put_contents( $local_file . '.tmp', $response[ 'body' ] ) ;
679
- // Unknown issue
680
- if ( md5_file( $local_file . '.tmp' ) !== $json[ 'target_md5' ] ) {
681
- LiteSpeed_Cache_Log::debug( 'Media: Failed to pull optimized img iteself: file md5 dismatch, server md5: ' . $json[ 'target_md5' ] ) ;
682
-
683
- // update status to failed
684
- $meta_value[ $md5 ][ 1 ] = self::DB_IMG_OPTIMIZE_STATUS_FAILED ;
685
- $q = "UPDATE $wpdb->postmeta SET meta_value = %s WHERE meta_id = %d ";
686
- $wpdb->query( $wpdb->prepare( $q, array( serialize( $meta_value ), $meta_value_row->bmeta_id ) ) ) ;
687
-
688
- // Notify server to update status
689
- LiteSpeed_Cache_Admin_API::post( LiteSpeed_Cache_Admin_API::IAPI_ACTION_PULL_IMG_FAILED, $data, $server ) ;
690
-
691
- return ; // exit from running pull process
692
- }
693
-
694
- // log webp file saved size summary
695
- $saved = $ori_size - filesize( $local_file . '.tmp' ) ;
696
- if ( $saved > 0 ) {
697
- $cmeta_value[ 'ori_total' ] += $ori_size ;
698
- $cmeta_value[ 'ori_saved' ] += $saved ;
699
- }
700
-
701
- // Backup ori img
702
- $extension = pathinfo( $local_file, PATHINFO_EXTENSION ) ;
703
- $bk_file = substr( $local_file, 0, -strlen( $extension ) ) . 'bk.' . $extension ;
704
- rename( $local_file, $bk_file ) ;
705
-
706
- // Replace ori img
707
- rename( $local_file . '.tmp', $local_file ) ;
708
-
709
- LiteSpeed_Cache_Log::debug( 'Media: Pulled optimized img: ' . $local_file ) ;
710
- }
711
-
712
-
713
- // Update meta value
714
- $meta_value[ $md5 ][ 1 ] = self::DB_IMG_OPTIMIZE_STATUS_PULLED ;
715
- }
716
- }
717
-
718
- LiteSpeed_Cache_Log::debug( 'Media: Pulled optimized img done, updating record pid: ' . $meta_value_row->post_id ) ;
719
-
720
- // Update data tag
721
- $q = "UPDATE $wpdb->postmeta SET meta_value = %s WHERE meta_id = %d ";
722
- $wpdb->query( $wpdb->prepare( $q, array( serialize( $meta_value ), $meta_value_row->bmeta_id ) ) ) ;
723
-
724
- /**
725
- * Update size saved info
726
- * @since 1.6.5
727
- */
728
- if ( $meta_value_row->cmeta_id ) {
729
- $q = "UPDATE $wpdb->postmeta SET meta_value = %s WHERE meta_id = %d ";
730
- $wpdb->query( $wpdb->prepare( $q, array( serialize( $cmeta_value ), $meta_value_row->cmeta_id ) ) ) ;
731
- }
732
- else {
733
- $q = "INSERT INTO $wpdb->postmeta SET meta_value = %s, meta_id = %d, meta_key = %s, post_id = %d ";
734
- $wpdb->query( $wpdb->prepare( $q, array( serialize( $cmeta_value ), $meta_value_row->cmeta_id, self::DB_IMG_OPTIMIZE_SIZE, $meta_value_row->post_id ) ) ) ;
735
- }
736
-
737
- // Update status tag if all pulled or still has requested img
738
- $has_notify = false ;// it may be bypassed in above loop
739
- $has_request = false ;
740
- foreach ( $meta_value as $v2 ) {
741
- if ( $v2[ 1 ] === self::DB_IMG_OPTIMIZE_STATUS_REQUESTED ) {
742
- $has_request = true ;
743
- }
744
- if ( $v2[ 1 ] === self::DB_IMG_OPTIMIZE_STATUS_NOTIFIED ) {
745
- $has_notify = true ;
746
- }
747
- }
748
-
749
- $q = "UPDATE $wpdb->postmeta SET meta_value = %s WHERE meta_id = %d ";
750
-
751
- // Update pid status
752
- if ( ! $has_notify ) {
753
- $new_status = self::DB_IMG_OPTIMIZE_STATUS_PULLED ;
754
- if ( $has_request ) {
755
- $new_status = self::DB_IMG_OPTIMIZE_STATUS_REQUESTED ;
756
- }
757
- LiteSpeed_Cache_Log::debug( 'Media: Updated pid status: ' . $new_status ) ;
758
-
759
- $wpdb->query( $wpdb->prepare( $q, array( $new_status, $meta_value_row->meta_id ) ) ) ;
760
- }
761
- }
762
-
763
- // If all pulled, update tag to done
764
- $q = "SELECT * FROM $wpdb->postmeta WHERE meta_key = %s AND meta_value = %s LIMIT 1" ;
765
- $meta_value_list = $wpdb->get_row( $wpdb->prepare( $q, array( self::DB_IMG_OPTIMIZE_STATUS, self::DB_IMG_OPTIMIZE_STATUS_NOTIFIED ) ) ) ;
766
- if ( ! $meta_value_list ) {
767
- LiteSpeed_Cache_Log::debug( 'Media: Marked poll status to all pulled ' ) ;
768
- update_option( LiteSpeed_Cache_Config::ITEM_MEDIA_NEED_PULL, self::DB_IMG_OPTIMIZE_STATUS_PULLED ) ;
769
- }
770
- }
771
-
772
- /**
773
- * Check if need to do a pull for optimized img
774
- *
775
- * @since 1.6
776
- * @access public
777
- */
778
- public static function check_need_pull()
779
- {
780
- $tag = get_option( LiteSpeed_Cache_Config::ITEM_MEDIA_NEED_PULL ) ;
781
- return defined( 'DOING_CRON' ) && $tag && $tag === self::DB_IMG_OPTIMIZE_STATUS_NOTIFIED ;
782
- }
783
-
784
- /**
785
- * Show an image's optm status
786
- *
787
- * @since 1.6.5
788
- * @access public
789
- */
790
- public function check_img()
791
- {
792
- $pid = $_POST[ 'data' ] ;
793
-
794
- LiteSpeed_Cache_Log::debug( 'Media: Check image [ID] ' . $pid ) ;
795
-
796
- $data = array() ;
797
-
798
- $data[ 'img_count' ] = $this->img_count() ;
799
-
800
- $info = get_post_meta( $pid, self::DB_IMG_OPTIMIZE_STATUS, true ) ;
801
- $data[ self::DB_IMG_OPTIMIZE_STATUS ] = $info ;
802
-
803
- $info = get_post_meta( $pid, self::DB_IMG_OPTIMIZE_DATA, true ) ;
804
- $data[ self::DB_IMG_OPTIMIZE_DATA ] = $info ;
805
-
806
- echo json_encode( $data ) ;
807
- exit;
808
- }
809
-
810
- /**
811
- * parse LiteSpeed IAPI server data
812
- *
813
- * @since 1.6.5
814
- * @access public
815
- */
816
- private function _parse_notify_data()
817
- {
818
- $notified_data = unserialize( base64_decode( $_POST[ 'data' ] ) ) ;
819
- if ( empty( $notified_data ) || ! is_array( $notified_data ) ) {
820
- LiteSpeed_Cache_Log::debug( 'Media: notify exit: no notified data' ) ;
821
- exit( json_encode( 'no notified data' ) ) ;
822
- }
823
-
824
- if ( empty( $_POST[ 'server' ] ) || substr( $_POST[ 'server' ], -21 ) !== 'api.litespeedtech.com' ) {
825
- LiteSpeed_Cache_Log::debug( 'Media: notify exit: no/wrong server' ) ;
826
- exit( json_encode( 'no/wrong server' ) ) ;
827
- }
828
-
829
- $_allowed_status = array( self::DB_IMG_OPTIMIZE_STATUS_NOTIFIED, self::DB_IMG_OPTIMIZE_STATUS_ERR, self::DB_IMG_OPTIMIZE_STATUS_REQUESTED ) ;
830
-
831
- if ( empty( $_POST[ 'status' ] ) || ! in_array( $_POST[ 'status' ], $_allowed_status ) ) {
832
- LiteSpeed_Cache_Log::debug( 'Media: notify exit: no/wrong status' ) ;
833
- exit( json_encode( 'no/wrong status' ) ) ;
834
- }
835
-
836
- return array( $notified_data, $_POST[ 'server' ], $_POST[ 'status' ] ) ;
837
- }
838
-
839
- /**
840
- * LiteSpeed Child server notify Client img status changed
841
- *
842
- * @since 1.6
843
- * @since 1.6.5 Added err/request status free switch
844
- * @access public
845
- */
846
- public function notify_img()
847
- {
848
- list( $notified_data, $server, $status ) = $this->_parse_notify_data() ;
849
-
850
- global $wpdb ;
851
-
852
- $pids = array_keys( $notified_data ) ;
853
-
854
- $q = "SELECT meta_id, post_id, meta_value FROM $wpdb->postmeta WHERE post_id IN ( " . implode( ',', array_fill( 0, count( $pids ), '%d' ) ) . " ) AND meta_key = %s" ;
855
- $meta_value_list = $wpdb->get_results( $wpdb->prepare( $q, array_merge( $pids, array( self::DB_IMG_OPTIMIZE_DATA ) ) ) ) ;
856
-
857
- $need_pull = false ;
858
-
859
- foreach ( $meta_value_list as $v ) {
860
- $changed = false ;
861
- $md52src_list = unserialize( $v->meta_value ) ;
862
- // replace src tag from requested to notified
863
- foreach ( $md52src_list as $md5 => $v2 ) {
864
- if ( in_array( $md5, $notified_data[ $v->post_id ] ) && $v2[ 1 ] !== self::DB_IMG_OPTIMIZE_STATUS_PULLED ) {
865
- $md52src_list[ $md5 ][ 1 ] = $status ;
866
- $md52src_list[ $md5 ][ 2 ] = $server ;
867
- $changed = true ;
868
- }
869
- }
870
-
871
- if ( ! $changed ) {
872
- LiteSpeed_Cache_Log::debug( 'Media: notify_img [status] ' . $status . ' continue: no changed meta [pid] ' . $v->post_id ) ;
873
- continue ;
874
- }
875
-
876
- $new_status = $this->_get_status_by_meta_data( $md52src_list, $status ) ;
877
-
878
- // Save meta data
879
- $md52src_list = serialize( $md52src_list ) ;
880
- $q = "UPDATE $wpdb->postmeta SET meta_value = %s WHERE meta_id = %d" ;
881
- $wpdb->query( $wpdb->prepare( $q, array( $md52src_list, $v->meta_id ) ) ) ;
882
-
883
- // Overwrite post meta status to the latest one
884
- $q = "UPDATE $wpdb->postmeta SET meta_value = %s WHERE post_id = %d AND meta_key = %s" ;
885
- // If partly needs notified to pull, notified should overwrite this post's status always
886
- $wpdb->query( $wpdb->prepare( $q, array( $new_status, $v->post_id, self::DB_IMG_OPTIMIZE_STATUS ) ) ) ;
887
-
888
- LiteSpeed_Cache_Log::debug( 'Media: notify_img [status] ' . $status . ' updated post_meta [pid] ' . $v->post_id ) ;
889
-
890
- if ( $status == self::DB_IMG_OPTIMIZE_STATUS_NOTIFIED ) {
891
- $need_pull = true ;
892
- }
893
- }
894
-
895
- if ( $need_pull ) {
896
- update_option( LiteSpeed_Cache_Config::ITEM_MEDIA_NEED_PULL, self::DB_IMG_OPTIMIZE_STATUS_NOTIFIED ) ;
897
- }
898
-
899
- // redo count err
900
-
901
- echo json_encode( array( 'count' => count( $notified_data ) ) ) ;
902
- exit() ;
903
- }
904
-
905
- /**
906
- * Generate post's img optm status from child images meta value
907
- *
908
- * @since 1.6.7
909
- * @access private
910
- */
911
- private function _get_status_by_meta_data( $md52src_list, $default_status )
912
- {
913
- $has_notify = false ;
914
- $has_request = false ;
915
- $has_pull = false ;
916
-
917
- foreach ( $md52src_list as $v ) {
918
- if ( $v[ 1 ] == self::DB_IMG_OPTIMIZE_STATUS_NOTIFIED ) {
919
- $has_notify = true ;
920
- }
921
- if ( $v[ 1 ] == self::DB_IMG_OPTIMIZE_STATUS_REQUESTED ) {
922
- $has_request = true ;
923
- }
924
- if ( $v[ 1 ] == self::DB_IMG_OPTIMIZE_STATUS_PULLED ) {
925
- $has_pull = true ;
926
- }
927
- }
928
-
929
- if ( $has_notify ) {
930
- $new_status = self::DB_IMG_OPTIMIZE_STATUS_NOTIFIED ;
931
- }
932
- elseif ( $has_request ) {
933
- $new_status = self::DB_IMG_OPTIMIZE_STATUS_REQUESTED ;
934
- }
935
- elseif ( $has_pull ) {
936
- $new_status = self::DB_IMG_OPTIMIZE_STATUS_PULLED ;
937
- }
938
- else {
939
- $new_status = $default_status ;
940
- }
941
-
942
- return $new_status ;
943
-
944
- }
945
-
946
- /**
947
- * Parse wp's meta value
948
- *
949
- * @since 1.6.7
950
- * @access private
951
- */
952
- private function _parse_wp_meta_value( $v )
953
- {
954
- if ( ! $v->meta_value ) {
955
- LiteSpeed_Cache_Log::debug( 'Media: bypassed parsing meta due to no meta_value: pid ' . $v->post_id ) ;
956
- return false ;
957
- }
958
-
959
- try {
960
- $meta_value = unserialize( $v->meta_value ) ;
961
- }
962
- catch ( \Exception $e ) {
963
- LiteSpeed_Cache_Log::debug( 'Media: bypassed parsing meta due to meta_value not json: pid ' . $v->post_id ) ;
964
- return false ;
965
- }
966
-
967
- if ( empty( $meta_value[ 'file' ] ) ) {
968
- LiteSpeed_Cache_Log::debug( 'Media: bypassed parsing meta due to no ori file: pid ' . $v->post_id ) ;
969
- return false ;
970
- }
971
-
972
- return $meta_value ;
973
-
974
- }
975
-
976
- /**
977
- * Push img to LiteSpeed IAPI server
978
- *
979
- * @since 1.6.7
980
- * @access private
981
- */
982
- private function _push_img_in_queue_to_ls()
983
- {
984
- $data = array(
985
- 'list' => $this->_img_in_queue,
986
- 'webp_only' => LiteSpeed_Cache::config( LiteSpeed_Cache_Config::OPID_MEDIA_IMG_WEBP_ONLY ),
987
- 'keep_exif' => LiteSpeed_Cache::config( LiteSpeed_Cache_Config::OPID_MEDIA_IMG_EXIF ),
988
- 'webp_lossless' => LiteSpeed_Cache::config( LiteSpeed_Cache_Config::OPID_MEDIA_IMG_WEBP_LOSSLESS ),
989
- ) ;
990
-
991
- // Push to LiteSpeed IAPI server
992
- $json = LiteSpeed_Cache_Admin_API::post( LiteSpeed_Cache_Admin_API::IAPI_ACTION_REQUEST_OPTIMIZE, LiteSpeed_Cache_Utility::arr2str( $data ) ) ;
993
-
994
- if ( $json === null ) {// admin_api will handle common err
995
- return null ;
996
- }
997
-
998
- if ( ! is_array( $json ) ) {
999
- LiteSpeed_Cache_Log::debug( 'Media: Failed to post to LiteSpeed IAPI server ', $json ) ;
1000
- $msg = sprintf( __( 'Failed to push to LiteSpeed IAPI server: %s', 'litespeed-cache' ), $json ) ;
1001
- LiteSpeed_Cache_Admin_Display::error( $msg ) ;
1002
- return null ;
1003
- }
1004
-
1005
- // Check data format
1006
- if ( empty( $json[ 'pids' ] ) || ! is_array( $json[ 'pids' ] ) ) {
1007
- LiteSpeed_Cache_Log::debug( 'Media: Failed to parse data from LiteSpeed IAPI server ', $json[ 'pids' ] ) ;
1008
- $msg = sprintf( __( 'Failed to parse data from LiteSpeed IAPI server: %s', 'litespeed-cache' ), $json[ 'pids' ] ) ;
1009
- LiteSpeed_Cache_Admin_Display::error( $msg ) ;
1010
- return null ;
1011
- }
1012
-
1013
- LiteSpeed_Cache_Log::debug( 'Media: posts data from LiteSpeed IAPI server count: ' . count( $json[ 'pids' ] ) ) ;
1014
-
1015
- return $json ;
1016
-
1017
- }
1018
-
1019
- /**
1020
- * Send destroy all requests cmd to LiteSpeed IAPI server and get the link to finish it ( avoid click by mistake )
1021
- *
1022
- * @since 1.6.7
1023
- * @access private
1024
- */
1025
- private function _img_optimize_destroy()
1026
- {
1027
- LiteSpeed_Cache_Log::debug( 'Media: sending DESTROY cmd to LiteSpeed IAPI' ) ;
1028
-
1029
- // Mark request time to avoid duplicated request
1030
- update_option( self::DB_IMG_OPTIMIZE_DESTROY, time() ) ;
1031
-
1032
- // Push to LiteSpeed IAPI server
1033
- $json = LiteSpeed_Cache_Admin_API::post( LiteSpeed_Cache_Admin_API::IAPI_ACTION_REQUEST_DESTROY ) ;
1034
-
1035
- // confirm link will be displayed by Admin_API automatically
1036
- if ( is_array( $json ) && $json ) {
1037
- LiteSpeed_Cache_Log::debug( 'Media: cmd result', $json ) ;
1038
- }
1039
-
1040
- }
1041
-
1042
- /**
1043
- * Callback from LiteSpeed IAPI server to destroy all optm data
1044
- *
1045
- * @since 1.6.7
1046
- * @access private
1047
- */
1048
- public function img_optimize_destroy_callback()
1049
- {
1050
- global $wpdb ;
1051
- LiteSpeed_Cache_Log::debug( 'Media: excuting DESTROY process' ) ;
1052
-
1053
- $request_time = get_option( self::DB_IMG_OPTIMIZE_DESTROY ) ;
1054
- if ( time() - $request_time > 300 ) {
1055
- LiteSpeed_Cache_Log::debug( 'Media: terminate DESTROY process due to timeout' ) ;
1056
- exit( 'Destroy callback timeout ( 300 seconds )' ) ;
1057
- }
1058
-
1059
- // Start deleting files
1060
- $q = "SELECT * from $wpdb->postmeta WHERE meta_key = %s" ;
1061
- $list = $wpdb->get_results( $wpdb->prepare( $q, array( self::DB_IMG_OPTIMIZE_DATA ) ) ) ;
1062
- if ( $list ) {
1063
- foreach ( $list as $v ) {
1064
- $meta_value_list = unserialize( $v->meta_value ) ;
1065
- foreach ( $meta_value_list as $v2 ) {
1066
-
1067
- $src = $v2[ 0 ] ;
1068
- $local_file = $this->wp_upload_dir[ 'basedir' ] . '/' . $src ;
1069
-
1070
- // del webp
1071
- file_exists( $local_file . '.webp' ) && unlink( $local_file . '.webp' ) ;
1072
- file_exists( $local_file . '.optm.webp' ) && unlink( $local_file . '.optm.webp' ) ;
1073
-
1074
- $extension = pathinfo( $local_file, PATHINFO_EXTENSION ) ;
1075
- $local_filename = substr( $local_file, 0, - strlen( $extension ) - 1 ) ;
1076
- $bk_file = $local_filename . '.bk.' . $extension ;
1077
- $bk_optm_file = $local_filename . '.bk.optm.' . $extension ;
1078
-
1079
- // del optimized ori
1080
- if ( file_exists( $bk_file ) ) {
1081
- unlink( $local_file ) ;
1082
- rename( $bk_file, $local_file ) ;
1083
- }
1084
- file_exists( $bk_optm_file ) && unlink( $bk_optm_file ) ;
1085
- }
1086
- }
1087
- }
1088
-
1089
- // Delete optm info
1090
- $q = "DELETE FROM $wpdb->postmeta WHERE meta_key LIKE 'litespeed-optimize%'" ;
1091
- $wpdb->query( $q ) ;
1092
-
1093
- // Clear credit info
1094
- delete_option( self::DB_IMG_OPTM_SUMMARY ) ;
1095
-
1096
- exit( 'ok' ) ;
1097
- }
1098
-
1099
- /**
1100
- * Resend requested img to LiteSpeed IAPI server
1101
- *
1102
- * @since 1.6.7
1103
- * @access private
1104
- */
1105
- private function _img_optimize_rescan()
1106
- {
1107
- LiteSpeed_Cache_Log::debug( 'Media: resend requested images' ) ;
1108
-
1109
- $_credit = (int) $this->summary_info( 'credit' ) ;
1110
-
1111
- global $wpdb ;
1112
-
1113
- $q = "SELECT a.post_id, a.meta_value, b.meta_id as bmeta_id, c.meta_id as cmeta_id, c.meta_value as cmeta_value
1114
- FROM $wpdb->postmeta a
1115
- LEFT JOIN $wpdb->postmeta b ON b.post_id = a.post_id
1116
- LEFT JOIN $wpdb->postmeta c ON c.post_id = a.post_id
1117
- WHERE a.meta_key = '_wp_attachment_metadata'
1118
- AND b.meta_key = %s
1119
- AND c.meta_key = %s
1120
- LIMIT %d
1121
- " ;
1122
- $limit_rows = apply_filters( 'litespeed_img_optm_resend_rows', 300 ) ;
1123
- $list = $wpdb->get_results( $wpdb->prepare( $q, array( self::DB_IMG_OPTIMIZE_STATUS, self::DB_IMG_OPTIMIZE_DATA, $limit_rows ) ) ) ;
1124
- if ( ! $list ) {
1125
- LiteSpeed_Cache_Log::debug( 'Media: resend request bypassed: no image found' ) ;
1126
- $msg = __( 'No image found.', 'litespeed-cache' ) ;
1127
- LiteSpeed_Cache_Admin_Display::error( $msg ) ;
1128
- return ;
1129
- }
1130
-
1131
- // meta list
1132
- $optm_data_list = array() ;
1133
- $optm_data_pid2mid_list = array() ;
1134
-
1135
- foreach ( $list as $v ) {
1136
- // wp meta
1137
- $meta_value = $this->_parse_wp_meta_value( $v ) ;
1138
- if ( ! $meta_value ) {
1139
- continue ;
1140
- }
1141
- if ( empty( $meta_value[ 'sizes' ] ) ) {
1142
- continue ;
1143
- }
1144
-
1145
- $optm_data_pid2mid_list[ $v->post_id ] = array( 'status_mid' => $v->bmeta_id, 'data_mid' => $v->cmeta_id ) ;
1146
-
1147
- // prepare for pushing
1148
- $this->tmp_pid = $v->post_id ;
1149
- $this->tmp_path = pathinfo( $meta_value[ 'file' ], PATHINFO_DIRNAME ) . '/' ;
1150
-
1151
- // ls optimized meta
1152
- $optm_meta = $optm_data_list[ $v->post_id ] = unserialize( $v->cmeta_value ) ;
1153
- $optm_list = array() ;
1154
- foreach ( $optm_meta as $md5 => $optm_row ) {
1155
- $optm_list[] = $optm_row[ 0 ] ;
1156
- // only do for requested/notified img
1157
- // if ( ! in_array( $optm_row[ 1 ], array( self::DB_IMG_OPTIMIZE_STATUS_NOTIFIED, self::DB_IMG_OPTIMIZE_STATUS_REQUESTED ) ) ) {
1158
- // continue ;
1159
- // }
1160
- }
1161
-
1162
- // check if there is new files from wp meta
1163
- $img_queue = array() ;
1164
- foreach ( $meta_value[ 'sizes' ] as $v2 ) {
1165
- $curr_file = $this->tmp_path . $v2[ 'file' ] ;
1166
-
1167
- // new child file OR not finished yet
1168
- if ( ! in_array( $curr_file, $optm_list ) ) {
1169
- $img_queue[] = $v2 ;
1170
- }
1171
- }
1172
-
1173
- // nothing to add
1174
- if ( ! $img_queue ) {
1175
- continue ;
1176
- }
1177
-
1178
- $num_will_incease = count( $img_queue ) ;
1179
- if ( $this->_img_total + $num_will_incease > $_credit ) {
1180
- LiteSpeed_Cache_Log::debug( 'Media: resend img request hit limit: [total] ' . $this->_img_total . " \t[add] $num_will_incease \t[credit] $_credit" ) ;
1181
- break ;
1182
- }
1183
-
1184
- foreach ( $img_queue as $v2 ) {
1185
- $this->_img_queue( $v2 ) ;
1186
- }
1187
- }
1188
-
1189
- // push to LiteSpeed IAPI server
1190
- if ( empty( $this->_img_in_queue ) ) {
1191
- $msg = __( 'No image found.', 'litespeed-cache' ) ;
1192
- LiteSpeed_Cache_Admin_Display::succeed( $msg ) ;
1193
- return ;
1194
- }
1195
-
1196
- $total_groups = count( $this->_img_in_queue ) ;
1197
- LiteSpeed_Cache_Log::debug( 'Media: prepared images to push: groups ' . $total_groups . ' images ' . $this->_img_total ) ;
1198
-
1199
- // Push to LiteSpeed IAPI server
1200
- $json = $this->_push_img_in_queue_to_ls() ;
1201
- if ( $json === null ) {
1202
- return ;
1203
- }
1204
- // Returned data is the requested and notifed images
1205
- $pids = $json[ 'pids' ] ;
1206
-
1207
- LiteSpeed_Cache_Log::debug( 'Media: returned data from LiteSpeed IAPI server count: ' . count( $pids ) ) ;
1208
-
1209
- $q = "UPDATE $wpdb->postmeta SET meta_value = %s WHERE meta_id = %d" ;
1210
-
1211
- // Update data
1212
- foreach ( $pids as $pid ) {
1213
- $md52src_list = $optm_data_list[ $pid ] ;
1214
-
1215
- foreach ( $this->_img_in_queue[ $pid ] as $md5 => $src_data ) {
1216
- $md52src_list[ $md5 ] = array( $src_data[ 'file' ], self::DB_IMG_OPTIMIZE_STATUS_REQUESTED ) ;
1217
- }
1218
-
1219
- $new_status = $this->_get_status_by_meta_data( $md52src_list, self::DB_IMG_OPTIMIZE_STATUS_REQUESTED ) ;
1220
-
1221
- $md52src_list = serialize( $md52src_list ) ;
1222
-
1223
- // Store data
1224
- $wpdb->query( $wpdb->prepare( $q, array( $new_status, $optm_data_pid2mid_list[ $pid ][ 'status_mid' ] ) ) ) ;
1225
- $wpdb->query( $wpdb->prepare( $q, array( $md52src_list, $optm_data_pid2mid_list[ $pid ][ 'data_mid' ] ) ) ) ;
1226
- }
1227
-
1228
- $accepted_groups = count( $pids ) ;
1229
- $accepted_imgs = $json[ 'total' ] ;
1230
-
1231
- $msg = sprintf( __( 'Pushed %1$s groups with %2$s images to LiteSpeed optimization server, accepted %3$s groups with %4$s images.', 'litespeed-cache' ), $total_groups, $this->_img_total, $accepted_groups, $accepted_imgs ) ;
1232
- LiteSpeed_Cache_Admin_Display::succeed( $msg ) ;
1233
-
1234
- // Update credit info
1235
- if ( isset( $json[ 'credit' ] ) ) {
1236
- $this->_update_credit( $json[ 'credit' ] ) ;
1237
- }
1238
-
1239
- }
1240
-
1241
- /**
1242
- * Push raw img to LiteSpeed IAPI server
1243
- *
1244
- * @since 1.6
1245
- * @access private
1246
- */
1247
- private function _img_optimize()
1248
- {
1249
- $_credit = (int) $this->summary_info( 'credit' ) ;
1250
- $credit_recovered = (int) $this->summary_info( 'credit_recovered' ) ;
1251
-
1252
- LiteSpeed_Cache_Log::debug( 'Media preparing images to push' ) ;
1253
-
1254
- global $wpdb ;
1255
- // Get images
1256
- $q = "SELECT b.post_id, b.meta_value
1257
- FROM $wpdb->posts a
1258
- LEFT JOIN $wpdb->postmeta b ON b.post_id = a.ID
1259
- LEFT JOIN $wpdb->postmeta c ON c.post_id = a.ID AND c.meta_key = %s
1260
- WHERE a.post_type = 'attachment'
1261
- AND a.post_status = 'inherit'
1262
- AND a.post_mime_type IN ('image/jpeg', 'image/png')
1263
- AND b.meta_key = '_wp_attachment_metadata'
1264
- AND c.post_id IS NULL
1265
- ORDER BY a.ID DESC
1266
- LIMIT %d
1267
- " ;
1268
- $q = $wpdb->prepare( $q, array( self::DB_IMG_OPTIMIZE_STATUS, apply_filters( 'litespeed_img_optimize_max_rows', 100 ) ) ) ;
1269
-
1270
- $img_set = array() ;
1271
- $list = $wpdb->get_results( $q ) ;
1272
- if ( ! $list ) {
1273
- LiteSpeed_Cache_Log::debug( 'Media optimize bypass: no image found' ) ;
1274
- return ;
1275
- }
1276
-
1277
- LiteSpeed_Cache_Log::debug( 'Media found images: ' . count( $list ) ) ;
1278
-
1279
- foreach ( $list as $v ) {
1280
-
1281
- $meta_value = $this->_parse_wp_meta_value( $v ) ;
1282
- if ( ! $meta_value ) {
1283
- continue ;
1284
- }
1285
-
1286
- /**
1287
- * Only send 500 images one time
1288
- * @since 1.6.3
1289
- * @since 1.6.5 use credit limit
1290
- */
1291
- $num_will_incease = 1 ;
1292
- if ( ! empty( $meta_value[ 'sizes' ] ) ) {
1293
- $num_will_incease += count( $meta_value[ 'sizes' ] ) ;
1294
- }
1295
- if ( $this->_img_total + $num_will_incease > $_credit ) {
1296
- if ( ! $this->_img_total ) {
1297
- $msg = sprintf( __( 'Number of images in one image group (%s) exceeds the credit (%s)', 'litespeed-cache' ), $num_will_incease, $_credit ) ;
1298
- LiteSpeed_Cache_Admin_Display::error( $msg ) ;
1299
- }
1300
- LiteSpeed_Cache_Log::debug( 'Media img request hit limit: [total] ' . $this->_img_total . " \t[add] $num_will_incease \t[credit] $_credit" ) ;
1301
- break ;
1302
- }
1303
- /**
1304
- * Check if need to test run ( new user only allow 1 group at first time)
1305
- * @since 1.6.6.1
1306
- */
1307
- if ( $this->_img_total && ! $credit_recovered ) {
1308
- LiteSpeed_Cache_Log::debug( 'Media: test run only allow 1 group ' ) ;
1309
- break ;
1310
- }
1311
-
1312
- // push orig image to queue
1313
- $this->tmp_pid = $v->post_id ;
1314
- $this->tmp_path = pathinfo( $meta_value[ 'file' ], PATHINFO_DIRNAME ) . '/' ;
1315
- $this->_img_queue( $meta_value, true ) ;
1316
- if ( ! empty( $meta_value[ 'sizes' ] ) ) {
1317
- array_map( array( $this, '_img_queue' ), $meta_value[ 'sizes' ] ) ;
1318
- }
1319
-
1320
- }
1321
-
1322
- // push to LiteSpeed IAPI server
1323
- if ( empty( $this->_img_in_queue ) ) {
1324
- $msg = __( 'No image found.', 'litespeed-cache' ) ;
1325
- LiteSpeed_Cache_Admin_Display::succeed( $msg ) ;
1326
- return ;
1327
- }
1328
-
1329
- $total_groups = count( $this->_img_in_queue ) ;
1330
- LiteSpeed_Cache_Log::debug( 'Media prepared images to push: groups ' . $total_groups . ' images ' . $this->_img_total ) ;
1331
-
1332
- // Push to LiteSpeed IAPI server
1333
- $json = $this->_push_img_in_queue_to_ls() ;
1334
- if ( $json === null ) {
1335
- return ;
1336
- }
1337
- $pids = $json[ 'pids' ] ;
1338
-
1339
- // Exclude those who have meta already
1340
- $q = "SELECT post_id FROM $wpdb->postmeta WHERE meta_key = %s and post_id in ( " . implode( ',', array_fill( 0, count( $pids ), '%s' ) ) . " )" ;
1341
- $tmp = $wpdb->get_results( $wpdb->prepare( $q, array_merge( array( self::DB_IMG_OPTIMIZE_STATUS ), $pids ) ) ) ;
1342
- $exists_pids = array() ;
1343
- foreach ( $tmp as $v ) {
1344
- $exists_pids[] = $v->post_id ;
1345
- }
1346
- if ( $exists_pids ) {
1347
- LiteSpeed_Cache_Log::debug( 'Media: existing posts data from LiteSpeed IAPI server count: ' . count( $exists_pids ) ) ;
1348
- }
1349
- $pids = array_diff( $pids, $exists_pids ) ;
1350
-
1351
- if ( ! $pids ) {
1352
- LiteSpeed_Cache_Log::debug( 'Media: Failed to store data from LiteSpeed IAPI server with empty pids' ) ;
1353
- LiteSpeed_Cache_Admin_Display::error( __( 'Post data is empty.', 'litespeed-cache' ) ) ;
1354
- return ;
1355
- }
1356
-
1357
- LiteSpeed_Cache_Log::debug( 'Media: diff posts data from LiteSpeed IAPI server count: ' . count( $pids ) ) ;
1358
-
1359
- $q = "INSERT INTO $wpdb->postmeta ( post_id, meta_key, meta_value ) VALUES " ;
1360
- $data_to_add = array() ;
1361
- foreach ( $pids as $pid ) {
1362
- $data_to_add[] = $pid ;
1363
- $data_to_add[] = self::DB_IMG_OPTIMIZE_STATUS ;
1364
- $data_to_add[] = self::DB_IMG_OPTIMIZE_STATUS_REQUESTED ;
1365
- $data_to_add[] = $pid ;
1366
- $data_to_add[] = self::DB_IMG_OPTIMIZE_DATA ;
1367
- $md52src_list = array() ;
1368
- foreach ( $this->_img_in_queue[ $pid ] as $md5 => $src_data ) {
1369
- $md52src_list[ $md5 ] = array( $src_data[ 'file' ], self::DB_IMG_OPTIMIZE_STATUS_REQUESTED ) ;
1370
- }
1371
- $data_to_add[] = serialize( $md52src_list ) ;
1372
- }
1373
- // Add placeholder
1374
- $q .= implode( ',', array_map(
1375
- function( $el ) { return '(' . implode( ',', $el ) . ')' ; },
1376
- array_chunk( array_fill( 0, count( $data_to_add ), '%s' ), 3 )
1377
- ) ) ;
1378
- // Store data
1379
- $wpdb->query( $wpdb->prepare( $q, $data_to_add ) ) ;
1380
-
1381
-
1382
- $accepted_groups = count( $pids ) ;
1383
- $accepted_imgs = $json[ 'total' ] ;
1384
-
1385
- $msg = sprintf( __( 'Pushed %1$s groups with %2$s images to LiteSpeed optimization server, accepted %3$s groups with %4$s images.', 'litespeed-cache' ), $total_groups, $this->_img_total, $accepted_groups, $accepted_imgs ) ;
1386
- LiteSpeed_Cache_Admin_Display::succeed( $msg ) ;
1387
-
1388
- // Update credit info
1389
- if ( isset( $json[ 'credit' ] ) ) {
1390
- $this->_update_credit( $json[ 'credit' ] ) ;
1391
- }
1392
- }
1393
-
1394
- /**
1395
- * Add a new img to queue which will be pushed to LiteSpeed
1396
- *
1397
- * @since 1.6
1398
- * @access private
1399
- */
1400
- private function _img_queue( $meta_value, $ori_file = false )
1401
- {
1402
- if ( empty( $meta_value[ 'file' ] ) || empty( $meta_value[ 'width' ] ) || empty( $meta_value[ 'height' ] ) ) {
1403
- LiteSpeed_Cache_Log::debug2( 'Media bypass image due to lack of file/w/h: pid ' . $this->tmp_pid, $meta_value ) ;
1404
- return ;
1405
- }
1406
-
1407
- if ( ! $ori_file ) {
1408
- $meta_value[ 'file' ] = $this->tmp_path . $meta_value[ 'file' ] ;
1409
- }
1410
-
1411
- // check file exists or not
1412
- $real_file = $this->wp_upload_dir[ 'basedir' ] . '/' . $meta_value[ 'file' ] ;
1413
- if ( ! file_exists( $real_file ) ) {
1414
- LiteSpeed_Cache_Log::debug2( 'Media bypass image due to file not exist: pid ' . $this->tmp_pid . ' ' . $real_file ) ;
1415
- return ;
1416
- }
1417
-
1418
- LiteSpeed_Cache_Log::debug2( 'Media adding image: pid ' . $this->tmp_pid ) ;
1419
-
1420
- $img_info = array(
1421
- 'url' => $this->wp_upload_dir[ 'baseurl' ] . '/' . $meta_value[ 'file' ],
1422
- 'file' => $meta_value[ 'file' ], // not needed in LiteSpeed sapi, just leave for local storage after post
1423
- 'width' => $meta_value[ 'width' ],
1424
- 'height' => $meta_value[ 'height' ],
1425
- 'mime_type' => ! empty( $meta_value[ 'mime-type' ] ) ? $meta_value[ 'mime-type' ] : '' ,
1426
- ) ;
1427
- $md5 = md5_file( $real_file ) ;
1428
-
1429
- if ( empty( $this->_img_in_queue[ $this->tmp_pid ] ) ) {
1430
- $this->_img_in_queue[ $this->tmp_pid ] = array() ;
1431
- }
1432
- $this->_img_in_queue[ $this->tmp_pid ][ $md5 ] = $img_info ;
1433
- $this->_img_total ++ ;
1434
- }
1435
-
1436
- /**
1437
- * Update client credit info
1438
- *
1439
- * @since 1.6.5
1440
- * @access private
1441
- */
1442
- private function _update_credit( $credit )
1443
- {
1444
- $summary = get_option( self::DB_IMG_OPTM_SUMMARY, array() ) ;
1445
- $summary[ 'credit' ] = $credit ;
1446
-
1447
- update_option( self::DB_IMG_OPTM_SUMMARY, $summary ) ;
1448
- }
1449
-
1450
- /**
1451
- * Get optm summary
1452
- *
1453
- * @since 1.6.5
1454
- * @access public
1455
- */
1456
- public function summary_info( $field = false )
1457
- {
1458
- $optm_summary = get_option( self::DB_IMG_OPTM_SUMMARY, array() ) ;
1459
-
1460
- if ( ! $field ) {
1461
- return $optm_summary ;
1462
- }
1463
- return ! empty( $optm_summary[ $field ] ) ? $optm_summary[ $field ] : 0 ;
1464
- }
1465
-
1466
- /**
1467
- * Count images
1468
- *
1469
- * @since 1.6
1470
- * @access public
1471
- */
1472
- public function img_count()
1473
- {
1474
- global $wpdb ;
1475
- $q = "SELECT count(*)
1476
- FROM $wpdb->posts a
1477
- LEFT JOIN $wpdb->postmeta b ON b.post_id = a.ID
1478
- WHERE a.post_type = 'attachment'
1479
- AND a.post_status = 'inherit'
1480
- AND a.post_mime_type IN ('image/jpeg', 'image/png')
1481
- AND b.meta_key = '_wp_attachment_metadata'
1482
- " ;
1483
- // $q = "SELECT count(*) FROM $wpdb->posts WHERE post_type = 'attachment' AND post_status = 'inherit' AND post_mime_type IN ('image/jpeg', 'image/png') " ;
1484
- $total_img = $wpdb->get_var( $q ) ;
1485
-
1486
- $q = "SELECT count(*)
1487
- FROM $wpdb->posts a
1488
- LEFT JOIN $wpdb->postmeta b ON b.post_id = a.ID
1489
- LEFT JOIN $wpdb->postmeta c ON c.post_id = a.ID
1490
- WHERE a.post_type = 'attachment'
1491
- AND a.post_status = 'inherit'
1492
- AND a.post_mime_type IN ('image/jpeg', 'image/png')
1493
- AND b.meta_key = '_wp_attachment_metadata'
1494
- AND c.meta_key = %s
1495
- AND c.meta_value= %s
1496
- " ;
1497
- $total_requested = $wpdb->get_var( $wpdb->prepare( $q, array( self::DB_IMG_OPTIMIZE_STATUS, self::DB_IMG_OPTIMIZE_STATUS_REQUESTED ) ) ) ;
1498
- $total_server_finished = $wpdb->get_var( $wpdb->prepare( $q, array( self::DB_IMG_OPTIMIZE_STATUS, self::DB_IMG_OPTIMIZE_STATUS_NOTIFIED ) ) ) ;
1499
- $total_pulled = $wpdb->get_var( $wpdb->prepare( $q, array( self::DB_IMG_OPTIMIZE_STATUS, self::DB_IMG_OPTIMIZE_STATUS_PULLED ) ) ) ;
1500
- $total_err = $wpdb->get_var( $wpdb->prepare( $q, array( self::DB_IMG_OPTIMIZE_STATUS, self::DB_IMG_OPTIMIZE_STATUS_ERR ) ) ) ;
1501
-
1502
- $q = "SELECT count(*)
1503
- FROM $wpdb->posts a
1504
- LEFT JOIN $wpdb->postmeta b ON b.post_id = a.ID
1505
- LEFT JOIN $wpdb->postmeta c ON c.post_id = a.ID AND c.meta_key = %s
1506
- WHERE a.post_type = 'attachment'
1507
- AND a.post_status = 'inherit'
1508
- AND a.post_mime_type IN ('image/jpeg', 'image/png')
1509
- AND b.meta_key = '_wp_attachment_metadata'
1510
- AND c.post_id IS NULL
1511
- " ;
1512
- $total_not_requested = $wpdb->get_var( $wpdb->prepare( $q, array( self::DB_IMG_OPTIMIZE_STATUS ) ) ) ;
1513
-
1514
- return array(
1515
- 'total_img' => $total_img,
1516
- 'total_not_requested' => $total_not_requested,
1517
- 'total_requested' => $total_requested,
1518
- 'total_err' => $total_err,
1519
- 'total_server_finished' => $total_server_finished,
1520
- 'total_pulled' => $total_pulled,
1521
- ) ;
1522
- }
1523
-
1524
  /**
1525
  * Run lazy load process
1526
  * NOTE: As this is after cache finalized, can NOT set any cache control anymore
16
 
17
  const LAZY_LIB = '/min/lazyload.js' ;
18
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
19
  private $content ;
20
  private $wp_upload_dir ;
 
 
 
 
21
 
22
  private $cfg_img_webp ;
23
 
86
  */
87
  public function after_admin_init()
88
  {
89
+ if ( get_option( LiteSpeed_Cache_Config::ITEM_IMG_OPTM_NEED_PULL ) ) {
90
  add_filter( 'manage_media_columns', array( $this, 'media_row_title' ) ) ;
91
  add_filter( 'manage_media_custom_column', array( $this, 'media_row_actions' ), 10, 2 ) ;
92
  }
119
 
120
  $local_file = get_attached_file( $post_id ) ;
121
 
122
+ $link = LiteSpeed_Cache_Utility::build_url( LiteSpeed_Cache::ACTION_IMG_OPTM, 'webp' . $post_id ) ;
123
  $desc = false ;
124
  $cls = 'litespeed-icon-media-webp' ;
125
  $cls_webp = '' ;
142
  $bk_file = substr( $local_file, 0, -strlen( $extension ) ) . 'bk.' . $extension ;
143
  $bk_optm_file = substr( $local_file, 0, -strlen( $extension ) ) . 'bk.optm.' . $extension ;
144
 
145
+ $link = LiteSpeed_Cache_Utility::build_url( LiteSpeed_Cache::ACTION_IMG_OPTM, 'orig' . $post_id ) ;
146
  $desc = false ;
147
  $cls = 'litespeed-icon-media-optm' ;
148
  $cls_ori = '' ;
162
  }
163
 
164
  $info_webp = '' ;
165
+ $size_meta = get_post_meta( $post_id, LiteSpeed_Cache_Img_Optm::DB_IMG_OPTIMIZE_SIZE, true ) ;
166
  if ( $size_meta && ! empty ( $size_meta[ 'webp_saved' ] ) ) {
167
  $percent = ceil( $size_meta[ 'webp_saved' ] * 100 / $size_meta[ 'webp_total' ] ) ;
168
  $pie_webp = LiteSpeed_Cache_GUI::pie( $percent, 30 ) ;
183
  echo "<p class='litespeed-media-p $cls_webp'>$info_webp $link_webp</p><p class='litespeed-media-p $cls_ori'>$info_ori $link_ori</p>" ;
184
  }
185
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
186
  /**
187
  * Get wp size info
188
  *
258
  }
259
  }
260
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
261
  /**
262
  * Handle all request actions from main cls
263
  *
271
  $type = LiteSpeed_Cache_Router::verify_type() ;
272
 
273
  switch ( $type ) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
274
  default:
275
  break ;
276
  }
278
  LiteSpeed_Cache_Admin::redirect() ;
279
  }
280
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
281
  /**
282
  * Run lazy load process
283
  * NOTE: As this is after cache finalized, can NOT set any cache control anymore
inc/router.class.php CHANGED
@@ -39,23 +39,23 @@ class LiteSpeed_Cache_Router
39
  return ;
40
  }
41
 
42
- LiteSpeed_Cache_Log::debug( 'Router: starting crawler role validation' ) ;
43
 
44
  // Check if is from crawler
45
  if ( empty( $_SERVER[ 'HTTP_USER_AGENT' ] ) || $_SERVER[ 'HTTP_USER_AGENT' ] !== Litespeed_Crawler::FAST_USER_AGENT ) {
46
- LiteSpeed_Cache_Log::debug( 'Router: user agent not match' ) ;
47
  return ;
48
  }
49
 
50
  // Hash validation
51
  $hash = get_option( LiteSpeed_Cache_Config::ITEM_CRAWLER_HASH ) ;
52
  if ( ! $hash || $_COOKIE[ 'litespeed_hash' ] != $hash ) {
53
- LiteSpeed_Cache_Log::debug( 'Router: crawler hash not match ' . $_COOKIE[ 'litespeed_hash' ] . ' != ' . $hash ) ;
54
  return ;
55
  }
56
 
57
  $role_uid = $_COOKIE[ 'litespeed_role' ] ;
58
- LiteSpeed_Cache_Log::debug( 'Router: role simulate litespeed_role uid ' . $role_uid ) ;
59
 
60
  wp_set_current_user( $role_uid ) ;
61
  }
@@ -74,7 +74,7 @@ class LiteSpeed_Cache_Router
74
  $user = wp_get_current_user() ;
75
  $user_id = $user->ID ;
76
 
77
- LiteSpeed_Cache_Log::debug( 'Router: get_uid: ' . $user_id, 3 ) ;
78
 
79
  define( 'LITESPEED_WP_UID', $user_id ) ;
80
 
@@ -104,11 +104,11 @@ class LiteSpeed_Cache_Router
104
  $role = array_shift( $tmp ) ;
105
  }
106
  }
107
- LiteSpeed_Cache_Log::debug( 'Router: get_role: ' . $role ) ;
108
 
109
  if ( ! $role ) {
110
  // Guest user
111
- LiteSpeed_Cache_Log::debug( 'Router: role: guest' ) ;
112
  }
113
 
114
  define( 'LITESPEED_WP_ROLE', $role ) ;
@@ -190,7 +190,7 @@ class LiteSpeed_Cache_Router
190
  self::$_action = false;
191
  self::get_instance()->verify_action() ;
192
  if ( self::$_action ) {
193
- defined( 'LSCWP_LOG' ) && LiteSpeed_Cache_Log::debug( 'LSCWP_CTRL verified: ' . var_export( self::$_action, true ) ) ;
194
  }
195
 
196
  }
@@ -264,11 +264,11 @@ class LiteSpeed_Cache_Router
264
  public static function verify_type()
265
  {
266
  if ( empty( $_REQUEST[ 'type' ] ) ) {
267
- LiteSpeed_Cache_Log::debug( 'Router no type', 2 ) ;
268
  return false ;
269
  }
270
 
271
- LiteSpeed_Cache_Log::debug( 'Router parsed type: ' . $_REQUEST[ 'type' ], 2 ) ;
272
 
273
  return $_REQUEST[ 'type' ] ;
274
  }
@@ -282,7 +282,7 @@ class LiteSpeed_Cache_Router
282
  private function verify_action()
283
  {
284
  if ( empty( $_REQUEST[ LiteSpeed_Cache::ACTION_KEY ] ) ) {
285
- LiteSpeed_Cache_Log::debug2( 'LSCWP_CTRL bypassed empty' ) ;
286
  return ;
287
  }
288
 
@@ -294,7 +294,7 @@ class LiteSpeed_Cache_Router
294
  if ( ! $this->verify_nonce( $action ) && ! $this->_verify_sapi_passive( $action ) && ! $this->_verify_sapi_aggressive( $action ) ) {
295
  // check if it is from admin ip
296
  if ( ! $this->is_admin_ip() ) {
297
- LiteSpeed_Cache_Log::debug( 'LSCWP_CTRL query string - did not match admin IP: ' . $action ) ;
298
  return ;
299
  }
300
 
@@ -307,7 +307,7 @@ class LiteSpeed_Cache_Router
307
  LiteSpeed_Cache::ACTION_QS_PURGE_ALL,
308
  LiteSpeed_Cache::ACTION_QS_PURGE_EMPTYCACHE,
309
  ) ) ) {
310
- LiteSpeed_Cache_Log::debug( 'LSCWP_CTRL query string - did not match admin IP Actions: ' . $action ) ;
311
  return ;
312
  }
313
 
@@ -315,7 +315,7 @@ class LiteSpeed_Cache_Router
315
  }
316
 
317
  /* Now it is a valid action, lets log and check the permission */
318
- LiteSpeed_Cache_Log::debug( 'LSCWP_CTRL: ' . $action ) ;
319
 
320
  // OK, as we want to do something magic, lets check if its allowed
321
  $_is_multisite = is_multisite() ;
@@ -381,9 +381,11 @@ class LiteSpeed_Cache_Router
381
  case LiteSpeed_Cache::ACTION_BLACKLIST_SAVE:
382
  case LiteSpeed_Cache::ACTION_PURGE:
383
  case LiteSpeed_Cache::ACTION_MEDIA:
 
384
  case LiteSpeed_Cache::ACTION_IAPI:
385
  case LiteSpeed_Cache::ACTION_CDN:
386
  case LiteSpeed_Cache::ACTION_IMPORT:
 
387
  if ( defined( 'LITESPEED_ON' ) && $_can_option && ! $_is_network_admin ) {
388
  self::$_action = $action ;
389
  }
@@ -413,7 +415,7 @@ class LiteSpeed_Cache_Router
413
  return ;
414
 
415
  default:
416
- LiteSpeed_Cache_Log::debug( 'LSCWP_CTRL match falied: ' . $action ) ;
417
  return ;
418
  }
419
 
39
  return ;
40
  }
41
 
42
+ LiteSpeed_Cache_Log::debug( '[Router] starting crawler role validation' ) ;
43
 
44
  // Check if is from crawler
45
  if ( empty( $_SERVER[ 'HTTP_USER_AGENT' ] ) || $_SERVER[ 'HTTP_USER_AGENT' ] !== Litespeed_Crawler::FAST_USER_AGENT ) {
46
+ LiteSpeed_Cache_Log::debug( '[Router] user agent not match' ) ;
47
  return ;
48
  }
49
 
50
  // Hash validation
51
  $hash = get_option( LiteSpeed_Cache_Config::ITEM_CRAWLER_HASH ) ;
52
  if ( ! $hash || $_COOKIE[ 'litespeed_hash' ] != $hash ) {
53
+ LiteSpeed_Cache_Log::debug( '[Router] crawler hash not match ' . $_COOKIE[ 'litespeed_hash' ] . ' != ' . $hash ) ;
54
  return ;
55
  }
56
 
57
  $role_uid = $_COOKIE[ 'litespeed_role' ] ;
58
+ LiteSpeed_Cache_Log::debug( '[Router] role simulate litespeed_role uid ' . $role_uid ) ;
59
 
60
  wp_set_current_user( $role_uid ) ;
61
  }
74
  $user = wp_get_current_user() ;
75
  $user_id = $user->ID ;
76
 
77
+ LiteSpeed_Cache_Log::debug( '[Router] get_uid: ' . $user_id, 3 ) ;
78
 
79
  define( 'LITESPEED_WP_UID', $user_id ) ;
80
 
104
  $role = array_shift( $tmp ) ;
105
  }
106
  }
107
+ LiteSpeed_Cache_Log::debug( '[Router] get_role: ' . $role ) ;
108
 
109
  if ( ! $role ) {
110
  // Guest user
111
+ LiteSpeed_Cache_Log::debug( '[Router] role: guest' ) ;
112
  }
113
 
114
  define( 'LITESPEED_WP_ROLE', $role ) ;
190
  self::$_action = false;
191
  self::get_instance()->verify_action() ;
192
  if ( self::$_action ) {
193
+ defined( 'LSCWP_LOG' ) && LiteSpeed_Cache_Log::debug( '[Router] LSCWP_CTRL verified: ' . var_export( self::$_action, true ) ) ;
194
  }
195
 
196
  }
264
  public static function verify_type()
265
  {
266
  if ( empty( $_REQUEST[ 'type' ] ) ) {
267
+ LiteSpeed_Cache_Log::debug( '[Router] no type', 2 ) ;
268
  return false ;
269
  }
270
 
271
+ LiteSpeed_Cache_Log::debug( '[Router] parsed type: ' . $_REQUEST[ 'type' ], 2 ) ;
272
 
273
  return $_REQUEST[ 'type' ] ;
274
  }
282
  private function verify_action()
283
  {
284
  if ( empty( $_REQUEST[ LiteSpeed_Cache::ACTION_KEY ] ) ) {
285
+ LiteSpeed_Cache_Log::debug2( '[Router] LSCWP_CTRL bypassed empty' ) ;
286
  return ;
287
  }
288
 
294
  if ( ! $this->verify_nonce( $action ) && ! $this->_verify_sapi_passive( $action ) && ! $this->_verify_sapi_aggressive( $action ) ) {
295
  // check if it is from admin ip
296
  if ( ! $this->is_admin_ip() ) {
297
+ LiteSpeed_Cache_Log::debug( '[Router] LSCWP_CTRL query string - did not match admin IP: ' . $action ) ;
298
  return ;
299
  }
300
 
307
  LiteSpeed_Cache::ACTION_QS_PURGE_ALL,
308
  LiteSpeed_Cache::ACTION_QS_PURGE_EMPTYCACHE,
309
  ) ) ) {
310
+ LiteSpeed_Cache_Log::debug( '[Router] LSCWP_CTRL query string - did not match admin IP Actions: ' . $action ) ;
311
  return ;
312
  }
313
 
315
  }
316
 
317
  /* Now it is a valid action, lets log and check the permission */
318
+ LiteSpeed_Cache_Log::debug( '[Router] LSCWP_CTRL: ' . $action ) ;
319
 
320
  // OK, as we want to do something magic, lets check if its allowed
321
  $_is_multisite = is_multisite() ;
381
  case LiteSpeed_Cache::ACTION_BLACKLIST_SAVE:
382
  case LiteSpeed_Cache::ACTION_PURGE:
383
  case LiteSpeed_Cache::ACTION_MEDIA:
384
+ case LiteSpeed_Cache::ACTION_IMG_OPTM:
385
  case LiteSpeed_Cache::ACTION_IAPI:
386
  case LiteSpeed_Cache::ACTION_CDN:
387
  case LiteSpeed_Cache::ACTION_IMPORT:
388
+ case LiteSpeed_Cache::ACTION_QUIC_CLOUD:
389
  if ( defined( 'LITESPEED_ON' ) && $_can_option && ! $_is_network_admin ) {
390
  self::$_action = $action ;
391
  }
415
  return ;
416
 
417
  default:
418
+ LiteSpeed_Cache_Log::debug( '[Router] LSCWP_CTRL match falied: ' . $action ) ;
419
  return ;
420
  }
421
 
inc/task.class.php CHANGED
@@ -38,10 +38,10 @@ class LiteSpeed_Cache_Task
38
  }
39
 
40
  // Register img optimization fetch ( always fetch immediately )
41
- if ( ! LiteSpeed_Cache::config( LiteSpeed_Cache_Config::OPID_MEDIA_IMG_OPTM_CRON_OFF ) && LiteSpeed_Cache_Media::check_need_pull() ) {
42
  self::schedule_filter_imgoptm() ;
43
 
44
- add_action( self::CRON_ACTION_HOOK_IMGOPTM, 'LiteSpeed_Cache_Media::pull_optimized_img' ) ;
45
  }
46
  else {
47
  // wp_clear_scheduled_hook( self::CRON_ACTION_HOOK_IMGOPTM ) ;
38
  }
39
 
40
  // Register img optimization fetch ( always fetch immediately )
41
+ if ( ! LiteSpeed_Cache::config( LiteSpeed_Cache_Config::OPID_MEDIA_IMG_OPTM_CRON_OFF ) && LiteSpeed_Cache_Img_Optm::check_need_pull() ) {
42
  self::schedule_filter_imgoptm() ;
43
 
44
+ add_action( self::CRON_ACTION_HOOK_IMGOPTM, 'LiteSpeed_Cache_Img_Optm::pull_optimized_img' ) ;
45
  }
46
  else {
47
  // wp_clear_scheduled_hook( self::CRON_ACTION_HOOK_IMGOPTM ) ;
inc/vary.class.php CHANGED
@@ -75,7 +75,7 @@ class LiteSpeed_Cache_Vary
75
  * @since 1.6.7
76
  */
77
  add_action( 'rest_api_init', function(){
78
- LiteSpeed_Cache_Log::debug( 'Vary: Rest API init disabled vary change' ) ;
79
  add_filter( 'litespeed_can_change_vary', '__return_false' ) ;
80
  } ) ;
81
 
@@ -197,7 +197,7 @@ class LiteSpeed_Cache_Vary
197
  */
198
  public function add_logged_in( $logged_in_cookie = false, $expire = false, $expiration = false, $uid = false )
199
  {
200
- LiteSpeed_Cache_Log::debug( 'Vary: add_logged_in' ) ;
201
  // If the cookie is lost somehow, set it
202
  $this->_update_default_vary( $uid, $expire ) ;
203
  }
@@ -211,7 +211,7 @@ class LiteSpeed_Cache_Vary
211
  */
212
  public function remove_logged_in()
213
  {
214
- LiteSpeed_Cache_Log::debug( 'Vary: remove_logged_in' ) ;
215
  // Force update vary to remove login status
216
  $this->_update_default_vary( -1 ) ;
217
  }
@@ -230,7 +230,7 @@ class LiteSpeed_Cache_Vary
230
  * @since 1.6.6
231
  */
232
  if ( LiteSpeed_Cache_Router::is_ajax() && ! apply_filters( 'litespeed_ajax_vary', false ) ) {
233
- LiteSpeed_Cache_Log::debug( 'Vary: can_change_vary bypassed due to ajax call' ) ;
234
  return false ;
235
  }
236
 
@@ -239,12 +239,12 @@ class LiteSpeed_Cache_Vary
239
  * @since 1.6.5
240
  */
241
  if ( $_SERVER["REQUEST_METHOD"] !== 'GET' && $_SERVER["REQUEST_METHOD"] !== 'POST' ) {
242
- LiteSpeed_Cache_Log::debug( 'Vary: can_change_vary bypassed due to method not get/post' ) ;
243
  return false ;
244
  }
245
 
246
  if ( ! apply_filters( 'litespeed_can_change_vary', true ) ) {
247
- LiteSpeed_Cache_Log::debug( 'Vary: can_change_vary bypassed due to litespeed_can_change_vary hook' ) ;
248
  return false ;
249
  }
250
 
@@ -265,7 +265,7 @@ class LiteSpeed_Cache_Vary
265
  define( 'LITESPEED_DID_' . __FUNCTION__, true ) ;
266
  }
267
  else {
268
- LiteSpeed_Cache_Log::debug2( "Vary: _update_default_vary bypassed due to run already" ) ;
269
  return ;
270
  }
271
 
@@ -280,7 +280,7 @@ class LiteSpeed_Cache_Vary
280
  $expire = time() + 2 * DAY_IN_SECONDS ;
281
  }
282
  self::_cookie( $vary, $expire ) ;
283
- LiteSpeed_Cache_Log::debug( "Vary: set_cookie ---> $vary" ) ;
284
  LiteSpeed_Cache_Control::set_nocache( 'changing default vary' . " $current_vary => $vary" ) ;
285
  }
286
  }
@@ -314,7 +314,7 @@ class LiteSpeed_Cache_Vary
314
  $uid = LiteSpeed_Cache_Router::get_uid() ;
315
  }
316
  else {
317
- LiteSpeed_Cache_Log::debug( 'Vary: uid: ' . $uid ) ;
318
  }
319
 
320
  // get user's group id
@@ -336,13 +336,13 @@ class LiteSpeed_Cache_Vary
336
 
337
  if ( $admin_bar ) {
338
  $vary[ 'admin_bar' ] = 1 ;
339
- LiteSpeed_Cache_Log::debug2( 'Vary: admin bar : true' ) ;
340
  }
341
 
342
  }
343
  else {
344
  // Guest user
345
- LiteSpeed_Cache_Log::debug( 'Vary: role id: failed, guest' ) ;
346
 
347
  }
348
 
@@ -437,7 +437,7 @@ class LiteSpeed_Cache_Vary
437
  if ( ! empty( $_SERVER[ $tag ] ) ) {
438
  $path = parse_url( $_SERVER[ $tag ] ) ;
439
  $path = ! empty( $path[ 'path' ] ) ? $path[ 'path' ] : false ;
440
- LiteSpeed_Cache_Log::debug( 'Cookie Vary path: ' . $path ) ;
441
  }
442
  return $path ;
443
  }
@@ -499,7 +499,7 @@ class LiteSpeed_Cache_Vary
499
  global $post ;
500
  if ( ! empty($post->post_password) ) {
501
  if ( isset($_COOKIE['wp-postpass_' . COOKIEHASH]) ) {
502
- LiteSpeed_Cache_Log::debug( 'Vary: finalize bypassed due to password protected vary ' ) ;
503
  // If user has password cookie, do not cache
504
  LiteSpeed_Cache_Control::set_nocache('password protected vary') ;
505
  return ;
75
  * @since 1.6.7
76
  */
77
  add_action( 'rest_api_init', function(){
78
+ LiteSpeed_Cache_Log::debug( '[Vary] Rest API init disabled vary change' ) ;
79
  add_filter( 'litespeed_can_change_vary', '__return_false' ) ;
80
  } ) ;
81
 
197
  */
198
  public function add_logged_in( $logged_in_cookie = false, $expire = false, $expiration = false, $uid = false )
199
  {
200
+ LiteSpeed_Cache_Log::debug( '[Vary] add_logged_in' ) ;
201
  // If the cookie is lost somehow, set it
202
  $this->_update_default_vary( $uid, $expire ) ;
203
  }
211
  */
212
  public function remove_logged_in()
213
  {
214
+ LiteSpeed_Cache_Log::debug( '[Vary] remove_logged_in' ) ;
215
  // Force update vary to remove login status
216
  $this->_update_default_vary( -1 ) ;
217
  }
230
  * @since 1.6.6
231
  */
232
  if ( LiteSpeed_Cache_Router::is_ajax() && ! apply_filters( 'litespeed_ajax_vary', false ) ) {
233
+ LiteSpeed_Cache_Log::debug( '[Vary] can_change_vary bypassed due to ajax call' ) ;
234
  return false ;
235
  }
236
 
239
  * @since 1.6.5
240
  */
241
  if ( $_SERVER["REQUEST_METHOD"] !== 'GET' && $_SERVER["REQUEST_METHOD"] !== 'POST' ) {
242
+ LiteSpeed_Cache_Log::debug( '[Vary] can_change_vary bypassed due to method not get/post' ) ;
243
  return false ;
244
  }
245
 
246
  if ( ! apply_filters( 'litespeed_can_change_vary', true ) ) {
247
+ LiteSpeed_Cache_Log::debug( '[Vary] can_change_vary bypassed due to litespeed_can_change_vary hook' ) ;
248
  return false ;
249
  }
250
 
265
  define( 'LITESPEED_DID_' . __FUNCTION__, true ) ;
266
  }
267
  else {
268
+ LiteSpeed_Cache_Log::debug2( "[Vary] _update_default_vary bypassed due to run already" ) ;
269
  return ;
270
  }
271
 
280
  $expire = time() + 2 * DAY_IN_SECONDS ;
281
  }
282
  self::_cookie( $vary, $expire ) ;
283
+ LiteSpeed_Cache_Log::debug( "[Vary] set_cookie ---> $vary" ) ;
284
  LiteSpeed_Cache_Control::set_nocache( 'changing default vary' . " $current_vary => $vary" ) ;
285
  }
286
  }
314
  $uid = LiteSpeed_Cache_Router::get_uid() ;
315
  }
316
  else {
317
+ LiteSpeed_Cache_Log::debug( '[Vary] uid: ' . $uid ) ;
318
  }
319
 
320
  // get user's group id
336
 
337
  if ( $admin_bar ) {
338
  $vary[ 'admin_bar' ] = 1 ;
339
+ LiteSpeed_Cache_Log::debug2( '[Vary] admin bar : true' ) ;
340
  }
341
 
342
  }
343
  else {
344
  // Guest user
345
+ LiteSpeed_Cache_Log::debug( '[Vary] role id: failed, guest' ) ;
346
 
347
  }
348
 
437
  if ( ! empty( $_SERVER[ $tag ] ) ) {
438
  $path = parse_url( $_SERVER[ $tag ] ) ;
439
  $path = ! empty( $path[ 'path' ] ) ? $path[ 'path' ] : false ;
440
+ LiteSpeed_Cache_Log::debug( '[Vary] Cookie Vary path: ' . $path ) ;
441
  }
442
  return $path ;
443
  }
499
  global $post ;
500
  if ( ! empty($post->post_password) ) {
501
  if ( isset($_COOKIE['wp-postpass_' . COOKIEHASH]) ) {
502
+ LiteSpeed_Cache_Log::debug( '[Vary] finalize bypassed due to password protected vary ' ) ;
503
  // If user has password cookie, do not cache
504
  LiteSpeed_Cache_Control::set_nocache('password protected vary') ;
505
  return ;
includes/litespeed-cache-activation.class.php CHANGED
@@ -119,6 +119,16 @@ class LiteSpeed_Cache_Activation
119
  $count++ ;
120
  }
121
  }
 
 
 
 
 
 
 
 
 
 
122
  if ( is_plugin_active_for_network( LSCWP_BASENAME ) ) {
123
  $count++ ;
124
  }
119
  $count++ ;
120
  }
121
  }
122
+
123
+ /**
124
+ * In case this is called outside the admin page
125
+ * @see https://codex.wordpress.org/Function_Reference/is_plugin_active_for_network
126
+ * @since 2.0
127
+ */
128
+ if ( ! function_exists( 'is_plugin_active_for_network' ) ) {
129
+ require_once( ABSPATH . '/wp-admin/includes/plugin.php' ) ;
130
+ }
131
+
132
  if ( is_plugin_active_for_network( LSCWP_BASENAME ) ) {
133
  $count++ ;
134
  }
includes/litespeed-cache-cdn.class.php CHANGED
@@ -80,21 +80,29 @@ class LiteSpeed_Cache_CDN
80
  }
81
  $this_url = $v[ LiteSpeed_Cache_Config::ITEM_CDN_MAPPING_URL ] ;
82
  $this_host = parse_url( $this_url, PHP_URL_HOST ) ;
 
83
  foreach ( $mapping_to_check as $to_check ) {
84
  if ( $v[ $to_check ] ) {
85
  LiteSpeed_Cache_Log::debug2( 'CDN: mapping ' . $to_check . ' -> ' . $this_url ) ;
86
- $this->cfg_cdn_mapping[ $to_check ] = $this_url ;
 
 
 
87
  if ( ! in_array( $this_host, $this->cdn_mapping_hosts ) ) {
88
  $this->cdn_mapping_hosts[] = $this_host ;
89
  }
90
  }
91
  }
 
92
  if ( $v[ LiteSpeed_Cache_Config::ITEM_CDN_MAPPING_FILETYPE ] ) {
93
  $filetypes = array_map( 'trim', explode( "\n", $v[ LiteSpeed_Cache_Config::ITEM_CDN_MAPPING_FILETYPE ] ) ) ;
94
  foreach ( $filetypes as $v2 ) {
95
  if ( $v2 ) {
96
  $this->cfg_cdn_mapping[ LiteSpeed_Cache_Config::ITEM_CDN_MAPPING_FILETYPE ] = true ;
97
- $this->cfg_cdn_mapping[ $v2 ] = $this_url ;
 
 
 
98
  if ( ! in_array( $this_host, $this->cdn_mapping_hosts ) ) {
99
  $this->cdn_mapping_hosts[] = $this_host ;
100
  }
@@ -141,6 +149,28 @@ class LiteSpeed_Cache_CDN
141
 
142
  }
143
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
144
  /**
145
  * Handle all request actions from main cls
146
  *
@@ -515,6 +545,11 @@ class LiteSpeed_Cache_CDN
515
  $final_url = $this->cfg_cdn_mapping[ $postfix ] ;
516
  }
517
 
 
 
 
 
 
518
  // Now lets replace CDN url
519
  if ( strpos( $this->cfg_url_ori, '*' ) !== false ) {
520
  $url = preg_replace( '#' . $scheme . $this->cfg_url_ori . '#iU', $final_url, $url ) ;
80
  }
81
  $this_url = $v[ LiteSpeed_Cache_Config::ITEM_CDN_MAPPING_URL ] ;
82
  $this_host = parse_url( $this_url, PHP_URL_HOST ) ;
83
+ // Check img/css/js
84
  foreach ( $mapping_to_check as $to_check ) {
85
  if ( $v[ $to_check ] ) {
86
  LiteSpeed_Cache_Log::debug2( 'CDN: mapping ' . $to_check . ' -> ' . $this_url ) ;
87
+
88
+ // If filetype to url is one to many, make url be an array
89
+ $this->_append_cdn_mapping( $to_check, $this_url ) ;
90
+
91
  if ( ! in_array( $this_host, $this->cdn_mapping_hosts ) ) {
92
  $this->cdn_mapping_hosts[] = $this_host ;
93
  }
94
  }
95
  }
96
+ // Check file types
97
  if ( $v[ LiteSpeed_Cache_Config::ITEM_CDN_MAPPING_FILETYPE ] ) {
98
  $filetypes = array_map( 'trim', explode( "\n", $v[ LiteSpeed_Cache_Config::ITEM_CDN_MAPPING_FILETYPE ] ) ) ;
99
  foreach ( $filetypes as $v2 ) {
100
  if ( $v2 ) {
101
  $this->cfg_cdn_mapping[ LiteSpeed_Cache_Config::ITEM_CDN_MAPPING_FILETYPE ] = true ;
102
+
103
+ // If filetype to url is one to many, make url be an array
104
+ $this->_append_cdn_mapping( $v2, $this_url ) ;
105
+
106
  if ( ! in_array( $this_host, $this->cdn_mapping_hosts ) ) {
107
  $this->cdn_mapping_hosts[] = $this_host ;
108
  }
149
 
150
  }
151
 
152
+ /**
153
+ * Associate all filetypes with url
154
+ *
155
+ * @since 2.0
156
+ * @access private
157
+ */
158
+ private function _append_cdn_mapping( $filetype, $url )
159
+ {
160
+ // If filetype to url is one to many, make url be an array
161
+ if ( empty( $this->cfg_cdn_mapping[ $filetype ] ) ) {
162
+ $this->cfg_cdn_mapping[ $filetype ] = $url ;
163
+ }
164
+ elseif ( is_array( $this->cfg_cdn_mapping[ $filetype ] ) ) {
165
+ // Append url to filetype
166
+ $this->cfg_cdn_mapping[ $filetype ][] = $url ;
167
+ }
168
+ else {
169
+ // Convert cfg_cdn_mapping from string to array
170
+ $this->cfg_cdn_mapping[ $filetype ] = array( $this->cfg_cdn_mapping[ $filetype ], $url ) ;
171
+ }
172
+ }
173
+
174
  /**
175
  * Handle all request actions from main cls
176
  *
545
  $final_url = $this->cfg_cdn_mapping[ $postfix ] ;
546
  }
547
 
548
+ // If filetype to url is one to many, need to random one
549
+ if ( is_array( $final_url ) ) {
550
+ $final_url = $final_url[ mt_rand( 0, count( $final_url ) - 1 ) ] ;
551
+ }
552
+
553
  // Now lets replace CDN url
554
  if ( strpos( $this->cfg_url_ori, '*' ) !== false ) {
555
  $url = preg_replace( '#' . $scheme . $this->cfg_url_ori . '#iU', $final_url, $url ) ;
includes/litespeed-cache-config.class.php CHANGED
@@ -21,7 +21,7 @@ class LiteSpeed_Cache_Config
21
  const ITEM_OPTM_CSS = 'litespeed-optm-css' ;// separate critical css that should be stored in option table
22
  const ITEM_OPTM_JS_DEFER_EXC = 'litespeed-optm-js-defer-excludes' ;
23
  const ITEM_MEDIA_LAZY_IMG_EXC = 'litespeed-media-lazy-img-excludes' ;
24
- const ITEM_MEDIA_NEED_PULL = 'litespeed-media-need-pull' ;
25
  const ITEM_ENV_REF = 'litespeed-env-ref' ;
26
  const ITEM_CACHE_DROP_QS = 'litespeed-cache-drop_qs' ;
27
  const ITEM_CDN_MAPPING = 'litespeed-cache-cdn_mapping' ;
@@ -35,6 +35,7 @@ class LiteSpeed_Cache_Config
35
 
36
  const ITEM_SETTING_MODE = 'litespeed-setting-mode' ;
37
  const ITEM_CRAWLER_HASH = 'litespeed-crawler-hash' ;
 
38
 
39
  // Server variables
40
  const ENV_CRAWLER_USLEEP = 'CRAWLER_USLEEP' ;
@@ -200,6 +201,7 @@ class LiteSpeed_Cache_Config
200
  const CRWL_LOAD_LIMIT = 'crawler_load_limit' ;
201
  const CRWL_DOMAIN_IP = 'crawler_domain_ip' ;
202
  const CRWL_CUSTOM_SITEMAP = 'crawler_custom_sitemap' ;
 
203
 
204
  const CRWL_CRON_ACTIVE = 'crawler_cron_active' ;
205
 
@@ -271,12 +273,17 @@ class LiteSpeed_Cache_Config
271
  {
272
  $site_options = get_site_option( self::OPTION_NAME ) ;
273
 
274
- if ( ! function_exists('is_plugin_active_for_network') ) { // todo: check if needed
275
- require_once(ABSPATH . '/wp-admin/includes/plugin.php') ;
276
- }
277
-
278
  $options = get_option( self::OPTION_NAME, $this->get_default_options() ) ;
279
 
 
 
 
 
 
 
 
 
 
280
  // If don't have site options
281
  if ( ! $site_options || ! is_array( $site_options ) || ! is_plugin_active_for_network( 'litespeed-cache/litespeed-cache.php' ) ) {
282
  if ( $options[ self::OPID_ENABLED_RADIO ] === self::VAL_ON2 ) { // Default to cache on
@@ -661,6 +668,7 @@ class LiteSpeed_Cache_Config
661
  self::CRWL_DOMAIN_IP => '',
662
  self::CRWL_CUSTOM_SITEMAP => '',
663
  self::CRWL_CRON_ACTIVE => false,
 
664
  ) ;
665
 
666
  if ( LSWCP_ESI_SUPPORT ) {
@@ -891,6 +899,9 @@ class LiteSpeed_Cache_Config
891
  define( 'LSWCP_EMPTYCACHE', true ) ;// clear all sites caches
892
  LiteSpeed_Cache_Purge::purge_all() ;
893
  LiteSpeed_Cache_Log::debug( "Config: plugin_upgrade option changed = $res" ) ;
 
 
 
894
  }
895
 
896
  /**
21
  const ITEM_OPTM_CSS = 'litespeed-optm-css' ;// separate critical css that should be stored in option table
22
  const ITEM_OPTM_JS_DEFER_EXC = 'litespeed-optm-js-defer-excludes' ;
23
  const ITEM_MEDIA_LAZY_IMG_EXC = 'litespeed-media-lazy-img-excludes' ;
24
+ const ITEM_IMG_OPTM_NEED_PULL = 'litespeed-media-need-pull' ;
25
  const ITEM_ENV_REF = 'litespeed-env-ref' ;
26
  const ITEM_CACHE_DROP_QS = 'litespeed-cache-drop_qs' ;
27
  const ITEM_CDN_MAPPING = 'litespeed-cache-cdn_mapping' ;
35
 
36
  const ITEM_SETTING_MODE = 'litespeed-setting-mode' ;
37
  const ITEM_CRAWLER_HASH = 'litespeed-crawler-hash' ;
38
+ const ITEM_GUIDE = 'litespeed-guide' ; // Array of each guidance tag as key, step as val
39
 
40
  // Server variables
41
  const ENV_CRAWLER_USLEEP = 'CRAWLER_USLEEP' ;
201
  const CRWL_LOAD_LIMIT = 'crawler_load_limit' ;
202
  const CRWL_DOMAIN_IP = 'crawler_domain_ip' ;
203
  const CRWL_CUSTOM_SITEMAP = 'crawler_custom_sitemap' ;
204
+ const CRWL_HTTP2 = 'crawler_http2' ;
205
 
206
  const CRWL_CRON_ACTIVE = 'crawler_cron_active' ;
207
 
273
  {
274
  $site_options = get_site_option( self::OPTION_NAME ) ;
275
 
 
 
 
 
276
  $options = get_option( self::OPTION_NAME, $this->get_default_options() ) ;
277
 
278
+ /**
279
+ * In case this is called outside the admin page
280
+ * @see https://codex.wordpress.org/Function_Reference/is_plugin_active_for_network
281
+ * @since 2.0
282
+ */
283
+ if ( ! function_exists( 'is_plugin_active_for_network' ) ) {
284
+ require_once( ABSPATH . '/wp-admin/includes/plugin.php' ) ;
285
+ }
286
+
287
  // If don't have site options
288
  if ( ! $site_options || ! is_array( $site_options ) || ! is_plugin_active_for_network( 'litespeed-cache/litespeed-cache.php' ) ) {
289
  if ( $options[ self::OPID_ENABLED_RADIO ] === self::VAL_ON2 ) { // Default to cache on
668
  self::CRWL_DOMAIN_IP => '',
669
  self::CRWL_CUSTOM_SITEMAP => '',
670
  self::CRWL_CRON_ACTIVE => false,
671
+ self::CRWL_HTTP2 => true,
672
  ) ;
673
 
674
  if ( LSWCP_ESI_SUPPORT ) {
899
  define( 'LSWCP_EMPTYCACHE', true ) ;// clear all sites caches
900
  LiteSpeed_Cache_Purge::purge_all() ;
901
  LiteSpeed_Cache_Log::debug( "Config: plugin_upgrade option changed = $res" ) ;
902
+
903
+ // Update img_optm table data for upgrading
904
+ LiteSpeed_Cache_Data::get_instance() ;
905
  }
906
 
907
  /**
includes/litespeed-cache-crawler.class.php CHANGED
@@ -384,6 +384,8 @@ class LiteSpeed_Cache_Crawler
384
  $crawler->set_base_url($this->_home_url) ;
385
  $crawler->set_run_duration($options[LiteSpeed_Cache_Config::CRWL_RUN_DURATION]) ;
386
 
 
 
387
  /**
388
  * Limit delay to use server setting
389
  * @since 1.8.3
384
  $crawler->set_base_url($this->_home_url) ;
385
  $crawler->set_run_duration($options[LiteSpeed_Cache_Config::CRWL_RUN_DURATION]) ;
386
 
387
+ $crawler->set_http2( $options[ LiteSpeed_Cache_Config::CRWL_HTTP2 ] ) ;
388
+
389
  /**
390
  * Limit delay to use server setting
391
  * @since 1.8.3
includes/litespeed-cache-gui.class.php CHANGED
@@ -79,15 +79,17 @@ class LiteSpeed_Cache_GUI
79
  *
80
  * @since 1.6.6
81
  */
82
- public static function pie( $percent, $width = 50 )
83
  {
 
 
 
 
84
  return "
85
  <svg class='litespeed-pie' viewbox='0 0 33.83098862 33.83098862' width='$width' height='$width' xmlns='http://www.w3.org/2000/svg'>
86
  <circle class='litespeed-pie_bg' />
87
  <circle class='litespeed-pie_circle' stroke-dasharray='$percent,100' />
88
- <g class='litespeed-pie_info'>
89
- <text x='16.91549431' y='15.5'>$percent%</text>
90
- </g>
91
  </svg>
92
  ";
93
 
79
  *
80
  * @since 1.6.6
81
  */
82
+ public static function pie( $percent, $width = 50, $finished_tick = false )
83
  {
84
+ $percentage = '<text x="16.91549431" y="15.5">' . $percent . '%</text>' ;
85
+ if ( $percent == 100 && $finished_tick ) {
86
+ $percentage = '<text x="16.91549431" y="15.5" fill="#73b38d">&#x2713</text>' ;
87
+ }
88
  return "
89
  <svg class='litespeed-pie' viewbox='0 0 33.83098862 33.83098862' width='$width' height='$width' xmlns='http://www.w3.org/2000/svg'>
90
  <circle class='litespeed-pie_bg' />
91
  <circle class='litespeed-pie_circle' stroke-dasharray='$percent,100' />
92
+ <g class='litespeed-pie_info'>$percentage</g>
 
 
93
  </svg>
94
  ";
95
 
includes/litespeed-cache-router.class.php CHANGED
@@ -39,23 +39,23 @@ class LiteSpeed_Cache_Router
39
  return ;
40
  }
41
 
42
- LiteSpeed_Cache_Log::debug( 'Router: starting crawler role validation' ) ;
43
 
44
  // Check if is from crawler
45
  if ( empty( $_SERVER[ 'HTTP_USER_AGENT' ] ) || $_SERVER[ 'HTTP_USER_AGENT' ] !== Litespeed_Crawler::FAST_USER_AGENT ) {
46
- LiteSpeed_Cache_Log::debug( 'Router: user agent not match' ) ;
47
  return ;
48
  }
49
 
50
  // Hash validation
51
  $hash = get_option( LiteSpeed_Cache_Config::ITEM_CRAWLER_HASH ) ;
52
  if ( ! $hash || $_COOKIE[ 'litespeed_hash' ] != $hash ) {
53
- LiteSpeed_Cache_Log::debug( 'Router: crawler hash not match ' . $_COOKIE[ 'litespeed_hash' ] . ' != ' . $hash ) ;
54
  return ;
55
  }
56
 
57
  $role_uid = $_COOKIE[ 'litespeed_role' ] ;
58
- LiteSpeed_Cache_Log::debug( 'Router: role simulate litespeed_role uid ' . $role_uid ) ;
59
 
60
  wp_set_current_user( $role_uid ) ;
61
  }
@@ -74,7 +74,7 @@ class LiteSpeed_Cache_Router
74
  $user = wp_get_current_user() ;
75
  $user_id = $user->ID ;
76
 
77
- LiteSpeed_Cache_Log::debug( 'Router: get_uid: ' . $user_id, 3 ) ;
78
 
79
  define( 'LITESPEED_WP_UID', $user_id ) ;
80
 
@@ -104,11 +104,11 @@ class LiteSpeed_Cache_Router
104
  $role = array_shift( $tmp ) ;
105
  }
106
  }
107
- LiteSpeed_Cache_Log::debug( 'Router: get_role: ' . $role ) ;
108
 
109
  if ( ! $role ) {
110
  // Guest user
111
- LiteSpeed_Cache_Log::debug( 'Router: role: guest' ) ;
112
  }
113
 
114
  define( 'LITESPEED_WP_ROLE', $role ) ;
@@ -190,7 +190,7 @@ class LiteSpeed_Cache_Router
190
  self::$_action = false;
191
  self::get_instance()->verify_action() ;
192
  if ( self::$_action ) {
193
- defined( 'LSCWP_LOG' ) && LiteSpeed_Cache_Log::debug( 'LSCWP_CTRL verified: ' . var_export( self::$_action, true ) ) ;
194
  }
195
 
196
  }
@@ -264,11 +264,11 @@ class LiteSpeed_Cache_Router
264
  public static function verify_type()
265
  {
266
  if ( empty( $_REQUEST[ 'type' ] ) ) {
267
- LiteSpeed_Cache_Log::debug( 'Router no type', 2 ) ;
268
  return false ;
269
  }
270
 
271
- LiteSpeed_Cache_Log::debug( 'Router parsed type: ' . $_REQUEST[ 'type' ], 2 ) ;
272
 
273
  return $_REQUEST[ 'type' ] ;
274
  }
@@ -282,7 +282,7 @@ class LiteSpeed_Cache_Router
282
  private function verify_action()
283
  {
284
  if ( empty( $_REQUEST[ LiteSpeed_Cache::ACTION_KEY ] ) ) {
285
- LiteSpeed_Cache_Log::debug2( 'LSCWP_CTRL bypassed empty' ) ;
286
  return ;
287
  }
288
 
@@ -294,7 +294,7 @@ class LiteSpeed_Cache_Router
294
  if ( ! $this->verify_nonce( $action ) && ! $this->_verify_sapi_passive( $action ) && ! $this->_verify_sapi_aggressive( $action ) ) {
295
  // check if it is from admin ip
296
  if ( ! $this->is_admin_ip() ) {
297
- LiteSpeed_Cache_Log::debug( 'LSCWP_CTRL query string - did not match admin IP: ' . $action ) ;
298
  return ;
299
  }
300
 
@@ -307,7 +307,7 @@ class LiteSpeed_Cache_Router
307
  LiteSpeed_Cache::ACTION_QS_PURGE_ALL,
308
  LiteSpeed_Cache::ACTION_QS_PURGE_EMPTYCACHE,
309
  ) ) ) {
310
- LiteSpeed_Cache_Log::debug( 'LSCWP_CTRL query string - did not match admin IP Actions: ' . $action ) ;
311
  return ;
312
  }
313
 
@@ -315,7 +315,7 @@ class LiteSpeed_Cache_Router
315
  }
316
 
317
  /* Now it is a valid action, lets log and check the permission */
318
- LiteSpeed_Cache_Log::debug( 'LSCWP_CTRL: ' . $action ) ;
319
 
320
  // OK, as we want to do something magic, lets check if its allowed
321
  $_is_multisite = is_multisite() ;
@@ -381,9 +381,11 @@ class LiteSpeed_Cache_Router
381
  case LiteSpeed_Cache::ACTION_BLACKLIST_SAVE:
382
  case LiteSpeed_Cache::ACTION_PURGE:
383
  case LiteSpeed_Cache::ACTION_MEDIA:
 
384
  case LiteSpeed_Cache::ACTION_IAPI:
385
  case LiteSpeed_Cache::ACTION_CDN:
386
  case LiteSpeed_Cache::ACTION_IMPORT:
 
387
  if ( defined( 'LITESPEED_ON' ) && $_can_option && ! $_is_network_admin ) {
388
  self::$_action = $action ;
389
  }
@@ -413,7 +415,7 @@ class LiteSpeed_Cache_Router
413
  return ;
414
 
415
  default:
416
- LiteSpeed_Cache_Log::debug( 'LSCWP_CTRL match falied: ' . $action ) ;
417
  return ;
418
  }
419
 
39
  return ;
40
  }
41
 
42
+ LiteSpeed_Cache_Log::debug( '[Router] starting crawler role validation' ) ;
43
 
44
  // Check if is from crawler
45
  if ( empty( $_SERVER[ 'HTTP_USER_AGENT' ] ) || $_SERVER[ 'HTTP_USER_AGENT' ] !== Litespeed_Crawler::FAST_USER_AGENT ) {
46
+ LiteSpeed_Cache_Log::debug( '[Router] user agent not match' ) ;
47
  return ;
48
  }
49
 
50
  // Hash validation
51
  $hash = get_option( LiteSpeed_Cache_Config::ITEM_CRAWLER_HASH ) ;
52
  if ( ! $hash || $_COOKIE[ 'litespeed_hash' ] != $hash ) {
53
+ LiteSpeed_Cache_Log::debug( '[Router] crawler hash not match ' . $_COOKIE[ 'litespeed_hash' ] . ' != ' . $hash ) ;
54
  return ;
55
  }
56
 
57
  $role_uid = $_COOKIE[ 'litespeed_role' ] ;
58
+ LiteSpeed_Cache_Log::debug( '[Router] role simulate litespeed_role uid ' . $role_uid ) ;
59
 
60
  wp_set_current_user( $role_uid ) ;
61
  }
74
  $user = wp_get_current_user() ;
75
  $user_id = $user->ID ;
76
 
77
+ LiteSpeed_Cache_Log::debug( '[Router] get_uid: ' . $user_id, 3 ) ;
78
 
79
  define( 'LITESPEED_WP_UID', $user_id ) ;
80
 
104
  $role = array_shift( $tmp ) ;
105
  }
106
  }
107
+ LiteSpeed_Cache_Log::debug( '[Router] get_role: ' . $role ) ;
108
 
109
  if ( ! $role ) {
110
  // Guest user
111
+ LiteSpeed_Cache_Log::debug( '[Router] role: guest' ) ;
112
  }
113
 
114
  define( 'LITESPEED_WP_ROLE', $role ) ;
190
  self::$_action = false;
191
  self::get_instance()->verify_action() ;
192
  if ( self::$_action ) {
193
+ defined( 'LSCWP_LOG' ) && LiteSpeed_Cache_Log::debug( '[Router] LSCWP_CTRL verified: ' . var_export( self::$_action, true ) ) ;
194
  }
195
 
196
  }
264
  public static function verify_type()
265
  {
266
  if ( empty( $_REQUEST[ 'type' ] ) ) {
267
+ LiteSpeed_Cache_Log::debug( '[Router] no type', 2 ) ;
268
  return false ;
269
  }
270
 
271
+ LiteSpeed_Cache_Log::debug( '[Router] parsed type: ' . $_REQUEST[ 'type' ], 2 ) ;
272
 
273
  return $_REQUEST[ 'type' ] ;
274
  }
282
  private function verify_action()
283
  {
284
  if ( empty( $_REQUEST[ LiteSpeed_Cache::ACTION_KEY ] ) ) {
285
+ LiteSpeed_Cache_Log::debug2( '[Router] LSCWP_CTRL bypassed empty' ) ;
286
  return ;
287
  }
288
 
294
  if ( ! $this->verify_nonce( $action ) && ! $this->_verify_sapi_passive( $action ) && ! $this->_verify_sapi_aggressive( $action ) ) {
295
  // check if it is from admin ip
296
  if ( ! $this->is_admin_ip() ) {
297
+ LiteSpeed_Cache_Log::debug( '[Router] LSCWP_CTRL query string - did not match admin IP: ' . $action ) ;
298
  return ;
299
  }
300
 
307
  LiteSpeed_Cache::ACTION_QS_PURGE_ALL,
308
  LiteSpeed_Cache::ACTION_QS_PURGE_EMPTYCACHE,
309
  ) ) ) {
310
+ LiteSpeed_Cache_Log::debug( '[Router] LSCWP_CTRL query string - did not match admin IP Actions: ' . $action ) ;
311
  return ;
312
  }
313
 
315
  }
316
 
317
  /* Now it is a valid action, lets log and check the permission */
318
+ LiteSpeed_Cache_Log::debug( '[Router] LSCWP_CTRL: ' . $action ) ;
319
 
320
  // OK, as we want to do something magic, lets check if its allowed
321
  $_is_multisite = is_multisite() ;
381
  case LiteSpeed_Cache::ACTION_BLACKLIST_SAVE:
382
  case LiteSpeed_Cache::ACTION_PURGE:
383
  case LiteSpeed_Cache::ACTION_MEDIA:
384
+ case LiteSpeed_Cache::ACTION_IMG_OPTM:
385
  case LiteSpeed_Cache::ACTION_IAPI:
386
  case LiteSpeed_Cache::ACTION_CDN:
387
  case LiteSpeed_Cache::ACTION_IMPORT:
388
+ case LiteSpeed_Cache::ACTION_QUIC_CLOUD:
389
  if ( defined( 'LITESPEED_ON' ) && $_can_option && ! $_is_network_admin ) {
390
  self::$_action = $action ;
391
  }
415
  return ;
416
 
417
  default:
418
+ LiteSpeed_Cache_Log::debug( '[Router] LSCWP_CTRL match falied: ' . $action ) ;
419
  return ;
420
  }
421
 
includes/litespeed-cache-task.class.php CHANGED
@@ -38,10 +38,10 @@ class LiteSpeed_Cache_Task
38
  }
39
 
40
  // Register img optimization fetch ( always fetch immediately )
41
- if ( ! LiteSpeed_Cache::config( LiteSpeed_Cache_Config::OPID_MEDIA_IMG_OPTM_CRON_OFF ) && LiteSpeed_Cache_Media::check_need_pull() ) {
42
  self::schedule_filter_imgoptm() ;
43
 
44
- add_action( self::CRON_ACTION_HOOK_IMGOPTM, 'LiteSpeed_Cache_Media::pull_optimized_img' ) ;
45
  }
46
  else {
47
  // wp_clear_scheduled_hook( self::CRON_ACTION_HOOK_IMGOPTM ) ;
38
  }
39
 
40
  // Register img optimization fetch ( always fetch immediately )
41
+ if ( ! LiteSpeed_Cache::config( LiteSpeed_Cache_Config::OPID_MEDIA_IMG_OPTM_CRON_OFF ) && LiteSpeed_Cache_Img_Optm::check_need_pull() ) {
42
  self::schedule_filter_imgoptm() ;
43
 
44
+ add_action( self::CRON_ACTION_HOOK_IMGOPTM, 'LiteSpeed_Cache_Img_Optm::pull_optimized_img' ) ;
45
  }
46
  else {
47
  // wp_clear_scheduled_hook( self::CRON_ACTION_HOOK_IMGOPTM ) ;
includes/litespeed-cache-vary.class.php CHANGED
@@ -75,7 +75,7 @@ class LiteSpeed_Cache_Vary
75
  * @since 1.6.7
76
  */
77
  add_action( 'rest_api_init', function(){
78
- LiteSpeed_Cache_Log::debug( 'Vary: Rest API init disabled vary change' ) ;
79
  add_filter( 'litespeed_can_change_vary', '__return_false' ) ;
80
  } ) ;
81
 
@@ -197,7 +197,7 @@ class LiteSpeed_Cache_Vary
197
  */
198
  public function add_logged_in( $logged_in_cookie = false, $expire = false, $expiration = false, $uid = false )
199
  {
200
- LiteSpeed_Cache_Log::debug( 'Vary: add_logged_in' ) ;
201
  // If the cookie is lost somehow, set it
202
  $this->_update_default_vary( $uid, $expire ) ;
203
  }
@@ -211,7 +211,7 @@ class LiteSpeed_Cache_Vary
211
  */
212
  public function remove_logged_in()
213
  {
214
- LiteSpeed_Cache_Log::debug( 'Vary: remove_logged_in' ) ;
215
  // Force update vary to remove login status
216
  $this->_update_default_vary( -1 ) ;
217
  }
@@ -230,7 +230,7 @@ class LiteSpeed_Cache_Vary
230
  * @since 1.6.6
231
  */
232
  if ( LiteSpeed_Cache_Router::is_ajax() && ! apply_filters( 'litespeed_ajax_vary', false ) ) {
233
- LiteSpeed_Cache_Log::debug( 'Vary: can_change_vary bypassed due to ajax call' ) ;
234
  return false ;
235
  }
236
 
@@ -239,12 +239,12 @@ class LiteSpeed_Cache_Vary
239
  * @since 1.6.5
240
  */
241
  if ( $_SERVER["REQUEST_METHOD"] !== 'GET' && $_SERVER["REQUEST_METHOD"] !== 'POST' ) {
242
- LiteSpeed_Cache_Log::debug( 'Vary: can_change_vary bypassed due to method not get/post' ) ;
243
  return false ;
244
  }
245
 
246
  if ( ! apply_filters( 'litespeed_can_change_vary', true ) ) {
247
- LiteSpeed_Cache_Log::debug( 'Vary: can_change_vary bypassed due to litespeed_can_change_vary hook' ) ;
248
  return false ;
249
  }
250
 
@@ -265,7 +265,7 @@ class LiteSpeed_Cache_Vary
265
  define( 'LITESPEED_DID_' . __FUNCTION__, true ) ;
266
  }
267
  else {
268
- LiteSpeed_Cache_Log::debug2( "Vary: _update_default_vary bypassed due to run already" ) ;
269
  return ;
270
  }
271
 
@@ -280,7 +280,7 @@ class LiteSpeed_Cache_Vary
280
  $expire = time() + 2 * DAY_IN_SECONDS ;
281
  }
282
  self::_cookie( $vary, $expire ) ;
283
- LiteSpeed_Cache_Log::debug( "Vary: set_cookie ---> $vary" ) ;
284
  LiteSpeed_Cache_Control::set_nocache( 'changing default vary' . " $current_vary => $vary" ) ;
285
  }
286
  }
@@ -314,7 +314,7 @@ class LiteSpeed_Cache_Vary
314
  $uid = LiteSpeed_Cache_Router::get_uid() ;
315
  }
316
  else {
317
- LiteSpeed_Cache_Log::debug( 'Vary: uid: ' . $uid ) ;
318
  }
319
 
320
  // get user's group id
@@ -336,13 +336,13 @@ class LiteSpeed_Cache_Vary
336
 
337
  if ( $admin_bar ) {
338
  $vary[ 'admin_bar' ] = 1 ;
339
- LiteSpeed_Cache_Log::debug2( 'Vary: admin bar : true' ) ;
340
  }
341
 
342
  }
343
  else {
344
  // Guest user
345
- LiteSpeed_Cache_Log::debug( 'Vary: role id: failed, guest' ) ;
346
 
347
  }
348
 
@@ -437,7 +437,7 @@ class LiteSpeed_Cache_Vary
437
  if ( ! empty( $_SERVER[ $tag ] ) ) {
438
  $path = parse_url( $_SERVER[ $tag ] ) ;
439
  $path = ! empty( $path[ 'path' ] ) ? $path[ 'path' ] : false ;
440
- LiteSpeed_Cache_Log::debug( 'Cookie Vary path: ' . $path ) ;
441
  }
442
  return $path ;
443
  }
@@ -499,7 +499,7 @@ class LiteSpeed_Cache_Vary
499
  global $post ;
500
  if ( ! empty($post->post_password) ) {
501
  if ( isset($_COOKIE['wp-postpass_' . COOKIEHASH]) ) {
502
- LiteSpeed_Cache_Log::debug( 'Vary: finalize bypassed due to password protected vary ' ) ;
503
  // If user has password cookie, do not cache
504
  LiteSpeed_Cache_Control::set_nocache('password protected vary') ;
505
  return ;
75
  * @since 1.6.7
76
  */
77
  add_action( 'rest_api_init', function(){
78
+ LiteSpeed_Cache_Log::debug( '[Vary] Rest API init disabled vary change' ) ;
79
  add_filter( 'litespeed_can_change_vary', '__return_false' ) ;
80
  } ) ;
81
 
197
  */
198
  public function add_logged_in( $logged_in_cookie = false, $expire = false, $expiration = false, $uid = false )
199
  {
200
+ LiteSpeed_Cache_Log::debug( '[Vary] add_logged_in' ) ;
201
  // If the cookie is lost somehow, set it
202
  $this->_update_default_vary( $uid, $expire ) ;
203
  }
211
  */
212
  public function remove_logged_in()
213
  {
214
+ LiteSpeed_Cache_Log::debug( '[Vary] remove_logged_in' ) ;
215
  // Force update vary to remove login status
216
  $this->_update_default_vary( -1 ) ;
217
  }
230
  * @since 1.6.6
231
  */
232
  if ( LiteSpeed_Cache_Router::is_ajax() && ! apply_filters( 'litespeed_ajax_vary', false ) ) {
233
+ LiteSpeed_Cache_Log::debug( '[Vary] can_change_vary bypassed due to ajax call' ) ;
234
  return false ;
235
  }
236
 
239
  * @since 1.6.5
240
  */
241
  if ( $_SERVER["REQUEST_METHOD"] !== 'GET' && $_SERVER["REQUEST_METHOD"] !== 'POST' ) {
242
+ LiteSpeed_Cache_Log::debug( '[Vary] can_change_vary bypassed due to method not get/post' ) ;
243
  return false ;
244
  }
245
 
246
  if ( ! apply_filters( 'litespeed_can_change_vary', true ) ) {
247
+ LiteSpeed_Cache_Log::debug( '[Vary] can_change_vary bypassed due to litespeed_can_change_vary hook' ) ;
248
  return false ;
249
  }
250
 
265
  define( 'LITESPEED_DID_' . __FUNCTION__, true ) ;
266
  }
267
  else {
268
+ LiteSpeed_Cache_Log::debug2( "[Vary] _update_default_vary bypassed due to run already" ) ;
269
  return ;
270
  }
271
 
280
  $expire = time() + 2 * DAY_IN_SECONDS ;
281
  }
282
  self::_cookie( $vary, $expire ) ;
283
+ LiteSpeed_Cache_Log::debug( "[Vary] set_cookie ---> $vary" ) ;
284
  LiteSpeed_Cache_Control::set_nocache( 'changing default vary' . " $current_vary => $vary" ) ;
285
  }
286
  }
314
  $uid = LiteSpeed_Cache_Router::get_uid() ;
315
  }
316
  else {
317
+ LiteSpeed_Cache_Log::debug( '[Vary] uid: ' . $uid ) ;
318
  }
319
 
320
  // get user's group id
336
 
337
  if ( $admin_bar ) {
338
  $vary[ 'admin_bar' ] = 1 ;
339
+ LiteSpeed_Cache_Log::debug2( '[Vary] admin bar : true' ) ;
340
  }
341
 
342
  }
343
  else {
344
  // Guest user
345
+ LiteSpeed_Cache_Log::debug( '[Vary] role id: failed, guest' ) ;
346
 
347
  }
348
 
437
  if ( ! empty( $_SERVER[ $tag ] ) ) {
438
  $path = parse_url( $_SERVER[ $tag ] ) ;
439
  $path = ! empty( $path[ 'path' ] ) ? $path[ 'path' ] : false ;
440
+ LiteSpeed_Cache_Log::debug( '[Vary] Cookie Vary path: ' . $path ) ;
441
  }
442
  return $path ;
443
  }
499
  global $post ;
500
  if ( ! empty($post->post_password) ) {
501
  if ( isset($_COOKIE['wp-postpass_' . COOKIEHASH]) ) {
502
+ LiteSpeed_Cache_Log::debug( '[Vary] finalize bypassed due to password protected vary ' ) ;
503
  // If user has password cookie, do not cache
504
  LiteSpeed_Cache_Control::set_nocache('password protected vary') ;
505
  return ;
includes/litespeed-cache.class.php CHANGED
@@ -19,7 +19,7 @@ class LiteSpeed_Cache
19
  private static $_instance ;
20
 
21
  const PLUGIN_NAME = 'litespeed-cache' ;
22
- const PLUGIN_VERSION = '1.9.1.1' ;
23
 
24
  const PAGE_EDIT_HTACCESS = 'lscache-edit-htaccess' ;
25
 
@@ -47,6 +47,7 @@ class LiteSpeed_Cache
47
  const ACTION_CRAWLER_CRON_ENABLE = 'crawler-cron-enable' ;
48
  const ACTION_DO_CRAWL = 'do-crawl' ;
49
  const ACTION_BLACKLIST_SAVE = 'blacklist-save' ;
 
50
 
51
  const ACTION_FRONT_PURGE = 'front-purge' ;
52
  const ACTION_FRONT_EXCLUDE = 'front-exclude' ;
@@ -57,6 +58,7 @@ class LiteSpeed_Cache
57
  const ACTION_IMPORT = 'import' ;
58
  const ACTION_PURGE = 'purge' ;
59
  const ACTION_MEDIA = 'media' ;
 
60
  const ACTION_IAPI = 'iapi' ;
61
  const ACTION_CDN = 'cdn' ;
62
  const ACTION_REPORT = 'report' ;
@@ -328,6 +330,10 @@ class LiteSpeed_Cache
328
  $msg = LiteSpeed_Cache_Media::handler() ;
329
  break ;
330
 
 
 
 
 
331
  case LiteSpeed_Cache::ACTION_PURGE:
332
  $msg = LiteSpeed_Cache_Purge::handler() ;
333
  break ;
@@ -352,6 +358,10 @@ class LiteSpeed_Cache
352
  $msg = LiteSpeed_Cache_Import::handler() ;
353
  break ;
354
 
 
 
 
 
355
  default:
356
  break ;
357
  }
19
  private static $_instance ;
20
 
21
  const PLUGIN_NAME = 'litespeed-cache' ;
22
+ const PLUGIN_VERSION = '2.0' ;
23
 
24
  const PAGE_EDIT_HTACCESS = 'lscache-edit-htaccess' ;
25
 
47
  const ACTION_CRAWLER_CRON_ENABLE = 'crawler-cron-enable' ;
48
  const ACTION_DO_CRAWL = 'do-crawl' ;
49
  const ACTION_BLACKLIST_SAVE = 'blacklist-save' ;
50
+ const ACTION_QUIC_CLOUD = 'quic_cloud' ;
51
 
52
  const ACTION_FRONT_PURGE = 'front-purge' ;
53
  const ACTION_FRONT_EXCLUDE = 'front-exclude' ;
58
  const ACTION_IMPORT = 'import' ;
59
  const ACTION_PURGE = 'purge' ;
60
  const ACTION_MEDIA = 'media' ;
61
+ const ACTION_IMG_OPTM = 'img_optm' ;
62
  const ACTION_IAPI = 'iapi' ;
63
  const ACTION_CDN = 'cdn' ;
64
  const ACTION_REPORT = 'report' ;
330
  $msg = LiteSpeed_Cache_Media::handler() ;
331
  break ;
332
 
333
+ case LiteSpeed_Cache::ACTION_IMG_OPTM:
334
+ $msg = LiteSpeed_Cache_Img_Optm::handler() ;
335
+ break ;
336
+
337
  case LiteSpeed_Cache::ACTION_PURGE:
338
  $msg = LiteSpeed_Cache_Purge::handler() ;
339
  break ;
358
  $msg = LiteSpeed_Cache_Import::handler() ;
359
  break ;
360
 
361
+ case LiteSpeed_Cache::ACTION_QUIC_CLOUD:
362
+ $msg = LiteSpeed_Cache_QUIC_CLOUD::handler() ;
363
+ break ;
364
+
365
  default:
366
  break ;
367
  }
includes/litespeed.autoload.php CHANGED
@@ -34,11 +34,13 @@ if ( !function_exists('_litespeed_autoload') ) {
34
  'LiteSpeed_Cache_ESI' => 'inc/esi.class.php',
35
  'LiteSpeed_Cache_GUI' => 'inc/gui.class.php',
36
  'LiteSpeed_Cache_Import' => 'inc/import.class.php',
 
37
  'LiteSpeed_Cache_Log' => 'inc/log.class.php',
38
  'LiteSpeed_Cache_Media' => 'inc/media.class.php',
39
  'LiteSpeed_Cache_Object' => 'inc/object.class.php',
40
  'LiteSpeed_Cache_Optimize' => 'inc/optimize.class.php',
41
  'LiteSpeed_Cache_Optimizer' => 'inc/optimizer.class.php',
 
42
  'LiteSpeed_Cache_Purge' => 'inc/purge.class.php',
43
  'LiteSpeed_Cache_Router' => 'inc/router.class.php',
44
  'LiteSpeed_Cache_Tag' => 'inc/tag.class.php',
34
  'LiteSpeed_Cache_ESI' => 'inc/esi.class.php',
35
  'LiteSpeed_Cache_GUI' => 'inc/gui.class.php',
36
  'LiteSpeed_Cache_Import' => 'inc/import.class.php',
37
+ 'LiteSpeed_Cache_Img_Optm' => 'inc/img_optm.class.php',
38
  'LiteSpeed_Cache_Log' => 'inc/log.class.php',
39
  'LiteSpeed_Cache_Media' => 'inc/media.class.php',
40
  'LiteSpeed_Cache_Object' => 'inc/object.class.php',
41
  'LiteSpeed_Cache_Optimize' => 'inc/optimize.class.php',
42
  'LiteSpeed_Cache_Optimizer' => 'inc/optimizer.class.php',
43
+ 'LiteSpeed_Cache_QUIC_CLOUD' => 'inc/quic_cloud.class.php',
44
  'LiteSpeed_Cache_Purge' => 'inc/purge.class.php',
45
  'LiteSpeed_Cache_Router' => 'inc/router.class.php',
46
  'LiteSpeed_Cache_Tag' => 'inc/tag.class.php',
js/iziModal.min.js ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
1
+ /*
2
+ * iziModal | v1.6.0
3
+ * http://izimodal.marcelodolce.com
4
+ * by Marcelo Dolce.
5
+ */
6
+ !function(t){"function"==typeof define&&define.amd?define(["jquery"],t):"object"==typeof module&&module.exports?module.exports=function(e,i){return void 0===i&&(i="undefined"!=typeof window?require("jquery"):require("jquery")(e)),t(i),i}:t(jQuery)}(function(t){function e(){var t,e=document.createElement("fakeelement"),i={animation:"animationend",OAnimation:"oAnimationEnd",MozAnimation:"animationend",WebkitAnimation:"webkitAnimationEnd"};for(t in i)if(void 0!==e.style[t])return i[t]}function i(t){return 9===t?navigator.appVersion.indexOf("MSIE 9.")!==-1:(userAgent=navigator.userAgent,userAgent.indexOf("MSIE ")>-1||userAgent.indexOf("Trident/")>-1)}function n(t){var e=/%|px|em|cm|vh|vw/;return parseInt(String(t).split(e)[0])}function o(e){var i=e.replace(/^.*#/,""),n=t(e);n.attr("id",i+"-tmp"),window.location.hash=e,n.attr("id",i)}var s=t(window),a=t(document),r="iziModal",l={CLOSING:"closing",CLOSED:"closed",OPENING:"opening",OPENED:"opened",DESTROYED:"destroyed"},d=e(),h=!!/Mobi/.test(navigator.userAgent);window.$iziModal={},window.$iziModal.autoOpen=0,window.$iziModal.history=!1;var c=function(t,e){this.init(t,e)};return c.prototype={constructor:c,init:function(e,i){var n=this;this.$element=t(e),void 0!==this.$element[0].id&&""!==this.$element[0].id?this.id=this.$element[0].id:(this.id=r+Math.floor(1e7*Math.random()+1),this.$element.attr("id",this.id)),this.classes=void 0!==this.$element.attr("class")?this.$element.attr("class"):"",this.content=this.$element.html(),this.state=l.CLOSED,this.options=i,this.width=0,this.timer=null,this.timerTimeout=null,this.progressBar=null,this.isPaused=!1,this.isFullscreen=!1,this.headerHeight=0,this.modalHeight=0,this.$overlay=t('<div class="'+r+'-overlay" style="background-color:'+i.overlayColor+'"></div>'),this.$navigate=t('<div class="'+r+'-navigate"><div class="'+r+'-navigate-caption">Use</div><button class="'+r+'-navigate-prev"></button><button class="'+r+'-navigate-next"></button></div>'),this.group={name:this.$element.attr("data-"+r+"-group"),index:null,ids:[]},this.$element.attr("aria-hidden","true"),this.$element.attr("aria-labelledby",this.id),this.$element.attr("role","dialog"),this.$element.hasClass("iziModal")||this.$element.addClass("iziModal"),void 0===this.group.name&&""!==i.group&&(this.group.name=i.group,this.$element.attr("data-"+r+"-group",i.group)),this.options.loop===!0&&this.$element.attr("data-"+r+"-loop",!0),t.each(this.options,function(t,e){var o=n.$element.attr("data-"+r+"-"+t);try{"undefined"!=typeof o&&(""===o||"true"==o?i[t]=!0:"false"==o?i[t]=!1:"function"==typeof e?i[t]=new Function(o):i[t]=o)}catch(s){}}),i.appendTo!==!1&&this.$element.appendTo(i.appendTo),i.iframe===!0?(this.$element.html('<div class="'+r+'-wrap"><div class="'+r+'-content"><iframe class="'+r+'-iframe"></iframe>'+this.content+"</div></div>"),null!==i.iframeHeight&&this.$element.find("."+r+"-iframe").css("height",i.iframeHeight)):this.$element.html('<div class="'+r+'-wrap"><div class="'+r+'-content">'+this.content+"</div></div>"),null!==this.options.background&&this.$element.css("background",this.options.background),this.$wrap=this.$element.find("."+r+"-wrap"),null===i.zindex||isNaN(parseInt(i.zindex))||(this.$element.css("z-index",i.zindex),this.$navigate.css("z-index",i.zindex-1),this.$overlay.css("z-index",i.zindex-2)),""!==i.radius&&this.$element.css("border-radius",i.radius),""!==i.padding&&this.$element.find("."+r+"-content").css("padding",i.padding),""!==i.theme&&("light"===i.theme?this.$element.addClass(r+"-light"):this.$element.addClass(i.theme)),i.rtl===!0&&this.$element.addClass(r+"-rtl"),i.openFullscreen===!0&&(this.isFullscreen=!0,this.$element.addClass("isFullscreen")),this.createHeader(),this.recalcWidth(),this.recalcVerticalPos(),!n.options.afterRender||"function"!=typeof n.options.afterRender&&"object"!=typeof n.options.afterRender||n.options.afterRender(n)},createHeader:function(){this.$header=t('<div class="'+r+'-header"><h2 class="'+r+'-header-title">'+this.options.title+'</h2><p class="'+r+'-header-subtitle">'+this.options.subtitle+'</p><div class="'+r+'-header-buttons"></div></div>'),this.options.closeButton===!0&&this.$header.find("."+r+"-header-buttons").append('<a href="javascript:void(0)" class="'+r+"-button "+r+'-button-close" data-'+r+"-close></a>"),this.options.fullscreen===!0&&this.$header.find("."+r+"-header-buttons").append('<a href="javascript:void(0)" class="'+r+"-button "+r+'-button-fullscreen" data-'+r+"-fullscreen></a>"),this.options.timeoutProgressbar===!0&&this.$header.prepend('<div class="'+r+'-progressbar"><div style="background-color:'+this.options.timeoutProgressbarColor+'"></div></div>'),""===this.options.subtitle&&this.$header.addClass(r+"-noSubtitle"),""!==this.options.title&&(null!==this.options.headerColor&&(this.options.borderBottom===!0&&this.$element.css("border-bottom","3px solid "+this.options.headerColor),this.$header.css("background",this.options.headerColor)),null===this.options.icon&&null===this.options.iconText||(this.$header.prepend('<i class="'+r+'-header-icon"></i>'),null!==this.options.icon&&this.$header.find("."+r+"-header-icon").addClass(this.options.icon).css("color",this.options.iconColor),null!==this.options.iconText&&this.$header.find("."+r+"-header-icon").html(this.options.iconText)),this.$element.css("overflow","hidden").prepend(this.$header))},setGroup:function(e){var i=this,n=this.group.name||e;if(this.group.ids=[],void 0!==e&&e!==this.group.name&&(n=e,this.group.name=n,this.$element.attr("data-"+r+"-group",n)),void 0!==n&&""!==n){var o=0;t.each(t("."+r+"[data-"+r+"-group="+n+"]"),function(e,n){i.group.ids.push(t(this)[0].id),i.id==t(this)[0].id&&(i.group.index=o),o++})}},toggle:function(){this.state==l.OPENED&&this.close(),this.state==l.CLOSED&&this.open()},startProgress:function(t){var e=this;this.isPaused=!1,clearTimeout(this.timerTimeout),this.options.timeoutProgressbar===!0?(this.progressBar={hideEta:null,maxHideTime:null,currentTime:(new Date).getTime(),el:this.$element.find("."+r+"-progressbar > div"),updateProgress:function(){if(!e.isPaused){e.progressBar.currentTime=e.progressBar.currentTime+10;var t=(e.progressBar.hideEta-e.progressBar.currentTime)/e.progressBar.maxHideTime*100;e.progressBar.el.width(t+"%"),t<0&&e.close()}}},t>0&&(this.progressBar.maxHideTime=parseFloat(t),this.progressBar.hideEta=(new Date).getTime()+this.progressBar.maxHideTime,this.timerTimeout=setInterval(this.progressBar.updateProgress,10))):this.timerTimeout=setTimeout(function(){e.close()},e.options.timeout)},pauseProgress:function(){this.isPaused=!0},resumeProgress:function(){this.isPaused=!1},resetProgress:function(t){clearTimeout(this.timerTimeout),this.progressBar={},this.$element.find("."+r+"-progressbar > div").width("100%")},open:function(e){function i(){s.state=l.OPENED,s.$element.trigger(l.OPENED),!s.options.onOpened||"function"!=typeof s.options.onOpened&&"object"!=typeof s.options.onOpened||s.options.onOpened(s)}function n(){s.$element.off("click","[data-"+r+"-close]").on("click","[data-"+r+"-close]",function(e){e.preventDefault();var i=t(e.currentTarget).attr("data-"+r+"-transitionOut");void 0!==i?s.close({transition:i}):s.close()}),s.$element.off("click","[data-"+r+"-fullscreen]").on("click","[data-"+r+"-fullscreen]",function(t){t.preventDefault(),s.isFullscreen===!0?(s.isFullscreen=!1,s.$element.removeClass("isFullscreen")):(s.isFullscreen=!0,s.$element.addClass("isFullscreen")),s.options.onFullscreen&&"function"==typeof s.options.onFullscreen&&s.options.onFullscreen(s),s.$element.trigger("fullscreen",s)}),s.$navigate.off("click","."+r+"-navigate-next").on("click","."+r+"-navigate-next",function(t){s.next(t)}),s.$element.off("click","[data-"+r+"-next]").on("click","[data-"+r+"-next]",function(t){s.next(t)}),s.$navigate.off("click","."+r+"-navigate-prev").on("click","."+r+"-navigate-prev",function(t){s.prev(t)}),s.$element.off("click","[data-"+r+"-prev]").on("click","[data-"+r+"-prev]",function(t){s.prev(t)})}var s=this;try{void 0!==e&&e.preventClose===!1&&t.each(t("."+r),function(e,i){if(void 0!==t(i).data().iziModal){var n=t(i).iziModal("getState");"opened"!=n&&"opening"!=n||t(i).iziModal("close")}})}catch(c){}if(function(){if(s.options.history){var t=document.title;document.title=t+" - "+s.options.title,o("#"+s.id),document.title=t,window.$iziModal.history=!0}else window.$iziModal.history=!1}(),this.state==l.CLOSED){if(n(),this.setGroup(),this.state=l.OPENING,this.$element.trigger(l.OPENING),this.$element.attr("aria-hidden","false"),this.options.timeoutProgressbar===!0&&this.$element.find("."+r+"-progressbar > div").width("100%"),this.options.iframe===!0){this.$element.find("."+r+"-content").addClass(r+"-content-loader"),this.$element.find("."+r+"-iframe").on("load",function(){t(this).parent().removeClass(r+"-content-loader")});var u=null;try{u=""!==t(e.currentTarget).attr("href")?t(e.currentTarget).attr("href"):null}catch(c){}if(null===this.options.iframeURL||null!==u&&void 0!==u||(u=this.options.iframeURL),null===u||void 0===u)throw new Error("Failed to find iframe URL");this.$element.find("."+r+"-iframe").attr("src",u)}(this.options.bodyOverflow||h)&&(t("html").addClass(r+"-isOverflow"),h&&t("body").css("overflow","hidden")),this.options.onOpening&&"function"==typeof this.options.onOpening&&this.options.onOpening(this),function(){if(s.group.ids.length>1){s.$navigate.appendTo("body"),s.$navigate.addClass("fadeIn"),s.options.navigateCaption===!0&&s.$navigate.find("."+r+"-navigate-caption").show();var n=s.$element.outerWidth();s.options.navigateArrows!==!1?"closeScreenEdge"===s.options.navigateArrows?(s.$navigate.find("."+r+"-navigate-prev").css("left",0).show(),s.$navigate.find("."+r+"-navigate-next").css("right",0).show()):(s.$navigate.find("."+r+"-navigate-prev").css("margin-left",-(n/2+84)).show(),s.$navigate.find("."+r+"-navigate-next").css("margin-right",-(n/2+84)).show()):(s.$navigate.find("."+r+"-navigate-prev").hide(),s.$navigate.find("."+r+"-navigate-next").hide());var o;0===s.group.index&&(o=t("."+r+"[data-"+r+'-group="'+s.group.name+'"][data-'+r+"-loop]").length,0===o&&s.options.loop===!1&&s.$navigate.find("."+r+"-navigate-prev").hide()),s.group.index+1===s.group.ids.length&&(o=t("."+r+"[data-"+r+'-group="'+s.group.name+'"][data-'+r+"-loop]").length,0===o&&s.options.loop===!1&&s.$navigate.find("."+r+"-navigate-next").hide())}s.options.overlay===!0&&(s.options.appendToOverlay===!1?s.$overlay.appendTo("body"):s.$overlay.appendTo(s.options.appendToOverlay)),s.options.transitionInOverlay&&s.$overlay.addClass(s.options.transitionInOverlay);var a=s.options.transitionIn;"object"==typeof e&&(void 0===e.transition&&void 0===e.transitionIn||(a=e.transition||e.transitionIn),void 0!==e.zindex&&s.setZindex(e.zindex)),""!==a&&void 0!==d?(s.$element.addClass("transitionIn "+a).show(),s.$wrap.one(d,function(){s.$element.removeClass(a+" transitionIn"),s.$overlay.removeClass(s.options.transitionInOverlay),s.$navigate.removeClass("fadeIn"),i()})):(s.$element.show(),i()),s.options.pauseOnHover!==!0||s.options.pauseOnHover!==!0||s.options.timeout===!1||isNaN(parseInt(s.options.timeout))||s.options.timeout===!1||0===s.options.timeout||(s.$element.off("mouseenter").on("mouseenter",function(t){t.preventDefault(),s.isPaused=!0}),s.$element.off("mouseleave").on("mouseleave",function(t){t.preventDefault(),s.isPaused=!1}))}(),this.options.timeout===!1||isNaN(parseInt(this.options.timeout))||this.options.timeout===!1||0===this.options.timeout||s.startProgress(this.options.timeout),this.options.overlayClose&&!this.$element.hasClass(this.options.transitionOut)&&this.$overlay.click(function(){s.close()}),this.options.focusInput&&this.$element.find(":input:not(button):enabled:visible:first").focus(),function p(){s.recalcLayout(),s.timer=setTimeout(p,300)}(),a.on("keydown."+r,function(t){s.options.closeOnEscape&&27===t.keyCode&&s.close()})}},close:function(e){function i(){n.state=l.CLOSED,n.$element.trigger(l.CLOSED),n.options.iframe===!0&&n.$element.find("."+r+"-iframe").attr("src",""),(n.options.bodyOverflow||h)&&(t("html").removeClass(r+"-isOverflow"),h&&t("body").css("overflow","auto")),n.options.onClosed&&"function"==typeof n.options.onClosed&&n.options.onClosed(n),n.options.restoreDefaultContent===!0&&n.$element.find("."+r+"-content").html(n.content),0===t("."+r+":visible").length&&t("html").removeClass(r+"-isAttached")}var n=this;if(this.state==l.OPENED||this.state==l.OPENING){a.off("keydown."+r),this.state=l.CLOSING,this.$element.trigger(l.CLOSING),this.$element.attr("aria-hidden","true"),clearTimeout(this.timer),clearTimeout(this.timerTimeout),n.options.onClosing&&"function"==typeof n.options.onClosing&&n.options.onClosing(this);var o=this.options.transitionOut;"object"==typeof e&&(void 0===e.transition&&void 0===e.transitionOut||(o=e.transition||e.transitionOut)),o===!1||""===o||void 0===d?(this.$element.hide(),this.$overlay.remove(),this.$navigate.remove(),i()):(this.$element.attr("class",[this.classes,r,o,"light"==this.options.theme?r+"-light":this.options.theme,this.isFullscreen===!0?"isFullscreen":"",this.options.rtl?r+"-rtl":""].join(" ")),this.$overlay.attr("class",r+"-overlay "+this.options.transitionOutOverlay),n.options.navigateArrows===!1||h||this.$navigate.attr("class",r+"-navigate fadeOut"),this.$element.one(d,function(){n.$element.hasClass(o)&&n.$element.removeClass(o+" transitionOut").hide(),n.$overlay.removeClass(n.options.transitionOutOverlay).remove(),n.$navigate.removeClass("fadeOut").remove(),i()}))}},next:function(e){var i=this,n="fadeInRight",o="fadeOutLeft",s=t("."+r+":visible"),a={};a.out=this,void 0!==e&&"object"!=typeof e?(e.preventDefault(),s=t(e.currentTarget),n=s.attr("data-"+r+"-transitionIn"),o=s.attr("data-"+r+"-transitionOut")):void 0!==e&&(void 0!==e.transitionIn&&(n=e.transitionIn),void 0!==e.transitionOut&&(o=e.transitionOut)),this.close({transition:o}),setTimeout(function(){for(var e=t("."+r+"[data-"+r+'-group="'+i.group.name+'"][data-'+r+"-loop]").length,o=i.group.index+1;o<=i.group.ids.length;o++){try{a["in"]=t("#"+i.group.ids[o]).data().iziModal}catch(s){}if("undefined"!=typeof a["in"]){t("#"+i.group.ids[o]).iziModal("open",{transition:n});break}if(o==i.group.ids.length&&e>0||i.options.loop===!0)for(var l=0;l<=i.group.ids.length;l++)if(a["in"]=t("#"+i.group.ids[l]).data().iziModal,"undefined"!=typeof a["in"]){t("#"+i.group.ids[l]).iziModal("open",{transition:n});break}}},200),t(document).trigger(r+"-group-change",a)},prev:function(e){var i=this,n="fadeInLeft",o="fadeOutRight",s=t("."+r+":visible"),a={};a.out=this,void 0!==e&&"object"!=typeof e?(e.preventDefault(),s=t(e.currentTarget),n=s.attr("data-"+r+"-transitionIn"),o=s.attr("data-"+r+"-transitionOut")):void 0!==e&&(void 0!==e.transitionIn&&(n=e.transitionIn),void 0!==e.transitionOut&&(o=e.transitionOut)),this.close({transition:o}),setTimeout(function(){for(var e=t("."+r+"[data-"+r+'-group="'+i.group.name+'"][data-'+r+"-loop]").length,o=i.group.index;o>=0;o--){try{a["in"]=t("#"+i.group.ids[o-1]).data().iziModal}catch(s){}if("undefined"!=typeof a["in"]){t("#"+i.group.ids[o-1]).iziModal("open",{transition:n});break}if(0===o&&e>0||i.options.loop===!0)for(var l=i.group.ids.length-1;l>=0;l--)if(a["in"]=t("#"+i.group.ids[l]).data().iziModal,"undefined"!=typeof a["in"]){t("#"+i.group.ids[l]).iziModal("open",{transition:n});break}}},200),t(document).trigger(r+"-group-change",a)},destroy:function(){var e=t.Event("destroy");this.$element.trigger(e),a.off("keydown."+r),clearTimeout(this.timer),clearTimeout(this.timerTimeout),this.options.iframe===!0&&this.$element.find("."+r+"-iframe").remove(),this.$element.html(this.$element.find("."+r+"-content").html()),this.$element.off("click","[data-"+r+"-close]"),this.$element.off("click","[data-"+r+"-fullscreen]"),this.$element.off("."+r).removeData(r).attr("style",""),this.$overlay.remove(),this.$navigate.remove(),this.$element.trigger(l.DESTROYED),this.$element=null},getState:function(){return this.state},getGroup:function(){return this.group},setWidth:function(t){this.options.width=t,this.recalcWidth();var e=this.$element.outerWidth();this.options.navigateArrows!==!0&&"closeToModal"!=this.options.navigateArrows||(this.$navigate.find("."+r+"-navigate-prev").css("margin-left",-(e/2+84)).show(),this.$navigate.find("."+r+"-navigate-next").css("margin-right",-(e/2+84)).show())},setTop:function(t){this.options.top=t,this.recalcVerticalPos(!1)},setBottom:function(t){this.options.bottom=t,this.recalcVerticalPos(!1)},setHeader:function(t){t?this.$element.find("."+r+"-header").show():(this.headerHeight=0,this.$element.find("."+r+"-header").hide())},setTitle:function(t){this.options.title=t,0===this.headerHeight&&this.createHeader(),0===this.$header.find("."+r+"-header-title").length&&this.$header.append('<h2 class="'+r+'-header-title"></h2>'),this.$header.find("."+r+"-header-title").html(t)},setSubtitle:function(t){""===t?(this.$header.find("."+r+"-header-subtitle").remove(),this.$header.addClass(r+"-noSubtitle")):(0===this.$header.find("."+r+"-header-subtitle").length&&this.$header.append('<p class="'+r+'-header-subtitle"></p>'),this.$header.removeClass(r+"-noSubtitle")),this.$header.find("."+r+"-header-subtitle").html(t),this.options.subtitle=t},setIcon:function(t){0===this.$header.find("."+r+"-header-icon").length&&this.$header.prepend('<i class="'+r+'-header-icon"></i>'),this.$header.find("."+r+"-header-icon").attr("class",r+"-header-icon "+t),this.options.icon=t},setIconText:function(t){this.$header.find("."+r+"-header-icon").html(t),this.options.iconText=t},setHeaderColor:function(t){this.options.borderBottom===!0&&this.$element.css("border-bottom","3px solid "+t),this.$header.css("background",t),this.options.headerColor=t},setBackground:function(t){t===!1?(this.options.background=null,this.$element.css("background","")):(this.$element.css("background",t),this.options.background=t)},setZindex:function(t){isNaN(parseInt(this.options.zindex))||(this.options.zindex=t,this.$element.css("z-index",t),this.$navigate.css("z-index",t-1),this.$overlay.css("z-index",t-2))},setFullscreen:function(t){t?(this.isFullscreen=!0,this.$element.addClass("isFullscreen")):(this.isFullscreen=!1,this.$element.removeClass("isFullscreen"))},setContent:function(t){if("object"==typeof t){var e=t["default"]||!1;e===!0&&(this.content=t.content),t=t.content}this.options.iframe===!1&&this.$element.find("."+r+"-content").html(t)},setTransitionIn:function(t){this.options.transitionIn=t},setTransitionOut:function(t){this.options.transitionOut=t},setTimeout:function(t){this.options.timeout=t},resetContent:function(){this.$element.find("."+r+"-content").html(this.content)},startLoading:function(){this.$element.find("."+r+"-loader").length||this.$element.append('<div class="'+r+'-loader fadeIn"></div>'),this.$element.find("."+r+"-loader").css({top:this.headerHeight,borderRadius:this.options.radius})},stopLoading:function(){var t=this.$element.find("."+r+"-loader");t.length||(this.$element.prepend('<div class="'+r+'-loader fadeIn"></div>'),t=this.$element.find("."+r+"-loader").css("border-radius",this.options.radius)),t.removeClass("fadeIn").addClass("fadeOut"),setTimeout(function(){t.remove()},600)},recalcWidth:function(){var t=this;if(this.$element.css("max-width",this.options.width),i()){var e=t.options.width;e.toString().split("%").length>1&&(e=t.$element.outerWidth()),t.$element.css({left:"50%",marginLeft:-(e/2)})}},recalcVerticalPos:function(t){null!==this.options.top&&this.options.top!==!1?(this.$element.css("margin-top",this.options.top),0===this.options.top&&this.$element.css({borderTopRightRadius:0,borderTopLeftRadius:0})):t===!1&&this.$element.css({marginTop:"",borderRadius:this.options.radius}),null!==this.options.bottom&&this.options.bottom!==!1?(this.$element.css("margin-bottom",this.options.bottom),0===this.options.bottom&&this.$element.css({borderBottomRightRadius:0,borderBottomLeftRadius:0})):t===!1&&this.$element.css({marginBottom:"",borderRadius:this.options.radius})},recalcLayout:function(){var e=this,o=s.height(),a=this.$element.outerHeight(),d=this.$element.outerWidth(),h=this.$element.find("."+r+"-content")[0].scrollHeight,c=h+this.headerHeight,u=this.$element.innerHeight()-this.headerHeight,p=(parseInt(-((this.$element.innerHeight()+1)/2))+"px",this.$wrap.scrollTop()),f=0;i()&&(d>=s.width()||this.isFullscreen===!0?this.$element.css({left:"0",marginLeft:""}):this.$element.css({left:"50%",marginLeft:-(d/2)})),this.options.borderBottom===!0&&""!==this.options.title&&(f=3),this.$element.find("."+r+"-header").length&&this.$element.find("."+r+"-header").is(":visible")?(this.headerHeight=parseInt(this.$element.find("."+r+"-header").innerHeight()),this.$element.css("overflow","hidden")):(this.headerHeight=0,this.$element.css("overflow","")),this.$element.find("."+r+"-loader").length&&this.$element.find("."+r+"-loader").css("top",this.headerHeight),a!==this.modalHeight&&(this.modalHeight=a,this.options.onResize&&"function"==typeof this.options.onResize&&this.options.onResize(this)),this.state!=l.OPENED&&this.state!=l.OPENING||(this.options.iframe===!0&&(o<this.options.iframeHeight+this.headerHeight+f||this.isFullscreen===!0?this.$element.find("."+r+"-iframe").css("height",o-(this.headerHeight+f)):this.$element.find("."+r+"-iframe").css("height",this.options.iframeHeight)),a==o?this.$element.addClass("isAttached"):this.$element.removeClass("isAttached"),this.isFullscreen===!1&&this.$element.width()>=s.width()?this.$element.find("."+r+"-button-fullscreen").hide():this.$element.find("."+r+"-button-fullscreen").show(),this.recalcButtons(),this.isFullscreen===!1&&(o=o-(n(this.options.top)||0)-(n(this.options.bottom)||0)),c>o?(this.options.top>0&&null===this.options.bottom&&h<s.height()&&this.$element.addClass("isAttachedBottom"),this.options.bottom>0&&null===this.options.top&&h<s.height()&&this.$element.addClass("isAttachedTop"),1===t("."+r+":visible").length&&t("html").addClass(r+"-isAttached"),this.$element.css("height",o)):(this.$element.css("height",h+(this.headerHeight+f)),this.$element.removeClass("isAttachedTop isAttachedBottom"),1===t("."+r+":visible").length&&t("html").removeClass(r+"-isAttached")),function(){h>u&&c>o?(e.$element.addClass("hasScroll"),e.$wrap.css("height",a-(e.headerHeight+f))):(e.$element.removeClass("hasScroll"),e.$wrap.css("height","auto"))}(),function(){u+p<h-30?e.$element.addClass("hasShadow"):e.$element.removeClass("hasShadow")}())},recalcButtons:function(){var t=this.$header.find("."+r+"-header-buttons").innerWidth()+10;this.options.rtl===!0?this.$header.css("padding-left",t):this.$header.css("padding-right",t)}},s.off("load."+r).on("load."+r,function(e){var i=document.location.hash;if(0===window.$iziModal.autoOpen&&!t("."+r).is(":visible"))try{var n=t(i).data();"undefined"!=typeof n&&n.iziModal.options.autoOpen!==!1&&t(i).iziModal("open")}catch(o){}}),s.off("hashchange."+r).on("hashchange."+r,function(e){var i=document.location.hash;if(""!==i)try{var n=t(i).data();"undefined"!=typeof n&&"opening"!==t(i).iziModal("getState")&&setTimeout(function(){t(i).iziModal("open",{preventClose:!1})},200)}catch(o){}else window.$iziModal.history&&t.each(t("."+r),function(e,i){if(void 0!==t(i).data().iziModal){var n=t(i).iziModal("getState");"opened"!=n&&"opening"!=n||t(i).iziModal("close")}})}),a.off("click","[data-"+r+"-open]").on("click","[data-"+r+"-open]",function(e){e.preventDefault();var i=t("."+r+":visible"),n=t(e.currentTarget).attr("data-"+r+"-open"),o=t(e.currentTarget).attr("data-"+r+"-preventClose"),s=t(e.currentTarget).attr("data-"+r+"-transitionIn"),a=t(e.currentTarget).attr("data-"+r+"-transitionOut"),l=t(e.currentTarget).attr("data-"+r+"-zindex");void 0!==l&&t(n).iziModal("setZindex",l),void 0===o&&(void 0!==a?i.iziModal("close",{transition:a}):i.iziModal("close")),setTimeout(function(){void 0!==s?t(n).iziModal("open",{transition:s}):t(n).iziModal("open")},200)}),a.off("keyup."+r).on("keyup."+r,function(e){if(t("."+r+":visible").length){var i=t("."+r+":visible")[0].id,n=t("#"+i).data().iziModal.options.arrowKeys,o=t("#"+i).iziModal("getGroup"),s=e||window.event,a=s.target||s.srcElement;void 0===i||!n||void 0===o.name||s.ctrlKey||s.metaKey||s.altKey||"INPUT"===a.tagName.toUpperCase()||"TEXTAREA"==a.tagName.toUpperCase()||(37===s.keyCode?t("#"+i).iziModal("prev",s):39===s.keyCode&&t("#"+i).iziModal("next",s))}}),t.fn[r]=function(e,i){if(!t(this).length&&"object"==typeof e){var n={$el:document.createElement("div"),id:this.selector.split("#"),"class":this.selector.split(".")};if(n.id.length>1){try{n.$el=document.createElement(id[0])}catch(o){}n.$el.id=this.selector.split("#")[1].trim()}else if(n["class"].length>1){try{n.$el=document.createElement(n["class"][0])}catch(o){}for(var s=1;s<n["class"].length;s++)n.$el.classList.add(n["class"][s].trim())}document.body.appendChild(n.$el),this.push(t(this.selector))}for(var a=this,l=0;l<a.length;l++){var d=t(a[l]),h=d.data(r),u=t.extend({},t.fn[r].defaults,d.data(),"object"==typeof e&&e);if(h||e&&"object"!=typeof e){if("string"==typeof e&&"undefined"!=typeof h)return h[e].apply(h,[].concat(i))}else d.data(r,h=new c(d,u));u.autoOpen&&(isNaN(parseInt(u.autoOpen))?u.autoOpen===!0&&h.open():setTimeout(function(){h.open()},u.autoOpen),window.$iziModal.autoOpen++)}return this},t.fn[r].defaults={title:"",subtitle:"",headerColor:"#88A0B9",background:null,theme:"",icon:null,iconText:null,iconColor:"",rtl:!1,width:600,top:null,bottom:null,borderBottom:!0,padding:0,radius:3,zindex:999,iframe:!1,iframeHeight:400,iframeURL:null,focusInput:!0,group:"",loop:!1,arrowKeys:!0,navigateCaption:!0,navigateArrows:!0,history:!1,restoreDefaultContent:!1,autoOpen:0,bodyOverflow:!1,fullscreen:!1,openFullscreen:!1,closeOnEscape:!0,closeButton:!0,appendTo:"body",appendToOverlay:"body",overlay:!0,overlayClose:!0,overlayColor:"rgba(0, 0, 0, 0.4)",timeout:!1,timeoutProgressbar:!1,pauseOnHover:!1,timeoutProgressbarColor:"rgba(255,255,255,0.5)",transitionIn:"comingIn",transitionOut:"comingOut",transitionInOverlay:"fadeIn",transitionOutOverlay:"fadeOut",onFullscreen:function(){},onResize:function(){},onOpening:function(){},onOpened:function(){},onClosing:function(){},onClosed:function(){},afterRender:function(){}},t.fn[r].Constructor=c,t.fn.iziModal});
languages/litespeed-cache.pot CHANGED
@@ -2,9 +2,9 @@
2
  # This file is distributed under the same license as the LiteSpeed Cache package.
3
  msgid ""
4
  msgstr ""
5
- "Project-Id-Version: LiteSpeed Cache 1.9.1\n"
6
  "Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/litespeed-cache\n"
7
- "POT-Creation-Date: 2018-02-20 14:41:46+00:00\n"
8
  "MIME-Version: 1.0\n"
9
  "Content-Type: text/plain; charset=UTF-8\n"
10
  "Content-Transfer-Encoding: 8bit\n"
@@ -28,52 +28,52 @@ msgstr ""
28
  msgid "Message from LiteSpeed image server"
29
  msgstr ""
30
 
31
- #: admin/litespeed-cache-admin-display.class.php:143
32
- #: admin/tpl/setting/settings_cdn.php:181
33
- #: admin/tpl/setting/settings_cdn.php:224 inc/gui.class.php:271
34
- #: includes/litespeed-cache-gui.class.php:271
35
  msgid "Manage"
36
  msgstr ""
37
 
38
- #: admin/litespeed-cache-admin-display.class.php:145
39
- #: admin/litespeed-cache-admin-display.class.php:234 inc/gui.class.php:279
40
- #: includes/litespeed-cache-gui.class.php:279
41
  msgid "Settings"
42
  msgstr ""
43
 
44
- #: admin/litespeed-cache-admin-display.class.php:148
45
  msgid "Edit .htaccess"
46
  msgstr ""
47
 
48
- #: admin/litespeed-cache-admin-display.class.php:152 inc/gui.class.php:288
49
- #: includes/litespeed-cache-gui.class.php:288
50
  msgid "Image Optimization"
51
  msgstr ""
52
 
53
- #: admin/litespeed-cache-admin-display.class.php:153 admin/tpl/settings.php:24
54
  msgid "Crawler"
55
  msgstr ""
56
 
57
- #: admin/litespeed-cache-admin-display.class.php:154
58
  msgid "Report"
59
  msgstr ""
60
 
61
- #: admin/litespeed-cache-admin-display.class.php:155
62
  msgid "Import / Export"
63
  msgstr ""
64
 
65
- #: admin/litespeed-cache-admin-display.class.php:158
66
  #: admin/tpl/setting/settings_debug.php:13
67
  msgid "Debug Log"
68
  msgstr ""
69
 
70
- #: admin/litespeed-cache-admin-display.class.php:254
71
  msgid ""
72
  "It is recommended that LiteSpeed Cache be purged after updating a plugin."
73
  msgstr ""
74
 
75
- #: admin/litespeed-cache-admin-display.class.php:796
76
- #: admin/litespeed-cache-admin-display.class.php:881
77
  #: admin/tpl/setting/settings_inc.cache_mobile.php:67
78
  #: admin/tpl/setting/settings_media.php:73
79
  #: admin/tpl/setting/settings_optimize.php:160
@@ -82,28 +82,35 @@ msgstr ""
82
  msgid "ON"
83
  msgstr ""
84
 
85
- #: admin/litespeed-cache-admin-display.class.php:797
86
- #: admin/litespeed-cache-admin-display.class.php:885
87
  #: admin/tpl/setting/settings_inc.cache_object.php:149
88
  #: admin/tpl/setting/settings_tuning.php:18
89
  #: admin/tpl/setting/settings_tuning.php:54
90
  msgid "OFF"
91
  msgstr ""
92
 
93
- #: admin/litespeed-cache-admin-display.class.php:911
94
  msgid "Recommended value: %s"
95
  msgstr ""
96
 
97
- #: admin/litespeed-cache-admin-display.class.php:927
 
 
 
 
 
 
 
98
  msgid "API"
99
  msgstr ""
100
 
101
- #: admin/litespeed-cache-admin-display.class.php:928
102
  msgid "Server variable(s) %s available to override this setting."
103
  msgstr ""
104
 
105
- #: admin/litespeed-cache-admin-display.class.php:930
106
- #: admin/tpl/image_optimization.php:113 admin/tpl/image_optimization.php:152
107
  #: admin/tpl/manage/manage_cdn.php:60
108
  #: admin/tpl/setting/settings_advanced.php:10
109
  #: admin/tpl/setting/settings_advanced.php:36
@@ -126,6 +133,22 @@ msgstr ""
126
  msgid "Learn More"
127
  msgstr ""
128
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
129
  #: admin/litespeed-cache-admin-error.class.php:87
130
  msgid "The installed PHP version is too old for the LiteSpeed Cache Plugin."
131
  msgstr ""
@@ -409,7 +432,7 @@ msgid "Site options saved."
409
  msgstr ""
410
 
411
  #: admin/litespeed-cache-admin-settings.class.php:342
412
- #: admin/litespeed-cache-admin-settings.class.php:987
413
  msgid "Default Public Cache"
414
  msgstr ""
415
 
@@ -425,65 +448,53 @@ msgstr ""
425
  msgid "Feed"
426
  msgstr ""
427
 
428
- #: admin/litespeed-cache-admin-settings.class.php:346
429
- msgid "404"
430
- msgstr ""
431
-
432
- #: admin/litespeed-cache-admin-settings.class.php:347
433
- msgid "403"
434
- msgstr ""
435
-
436
- #: admin/litespeed-cache-admin-settings.class.php:348
437
- msgid "500"
438
- msgstr ""
439
-
440
  #: admin/litespeed-cache-admin-settings.class.php:844
441
  #: admin/tpl/setting/settings_debug.php:78
442
  msgid "Log File Size Limit"
443
  msgstr ""
444
 
445
- #: admin/litespeed-cache-admin-settings.class.php:910
446
  #: admin/tpl/setting/settings_crawler.php:13
447
  msgid "Delay"
448
  msgstr ""
449
 
450
- #: admin/litespeed-cache-admin-settings.class.php:911
451
  #: admin/tpl/setting/settings_crawler.php:37
452
  msgid "Run Duration"
453
  msgstr ""
454
 
455
- #: admin/litespeed-cache-admin-settings.class.php:912
456
  msgid "Cron Interval"
457
  msgstr ""
458
 
459
- #: admin/litespeed-cache-admin-settings.class.php:913
460
  msgid "Whole Interval"
461
  msgstr ""
462
 
463
- #: admin/litespeed-cache-admin-settings.class.php:914
464
  #: admin/tpl/setting/settings_crawler.php:73
465
  msgid "Threads"
466
  msgstr ""
467
 
468
- #: admin/litespeed-cache-admin.class.php:210
469
  msgid ""
470
  "For this scenario only, the network admin may uncheck \"Check Advanced Cache"
471
  "\" in LiteSpeed Cache settings."
472
  msgstr ""
473
 
474
- #: admin/litespeed-cache-admin.class.php:212
475
  msgid ""
476
  "For this scenario only, please uncheck \"Check Advanced Cache\" in LiteSpeed "
477
  "Cache settings."
478
  msgstr ""
479
 
480
- #: admin/litespeed-cache-admin.class.php:214
481
  msgid ""
482
  "Please disable/deactivate any other Full Page Cache solutions that are "
483
  "currently being used."
484
  msgstr ""
485
 
486
- #: admin/litespeed-cache-admin.class.php:215
487
  msgid ""
488
  "LiteSpeed Cache does work with other cache solutions, but only their non-"
489
  "page caching offerings—such as minifying css/js files."
@@ -540,7 +551,7 @@ msgid "Disable"
540
  msgstr ""
541
 
542
  #: admin/tpl/crawler.php:94 admin/tpl/manage/manage_cdn.php:15
543
- #: admin/tpl/setting/settings_optimize.php:13 admin/tpl/settings.php:162
544
  msgid "WARNING"
545
  msgstr ""
546
 
@@ -751,199 +762,228 @@ msgstr ""
751
  msgid "A TTL of 0 indicates do not cache."
752
  msgstr ""
753
 
754
- #: admin/tpl/image_optimization.php:13
755
  msgid "Level"
756
  msgstr ""
757
 
758
- #: admin/tpl/image_optimization.php:17
759
  msgid "Credit"
760
  msgstr ""
761
 
762
- #: admin/tpl/image_optimization.php:18
763
  msgid "Credit recovers with each successful pull."
764
  msgstr ""
765
 
766
- #: admin/tpl/image_optimization.php:22
767
  msgid "Total Reduction"
768
  msgstr ""
769
 
770
- #: admin/tpl/image_optimization.php:26
771
  msgid "Images pulled"
772
  msgstr ""
773
 
774
- #: admin/tpl/image_optimization.php:29
775
  msgid "Images failed to fetch"
776
  msgstr ""
777
 
778
- #: admin/tpl/image_optimization.php:32
779
  msgid "Images failed to notify"
780
  msgstr ""
781
 
782
- #: admin/tpl/image_optimization.php:35
783
  msgid "Images failed to pull"
784
  msgstr ""
785
 
786
- #: admin/tpl/image_optimization.php:38
787
  msgid "Last Request"
788
  msgstr ""
789
 
790
- #: admin/tpl/image_optimization.php:49
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
791
  msgid "LiteSpeed Cache Image Optimization"
792
  msgstr ""
793
 
794
- #: admin/tpl/image_optimization.php:61
795
- msgid "Optimization Summary"
796
  msgstr ""
797
 
798
- #: admin/tpl/image_optimization.php:91 admin/tpl/image_optimization.php:111
799
- msgid "Update Reduction Status"
800
  msgstr ""
801
 
802
- #: admin/tpl/image_optimization.php:94
803
  msgid ""
804
  "This will communicate with LiteSpeed's Image Optimization Server and "
805
  "retrieve the most recent status."
806
  msgstr ""
807
 
808
- #: admin/tpl/image_optimization.php:99
809
  msgid "Image Information"
810
  msgstr ""
811
 
812
- #: admin/tpl/image_optimization.php:100
813
  msgid "Beta Version"
814
  msgstr ""
815
 
816
- #: admin/tpl/image_optimization.php:103
817
- msgid "<a %s>Image groups</a> total"
818
  msgstr ""
819
 
820
- #: admin/tpl/image_optimization.php:104
821
- msgid "Image groups not yet requested"
822
  msgstr ""
823
 
824
- #: admin/tpl/image_optimization.php:108 admin/tpl/image_optimization.php:116
825
- msgid "Send Optimization Request"
826
  msgstr ""
827
 
828
- #: admin/tpl/image_optimization.php:111
829
  msgid "Please press the %s button before sending a new request."
830
  msgstr ""
831
 
832
- #: admin/tpl/image_optimization.php:119
833
  msgid ""
834
  "This will send the optimization request and the images to LiteSpeed's Image "
835
  "Optimization Server."
836
  msgstr ""
837
 
838
- #: admin/tpl/image_optimization.php:120
839
  msgid "You can send at most %s images at once."
840
  msgstr ""
841
 
842
- #: admin/tpl/image_optimization.php:128
843
- msgid "Image groups requested"
 
 
 
 
844
  msgstr ""
845
 
846
- #: admin/tpl/image_optimization.php:130
847
- msgid "Image groups failed to optimize"
848
  msgstr ""
849
 
850
- #: admin/tpl/image_optimization.php:132
851
  msgid ""
852
  "After LiteSpeed's Image Optimization Server finishes optimization, it will "
853
  "notify your site to pull the optimized images."
854
  msgstr ""
855
 
856
- #: admin/tpl/image_optimization.php:133
857
  msgid "This process is automatic."
858
  msgstr ""
859
 
860
- #: admin/tpl/image_optimization.php:136
861
- msgid "Image groups notified to pull"
862
  msgstr ""
863
 
864
- #: admin/tpl/image_optimization.php:139
865
- msgid "Pull Images"
866
- msgstr ""
867
-
868
- #: admin/tpl/image_optimization.php:142
869
  msgid "Only press the button if the pull cron job is disabled."
870
  msgstr ""
871
 
872
- #: admin/tpl/image_optimization.php:143
873
  msgid "Images will be pulled automatically if the cron job is running."
874
  msgstr ""
875
 
876
- #: admin/tpl/image_optimization.php:147
877
  msgid "Last pull initiated by cron at %s."
878
  msgstr ""
879
 
880
- #: admin/tpl/image_optimization.php:151
881
- msgid "Image groups optimized and pulled"
882
  msgstr ""
883
 
884
- #: admin/tpl/image_optimization.php:157
885
  msgid "Revert Optimization"
886
  msgstr ""
887
 
888
- #: admin/tpl/image_optimization.php:160
889
  msgid ""
890
  "Switch all images in the media library back to their original unoptimized "
891
  "versions."
892
  msgstr ""
893
 
894
- #: admin/tpl/image_optimization.php:166
895
  msgid "Undo Optimization"
896
  msgstr ""
897
 
898
- #: admin/tpl/image_optimization.php:169
899
  msgid "Revert all optimized images back to their original versions."
900
  msgstr ""
901
 
902
- #: admin/tpl/image_optimization.php:175
903
  msgid "Re-do Optimization"
904
  msgstr ""
905
 
906
- #: admin/tpl/image_optimization.php:178
907
  msgid "Switch back to using optimized images."
908
  msgstr ""
909
 
910
- #: admin/tpl/image_optimization.php:183
911
  msgid "Results can be checked in <a %s>Media Library</a>."
912
  msgstr ""
913
 
914
- #: admin/tpl/image_optimization.php:187
915
  msgid "Send New Thumbnail Requests"
916
  msgstr ""
917
 
918
- #: admin/tpl/image_optimization.php:190
919
  msgid ""
920
  "Scan for any new unoptimized image thumbnail sizes and resend necessary "
921
  "image optimization requests."
922
  msgstr ""
923
 
924
- #: admin/tpl/image_optimization.php:195
925
  msgid "Reset IAPI Key"
926
  msgstr ""
927
 
928
- #: admin/tpl/image_optimization.php:198
929
  msgid ""
930
  "The current IAPI key must be reset after changing home URL or domain before "
931
  "making any further optimization requests."
932
  msgstr ""
933
 
934
- #: admin/tpl/image_optimization.php:203
935
  msgid "Destroy All Optimization Data!"
936
  msgstr ""
937
 
938
- #: admin/tpl/image_optimization.php:206
939
  msgid ""
940
  "Remove all previous image optimization requests/results, revert completed "
941
  "optimizations, and delete all optimization files."
942
  msgstr ""
943
 
944
- #: admin/tpl/image_optimization.php:208
945
  #: admin/tpl/setting/settings_advanced.php:50
946
  #: admin/tpl/setting/settings_cdn.php:97
 
 
 
947
  #: admin/tpl/setting/settings_excludes.php:63
948
  #: admin/tpl/setting/settings_excludes.php:101
949
  #: admin/tpl/setting/settings_inc.cache_browser.php:12
@@ -957,16 +997,16 @@ msgstr ""
957
  #: admin/tpl/setting/settings_optimize.php:162
958
  #: admin/tpl/setting/settings_tuning.php:20
959
  #: admin/tpl/setting/settings_tuning.php:56
960
- msgid "NOTE:"
961
  msgstr ""
962
 
963
- #: admin/tpl/image_optimization.php:209
964
  msgid ""
965
  "If there are unfinished requests in progress, the requests' credits will NOT "
966
  "be recovered."
967
  msgstr ""
968
 
969
- #: admin/tpl/image_optimization.php:209
970
  #: admin/tpl/setting/settings_optimize.php:87
971
  #: admin/tpl/setting/settings_optimize.php:163
972
  msgid "JS Combine"
@@ -1011,16 +1051,26 @@ msgid ""
1011
  "Cache settings."
1012
  msgstr ""
1013
 
1014
- #: admin/tpl/inc/admin_footer.php:5
1015
- msgid ""
1016
- "Rate <strong>LiteSpeed Cache</strong> with %s on WordPress.org if you like "
1017
- "us!"
1018
  msgstr ""
1019
 
1020
- #: admin/tpl/inc/admin_footer.php:8
1021
- msgid ""
1022
- "If there are any questions that are not answered in the <a %s>FAQs</a>, do "
1023
- "not hesitate to ask them on the <a %s>support forum</a>."
 
 
 
 
 
 
 
 
 
 
 
 
1024
  msgstr ""
1025
 
1026
  #: admin/tpl/inc/api_key.php:11
@@ -1387,8 +1437,8 @@ msgstr ""
1387
  msgid "Are you sure you want to purge all?"
1388
  msgstr ""
1389
 
1390
- #: admin/tpl/manage/manage_purge.php:61 inc/gui.class.php:316
1391
- #: includes/litespeed-cache-gui.class.php:316
1392
  msgid "Object Cache Purge All"
1393
  msgstr ""
1394
 
@@ -1396,8 +1446,8 @@ msgstr ""
1396
  msgid "Purge all the object caches"
1397
  msgstr ""
1398
 
1399
- #: admin/tpl/manage/manage_purge.php:71 inc/gui.class.php:326
1400
- #: includes/litespeed-cache-gui.class.php:326
1401
  msgid "Opcode Cache Purge All"
1402
  msgstr ""
1403
 
@@ -1512,8 +1562,8 @@ msgstr ""
1512
  msgid "DB Optimizer"
1513
  msgstr ""
1514
 
1515
- #: admin/tpl/manage.php:12 admin/tpl/setting/settings_cdn.php:181
1516
- #: admin/tpl/setting/settings_cdn.php:224 admin/tpl/settings.php:14
1517
  msgid "CDN"
1518
  msgstr ""
1519
 
@@ -1824,8 +1874,7 @@ msgstr ""
1824
 
1825
  #: admin/tpl/setting/settings_cdn.php:98
1826
  msgid ""
1827
- "If multiple CDN paths are configured with the same settings, the last one "
1828
- "will override the others."
1829
  msgstr ""
1830
 
1831
  #: admin/tpl/setting/settings_cdn.php:103
@@ -1891,14 +1940,6 @@ msgstr ""
1891
  msgid "Off"
1892
  msgstr ""
1893
 
1894
- #: admin/tpl/setting/settings_cdn.php:160
1895
- msgid "Google"
1896
- msgstr ""
1897
-
1898
- #: admin/tpl/setting/settings_cdn.php:166
1899
- msgid "Cdnjs"
1900
- msgstr ""
1901
-
1902
  #: admin/tpl/setting/settings_cdn.php:170
1903
  msgid ""
1904
  "Improve page load time by loading jQuery from a remote CDN service instead "
@@ -1910,76 +1951,64 @@ msgid "Quic Cloud API"
1910
  msgstr ""
1911
 
1912
  #: admin/tpl/setting/settings_cdn.php:180
1913
- msgid "Use Quic Cloud API functionality."
 
1914
  msgstr ""
1915
 
1916
- #: admin/tpl/setting/settings_cdn.php:181
1917
- #: admin/tpl/setting/settings_cdn.php:224
1918
  msgid "This can be managed from <a %2$s>%1$s</a>."
1919
  msgstr ""
1920
 
1921
- #: admin/tpl/setting/settings_cdn.php:185
1922
- #: admin/tpl/setting/settings_cdn.php:228
1923
  msgid "Email Address"
1924
  msgstr ""
1925
 
1926
- #: admin/tpl/setting/settings_cdn.php:189
1927
- msgid "Your Email address on Quic Cloud."
 
1928
  msgstr ""
1929
 
1930
- #: admin/tpl/setting/settings_cdn.php:194
1931
  msgid "User API Key"
1932
  msgstr ""
1933
 
1934
- #: admin/tpl/setting/settings_cdn.php:198
1935
- msgid "Your API key is used to access Quic Cloud APIs."
 
1936
  msgstr ""
1937
 
1938
- #: admin/tpl/setting/settings_cdn.php:199
1939
- msgid "Get it from <a %s>Quic Cloud</a>."
 
1940
  msgstr ""
1941
 
1942
- #: admin/tpl/setting/settings_cdn.php:204
1943
  msgid "Site Domain"
1944
  msgstr ""
1945
 
1946
- #: admin/tpl/setting/settings_cdn.php:210
1947
- #: admin/tpl/setting/settings_cdn.php:255
1948
  msgid "You can just type part of the domain."
1949
  msgstr ""
1950
 
1951
- #: admin/tpl/setting/settings_cdn.php:211
1952
- #: admin/tpl/setting/settings_cdn.php:256
1953
  msgid ""
1954
  "Once saved, it will be matched with the current list and completed "
1955
  "automatically."
1956
  msgstr ""
1957
 
1958
- #: admin/tpl/setting/settings_cdn.php:219
1959
  msgid "Cloudflare API"
1960
  msgstr ""
1961
 
1962
- #: admin/tpl/setting/settings_cdn.php:223
1963
- msgid "Use Cloudflare API functionality."
1964
- msgstr ""
1965
-
1966
- #: admin/tpl/setting/settings_cdn.php:232
1967
- msgid "Your Email address on Cloudflare."
1968
- msgstr ""
1969
-
1970
- #: admin/tpl/setting/settings_cdn.php:237
1971
  msgid "Global API Key"
1972
  msgstr ""
1973
 
1974
- #: admin/tpl/setting/settings_cdn.php:241
1975
- msgid "Your API key is used to access Cloudflare APIs."
1976
- msgstr ""
1977
-
1978
- #: admin/tpl/setting/settings_cdn.php:242
1979
- msgid "Get it from <a %s>Cloudflare account</a>."
1980
- msgstr ""
1981
-
1982
- #: admin/tpl/setting/settings_cdn.php:247
1983
  msgid "Domain"
1984
  msgstr ""
1985
 
@@ -2030,12 +2059,6 @@ msgid ""
2030
  "Specify time in microseconds for the delay between requests during a crawl."
2031
  msgstr ""
2032
 
2033
- #: admin/tpl/setting/settings_crawler.php:22
2034
- #: admin/tpl/setting/settings_crawler.php:95
2035
- #: admin/tpl/setting/settings_crawler.php:100
2036
- msgid "NOTE"
2037
- msgstr ""
2038
-
2039
  #: admin/tpl/setting/settings_crawler.php:23
2040
  msgid "Server allowed min value"
2041
  msgstr ""
@@ -2108,69 +2131,91 @@ msgid ""
2108
  msgstr ""
2109
 
2110
  #: admin/tpl/setting/settings_crawler.php:139
2111
- #: admin/tpl/setting/settings_crawler.php:232
2112
- msgid "Custom Sitemap"
 
 
 
2113
  msgstr ""
2114
 
2115
  #: admin/tpl/setting/settings_crawler.php:144
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2116
  msgid ""
2117
  "The crawler can use your Google XML Sitemap instead of its own. Enter the "
2118
  "full URL to your sitemap here."
2119
  msgstr ""
2120
 
2121
- #: admin/tpl/setting/settings_crawler.php:150
2122
  msgid "Sitemap Generation"
2123
  msgstr ""
2124
 
2125
- #: admin/tpl/setting/settings_crawler.php:155
2126
  msgid "Include Posts"
2127
  msgstr ""
2128
 
2129
- #: admin/tpl/setting/settings_crawler.php:162
2130
  msgid "Include Pages"
2131
  msgstr ""
2132
 
2133
- #: admin/tpl/setting/settings_crawler.php:169
2134
  msgid "Include Categories"
2135
  msgstr ""
2136
 
2137
- #: admin/tpl/setting/settings_crawler.php:176
2138
  msgid "Include Tags"
2139
  msgstr ""
2140
 
2141
- #: admin/tpl/setting/settings_crawler.php:185
2142
  msgid "Exclude Custom Post Types"
2143
  msgstr ""
2144
 
2145
- #: admin/tpl/setting/settings_crawler.php:190
2146
  msgid "Exclude certain Custom Post Types in sitemap."
2147
  msgstr ""
2148
 
2149
- #: admin/tpl/setting/settings_crawler.php:196
2150
  msgid "Available Custom Post Type"
2151
  msgstr ""
2152
 
2153
- #: admin/tpl/setting/settings_crawler.php:204
2154
  msgid "Order links by"
2155
  msgstr ""
2156
 
2157
- #: admin/tpl/setting/settings_crawler.php:210
2158
  msgid "Date, descending (Default)"
2159
  msgstr ""
2160
 
2161
- #: admin/tpl/setting/settings_crawler.php:216
2162
  msgid "Date, ascending"
2163
  msgstr ""
2164
 
2165
- #: admin/tpl/setting/settings_crawler.php:222
2166
  msgid "Alphabetical, descending"
2167
  msgstr ""
2168
 
2169
- #: admin/tpl/setting/settings_crawler.php:228
2170
  msgid "Alphabetical, ascending"
2171
  msgstr ""
2172
 
2173
- #: admin/tpl/setting/settings_crawler.php:232
2174
  msgid "These options will be invalid when using %s."
2175
  msgstr ""
2176
 
@@ -2645,14 +2690,6 @@ msgstr ""
2645
  msgid "If %1$s is %2$s, then %3$s must be populated!"
2646
  msgstr ""
2647
 
2648
- #: admin/tpl/setting/settings_inc.cache_object.php:4
2649
- msgid "Enabled"
2650
- msgstr ""
2651
-
2652
- #: admin/tpl/setting/settings_inc.cache_object.php:5
2653
- msgid "Disabled"
2654
- msgstr ""
2655
-
2656
  #: admin/tpl/setting/settings_inc.cache_object.php:12
2657
  msgid "Not Available"
2658
  msgstr ""
@@ -2966,16 +3003,6 @@ msgstr ""
2966
  msgid "Both full URLs and partial strings can be used."
2967
  msgstr ""
2968
 
2969
- #: admin/tpl/setting/settings_media.php:36
2970
- #: admin/tpl/setting/settings_optimize.php:137
2971
- #: admin/tpl/setting/settings_tuning.php:24
2972
- #: admin/tpl/setting/settings_tuning.php:40
2973
- #: admin/tpl/setting/settings_tuning.php:60
2974
- #: admin/tpl/setting/settings_tuning.php:76
2975
- #: admin/tpl/setting/settings_tuning.php:148
2976
- msgid "API:"
2977
- msgstr ""
2978
-
2979
  #: admin/tpl/setting/settings_media.php:37
2980
  #: admin/tpl/setting/settings_tuning.php:41
2981
  #: admin/tpl/setting/settings_tuning.php:77
@@ -3288,7 +3315,7 @@ msgstr ""
3288
 
3289
  #: admin/tpl/setting/settings_purge.php:51
3290
  #: thirdparty/lscwp-3rd-woocommerce.cls.php:858
3291
- msgid "Note:"
3292
  msgstr ""
3293
 
3294
  #: admin/tpl/setting/settings_purge.php:53
@@ -3513,29 +3540,29 @@ msgstr ""
3513
  msgid "Compatibilities"
3514
  msgstr ""
3515
 
3516
- #: admin/tpl/settings.php:126
3517
  msgid "LiteSpeed Cache Settings"
3518
  msgstr ""
3519
 
3520
- #: admin/tpl/settings.php:132
3521
  msgid "Basic View"
3522
  msgstr ""
3523
 
3524
- #: admin/tpl/settings.php:133
3525
  msgid "Advanced View"
3526
  msgstr ""
3527
 
3528
- #: admin/tpl/settings.php:164
3529
  msgid "The network admin selected use primary site configs for all subsites."
3530
  msgstr ""
3531
 
3532
- #: admin/tpl/settings.php:165
3533
  msgid ""
3534
  "The following options are selected, but are not editable in this settings "
3535
  "page."
3536
  msgstr ""
3537
 
3538
- #: admin/tpl/settings.php:187 admin/tpl/settings.php:190
3539
  msgid "Save Changes"
3540
  msgstr ""
3541
 
@@ -3555,27 +3582,27 @@ msgstr ""
3555
  msgid "Purged the tags!"
3556
  msgstr ""
3557
 
3558
- #: inc/cdn.class.php:615 includes/litespeed-cache-cdn.class.php:615
3559
  msgid "Notified Cloudflare to set development mode to %s successfully."
3560
  msgstr ""
3561
 
3562
- #: inc/cdn.class.php:633 includes/litespeed-cache-cdn.class.php:633
3563
  msgid "Cloudflare API is set to off."
3564
  msgstr ""
3565
 
3566
- #: inc/cdn.class.php:649 includes/litespeed-cache-cdn.class.php:649
3567
  msgid "Notified Cloudflare to purge all successfully."
3568
  msgstr ""
3569
 
3570
- #: inc/cdn.class.php:664 includes/litespeed-cache-cdn.class.php:664
3571
  msgid "No available Cloudflare zone"
3572
  msgstr ""
3573
 
3574
- #: inc/cdn.class.php:759 includes/litespeed-cache-cdn.class.php:759
3575
  msgid "Communicated with Cloudflare successfully."
3576
  msgstr ""
3577
 
3578
- #: inc/cdn.class.php:768 includes/litespeed-cache-cdn.class.php:768
3579
  msgid "Failed to communicate with Cloudflare"
3580
  msgstr ""
3581
 
@@ -3599,167 +3626,172 @@ msgstr ""
3599
  msgid "Position reset notification sent successfully"
3600
  msgstr ""
3601
 
3602
- #: inc/crawler.class.php:464 includes/litespeed-cache-crawler.class.php:464
3603
- #: lib/litespeed/litespeed-crawler.class.php:366
3604
  msgid "Crawler %s reached end of sitemap file."
3605
  msgstr ""
3606
 
3607
- #: inc/crawler.class.php:494 inc/crawler.class.php:498
3608
- #: includes/litespeed-cache-crawler.class.php:494
3609
- #: includes/litespeed-cache-crawler.class.php:498
3610
  msgid "Guest"
3611
  msgstr ""
3612
 
3613
- #: inc/gui.class.php:208 includes/litespeed-cache-gui.class.php:208
3614
  msgid "Purge this page"
3615
  msgstr ""
3616
 
3617
- #: inc/gui.class.php:216 includes/litespeed-cache-gui.class.php:216
3618
  msgid "Mark this page as "
3619
  msgstr ""
3620
 
3621
- #: inc/gui.class.php:223 includes/litespeed-cache-gui.class.php:223
3622
  msgid "Non cacheable"
3623
  msgstr ""
3624
 
3625
- #: inc/gui.class.php:230 includes/litespeed-cache-gui.class.php:230
3626
  msgid "Private cache"
3627
  msgstr ""
3628
 
3629
- #: inc/gui.class.php:237 includes/litespeed-cache-gui.class.php:237
3630
  msgid "No optimization"
3631
  msgstr ""
3632
 
3633
- #: inc/gui.class.php:244 includes/litespeed-cache-gui.class.php:244
3634
  msgid "More settings"
3635
  msgstr ""
3636
 
3637
- #: inc/gui.class.php:263 inc/gui.class.php:297
3638
- #: includes/litespeed-cache-gui.class.php:263
3639
- #: includes/litespeed-cache-gui.class.php:297
3640
  msgid "LiteSpeed Cache Purge All"
3641
  msgstr ""
3642
 
3643
- #: inc/gui.class.php:306 includes/litespeed-cache-gui.class.php:306
3644
  msgid "Cloudflare Purge All"
3645
  msgstr ""
3646
 
3647
- #: inc/import.class.php:128
3648
- msgid "Import failed due to file error."
3649
  msgstr ""
3650
 
3651
- #: inc/import.class.php:160
3652
- msgid "Imported setting file %s successfully."
3653
  msgstr ""
3654
 
3655
- #: inc/litespeed-cache.class.php:260 includes/litespeed-cache.class.php:260
3656
- msgid "Crawler blacklist is saved."
 
3657
  msgstr ""
3658
 
3659
- #: inc/litespeed-cache.class.php:265 includes/litespeed-cache.class.php:265
3660
- msgid "Notified LiteSpeed Web Server to purge the front page."
3661
  msgstr ""
3662
 
3663
- #: inc/litespeed-cache.class.php:270 includes/litespeed-cache.class.php:270
3664
- msgid "Notified LiteSpeed Web Server to purge pages."
3665
  msgstr ""
3666
 
3667
- #: inc/litespeed-cache.class.php:275 includes/litespeed-cache.class.php:275
3668
- msgid "Notified LiteSpeed Web Server to purge CSS/JS entries."
3669
  msgstr ""
3670
 
3671
- #: inc/litespeed-cache.class.php:280 includes/litespeed-cache.class.php:280
3672
- msgid "Notified LiteSpeed Web Server to purge error pages."
3673
  msgstr ""
3674
 
3675
- #: inc/litespeed-cache.class.php:286 includes/litespeed-cache.class.php:286
3676
- msgid "Notified LiteSpeed Web Server to purge all caches."
3677
  msgstr ""
3678
 
3679
- #: inc/litespeed-cache.class.php:293 includes/litespeed-cache.class.php:293
3680
- msgid "Notified LiteSpeed Web Server to purge everything."
 
 
3681
  msgstr ""
3682
 
3683
- #: inc/litespeed-cache.class.php:308 includes/litespeed-cache.class.php:308
3684
- msgid "Notified LiteSpeed Web Server to purge the list."
3685
  msgstr ""
3686
 
3687
- #: inc/media.class.php:128
3688
- msgid "LiteSpeed Optimization"
3689
  msgstr ""
3690
 
3691
- #: inc/media.class.php:152
3692
- msgid "Disable WebP"
3693
  msgstr ""
3694
 
3695
- #: inc/media.class.php:157
3696
- msgid "Enable WebP"
3697
  msgstr ""
3698
 
3699
- #: inc/media.class.php:175
3700
- msgid "Restore Original File"
3701
  msgstr ""
3702
 
3703
- #: inc/media.class.php:180
3704
- msgid "Switch To Optimized File"
3705
  msgstr ""
3706
 
3707
- #: inc/media.class.php:194
3708
- msgid "WebP saved %s"
3709
  msgstr ""
3710
 
3711
- #: inc/media.class.php:203
3712
- msgid "Original saved %s"
3713
  msgstr ""
3714
 
3715
- #: inc/media.class.php:310
3716
- msgid "Disabled WebP file successfully."
3717
  msgstr ""
3718
 
3719
- #: inc/media.class.php:316
3720
- msgid "Enabled WebP file successfully."
3721
  msgstr ""
3722
 
3723
- #: inc/media.class.php:332
3724
- msgid "Restored original file successfully."
3725
  msgstr ""
3726
 
3727
- #: inc/media.class.php:339
3728
- msgid "Switched to optimized file successfully."
3729
  msgstr ""
3730
 
3731
- #: inc/media.class.php:435
3732
- msgid "Failed to communicate with LiteSpeed IAPI server"
3733
  msgstr ""
3734
 
3735
- #: inc/media.class.php:444
3736
- msgid "Communicated with LiteSpeed Image Optimization Server successfully."
3737
  msgstr ""
3738
 
3739
- #: inc/media.class.php:1000
3740
- msgid "Failed to push to LiteSpeed IAPI server: %s"
3741
  msgstr ""
3742
 
3743
- #: inc/media.class.php:1008
3744
- msgid "Failed to parse data from LiteSpeed IAPI server: %s"
3745
  msgstr ""
3746
 
3747
- #: inc/media.class.php:1126 inc/media.class.php:1191 inc/media.class.php:1324
3748
- msgid "No image found."
3749
  msgstr ""
3750
 
3751
- #: inc/media.class.php:1231 inc/media.class.php:1385
3752
- msgid ""
3753
- "Pushed %1$s groups with %2$s images to LiteSpeed optimization server, "
3754
- "accepted %3$s groups with %4$s images."
3755
  msgstr ""
3756
 
3757
- #: inc/media.class.php:1297
3758
- msgid "Number of images in one image group (%s) exceeds the credit (%s)"
3759
  msgstr ""
3760
 
3761
- #: inc/media.class.php:1353
3762
- msgid "Post data is empty."
 
 
 
 
3763
  msgstr ""
3764
 
3765
  #: inc/purge.class.php:64 includes/litespeed-cache-purge.class.php:64
@@ -3806,35 +3838,35 @@ msgstr ""
3806
  msgid " %s ago"
3807
  msgstr ""
3808
 
3809
- #: lib/litespeed/litespeed-crawler.class.php:196
3810
  msgid "Cannot read meta file: %s"
3811
  msgstr ""
3812
 
3813
- #: lib/litespeed/litespeed-crawler.class.php:201
3814
  msgid "Oh look, there is already another LiteSpeed crawler running!"
3815
  msgstr ""
3816
 
3817
- #: lib/litespeed/litespeed-crawler.class.php:207
3818
  msgid "Stopped due to load hit the maximum."
3819
  msgstr ""
3820
 
3821
- #: lib/litespeed/litespeed-crawler.class.php:261
3822
  msgid "Stopped due to error when crawling urls %1$s : %2$s"
3823
  msgstr ""
3824
 
3825
- #: lib/litespeed/litespeed-crawler.class.php:268
3826
  msgid "Stopped: crawler disabled by the server admin"
3827
  msgstr ""
3828
 
3829
- #: lib/litespeed/litespeed-crawler.class.php:293
3830
  msgid "Stopped due to exceeding defined Maximum Run Time"
3831
  msgstr ""
3832
 
3833
- #: lib/litespeed/litespeed-crawler.class.php:310
3834
  msgid "Stopped due to reset meta position"
3835
  msgstr ""
3836
 
3837
- #: lib/litespeed/litespeed-crawler.class.php:318
3838
  msgid "Stopped due to load over limit"
3839
  msgstr ""
3840
 
@@ -3931,10 +3963,6 @@ msgstr ""
3931
  msgid "To test the cart, visit the <a %s>FAQ</a>."
3932
  msgstr ""
3933
 
3934
- #. Plugin Name of the plugin/theme
3935
- msgid "LiteSpeed Cache"
3936
- msgstr ""
3937
-
3938
  #. Plugin URI of the plugin/theme
3939
  msgid ""
3940
  "https://www.litespeedtech.com/products/cache-plugins/wordpress-acceleration"
2
  # This file is distributed under the same license as the LiteSpeed Cache package.
3
  msgid ""
4
  msgstr ""
5
+ "Project-Id-Version: LiteSpeed Cache 2.0\n"
6
  "Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/litespeed-cache\n"
7
+ "POT-Creation-Date: 2018-03-07 18:04:04+00:00\n"
8
  "MIME-Version: 1.0\n"
9
  "Content-Type: text/plain; charset=UTF-8\n"
10
  "Content-Transfer-Encoding: 8bit\n"
28
  msgid "Message from LiteSpeed image server"
29
  msgstr ""
30
 
31
+ #: admin/litespeed-cache-admin-display.class.php:152
32
+ #: admin/tpl/setting/settings_cdn.php:203
33
+ #: admin/tpl/setting/settings_cdn.php:246 inc/gui.class.php:273
34
+ #: includes/litespeed-cache-gui.class.php:273
35
  msgid "Manage"
36
  msgstr ""
37
 
38
+ #: admin/litespeed-cache-admin-display.class.php:154
39
+ #: admin/litespeed-cache-admin-display.class.php:243 inc/gui.class.php:281
40
+ #: includes/litespeed-cache-gui.class.php:281
41
  msgid "Settings"
42
  msgstr ""
43
 
44
+ #: admin/litespeed-cache-admin-display.class.php:157
45
  msgid "Edit .htaccess"
46
  msgstr ""
47
 
48
+ #: admin/litespeed-cache-admin-display.class.php:161 inc/gui.class.php:290
49
+ #: includes/litespeed-cache-gui.class.php:290
50
  msgid "Image Optimization"
51
  msgstr ""
52
 
53
+ #: admin/litespeed-cache-admin-display.class.php:162 admin/tpl/settings.php:24
54
  msgid "Crawler"
55
  msgstr ""
56
 
57
+ #: admin/litespeed-cache-admin-display.class.php:163
58
  msgid "Report"
59
  msgstr ""
60
 
61
+ #: admin/litespeed-cache-admin-display.class.php:164
62
  msgid "Import / Export"
63
  msgstr ""
64
 
65
+ #: admin/litespeed-cache-admin-display.class.php:167
66
  #: admin/tpl/setting/settings_debug.php:13
67
  msgid "Debug Log"
68
  msgstr ""
69
 
70
+ #: admin/litespeed-cache-admin-display.class.php:263
71
  msgid ""
72
  "It is recommended that LiteSpeed Cache be purged after updating a plugin."
73
  msgstr ""
74
 
75
+ #: admin/litespeed-cache-admin-display.class.php:805
76
+ #: admin/litespeed-cache-admin-display.class.php:890
77
  #: admin/tpl/setting/settings_inc.cache_mobile.php:67
78
  #: admin/tpl/setting/settings_media.php:73
79
  #: admin/tpl/setting/settings_optimize.php:160
82
  msgid "ON"
83
  msgstr ""
84
 
85
+ #: admin/litespeed-cache-admin-display.class.php:806
86
+ #: admin/litespeed-cache-admin-display.class.php:894
87
  #: admin/tpl/setting/settings_inc.cache_object.php:149
88
  #: admin/tpl/setting/settings_tuning.php:18
89
  #: admin/tpl/setting/settings_tuning.php:54
90
  msgid "OFF"
91
  msgstr ""
92
 
93
+ #: admin/litespeed-cache-admin-display.class.php:920
94
  msgid "Recommended value: %s"
95
  msgstr ""
96
 
97
+ #: admin/litespeed-cache-admin-display.class.php:936
98
+ #: admin/tpl/setting/settings_media.php:36
99
+ #: admin/tpl/setting/settings_optimize.php:137
100
+ #: admin/tpl/setting/settings_tuning.php:24
101
+ #: admin/tpl/setting/settings_tuning.php:40
102
+ #: admin/tpl/setting/settings_tuning.php:60
103
+ #: admin/tpl/setting/settings_tuning.php:76
104
+ #: admin/tpl/setting/settings_tuning.php:148
105
  msgid "API"
106
  msgstr ""
107
 
108
+ #: admin/litespeed-cache-admin-display.class.php:937
109
  msgid "Server variable(s) %s available to override this setting."
110
  msgstr ""
111
 
112
+ #: admin/litespeed-cache-admin-display.class.php:939
113
+ #: admin/tpl/image_optimization.php:154 admin/tpl/image_optimization.php:211
114
  #: admin/tpl/manage/manage_cdn.php:60
115
  #: admin/tpl/setting/settings_advanced.php:10
116
  #: admin/tpl/setting/settings_advanced.php:36
133
  msgid "Learn More"
134
  msgstr ""
135
 
136
+ #: admin/litespeed-cache-admin-display.class.php:954
137
+ msgid "%s groups"
138
+ msgstr ""
139
+
140
+ #: admin/litespeed-cache-admin-display.class.php:957
141
+ msgid "%s images"
142
+ msgstr ""
143
+
144
+ #: admin/litespeed-cache-admin-display.class.php:967
145
+ msgid "%s group"
146
+ msgstr ""
147
+
148
+ #: admin/litespeed-cache-admin-display.class.php:970
149
+ msgid "%s image"
150
+ msgstr ""
151
+
152
  #: admin/litespeed-cache-admin-error.class.php:87
153
  msgid "The installed PHP version is too old for the LiteSpeed Cache Plugin."
154
  msgstr ""
432
  msgstr ""
433
 
434
  #: admin/litespeed-cache-admin-settings.class.php:342
435
+ #: admin/litespeed-cache-admin-settings.class.php:994
436
  msgid "Default Public Cache"
437
  msgstr ""
438
 
448
  msgid "Feed"
449
  msgstr ""
450
 
 
 
 
 
 
 
 
 
 
 
 
 
451
  #: admin/litespeed-cache-admin-settings.class.php:844
452
  #: admin/tpl/setting/settings_debug.php:78
453
  msgid "Log File Size Limit"
454
  msgstr ""
455
 
456
+ #: admin/litespeed-cache-admin-settings.class.php:917
457
  #: admin/tpl/setting/settings_crawler.php:13
458
  msgid "Delay"
459
  msgstr ""
460
 
461
+ #: admin/litespeed-cache-admin-settings.class.php:918
462
  #: admin/tpl/setting/settings_crawler.php:37
463
  msgid "Run Duration"
464
  msgstr ""
465
 
466
+ #: admin/litespeed-cache-admin-settings.class.php:919
467
  msgid "Cron Interval"
468
  msgstr ""
469
 
470
+ #: admin/litespeed-cache-admin-settings.class.php:920
471
  msgid "Whole Interval"
472
  msgstr ""
473
 
474
+ #: admin/litespeed-cache-admin-settings.class.php:921
475
  #: admin/tpl/setting/settings_crawler.php:73
476
  msgid "Threads"
477
  msgstr ""
478
 
479
+ #: admin/litespeed-cache-admin.class.php:206
480
  msgid ""
481
  "For this scenario only, the network admin may uncheck \"Check Advanced Cache"
482
  "\" in LiteSpeed Cache settings."
483
  msgstr ""
484
 
485
+ #: admin/litespeed-cache-admin.class.php:208
486
  msgid ""
487
  "For this scenario only, please uncheck \"Check Advanced Cache\" in LiteSpeed "
488
  "Cache settings."
489
  msgstr ""
490
 
491
+ #: admin/litespeed-cache-admin.class.php:210
492
  msgid ""
493
  "Please disable/deactivate any other Full Page Cache solutions that are "
494
  "currently being used."
495
  msgstr ""
496
 
497
+ #: admin/litespeed-cache-admin.class.php:211
498
  msgid ""
499
  "LiteSpeed Cache does work with other cache solutions, but only their non-"
500
  "page caching offerings—such as minifying css/js files."
551
  msgstr ""
552
 
553
  #: admin/tpl/crawler.php:94 admin/tpl/manage/manage_cdn.php:15
554
+ #: admin/tpl/setting/settings_optimize.php:13 admin/tpl/settings.php:165
555
  msgid "WARNING"
556
  msgstr ""
557
 
762
  msgid "A TTL of 0 indicates do not cache."
763
  msgstr ""
764
 
765
+ #: admin/tpl/image_optimization.php:16
766
  msgid "Level"
767
  msgstr ""
768
 
769
+ #: admin/tpl/image_optimization.php:20
770
  msgid "Credit"
771
  msgstr ""
772
 
773
+ #: admin/tpl/image_optimization.php:21
774
  msgid "Credit recovers with each successful pull."
775
  msgstr ""
776
 
777
+ #: admin/tpl/image_optimization.php:25
778
  msgid "Total Reduction"
779
  msgstr ""
780
 
781
+ #: admin/tpl/image_optimization.php:29
782
  msgid "Images pulled"
783
  msgstr ""
784
 
785
+ #: admin/tpl/image_optimization.php:32
786
  msgid "Images failed to fetch"
787
  msgstr ""
788
 
789
+ #: admin/tpl/image_optimization.php:35
790
  msgid "Images failed to notify"
791
  msgstr ""
792
 
793
+ #: admin/tpl/image_optimization.php:38
794
  msgid "Images failed to pull"
795
  msgstr ""
796
 
797
+ #: admin/tpl/image_optimization.php:41
798
  msgid "Last Request"
799
  msgstr ""
800
 
801
+ #: admin/tpl/image_optimization.php:52 admin/tpl/image_optimization.php:53
802
+ msgid "Click the %s button."
803
+ msgstr ""
804
+
805
+ #: admin/tpl/image_optimization.php:52 admin/tpl/image_optimization.php:116
806
+ #: admin/tpl/image_optimization.php:152
807
+ msgid "Update Status"
808
+ msgstr ""
809
+
810
+ #: admin/tpl/image_optimization.php:53 admin/tpl/image_optimization.php:149
811
+ #: admin/tpl/image_optimization.php:157
812
+ msgid "Send Optimization Request"
813
+ msgstr ""
814
+
815
+ #: admin/tpl/image_optimization.php:54
816
+ msgid "Click the %s button or wait for the cron job to finish the pull action."
817
+ msgstr ""
818
+
819
+ #: admin/tpl/image_optimization.php:54 admin/tpl/image_optimization.php:194
820
+ msgid "Pull Images"
821
+ msgstr ""
822
+
823
+ #: admin/tpl/image_optimization.php:55
824
+ msgid "Repeat the above steps until you have leveled up."
825
+ msgstr ""
826
+
827
+ #: admin/tpl/image_optimization.php:70
828
  msgid "LiteSpeed Cache Image Optimization"
829
  msgstr ""
830
 
831
+ #: admin/tpl/image_optimization.php:83
832
+ msgid "How to Level Up"
833
  msgstr ""
834
 
835
+ #: admin/tpl/image_optimization.php:86
836
+ msgid "Optimization Summary"
837
  msgstr ""
838
 
839
+ #: admin/tpl/image_optimization.php:119
840
  msgid ""
841
  "This will communicate with LiteSpeed's Image Optimization Server and "
842
  "retrieve the most recent status."
843
  msgstr ""
844
 
845
+ #: admin/tpl/image_optimization.php:124
846
  msgid "Image Information"
847
  msgstr ""
848
 
849
+ #: admin/tpl/image_optimization.php:125
850
  msgid "Beta Version"
851
  msgstr ""
852
 
853
+ #: admin/tpl/image_optimization.php:135
854
+ msgid "Images total"
855
  msgstr ""
856
 
857
+ #: admin/tpl/image_optimization.php:137
858
+ msgid "What is a group?"
859
  msgstr ""
860
 
861
+ #: admin/tpl/image_optimization.php:140
862
+ msgid "Images not yet requested"
863
  msgstr ""
864
 
865
+ #: admin/tpl/image_optimization.php:152
866
  msgid "Please press the %s button before sending a new request."
867
  msgstr ""
868
 
869
+ #: admin/tpl/image_optimization.php:160
870
  msgid ""
871
  "This will send the optimization request and the images to LiteSpeed's Image "
872
  "Optimization Server."
873
  msgstr ""
874
 
875
+ #: admin/tpl/image_optimization.php:161
876
  msgid "You can send at most %s images at once."
877
  msgstr ""
878
 
879
+ #: admin/tpl/image_optimization.php:169
880
+ msgid "Images requested"
881
+ msgstr ""
882
+
883
+ #: admin/tpl/image_optimization.php:174
884
+ msgid "Images failed to optimize"
885
  msgstr ""
886
 
887
+ #: admin/tpl/image_optimization.php:179
888
+ msgid "Image files missing"
889
  msgstr ""
890
 
891
+ #: admin/tpl/image_optimization.php:184
892
  msgid ""
893
  "After LiteSpeed's Image Optimization Server finishes optimization, it will "
894
  "notify your site to pull the optimized images."
895
  msgstr ""
896
 
897
+ #: admin/tpl/image_optimization.php:185
898
  msgid "This process is automatic."
899
  msgstr ""
900
 
901
+ #: admin/tpl/image_optimization.php:188
902
+ msgid "Images notified to pull"
903
  msgstr ""
904
 
905
+ #: admin/tpl/image_optimization.php:197
 
 
 
 
906
  msgid "Only press the button if the pull cron job is disabled."
907
  msgstr ""
908
 
909
+ #: admin/tpl/image_optimization.php:198
910
  msgid "Images will be pulled automatically if the cron job is running."
911
  msgstr ""
912
 
913
+ #: admin/tpl/image_optimization.php:202
914
  msgid "Last pull initiated by cron at %s."
915
  msgstr ""
916
 
917
+ #: admin/tpl/image_optimization.php:207
918
+ msgid "Images optimized and pulled"
919
  msgstr ""
920
 
921
+ #: admin/tpl/image_optimization.php:216
922
  msgid "Revert Optimization"
923
  msgstr ""
924
 
925
+ #: admin/tpl/image_optimization.php:219
926
  msgid ""
927
  "Switch all images in the media library back to their original unoptimized "
928
  "versions."
929
  msgstr ""
930
 
931
+ #: admin/tpl/image_optimization.php:225
932
  msgid "Undo Optimization"
933
  msgstr ""
934
 
935
+ #: admin/tpl/image_optimization.php:228
936
  msgid "Revert all optimized images back to their original versions."
937
  msgstr ""
938
 
939
+ #: admin/tpl/image_optimization.php:234
940
  msgid "Re-do Optimization"
941
  msgstr ""
942
 
943
+ #: admin/tpl/image_optimization.php:237
944
  msgid "Switch back to using optimized images."
945
  msgstr ""
946
 
947
+ #: admin/tpl/image_optimization.php:242
948
  msgid "Results can be checked in <a %s>Media Library</a>."
949
  msgstr ""
950
 
951
+ #: admin/tpl/image_optimization.php:246
952
  msgid "Send New Thumbnail Requests"
953
  msgstr ""
954
 
955
+ #: admin/tpl/image_optimization.php:249
956
  msgid ""
957
  "Scan for any new unoptimized image thumbnail sizes and resend necessary "
958
  "image optimization requests."
959
  msgstr ""
960
 
961
+ #: admin/tpl/image_optimization.php:254
962
  msgid "Reset IAPI Key"
963
  msgstr ""
964
 
965
+ #: admin/tpl/image_optimization.php:257
966
  msgid ""
967
  "The current IAPI key must be reset after changing home URL or domain before "
968
  "making any further optimization requests."
969
  msgstr ""
970
 
971
+ #: admin/tpl/image_optimization.php:262
972
  msgid "Destroy All Optimization Data!"
973
  msgstr ""
974
 
975
+ #: admin/tpl/image_optimization.php:265
976
  msgid ""
977
  "Remove all previous image optimization requests/results, revert completed "
978
  "optimizations, and delete all optimization files."
979
  msgstr ""
980
 
981
+ #: admin/tpl/image_optimization.php:267
982
  #: admin/tpl/setting/settings_advanced.php:50
983
  #: admin/tpl/setting/settings_cdn.php:97
984
+ #: admin/tpl/setting/settings_crawler.php:22
985
+ #: admin/tpl/setting/settings_crawler.php:95
986
+ #: admin/tpl/setting/settings_crawler.php:100
987
  #: admin/tpl/setting/settings_excludes.php:63
988
  #: admin/tpl/setting/settings_excludes.php:101
989
  #: admin/tpl/setting/settings_inc.cache_browser.php:12
997
  #: admin/tpl/setting/settings_optimize.php:162
998
  #: admin/tpl/setting/settings_tuning.php:20
999
  #: admin/tpl/setting/settings_tuning.php:56
1000
+ msgid "NOTE"
1001
  msgstr ""
1002
 
1003
+ #: admin/tpl/image_optimization.php:268
1004
  msgid ""
1005
  "If there are unfinished requests in progress, the requests' credits will NOT "
1006
  "be recovered."
1007
  msgstr ""
1008
 
1009
+ #: admin/tpl/image_optimization.php:268
1010
  #: admin/tpl/setting/settings_optimize.php:87
1011
  #: admin/tpl/setting/settings_optimize.php:163
1012
  msgid "JS Combine"
1051
  "Cache settings."
1052
  msgstr ""
1053
 
1054
+ #: admin/tpl/inc/admin_footer.php:6
1055
+ msgid "Rate %s on %s"
 
 
1056
  msgstr ""
1057
 
1058
+ #. #-#-#-#-# litespeed-cache.pot (LiteSpeed Cache 2.0) #-#-#-#-#
1059
+ #. Plugin Name of the plugin/theme
1060
+ #: admin/tpl/inc/admin_footer.php:6
1061
+ msgid "LiteSpeed Cache"
1062
+ msgstr ""
1063
+
1064
+ #: admin/tpl/inc/admin_footer.php:9
1065
+ msgid "Read LiteSpeed Wiki"
1066
+ msgstr ""
1067
+
1068
+ #: admin/tpl/inc/admin_footer.php:11
1069
+ msgid "Visit LSCWP support forum"
1070
+ msgstr ""
1071
+
1072
+ #: admin/tpl/inc/admin_footer.php:13
1073
+ msgid "Join LiteSpeed Slack community"
1074
  msgstr ""
1075
 
1076
  #: admin/tpl/inc/api_key.php:11
1437
  msgid "Are you sure you want to purge all?"
1438
  msgstr ""
1439
 
1440
+ #: admin/tpl/manage/manage_purge.php:61 inc/gui.class.php:318
1441
+ #: includes/litespeed-cache-gui.class.php:318
1442
  msgid "Object Cache Purge All"
1443
  msgstr ""
1444
 
1446
  msgid "Purge all the object caches"
1447
  msgstr ""
1448
 
1449
+ #: admin/tpl/manage/manage_purge.php:71 inc/gui.class.php:328
1450
+ #: includes/litespeed-cache-gui.class.php:328
1451
  msgid "Opcode Cache Purge All"
1452
  msgstr ""
1453
 
1562
  msgid "DB Optimizer"
1563
  msgstr ""
1564
 
1565
+ #: admin/tpl/manage.php:12 admin/tpl/setting/settings_cdn.php:203
1566
+ #: admin/tpl/setting/settings_cdn.php:246 admin/tpl/settings.php:14
1567
  msgid "CDN"
1568
  msgstr ""
1569
 
1874
 
1875
  #: admin/tpl/setting/settings_cdn.php:98
1876
  msgid ""
1877
+ "To randomize CDN hostname, define multiple hostnames for the same resources."
 
1878
  msgstr ""
1879
 
1880
  #: admin/tpl/setting/settings_cdn.php:103
1940
  msgid "Off"
1941
  msgstr ""
1942
 
 
 
 
 
 
 
 
 
1943
  #: admin/tpl/setting/settings_cdn.php:170
1944
  msgid ""
1945
  "Improve page load time by loading jQuery from a remote CDN service instead "
1951
  msgstr ""
1952
 
1953
  #: admin/tpl/setting/settings_cdn.php:180
1954
+ #: admin/tpl/setting/settings_cdn.php:245
1955
+ msgid "Use %s API functionality."
1956
  msgstr ""
1957
 
1958
+ #: admin/tpl/setting/settings_cdn.php:203
1959
+ #: admin/tpl/setting/settings_cdn.php:246
1960
  msgid "This can be managed from <a %2$s>%1$s</a>."
1961
  msgstr ""
1962
 
1963
+ #: admin/tpl/setting/settings_cdn.php:207
1964
+ #: admin/tpl/setting/settings_cdn.php:250
1965
  msgid "Email Address"
1966
  msgstr ""
1967
 
1968
+ #: admin/tpl/setting/settings_cdn.php:211
1969
+ #: admin/tpl/setting/settings_cdn.php:254
1970
+ msgid "Your Email address on %s."
1971
  msgstr ""
1972
 
1973
+ #: admin/tpl/setting/settings_cdn.php:216
1974
  msgid "User API Key"
1975
  msgstr ""
1976
 
1977
+ #: admin/tpl/setting/settings_cdn.php:220
1978
+ #: admin/tpl/setting/settings_cdn.php:263
1979
+ msgid "Your API key is used to access %s APIs."
1980
  msgstr ""
1981
 
1982
+ #: admin/tpl/setting/settings_cdn.php:221
1983
+ #: admin/tpl/setting/settings_cdn.php:264
1984
+ msgid "Get it from <a %1$s>%2$s</a>."
1985
  msgstr ""
1986
 
1987
+ #: admin/tpl/setting/settings_cdn.php:226
1988
  msgid "Site Domain"
1989
  msgstr ""
1990
 
1991
+ #: admin/tpl/setting/settings_cdn.php:232
1992
+ #: admin/tpl/setting/settings_cdn.php:277
1993
  msgid "You can just type part of the domain."
1994
  msgstr ""
1995
 
1996
+ #: admin/tpl/setting/settings_cdn.php:233
1997
+ #: admin/tpl/setting/settings_cdn.php:278
1998
  msgid ""
1999
  "Once saved, it will be matched with the current list and completed "
2000
  "automatically."
2001
  msgstr ""
2002
 
2003
+ #: admin/tpl/setting/settings_cdn.php:241
2004
  msgid "Cloudflare API"
2005
  msgstr ""
2006
 
2007
+ #: admin/tpl/setting/settings_cdn.php:259
 
 
 
 
 
 
 
 
2008
  msgid "Global API Key"
2009
  msgstr ""
2010
 
2011
+ #: admin/tpl/setting/settings_cdn.php:269
 
 
 
 
 
 
 
 
2012
  msgid "Domain"
2013
  msgstr ""
2014
 
2059
  "Specify time in microseconds for the delay between requests during a crawl."
2060
  msgstr ""
2061
 
 
 
 
 
 
 
2062
  #: admin/tpl/setting/settings_crawler.php:23
2063
  msgid "Server allowed min value"
2064
  msgstr ""
2131
  msgstr ""
2132
 
2133
  #: admin/tpl/setting/settings_crawler.php:139
2134
+ msgid "HTTP/2 Crawl"
2135
+ msgstr ""
2136
+
2137
+ #: admin/tpl/setting/settings_crawler.php:143
2138
+ msgid "Crawl using the HTTP/2 protocal."
2139
  msgstr ""
2140
 
2141
  #: admin/tpl/setting/settings_crawler.php:144
2142
+ msgid "Current curl HTTP/2 extension status"
2143
+ msgstr ""
2144
+
2145
+ #: admin/tpl/setting/settings_crawler.php:146
2146
+ #: admin/tpl/setting/settings_inc.cache_object.php:4
2147
+ msgid "Enabled"
2148
+ msgstr ""
2149
+
2150
+ #: admin/tpl/setting/settings_crawler.php:148
2151
+ #: admin/tpl/setting/settings_inc.cache_object.php:5
2152
+ msgid "Disabled"
2153
+ msgstr ""
2154
+
2155
+ #: admin/tpl/setting/settings_crawler.php:155
2156
+ #: admin/tpl/setting/settings_crawler.php:248
2157
+ msgid "Custom Sitemap"
2158
+ msgstr ""
2159
+
2160
+ #: admin/tpl/setting/settings_crawler.php:160
2161
  msgid ""
2162
  "The crawler can use your Google XML Sitemap instead of its own. Enter the "
2163
  "full URL to your sitemap here."
2164
  msgstr ""
2165
 
2166
+ #: admin/tpl/setting/settings_crawler.php:166
2167
  msgid "Sitemap Generation"
2168
  msgstr ""
2169
 
2170
+ #: admin/tpl/setting/settings_crawler.php:171
2171
  msgid "Include Posts"
2172
  msgstr ""
2173
 
2174
+ #: admin/tpl/setting/settings_crawler.php:178
2175
  msgid "Include Pages"
2176
  msgstr ""
2177
 
2178
+ #: admin/tpl/setting/settings_crawler.php:185
2179
  msgid "Include Categories"
2180
  msgstr ""
2181
 
2182
+ #: admin/tpl/setting/settings_crawler.php:192
2183
  msgid "Include Tags"
2184
  msgstr ""
2185
 
2186
+ #: admin/tpl/setting/settings_crawler.php:201
2187
  msgid "Exclude Custom Post Types"
2188
  msgstr ""
2189
 
2190
+ #: admin/tpl/setting/settings_crawler.php:206
2191
  msgid "Exclude certain Custom Post Types in sitemap."
2192
  msgstr ""
2193
 
2194
+ #: admin/tpl/setting/settings_crawler.php:212
2195
  msgid "Available Custom Post Type"
2196
  msgstr ""
2197
 
2198
+ #: admin/tpl/setting/settings_crawler.php:220
2199
  msgid "Order links by"
2200
  msgstr ""
2201
 
2202
+ #: admin/tpl/setting/settings_crawler.php:226
2203
  msgid "Date, descending (Default)"
2204
  msgstr ""
2205
 
2206
+ #: admin/tpl/setting/settings_crawler.php:232
2207
  msgid "Date, ascending"
2208
  msgstr ""
2209
 
2210
+ #: admin/tpl/setting/settings_crawler.php:238
2211
  msgid "Alphabetical, descending"
2212
  msgstr ""
2213
 
2214
+ #: admin/tpl/setting/settings_crawler.php:244
2215
  msgid "Alphabetical, ascending"
2216
  msgstr ""
2217
 
2218
+ #: admin/tpl/setting/settings_crawler.php:248
2219
  msgid "These options will be invalid when using %s."
2220
  msgstr ""
2221
 
2690
  msgid "If %1$s is %2$s, then %3$s must be populated!"
2691
  msgstr ""
2692
 
 
 
 
 
 
 
 
 
2693
  #: admin/tpl/setting/settings_inc.cache_object.php:12
2694
  msgid "Not Available"
2695
  msgstr ""
3003
  msgid "Both full URLs and partial strings can be used."
3004
  msgstr ""
3005
 
 
 
 
 
 
 
 
 
 
 
3006
  #: admin/tpl/setting/settings_media.php:37
3007
  #: admin/tpl/setting/settings_tuning.php:41
3008
  #: admin/tpl/setting/settings_tuning.php:77
3315
 
3316
  #: admin/tpl/setting/settings_purge.php:51
3317
  #: thirdparty/lscwp-3rd-woocommerce.cls.php:858
3318
+ msgid "Note"
3319
  msgstr ""
3320
 
3321
  #: admin/tpl/setting/settings_purge.php:53
3540
  msgid "Compatibilities"
3541
  msgstr ""
3542
 
3543
+ #: admin/tpl/settings.php:129
3544
  msgid "LiteSpeed Cache Settings"
3545
  msgstr ""
3546
 
3547
+ #: admin/tpl/settings.php:135
3548
  msgid "Basic View"
3549
  msgstr ""
3550
 
3551
+ #: admin/tpl/settings.php:136
3552
  msgid "Advanced View"
3553
  msgstr ""
3554
 
3555
+ #: admin/tpl/settings.php:167
3556
  msgid "The network admin selected use primary site configs for all subsites."
3557
  msgstr ""
3558
 
3559
+ #: admin/tpl/settings.php:168
3560
  msgid ""
3561
  "The following options are selected, but are not editable in this settings "
3562
  "page."
3563
  msgstr ""
3564
 
3565
+ #: admin/tpl/settings.php:190 admin/tpl/settings.php:193
3566
  msgid "Save Changes"
3567
  msgstr ""
3568
 
3582
  msgid "Purged the tags!"
3583
  msgstr ""
3584
 
3585
+ #: inc/cdn.class.php:650 includes/litespeed-cache-cdn.class.php:650
3586
  msgid "Notified Cloudflare to set development mode to %s successfully."
3587
  msgstr ""
3588
 
3589
+ #: inc/cdn.class.php:668 includes/litespeed-cache-cdn.class.php:668
3590
  msgid "Cloudflare API is set to off."
3591
  msgstr ""
3592
 
3593
+ #: inc/cdn.class.php:684 includes/litespeed-cache-cdn.class.php:684
3594
  msgid "Notified Cloudflare to purge all successfully."
3595
  msgstr ""
3596
 
3597
+ #: inc/cdn.class.php:699 includes/litespeed-cache-cdn.class.php:699
3598
  msgid "No available Cloudflare zone"
3599
  msgstr ""
3600
 
3601
+ #: inc/cdn.class.php:794 includes/litespeed-cache-cdn.class.php:794
3602
  msgid "Communicated with Cloudflare successfully."
3603
  msgstr ""
3604
 
3605
+ #: inc/cdn.class.php:803 includes/litespeed-cache-cdn.class.php:803
3606
  msgid "Failed to communicate with Cloudflare"
3607
  msgstr ""
3608
 
3626
  msgid "Position reset notification sent successfully"
3627
  msgstr ""
3628
 
3629
+ #: inc/crawler.class.php:466 includes/litespeed-cache-crawler.class.php:466
3630
+ #: lib/litespeed/litespeed-crawler.class.php:402
3631
  msgid "Crawler %s reached end of sitemap file."
3632
  msgstr ""
3633
 
3634
+ #: inc/crawler.class.php:496 inc/crawler.class.php:500
3635
+ #: includes/litespeed-cache-crawler.class.php:496
3636
+ #: includes/litespeed-cache-crawler.class.php:500
3637
  msgid "Guest"
3638
  msgstr ""
3639
 
3640
+ #: inc/gui.class.php:210 includes/litespeed-cache-gui.class.php:210
3641
  msgid "Purge this page"
3642
  msgstr ""
3643
 
3644
+ #: inc/gui.class.php:218 includes/litespeed-cache-gui.class.php:218
3645
  msgid "Mark this page as "
3646
  msgstr ""
3647
 
3648
+ #: inc/gui.class.php:225 includes/litespeed-cache-gui.class.php:225
3649
  msgid "Non cacheable"
3650
  msgstr ""
3651
 
3652
+ #: inc/gui.class.php:232 includes/litespeed-cache-gui.class.php:232
3653
  msgid "Private cache"
3654
  msgstr ""
3655
 
3656
+ #: inc/gui.class.php:239 includes/litespeed-cache-gui.class.php:239
3657
  msgid "No optimization"
3658
  msgstr ""
3659
 
3660
+ #: inc/gui.class.php:246 includes/litespeed-cache-gui.class.php:246
3661
  msgid "More settings"
3662
  msgstr ""
3663
 
3664
+ #: inc/gui.class.php:265 inc/gui.class.php:299
3665
+ #: includes/litespeed-cache-gui.class.php:265
3666
+ #: includes/litespeed-cache-gui.class.php:299
3667
  msgid "LiteSpeed Cache Purge All"
3668
  msgstr ""
3669
 
3670
+ #: inc/gui.class.php:308 includes/litespeed-cache-gui.class.php:308
3671
  msgid "Cloudflare Purge All"
3672
  msgstr ""
3673
 
3674
+ #: inc/img_optm.class.php:76
3675
+ msgid "Failed to communicate with LiteSpeed IAPI server"
3676
  msgstr ""
3677
 
3678
+ #: inc/img_optm.class.php:85
3679
+ msgid "Communicated with LiteSpeed Image Optimization Server successfully."
3680
  msgstr ""
3681
 
3682
+ #: inc/img_optm.class.php:134 inc/img_optm.class.php:189
3683
+ #: inc/img_optm.class.php:1154 inc/img_optm.class.php:1219
3684
+ msgid "No image found."
3685
  msgstr ""
3686
 
3687
+ #: inc/img_optm.class.php:161
3688
+ msgid "Number of images in one image group (%s) exceeds the credit (%s)"
3689
  msgstr ""
3690
 
3691
+ #: inc/img_optm.class.php:209
3692
+ msgid "Optimized successfully."
3693
  msgstr ""
3694
 
3695
+ #: inc/img_optm.class.php:266
3696
+ msgid "Pushed %1$s to LiteSpeed optimization server, accepted %2$s."
3697
  msgstr ""
3698
 
3699
+ #: inc/img_optm.class.php:602
3700
+ msgid "Failed to push to LiteSpeed IAPI server: %s"
3701
  msgstr ""
3702
 
3703
+ #: inc/img_optm.class.php:610
3704
+ msgid "Failed to parse data from LiteSpeed IAPI server: %s"
3705
  msgstr ""
3706
 
3707
+ #: inc/img_optm.class.php:1257
3708
+ msgid ""
3709
+ "Pushed %1$s groups with %2$s images to LiteSpeed optimization server, "
3710
+ "accepted %3$s groups with %4$s images."
3711
  msgstr ""
3712
 
3713
+ #: inc/img_optm.class.php:1479
3714
+ msgid "Disabled WebP file successfully."
3715
  msgstr ""
3716
 
3717
+ #: inc/img_optm.class.php:1485
3718
+ msgid "Enabled WebP file successfully."
3719
  msgstr ""
3720
 
3721
+ #: inc/img_optm.class.php:1501
3722
+ msgid "Restored original file successfully."
3723
  msgstr ""
3724
 
3725
+ #: inc/img_optm.class.php:1508
3726
+ msgid "Switched to optimized file successfully."
3727
  msgstr ""
3728
 
3729
+ #: inc/import.class.php:128
3730
+ msgid "Import failed due to file error."
3731
  msgstr ""
3732
 
3733
+ #: inc/import.class.php:160
3734
+ msgid "Imported setting file %s successfully."
3735
  msgstr ""
3736
 
3737
+ #: inc/litespeed-cache.class.php:262 includes/litespeed-cache.class.php:262
3738
+ msgid "Crawler blacklist is saved."
3739
  msgstr ""
3740
 
3741
+ #: inc/litespeed-cache.class.php:267 includes/litespeed-cache.class.php:267
3742
+ msgid "Notified LiteSpeed Web Server to purge the front page."
3743
  msgstr ""
3744
 
3745
+ #: inc/litespeed-cache.class.php:272 includes/litespeed-cache.class.php:272
3746
+ msgid "Notified LiteSpeed Web Server to purge pages."
3747
  msgstr ""
3748
 
3749
+ #: inc/litespeed-cache.class.php:277 includes/litespeed-cache.class.php:277
3750
+ msgid "Notified LiteSpeed Web Server to purge CSS/JS entries."
3751
  msgstr ""
3752
 
3753
+ #: inc/litespeed-cache.class.php:282 includes/litespeed-cache.class.php:282
3754
+ msgid "Notified LiteSpeed Web Server to purge error pages."
3755
  msgstr ""
3756
 
3757
+ #: inc/litespeed-cache.class.php:288 includes/litespeed-cache.class.php:288
3758
+ msgid "Notified LiteSpeed Web Server to purge all caches."
3759
  msgstr ""
3760
 
3761
+ #: inc/litespeed-cache.class.php:295 includes/litespeed-cache.class.php:295
3762
+ msgid "Notified LiteSpeed Web Server to purge everything."
3763
  msgstr ""
3764
 
3765
+ #: inc/litespeed-cache.class.php:310 includes/litespeed-cache.class.php:310
3766
+ msgid "Notified LiteSpeed Web Server to purge the list."
3767
  msgstr ""
3768
 
3769
+ #: inc/media.class.php:103
3770
+ msgid "LiteSpeed Optimization"
3771
  msgstr ""
3772
 
3773
+ #: inc/media.class.php:127
3774
+ msgid "Disable WebP"
3775
  msgstr ""
3776
 
3777
+ #: inc/media.class.php:132
3778
+ msgid "Enable WebP"
3779
  msgstr ""
3780
 
3781
+ #: inc/media.class.php:150
3782
+ msgid "Restore Original File"
 
 
3783
  msgstr ""
3784
 
3785
+ #: inc/media.class.php:155
3786
+ msgid "Switch To Optimized File"
3787
  msgstr ""
3788
 
3789
+ #: inc/media.class.php:169
3790
+ msgid "WebP saved %s"
3791
+ msgstr ""
3792
+
3793
+ #: inc/media.class.php:178
3794
+ msgid "Original saved %s"
3795
  msgstr ""
3796
 
3797
  #: inc/purge.class.php:64 includes/litespeed-cache-purge.class.php:64
3838
  msgid " %s ago"
3839
  msgstr ""
3840
 
3841
+ #: lib/litespeed/litespeed-crawler.class.php:208
3842
  msgid "Cannot read meta file: %s"
3843
  msgstr ""
3844
 
3845
+ #: lib/litespeed/litespeed-crawler.class.php:213
3846
  msgid "Oh look, there is already another LiteSpeed crawler running!"
3847
  msgstr ""
3848
 
3849
+ #: lib/litespeed/litespeed-crawler.class.php:219
3850
  msgid "Stopped due to load hit the maximum."
3851
  msgstr ""
3852
 
3853
+ #: lib/litespeed/litespeed-crawler.class.php:301
3854
  msgid "Stopped due to error when crawling urls %1$s : %2$s"
3855
  msgstr ""
3856
 
3857
+ #: lib/litespeed/litespeed-crawler.class.php:308
3858
  msgid "Stopped: crawler disabled by the server admin"
3859
  msgstr ""
3860
 
3861
+ #: lib/litespeed/litespeed-crawler.class.php:329
3862
  msgid "Stopped due to exceeding defined Maximum Run Time"
3863
  msgstr ""
3864
 
3865
+ #: lib/litespeed/litespeed-crawler.class.php:346
3866
  msgid "Stopped due to reset meta position"
3867
  msgstr ""
3868
 
3869
+ #: lib/litespeed/litespeed-crawler.class.php:354
3870
  msgid "Stopped due to load over limit"
3871
  msgstr ""
3872
 
3963
  msgid "To test the cart, visit the <a %s>FAQ</a>."
3964
  msgstr ""
3965
 
 
 
 
 
3966
  #. Plugin URI of the plugin/theme
3967
  msgid ""
3968
  "https://www.litespeedtech.com/products/cache-plugins/wordpress-acceleration"
lib/litespeed/litespeed-crawler.class.php CHANGED
@@ -11,6 +11,7 @@ class Litespeed_Crawler
11
  private $_baseUrl ;
12
  private $_sitemap_file ;
13
  private $_meta_file ;
 
14
  private $_run_delay = 500 ;//microseconds
15
  private $_run_duration = 200 ;//seconds
16
  private $_threads_limit = 3 ;
@@ -43,6 +44,17 @@ class Litespeed_Crawler
43
  $this->_meta_file = $this->_sitemap_file . '.meta' ;
44
  }
45
 
 
 
 
 
 
 
 
 
 
 
 
46
  /**
47
  * Set headers for curl request
48
  *
@@ -239,6 +251,34 @@ class Litespeed_Crawler
239
  return $this->_return($end_reason) ;
240
  }
241
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
242
  /**
243
  * Run crawler
244
  *
@@ -267,17 +307,13 @@ class Litespeed_Crawler
267
  if ( stripos($rets[$i], "HTTP/1.1 428 Precondition Required") !== false ) {
268
  return __('Stopped: crawler disabled by the server admin', 'litespeed-cache') ;
269
  }
270
- elseif ( stripos($rets[$i], "X-Litespeed-Cache-Control: no-cache") !== false ) {
 
271
  // Only default visitor crawler needs to add blacklist
272
  if ( $this->_meta[ 'curr_crawler' ] == 0 ) {
273
  $this->_blacklist[] = $url ;
274
  }
275
  }
276
- elseif ( stripos($rets[$i], "HTTP/1.1 200 OK") === false && stripos($rets[$i], "HTTP/1.1 201 Created") === false ){
277
- if ( $this->_meta[ 'curr_crawler' ] == 0 ) {
278
- $this->_blacklist[] = $url ;
279
- }
280
- }
281
  }
282
 
283
  // update offset position
@@ -530,7 +566,8 @@ class Litespeed_Crawler
530
  * Try to enable http2 connection (only available since PHP7+)
531
  * @since 1.9.1
532
  */
533
- if ( defined( 'CURL_HTTP_VERSION_2' ) ) {
 
534
  $options[ CURL_HTTP_VERSION_2 ] = 1 ;
535
  }
536
  else {
11
  private $_baseUrl ;
12
  private $_sitemap_file ;
13
  private $_meta_file ;
14
+ private $_http2 = true ;
15
  private $_run_delay = 500 ;//microseconds
16
  private $_run_duration = 200 ;//seconds
17
  private $_threads_limit = 3 ;
44
  $this->_meta_file = $this->_sitemap_file . '.meta' ;
45
  }
46
 
47
+ /**
48
+ * Set http/2 option for curl request
49
+ *
50
+ * @since 2.0
51
+ * @access public
52
+ */
53
+ public function set_http2( $is_enabled )
54
+ {
55
+ $this->_http2 = $is_enabled ;
56
+ }
57
+
58
  /**
59
  * Set headers for curl request
60
  *
251
  return $this->_return($end_reason) ;
252
  }
253
 
254
+ /**
255
+ * Check returned curl header to find if the status is 200 ok or not
256
+ *
257
+ * @since 2.0
258
+ * @access private
259
+ */
260
+ private function _status_ok_and_cached( $headers )
261
+ {
262
+ if ( stripos( $headers, 'X-Litespeed-Cache-Control: no-cache' ) !== false ) {
263
+ return false ;
264
+ }
265
+
266
+ $_http_status_ok_list = array(
267
+ 'HTTP/1.1 200 OK',
268
+ 'HTTP/1.1 201 Created',
269
+ 'HTTP/2 200',
270
+ 'HTTP/2 201',
271
+ ) ;
272
+
273
+ foreach ( $_http_status_ok_list as $http_status ) {
274
+ if ( stripos( $headers, $http_status ) !== false ) {
275
+ return true ;
276
+ }
277
+ }
278
+
279
+ return false ;
280
+ }
281
+
282
  /**
283
  * Run crawler
284
  *
307
  if ( stripos($rets[$i], "HTTP/1.1 428 Precondition Required") !== false ) {
308
  return __('Stopped: crawler disabled by the server admin', 'litespeed-cache') ;
309
  }
310
+
311
+ if ( ! $this->_status_ok_and_cached( $rets[ $i ] ) ) {
312
  // Only default visitor crawler needs to add blacklist
313
  if ( $this->_meta[ 'curr_crawler' ] == 0 ) {
314
  $this->_blacklist[] = $url ;
315
  }
316
  }
 
 
 
 
 
317
  }
318
 
319
  // update offset position
566
  * Try to enable http2 connection (only available since PHP7+)
567
  * @since 1.9.1
568
  */
569
+ if ( defined( 'CURL_HTTP_VERSION_2' ) && $this->_http2 ) {
570
+ defined( 'LSCWP_LOG' ) && LiteSpeed_Cache_Log::debug( 'Crawler Lib: Enabled HTTP2' ) ;
571
  $options[ CURL_HTTP_VERSION_2 ] = 1 ;
572
  }
573
  else {
litespeed-cache.php CHANGED
@@ -15,7 +15,7 @@
15
  * Plugin Name: LiteSpeed Cache
16
  * Plugin URI: https://www.litespeedtech.com/products/cache-plugins/wordpress-acceleration
17
  * Description: WordPress plugin to connect to LSCache on LiteSpeed Web Server.
18
- * Version: 1.9.1.1
19
  * Author: LiteSpeed Technologies
20
  * Author URI: https://www.litespeedtech.com
21
  * License: GPLv3
15
  * Plugin Name: LiteSpeed Cache
16
  * Plugin URI: https://www.litespeedtech.com/products/cache-plugins/wordpress-acceleration
17
  * Description: WordPress plugin to connect to LSCache on LiteSpeed Web Server.
18
+ * Version: 2.0
19
  * Author: LiteSpeed Technologies
20
  * Author URI: https://www.litespeedtech.com
21
  * License: GPLv3
readme.txt CHANGED
@@ -1,9 +1,9 @@
1
  === LiteSpeed Cache ===
2
  Contributors: LiteSpeedTech
3
- Tags: cache, wp-cache, litespeed, super cache, http2, total cache, wordfence
4
  Requires at least: 4.0
5
  Tested up to: 4.9.4
6
- Stable tag: 1.9.1.1
7
  License: GPLv3
8
  License URI: http://www.gnu.org/licenses/gpl.html
9
 
@@ -25,6 +25,8 @@ LSCWP includes additional optimization features, such as Database Optimization,
25
 
26
  Want to know more about caching in general, and LiteSpeed caching in particular? See [our Caching 101 blog series](https://blog.litespeedtech.com/tag/caching-101/).
27
 
 
 
28
  == Installation ==
29
 
30
  1. Install [LiteSpeed Web Server Enterprise](https://www.litespeedtech.com/products/litespeed-web-server) with LSCache Module, [LiteSpeed Web ADC](https://www.litespeedtech.com/products/litespeed-web-adc), or [OpenLiteSpeed](https://www.litespeedtech.com/open-source/openlitespeed) with cache module [Free].
@@ -244,13 +246,35 @@ Click on the `Advanced View` link at the top of the page, and several more tabs
244
  11. Admin Settings - Thirdparty WooCommerce
245
  12. Admin Management - Purge
246
  13. Admin Management - DB Optimizer
247
- 14. Admin Crawler Status Page
248
- 15. Cache Miss Example
249
- 16. Cache Hit Example
250
- 17. Frontend Adminbar Shortcut
 
251
 
252
  == Changelog ==
253
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
254
  = 1.9.1.1 - February 20 2018 =
255
  * [Hotfix] Removed empty crawler when no role simulation is set.
256
 
1
  === LiteSpeed Cache ===
2
  Contributors: LiteSpeedTech
3
+ Tags: cache, wp-cache, litespeed, super cache, http2, total cache, optimize
4
  Requires at least: 4.0
5
  Tested up to: 4.9.4
6
+ Stable tag: 2.0
7
  License: GPLv3
8
  License URI: http://www.gnu.org/licenses/gpl.html
9
 
25
 
26
  Want to know more about caching in general, and LiteSpeed caching in particular? See [our Caching 101 blog series](https://blog.litespeedtech.com/tag/caching-101/).
27
 
28
+ [Join our Slack community](https://goo.gl/FG9S4N).
29
+
30
  == Installation ==
31
 
32
  1. Install [LiteSpeed Web Server Enterprise](https://www.litespeedtech.com/products/litespeed-web-server) with LSCache Module, [LiteSpeed Web ADC](https://www.litespeedtech.com/products/litespeed-web-adc), or [OpenLiteSpeed](https://www.litespeedtech.com/open-source/openlitespeed) with cache module [Free].
246
  11. Admin Settings - Thirdparty WooCommerce
247
  12. Admin Management - Purge
248
  13. Admin Management - DB Optimizer
249
+ 14. Image Optimization
250
+ 15. Admin Crawler Status Page
251
+ 16. Cache Miss Example
252
+ 17. Cache Hit Example
253
+ 18. Frontend Adminbar Shortcut
254
 
255
  == Changelog ==
256
 
257
+ = 2.0 - Mar 7 2018 =
258
+ * [NEW FEATURE] *Image Optimization* Added level up guidance.
259
+ * [REFACTOR] *Image Optimization* Refactored Image Optimization class.
260
+ * [IAPI] *Image Optimization* New European Image Optimization server (EU2).
261
+ * [IMPROVEMENT] *Image Optimization* Manual pull action continues pulling until complete.
262
+ * [IMPROVEMENT] *CDN* Multiple CDNs can now be randomized for a single resource.
263
+ * [IMPROVEMENT] *Image Optimization* Improved compatibility of long src images.
264
+ * [IMPROVEMENT] *Image Optimization* Reduced runtime load.
265
+ * [IMPROVEMENT] *Image Optimization* Avoid potential loss/reset of notified images status when pulling.
266
+ * [IMPROVEMENT] *Image Optimization* Avoid duplicated optimization for multiple records in Media that have the same image source.
267
+ * [IMPROVEMENT] *Image Optimization* Fixed issue where phantom images continued to show in not-yet-requested queue.
268
+ * [BUGFIX] *Core* Improved compatibility when upgrading outside of WP Admin. (@jikatal @TylorB)
269
+ * [BUGFIX] *Crawler* Improved HTTP/2 compatibility to avoid erroneous blacklisting.
270
+ * [BUGFIX] *Crawler* Changing Delay setting will use server variable for min value validation if set.
271
+ * [UPDATE] *Crawler* Added HTTP/2 protocol switch in the Crawler settings.
272
+ * [UPDATE] Removed unnecessary translation strings.
273
+ * [GUI] Display translated role group name string instead of English values. (@Richard Hordern)
274
+ * [GUI] Added Join LiteSpeed Slack link.
275
+ * [GUI] *Import / Export* Cosmetic changes to Import Settings file field.
276
+ * [INTEGRATION] Improved compatibility with WPML Media for Image Optimization. (@szmigieldesign)
277
+
278
  = 1.9.1.1 - February 20 2018 =
279
  * [Hotfix] Removed empty crawler when no role simulation is set.
280
 
thirdparty/lscwp-3rd-woocommerce.cls.php CHANGED
@@ -855,7 +855,7 @@ class LiteSpeed_Cache_ThirdParty_WooCommerce
855
  </tr>
856
  </tbody></table>
857
  <div class='litespeed-callout-warning'>
858
- <h4>" . __('Note:', 'litespeed-cache') . "</h4>
859
  <i>
860
  " . __('After verifying that the cache works in general, please test the cart.', 'litespeed-cache') . "
861
  " . sprintf(__('To test the cart, visit the <a %s>FAQ</a>.', 'litespeed-cache'), 'href="https://www.litespeedtech.com/support/wiki/doku.php/litespeed_wiki:cache:lscwp:information:configuration" target="_blank"' ) . "
855
  </tr>
856
  </tbody></table>
857
  <div class='litespeed-callout-warning'>
858
+ <h4>" . __('Note', 'litespeed-cache') . ":</h4>
859
  <i>
860
  " . __('After verifying that the cache works in general, please test the cart.', 'litespeed-cache') . "
861
  " . sprintf(__('To test the cart, visit the <a %s>FAQ</a>.', 'litespeed-cache'), 'href="https://www.litespeedtech.com/support/wiki/doku.php/litespeed_wiki:cache:lscwp:information:configuration" target="_blank"' ) . "