Disable admin notices individually - Version 1.1.1

Version Description

  • Added: Compatibility with Learndash
  • Added: Compatibility with Wordpress 4.2 - 5.x
  • Added: Multisite support
  • Added: Minor link style (hide notification forever) changes.
Download this release

Release Info

Developer alexkovalevv
Plugin Icon 128x128 Disable admin notices individually
Version 1.1.1
Comparing to
See all releases

Code changes from version 1.0.6 to 1.1.1

Files changed (185) hide show
  1. admin/ajax/hide-notice.php +36 -40
  2. admin/ajax/restore-notice.php +33 -35
  3. admin/assets/css/notifications-panel.css +65 -65
  4. admin/assets/js/notifications-panel.js +21 -6
  5. admin/boot.php +79 -55
  6. admin/options.php +201 -140
  7. admin/pages/class-pages-more-features.php +27 -0
  8. admin/pages/class-pages-notices.php +113 -0
  9. admin/pages/index.php +2 -0
  10. admin/pages/more-features.php +0 -16
  11. admin/pages/notices.php +0 -102
  12. clearfy.php +54 -0
  13. disable-admin-notices.php +134 -58
  14. includes/3rd-party/class-clearfy-plugin.php +79 -0
  15. includes/class-plugin.php +78 -0
  16. includes/class.plugin.php +0 -135
  17. includes/classes/class-configurate-notices.php +434 -0
  18. includes/classes/class.configurate-notices.php +0 -319
  19. languages/disable-admin-notices-es_ES.mo +0 -0
  20. languages/disable-admin-notices-es_ES.po +182 -0
  21. languages/disable-admin-notices-nl_BE.mo +0 -0
  22. languages/disable-admin-notices-nl_BE.po +173 -0
  23. languages/disable-admin-notices-pt_BR.mo +0 -0
  24. languages/disable-admin-notices-pt_BR.po +181 -0
  25. libs/factory/adverts/boot.php +50 -0
  26. libs/factory/adverts/includes/class-base.php +319 -0
  27. libs/factory/adverts/includes/class-dashboard-widget.php +125 -0
  28. libs/factory/adverts/includes/class-rest-request.php +197 -0
  29. libs/factory/adverts/includes/index.php +2 -0
  30. libs/factory/adverts/index.php +2 -0
  31. libs/factory/adverts/langs/wbcr_factory_adverts_102-ru_RU.mo +0 -0
  32. libs/factory/adverts/langs/wbcr_factory_adverts_102-ru_RU.po +83 -0
  33. libs/factory/bootstrap/assets/css-min/bootstrap.accordion.min.css +1 -1
  34. libs/factory/bootstrap/assets/css-min/bootstrap.blue.min.css +1 -1
  35. libs/factory/bootstrap/assets/css-min/bootstrap.coffee.min.css +1 -1
  36. libs/factory/bootstrap/assets/css-min/bootstrap.core.min.css +2 -2
  37. libs/factory/bootstrap/assets/css-min/bootstrap.ectoplasm.min.css +1 -1
  38. libs/factory/bootstrap/assets/css-min/bootstrap.form-group.min.css +1 -1
  39. libs/factory/bootstrap/assets/css-min/bootstrap.light.min.css +1 -1
  40. libs/factory/bootstrap/assets/css-min/bootstrap.midnight.min.css +1 -1
  41. libs/factory/bootstrap/assets/css-min/bootstrap.ocean.min.css +1 -1
  42. libs/factory/bootstrap/assets/css-min/bootstrap.separator.min.css +1 -1
  43. libs/factory/bootstrap/assets/css-min/bootstrap.sunrise.min.css +1 -1
  44. libs/factory/bootstrap/assets/css-min/control.checkbox.min.css +1 -1
  45. libs/factory/bootstrap/assets/css-min/control.dropdown.min.css +1 -1
  46. libs/factory/bootstrap/assets/css-min/control.multiple-textbox.min.css +1 -1
  47. libs/factory/bootstrap/assets/css-min/holder.more-link.min.css +1 -1
  48. libs/factory/bootstrap/assets/js-min/bootstrap.dropdown.min.js +1 -1
  49. libs/factory/bootstrap/assets/js-min/control.checkbox.min.js +1 -1
  50. libs/factory/bootstrap/assets/js-min/control.dropdown.min.js +1 -1
  51. libs/factory/bootstrap/assets/js-min/control.list.min.js +1 -1
  52. libs/factory/bootstrap/assets/js-min/control.multiple-textbox.min.js +1 -1
  53. libs/factory/bootstrap/boot.php +45 -36
  54. libs/factory/bootstrap/includes/functions.php +253 -259
  55. libs/factory/bootstrap/includes/index.php +2 -0
  56. libs/factory/bootstrap/index.php +2 -0
  57. libs/factory/clearfy/assets/css/clearfy-base.css +181 -0
  58. libs/factory/clearfy/assets/css/clearfy-base.less +170 -0
  59. libs/factory/clearfy/assets/css/license-manager.css +663 -0
  60. libs/factory/clearfy/assets/img/loader.gif +0 -0
  61. libs/factory/clearfy/assets/js/globals.js +203 -0
  62. libs/factory/clearfy/assets/js/license-manager.js +96 -0
  63. libs/factory/clearfy/boot.php +41 -29
  64. libs/factory/clearfy/includes/ajax-handlers.php +92 -0
  65. libs/factory/clearfy/includes/class-configurate.php +116 -0
  66. libs/factory/clearfy/includes/class-helpers.php +362 -0
  67. libs/factory/clearfy/includes/class.configurate.php +0 -67
  68. libs/factory/clearfy/includes/class.helpers.php +0 -180
  69. {admin/assets/css → libs/factory/clearfy/includes}/index.php +0 -0
  70. {admin/assets → libs/factory/clearfy}/index.php +0 -0
  71. libs/factory/clearfy/langs/wbcr_factory_clearfy_200-fr-FR.mo +0 -0
  72. libs/factory/clearfy/langs/wbcr_factory_clearfy_200-fr-FR.po +0 -129
  73. libs/factory/clearfy/langs/wbcr_factory_clearfy_200-ru_RU.mo +0 -0
  74. libs/factory/clearfy/langs/wbcr_factory_clearfy_200-ru_RU.po +0 -124
  75. libs/factory/clearfy/langs/wbcr_factory_clearfy_212-ru_RU.mo +0 -0
  76. libs/factory/clearfy/langs/wbcr_factory_clearfy_212-ru_RU.po +307 -0
  77. libs/factory/clearfy/pages/class-page-license.php +365 -0
  78. libs/factory/clearfy/pages/class-page-more-features.php +170 -0
  79. libs/factory/clearfy/pages/class-pages.php +440 -0
  80. {admin/assets/js → libs/factory/clearfy/pages}/index.php +0 -0
  81. libs/factory/clearfy/pages/more-features.php +0 -148
  82. libs/factory/core/README.md +3 -0
  83. libs/factory/core/boot.php +61 -39
  84. libs/factory/core/includes/activation/activator.class.php +0 -187
  85. libs/factory/core/includes/activation/class-factory-activator.php +43 -0
  86. libs/factory/core/includes/activation/class-factory-update.php +39 -0
  87. libs/factory/core/includes/activation/index.php +2 -0
  88. libs/factory/core/includes/activation/update.class.php +0 -38
  89. libs/factory/core/includes/assets-managment/assets-list.class.php +0 -173
  90. libs/factory/core/includes/assets-managment/class-factory-assets-list.php +126 -0
  91. libs/factory/core/includes/assets-managment/class-factory-script-list.php +166 -0
  92. libs/factory/core/includes/assets-managment/class-factory-style-list.php +86 -0
  93. libs/factory/core/includes/assets-managment/index.php +2 -0
  94. libs/factory/core/includes/assets-managment/script-list.class.php +0 -97
  95. libs/factory/core/includes/assets-managment/style-list.class.php +0 -51
  96. libs/factory/core/includes/base.class.php +0 -378
  97. libs/factory/core/includes/class-check-compatibility.php +122 -0
  98. libs/factory/core/includes/class-factory-migrations.php +541 -0
  99. libs/factory/core/includes/class-factory-notices.php +291 -0
  100. libs/factory/core/includes/class-factory-options.php +432 -0
  101. libs/factory/core/includes/class-factory-plugin-abstract.php +674 -0
  102. libs/factory/core/includes/class-factory-plugin-base.php +519 -0
  103. libs/factory/core/includes/class-factory-requests.php +150 -0
  104. libs/factory/core/includes/class-factory-requirements.php +293 -0
  105. libs/factory/core/includes/entities/class-factory-paths.php +33 -0
  106. libs/factory/core/includes/entities/class-factory-support.php +124 -0
  107. libs/factory/core/includes/functions.php +182 -146
  108. libs/factory/core/includes/index.php +2 -0
  109. libs/factory/core/includes/plugin.class.php +0 -833
  110. libs/factory/core/includes/premium/class-factory-license-interface.php +32 -0
  111. libs/factory/core/includes/premium/class-factory-manager.php +90 -0
  112. libs/factory/core/includes/premium/class-factory-provider-abstract.php +235 -0
  113. libs/factory/core/includes/premium/index.php +2 -0
  114. libs/factory/core/includes/request.class.php +0 -126
  115. libs/factory/core/includes/updates/class-factory-premium-upgrader.php +778 -0
  116. libs/factory/core/includes/updates/class-factory-upgrader.php +313 -0
  117. libs/factory/core/includes/updates/index.php +2 -0
  118. libs/factory/core/includes/updates/repositories/class-factory-repository-abstract.php +62 -0
  119. libs/factory/core/includes/updates/repositories/class-factory-wordpress.php +72 -0
  120. {languages → libs/factory/core/includes/updates/repositories}/index.php +0 -0
  121. libs/factory/core/index.php +2 -0
  122. libs/factory/core/langs/index.php +2 -0
  123. libs/factory/core/langs/wbcr_factory_420-ru_RU.mo +0 -0
  124. libs/factory/core/langs/wbcr_factory_420-ru_RU.po +128 -0
  125. libs/factory/forms/boot.php +252 -250
  126. libs/factory/forms/controls/checkbox.php +4 -4
  127. libs/factory/forms/controls/color-and-opacity.php +4 -4
  128. libs/factory/forms/controls/color.php +2 -2
  129. libs/factory/forms/controls/customs/html.php +2 -2
  130. libs/factory/forms/controls/customs/index.php +2 -0
  131. libs/factory/forms/controls/customs/separator.php +2 -2
  132. libs/factory/forms/controls/datepicker-range.php +4 -4
  133. libs/factory/forms/controls/dropdown-and-colors.php +6 -6
  134. libs/factory/forms/controls/dropdown.php +239 -234
  135. libs/factory/forms/controls/font.php +11 -11
  136. libs/factory/forms/controls/google-font.php +8 -8
  137. libs/factory/forms/controls/gradient.php +4 -4
  138. libs/factory/forms/controls/hidden.php +2 -2
  139. libs/factory/forms/controls/holders/accordion-item.php +2 -2
  140. libs/factory/forms/controls/holders/accordion.php +2 -2
  141. libs/factory/forms/controls/holders/columns.php +2 -2
  142. libs/factory/forms/controls/holders/control-group-item.php +2 -2
  143. libs/factory/forms/controls/holders/control-group.php +3 -3
  144. libs/factory/forms/controls/holders/div.php +2 -2
  145. libs/factory/forms/controls/holders/form-group.php +2 -2
  146. libs/factory/forms/controls/holders/index.php +2 -0
  147. libs/factory/forms/controls/holders/more-link.php +2 -2
  148. libs/factory/forms/controls/holders/tab-item.php +2 -2
  149. libs/factory/forms/controls/holders/tab.php +4 -4
  150. libs/factory/forms/controls/index.php +2 -0
  151. libs/factory/forms/controls/integer.php +2 -2
  152. libs/factory/forms/controls/list.php +4 -4
  153. libs/factory/forms/controls/multiple-textbox.php +3 -3
  154. libs/factory/forms/controls/paddings-editor.php +3 -3
  155. libs/factory/forms/controls/pattern.php +9 -9
  156. libs/factory/forms/controls/radio-colors.php +2 -2
  157. libs/factory/forms/controls/radio.php +2 -2
  158. libs/factory/forms/controls/textarea.php +9 -4
  159. libs/factory/forms/controls/textbox.php +2 -11
  160. libs/factory/forms/controls/url.php +3 -3
  161. libs/factory/forms/controls/wp-editor.php +3 -3
  162. libs/factory/forms/includes/complex-control.class.php +4 -4
  163. libs/factory/forms/includes/control-holder.class.php +5 -5
  164. libs/factory/forms/includes/control.class.php +32 -9
  165. libs/factory/forms/includes/custom-element.class.php +2 -2
  166. libs/factory/forms/includes/form-element.class.php +7 -7
  167. libs/factory/forms/includes/form-layout.class.php +5 -5
  168. libs/factory/forms/includes/form.class.php +49 -53
  169. libs/factory/forms/includes/holder.class.php +6 -6
  170. libs/factory/forms/includes/html-builder.class.php +2 -2
  171. libs/factory/forms/includes/index.php +2 -0
  172. libs/factory/forms/includes/providers/index.php +2 -0
  173. libs/factory/forms/includes/providers/meta-value-provider.class.php +2 -2
  174. libs/factory/forms/includes/providers/options-value-provider.class.php +13 -11
  175. libs/factory/forms/includes/providers/value-provider.interface.php +2 -2
  176. libs/factory/forms/index.php +2 -0
  177. libs/factory/forms/langs/wbcr_factory_forms_400-fr-FR.mo +0 -0
  178. libs/factory/forms/langs/wbcr_factory_forms_400-fr-FR.po +0 -104
  179. libs/factory/forms/langs/{wbcr_factory_forms_400-ru_RU.mo → wbcr_factory_forms_418-ru_RU.mo} +0 -0
  180. libs/factory/forms/langs/{wbcr_factory_forms_400-ru_RU.po → wbcr_factory_forms_418-ru_RU.po} +0 -0
  181. libs/factory/forms/layouts/bootstrap-3/bootstrap-3.php +7 -7
  182. libs/factory/forms/layouts/bootstrap-3/index.php +2 -0
  183. libs/factory/forms/layouts/index.php +2 -0
  184. libs/factory/pages/boot.php +41 -38
  185. libs/factory/pages/includes/admin-page.class.php +463 -356
admin/ajax/hide-notice.php CHANGED
@@ -1,50 +1,46 @@
1
  <?php
2
- /**
3
- * Hides notifications
4
- * @author Webcraftic <wordpress.webraftic@gmail.com>
5
- * @copyright (c) 12.01.2018, Webcraftic
6
- * @version 1.0
7
- */
8
-
9
- // Exit if accessed directly
10
- if( !defined('ABSPATH') ) {
11
- exit;
12
- }
13
-
14
- function wbcr_dan_ajax_hide_notices()
15
- {
16
- check_ajax_referer(WDN_Plugin::app()->getPluginName() . '_ajax_hide_notices_nonce', 'security');
17
-
18
- if( !current_user_can('update_plugins') ) {
19
- echo json_encode(array('error' => __('You don\'t have enough capability to edit this information.', 'disable-admin-notices')));
20
- exit;
21
- }
22
-
23
- $notice_id = isset($_POST['notice_id'])
24
- ? sanitize_text_field($_POST['notice_id'])
25
- : null;
26
-
27
- $notice_html = isset($_POST['notice_html'])
28
- ? wp_kses($_POST['notice_html'], array())
29
- : null;
30
-
31
- if( empty($notice_id) ) {
32
- echo json_encode(array('error' => __('Undefinded notice id.', 'disable-admin-notices')));
33
- exit;
34
  }
35
 
36
- $get_hidden_notices = WDN_Plugin::app()->getOption('hidden_notices');
 
37
 
38
- if( !is_array($get_hidden_notices) ) {
39
- $get_hidden_notices = array();
40
  }
41
 
42
- $get_hidden_notices[$notice_id] = rtrim(trim($notice_html));
43
 
44
- WDN_Plugin::app()->updateOption('hidden_notices', $get_hidden_notices);
45
 
46
- echo json_encode(array('success' => __('Success', 'disable-admin-notices')));
47
- exit;
 
48
  }
 
49
 
50
- add_action('wp_ajax_wbcr_dan_hide_notices', 'wbcr_dan_ajax_hide_notices');
1
  <?php
2
+ /**
3
+ * Hides notifications
4
+ *
5
+ * Github: https://github.com/alexkovalevv
6
+ *
7
+ * @author Alexander Kovalev <alex.kovalevv@gmail.com>
8
+ * @copyright (c) 2018 Webraftic Ltd
9
+ * @version 1.0
10
+ */
11
+
12
+ // Exit if accessed directly
13
+ if ( ! defined( 'ABSPATH' ) ) {
14
+ exit;
15
+ }
16
+
17
+ function wbcr_dan_ajax_hide_notices() {
18
+ check_ajax_referer( WDN_Plugin::app()->getPluginName() . '_ajax_hide_notices_nonce', 'security' );
19
+
20
+ if ( current_user_can( 'manage_options' ) || current_user_can( 'manage_network' ) ) {
21
+ $notice_id = WDN_Plugin::app()->request->post( 'notice_id', null, true );
22
+ $notice_html = WDN_Plugin::app()->request->post( 'notice_html', null );
23
+ $notice_html = wp_kses( $notice_html, [] );
24
+
25
+ if ( empty( $notice_id ) ) {
26
+ wp_send_json_error( [ 'error_message' => __( 'Undefinded notice id.', 'disable-admin-notices' ) ] );
 
 
 
 
 
 
 
27
  }
28
 
29
+ $current_user_id = get_current_user_id();
30
+ $get_hidden_notices = get_user_meta( $current_user_id, WDN_Plugin::app()->getOptionName( 'hidden_notices' ), true );
31
 
32
+ if ( ! is_array( $get_hidden_notices ) ) {
33
+ $get_hidden_notices = [];
34
  }
35
 
36
+ $get_hidden_notices[ $notice_id ] = rtrim( trim( $notice_html ) );
37
 
38
+ update_user_meta( $current_user_id, WDN_Plugin::app()->getOptionName( 'hidden_notices' ), $get_hidden_notices );
39
 
40
+ wp_send_json_success();
41
+ } else {
42
+ wp_send_json_error( [ 'error_message' => __( 'You don\'t have enough capability to edit this information.', 'disable-admin-notices' ) ] );
43
  }
44
+ }
45
 
46
+ add_action( 'wp_ajax_wbcr-dan-hide-notices', 'wbcr_dan_ajax_hide_notices' );
admin/ajax/restore-notice.php CHANGED
@@ -1,44 +1,42 @@
1
  <?php
2
- /**
3
- * Restore notice
4
- * @author Webcraftic <wordpress.webraftic@gmail.com>
5
- * @copyright (c) 12.01.2018, Webcraftic
6
- * @version 1.0
7
- */
8
-
9
- // Exit if accessed directly
10
- if( !defined('ABSPATH') ) {
11
- exit;
12
- }
13
-
14
- function wbcr_dan_ajax_restore_notice()
15
- {
16
- check_ajax_referer(WDN_Plugin::app()->getPluginName() . '_ajax_restore_notice_nonce', 'security');
17
-
18
- if( !current_user_can('update_plugins') ) {
19
- echo json_encode(array('error' => __('You don\'t have enough capability to edit this information.', 'disable-admin-notices')));
20
- exit;
21
- }
22
-
23
- $notice_id = isset($_POST['notice_id'])
24
- ? sanitize_text_field($_POST['notice_id'])
25
- : null;
26
-
27
- if( empty($notice_id) ) {
28
- echo json_encode(array('error' => __('Undefinded notice id.', 'disable-admin-notices')));
29
- exit;
30
  }
31
 
32
- $get_hidden_notices = WDN_Plugin::app()->getOption('hidden_notices');
 
33
 
34
- if( !empty($get_hidden_notices) && isset($get_hidden_notices[$notice_id]) ) {
35
- unset($get_hidden_notices[$notice_id]);
36
  }
37
 
38
- WDN_Plugin::app()->updateOption('hidden_notices', $get_hidden_notices);
39
 
40
- echo json_encode(array('success' => __('Success', 'disable-admin-notices')));
41
- exit;
 
42
  }
 
43
 
44
- add_action('wp_ajax_wbcr_dan_restore_notice', 'wbcr_dan_ajax_restore_notice');
1
  <?php
2
+ /**
3
+ * Restore notice
4
+ *
5
+ * Github: https://github.com/alexkovalevv
6
+ *
7
+ * @author Alexander Kovalev <alex.kovalevv@gmail.com>
8
+ * @copyright (c) 2018 Webraftic Ltd
9
+ * @version 1.0
10
+ */
11
+
12
+ // Exit if accessed directly
13
+ if ( ! defined( 'ABSPATH' ) ) {
14
+ exit;
15
+ }
16
+
17
+ function wbcr_dan_ajax_restore_notice() {
18
+ check_ajax_referer( WDN_Plugin::app()->getPluginName() . '_ajax_restore_notice_nonce', 'security' );
19
+
20
+ if ( current_user_can( 'manage_options' ) || current_user_can( 'manage_network' ) ) {
21
+ $notice_id = WDN_Plugin::app()->request->post( 'notice_id', null, true );
22
+
23
+ if ( empty( $notice_id ) ) {
24
+ wp_send_json_error( [ 'error_message' => __( 'Undefinded notice id.', 'disable-admin-notices' ) ] );
 
 
 
 
 
25
  }
26
 
27
+ $current_user_id = get_current_user_id();
28
+ $get_hidden_notices = get_user_meta( $current_user_id, WDN_Plugin::app()->getOptionName( 'hidden_notices' ), true );
29
 
30
+ if ( ! empty( $get_hidden_notices ) && isset( $get_hidden_notices[ $notice_id ] ) ) {
31
+ unset( $get_hidden_notices[ $notice_id ] );
32
  }
33
 
34
+ update_user_meta( $current_user_id, WDN_Plugin::app()->getOptionName( 'hidden_notices' ), $get_hidden_notices );
35
 
36
+ wp_send_json_success();
37
+ } else {
38
+ wp_send_json_error( [ 'error_message' => __( 'You don\'t have enough capability to edit this information.', 'disable-admin-notices' ) ] );
39
  }
40
+ }
41
 
42
+ add_action( 'wp_ajax_wbcr-dan-restore-notice', 'wbcr_dan_ajax_restore_notice' );
admin/assets/css/notifications-panel.css CHANGED
@@ -1,65 +1,65 @@
1
- /**
2
- * Notification panel in admin bar
3
- * @author Alex Kovalev <alex.kovalevv@gmail.com>
4
- * @copyright Alex Kovalev 23.08.2017
5
- */
6
- #wp-admin-bar-wbcr-han-notify-panel .wbcr-han-adminbar-counter {
7
- background-color: #0073aa;
8
- border-radius: 50%;
9
- color: #fff;
10
- font-weight: bold;
11
- padding: 2px 6px;
12
- font-size: 0.85em;
13
- margin-left: 5px;
14
- }
15
- #wp-admin-bar-wbcr-han-notify-panel .ab-sub-wrapper {
16
- max-height: 500px;
17
- overflow-y: scroll;
18
- }
19
- #wp-admin-bar-wbcr-han-notify-panel .ab-sub-wrapper ul.ab-submenu {
20
- width: 400px;
21
- padding: 0;
22
- }
23
- #wp-admin-bar-wbcr-han-notify-panel .ab-sub-wrapper ul.ab-submenu > li {
24
- border-left: 4px solid #26292b;
25
- padding: 0;
26
- }
27
- #wp-admin-bar-wbcr-han-notify-panel .ab-sub-wrapper ul.ab-submenu > li.wpnc-updated {
28
- border-left-color: #7ad03a;
29
- }
30
- #wp-admin-bar-wbcr-han-notify-panel .ab-sub-wrapper ul.ab-submenu > li.wpnc-update-nag {
31
- border-left-color: #ffba00;
32
- }
33
- #wp-admin-bar-wbcr-han-notify-panel .ab-sub-wrapper ul.ab-submenu > li.wpnc-error {
34
- border-left-color: #dd3d36;
35
- }
36
- #wp-admin-bar-wbcr-han-notify-panel .ab-sub-wrapper ul.ab-submenu > li .wbcr-han-panel-restore-notify-line {
37
- text-align: right;
38
- }
39
- #wp-admin-bar-wbcr-han-notify-panel .ab-sub-wrapper ul.ab-submenu > li .wbcr-han-panel-restore-notify-line a {
40
- color: #ffba00 !important;
41
- text-decoration: none !important;
42
- }
43
- #wp-admin-bar-wbcr-han-notify-panel .ab-sub-wrapper ul.ab-submenu > li .wbcr-han-panel-restore-notify-line a:hover {
44
- text-decoration: underline !important;
45
- color: #ffc11a !important;
46
- }
47
- #wp-admin-bar-wbcr-han-notify-panel .ab-sub-wrapper ul.ab-submenu > li .ab-item {
48
- height: 100% !important;
49
- white-space: normal !important;
50
- padding: .5em 1em;
51
- border-bottom: 1px solid #4a4f55;
52
- color: #949494;
53
- line-height: .5em;
54
- }
55
- #wp-admin-bar-wbcr-han-notify-panel .ab-sub-wrapper ul.ab-submenu > li .ab-item a {
56
- display: inline;
57
- padding: 0;
58
- margin: 0;
59
- text-decoration: underline;
60
- line-height: .5em;
61
- color: #949494;
62
- }
63
- #wp-admin-bar-wbcr-han-notify-panel .ab-sub-wrapper ul.ab-submenu li:nth-child(2n) {
64
- background: #26292b;
65
- }
1
+ /**
2
+ * Notification panel in admin bar
3
+ * @author Alex Kovalev <alex.kovalevv@gmail.com>
4
+ * @copyright Alex Kovalev 23.08.2017
5
+ */
6
+ #wp-admin-bar-wbcr-han-notify-panel .wbcr-han-adminbar-counter {
7
+ background-color: #0073aa;
8
+ border-radius: 50%;
9
+ color: #fff;
10
+ font-weight: bold;
11
+ padding: 2px 6px;
12
+ font-size: 0.85em;
13
+ margin-left: 5px;
14
+ }
15
+ #wp-admin-bar-wbcr-han-notify-panel .ab-sub-wrapper {
16
+ max-height: 500px;
17
+ overflow-y: scroll;
18
+ }
19
+ #wp-admin-bar-wbcr-han-notify-panel .ab-sub-wrapper ul.ab-submenu {
20
+ width: 400px;
21
+ padding: 0;
22
+ }
23
+ #wp-admin-bar-wbcr-han-notify-panel .ab-sub-wrapper ul.ab-submenu > li {
24
+ border-left: 4px solid #26292b;
25
+ padding: 0;
26
+ }
27
+ #wp-admin-bar-wbcr-han-notify-panel .ab-sub-wrapper ul.ab-submenu > li.wpnc-updated {
28
+ border-left-color: #7ad03a;
29
+ }
30
+ #wp-admin-bar-wbcr-han-notify-panel .ab-sub-wrapper ul.ab-submenu > li.wpnc-update-nag {
31
+ border-left-color: #ffba00;
32
+ }
33
+ #wp-admin-bar-wbcr-han-notify-panel .ab-sub-wrapper ul.ab-submenu > li.wpnc-error {
34
+ border-left-color: #dd3d36;
35
+ }
36
+ #wp-admin-bar-wbcr-han-notify-panel .ab-sub-wrapper ul.ab-submenu > li .wbcr-han-panel-restore-notify-line {
37
+ text-align: right;
38
+ }
39
+ #wp-admin-bar-wbcr-han-notify-panel .ab-sub-wrapper ul.ab-submenu > li .wbcr-han-panel-restore-notify-line a {
40
+ color: #ffba00 !important;
41
+ text-decoration: none !important;
42
+ }
43
+ #wp-admin-bar-wbcr-han-notify-panel .ab-sub-wrapper ul.ab-submenu > li .wbcr-han-panel-restore-notify-line a:hover {
44
+ text-decoration: underline !important;
45
+ color: #ffc11a !important;
46
+ }
47
+ #wp-admin-bar-wbcr-han-notify-panel .ab-sub-wrapper ul.ab-submenu > li .ab-item {
48
+ height: 100% !important;
49
+ white-space: normal !important;
50
+ padding: .5em 1em;
51
+ border-bottom: 1px solid #4a4f55;
52
+ color: #949494;
53
+ line-height: .5em;
54
+ }
55
+ #wp-admin-bar-wbcr-han-notify-panel .ab-sub-wrapper ul.ab-submenu > li .ab-item a {
56
+ display: inline;
57
+ padding: 0;
58
+ margin: 0;
59
+ text-decoration: underline;
60
+ line-height: .5em;
61
+ color: #949494;
62
+ }
63
+ #wp-admin-bar-wbcr-han-notify-panel .ab-sub-wrapper ul.ab-submenu li:nth-child(2n) {
64
+ background: #26292b;
65
+ }
admin/assets/js/notifications-panel.js CHANGED
@@ -10,8 +10,10 @@
10
 
11
  $(document).ready(function() {
12
  $(document).on('click', '.wbcr-han-panel-restore-notify-link', function() {
 
13
  var self = $(this),
14
  noticeID = $(this).data('notice-id'),
 
15
  counterEl = $('.wbcr-han-adminbar-counter');
16
 
17
  if( !noticeID ) {
@@ -24,21 +26,34 @@
24
  type: 'post',
25
  dataType: 'json',
26
  data: {
27
- action: 'wbcr_dan_restore_notice',
28
- security: wbcr_dan_ajax_restore_nonce,
29
  notice_id: noticeID
30
  },
31
- success: function(data, textStatus, jqXHR) {
32
- if( data == 'error' && data.error ) {
33
- alert(data.error);
34
- self.closest('li').show();
 
 
 
 
 
 
35
  return;
36
  }
37
 
38
  counterEl.text(counterEl.text() - 1);
39
  self.closest('li').remove();
 
 
 
 
 
40
  }
41
  });
 
 
42
  });
43
  });
44
  })(jQuery);
10
 
11
  $(document).ready(function() {
12
  $(document).on('click', '.wbcr-han-panel-restore-notify-link', function() {
13
+
14
  var self = $(this),
15
  noticeID = $(this).data('notice-id'),
16
+ nonce = $(this).data('nonce'),
17
  counterEl = $('.wbcr-han-adminbar-counter');
18
 
19
  if( !noticeID ) {
26
  type: 'post',
27
  dataType: 'json',
28
  data: {
29
+ action: 'wbcr-dan-restore-notice',
30
+ security: nonce,
31
  notice_id: noticeID
32
  },
33
+ success: function(response) {
34
+ if( !response || !response.success ) {
35
+
36
+ if( response.data.error_message ) {
37
+ console.log(response.data.error_message);
38
+ self.closest('li').show();
39
+ } else {
40
+ console.log(response);
41
+ }
42
+
43
  return;
44
  }
45
 
46
  counterEl.text(counterEl.text() - 1);
47
  self.closest('li').remove();
48
+ },
49
+ error: function(xhr, ajaxOptions, thrownError) {
50
+ console.log(xhr.status);
51
+ console.log(xhr.responseText);
52
+ console.log(thrownError);
53
  }
54
  });
55
+
56
+ return false;
57
  });
58
  });
59
  })(jQuery);
admin/boot.php CHANGED
@@ -1,70 +1,94 @@
1
  <?php
2
- /**
3
- * Admin boot
4
- * @author Webcraftic <wordpress.webraftic@gmail.com>
5
- * @copyright Webcraftic 25.05.2017
6
- * @version 1.0
7
- */
8
-
9
- // Exit if accessed directly
10
- if( !defined('ABSPATH') ) {
11
- exit;
12
- }
13
-
14
- function wbcr_dan_rating_widget_url($page_url, $plugin_name)
15
- {
16
- if( $plugin_name == WDN_Plugin::app()->getPluginName() ) {
17
- return 'https://goo.gl/68ucHp';
18
- }
19
 
20
- return $page_url;
21
- }
22
-
23
- add_filter('wbcr_factory_pages_401_imppage_rating_widget_url', 'wbcr_dan_rating_widget_url', 10, 2);
24
-
25
- function wbcr_dan_group_options($options)
26
- {
27
- $options[] = array(
28
- 'name' => 'hide_admin_notices',
29
- 'title' => __('Hide admin notices', 'disable-admin-notices'),
30
- 'tags' => array(),
31
- 'values' => array('hide_admin_notices' => 'only_selected')
32
- );
33
- $options[] = array(
34
- 'name' => 'show_notices_in_adminbar',
35
- 'title' => __('Enable hidden notices in adminbar', 'disable-admin-notices'),
36
- 'tags' => array()
37
- );
38
-
39
- /*$options[] = array(
40
- 'name' => 'hidden_notices',
41
- 'title' => __('Hidden notices', 'disable-admin-notices'),
42
- 'tags' => array()
43
- );*/
44
-
45
- return $options;
46
- }
47
 
48
- function wbcr_dan_set_plugin_meta($links, $file)
49
- {
50
- if( $file == WDN_PLUGIN_BASE ) {
51
  $url = 'https://clearfy.pro';
52
 
53
- if( get_locale() == 'ru_RU' ) {
54
  $url = 'https://ru.clearfy.pro';
55
  }
56
- $url .= '?utm_source=wordpress.org&utm_campaign=' . WDN_Plugin::app()->getPluginName();
57
- $links[] = '<a href="' . $url . '" style="color: #FF5722;font-weight: bold;" target="_blank">' . __('Get ultimate plugin free', 'disable-admin-notices') . '</a>';
58
  }
59
 
60
  return $links;
61
- }
62
 
63
- add_filter("wbcr_clearfy_group_options", 'wbcr_dan_group_options');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
64
 
65
- if( !defined('LOADING_DISABLE_ADMIN_NOTICES_AS_ADDON') ) {
66
- add_filter('plugin_row_meta', 'wbcr_dan_set_plugin_meta', 10, 2);
67
- }
68
 
 
 
 
 
 
 
 
 
 
 
 
 
 
69
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
70
 
 
 
 
1
  <?php
2
+ /**
3
+ * Файл использует для реализации коротких сниппетов. Обычно сниппеты относятся к интеграции
4
+ * или каким мелким исправлениям и фиксам в интерфейсе этого плагина.
5
+ *
6
+ * Github: https://github.com/alexkovalevv
7
+ *
8
+ * @author Alexander Kovalev <alex.kovalevv@gmail.com>
9
+ * @copyright (c) 2018 Webraftic Ltd
10
+ * @version 1.0
11
+ */
 
 
 
 
 
 
 
12
 
13
+ // Exit if accessed directly
14
+ if ( ! defined( 'ABSPATH' ) ) {
15
+ exit;
16
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
17
 
18
+ if ( ! defined( 'LOADING_DISABLE_ADMIN_NOTICES_AS_ADDON' ) ) {
19
+ add_filter( 'plugin_row_meta', function ( $links, $file ) {
20
+ if ( $file == WDN_PLUGIN_BASE ) {
21
  $url = 'https://clearfy.pro';
22
 
23
+ if ( get_locale() == 'ru_RU' ) {
24
  $url = 'https://ru.clearfy.pro';
25
  }
26
+ $url .= '?utm_source=wordpress.org&utm_campaign=' . WDN_Plugin::app()->getPluginName();
27
+ $links[] = '<a href="' . $url . '" style="color: #FF5722;font-weight: bold;" target="_blank">' . __( 'Get ultimate plugin free', 'disable-admin-notices' ) . '</a>';
28
  }
29
 
30
  return $links;
31
+ }, 10, 2 );
32
 
33
+ /**
34
+ * Изменяем ссылку по умолчанию на собственную в виджете "Голосу за нас".
35
+ *
36
+ * Ссылка ведет на страницу рейтинга в репозитори Wordpress.org
37
+ * https://wordpress.org/support/plugin/disable-admin-notices/reviews/
38
+ *
39
+ * @author Alexander Kovalev <alex.kovalevv@gmail.com>
40
+ * @since 1.0
41
+ *
42
+ * @param string $page_url
43
+ * @param string $plugin_name
44
+ *
45
+ * @return string
46
+ */
47
+ add_filter( 'wbcr_factory_pages_420_imppage_rating_widget_url', function ( $page_url, $plugin_name ) {
48
+ if ( ! defined( 'LOADING_DISABLE_ADMIN_NOTICES_AS_ADDON' ) && ( $plugin_name == WDN_Plugin::app()->getPluginName() ) ) {
49
+ return 'https://goo.gl/68ucHp';
50
+ }
51
 
52
+ return $page_url;
53
+ }, 10, 2 );
 
54
 
55
+ /**
56
+ * Удаляем лишние виджеты из правого сайдбара в интерфейсе плагина
57
+ *
58
+ * - Виджет с премиум рекламой
59
+ * - Виджет с рейтингом
60
+ * - Виджет с маркерами информации
61
+ */
62
+ add_filter( 'wbcr/factory/pages/impressive/widgets', function ( $widgets, $position, $plugin ) {
63
+ if ( WDN_Plugin::app()->getPluginName() == $plugin->getPluginName() && 'right' == $position ) {
64
+ unset( $widgets['business_suggetion'] );
65
+ unset( $widgets['rating_widget'] );
66
+ unset( $widgets['info_widget'] );
67
+ }
68
 
69
+ return $widgets;
70
+ }, 20, 3 );
71
+ } else {
72
+ /**
73
+ * Регистрируем опции плагина в Clearfy, чтобы тот мог совершать манипуляции с опциями этого плагина.
74
+ * Обычно такие манипуляции относятся к быстрым настройкам, сбросу настроек.
75
+ *
76
+ * @author Alexander Kovalev <alex.kovalevv@gmail.com>
77
+ * @since 1.0
78
+ */
79
+ add_filter( "wbcr_clearfy_group_options", function ( $options ) {
80
+ $options[] = [
81
+ 'name' => 'hide_admin_notices',
82
+ 'title' => __( 'Hide admin notices', 'disable-admin-notices' ),
83
+ 'tags' => [],
84
+ 'values' => [ 'hide_admin_notices' => 'only_selected' ]
85
+ ];
86
+ $options[] = [
87
+ 'name' => 'show_notices_in_adminbar',
88
+ 'title' => __( 'Enable hidden notices in adminbar', 'disable-admin-notices' ),
89
+ 'tags' => []
90
+ ];
91
 
92
+ return $options;
93
+ } );
94
+ }
admin/options.php CHANGED
@@ -1,155 +1,216 @@
1
  <?php
2
- /**
3
- * Options for additionally form
4
- * @author Webcraftic <wordpress.webraftic@gmail.com>
5
- * @copyright (c) 21.01.2018, Webcraftic
6
- * @version 1.0
7
- */
8
-
9
- // Exit if accessed directly
10
- if( !defined('ABSPATH') ) {
11
- exit;
12
- }
13
-
14
- /**
15
- * @return array
16
- */
17
- function wbcr_dan_get_plugin_options()
18
- {
19
- $options = array();
20
-
21
- $options[] = array(
22
- 'type' => 'html',
23
- 'html' => '<div class="wbcr-factory-page-group-header">' . '<strong>' . __('Admin notifications, Update nags', 'disable-admin-notices') . '</strong>' . '<p>' . __('Do you know the situation, when some plugin offers you to update to premium, to collect technical data and shows many annoying notices? You are close these notices every now and again but they newly appears and interfere your work with WordPress. Even worse, some plugin’s authors delete “close” button from notices and they shows in your admin panel forever.', 'disable-admin-notices') . '</p>' . '</div>'
24
- );
25
-
26
- $options[] = array(
27
- 'type' => 'dropdown',
28
- 'name' => 'hide_admin_notices',
29
- 'way' => 'buttons',
30
- 'title' => __('Hide admin notices', 'disable-admin-notices'),
31
- 'data' => array(
32
- array(
33
- 'all',
34
- __('All notices', 'disable-admin-notices'),
35
- __('Hide all notices globally.', 'disable-admin-notices')
36
- ),
37
- array(
38
- 'only_selected',
39
- __('Only selected', 'disable-admin-notices'),
40
- __('Hide selected notices only. You will see the link "Hide notification forever" in each notice. Push it and they will not bother you anymore.', 'disable-admin-notices')
41
- ),
42
- array(
43
- 'not_hide',
44
- __("Don't nide", 'disable-admin-notices'),
45
- __('Do not hide notices and do not show “Hide notification forever” link for admin.', 'disable-admin-notices')
46
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
47
  ),
48
- 'layout' => array('hint-type' => 'icon', 'hint-icon-color' => 'green'),
49
- 'hint' => __('Some plugins shows notifications about premium version, data collecting or promote their services. Even if you push close button (that sometimes are impossible), notices are shows again in some time. This option allows you to control notices. Hide them all or each individually. Some plugins shows notifications about premium version, data collecting or promote their services. Even if you push close button (that sometimes are impossible), notices are shows again in some time. This option allows you to control notices. Hide them all or each individually.', 'disable-admin-notices'),
50
- 'default' => 'only_selected',
51
- 'events' => array(
52
- 'all' => array(
53
- 'show' => '.factory-control-hide_admin_notices_user_roles',
54
- 'hide' => '.factory-control-reset_notices_button'
55
- ),
56
- 'only_selected' => array(
57
- 'hide' => '.factory-control-hide_admin_notices_user_roles',
58
- 'show' => '.factory-control-reset_notices_button'
59
- ),
60
- 'not_hide' => array(
61
- 'hide' => '.factory-control-hide_admin_notices_user_roles, .factory-control-reset_notices_button'
62
- )
63
  )
64
- );
65
-
66
- $options[] = array(
67
- 'type' => 'checkbox',
68
- 'way' => 'buttons',
69
- 'name' => 'show_notices_in_adminbar',
70
- 'title' => __('Enable hidden notices in adminbar', 'disable-admin-notices'),
71
- 'layout' => array('hint-type' => 'icon', 'hint-icon-color' => 'green'),
72
- 'hint' => __('By default, the plugin hides all notices, which you specified. If you enable this option, the plugin will collect all hidden notices and show them into the top admin toolbar. It will not disturb you but will allow to look notices at your convenience.', 'disable-admin-notices'),
73
- 'default' => false
74
- );
75
-
76
- $options[] = array(
77
- 'type' => 'html',
78
- 'html' => 'wbcr_dan_reset_notices_button'
79
- );
80
-
81
- $options[] = array(
82
- 'type' => 'separator'
83
- );
84
-
85
- return $options;
86
- }
87
-
88
- /**
89
- * @param $form
90
- * @param $page Wbcr_FactoryPages401_ImpressiveThemplate
91
- * @return mixed
92
- */
93
- function wbcr_dan_additionally_form_options($form, $page)
94
- {
95
- if( empty($form) ) {
96
- return $form;
97
- }
98
-
99
- $options = wbcr_dan_get_plugin_options();
100
-
101
- foreach(array_reverse($options) as $option) {
102
- array_unshift($form[0]['items'], $option);
103
- }
104
-
 
 
 
 
 
 
 
 
 
105
  return $form;
106
  }
107
 
108
- add_filter('wbcr_clr_additionally_form_options', 'wbcr_dan_additionally_form_options', 10, 2);
109
-
110
- /**
111
- * @param $html_builder Wbcr_FactoryForms400_Html
112
- */
113
- function wbcr_dan_reset_notices_button($html_builder)
114
- {
115
- $form_name = $html_builder->getFormName();
116
- $reseted = false;
117
 
118
- if( isset($_POST['wbcr_dan_reset_action']) ) {
119
- check_admin_referer($form_name, 'wbcr_dan_reset_nonce');
120
-
121
- WDN_Plugin::app()->deleteOption('hidden_notices');
122
 
123
- $reseted = true;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
124
  }
125
 
126
- $count_hidden_notices = 0;
127
- $hidden_notices = WDN_Plugin::app()->getOption('hidden_notices');
128
-
129
- if( !empty($hidden_notices) ) {
130
- $count_hidden_notices = sizeof($hidden_notices);
131
- }
132
 
133
- ?>
134
- <div class="form-group form-group-checkbox factory-control-reset_notices_button">
135
- <label for="wbcr_clearfy_reset_notices_button" class="col-sm-6 control-label">
136
- <span class="factory-hint-icon factory-hint-icon-grey" data-toggle="factory-tooltip" data-placement="right" title="" data-original-title="<?php _e('Push reset hidden notices if you need to show hidden notices again.', 'disable-admin-notices') ?>">
 
137
  <img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAkAAAAJCAQAAABKmM6bAAAAUUlEQVQIHU3BsQ1AQABA0X/komIrnQHYwyhqQ1hBo9KZRKL9CBfeAwy2ri42JA4mPQ9rJ6OVt0BisFM3Po7qbEliru7m/FkY+TN64ZVxEzh4ndrMN7+Z+jXCAAAAAElFTkSuQmCC" alt="">
138
  </span>
139
- </label>
140
-
141
- <div class="control-group col-sm-6">
142
- <div class="factory-checkbox factory-from-control-checkbox factory-buttons-way btn-group">
143
- <form method="post">
144
- <?php wp_nonce_field($form_name, 'wbcr_dan_reset_nonce'); ?>
145
- <input type="submit" name="wbcr_dan_reset_action" value="<?php printf(__('Reset hidden notices (%s)', 'disable-admin-notices'), $count_hidden_notices) ?>" class="button button-default"/>
146
- <?php if( $reseted ): ?>
147
- <div style="color:green;margin-top:5px;"><?php _e('Hidden notices are successfully reset, now you can see them again!', 'disable-admin-notices') ?></div>
148
- <?php endif; ?>
149
- </form>
150
- </div>
151
- </div>
152
- </div>
 
 
 
 
 
 
 
153
  <?php
154
- }
155
 
1
  <?php
2
+ /**
3
+ * Регистрируем поля Html формы в Clearfy на странице "Подолнительно". Если этот плагин загружен, как отдельный плагин
4
+ * то поля будет зарегистрированы для страницы общих настроек этого плагина.
5
+ *
6
+ * Github: https://github.com/alexkovalevv
7
+ *
8
+ * @author Alexander Kovalev <alex.kovalevv@gmail.com>
9
+ * @copyright (c) 2018 Webraftic Ltd
10
+ * @version 1.0
11
+ */
12
+
13
+ // Exit if accessed directly
14
+ if ( ! defined( 'ABSPATH' ) ) {
15
+ exit;
16
+ }
17
+
18
+ /**
19
+ * Регистрируем поля Html формы с настройками плагина.
20
+ *
21
+ * Эта функция используется для общей страницы настроек текущего плагина,
22
+ * а также для раширения настроек в плагине Clearfy.
23
+ *
24
+ * @author Alexander Kovalev <alex.kovalevv@gmail.com>
25
+ * @since 1.0
26
+ * @return array Возвращает группу зарегистрируемых опций
27
+ */
28
+ function wbcr_dan_get_plugin_options() {
29
+ $options = [];
30
+
31
+ $options[] = [
32
+ 'type' => 'html',
33
+ 'html' => '<div class="wbcr-factory-page-group-header">' . '<strong>' . __( 'Admin notifications, Update nags', 'disable-admin-notices' ) . '</strong>' . '<p>' . __( 'Do you know the situation, when some plugin offers you to update to premium, to collect technical data and shows many annoying notices? You are close these notices every now and again but they newly appears and interfere your work with WordPress. Even worse, some plugin’s authors delete “close” button from notices and they shows in your admin panel forever.', 'disable-admin-notices' ) . '</p>' . '</div>'
34
+ ];
35
+
36
+ $options[] = [
37
+ 'type' => 'dropdown',
38
+ 'name' => 'hide_admin_notices',
39
+ 'way' => 'buttons',
40
+ 'title' => __( 'Hide admin notices', 'disable-admin-notices' ),
41
+ 'data' => [
42
+ [
43
+ 'all',
44
+ __( 'All notices', 'disable-admin-notices' ),
45
+ __( 'Hide all notices globally.', 'disable-admin-notices' )
46
+ ],
47
+ [
48
+ 'only_selected',
49
+ __( 'Only selected', 'disable-admin-notices' ),
50
+ __( 'Hide selected notices only. You will see the link "Hide notification forever" in each notice. Push it and they will not bother you anymore.', 'disable-admin-notices' )
51
+ ],
52
+ [
53
+ 'not_hide',
54
+ __( "Don't nide", 'disable-admin-notices' ),
55
+ __( 'Do not hide notices and do not show “Hide notification forever” link for admin.', 'disable-admin-notices' )
56
+ ]
57
+ ],
58
+ 'layout' => [ 'hint-type' => 'icon', 'hint-icon-color' => 'green' ],
59
+ 'hint' => __( 'Some plugins shows notifications about premium version, data collecting or promote their services. Even if you push close button (that sometimes are impossible), notices are shows again in some time. This option allows you to control notices. Hide them all or each individually. Some plugins shows notifications about premium version, data collecting or promote their services. Even if you push close button (that sometimes are impossible), notices are shows again in some time. This option allows you to control notices. Hide them all or each individually.', 'disable-admin-notices' ),
60
+ 'default' => 'only_selected',
61
+ 'events' => [
62
+ 'all' => [
63
+ 'show' => '.factory-control-hide_admin_notices_user_roles',
64
+ 'hide' => '.factory-control-reset_notices_button'
65
+ ],
66
+ 'only_selected' => [
67
+ 'hide' => '.factory-control-hide_admin_notices_user_roles',
68
+ 'show' => '.factory-control-reset_notices_button'
69
+ ],
70
+ 'not_hide' => [
71
+ 'hide' => '.factory-control-hide_admin_notices_user_roles, .factory-control-reset_notices_button'
72
+ ]
73
+ ]
74
+ ];
75
+
76
+ /*$options[] = array(
77
+ 'type' => 'dropdown',
78
+ 'name' => 'hide_admin_notices_for',
79
+ 'way' => 'buttons',
80
+ 'title' => __('Hide admin notices only for', 'disable-admin-notices'),
81
+ 'data' => array(
82
+ array(
83
+ 'user',
84
+ __('Current user', 'disable-admin-notices')
85
  ),
86
+ array(
87
+ 'all_users',
88
+ __('All users', 'disable-admin-notices')
 
 
 
 
 
 
 
 
 
 
 
 
89
  )
90
+ ),
91
+ 'layout' => array('hint-type' => 'icon', 'hint-icon-color' => 'green'),
92
+ 'hint' => __('Choose who to hide notifications for?', 'disable-admin-notices'),
93
+ 'default' => 'user',
94
+ 'events' => array(
95
+ 'all' => array(
96
+ 'show' => '.factory-control-hide_admin_notices_user_roles',
97
+ 'hide' => '.factory-control-reset_notices_button'
98
+ ),
99
+ 'only_selected' => array(
100
+ 'hide' => '.factory-control-hide_admin_notices_user_roles',
101
+ 'show' => '.factory-control-reset_notices_button'
102
+ ),
103
+ 'not_hide' => array(
104
+ 'hide' => '.factory-control-hide_admin_notices_user_roles, .factory-control-reset_notices_button'
105
+ )
106
+ )
107
+ );*/
108
+
109
+ $options[] = [
110
+ 'type' => 'checkbox',
111
+ 'way' => 'buttons',
112
+ 'name' => 'show_notices_in_adminbar',
113
+ 'title' => __( 'Enable hidden notices in adminbar', 'disable-admin-notices' ),
114
+ 'layout' => [ 'hint-type' => 'icon', 'hint-icon-color' => 'green' ],
115
+ 'hint' => __( 'By default, the plugin hides all notices, which you specified. If you enable this option, the plugin will collect all hidden notices and show them into the top admin toolbar. It will not disturb you but will allow to look notices at your convenience.', 'disable-admin-notices' ),
116
+ 'default' => false
117
+ ];
118
+
119
+ $options[] = [
120
+ 'type' => 'html',
121
+ 'html' => 'wbcr_dan_reset_notices_button'
122
+ ];
123
+
124
+ return $options;
125
+ }
126
+
127
+ /**
128
+ * Расширяем опции html формы страницы "Дополнительно" в плагине Clearfy
129
+ *
130
+ * Это необходимо для того, чтобы не создавать отдельную страницу в плагине Clearfy, \
131
+ * с настройками этого плагина, потому что это ухудшает юзабилити.
132
+ *
133
+ * @param array $form Массив с группой настроек, страницы "Дополнительно" в плагине Clearfy
134
+ * @param Wbcr_FactoryPages420_ImpressiveThemplate $page Экземпляр страницы
135
+ *
136
+ * @return mixed Отсортированный массив с группой опций
137
+ */
138
+ function wbcr_dan_additionally_form_options( $form, $page ) {
139
+ if ( empty( $form ) ) {
140
  return $form;
141
  }
142
 
143
+ $options = wbcr_dan_get_plugin_options();
 
 
 
 
 
 
 
 
144
 
145
+ foreach ( array_reverse( $options ) as $option ) {
146
+ array_unshift( $form[0]['items'], $option );
147
+ }
 
148
 
149
+ return $form;
150
+ }
151
+
152
+ add_filter( 'wbcr_clr_additionally_form_options', 'wbcr_dan_additionally_form_options', 10, 2 );
153
+
154
+ /**
155
+ * Реализует кнопку сброса скрытых уведомлений.
156
+ *
157
+ * Вы можете выбрать для какой группы пользователей сбросить уведомления.
158
+ * Эта модикация является не стандартной, поэтому мы не можете реалировать ее
159
+ * через фреймворк.
160
+ *
161
+ * @author Alexander Kovalev <alex.kovalevv@gmail.com>
162
+ * @since 1.0
163
+ *
164
+ * @param @param $html_builder Wbcr_FactoryForms418_Html
165
+ */
166
+ function wbcr_dan_reset_notices_button( $html_builder ) {
167
+ global $wpdb;
168
+
169
+ $form_name = $html_builder->getFormName();
170
+ $reseted = false;
171
+
172
+ if ( isset( $_POST['wbcr_dan_reset_action'] ) ) {
173
+ check_admin_referer( $form_name, 'wbcr_dan_reset_nonce' );
174
+ $reset_for_users = WDN_Plugin::app()->request->post( 'wbcr_dan_reset_for_users', 'current_user', true );
175
+
176
+ if ( $reset_for_users == 'current_user' ) {
177
+ delete_user_meta( get_current_user_id(), WDN_Plugin::app()->getOptionName( 'hidden_notices' ) );
178
+ } else {
179
+ $meta_key = sanitize_key( WDN_Plugin::app()->getOptionName( 'hidden_notices' ) );
180
+ $wpdb->query( "DELETE FROM {$wpdb->usermeta} WHERE meta_key = '{$meta_key}'" );
181
  }
182
 
183
+ $reseted = true;
184
+ }
 
 
 
 
185
 
186
+ ?>
187
+ <div class="form-group form-group-checkbox factory-control-reset_notices_button">
188
+ <label for="wbcr_clearfy_reset_notices_button" class="col-sm-4 control-label">
189
+ <?= __( 'Reset hidden notices for', 'disable-admin-notices' ); ?>
190
+ <span class="factory-hint-icon factory-hint-icon-grey" data-toggle="factory-tooltip" data-placement="right" title="" data-original-title="<?php _e( 'Push reset hidden notices if you need to show hidden notices again.', 'disable-admin-notices' ) ?>">
191
  <img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAkAAAAJCAQAAABKmM6bAAAAUUlEQVQIHU3BsQ1AQABA0X/komIrnQHYwyhqQ1hBo9KZRKL9CBfeAwy2ri42JA4mPQ9rJ6OVt0BisFM3Po7qbEliru7m/FkY+TN64ZVxEzh4ndrMN7+Z+jXCAAAAAElFTkSuQmCC" alt="">
192
  </span>
193
+ </label>
194
+ <div class="control-group col-sm-8">
195
+ <div class="factory-checkbox factory-from-control-checkbox factory-buttons-way btn-group">
196
+ <form method="post">
197
+ <?php wp_nonce_field( $form_name, 'wbcr_dan_reset_nonce' ); ?>
198
+ <p>
199
+ <input type="radio" name="wbcr_dan_reset_for_users" value="current_user" checked/> <?= __( 'current user', 'disable-admin-notices' ); ?>
200
+ </p>
201
+ <p>
202
+ <input type="radio" name="wbcr_dan_reset_for_users" value="all"/> <?= __( 'all users', 'disable-admin-notices' ); ?>
203
+ </p>
204
+ <p>
205
+ <input type="submit" name="wbcr_dan_reset_action" value="<?= __( 'Reset notices', 'disable-admin-notices' ); ?>" class="button button-default"/>
206
+ </p>
207
+ <?php if ( $reseted ): ?>
208
+ <div style="color:green;margin-top:5px;"><?php _e( 'Hidden notices are successfully reset, now you can see them again!', 'disable-admin-notices' ) ?></div>
209
+ <?php endif; ?>
210
+ </form>
211
+ </div>
212
+ </div>
213
+ </div>
214
  <?php
215
+ }
216
 
admin/pages/class-pages-more-features.php ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Рекламная страница.
4
+ *
5
+ * Используется для рекламы плагина Clearfy. Пользователь может изучить все возможности плагина Clearfy
6
+ * и перейти на лендинг плагина, чтобы скачать и попробовать его.
7
+ *
8
+ * Может быть использована только, если этот плагин используется как отдельный плагин, а не как аддон
9
+ * для плагина Clearfy. Если плагин загружен, как аддон для Clearfy, эта страница не будет подключена.
10
+ *
11
+ * НЕ поддерживает режим работы с мультисаймами!
12
+ *
13
+ * Github: https://github.com/alexkovalevv
14
+ *
15
+ * @author Alexander Kovalev <alex.kovalevv@gmail.com>
16
+ * @copyright (c) 2018 Webraftic Ltd
17
+ * @version 1.0
18
+ */
19
+
20
+ // Exit if accessed directly
21
+ if ( ! defined( 'ABSPATH' ) ) {
22
+ exit;
23
+ }
24
+
25
+ class WDN_MoreFeaturesPage extends Wbcr_FactoryClearfy212_MoreFeaturesPage {
26
+
27
+ }
admin/pages/class-pages-notices.php ADDED
@@ -0,0 +1,113 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Страница общих настроек для этого плагина.
4
+ *
5
+ * Может быть использована только, если этот плагин используется как отдельный плагин, а не как аддон
6
+ * дя плагина Clearfy. Если плагин загружен, как аддон для Clearfy, эта страница не будет подключена.
7
+ *
8
+ * Поддерживает режим работы с мультисаймами. Вы можете увидеть эту страницу в панели настройки сети.
9
+ *
10
+ * Github: https://github.com/alexkovalevv
11
+ *
12
+ * @author Alexander Kovalev <alex.kovalevv@gmail.com>
13
+ * @copyright (c) 2018 Webraftic Ltd
14
+ * @version 1.0
15
+ */
16
+
17
+ // Exit if accessed directly
18
+ if ( ! defined( 'ABSPATH' ) ) {
19
+ exit;
20
+ }
21
+
22
+ class WDN_NoticesPage extends Wbcr_FactoryClearfy212_PageBase {
23
+
24
+ /**
25
+ * {@inheritDoc}
26
+ *
27
+ * @var string
28
+ */
29
+ public $id = "notices";
30
+
31
+ /**
32
+ * {@inheritDoc}
33
+ *
34
+ * @var string
35
+ */
36
+ public $page_menu_dashicon = 'dashicons-testimonial';
37
+
38
+ /**
39
+ * {@inheritDoc}
40
+ *
41
+ * @var bool
42
+ */
43
+ public $available_for_multisite = true;
44
+
45
+ /**
46
+ * {@inheritDoc}
47
+ *
48
+ * @since 1.1.0
49
+ * @var bool
50
+ */
51
+ public $show_right_sidebar_in_options = true;
52
+
53
+
54
+ /**
55
+ * @param Wbcr_Factory420_Plugin $plugin
56
+ */
57
+ public function __construct( Wbcr_Factory420_Plugin $plugin ) {
58
+ $this->menu_title = __( 'Hide admin notices', 'disable-admin-notices' );
59
+
60
+ $this->internal = false;
61
+ $this->menu_target = 'options-general.php';
62
+ $this->add_link_to_plugin_actions = true;
63
+
64
+ parent::__construct( $plugin );
65
+
66
+ $this->plugin = $plugin;
67
+ }
68
+
69
+ /**
70
+ * {@inheritDoc}
71
+ *
72
+ * @return array
73
+ */
74
+ public function actionsNotice( $notices ) {
75
+ $notices[] = [
76
+ 'conditions' => [
77
+ 'wbcr_dan_reseted_notices' => 1
78
+ ],
79
+ 'type' => 'success',
80
+ 'message' => __( 'Hidden notices are successfully reset, now you can see them again!', 'disable-admin-notices' )
81
+ ];
82
+
83
+ /*$notices[] = array(
84
+ 'conditions' => array(
85
+ 'wbcr_dan_clear_comments_error' => 1,
86
+ 'wbcr_dan_code' => 'interal_error'
87
+ ),
88
+ 'type' => 'danger',
89
+ 'message' => __('An error occurred while trying to delete comments. Internal error occured. Please try again later.', 'factory_pages_420')
90
+ );*/
91
+
92
+ return $notices;
93
+ }
94
+
95
+ /**
96
+ * {@inheritDoc}
97
+ *
98
+ * @return array
99
+ */
100
+ public function getPageOptions() {
101
+ $options = wbcr_dan_get_plugin_options();
102
+
103
+ $formOptions = [];
104
+
105
+ $formOptions[] = [
106
+ 'type' => 'form-group',
107
+ 'items' => $options,
108
+ //'cssClass' => 'postbox'
109
+ ];
110
+
111
+ return apply_filters( 'wbcr_dan_notices_form_options', $formOptions, $this );
112
+ }
113
+ }
admin/pages/index.php CHANGED
@@ -0,0 +1,2 @@
 
 
1
+ <?php
2
+ // Silence is golden.
admin/pages/more-features.php DELETED
@@ -1,16 +0,0 @@
1
- <?php
2
-
3
- /**
4
- * The page Settings.
5
- *
6
- * @since 1.0.0
7
- */
8
-
9
- // Exit if accessed directly
10
- if( !defined('ABSPATH') ) {
11
- exit;
12
- }
13
-
14
- class WDN_MoreFeaturesPage extends Wbcr_FactoryClearfy200_MoreFeaturesPage {
15
-
16
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
admin/pages/notices.php DELETED
@@ -1,102 +0,0 @@
1
- <?php
2
-
3
- /**
4
- * The page Settings.
5
- *
6
- * @since 1.0.0
7
- */
8
-
9
- // Exit if accessed directly
10
- if( !defined('ABSPATH') ) {
11
- exit;
12
- }
13
-
14
- class WDN_NoticesPage extends Wbcr_FactoryPages401_ImpressiveThemplate {
15
-
16
- /**
17
- * The id of the page in the admin menu.
18
- *
19
- * Mainly used to navigate between pages.
20
- * @see FactoryPages401_AdminPage
21
- *
22
- * @since 1.0.0
23
- * @var string
24
- */
25
- public $id = "notices";
26
- public $page_menu_dashicon = 'dashicons-testimonial';
27
-
28
- /**
29
- * @param Wbcr_Factory400_Plugin $plugin
30
- */
31
- public function __construct(Wbcr_Factory400_Plugin $plugin)
32
- {
33
- $this->menu_title = __('Hide admin notices', 'disable-admin-notices');
34
-
35
- if( !defined('LOADING_DISABLE_ADMIN_NOTICES_AS_ADDON') ) {
36
- $this->internal = false;
37
- $this->menu_target = 'options-general.php';
38
- $this->add_link_to_plugin_actions = true;
39
- }
40
-
41
- parent::__construct($plugin);
42
-
43
- $this->plugin = $plugin;
44
- }
45
-
46
- public function getMenuTitle()
47
- {
48
- return defined('LOADING_DISABLE_ADMIN_NOTICES_AS_ADDON')
49
- ? __('Notices', 'disable-admin-notices')
50
- : __('General', 'disable-admin-notices');
51
- }
52
-
53
-
54
- /**
55
- * We register notifications for some actions
56
- * @param array $notices
57
- * @param Wbcr_Factory400_Plugin $plugin
58
- * @return array
59
- */
60
- public function actionsNotice($notices)
61
- {
62
- $notices[] = array(
63
- 'conditions' => array(
64
- 'wbcr_dan_reseted_notices' => 1
65
- ),
66
- 'type' => 'success',
67
- 'message' => __('Hidden notices are successfully reset, now you can see them again!', 'disable-admin-notices')
68
- );
69
-
70
- /*$notices[] = array(
71
- 'conditions' => array(
72
- 'wbcr_dan_clear_comments_error' => 1,
73
- 'wbcr_dan_code' => 'interal_error'
74
- ),
75
- 'type' => 'danger',
76
- 'message' => __('An error occurred while trying to delete comments. Internal error occured. Please try again later.', 'factory_pages_401')
77
- );*/
78
-
79
- return $notices;
80
- }
81
-
82
- /**
83
- * Permalinks options.
84
- *
85
- * @since 1.0.0
86
- * @return mixed[]
87
- */
88
- public function getOptions()
89
- {
90
- $options = wbcr_dan_get_plugin_options();
91
-
92
- $formOptions = array();
93
-
94
- $formOptions[] = array(
95
- 'type' => 'form-group',
96
- 'items' => $options,
97
- //'cssClass' => 'postbox'
98
- );
99
-
100
- return apply_filters('wbcr_dan_notices_form_options', $formOptions, $this);
101
- }
102
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
clearfy.php ADDED
@@ -0,0 +1,54 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Этот файл инициализирует этот плагин, как аддон для плагина Clearfy.
4
+ *
5
+ * Файл будет подключен только в плагине Clearfy, используя особый вариант загрузки. Это более простое решение
6
+ * пришло на смену встроенной системы подключения аддонов в фреймворке.
7
+ *
8
+ * Github: https://github.com/alexkovalevv
9
+ *
10
+ * @author Alexander Kovalev <alex.kovalevv@gmail.com>
11
+ * @copyright (c) 2018 Webraftic Ltd
12
+ * @version 1.0
13
+ */
14
+
15
+ // Exit if accessed directly
16
+ if ( ! defined( 'ABSPATH' ) ) {
17
+ exit;
18
+ }
19
+
20
+ if ( ! defined( 'WDN_PLUGIN_ACTIVE' ) ) {
21
+ define( 'WDN_PLUGIN_VERSION', '1.1.0' );
22
+ define( 'WDN_PLUGIN_ACTIVE', true );
23
+
24
+ // Этот плагин загружен, как аддон для плагина Clearfy
25
+ define( 'LOADING_DISABLE_ADMIN_NOTICES_AS_ADDON', true );
26
+
27
+ if ( ! defined( 'WDN_PLUGIN_DIR' ) ) {
28
+ define( 'WDN_PLUGIN_DIR', dirname( __FILE__ ) );
29
+ }
30
+
31
+ if ( ! defined( 'WDN_PLUGIN_BASE' ) ) {
32
+ define( 'WDN_PLUGIN_BASE', plugin_basename( __FILE__ ) );
33
+ }
34
+
35
+ if ( ! defined( 'WDN_PLUGIN_URL' ) ) {
36
+ define( 'WDN_PLUGIN_URL', plugins_url( null, __FILE__ ) );
37
+ }
38
+
39
+ try {
40
+ // Global scripts
41
+ require_once( WDN_PLUGIN_DIR . '/includes/3rd-party/class-clearfy-plugin.php' );
42
+ new WDN_Plugin();
43
+ } catch( Exception $e ) {
44
+ $wdan_plugin_error_func = function () use ( $e ) {
45
+ $error = sprintf( "The %s plugin has stopped. <b>Error:</b> %s Code: %s", 'Webcraftic Disable Admin Notices', $e->getMessage(), $e->getCode() );
46
+ echo '<div class="notice notice-error"><p>' . $error . '</p></div>';
47
+ };
48
+
49
+ add_action( 'admin_notices', $wdan_plugin_error_func );
50
+ add_action( 'network_admin_notices', $wdan_plugin_error_func );
51
+ }
52
+ }
53
+
54
+
disable-admin-notices.php CHANGED
@@ -1,59 +1,135 @@
1
  <?php
2
- /**
3
- * Plugin Name: Webcraftic Disable Admin Notices Individually
4
- * Plugin URI: https://wordpress.org/plugins/disable-admin-notices/
5
- * Description: Disable admin notices plugin gives you the option to hide updates warnings and inline notices in the admin panel.
6
- * Author: Webcraftic <wordpress.webraftic@gmail.com>
7
- * Version: 1.0.6
8
- * Text Domain: disable-admin-notices
9
- * Domain Path: /languages/
10
- * Author URI: https://clearfy.pro
11
- */
12
-
13
- // Exit if accessed directly
14
- if( !defined('ABSPATH') ) {
15
- exit;
16
- }
17
-
18
- if( defined('WDN_PLUGIN_ACTIVE') || (defined('WCL_PLUGIN_ACTIVE') && !defined('LOADING_DISABLE_ADMIN_NOTICES_AS_ADDON')) ) {
19
- function wbcr_dan_admin_notice_error()
20
- {
21
- ?>
22
- <div class="notice notice-error">
23
- <p><?php _e('We found that you have the "Clearfy - disable unused features" plugin installed, this plugin already has disable comments functions, so you can deactivate plugin "Disable admin notices"!'); ?></p>
24
- </div>
25
- <?php
26
- }
27
-
28
- add_action('admin_notices', 'wbcr_dan_admin_notice_error');
29
-
30
- return;
31
- } else {
32
-
33
- define('WDN_PLUGIN_ACTIVE', true);
34
- define('WDN_PLUGIN_DIR', dirname(__FILE__));
35
- define('WDN_PLUGIN_BASE', plugin_basename(__FILE__));
36
- define('WDN_PLUGIN_URL', plugins_url(null, __FILE__));
37
-
38
-
39
-
40
- if( !defined('LOADING_DISABLE_ADMIN_NOTICES_AS_ADDON') ) {
41
- require_once(WDN_PLUGIN_DIR . '/libs/factory/core/boot.php');
42
- }
43
-
44
- require_once(WDN_PLUGIN_DIR . '/includes/class.plugin.php');
45
-
46
- if( !defined('LOADING_DISABLE_ADMIN_NOTICES_AS_ADDON') ) {
47
-
48
- new WDN_Plugin(__FILE__, array(
49
- 'prefix' => 'wbcr_dan_',
50
- 'plugin_name' => 'wbcr_dan',
51
- 'plugin_title' => __('Webcraftic disable admin notices', 'disable-admin-notices'),
52
- 'plugin_version' => '1.0.6',
53
- 'required_php_version' => '5.2',
54
- 'required_wp_version' => '4.2',
55
- 'plugin_build' => 'free',
56
- 'updates' => WDN_PLUGIN_DIR . '/updates/'
57
- ));
58
- }
59
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  <?php
2
+ /**
3
+ * Plugin Name: Webcraftic Disable Admin Notices Individually
4
+ * Plugin URI: https://webcraftic.com
5
+ * Description: Disable admin notices plugin gives you the option to hide updates warnings and inline notices in the admin panel.
6
+ * Author: Webcraftic <wordpress.webraftic@gmail.com>
7
+ * Version: 1.1.1
8
+ * Text Domain: disable-admin-notices
9
+ * Domain Path: /languages/
10
+ * Author URI: https://webcraftic.com
11
+ * Framework Version: FACTORY_420_VERSION
12
+ */
13
+
14
+ /**
15
+ * Developers who contributions in the development plugin:
16
+ *
17
+ * Alexander Kovalev
18
+ * ---------------------------------------------------------------------------------
19
+ * Full plugin development.
20
+ *
21
+ * Email: alex.kovalevv@gmail.com
22
+ * Personal card: https://alexkovalevv.github.io
23
+ * Personal repo: https://github.com/alexkovalevv
24
+ * ---------------------------------------------------------------------------------
25
+ */
26
+
27
+ // Exit if accessed directly
28
+ if ( ! defined( 'ABSPATH' ) ) {
29
+ exit;
30
+ }
31
+
32
+ /**
33
+ * -----------------------------------------------------------------------------
34
+ * CHECK REQUIREMENTS
35
+ * Check compatibility with php and wp version of the user's site. As well as checking
36
+ * compatibility with other plugins from Webcraftic.
37
+ * -----------------------------------------------------------------------------
38
+ */
39
+
40
+ require_once( dirname( __FILE__ ) . '/libs/factory/core/includes/class-factory-requirements.php' );
41
+
42
+ // @formatter:off
43
+ $wdan_plugin_info = array(
44
+ 'prefix' => 'wbcr_dan_',
45
+ 'plugin_name' => 'wbcr_dan',
46
+ 'plugin_title' => __( 'Webcraftic disable admin notices', 'disable-admin-notices' ),
47
+
48
+ // PLUGIN SUPPORT
49
+ 'support_details' => array(
50
+ 'url' => 'https://webcraftic.com',
51
+ 'pages_map' => array(
52
+ 'support' => 'support', // {site}/support
53
+ 'docs' => 'docs' // {site}/docs
54
+ )
55
+ ),
56
+
57
+ // PLUGIN ADVERTS
58
+ 'render_adverts' => true,
59
+ 'adverts_settings' => array(
60
+ 'dashboard_widget' => true, // show dashboard widget (default: false)
61
+ 'right_sidebar' => true, // show adverts sidebar (default: false)
62
+ 'notice' => true, // show notice message (default: false)
63
+ ),
64
+
65
+ // FRAMEWORK MODULES
66
+ 'load_factory_modules' => array(
67
+ array( 'libs/factory/bootstrap', 'factory_bootstrap_421', 'admin' ),
68
+ array( 'libs/factory/forms', 'factory_forms_418', 'admin' ),
69
+ array( 'libs/factory/pages', 'factory_pages_420', 'admin' ),
70
+ array( 'libs/factory/clearfy', 'factory_clearfy_212', 'all' ),
71
+ array( 'libs/factory/adverts', 'factory_adverts_102', 'admin')
72
+ )
73
+ );
74
+
75
+ $wdan_compatibility = new Wbcr_Factory420_Requirements( __FILE__, array_merge( $wdan_plugin_info, array(
76
+ 'plugin_already_activate' => defined( 'WDN_PLUGIN_ACTIVE' ),
77
+ 'required_php_version' => '5.4',
78
+ 'required_wp_version' => '4.2.0',
79
+ 'required_clearfy_check_component' => false
80
+ ) ) );
81
+
82
+
83
+ /**
84
+ * If the plugin is compatible, then it will continue its work, otherwise it will be stopped,
85
+ * and the user will throw a warning.
86
+ */
87
+ if ( ! $wdan_compatibility->check() ) {
88
+ return;
89
+ }
90
+
91
+ /**
92
+ * -----------------------------------------------------------------------------
93
+ * CONSTANTS
94
+ * Install frequently used constants and constants for debugging, which will be
95
+ * removed after compiling the plugin.
96
+ * -----------------------------------------------------------------------------
97
+ */
98
+
99
+ // This plugin is activated
100
+ define( 'WDN_PLUGIN_ACTIVE', true );
101
+ define( 'WDN_PLUGIN_VERSION', $wdan_compatibility->get_plugin_version() );
102
+ define( 'WDN_PLUGIN_DIR', dirname( __FILE__ ) );
103
+ define( 'WDN_PLUGIN_BASE', plugin_basename( __FILE__ ) );
104
+ define( 'WDN_PLUGIN_URL', plugins_url( null, __FILE__ ) );
105
+
106
+
107
+
108
+
109
+ /**
110
+ * -----------------------------------------------------------------------------
111
+ * PLUGIN INIT
112
+ * -----------------------------------------------------------------------------
113
+ */
114
+
115
+ require_once( WDN_PLUGIN_DIR . '/libs/factory/core/boot.php' );
116
+ require_once( WDN_PLUGIN_DIR . '/includes/class-plugin.php' );
117
+
118
+ try {
119
+ new WDN_Plugin( __FILE__, array_merge( $wdan_plugin_info, array(
120
+ 'plugin_version' => WDN_PLUGIN_VERSION,
121
+ 'plugin_text_domain' => $wdan_compatibility->get_text_domain(),
122
+ ) ) );
123
+ } catch( Exception $e ) {
124
+ // Plugin wasn't initialized due to an error
125
+ define( 'WDN_PLUGIN_THROW_ERROR', true );
126
+
127
+ $wdan_plugin_error_func = function () use ( $e ) {
128
+ $error = sprintf( "The %s plugin has stopped. <b>Error:</b> %s Code: %s", 'Webcraftic Disable Admin Notices', $e->getMessage(), $e->getCode() );
129
+ echo '<div class="notice notice-error"><p>' . $error . '</p></div>';
130
+ };
131
+
132
+ add_action( 'admin_notices', $wdan_plugin_error_func );
133
+ add_action( 'network_admin_notices', $wdan_plugin_error_func );
134
+ }
135
+ // @formatter:on
includes/3rd-party/class-clearfy-plugin.php ADDED
@@ -0,0 +1,79 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Disable admin notices core class
4
+ *
5
+ * Github: https://github.com/alexkovalevv
6
+ *
7
+ * @author Alexander Kovalev <alex.kovalevv@gmail.com>
8
+ * @copyright (c) 2018 Webraftic Ltd
9
+ * @version 1.0
10
+ */
11
+
12
+ // Exit if accessed directly
13
+ if ( ! defined( 'ABSPATH' ) ) {
14
+ exit;
15
+ }
16
+
17
+ class WDN_Plugin {
18
+
19
+ /**
20
+ * @var WCL_Plugin
21
+ */
22
+ private static $app;
23
+
24
+ /**
25
+ * Конструктор
26
+ * Вы
27
+ *
28
+ * @author Alexander Kovalev <alex.kovalevv@gmail.com>
29
+ * @throws \Exception
30
+ */
31
+ public function __construct() {
32
+ if ( ! class_exists( 'WCL_Plugin' ) ) {
33
+ throw new Exception( 'Plugin Clearfy is not installed!' );
34
+ }
35
+
36
+ self::$app = WCL_Plugin::app();
37
+
38
+ $this->globalScripts();
39
+
40
+ if ( is_admin() ) {
41
+ $this->adminScripts();
42
+ }
43
+ }
44
+
45
+ /**
46
+ * @return WCL_Plugin
47
+ */
48
+ public static function app() {
49
+ return self::$app;
50
+ }
51
+
52
+ /**
53
+ * Выполняет сценарии, которые должны быть запущены только в бекенде
54
+ *
55
+ * @author Alexander Kovalev <alex.kovalevv@gmail.com>
56
+ * @since 1.1.0
57
+ */
58
+ private function adminScripts() {
59
+ require( WDN_PLUGIN_DIR . '/admin/options.php' );
60
+
61
+ if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) {
62
+ require( WDN_PLUGIN_DIR . '/admin/ajax/hide-notice.php' );
63
+ require( WDN_PLUGIN_DIR . '/admin/ajax/restore-notice.php' );
64
+ }
65
+
66
+ require( WDN_PLUGIN_DIR . '/admin/boot.php' );
67
+ }
68
+
69
+ /**
70
+ * Выполняет сценрии, которые должны быть запущены глобально
71
+ *
72
+ * @author Alexander Kovalev <alex.kovalevv@gmail.com>
73
+ * @since 1.1.0
74
+ */
75
+ private function globalScripts() {
76
+ require( WDN_PLUGIN_DIR . '/includes/classes/class-configurate-notices.php' );
77
+ new WDN_ConfigHideNotices( self::$app );
78
+ }
79
+ }
includes/class-plugin.php ADDED
@@ -0,0 +1,78 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Disable admin notices core class
4
+ *
5
+ * @author Alexander Kovalev <alex.kovalevv@gmail.com>
6
+ * Github: https://github.com/alexkovalevv
7
+ * @copyright (c) 2018 Webraftic Ltd
8
+ * @version 1.0
9
+ */
10
+
11
+ // Exit if accessed directly
12
+ //use WBCR\Factory_Adverts_102\Base;
13
+
14
+ if ( ! defined( 'ABSPATH' ) ) {
15
+ exit;
16
+ }
17
+
18
+ class WDN_Plugin extends Wbcr_Factory420_Plugin {
19
+
20
+ /**
21
+ * @var Wbcr_Factory420_Plugin
22
+ */
23
+ private static $app;
24
+ private $plugin_data;
25
+
26
+
27
+ /**
28
+ * @param string $plugin_path
29
+ * @param array $data
30
+ *
31
+ * @throws Exception
32
+ */
33
+ public function __construct( $plugin_path, $data ) {
34
+ parent::__construct( $plugin_path, $data );
35
+
36
+ self::$app = $this;
37
+ $this->plugin_data = $data;
38
+
39
+ $this->global_scripts();
40
+
41
+ if ( is_admin() ) {
42
+ $this->admin_scripts();
43
+ }
44
+ }
45
+
46
+ /**
47
+ * @return Wbcr_Factory420_Plugin
48
+ */
49
+ public static function app() {
50
+ return self::$app;
51
+ }
52
+
53
+ private function registerPages() {
54
+ if ( $this->as_addon ) {
55
+ return;
56
+ }
57
+
58
+ self::app()->registerPage( 'WDN_NoticesPage', WDN_PLUGIN_DIR . '/admin/pages/class-pages-notices.php' );
59
+ self::app()->registerPage( 'WDN_MoreFeaturesPage', WDN_PLUGIN_DIR . '/admin/pages/class-pages-more-features.php' );
60
+ }
61
+
62
+ private function admin_scripts() {
63
+ require( WDN_PLUGIN_DIR . '/admin/options.php' );
64
+
65
+ if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) {
66
+ require( WDN_PLUGIN_DIR . '/admin/ajax/hide-notice.php' );
67
+ require( WDN_PLUGIN_DIR . '/admin/ajax/restore-notice.php' );
68
+ }
69
+
70
+ require( WDN_PLUGIN_DIR . '/admin/boot.php' );
71
+ $this->registerPages();
72
+ }
73
+
74
+ private function global_scripts() {
75
+ require( WDN_PLUGIN_DIR . '/includes/classes/class-configurate-notices.php' );
76
+ new WDN_ConfigHideNotices( self::$app );
77
+ }
78
+ }
includes/class.plugin.php DELETED
@@ -1,135 +0,0 @@
1
- <?php
2
- /**
3
- * Hide my wp core class
4
- * @author Webcraftic <wordpress.webraftic@gmail.com>
5
- * @copyright (c) 19.02.2018, Webcraftic
6
- * @version 1.0
7
- */
8
-
9
- // Exit if accessed directly
10
- if( !defined('ABSPATH') ) {
11
- exit;
12
- }
13
-
14
- if( !class_exists('WDN_Plugin') ) {
15
-
16
- if( !class_exists('WDN_PluginFactory') ) {
17
- if( defined('LOADING_DISABLE_ADMIN_NOTICES_AS_ADDON') ) {
18
- class WDN_PluginFactory {
19
-
20
- }
21
- } else {
22
- class WDN_PluginFactory extends Wbcr_Factory400_Plugin {
23
-
24
- }
25
- }
26
- }
27
-
28
- class WDN_Plugin extends WDN_PluginFactory {
29
-
30
- /**
31
- * @var Wbcr_Factory400_Plugin
32
- */
33
- private static $app;
34
-
35
- /**
36
- * @var bool
37
- */
38
- private $as_addon;
39
-
40
- /**
41
- * @param string $plugin_path
42
- * @param array $data
43
- * @throws Exception
44
- */
45
- public function __construct($plugin_path, $data)
46
- {
47
- $this->as_addon = isset($data['as_addon']);
48
-
49
- if( $this->as_addon ) {
50
- $plugin_parent = isset($data['plugin_parent'])
51
- ? $data['plugin_parent']
52
- : null;
53
-
54
- if( !($plugin_parent instanceof Wbcr_Factory400_Plugin) ) {
55
- throw new Exception('An invalid instance of the class was passed.');
56
- }
57
-
58
- self::$app = $plugin_parent;
59
- } else {
60
- self::$app = $this;
61
- }
62
-
63
- if( !$this->as_addon ) {
64
- parent::__construct($plugin_path, $data);
65
- }
66
-
67
- $this->setTextDomain();
68
- $this->setModules();
69
-
70
- $this->globalScripts();
71
-
72
- if( is_admin() ) {
73
- $this->adminScripts();
74
- }
75
- }
76
-
77
- /**
78
- * @return Wbcr_Factory400_Plugin
79
- */
80
- public static function app()
81
- {
82
- return self::$app;
83
- }
84
-
85
- protected function setTextDomain()
86
- {
87
- // Localization plugin
88
- load_plugin_textdomain('disable-admin-notices', false, dirname(WDN_PLUGIN_BASE) . '/languages/');
89
- }
90
-
91
- protected function setModules()
92
- {
93
- if( !$this->as_addon ) {
94
- self::app()->load(array(
95
- array('libs/factory/bootstrap', 'factory_bootstrap_400', 'admin'),
96
- array('libs/factory/forms', 'factory_forms_400', 'admin'),
97
- array('libs/factory/pages', 'factory_pages_401', 'admin'),
98
- array('libs/factory/clearfy', 'factory_clearfy_200', 'all')
99
- ));
100
- }
101
- }
102
-
103
- private function registerPages()
104
- {
105
- if( $this->as_addon ) {
106
- return;
107
- }
108
- self::app()->registerPage('WDN_NoticesPage', WDN_PLUGIN_DIR . '/admin/pages/notices.php');
109
- self::app()->registerPage('WDN_MoreFeaturesPage', WDN_PLUGIN_DIR . '/admin/pages/more-features.php');
110
- }
111
-
112
- private function adminScripts()
113
- {
114
- require(WDN_PLUGIN_DIR . '/admin/options.php');
115
-
116
- if( defined('DOING_AJAX') && DOING_AJAX && isset($_REQUEST['action']) && $_REQUEST['action'] == 'wbcr_dan_hide_notices' ) {
117
- require(WDN_PLUGIN_DIR . '/admin/ajax/hide-notice.php');
118
- }
119
-
120
- if( defined('DOING_AJAX') && DOING_AJAX && isset($_REQUEST['action']) && $_REQUEST['action'] == 'wbcr_dan_restore_notice' ) {
121
- require(WDN_PLUGIN_DIR . '/admin/ajax/restore-notice.php');
122
- }
123
-
124
- require(WDN_PLUGIN_DIR . '/admin/boot.php');
125
-
126
- $this->registerPages();
127
- }
128
-
129
- private function globalScripts()
130
- {
131
- require(WDN_PLUGIN_DIR . '/includes/classes/class.configurate-notices.php');
132
- new WDN_ConfigHideNotices(self::$app);
133
- }
134
- }
135
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/classes/class-configurate-notices.php ADDED
@@ -0,0 +1,434 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * This class configures hide admin notices
5
+ *
6
+ * Github: https://github.com/alexkovalevv
7
+ *
8
+ * @author Alexander Kovalev <alex.kovalevv@gmail.com>
9
+ * @copyright (c) 2018 Webraftic Ltd
10
+ * @version 1.0
11
+ */
12
+
13
+ // Exit if accessed directly
14
+ if ( ! defined( 'ABSPATH' ) ) {
15
+ exit;
16
+ }
17
+
18
+ class WDN_ConfigHideNotices extends Wbcr_FactoryClearfy212_Configurate {
19
+
20
+ public function registerActionsAndFilters() {
21
+ if ( is_admin() ) {
22
+ $hide_notices_type = $this->getPopulateOption( 'hide_admin_notices' );
23
+
24
+ if ( $hide_notices_type != 'not_hide' ) {
25
+ add_action( 'admin_print_scripts', [ $this, 'catchNotices' ], 999 );
26
+
27
+ if ( empty( $hide_notices_type ) || $hide_notices_type == 'only_selected' ) {
28
+ add_action( 'admin_head', [ $this, 'printNotices' ], 999 );
29
+ }
30
+
31
+ if ( ! empty( $hide_notices_type ) ) {
32
+ add_action( 'admin_bar_menu', [ $this, 'notificationsPanel' ], 999 );
33
+ add_action( 'admin_enqueue_scripts', [ $this, 'notificationsPanelStyles' ] );
34
+ }
35
+ }
36
+ }
37
+ }
38
+
39
+ public function printNotices() {
40
+ if ( is_multisite() && is_network_admin() ) {
41
+ add_action( 'network_admin_notices', [ $this, 'noticesCollection' ] );
42
+ } else {
43
+ add_action( 'admin_notices', [ $this, 'noticesCollection' ] );
44
+ }
45
+ }
46
+
47
+
48
+ public function notificationsPanelStyles() {
49
+ if ( ! $this->getPopulateOption( 'show_notices_in_adminbar', false ) && current_user_can( 'manage_network' ) ) {
50
+ return;
51
+ }
52
+
53
+ wp_enqueue_style( 'wbcr-notification-panel-styles', WDN_PLUGIN_URL . '/admin/assets/css/notifications-panel.css', [], $this->plugin->getPluginVersion() );
54
+ wp_enqueue_script( 'wbcr-notification-panel-scripts', WDN_PLUGIN_URL . '/admin/assets/js/notifications-panel.js', [], $this->plugin->getPluginVersion() );
55
+ }
56
+
57
+ public function notificationsPanel( &$wp_admin_bar ) {
58
+ if ( ! $this->getPopulateOption( 'show_notices_in_adminbar', false ) ) {
59
+ return;
60
+ }
61
+
62
+ if ( current_user_can( 'manage_options' ) || current_user_can( 'manage_network' ) ) {
63
+ $titles = [];
64
+
65
+ $notifications = get_user_meta( get_current_user_id(), WDN_Plugin::app()->getOptionName( 'hidden_notices' ), true );
66
+
67
+ if ( empty( $notifications ) ) {
68
+ return;
69
+ }
70
+
71
+ $cont_notifications = sizeof( $notifications );
72
+
73
+ // Add top menu
74
+ $wp_admin_bar->add_menu( [
75
+ 'id' => 'wbcr-han-notify-panel',
76
+ 'parent' => 'top-secondary',
77
+ 'title' => sprintf( __( 'Notifications %s', 'disable-admin-notices' ), '<span class="wbcr-han-adminbar-counter">' . $cont_notifications . '</span>' ),
78
+ 'href' => false
79
+ ] );
80
+
81
+ // loop
82
+ if ( ! empty( $notifications ) ) {
83
+ $i = 0;
84
+ foreach ( $notifications as $notice_id => $message ) {
85
+ $message = $this->getExcerpt( stripslashes( $message ), 0, 350 );
86
+ $message .= '<div class="wbcr-han-panel-restore-notify-line">';
87
+ $message .= '<a href="#" data-nonce="' . wp_create_nonce( $this->plugin->getPluginName() . '_ajax_restore_notice_nonce' );
88
+ $message .= '" data-notice-id="' . esc_attr( $notice_id ) . '" class="wbcr-han-panel-restore-notify-link">';
89
+ $message .= __( 'Restore notice', 'clearfy' ) . ( isset( $titles[ $notice_id ] ) ? ' (' . $titles[ $notice_id ] . ')' : '' );
90
+ $message .= '</a></div>';
91
+
92
+ $wp_admin_bar->add_menu( [
93
+ 'id' => 'wbcr-han-notify-panel-item-' . $i,
94
+ 'parent' => 'wbcr-han-notify-panel',
95
+ 'title' => $message,
96
+ 'href' => false,
97
+ 'meta' => [
98
+ 'class' => ''
99
+ ]
100
+ ] );
101
+
102
+ $i ++;
103
+ }
104
+ }
105
+ }
106
+ }
107
+
108
+ public function noticesCollection() {
109
+ global $wbcr_dan_plugin_all_notices;
110
+
111
+ if ( empty( $wbcr_dan_plugin_all_notices ) ) {
112
+ return;
113
+ }
114
+ ?>
115
+ <!-- Disable admin notices plugin (Clearfy tools) -->
116
+ <style>
117
+ .wbcr-dan-hide-notices {
118
+ position: initial;
119
+ padding: 5px 5px 0;
120
+ background: transparent;
121
+ }
122
+
123
+ .wbcr-dan-hide-notices > div {
124
+ margin: 0 !important;
125
+ }
126
+
127
+ .wbcr-dan-hide-notice-link {
128
+ display: block;
129
+ text-align: right;
130
+ margin: 5px 0 5px 5px;
131
+ font-weight: bold;
132
+ color: #F44336;
133
+ }
134
+
135
+ .is-dismissible .wbcr-dan-hide-notice-link {
136
+ margin-right: -30px;
137
+ }
138
+
139
+ .wbcr-dan-hide-notice-link:active, .wbcr-dan-hide-notice-link:focus {
140
+ box-shadow: none;
141
+ outline: none;
142
+ }
143
+ </style>
144
+ <!-- Disable admin notices plugin (Clearfy tools) -->
145
+ <script>
146
+ jQuery(document).ready(function($) {
147
+ $(document).on('click', '.wbcr-dan-hide-notice-link', function() {
148
+ var self = $(this),
149
+ noticeID = self.data('notice-id'),
150
+ nonce = self.data('nonce'),
151
+ noticeHtml = self.closest('.wbcr-dan-hide-notices').clone(),
152
+ contanierEl = self.closest('.wbcr-dan-hide-notices').parent();
153
+
154
+ noticeHtml.find('.wbcr-dan-hide-notice-link').remove();
155
+
156
+ if( !noticeID ) {
157
+ alert('Undefinded error. Please report the bug to our support forum.');
158
+ }
159
+
160
+ contanierEl.hide();
161
+
162
+ $.ajax(ajaxurl, {
163
+ type: 'post',
164
+ dataType: 'json',
165
+ data: {
166
+ action: 'wbcr-dan-hide-notices',
167
+ security: nonce,
168
+ notice_id: noticeID,
169
+ notice_html: noticeHtml.html()
170
+ },
171
+ success: function(response) {
172
+ if( !response || !response.success ) {
173
+
174
+ if( response.data.error_message ) {
175
+ console.log(response.data.error_message);
176
+ self.closest('li').show();
177
+ } else {
178
+ console.log(response);
179
+ }
180
+
181
+ contanierEl.show();
182
+ return;
183
+ }
184
+
185
+ contanierEl.remove();
186
+ },
187
+ error: function(xhr, ajaxOptions, thrownError) {
188
+ console.log(xhr.status);
189
+ console.log(xhr.responseText);
190
+ console.log(thrownError);
191
+ }
192
+ });
193
+
194
+ return false;
195
+ });
196
+ });
197
+ </script>
198
+ <?php
199
+ foreach ( $wbcr_dan_plugin_all_notices as $val ) {
200
+ echo $val;
201
+ }
202
+ }
203
+
204
+ public function catchNotices() {
205
+ global $wbcr_dan_plugin_all_notices;
206
+
207
+ try {
208
+ if ( is_multisite() && is_network_admin() ) {
209
+ $wp_filter_admin_notices = &$this->getWPFilter( 'network_admin_notices' );
210
+ } else {
211
+ $wp_filter_admin_notices = &$this->getWPFilter( 'admin_notices' );
212
+ }
213
+ //todo: Доработать all admin notices
214
+
215
+ } catch( Exception $e ) {
216
+ $wp_filter_admin_notices = null;
217
+ }
218
+
219
+ $hide_notices_type = $this->getPopulateOption( 'hide_admin_notices' );
220
+
221
+ if ( empty( $hide_notices_type ) || $hide_notices_type == 'only_selected' ) {
222
+ $get_hidden_notices = get_user_meta( get_current_user_id(), WDN_Plugin::app()->getOptionName( 'hidden_notices' ), true );
223
+
224
+ $content = [];
225
+ foreach ( (array) $wp_filter_admin_notices as $filters ) {
226
+ foreach ( $filters as $callback_name => $callback ) {
227
+
228
+ if ( 'usof_hide_admin_notices_start' == $callback_name || 'usof_hide_admin_notices_end' == $callback_name ) {
229
+ continue;
230
+ }
231
+
232
+ ob_start();
233
+
234
+ // #CLRF-140 fix bug for php7
235
+ // when the developers forgot to delete the argument in the function of implementing the notification.
236
+ $args = [];
237
+ $accepted_args = isset( $callback['accepted_args'] ) && ! empty( $callback['accepted_args'] ) ? $callback['accepted_args'] : 0;
238
+
239
+ if ( $accepted_args > 0 ) {
240
+ for ( $i = 0; $i < (int) $accepted_args; $i ++ ) {
241
+ $args[] = null;
242
+ }
243
+ }
244
+ //===========
245
+
246
+ call_user_func_array( $callback['function'], $args );
247
+ $cont = ob_get_clean();
248
+
249
+ if ( empty( $cont ) ) {
250
+ continue;
251
+ }
252
+
253
+ $salt = is_multisite() ? get_current_blog_id() : '';
254
+ $uniq_id1 = md5( $cont . $salt );
255
+ $uniq_id2 = md5( $callback_name . $salt );
256
+
257
+ if ( is_array( $callback['function'] ) && sizeof( $callback['function'] ) == 2 ) {
258
+ $class = $callback['function'][0];
259
+ if ( is_object( $class ) ) {
260
+ $class_name = get_class( $class );
261
+ $method_name = $callback['function'][1];
262
+ $uniq_id2 = md5( $class_name . ':' . $method_name );
263
+ }
264
+ }
265
+ //838339d1a188e17fec838c2df3058603
266
+ //838339d1a188e17fec838c2df3058603
267
+ if ( ! empty( $get_hidden_notices ) ) {
268
+
269
+ $skip_notice = true;
270
+ foreach ( (array) $get_hidden_notices as $key => $notice ) {
271
+ $splited_notice_id = explode( '_', $key );
272
+ if ( empty( $splited_notice_id ) || sizeof( $splited_notice_id ) < 2 ) {
273
+ continue;
274
+ }
275
+ $compare_notice_id_1 = $splited_notice_id[0];
276
+ $compare_notice_id_2 = $splited_notice_id[1];
277
+
278
+ if ( $compare_notice_id_1 == $uniq_id1 || $compare_notice_id_2 == $uniq_id2 ) {
279
+ $skip_notice = false;
280
+ }
281
+ }
282
+
283
+ if ( ! $skip_notice ) {
284
+ continue;
285
+ }
286
+ }
287
+
288
+ $hide_link = '<a href="#" data-nonce="' . wp_create_nonce( $this->plugin->getPluginName() . '_ajax_hide_notices_nonce' ) . '" data-notice-id="' . $uniq_id1 . '_' . $uniq_id2 . '" class="wbcr-dan-hide-notice-link">[' . __( 'Hide notification forever', 'disable-admin-notices' ) . ']</a>';
289
+
290
+ // Fix for Woocommerce membership
291
+ if ( $cont != '<div class="js-wc-memberships-admin-notice-placeholder"></div>' ) {
292
+ $cont = preg_replace( '/<(script|style)([^>]+)?>(.*?)<\/(script|style)>/is', '', $cont );
293
+ $cont = rtrim( trim( $cont ) );
294
+ $cont = preg_replace( '/^(<div[^>]+>)(.*?)(<\/div>)$/is', '$1<div class="wbcr-dan-hide-notices">$2' . $hide_link . '</div>$3', $cont );
295
+ }
296
+
297
+ if ( empty( $cont ) ) {
298
+ continue;
299
+ }
300
+ $content[] = $cont;
301
+ }
302
+ }
303
+
304
+ $wbcr_dan_plugin_all_notices = $content;
305
+ }
306
+
307
+ try {
308
+ $wp_filter_user_admin_notices = &$this->getWPFilter( 'user_admin_notices' );
309
+ } catch( Exception $e ) {
310
+ $wp_filter_user_admin_notices = null;
311
+ }
312
+
313
+ try {
314
+ $wp_filter_network_admin_notices = &$this->getWPFilter( 'network_admin_notices' );
315
+ } catch( Exception $e ) {
316
+ $wp_filter_network_admin_notices = null;
317
+ }
318
+
319
+ if ( is_user_admin() && $wp_filter_user_admin_notices !== null ) {
320
+ $wp_filter_user_admin_notices = null;
321
+ } else if ( is_network_admin() && $wp_filter_network_admin_notices !== null ) {
322
+ //unset($wp_filter['network_admin_notices']);
323
+ foreach ( $wp_filter_network_admin_notices as $f_key => $f ) {
324
+ foreach ( $f as $c_name => $clback ) {
325
+ if ( is_array( $clback['function'] ) && sizeof( $clback['function'] ) == 2 ) {
326
+ $class = $clback['function'][0];
327
+ if ( is_object( $class ) ) {
328
+ $class_name = get_class( $class );
329
+ }
330
+ }
331
+
332
+ unset( $wp_filter_network_admin_notices[ $f_key ][ $c_name ] );
333
+ }
334
+ }
335
+ } else if ( $wp_filter_admin_notices !== null ) {
336
+ foreach ( $wp_filter_admin_notices as $f_key => $f ) {
337
+ foreach ( $f as $c_name => $clback ) {
338
+ if ( is_array( $clback['function'] ) && sizeof( $clback['function'] ) == 2 ) {
339
+ $class = $clback['function'][0];
340
+ if ( is_object( $class ) ) {
341
+ $class_name = get_class( $class );
342
+ }
343
+ }
344
+
345
+ unset( $wp_filter_admin_notices[ $f_key ][ $c_name ] );
346
+ }
347
+ }
348
+
349
+ unset( $f_key );
350
+ unset( $f );
351
+ }
352
+
353
+ try {
354
+ $wp_filter_all_admin_notices = &$this->getWPfilter( 'all_admin_notices' );
355
+ } catch( Exception $e ) {
356
+ $wp_filter_all_admin_notices = null;
357
+ }
358
+
359
+ if ( $wp_filter_all_admin_notices !== null ) {
360
+ foreach ( $wp_filter_all_admin_notices as $f_key => $f ) {
361
+ foreach ( $f as $c_name => $clback ) {
362
+ if ( is_array( $clback['function'] ) && sizeof( $clback['function'] ) == 2 ) {
363
+ $class = $clback['function'][0];
364
+ if ( is_object( $class ) ) {
365
+ $class_name = get_class( $class );
366
+
367
+ #Fix for Learn dash && Woocommerce membership
368
+ if ( $class_name == 'Learndash_Admin_Menus_Tabs' || $class_name == 'WC_Memberships_Admin' ) {
369
+ continue;
370
+ }
371
+ }
372
+ }
373
+
374
+ #Fix for Divi theme
375
+ if ( $c_name == 'et_pb_export_layouts_interface' ) {
376
+ continue;
377
+ }
378
+
379
+ unset( $wp_filter_all_admin_notices[ $f_key ][ $c_name ] );
380
+ }
381
+ }
382
+
383
+ unset( $f_key );
384
+ unset( $f );
385
+ }
386
+ }
387
+
388
+
389
+ /**
390
+ * Get excerpt from string
391
+ *
392
+ * @param String $str String to get an excerpt from
393
+ * @param Integer $startPos Position int string to start excerpt from
394
+ * @param Integer $maxLength Maximum length the excerpt may be
395
+ *
396
+ * @return String excerpt
397
+ */
398
+ public function getExcerpt( $str, $startPos = 0, $maxLength = 100 ) {
399
+ if ( strlen( $str ) > $maxLength ) {
400
+ $excerpt = substr( $str, $startPos, $maxLength - 3 );
401
+ $lastSpace = strrpos( $excerpt, ' ' );
402
+ $excerpt = substr( $excerpt, 0, $lastSpace );
403
+ $excerpt .= '...';
404
+ } else {
405
+ $excerpt = $str;
406
+ }
407
+
408
+ return $excerpt;
409
+ }
410
+
411
+ /**
412
+ * Access to global variable $wp_filter in WP core.
413
+ * Migration from WP 4.2 to 4.9
414
+ *
415
+ * @see https://codex.wordpress.org/Version_4.7 WP 4.7 changelog (WP_Hook)
416
+ *
417
+ * @param $key string filter name
418
+ *
419
+ * @return array $wp_filter callbacks array by link
420
+ * @throws Exception if key not exists
421
+ */
422
+ private function &getWPFilter( $key ) {
423
+ global $wp_version, $wp_filter;
424
+
425
+ if ( ! isset( $wp_filter[ $key ] ) ) {
426
+ throw new Exception( 'key not exists' );
427
+ }
428
+ if ( version_compare( $wp_version, '4.7.0', '>=' ) ) {
429
+ return $wp_filter[ $key ]->callbacks;
430
+ } else {
431
+ return $wp_filter[ $key ];
432
+ }
433
+ }
434
+ }
includes/classes/class.configurate-notices.php DELETED
@@ -1,319 +0,0 @@
1
- <?php
2
-
3
- /**
4
- * This class configures hide admin notices
5
- * @author Webcraftic <wordpress.webraftic@gmail.com>
6
- * @copyright (c) 2017 Webraftic Ltd
7
- * @version 1.0
8
- */
9
-
10
- // Exit if accessed directly
11
- if( !defined('ABSPATH') ) {
12
- exit;
13
- }
14
-
15
- class WDN_ConfigHideNotices extends Wbcr_FactoryClearfy200_Configurate {
16
-
17
- public function registerActionsAndFilters()
18
- {
19
- if( is_admin() ) {
20
- $hide_notices_type = $this->getOption('hide_admin_notices');
21
- if( $hide_notices_type != 'not_hide' ) {
22
- add_action('admin_print_scripts', array($this, 'catchNotices'), 999);
23
-
24
- if( empty($hide_notices_type) || $hide_notices_type == 'only_selected' ) {
25
- add_action('admin_head', array($this, 'printNotices'), 999);
26
- }
27
-
28
- if( !empty($hide_notices_type) && $this->getOption('show_notices_in_adminbar') ) {
29
- add_action('admin_bar_menu', array($this, 'notificationsPanel'), 999);
30
- add_action('admin_enqueue_scripts', array($this, 'notificationsPanelStyles'));
31
- }
32
-
33
- add_action('admin_head', array($this, 'printNonce'), 999);
34
- }
35
- }
36
- }
37
-
38
- public function printNotices()
39
- {
40
- add_action('admin_notices', array($this, 'noticesCollection'));
41
- }
42
-
43
- public function printNonce()
44
- {
45
- ?>
46
- <!-- Disable admin notices plugin (Clearfy tools) -->
47
- <script>
48
- var wbcr_dan_ajax_restore_nonce = "<?=wp_create_nonce($this->plugin->getPluginName() . '_ajax_restore_notice_nonce')?>";
49
- var wbcr_dan_ajax_hide_notice_nonce = "<?=wp_create_nonce($this->plugin->getPluginName() . '_ajax_hide_notices_nonce')?>";
50
- </script>
51
- <?php
52
- }
53
-
54
-
55
- public function notificationsPanelStyles()
56
- {
57
- wp_enqueue_style('wbcr-notification-panel-styles', WDN_PLUGIN_URL . '/admin/assets/css/notifications-panel.css', array(), $this->plugin->getPluginVersion());
58
- wp_enqueue_script('wbcr-notification-panel-scripts', WDN_PLUGIN_URL . '/admin/assets/js/notifications-panel.js', array(), $this->plugin->getPluginVersion());
59
- }
60
-
61
- public function notificationsPanel(&$wp_admin_bar)
62
- {
63
- if( !current_user_can('administrator') ) {
64
- return;
65
- }
66
-
67
- $notifications = $this->getOption('hidden_notices');
68
-
69
- if( empty($notifications) ) {
70
- return;
71
- }
72
-
73
- $cont_notifications = sizeof($notifications);
74
-
75
- // Add top menu
76
- $wp_admin_bar->add_menu(array(
77
- 'id' => 'wbcr-han-notify-panel',
78
- 'parent' => 'top-secondary',
79
- 'title' => sprintf(__('Notifications %s', 'disable-admin-notices'), '<span class="wbcr-han-adminbar-counter">' . $cont_notifications . '</span>'),
80
- 'href' => false
81
- ));
82
-
83
- // loop
84
- if( !empty($notifications) ) {
85
- $i = 0;
86
- foreach($notifications as $notice_id => $message) {
87
- $message = $this->getExcerpt(stripslashes($message), 0, 350);
88
- $message .= '<div class="wbcr-han-panel-restore-notify-line"><a href="#" data-notice-id="' . esc_attr($notice_id) . '" class="wbcr-han-panel-restore-notify-link">' . __('Restore notice', 'clearfy') . '</a></div>';
89
-
90
- $wp_admin_bar->add_menu(array(
91
- 'id' => 'wbcr-han-notify-panel-item-' . $i,
92
- 'parent' => 'wbcr-han-notify-panel',
93
- 'title' => $message,
94
- 'href' => false,
95
- 'meta' => array(
96
- 'class' => ''
97
- )
98
- ));
99
-
100
- $i++;
101
- }
102
- }
103
- }
104
-
105
- public function noticesCollection()
106
- {
107
- global $wbcr_dan_plugin_all_notices;
108
-
109
- if( empty($wbcr_dan_plugin_all_notices) ) {
110
- return;
111
- }
112
- ?>
113
- <!-- Disable admin notices plugin (Clearfy tools) -->
114
- <style>
115
- .wbcr-dan-hide-notices {
116
- position: relative;
117
- padding: 5px 5px 0;
118
- background: #fff;
119
- }
120
-
121
- .wbcr-dan-hide-notices > div {
122
- margin: 0 !important;
123
- }
124
-
125
- .wbcr-dan-hide-notice-link {
126
- display: block;
127
- text-align: right;
128
- margin: 5px 0 5px 5px;
129
- font-weight: bold;
130
- color: #F44336;
131
- }
132
-
133
- .is-dismissible .wbcr-dan-hide-notice-link {
134
- margin-right: -30px;
135
- }
136
-
137
- .wbcr-dan-hide-notice-link:active, .wbcr-dan-hide-notice-link:focus {
138
- box-shadow: none;
139
- outline: none;
140
- }
141
- </style>
142
-
143
- <!-- Disable admin notices plugin (Clearfy tools) -->
144
- <script>
145
- jQuery(document).ready(function($) {
146
- $(document).on('click', '.wbcr-dan-hide-notice-link', function() {
147
- var self = $(this),
148
- noticeID = self.data('notice-id'),
149
- noticeHtml = self.closest('.wbcr-dan-hide-notices').clone(),
150
- contanierEl = self.closest('.wbcr-dan-hide-notices').parent();
151
-
152
- noticeHtml.find('.wbcr-dan-hide-notice-link').remove();
153
-
154
- if( !noticeID ) {
155
- alert('Undefinded error. Please report the bug to our support forum.');
156
- }
157
-
158
- contanierEl.hide();
159
-
160
- $.ajax(ajaxurl, {
161
- type: 'post',
162
- dataType: 'json',
163
- data: {
164
- action: 'wbcr_dan_hide_notices',
165
- security: wbcr_dan_ajax_hide_notice_nonce,
166
- notice_id: noticeID,
167
- notice_html: noticeHtml.html()
168
- },
169
- success: function(data, textStatus, jqXHR) {
170
- if( data == 'error' && data.error ) {
171
- alert(data.error);
172
-
173
- contanierEl.show();
174
- return;
175
- }
176
-
177
- contanierEl.remove();
178
- }
179
- });
180
- });
181
- });
182
- </script>
183
- <?php
184
- foreach($wbcr_dan_plugin_all_notices as $val) {
185
- echo $val;
186
- }
187
- }
188
-
189
- public function catchNotices()
190
- {
191
- global $wp_filter, $wbcr_dan_plugin_all_notices;
192
-
193
- $hide_notices_type = $this->getOption('hide_admin_notices');
194
-
195
- if( empty($hide_notices_type) || $hide_notices_type == 'only_selected' ) {
196
- $get_hidden_notices = $this->getOption('hidden_notices');
197
-
198
- $content = array();
199
- foreach((array)$wp_filter['admin_notices']->callbacks as $filters) {
200
- foreach($filters as $callback_name => $callback) {
201
-
202
- if( 'usof_hide_admin_notices_start' == $callback_name || 'usof_hide_admin_notices_end' == $callback_name ) {
203
- continue;
204
- }
205
-
206
- ob_start();
207
-
208
- // #CLRF-140 fix bug for php7
209
- // when the developers forgot to delete the argument in the function of implementing the notification.
210
- $args = array();
211
- $accepted_args = isset($callback['accepted_args']) && !empty($callback['accepted_args'])
212
- ? $callback['accepted_args']
213
- : 0;
214
-
215
- if( $accepted_args > 0 ) {
216
- for($i = 0; $i < (int)$accepted_args; $i++) {
217
- $args[] = null;
218
- }
219
- }
220
- //===========
221
-
222
- call_user_func_array($callback['function'], $args);
223
- $cont = ob_get_clean();
224
-
225
- if( empty($cont) ) {
226
- continue;
227
- }
228
-
229
- $uniq_id1 = md5($cont);
230
- $uniq_id2 = md5($callback_name);
231
-
232
- if( is_array($callback['function']) && sizeof($callback['function']) == 2 ) {
233
- $class = $callback['function'][0];
234
- if( is_object($class) ) {
235
- $class_name = get_class($class);
236
- $method_name = $callback['function'][1];
237
- $uniq_id2 = md5($class_name . ':' . $method_name);
238
- }
239
- }
240
- //838339d1a188e17fec838c2df3058603
241
- //838339d1a188e17fec838c2df3058603
242
- if( !empty($get_hidden_notices) ) {
243
-
244
- $skip_notice = true;
245
- foreach((array)$get_hidden_notices as $key => $notice) {
246
- $splited_notice_id = explode('_', $key);
247
- if( empty($splited_notice_id) || sizeof($splited_notice_id) < 2 ) {
248
- continue;
249
- }
250
- $compare_notice_id_1 = $splited_notice_id[0];
251
- $compare_notice_id_2 = $splited_notice_id[1];
252
-
253
- if( $compare_notice_id_1 == $uniq_id1 || $compare_notice_id_2 == $uniq_id2 ) {
254
- $skip_notice = false;
255
- }
256
- }
257
-
258
- if( !$skip_notice ) {
259
- continue;
260
- }
261
- }
262
-
263
- $hide_link = '<a href="#" data-notice-id="' . $uniq_id1 . '_' . $uniq_id2 . '" class="wbcr-dan-hide-notice-link">[' . __('Hide notification forever', 'disable-admin-notices') . ']</a>';
264
-
265
- $cont = preg_replace('/<(script|style)([^>]+)?>(.*?)<\/(script|style)>/is', '', $cont);
266
- $cont = rtrim(trim($cont));
267
- $cont = preg_replace('/^(<div[^>]+>)(.*?)(<\/div>)$/is', '$1<div class="wbcr-dan-hide-notices">$2' . $hide_link . '</div>$3', $cont);
268
-
269
- if( empty($cont) ) {
270
- continue;
271
- }
272
- $content[] = $cont;
273
- }
274
- }
275
-
276
- $wbcr_dan_plugin_all_notices = $content;
277
- }
278
-
279
- if( is_user_admin() ) {
280
- if( isset($wp_filter['user_admin_notices']) ) {
281
- unset($wp_filter['user_admin_notices']);
282
- }
283
- } elseif( isset($wp_filter['admin_notices']) ) {
284
- unset($wp_filter['admin_notices']);
285
- }
286
- if( isset($wp_filter['all_admin_notices']) ) {
287
- foreach($wp_filter['all_admin_notices']->callbacks as $f_key => $f) {
288
- foreach($f as $c_name => $clback) {
289
- #Fix for Divi theme
290
- if( $c_name != 'et_pb_export_layouts_interface' ) {
291
- unset($wp_filter['all_admin_notices']->callbacks[$f_key][$c_name]);
292
- }
293
- }
294
- }
295
- }
296
- }
297
-
298
- /**
299
- * Get excerpt from string
300
- *
301
- * @param String $str String to get an excerpt from
302
- * @param Integer $startPos Position int string to start excerpt from
303
- * @param Integer $maxLength Maximum length the excerpt may be
304
- * @return String excerpt
305
- */
306
- function getExcerpt($str, $startPos = 0, $maxLength = 100)
307
- {
308
- if( strlen($str) > $maxLength ) {
309
- $excerpt = substr($str, $startPos, $maxLength - 3);
310
- $lastSpace = strrpos($excerpt, ' ');
311
- $excerpt = substr($excerpt, 0, $lastSpace);
312
- $excerpt .= '...';
313
- } else {
314
- $excerpt = $str;
315
- }
316
-
317
- return $excerpt;
318
- }
319
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
languages/disable-admin-notices-es_ES.mo ADDED
Binary file
languages/disable-admin-notices-es_ES.po ADDED
@@ -0,0 +1,182 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Translation of Plugins - Clearfy in Spanish (Spain)
2
+ # This file is distributed under the same license as the Plugins - Clearfy – WordPress optimization plugin and disable ultimate tweaker - Development (trunk) package.
3
+ msgid ""
4
+ msgstr ""
5
+ "Project-Id-Version: \n"
6
+ "POT-Creation-Date: 2019-04-28 06:26+0300\n"
7
+ "PO-Revision-Date: 2019-04-28 06:26+0300\n"
8
+ "Last-Translator: \n"
9
+ "Language-Team: \n"
10
+ "Language: es\n"
11
+ "MIME-Version: 1.0\n"
12
+ "Content-Type: text/plain; charset=UTF-8\n"
13
+ "Content-Transfer-Encoding: 8bit\n"
14
+ "Plural-Forms: nplurals=2; plural=n != 1;\n"
15
+ "X-Generator: Poedit 2.1.1\n"
16
+ "Plural-Forms: nplurals=2; plural=n != 1;\n"
17
+ "X-Generator: Poedit 2.1.1\n"
18
+ "X-Poedit-Basepath: ..\n"
19
+ "Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
20
+ "%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
21
+ "X-Poedit-SourceCharset: UTF-8\n"
22
+ "X-Poedit-KeywordsList: __;_e;_n:1,2;_x:1,2c;_ex:1,2c\n"
23
+ "X-Poedit-SearchPath-0: .\n"
24
+ "X-Poedit-SearchPathExcluded-0: libs\n"
25
+ "X-Poedit-SearchPathExcluded-1: components\n"
26
+ "X-Poedit-SearchPathExcluded-2: cache\n"
27
+
28
+ #: admin/ajax/hide-notice.php:24 admin/ajax/restore-notice.php:22
29
+ msgid "Undefinded notice id."
30
+ msgstr "Aviso de ID indefinido"
31
+
32
+ #: admin/ajax/hide-notice.php:40 admin/ajax/restore-notice.php:36
33
+ msgid "You don't have enough capability to edit this information."
34
+ msgstr "No tienes suficiente permisos para editar esta información."
35
+
36
+ #: admin/boot.php:18 admin/options.php:30 admin/pages/notices.php:38
37
+ msgid "Hide admin notices"
38
+ msgstr "Ocultar avisos administrativos"
39
+
40
+ #: admin/boot.php:24 admin/options.php:103
41
+ msgid "Enable hidden notices in adminbar"
42
+ msgstr "Habilitar avisos ocultos en la barra de administración"
43
+
44
+ #: admin/boot.php:46
45
+ msgid "Get ultimate plugin free"
46
+ msgstr "Obtener el ultimate plugin gratis"
47
+
48
+ #: admin/options.php:23
49
+ msgid "Admin notifications, Update nags"
50
+ msgstr "Notificaciones de administrador, actualización de nags"
51
+
52
+ #: admin/options.php:23
53
+ msgid ""
54
+ "Do you know the situation, when some plugin offers you to update to premium, "
55
+ "to collect technical data and shows many annoying notices? You are close "
56
+ "these notices every now and again but they newly appears and interfere your "
57
+ "work with WordPress. Even worse, some plugin’s authors delete “close” button "
58
+ "from notices and they shows in your admin panel forever."
59
+ msgstr ""
60
+ "¿Conoces la situación cuando algún plugin te ofrece actualizar a Premium, "
61
+ "recopilar datos técnicos y mostrar muchos avisos molestos? A veces no están, "
62
+ "pero aparecen de nuevo e interfieren en tu trabajo con WordPress. Peor aún, "
63
+ "los autores de algunos plugin eliminan el botón \"cerrar\" de las "
64
+ "notificaciones y se muestran en su panel de administración para siempre."
65
+
66
+ #: admin/options.php:34
67
+ msgid "All notices"
68
+ msgstr "Todos los avisos"
69
+
70
+ #: admin/options.php:35
71
+ msgid "Hide all notices globally."
72
+ msgstr "Ocultar todos los avisos globalmente."
73
+
74
+ #: admin/options.php:39
75
+ msgid "Only selected"
76
+ msgstr "Solo seleccionados"
77
+
78
+ #: admin/options.php:40
79
+ msgid ""
80
+ "Hide selected notices only. You will see the link \"Hide notification forever"
81
+ "\" in each notice. Push it and they will not bother you anymore."
82
+ msgstr ""
83
+ "Ocultar solo los avisos seleccionados. Verá el enlace \"Ocultar notificación "
84
+ "para siempre\" en cada aviso. Click y ya no los veras mas."
85
+
86
+ #: admin/options.php:44
87
+ msgid "Don't nide"
88
+ msgstr "No ocultar"
89
+
90
+ #: admin/options.php:45
91
+ msgid ""
92
+ "Do not hide notices and do not show “Hide notification forever” link for "
93
+ "admin."
94
+ msgstr ""
95
+ "No ocultar avisos y no mostrar el enlace \"Ocultar notificación para siempre"
96
+ "\" para el administrador."
97
+
98
+ #: admin/options.php:49
99
+ msgid ""
100
+ "Some plugins shows notifications about premium version, data collecting or "
101
+ "promote their services. Even if you push close button (that sometimes are "
102
+ "impossible), notices are shows again in some time. This option allows you to "
103
+ "control notices. Hide them all or each individually. Some plugins shows "
104
+ "notifications about premium version, data collecting or promote their "
105
+ "services. Even if you push close button (that sometimes are impossible), "
106
+ "notices are shows again in some time. This option allows you to control "
107
+ "notices. Hide them all or each individually."
108
+ msgstr ""
109
+ "Algunos plugin muestran notificaciones sobre la versión premium: "
110
+ "Recopilación de datos o la promoción de sus servicios; Incluso si presiona "
111
+ "el botón de cierre (que a veces es imposible), las notificaciones se "
112
+ "muestran de nuevo en algún momento. Esta opción le permite controlar avisos. "
113
+ "Ocúltelas todas o cada una individualmente."
114
+
115
+ #: admin/options.php:105
116
+ msgid ""
117
+ "By default, the plugin hides all notices, which you specified. If you enable "
118
+ "this option, the plugin will collect all hidden notices and show them into "
119
+ "the top admin toolbar. It will not disturb you but will allow to look "
120
+ "notices at your convenience."
121
+ msgstr ""
122
+ "Por defecto, el plugin oculta todos los avisos que especificó. Si habilita "
123
+ "esta opción, el plugin recopilará todos los avisos ocultos y los mostrará en "
124
+ "la barra superior de administración de herramientas. No le molestará, pero "
125
+ "le permitirá ver los avisos según su conveniencia."
126
+
127
+ #: admin/options.php:166
128
+ msgid "Reset hidden notices for"
129
+ msgstr "Restablecer avisos ocultos para"
130
+
131
+ #: admin/options.php:167
132
+ msgid "Push reset hidden notices if you need to show hidden notices again."
133
+ msgstr "Pulse reiniciar avisos ocultos si necesita mostrarlos de nuevo."
134
+
135
+ #: admin/options.php:177
136
+ msgid "current user"
137
+ msgstr "usuario actual"
138
+
139
+ #: admin/options.php:181
140
+ msgid "all users"
141
+ msgstr "todos los usuarios"
142
+
143
+ #: admin/options.php:185
144
+ msgid "Reset notices"
145
+ msgstr "Restablecer avisos"
146
+
147
+ #: admin/options.php:188 admin/pages/notices.php:71
148
+ msgid "Hidden notices are successfully reset, now you can see them again!"
149
+ msgstr ""
150
+ "Los avisos ocultos se restablecieron con éxito, ¡ahora puedes verlos "
151
+ "nuevamente!"
152
+
153
+ #: admin/pages/notices.php:54
154
+ msgid "Notices"
155
+ msgstr "Avisos"
156
+
157
+ #: admin/pages/notices.php:55
158
+ msgid "General"
159
+ msgstr "General"
160
+
161
+ #: disable-admin-notices.php:84
162
+ msgid "Webcraftic disable admin notices"
163
+ msgstr "Deshabilitar los avisos Webcraftic de administración"
164
+
165
+ #: includes/classes/class.configurate-notices.php:74
166
+ #, php-format
167
+ msgid "Notifications %s"
168
+ msgstr "Notificaciones %s"
169
+
170
+ #: includes/classes/class.configurate-notices.php:86
171
+ msgid "Restore notice"
172
+ msgstr "Aviso de restauración"
173
+
174
+ #: includes/classes/class.configurate-notices.php:285
175
+ msgid "Hide notification forever"
176
+ msgstr "Ocultar notificaciones para siempre"
177
+
178
+ #~ msgid "Assets Manager"
179
+ #~ msgstr "Gestor de Activos"
180
+
181
+ #~ msgid "Settings has been successfully imported!"
182
+ #~ msgstr "¡Configuración importada exitosamente!"
languages/disable-admin-notices-nl_BE.mo ADDED
Binary file
languages/disable-admin-notices-nl_BE.po ADDED
@@ -0,0 +1,173 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ msgid ""
2
+ msgstr ""
3
+ "Project-Id-Version: Clearfy\n"
4
+ "POT-Creation-Date: 2018-09-06 18:31+0300\n"
5
+ "PO-Revision-Date: \n"
6
+ "Last-Translator: \n"
7
+ "Language-Team: \n"
8
+ "Language: nl_BE\n"
9
+ "MIME-Version: 1.0\n"
10
+ "Content-Type: text/plain; charset=UTF-8\n"
11
+ "Content-Transfer-Encoding: 8bit\n"
12
+ "X-Generator: Poedit 2.1.1\n"
13
+ "Plural-Forms: nplurals=2; plural=n != 1;\n"
14
+ "X-Generator: Poedit 2.1.1\n"
15
+ "X-Poedit-Basepath: ..\n"
16
+ "Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
17
+ "%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
18
+ "X-Poedit-SourceCharset: UTF-8\n"
19
+ "X-Poedit-KeywordsList: __;_e;_n:1,2;_x:1,2c;_ex:1,2c\n"
20
+ "X-Poedit-SearchPath-0: .\n"
21
+ "X-Poedit-SearchPathExcluded-0: libs\n"
22
+ "X-Poedit-SearchPathExcluded-1: components\n"
23
+ "X-Poedit-SearchPathExcluded-2: cache\n"
24
+
25
+ #: admin/ajax/hide-notice.php:19 admin/ajax/restore-notice.php:19
26
+ msgid "You don't have enough capability to edit this information."
27
+ msgstr "Je hebt niet voldoende mogelijkheden om deze informatie te bewerken."
28
+
29
+ #: admin/ajax/hide-notice.php:32 admin/ajax/restore-notice.php:28
30
+ msgid "Undefinded notice id."
31
+ msgstr "Ongedefinieerde mededeling id."
32
+
33
+ #: admin/ajax/hide-notice.php:46 admin/ajax/restore-notice.php:40
34
+ msgid "Success"
35
+ msgstr "Succes"
36
+
37
+ #: admin/boot.php:18 admin/options.php:30 admin/pages/notices.php:33
38
+ msgid "Hide admin notices"
39
+ msgstr "Verberg admin meldingen"
40
+
41
+ #: admin/boot.php:24 admin/options.php:70
42
+ msgid "Enable hidden notices in adminbar"
43
+ msgstr "Schakel verborgen meldingen in de beheer balk in"
44
+
45
+ #: admin/boot.php:46
46
+ msgid "Get ultimate plugin free"
47
+ msgstr "Krijg ultieme plugin gratis"
48
+
49
+ #: admin/options.php:23
50
+ msgid "Admin notifications, Update nags"
51
+ msgstr "Admin mededelingen, Update meldingen"
52
+
53
+ #: admin/options.php:23
54
+ msgid ""
55
+ "Do you know the situation, when some plugin offers you to update to premium, "
56
+ "to collect technical data and shows many annoying notices? You are close these "
57
+ "notices every now and again but they newly appears and interfere your work "
58
+ "with WordPress. Even worse, some plugin’s authors delete “close” button from "
59
+ "notices and they shows in your admin panel forever."
60
+ msgstr ""
61
+ "Herkent u de situatie, waarin sommige plugins u aanbieden om te updaten naar "
62
+ "premium, om technische gegevens te verzamelen en veel vervelende meldingen "
63
+ "weergeven? Zo nu en dan sluit u deze meldingen, maar ze verschijnen keer op "
64
+ "keer opnieuw en belemmeren uw werk met WordPress. Erger nog, de auteurs van "
65
+ "sommige plugins verwijderen de knop \"Sluiten\" uit meldingen en blijven "
66
+ "continu zichtbaar in uw beheer venster."
67
+
68
+ #: admin/options.php:34
69
+ msgid "All notices"
70
+ msgstr "Alle mededelingen"
71
+
72
+ #: admin/options.php:35
73
+ msgid "Hide all notices globally."
74
+ msgstr "Alle meldingen globaal verbergen."
75
+
76
+ #: admin/options.php:39
77
+ msgid "Only selected"
78
+ msgstr "Enkel geselecteerd"
79
+
80
+ #: admin/options.php:40
81
+ msgid ""
82
+ "Hide selected notices only. You will see the link \"Hide notification forever"
83
+ "\" in each notice. Push it and they will not bother you anymore."
84
+ msgstr ""
85
+ "Slechts bepaalde meldingen verbergen. U ziet in elke melding de link \"Verberg "
86
+ "melding voor altijd\". Klik erop en ze zullen je niet meer lastig vallen."
87
+
88
+ #: admin/options.php:44
89
+ msgid "Don't nide"
90
+ msgstr "Niet verbergen"
91
+
92
+ #: admin/options.php:45
93
+ msgid ""
94
+ "Do not hide notices and do not show “Hide notification forever” link for admin."
95
+ msgstr ""
96
+ "Meldingen niet verbergen en laat de link 'Verberg melding voor altijd' niet "
97
+ "zien voor beheerder."
98
+
99
+ #: admin/options.php:49
100
+ msgid ""
101
+ "Some plugins shows notifications about premium version, data collecting or "
102
+ "promote their services. Even if you push close button (that sometimes are "
103
+ "impossible), notices are shows again in some time. This option allows you to "
104
+ "control notices. Hide them all or each individually. Some plugins shows "
105
+ "notifications about premium version, data collecting or promote their "
106
+ "services. Even if you push close button (that sometimes are impossible), "
107
+ "notices are shows again in some time. This option allows you to control "
108
+ "notices. Hide them all or each individually."
109
+ msgstr ""
110
+ "Sommige plugins tonen meldingen over de premium versie, het verzamelen van "
111
+ "gegevens of het promoten van hun diensten. Zelfs als je op afsluiten klikt "
112
+ "(wat soms niet eens mogelijk is), worden mededelingen binnen afzienbare tijd "
113
+ "opnieuw getoond. Met deze optie kunt u mededelingen beheren. Verberg ze "
114
+ "allemaal of elk afzonderlijk."
115
+
116
+ #: admin/options.php:72
117
+ msgid ""
118
+ "By default, the plugin hides all notices, which you specified. If you enable "
119
+ "this option, the plugin will collect all hidden notices and show them into the "
120
+ "top admin toolbar. It will not disturb you but will allow to look notices at "
121
+ "your convenience."
122
+ msgstr ""
123
+ "Standaard verbergt de plugin alle kennisgevingen die u hebt opgegeven. Als u "
124
+ "deze optie inschakelt, verzamelt de plugin alle verborgen mededelingen en "
125
+ "toont deze in de bovenste beheer werkbalk. Het zal niet storend zijn, maar zal "
126
+ "je toelaten om aankondigingen op je gemak te bekijken."
127
+
128
+ #: admin/options.php:136
129
+ msgid "Push reset hidden notices if you need to show hidden notices again."
130
+ msgstr ""
131
+ "Druk op reset verborgen mededelingen als u verborgen mededelingen opnieuw wilt "
132
+ "weergeven."
133
+
134
+ #: admin/options.php:145
135
+ #, php-format
136
+ msgid "Reset hidden notices (%s)"
137
+ msgstr "Reset verborgen mededelingen (%s)"
138
+
139
+ #: admin/options.php:147 admin/pages/notices.php:85
140
+ msgid "Hidden notices are successfully reset, now you can see them again!"
141
+ msgstr "Verborgen meldingen zijn succesvol gereset, nu kun je ze opnieuw zien!"
142
+
143
+ #: admin/pages/notices.php:49
144
+ msgid "Notices"
145
+ msgstr "Mededelingen"
146
+
147
+ #: admin/pages/notices.php:50
148
+ msgid "General"
149
+ msgstr "Algemeen"
150
+
151
+ #: disable-admin-notices.php:23
152
+ msgid ""
153
+ "We found that you have the \"Clearfy - disable unused features\" plugin "
154
+ "installed, this plugin already has disable comments functions, so you can "
155
+ "deactivate plugin \"Disable admin notices\"!"
156
+ msgstr ""
157
+
158
+ #: disable-admin-notices.php:80
159
+ msgid "Webcraftic disable admin notices"
160
+ msgstr "Webcraftic uitschakelen admin mededelingen"
161
+
162
+ #: includes/classes/class.configurate-notices.php:79
163
+ #, php-format
164
+ msgid "Notifications %s"
165
+ msgstr "Meldingen %s"
166
+
167
+ #: includes/classes/class.configurate-notices.php:88
168
+ msgid "Restore notice"
169
+ msgstr "Herstel mededelingen"
170
+
171
+ #: includes/classes/class.configurate-notices.php:267
172
+ msgid "Hide notification forever"
173
+ msgstr "Verberg melding voor altijd"
languages/disable-admin-notices-pt_BR.mo ADDED
Binary file
languages/disable-admin-notices-pt_BR.po ADDED
@@ -0,0 +1,181 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ msgid ""
2
+ msgstr ""
3
+ "Project-Id-Version: clearfy\n"
4
+ "POT-Creation-Date: 2018-09-06 18:31+0300\n"
5
+ "PO-Revision-Date: 2018-09-06 18:31+0300\n"
6
+ "Last-Translator: alex.kovalevv@gmail.com <alex.kovalevv@gmail.com>\n"
7
+ "Language-Team: Alex Kovalev <alex.kovalevv@gmail.com>\n"
8
+ "Language: pt_BR\n"
9
+ "MIME-Version: 1.0\n"
10
+ "Content-Type: text/plain; charset=UTF-8\n"
11
+ "Content-Transfer-Encoding: 8bit\n"
12
+ "X-Generator: Poedit 2.1.1\n"
13
+ "X-Poedit-Basepath: ..\n"
14
+ "Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
15
+ "%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
16
+ "X-Poedit-SourceCharset: UTF-8\n"
17
+ "X-Poedit-KeywordsList: __;_e;_n:1,2;_x:1,2c;_ex:1,2c\n"
18
+ "X-Poedit-SearchPath-0: .\n"
19
+ "X-Poedit-SearchPathExcluded-0: libs\n"
20
+ "X-Poedit-SearchPathExcluded-1: components\n"
21
+ "X-Poedit-SearchPathExcluded-2: cache\n"
22
+
23
+ #: admin/ajax/hide-notice.php:19 admin/ajax/restore-notice.php:19
24
+ msgid "You don't have enough capability to edit this information."
25
+ msgstr "Você não tem capacidade suficiente para editar essas informações."
26
+
27
+ #: admin/ajax/hide-notice.php:32 admin/ajax/restore-notice.php:28
28
+ msgid "Undefinded notice id."
29
+ msgstr "ID de aviso não identificada."
30
+
31
+ #: admin/ajax/hide-notice.php:46 admin/ajax/restore-notice.php:40
32
+ msgid "Success"
33
+ msgstr "Sucesso"
34
+
35
+ #: admin/boot.php:18 admin/options.php:30 admin/pages/notices.php:33
36
+ msgid "Hide admin notices"
37
+ msgstr "Ocultar avisos de administrador"
38
+
39
+ #: admin/boot.php:24 admin/options.php:70
40
+ msgid "Enable hidden notices in adminbar"
41
+ msgstr "Ativar avisos ocultos no adminbar"
42
+
43
+ #: admin/boot.php:46
44
+ msgid "Get ultimate plugin free"
45
+ msgstr "Obtenha o melhor plugin grátis"
46
+
47
+ #: admin/options.php:23
48
+ msgid "Admin notifications, Update nags"
49
+ msgstr "Notificações de administrador, Atualizações nags"
50
+
51
+ #: admin/options.php:23
52
+ msgid ""
53
+ "Do you know the situation, when some plugin offers you to update to premium, "
54
+ "to collect technical data and shows many annoying notices? You are close "
55
+ "these notices every now and again but they newly appears and interfere your "
56
+ "work with WordPress. Even worse, some plugin’s authors delete “close” button "
57
+ "from notices and they shows in your admin panel forever."
58
+ msgstr ""
59
+ "Você conhece a situação, quando algum plugin lhe oferece para atualizar para "
60
+ "premium, para coletar dados técnicos e mostra muitos avisos irritantes? Você "
61
+ "está próximo desses avisos de vez em quando, mas eles aparecem recentemente "
62
+ "e interferem no seu trabalho com o WordPress. Pior ainda, alguns autores de "
63
+ "plug-in excluem o botão “fechar” dos avisos e eles são exibidos no seu "
64
+ "painel de administração para sempre."
65
+
66
+ #: admin/options.php:34
67
+ msgid "All notices"
68
+ msgstr "Todos os avisos"
69
+
70
+ #: admin/options.php:35
71
+ msgid "Hide all notices globally."
72
+ msgstr "Esconda todos os avisos globalmente."
73
+
74
+ #: admin/options.php:39
75
+ msgid "Only selected"
76
+ msgstr "Apenas selecionado"
77
+
78
+ #: admin/options.php:40
79
+ msgid ""
80
+ "Hide selected notices only. You will see the link \"Hide notification forever"
81
+ "\" in each notice. Push it and they will not bother you anymore."
82
+ msgstr ""
83
+ "Ocultar apenas avisos selecionados. Você verá o link \"Ocultar notificação "
84
+ "para sempre\" em cada aviso. Empurre-o e eles não vão incomodá-lo mais."
85
+
86
+ #: admin/options.php:44
87
+ msgid "Don't nide"
88
+ msgstr "Não nide"
89
+
90
+ #: admin/options.php:45
91
+ msgid ""
92
+ "Do not hide notices and do not show “Hide notification forever” link for "
93
+ "admin."
94
+ msgstr ""
95
+ "Não oculte avisos e não mostre o link \"Ocultar notificação para sempre\" "
96
+ "para o administrador."
97
+
98
+ #: admin/options.php:49
99
+ msgid ""
100
+ "Some plugins shows notifications about premium version, data collecting or "
101
+ "promote their services. Even if you push close button (that sometimes are "
102
+ "impossible), notices are shows again in some time. This option allows you to "
103
+ "control notices. Hide them all or each individually. Some plugins shows "
104
+ "notifications about premium version, data collecting or promote their "
105
+ "services. Even if you push close button (that sometimes are impossible), "
106
+ "notices are shows again in some time. This option allows you to control "
107
+ "notices. Hide them all or each individually."
108
+ msgstr ""
109
+ "Alguns plugins mostram notificações sobre a versão premium, coleta de dados "
110
+ "ou promover seus serviços. Mesmo se você apertar o botão fechar (que às "
111
+ "vezes são impossíveis), os avisos são exibidos novamente em algum momento. "
112
+ "Esta opção permite controlar avisos. Esconda-os todos ou cada um "
113
+ "individualmente. Alguns plugins mostram notificações sobre a versão premium, "
114
+ "coleta de dados ou promover seus serviços. Mesmo se você apertar o botão "
115
+ "fechar (que às vezes são impossíveis), os avisos são exibidos novamente em "
116
+ "algum momento. Esta opção permite controlar avisos. Esconda-os todos ou cada "
117
+ "um individualmente."
118
+
119
+ #: admin/options.php:72
120
+ msgid ""
121
+ "By default, the plugin hides all notices, which you specified. If you enable "
122
+ "this option, the plugin will collect all hidden notices and show them into "
123
+ "the top admin toolbar. It will not disturb you but will allow to look "
124
+ "notices at your convenience."
125
+ msgstr ""
126
+ "Por padrão, o plug-in oculta todos os avisos especificados. Se você ativar "
127
+ "essa opção, o plug-in coletará todos os avisos ocultos e os mostrará na "
128
+ "barra de ferramentas superior do administrador. Não o incomodará, mas "
129
+ "permitirá que você veja avisos de acordo com sua conveniência."
130
+
131
+ #: admin/options.php:136
132
+ msgid "Push reset hidden notices if you need to show hidden notices again."
133
+ msgstr ""
134
+ "Envie os avisos ocultos redefinidos se precisar mostrar avisos ocultos "
135
+ "novamente."
136
+
137
+ #: admin/options.php:145
138
+ #, php-format
139
+ msgid "Reset hidden notices (%s)"
140
+ msgstr "Redefinir avisos ocultos ( %s )"
141
+
142
+ #: admin/options.php:147 admin/pages/notices.php:85
143
+ msgid "Hidden notices are successfully reset, now you can see them again!"
144
+ msgstr ""
145
+ "Avisos ocultos são redefinidos com sucesso, agora você pode vê-los novamente!"
146
+
147
+ #: admin/pages/notices.php:49
148
+ msgid "Notices"
149
+ msgstr "Avisos"
150
+
151
+ #: admin/pages/notices.php:50
152
+ msgid "General"
153
+ msgstr "Geral"
154
+
155
+ #: disable-admin-notices.php:23
156
+ msgid ""
157
+ "We found that you have the \"Clearfy - disable unused features\" plugin "
158
+ "installed, this plugin already has disable comments functions, so you can "
159
+ "deactivate plugin \"Disable admin notices\"!"
160
+ msgstr ""
161
+ "Descobrimos que você tem o plug-in \"Clearfy - desativar recursos não "
162
+ "utilizados \" instalado, este plugin já tem funções de desabilitar "
163
+ "comentários, então você pode desativar o plugin \"Desativar avisos do "
164
+ "administrador \"!"
165
+
166
+ #: disable-admin-notices.php:80
167
+ msgid "Webcraftic disable admin notices"
168
+ msgstr "Webcraftic desabilitar avisos de administração"
169
+
170
+ #: includes/classes/class.configurate-notices.php:79
171
+ #, php-format
172
+ msgid "Notifications %s"
173
+ msgstr "Notificações %s"
174
+
175
+ #: includes/classes/class.configurate-notices.php:88
176
+ msgid "Restore notice"
177
+ msgstr "Aviso de restauração"
178
+
179
+ #: includes/classes/class.configurate-notices.php:267
180
+ msgid "Hide notification forever"
181
+ msgstr "Ocultar a notificação para sempre"
libs/factory/adverts/boot.php ADDED
@@ -0,0 +1,50 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ use WBCR\Factory_Adverts_102\Base;
4
+
5
+ /**
6
+ * Factory Adverts
7
+ *
8
+ * @author Alexander Vitkalov <nechin.va@gmail.com>
9
+ * @author Alexander Kovalev <alex.kovalevv@gmail.com>, Github: https://github.com/alexkovalevv
10
+ * @since 1.0.0
11
+ *
12
+ * @package factory-ad-inserter
13
+ * @copyright (c) 2019, Webcraftic Ltd
14
+ *
15
+ * @version 1.2.3
16
+ */
17
+
18
+ // Exit if accessed directly
19
+ if ( ! defined( 'ABSPATH' ) ) {
20
+ exit;
21
+ }
22
+
23
+ if ( defined( 'FACTORY_ADVERTS_102_LOADED' ) || ( defined( 'FACTORY_ADVERTS_BLOCK' ) && FACTORY_ADVERTS_BLOCK ) ) {
24
+ return;
25
+ }
26
+
27
+ # Устанавливаем константу, что модуль уже загружен
28
+ define( 'FACTORY_ADVERTS_102_LOADED', true );
29
+
30
+ # Устанавливаем версию модуля
31
+ define( 'FACTORY_ADVERTS_102_VERSION', '1.0.2' );
32
+
33
+ # Регистрируем тектовый домен, для интернализации интерфейса модуля
34
+ load_plugin_textdomain( 'wbcr_factory_adverts_102', false, dirname( plugin_basename( __FILE__ ) ) . '/langs' );
35
+
36
+ # Устанавливаем директорию модуля
37
+ define( 'FACTORY_ADVERTS_102_DIR', dirname( __FILE__ ) );
38
+
39
+ # Устанавливаем url модуля
40
+ define( 'FACTORY_ADVERTS_102_URL', plugins_url( null, __FILE__ ) );
41
+
42
+ require_once( FACTORY_ADVERTS_102_DIR . '/includes/class-rest-request.php' );
43
+ require_once( FACTORY_ADVERTS_102_DIR . '/includes/class-base.php' );
44
+
45
+ /**
46
+ * @param Wbcr_Factory420_Plugin $plugin
47
+ */
48
+ add_action( 'wbcr_factory_adverts_102_plugin_created', function ( $plugin ) {
49
+ $plugin->set_adverts_manager( "WBCR\Factory_Adverts_102\Base" );
50
+ } );
libs/factory/adverts/includes/class-base.php ADDED
@@ -0,0 +1,319 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace WBCR\Factory_Adverts_102;
4
+
5
+ // Exit if accessed directly
6
+ if ( ! defined( 'ABSPATH' ) ) {
7
+ exit;
8
+ }
9
+
10
+ /**
11
+ * Base class for adverts module.
12
+ *
13
+ * Contains methods for retrieving banner data for a specific position.
14
+ * With this class user cat get advert content for a specific position.
15
+ * This class use functional design pattern.
16
+ *
17
+ * @author Alexander Vitkalov <nechin.va@gmail.com>
18
+ * @author Alexander Kovalev <alex.kovalevv@gmail.com>, Github: https://github.com/alexkovalevv
19
+ *
20
+ * @since 1.0.0 Added
21
+ * @package factory-adverts
22
+ * @copyright (c) 2019 Webcraftic Ltd
23
+ */
24
+ class Base {
25
+
26
+ /**
27
+ * Экзепляр плагина с которым взаимодействует этот модуль
28
+ *
29
+ * @author Alexander Kovalev <alex.kovalevv@gmail.com>
30
+ * @since 1.0.1
31
+ * @var \Wbcr_Factory420_Plugin
32
+ */
33
+ private $plugin;
34
+
35
+ /*
36
+ * Contain array data with the plugin information and the module settings.
37
+ * Mainly used to get the name of the plugin and how to get the adverts blocks.
38
+ *
39
+ * @since 1.0.0 Added
40
+ *
41
+ * @var array Example: array(
42
+ * 'dashboard_widget' => true,
43
+ * 'right_sidebar' => true,
44
+ * 'notice' => true,
45
+ * ...
46
+ * )
47
+ *
48
+ */
49
+ private $settings = [];
50
+
51
+ /**
52
+ * Экземпляр класса для работы API CreativeMotion
53
+ *
54
+ * @author Alexander Kovalev <alex.kovalevv@gmail.com>
55
+ * @since 1.0.1
56
+ * @var \WBCR\Factory_Adverts_102\Creative_Motion_API
57
+ */
58
+ private $api;
59
+
60
+ /**
61
+ * Сохраняем уже полученные данные, для объектного кеширования
62
+ *
63
+ * @author Alexander Kovalev <alex.kovalevv@gmail.com>
64
+ * @since 1.0.1
65
+ * @var array
66
+ */
67
+ private $placements = [];
68
+
69
+ /**
70
+ * @author Alexander Kovalev <alex.kovalevv@gmail.com>
71
+ * @since 1.0.1
72
+ * @var array
73
+ */
74
+ private $errors = [];
75
+
76
+ /**
77
+ * Wbcr_Factory_Adinserter constructor.
78
+ *
79
+ * - Store plugin information and settings.
80
+ * - Add filter and actions.
81
+ * - Include dashboard widget.
82
+ *
83
+ * @since 1.0.0 Added
84
+ *
85
+ * @param \Wbcr_Factory420_Plugin $plugin
86
+ */
87
+ public function __construct( \Wbcr_Factory420_Plugin $plugin, $settings ) {
88
+ $this->plugin = $plugin;
89
+
90
+ $this->settings = wp_parse_args( $settings, [
91
+ 'dashboard_widget' => false, // show dashboard widget (default: false)
92
+ 'right_sidebar' => false, // show adverts sidebar (default: false)
93
+ 'notice' => false, // show notice message (default: false),
94
+ 'business_suggetion' => false,
95
+ 'support' => false
96
+ ] );
97
+
98
+ $this->api = new Creative_Motion_API( $this->plugin );
99
+
100
+ add_filter( 'wbcr/factory/pages/impressive/widgets', [ $this, 'register_plugin_widgets' ], 10, 3 );
101
+ add_action( 'wbcr/factory/admin_notices', [ $this, 'register_plugin_notice' ], 10, 2 );
102
+ add_action( 'current_screen', [ $this, 'register_dashboard_widget' ], 10, 2 );
103
+ }
104
+
105
+ /**
106
+ * Directly get advert content for selected position.
107
+ *
108
+ * @since 1.0.1 Rename method. Content should now be printed.
109
+ * @since 1.0.0 Added
110
+ *
111
+ * @param string $position Custom position name
112
+ *
113
+ * @return void
114
+ */
115
+ public function render_placement( $position = 'right_sidebar' ) {
116
+ $content = '';
117
+
118
+ if ( $position ) {
119
+ $content = $this->get_content( $position );
120
+ }
121
+
122
+ echo $content;
123
+ }
124
+
125
+ /**
126
+ * Register widgets.
127
+ *
128
+ * Depending on the settings, register new widgets.
129
+ *
130
+ * @since 1.0.0 Added
131
+ *
132
+ * @param array $widgets Already existing registered widgets
133
+ * @param string $position Position for the widget
134
+ * @param string $plugin Plugin object for which the hook is run
135
+ *
136
+ * @return array array(
137
+ * 'adverts_widget' => '<p></p>',
138
+ * 'business_suggetion' => '<p></p>',
139
+ * 'support' => '<p></p>',
140
+ * ...
141
+ * )
142
+ */
143
+ public function register_plugin_widgets( $widgets, $position, $plugin ) {
144
+ if ( $plugin->getPluginName() == $this->plugin->getPluginName() && 'right' == $position ) {
145
+
146
+ if ( $this->settings['right_sidebar'] ) {
147
+ $content = $this->get_content( 'right_sidebar' );
148
+ $widgets['adverts_widget'] = $content;
149
+
150
+ if ( empty( $widgets['adverts_widget'] ) ) {
151
+ if ( defined( 'FACTORY_ADVERTS_DEBUG' ) && FACTORY_ADVERTS_DEBUG ) {
152
+ $debug_message = '<div style="background: #fff4f1;padding: 10px;color: #a58074;">';
153
+ $debug_message .= $this->get_debug_message( 'right_sidebar' );
154
+ $debug_message .= '</div>';
155
+
156
+ $widgets['adverts_widget'] = $debug_message;
157
+ } else {
158
+ unset( $widgets['adverts_widget'] );
159
+ }
160
+ }
161
+ }
162
+
163
+ if ( $this->settings['business_suggetion'] ) {
164
+ $content = $this->get_content( 'business_suggetion' );
165
+
166
+ if ( ! empty( $content ) ) {
167
+ $widgets['business_suggetion'] = $content;
168
+ }
169
+ }
170
+
171
+ if ( $this->settings['support'] ) {
172
+ $content = $this->get_content( 'support' );
173
+
174
+ if ( ! empty( $content ) ) {
175
+ $widgets['support'] = $content;
176
+ }
177
+ }
178
+ }
179
+
180
+ return $widgets;
181
+ }
182
+
183
+ /**
184
+ * Регистрирует уведомление для текущего плагина
185
+ *
186
+ * Мы добавляем уведомления в массив всех уведомлений плагина с ключем 'adverts_notice',
187
+ * то есть если другие плагины, тоже добавят свои рекламные уведомления, они просто
188
+ * будут перезаписывать друг друга, в итоге будет отображено только одно рекламное
189
+ * уведомеление. Это нужно для того, чтобы ограничить пользователя от спама.
190
+ *
191
+ * @author Alexander Kovalev <alex.kovalevv@gmail.com>
192
+ *
193
+ * @since 1.0.1 Переделан полностью под интферфейс фреймворка. Используем встроенную систему уведомлений.
194
+ * @since 1.0.0 Added
195
+ *
196
+ * @param array $notices Массив со списком всех уведомлений, которые будут напечатыны в админ панели
197
+ * @param string $plugin_name Имя плагина, передано для того, чтобы выводить уведомления условно, только для конкретного плагина
198
+ */
199
+ public function register_plugin_notice( $notices, $plugin_name ) {
200
+ if ( $plugin_name !== $this->plugin->getPluginName() ) {
201
+ return $notices;
202
+ }
203
+
204
+ if ( $this->settings['notice'] ) {
205
+ $notice_content = $this->get_content( 'notice' );
206
+
207
+ if ( empty( $notice_content ) ) {
208
+ # Информация для отладки
209
+ if ( defined( 'FACTORY_ADVERTS_DEBUG' ) && FACTORY_ADVERTS_DEBUG ) {
210
+ $debug_message = $this->get_debug_message( 'notice' );
211
+
212
+ $notices['adverts_notice'] = [
213
+ 'id' => 'adverts_debug',
214
+ 'type' => 'error',
215
+ 'dismissible' => false,
216
+ 'dismiss_expires' => 0,
217
+ 'text' => '<p><b>' . $this->plugin->getPluginTitle() . '</b>:<br>' . $debug_message . '</p>'
218
+ ];
219
+ }
220
+
221
+ return $notices;
222
+ }
223
+
224
+ $hash = md5( $notice_content );
225
+
226
+ $notices['adverts_notice'] = [
227
+ 'id' => 'adverts_' . $hash,
228
+ 'type' => 'success',
229
+ 'dismissible' => true,
230
+ 'dismiss_expires' => 0,
231
+ 'text' => '<p><b>' . $this->plugin->getPluginTitle() . '</b>:<br>' . $notice_content . '</p>'
232
+ ];
233
+ }
234
+
235
+ return $notices;
236
+ }
237
+
238
+ /**
239
+ * Include dashboard widget
240
+ *
241
+ * Include functionality the output of the widget on the dashboard.
242
+ * Only one dashboard widget must be shown for some plugins with this setting (dashboard_widget).
243
+ *
244
+ * @since 1.0.0 Added
245
+ */
246
+ public function register_dashboard_widget() {
247
+ if ( $this->settings['dashboard_widget'] && current_user_can( 'manage_options' ) ) {
248
+ $current_screen = get_current_screen();
249
+
250
+ if ( ! in_array( $current_screen->id, [ 'dashboard', 'dashboard-network' ] ) ) {
251
+ return;
252
+ }
253
+
254
+ $content = $this->get_content( 'dashboard_widget' );
255
+
256
+ if ( empty( $content ) && defined( 'FACTORY_ADVERTS_DEBUG' ) && FACTORY_ADVERTS_DEBUG ) {
257
+ $content = $this->get_debug_message( 'dashboard_widget' );
258
+ }
259
+
260
+ require_once FACTORY_ADVERTS_102_DIR . '/includes/class-dashboard-widget.php';
261
+ new Dashboard_Widget( $this->plugin, $content );
262
+ }
263
+ }
264
+
265
+ /**
266
+ * Позволяет получить сообщение об ошибках
267
+ *
268
+ * Метод проверяет последние ошибки, которые могли произойти в результате api запроса.
269
+ * Если ошибки есть, он выводит предупреждение и список последних ошибок. Если ошибок нет,
270
+ * метод вернет просто предупреждение, что реклама не настроена.
271
+ *
272
+ * @author Alexander Kovalev <alex.kovalevv@gmail.com>
273
+ * @since 1.0.1
274
+ *
275
+ * @param string $position Position for the widget
276
+ *
277
+ * @return string Возвращает сообщение с последниеми ошибками для отладки
278
+ */
279
+ private function get_debug_message( $position ) {
280
+ $debug_massage = 'Plugin ads not configured or server unavailable. See full error report below.<br>';
281
+
282
+ if ( isset( $this->errors[ $position ] ) && ! empty( $this->errors ) ) {
283
+ $debug_massage .= '<b>Last errors:</b><br>';
284
+ foreach ( $this->errors[ $position ] as $error_code => $error_message ) {
285
+ $debug_massage .= 'Code: ' . $error_code . ' Error: ' . $error_message . '<br>';
286
+ }
287
+ }
288
+
289
+ return $debug_massage;
290
+ }
291
+
292
+ /**
293
+ * Get advert content for selected position.
294
+ *
295
+ * @since 1.0.1 Полностью переписан
296
+ * @since 1.0.0 Added
297
+ *
298
+ * @param string $position The position for advert
299
+ *
300
+ * @return string
301
+ */
302
+ private function get_content( $position ) {
303
+ if ( isset( $this->placements[ $position ] ) ) {
304
+ return $this->placements[ $position ];
305
+ }
306
+
307
+ $content = $this->api->get_content( $position );
308
+
309
+ if ( is_wp_error( $content ) ) {
310
+ $this->errors[ $position ][ $content->get_error_code() ] = $content->get_error_message();
311
+
312
+ return null;
313
+ }
314
+
315
+ $this->placements[ $position ] = $content;
316
+
317
+ return $content;
318
+ }
319
+ }
libs/factory/adverts/includes/class-dashboard-widget.php ADDED
@@ -0,0 +1,125 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace WBCR\Factory_Adverts_102;
4
+
5
+ // Exit if accessed directly
6
+ if ( ! defined( 'ABSPATH' ) ) {
7
+ exit;
8
+ }
9
+
10
+ /**
11
+ * Adverts Dashboard Widget.
12
+ *
13
+ * Adds a widget with a banner or a list of news.
14
+ *
15
+ * @author Alexander Vitkalov <nechin.va@gmail.com>
16
+ * @author Alexander Kovalev <alex.kovalevv@gmail.com>, Github: https://github.com/alexkovalevv
17
+ *
18
+ * @since 1.0.0 Added
19
+ * @package factory-adverts
20
+ * @copyright (c) 2019 Webcraftic Ltd
21
+ */
22
+ class Dashboard_Widget {
23
+
24
+ /**
25
+ * Контент, который должен быть напечатан внутри дашбоард виджета
26
+ *
27
+ * @author Alexander Kovalev <alex.kovalevv@gmail.com>
28
+ * @since 1.0.1
29
+ * @var string
30
+ */
31
+ private $content;
32
+
33
+ /**
34
+ * Экзепляр плагина с которым взаимодействует этот модуль
35
+ *
36
+ * @author Alexander Kovalev <alex.kovalevv@gmail.com>
37
+ * @since 1.0.1
38
+ * @var \Wbcr_Factory420_Plugin
39
+ */
40
+ private $plugin;
41
+
42
+ /**
43
+ * Dashboard_Widget constructor.
44
+ *
45
+ * Call parent constructor. Registration hooks.
46
+ *
47
+ * @since 1.0.0 Added
48
+ *
49
+ * @param \Wbcr_Factory420_Plugin $plugin
50
+ * @param string $content
51
+ */
52
+ public function __construct( \Wbcr_Factory420_Plugin $plugin, $content ) {
53
+
54
+ $this->plugin = $plugin;
55
+ $this->content = $content;
56
+
57
+ if ( ! empty( $this->content ) ) {
58
+ if ( $this->plugin->isNetworkActive() && $this->plugin->isNetworkAdmin() ) {
59
+ add_action( 'wp_network_dashboard_setup', [ $this, 'add_dashboard_widgets' ], 999 );
60
+
61
+ return;
62
+ }
63
+
64
+ add_action( 'wp_dashboard_setup', [ $this, 'add_dashboard_widgets' ], 999 );
65
+ }
66
+ }
67
+
68
+ /**
69
+ * Add the News widget to the dashboard.
70
+ *
71
+ * @since 1.0.0 Added
72
+ */
73
+ public function add_dashboard_widgets() {
74
+ $widget_id = 'wbcr-factory-adverts-widget';
75
+
76
+ wp_add_dashboard_widget( $widget_id, $this->plugin->getPluginTitle() . ' News', [
77
+ $this,
78
+ 'print_widget_content'
79
+ ] );
80
+
81
+ $this->sort_dashboard_widgets( $widget_id );
82
+ }
83
+
84
+ /**
85
+ * Create the function to output the contents of the Dashboard Widget.
86
+ *
87
+ * @since 1.0.0 Added
88
+ */
89
+ public function print_widget_content() {
90
+ ?>
91
+ <div class="wordpress-news hide-if-no-js">
92
+ <div class="rss-widget">
93
+ <?php echo $this->content; ?>
94
+ </div>
95
+ </div>
96
+ <?php
97
+
98
+ }
99
+
100
+ /**
101
+ * Сортируем виджеты на странице дашбоард
102
+ *
103
+ * Виджеты должны быть в таком порядке, чтобы наш виджет был выше всех.
104
+ *
105
+ * @author Alexander Kovalev <alex.kovalevv@gmail.com>
106
+ * @author Alexander Vitkalov <nechin.va@gmail.com>
107
+ *
108
+ * @since 1.0.2 Добавлена поддержка мультисайтов
109
+ * @since 1.0.0 Добавлен
110
+ *
111
+ * @param string $widget_id ID нашего виджета
112
+ */
113
+ private function sort_dashboard_widgets( $widget_id ) {
114
+ global $wp_meta_boxes;
115
+
116
+ $location = $this->plugin->isNetworkAdmin() ? 'dashboard-network' : 'dashboard';
117
+
118
+ $normal_core = $wp_meta_boxes[ $location ]['normal']['core'];
119
+ $widget_backup = [ $widget_id => $normal_core[ $widget_id ] ];
120
+ unset( $normal_core[ $widget_id ] );
121
+ $sorted_core = array_merge( $widget_backup, $normal_core );
122
+
123
+ $wp_meta_boxes['dashboard']['normal']['core'] = $sorted_core;
124
+ }
125
+ }
libs/factory/adverts/includes/class-rest-request.php ADDED
@@ -0,0 +1,197 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace WBCR\Factory_Adverts_102;
4
+
5
+ // Exit if accessed directly
6
+ if ( ! defined( 'ABSPATH' ) ) {
7
+ exit;
8
+ }
9
+
10
+ /**
11
+ * Factory request class.
12
+ *
13
+ * Performs a server request, retrieves banner data and stores it in the cache.
14
+ *
15
+ * @author Alexander Kovalev <alex.kovalevv@gmail.com>, Github: https://github.com/alexkovalevv
16
+ * @author Alexander Vitkalov <nechin.va@gmail.com>
17
+ *
18
+ * @since 1.0.1 Изменил имя класса и доработал его.
19
+ * @since 1.0.0 Added
20
+ *
21
+ * @package factory-adverts
22
+ * @copyright (c) 2019 Webcraftic Ltd
23
+ */
24
+ class Creative_Motion_API {
25
+
26
+ /**
27
+ * Rest request url.
28
+ *
29
+ * Define rest request url for rest request to remote server.
30
+ *
31
+ * @since 1.2.1
32
+ */
33
+ const SERVER_URL = 'https://api.cm-wp.com';
34
+
35
+ /**
36
+ * Rest route path.
37
+ *
38
+ * Define rest route path for rest request.
39
+ *
40
+ * @since 1.0.0
41
+ */
42
+ const REST_ROUTE = '/adverds/v1/advt';
43
+
44
+ /**
45
+ * Интервал между запросами по умолчанию
46
+ *
47
+ * Значение в часах.
48
+ *
49
+ * @since 1.0.1
50
+ */
51
+ const DEFAULT_REQUESTS_INTERVAL = 24;
52
+
53
+ /**
54
+ * Интервал между запросами, если сервер недоступен
55
+ *
56
+ * Значение в часах.
57
+ *
58
+ * @since 1.0.1
59
+ */
60
+ const SERVER_UNAVAILABLE_INTERVAL = 4;
61
+
62
+
63
+ /**
64
+ * Экзепляр плагина с которым взаимодействует этот модуль
65
+ *
66
+ * @author Alexander Kovalev <alex.kovalevv@gmail.com>
67
+ * @since 1.0.1
68
+ * @var \Wbcr_Factory420_Plugin
69
+ */
70
+ private $plugin;
71
+
72
+
73
+ /**
74
+ * Request constructor.
75
+ *
76
+ * Variable initialization.
77
+ *
78
+ * @since 1.0.0 Added
79
+ *
80
+ * @param \Wbcr_Factory420_Plugin $plugin_name
81
+ */
82
+ public function __construct( \Wbcr_Factory420_Plugin $plugin ) {
83
+ $this->plugin = $plugin;
84
+ }
85
+
86
+ /**
87
+ * Get adverts content.
88
+ *
89
+ * @author Alexander Kovalev <alex.kovalevv@gmail.com>
90
+ * @since 1.0.1
91
+ *
92
+ * @param $position
93
+ *
94
+ * @return string|\WP_Error
95
+ */
96
+ public function get_content( $position ) {
97
+ $data = $this->get_cache( $position );
98
+
99
+ if ( is_wp_error( $data ) ) {
100
+ return $data;
101
+ }
102
+
103
+ return strip_tags( $data['content'], '<b>,<a>,<i>,<strong>,<img>,<ul>,<ol>,<li>' );
104
+ }
105
+
106
+ /**
107
+ * Get data from cache.
108
+ *
109
+ * If data in the cache, not empty and not expired, then get data from cache. Or get data from server.
110
+ *
111
+ * @author Alexander Kovalev <alex.kovalevv@gmail.com>
112
+ *
113
+ * @since 1.0.1 Полностью переписан, с перехватом api ошибок
114
+ * @since 1.0.0 Added
115
+ *
116
+ * @return mixed array(
117
+ * 'plugin' => 'wbcr_insert_php',
118
+ * 'content' => '<p></p>',
119
+ * 'expires' => 1563542199,
120
+ * );
121
+ */
122
+ private function get_cache( $position ) {
123
+
124
+ if ( defined( 'FACTORY_ADVERTS_DEBUG' ) && FACTORY_ADVERTS_DEBUG ) {
125
+ return $this->do_api_request( $position );
126
+ }
127
+
128
+ $key = $this->plugin->getPrefix() . md5( $position . 'advert_transient_' );
129
+
130
+ $cached = get_transient( $key );
131
+
132
+ if ( $cached !== false ) {
133
+ if ( isset( $cached['error_code'] ) && isset( $cached['error'] ) ) {
134
+ return new \WP_Error( $cached['error_code'], $cached['error'] );
135
+ }
136
+
137
+ return $cached;
138
+ }
139
+
140
+ $data = $this->do_api_request( $position );
141
+
142
+ if ( is_wp_error( $data ) ) {
143
+ set_transient( $key, [
144
+ 'error' => $data->get_error_message(),
145
+ 'error_code' => $data->get_error_code()
146
+ ], self::SERVER_UNAVAILABLE_INTERVAL * HOUR_IN_SECONDS );
147
+
148
+ return $data;
149
+ }
150
+
151
+ set_transient( $key, $data, $data['expires'] );
152
+
153
+ return $data;
154
+ }
155
+
156
+ /**
157
+ * Performs rest api request.
158
+ *
159
+ * In some case on the server (Apache) in the .htaccess must be set
160
+ * RewriteRule ^wp-json/(.*)[?](.*) /?rest_route=/$1&$2 [L]
161
+ *
162
+ * @since 1.0.1 Добавлен перехват ошибок, рефакторинг кода.
163
+ * @since 1.0.0 Added
164
+ *
165
+ * @return mixed array(
166
+ * 'plugin' => 'wbcr_insert_php',
167
+ * 'content' => '<p></p>',
168
+ * 'expires' => 1563542199,
169
+ * );
170
+ */
171
+ private function do_api_request( $position ) {
172
+ $default_result = [
173
+ 'content' => '',
174
+ 'expires' => self::DEFAULT_REQUESTS_INTERVAL * HOUR_IN_SECONDS,
175
+ ];
176
+
177
+ $url = untrailingslashit( self::SERVER_URL ) . '/wp-json' . self::REST_ROUTE;
178
+ $url = add_query_arg( [ 'plugin' => $this->plugin->getPluginName(), 'position' => $position ], $url );
179
+
180
+ $response = wp_remote_get( $url );
181
+
182
+ $code = wp_remote_retrieve_response_code( $response );
183
+ $body = wp_remote_retrieve_body( $response );
184
+
185
+ $data = @json_decode( $body, true );
186
+
187
+ if ( is_wp_error( $response ) ) {
188
+ return $response;
189
+ }
190
+
191
+ if ( 200 !== $code ) {
192
+ return new \WP_Error( 'http_request_error', 'Failed request to the remote server. Code: ' . $code );
193
+ }
194
+
195
+ return wp_parse_args( $data, $default_result );
196
+ }
197
+ }
libs/factory/adverts/includes/index.php ADDED
@@ -0,0 +1,2 @@
 
 
1
+ <?php
2
+ // Silence is golden.
libs/factory/adverts/index.php ADDED
@@ -0,0 +1,2 @@
 
 
1
+ <?php
2
+ // Silence is golden.
libs/factory/adverts/langs/wbcr_factory_adverts_102-ru_RU.mo ADDED
Binary file
libs/factory/adverts/langs/wbcr_factory_adverts_102-ru_RU.po ADDED
@@ -0,0 +1,83 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ msgid ""
2
+ msgstr ""
3
+ "Project-Id-Version: factory_forms\n"
4
+ "POT-Creation-Date: 2018-10-16 22:44+0300\n"
5
+ "PO-Revision-Date: 2018-10-16 22:45+0300\n"
6
+ "Last-Translator: \n"
7
+ "Language-Team: Alex Kovalev <alex.kovalevv@gmail.com>\n"
8
+ "Language: ru_RU\n"
9
+ "MIME-Version: 1.0\n"
10
+ "Content-Type: text/plain; charset=UTF-8\n"
11
+ "Content-Transfer-Encoding: 8bit\n"
12
+ "X-Generator: Poedit 2.1.1\n"
13
+ "X-Poedit-Basepath: ..\n"
14
+ "Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
15
+ "%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
16
+ "X-Poedit-SourceCharset: UTF-8\n"
17
+ "X-Poedit-KeywordsList: __;_e;_n:1,2;_x:1,2c;_ex:1,2c\n"
18
+ "X-Poedit-SearchPath-0: .\n"
19
+
20
+ #: includes/check-compatibility.php:80
21
+ msgid "warning"
22
+ msgstr "предупреждение"
23
+
24
+ #: includes/check-compatibility.php:82
25
+ #, php-format
26
+ msgid "The %s plugin has stopped."
27
+ msgstr "Работа плагина %s была остановлена."
28
+
29
+ #: includes/check-compatibility.php:83
30
+ msgid "Possible reasons:"
31
+ msgstr "Возможные причины:"
32
+
33
+ #: includes/check-compatibility.php:89
34
+ #, php-format
35
+ msgid "You need to update the PHP version to %s or higher!"
36
+ msgstr "Вам нужно обновить версию PHP до %s или выше!"
37
+
38
+ #: includes/check-compatibility.php:94
39
+ #, php-format
40
+ msgid "You need to update WordPress to %s or higher!"
41
+ msgstr "Вам нужно обновить WordPress до %s или выше!"
42
+
43
+ #: includes/functions.php:132
44
+ #, php-format
45
+ msgid ""
46
+ "%1$s is <strong>deprecated</strong> since version %2$s! Use %3$s instead."
47
+ msgstr ""
48
+ "%1$s является <strong>устаревшим,</strong> начиная с версии %2$s в "
49
+ "Wordpress! Используйте %3$s."
50
+
51
+ #: includes/functions.php:134
52
+ #, php-format
53
+ msgid ""
54
+ "%1$s is <strong>deprecated</strong> since version %2$s with no alternative "
55
+ "available."
56
+ msgstr ""
57
+ "%1$s был вызван с параметром, который является <strong>устаревшими</strong> "
58
+ "начиная с версии %2$s , в настоящее время доступных альтернатив нет."
59
+
60
+ #: includes/plugin.class.php:202 includes/plugin.class.php:237
61
+ msgid ""
62
+ "You are trying to call this earlier than the plugin menu will be registered."
63
+ msgstr ""
64
+ "Вы пытаетесь вызвать это раньше, чем будет зарегистрировано меню плагина."
65
+
66
+ #: includes/plugin.class.php:220
67
+ msgid ""
68
+ "You are trying to get a link to a page that does not have multisite mode. "
69
+ "Clicking this link will lead the user to a non-existent page."
70
+ msgstr ""
71
+ "Вы пытаетесь получить ссылку на страницу, которая не имеет "
72
+ "многопользовательского режима. Щелчок по этой ссылке приведет пользователя "
73
+ "к несуществующей странице."
74
+
75
+ #: includes/plugin.class.php:222
76
+ msgid ""
77
+ "Trying to get a link to an unregistered page. You are trying to call this "
78
+ "earlier than the plugin menu will be registered."
79
+ msgstr ""
80
+ "Попытка получить ссылку на незарегистрированную страницу. Вы пытаетесь "
81
+ "вызвать это раньше, чем будет зарегистрировано меню плагина."
82
+
83
+
libs/factory/bootstrap/assets/css-min/bootstrap.accordion.min.css CHANGED
@@ -8,4 +8,4 @@
8
  */
9
 
10
 
11
- .factory-bootstrap-400 .factory-accordion{margin:0 0 30px;border-top:1px solid #DDD;border-right:1px solid #DDD;border-left:1px solid #DDD;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.factory-bootstrap-400 .factory-accordion>h3{border-bottom:1px solid #DDD;cursor:pointer;padding:8px 15px;margin:0}.factory-bootstrap-400 .factory-accordion>div{display:none;margin:0;border-bottom:1px solid #DDD}.factory-bootstrap-400 .factory-accordion-item{display:none}.factory-bootstrap-400 .inner-factory-accordion-item{padding:10px 0}.factory-bootstrap-400 .factory-accordion>h3.active:hover{cursor:default}
8
  */
9
 
10
 
11
+ .factory-bootstrap-421 .factory-accordion{margin:0 0 30px;border-top:1px solid #DDD;border-right:1px solid #DDD;border-left:1px solid #DDD;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.factory-bootstrap-421 .factory-accordion>h3{border-bottom:1px solid #DDD;cursor:pointer;padding:8px 15px;margin:0}.factory-bootstrap-421 .factory-accordion>div{display:none;margin:0;border-bottom:1px solid #DDD}.factory-bootstrap-421 .factory-accordion-item{display:none}.factory-bootstrap-421 .inner-factory-accordion-item{padding:10px 0}.factory-bootstrap-421 .factory-accordion>h3.active:hover{cursor:default}
libs/factory/bootstrap/assets/css-min/bootstrap.blue.min.css CHANGED
@@ -8,4 +8,4 @@
8
  */
9
 
10
 
11
- .factory-bootstrap-400 .btn-primary{background:#e1a948;border-color:#d39323;color:#fff;-webkit-box-shadow:inset 0 1px 0 #ecc88a,0 1px 0 rgba(0,0,0,.15);box-shadow:inset 0 1px 0 #ecc88a,0 1px 0 rgba(0,0,0,.15)}.factory-bootstrap-400 .btn-primary:focus,.factory-bootstrap-400 .btn-primary:hover{background:#db9825;border-color:#bd831f;color:#fff;-webkit-box-shadow:inset 0 1px 0 #e8be74,0 1px 0 rgba(0,0,0,.15);box-shadow:inset 0 1px 0 #e8be74,0 1px 0 rgba(0,0,0,.15)}.factory-bootstrap-400 .btn-primary:active{background:#db9825;border-color:#bd831f;color:#fff;-webkit-box-shadow:inset 0 2px 5px -3px rgba(0,0,0,.5);box-shadow:inset 0 2px 5px -3px rgba(0,0,0,.5)}.factory-bootstrap-400 .btn-primary:disabled,.factory-bootstrap-400 .btn-primary[disabled]{color:#d1cdc7!important;background:#db9825!important;border-color:#bd831f!important;text-shadow:none!important}.factory-bootstrap-400 .btn-group .btn.active.value{background-color:#e1a948;-webkit-box-shadow:inset 0 1px 2px #d39323;box-shadow:inset 0 1px 2px #d39323;border-top:1px solid #d39323;border-bottom:1px solid #d39323;border-left:1px solid #d39323}.factory-bootstrap-400 .pagination>.active>a,.factory-bootstrap-400 .pagination>.active>a:focus,.factory-bootstrap-400 .pagination>.active>a:hover,.factory-bootstrap-400 .pagination>.active>span,.factory-bootstrap-400 .pagination>.active>span:focus,.factory-bootstrap-400 .pagination>.active>span:hover{background-color:#e1a948;border-color:#d39323}
8
  */
9
 
10
 
11
+ .factory-bootstrap-421 .btn-primary{background:#e1a948;border-color:#d39323;color:#fff;-webkit-box-shadow:inset 0 1px 0 #ecc88a,0 1px 0 rgba(0,0,0,.15);box-shadow:inset 0 1px 0 #ecc88a,0 1px 0 rgba(0,0,0,.15)}.factory-bootstrap-421 .btn-primary:focus,.factory-bootstrap-421 .btn-primary:hover{background:#db9825;border-color:#bd831f;color:#fff;-webkit-box-shadow:inset 0 1px 0 #e8be74,0 1px 0 rgba(0,0,0,.15);box-shadow:inset 0 1px 0 #e8be74,0 1px 0 rgba(0,0,0,.15)}.factory-bootstrap-421 .btn-primary:active{background:#db9825;border-color:#bd831f;color:#fff;-webkit-box-shadow:inset 0 2px 5px -3px rgba(0,0,0,.5);box-shadow:inset 0 2px 5px -3px rgba(0,0,0,.5)}.factory-bootstrap-421 .btn-primary:disabled,.factory-bootstrap-421 .btn-primary[disabled]{color:#d1cdc7!important;background:#db9825!important;border-color:#bd831f!important;text-shadow:none!important}.factory-bootstrap-421 .btn-group .btn.active.value{background-color:#e1a948;-webkit-box-shadow:inset 0 1px 2px #d39323;box-shadow:inset 0 1px 2px #d39323;border-top:1px solid #d39323;border-bottom:1px solid #d39323;border-left:1px solid #d39323}.factory-bootstrap-421 .pagination>.active>a,.factory-bootstrap-421 .pagination>.active>a:focus,.factory-bootstrap-421 .pagination>.active>a:hover,.factory-bootstrap-421 .pagination>.active>span,.factory-bootstrap-421 .pagination>.active>span:focus,.factory-bootstrap-421 .pagination>.active>span:hover{background-color:#e1a948;border-color:#d39323}
libs/factory/bootstrap/assets/css-min/bootstrap.coffee.min.css CHANGED
@@ -8,4 +8,4 @@
8
  */
9
 
10
 
11
- .factory-bootstrap-400 .btn-primary{background:#c7a589;border-color:#b78a66;color:#fff;-webkit-box-shadow:inset 0 1px 0 #e0cdbd,0 1px 0 rgba(0,0,0,.15);box-shadow:inset 0 1px 0 #e0cdbd,0 1px 0 rgba(0,0,0,.15)}.factory-bootstrap-400 .btn-primary:focus,.factory-bootstrap-400 .btn-primary:hover{background:#ba906d;border-color:#ae7d55;color:#fff;-webkit-box-shadow:inset 0 1px 0 #d7bfac,0 1px 0 rgba(0,0,0,.15);box-shadow:inset 0 1px 0 #d7bfac,0 1px 0 rgba(0,0,0,.15)}.factory-bootstrap-400 .btn-primary:active{background:#ba906d;border-color:#ae7d55;color:#fff;-webkit-box-shadow:inset 0 2px 5px -3px rgba(0,0,0,.5);box-shadow:inset 0 2px 5px -3px rgba(0,0,0,.5)}.factory-bootstrap-400 .btn-primary:disabled,.factory-bootstrap-400 .btn-primary[disabled]{color:#d1cbc7!important;background:#ba906d!important;border-color:#ae7d55!important;text-shadow:none!important}.factory-bootstrap-400 .btn-group .btn.active.value{background-color:#c7a589;-webkit-box-shadow:inset 0 1px 2px #b78a66;box-shadow:inset 0 1px 2px #b78a66;border-top:1px solid #b78a66;border-bottom:1px solid #b78a66;border-left:1px solid #b78a66}.factory-bootstrap-400 .pagination>.active>a,.factory-bootstrap-400 .pagination>.active>a:focus,.factory-bootstrap-400 .pagination>.active>a:hover,.factory-bootstrap-400 .pagination>.active>span,.factory-bootstrap-400 .pagination>.active>span:focus,.factory-bootstrap-400 .pagination>.active>span:hover{background-color:#c7a589;border-color:#b78a66}
8
  */
9
 
10
 
11
+ .factory-bootstrap-421 .btn-primary{background:#c7a589;border-color:#b78a66;color:#fff;-webkit-box-shadow:inset 0 1px 0 #e0cdbd,0 1px 0 rgba(0,0,0,.15);box-shadow:inset 0 1px 0 #e0cdbd,0 1px 0 rgba(0,0,0,.15)}.factory-bootstrap-421 .btn-primary:focus,.factory-bootstrap-421 .btn-primary:hover{background:#ba906d;border-color:#ae7d55;color:#fff;-webkit-box-shadow:inset 0 1px 0 #d7bfac,0 1px 0 rgba(0,0,0,.15);box-shadow:inset 0 1px 0 #d7bfac,0 1px 0 rgba(0,0,0,.15)}.factory-bootstrap-421 .btn-primary:active{background:#ba906d;border-color:#ae7d55;color:#fff;-webkit-box-shadow:inset 0 2px 5px -3px rgba(0,0,0,.5);box-shadow:inset 0 2px 5px -3px rgba(0,0,0,.5)}.factory-bootstrap-421 .btn-primary:disabled,.factory-bootstrap-421 .btn-primary[disabled]{color:#d1cbc7!important;background:#ba906d!important;border-color:#ae7d55!important;text-shadow:none!important}.factory-bootstrap-421 .btn-group .btn.active.value{background-color:#c7a589;-webkit-box-shadow:inset 0 1px 2px #b78a66;box-shadow:inset 0 1px 2px #b78a66;border-top:1px solid #b78a66;border-bottom:1px solid #b78a66;border-left:1px solid #b78a66}.factory-bootstrap-421 .pagination>.active>a,.factory-bootstrap-421 .pagination>.active>a:focus,.factory-bootstrap-421 .pagination>.active>a:hover,.factory-bootstrap-421 .pagination>.active>span,.factory-bootstrap-421 .pagination>.active>span:focus,.factory-bootstrap-421 .pagination>.active>span:hover{background-color:#c7a589;border-color:#b78a66}
libs/factory/bootstrap/assets/css-min/bootstrap.core.min.css CHANGED
@@ -8,7 +8,7 @@
8
  */
9
 
10
 
11
- .factory-bootstrap-400 article,.factory-bootstrap-400 aside,.factory-bootstrap-400 details,.factory-bootstrap-400 figcaption,.factory-bootstrap-400 figure,.factory-bootstrap-400 footer,.factory-bootstrap-400 header,.factory-bootstrap-400 hgroup,.factory-bootstrap-400 main,.factory-bootstrap-400 nav,.factory-bootstrap-400 section,.factory-bootstrap-400 summary{display:block}.factory-bootstrap-400 audio,.factory-bootstrap-400 canvas,.factory-bootstrap-400 video{display:inline-block}.factory-bootstrap-400 audio:not([controls]){display:none;height:0}.factory-bootstrap-400 [hidden],.factory-bootstrap-400 template{display:none}.factory-bootstrap-400 body{margin:0}.factory-bootstrap-400 a{background:0 0}.factory-bootstrap-400 a:focus{outline:thin dotted}.factory-bootstrap-400 a:active,.factory-bootstrap-400 a:hover{outline:0}.factory-bootstrap-400 h1{margin:.67em 0}.factory-bootstrap-400 b,.factory-bootstrap-400 strong{font-weight:700}.factory-bootstrap-400 dfn{font-style:italic}.factory-bootstrap-400 hr{height:0;-moz-box-sizing:content-box;box-sizing:content-box}.factory-bootstrap-400 mark{color:#000;background:#ff0}.factory-bootstrap-400 code,.factory-bootstrap-400 kbd,.factory-bootstrap-400 pre,.factory-bootstrap-400 samp{font-size:1em}.factory-bootstrap-400 pre{white-space:pre-wrap}.factory-bootstrap-400 q{quotes:"\201C" "\201D" "\2018" "\2019"}.factory-bootstrap-400 sub,.factory-bootstrap-400 sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}.factory-bootstrap-400 sup{top:-.5em}.factory-bootstrap-400 sub{bottom:-.25em}.factory-bootstrap-400 img{border:0}.factory-bootstrap-400 svg:not(:root){overflow:hidden}.factory-bootstrap-400 figure{margin:0}.factory-bootstrap-400 button,.factory-bootstrap-400 input,.factory-bootstrap-400 select,.factory-bootstrap-400 textarea{margin:0}.factory-bootstrap-400 button,.factory-bootstrap-400 select{text-transform:none}.factory-bootstrap-400 select{padding-right:4px!important}.factory-bootstrap-400 button,.factory-bootstrap-400 input[type=reset],.factory-bootstrap-400 input[type=submit],html .factory-bootstrap-400 input[type=button]{cursor:pointer;-webkit-appearance:button}.factory-bootstrap-400 button[disabled],html .factory-bootstrap-400 input[disabled]{cursor:default}.factory-bootstrap-400 input[type=checkbox],.factory-bootstrap-400 input[type=radio]{padding:0;box-sizing:border-box}.factory-bootstrap-400 input[type=search]{-webkit-appearance:textfield}.factory-bootstrap-400 input[type=search]::-webkit-search-cancel-button,.factory-bootstrap-400 input[type=search]::-webkit-search-decoration{-webkit-appearance:none}.factory-bootstrap-400 button::-moz-focus-inner,.factory-bootstrap-400 input::-moz-focus-inner{padding:0;border:0}.factory-bootstrap-400 textarea{overflow:auto;vertical-align:top}.factory-bootstrap-400 table{border-collapse:collapse;border-spacing:0}@media print{.factory-bootstrap-400 *{color:#000!important;text-shadow:none!important;background:transparent!important;box-shadow:none!important}.factory-bootstrap-400 a,.factory-bootstrap-400 a:visited{text-decoration:underline}.factory-bootstrap-400 a[href]:after{content:" (" attr(href) ")"}.factory-bootstrap-400 abbr[title]:after{content:" (" attr(title) ")"}.factory-bootstrap-400 a[href^="javascript:"]:after,.factory-bootstrap-400 a[href^="#"]:after{content:""}.factory-bootstrap-400 blockquote,.factory-bootstrap-400 pre{border:1px solid #999;page-break-inside:avoid}.factory-bootstrap-400 thead{display:table-header-group}.factory-bootstrap-400 img,.factory-bootstrap-400 tr{page-break-inside:avoid}.factory-bootstrap-400 img{max-width:100%!important}@page{margin:2cm .5cm}.factory-bootstrap-400 h2,.factory-bootstrap-400 h3,.factory-bootstrap-400 p{orphans:3;widows:3}.factory-bootstrap-400 h2,.factory-bootstrap-400 h3{page-break-after:avoid}.factory-bootstrap-400 select{background:#fff!important}.factory-bootstrap-400 .navbar{display:none}.factory-bootstrap-400 .table td,.factory-bootstrap-400 .table th{background-color:#fff!important}.factory-bootstrap-400 .btn>.caret,.factory-bootstrap-400 .dropup>.btn>.caret{border-top-color:#000!important}.factory-bootstrap-400 .label{border:1px solid #000}.factory-bootstrap-400 .table{border-collapse:collapse!important}.factory-bootstrap-400 .table-bordered td,.factory-bootstrap-400 .table-bordered th{border:1px solid #ddd!important}}.factory-bootstrap-400 *,.factory-bootstrap-400 :after,.factory-bootstrap-400 :before{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html .factory-bootstrap-400{-webkit-tap-highlight-color:rgba(0,0,0,0)}.factory-bootstrap-400 body{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;line-height:1.428571429;color:#333;background-color:#fff}.factory-bootstrap-400 button,.factory-bootstrap-400 input,.factory-bootstrap-400 select,.factory-bootstrap-400 textarea{font-family:inherit;font-size:inherit;line-height:inherit}.factory-bootstrap-400 img{vertical-align:middle}.factory-bootstrap-400 .img-responsive{display:block;height:auto;max-width:100%}.factory-bootstrap-400 .img-rounded{border-radius:6px}.factory-bootstrap-400 .img-thumbnail{display:inline-block;height:auto;max-width:100%;padding:4px;line-height:1.428571429;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.factory-bootstrap-400 .img-circle{border-radius:50%}.factory-bootstrap-400 hr{margin-top:20px;margin-bottom:20px;border:0;border-top:1px solid #eee}.factory-bootstrap-400 .sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.factory-bootstrap-400 .h1,.factory-bootstrap-400 .h2,.factory-bootstrap-400 .h3,.factory-bootstrap-400 .h4,.factory-bootstrap-400 .h5,.factory-bootstrap-400 .h6,.factory-bootstrap-400 h1,.factory-bootstrap-400 h2,.factory-bootstrap-400 h3,.factory-bootstrap-400 h4,.factory-bootstrap-400 h5,.factory-bootstrap-400 h6{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-weight:500;line-height:1.1;color:inherit}.factory-bootstrap-400 .h1 .small,.factory-bootstrap-400 .h1 small,.factory-bootstrap-400 .h2 .small,.factory-bootstrap-400 .h2 small,.factory-bootstrap-400 .h3 .small,.factory-bootstrap-400 .h3 small,.factory-bootstrap-400 .h4 .small,.factory-bootstrap-400 .h4 small,.factory-bootstrap-400 .h5 .small,.factory-bootstrap-400 .h5 small,.factory-bootstrap-400 .h6 .small,.factory-bootstrap-400 .h6 small,.factory-bootstrap-400 h1 .small,.factory-bootstrap-400 h1 small,.factory-bootstrap-400 h2 .small,.factory-bootstrap-400 h2 small,.factory-bootstrap-400 h3 .small,.factory-bootstrap-400 h3 small,.factory-bootstrap-400 h4 .small,.factory-bootstrap-400 h4 small,.factory-bootstrap-400 h5 .small,.factory-bootstrap-400 h5 small,.factory-bootstrap-400 h6 .small,.factory-bootstrap-400 h6 small{font-weight:400;line-height:1;color:#999}.factory-bootstrap-400 h1,.factory-bootstrap-400 h2,.factory-bootstrap-400 h3{margin-top:20px;margin-bottom:10px}.factory-bootstrap-400 h1 .small,.factory-bootstrap-400 h1 small,.factory-bootstrap-400 h2 .small,.factory-bootstrap-400 h2 small,.factory-bootstrap-400 h3 .small,.factory-bootstrap-400 h3 small{font-size:65%}.factory-bootstrap-400 h4,.factory-bootstrap-400 h5,.factory-bootstrap-400 h6{margin-top:10px;margin-bottom:10px}.factory-bootstrap-400 h4 .small,.factory-bootstrap-400 h4 small,.factory-bootstrap-400 h5 .small,.factory-bootstrap-400 h5 small,.factory-bootstrap-400 h6 .small,.factory-bootstrap-400 h6 small{font-size:75%}.factory-bootstrap-400 .h1,.factory-bootstrap-400 h1{font-size:36px}.factory-bootstrap-400 .h2,.factory-bootstrap-400 h2{font-size:30px}.factory-bootstrap-400 .h3,.factory-bootstrap-400 h3{font-size:24px}.factory-bootstrap-400 .h4,.factory-bootstrap-400 h4{font-size:18px}.factory-bootstrap-400 .h5,.factory-bootstrap-400 h5{font-size:14px}.factory-bootstrap-400 .h6,.factory-bootstrap-400 h6{font-size:12px}.factory-bootstrap-400 p{margin:0 0 10px}.factory-bootstrap-400 .lead{margin-bottom:20px;font-size:16px;font-weight:200;line-height:1.4}@media (min-width:768px){.lead{font-size:21px}}.factory-bootstrap-400 .small,.factory-bootstrap-400 small{font-size:85%}.factory-bootstrap-400 cite{font-style:normal}.factory-bootstrap-400 .text-muted{color:#999}.factory-bootstrap-400 .text-primary{color:#428bca}.factory-bootstrap-400 .text-primary:hover{color:#3071a9}.factory-bootstrap-400 .text-warning{color:#8a6d3b}.factory-bootstrap-400 .text-warning:hover{color:#66512c}.factory-bootstrap-400 .text-danger{color:#a94442}.factory-bootstrap-400 .text-danger:hover{color:#843534}.factory-bootstrap-400 .text-success{color:#3c763d}.factory-bootstrap-400 .text-success:hover{color:#2b542c}.factory-bootstrap-400 .text-info{color:#31708f}.factory-bootstrap-400 .text-info:hover{color:#245269}.factory-bootstrap-400 .text-left{text-align:left}.factory-bootstrap-400 .text-right{text-align:right}.factory-bootstrap-400 .text-center{text-align:center}.factory-bootstrap-400 .page-header{padding-bottom:9px;margin:40px 0 20px;border-bottom:1px solid #eee}.factory-bootstrap-400 ol,.factory-bootstrap-400 ul{margin-top:0;margin-bottom:10px}.factory-bootstrap-400 ol ol,.factory-bootstrap-400 ol ul,.factory-bootstrap-400 ul ol,.factory-bootstrap-400 ul ul{margin-bottom:0}.factory-bootstrap-400 .list-inline,.factory-bootstrap-400 .list-unstyled{padding-left:0;list-style:none}.factory-bootstrap-400 .list-inline>li{display:inline-block;padding-right:5px;padding-left:5px}.factory-bootstrap-400 .list-inline>li:first-child{padding-left:0}.factory-bootstrap-400 dl{margin-top:0;margin-bottom:20px}.factory-bootstrap-400 dd,.factory-bootstrap-400 dt{line-height:1.428571429}.factory-bootstrap-400 dt{font-weight:700}.factory-bootstrap-400 dd{margin-left:0}@media (min-width:768px){.dl-horizontal dt{float:left;width:160px;overflow:hidden;clear:left;text-align:right;text-overflow:ellipsis;white-space:nowrap}.dl-horizontal dd{margin-left:180px}.dl-horizontal dd:after,.dl-horizontal dd:before{display:table;content:" "}.dl-horizontal dd:after{clear:both}}.factory-bootstrap-400 abbr[data-original-title],.factory-bootstrap-400 abbr[title]{cursor:help;border-bottom:1px dotted #999}.factory-bootstrap-400 .initialism{font-size:90%;text-transform:uppercase}.factory-bootstrap-400 blockquote{padding:10px 20px;margin:0 0 20px;border-left:5px solid #eee}.factory-bootstrap-400 blockquote p{font-size:17.5px;font-weight:300;line-height:1.25}.factory-bootstrap-400 blockquote p:last-child{margin-bottom:0}.factory-bootstrap-400 blockquote .small,.factory-bootstrap-400 blockquote small{display:block;line-height:1.428571429;color:#999}.factory-bootstrap-400 blockquote .small:before,.factory-bootstrap-400 blockquote small:before{content:'\2014 \00A0'}.factory-bootstrap-400 blockquote.pull-right{padding-right:15px;padding-left:0;border-right:5px solid #eee;border-left:0}.factory-bootstrap-400 blockquote.pull-right .small,.factory-bootstrap-400 blockquote.pull-right p,.factory-bootstrap-400 blockquote.pull-right small{text-align:right}.factory-bootstrap-400 blockquote.pull-right .small:before,.factory-bootstrap-400 blockquote.pull-right small:before{content:''}.factory-bootstrap-400 blockquote.pull-right .small:after,.factory-bootstrap-400 blockquote.pull-right small:after{content:'\00A0 \2014'}.factory-bootstrap-400 blockquote:after,.factory-bootstrap-400 blockquote:before{content:""}.factory-bootstrap-400 address{margin-bottom:20px;font-style:normal;line-height:1.428571429}.factory-bootstrap-400 code,.factory-bootstrap-400 kbd,.factory-bootstrap-400 pre,.factory-bootstrap-400 samp{font-family:Menlo,Monaco,Consolas,"Courier New",monospace}.factory-bootstrap-400 code{padding:2px 4px;font-size:90%;color:#c7254e;white-space:nowrap;background-color:#f9f2f4;border-radius:4px}.factory-bootstrap-400 pre{display:block;padding:9.5px;margin:0 0 10px;font-size:13px;line-height:1.428571429;color:#333;word-break:break-all;word-wrap:break-word;background-color:#f5f5f5;border:1px solid #ccc;border-radius:4px}.factory-bootstrap-400 pre code{padding:0;font-size:inherit;color:inherit;white-space:pre-wrap;background-color:transparent;border-radius:0}.factory-bootstrap-400 .pre-scrollable{max-height:340px;overflow-y:scroll}.factory-bootstrap-400 .container{padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}.factory-bootstrap-400 .container:after,.factory-bootstrap-400 .container:before{display:table;content:" "}.factory-bootstrap-400 .container:after{clear:both}@media (min-width:768px){.container{width:750px}}@media (min-width:992px){.container{width:970px}}@media (min-width:1200px){.container{width:1170px}}.factory-bootstrap-400 .row{margin-right:-15px;margin-left:-15px}.factory-bootstrap-400 .row:after,.factory-bootstrap-400 .row:before{display:table;content:" "}.factory-bootstrap-400 .row:after{clear:both}.factory-bootstrap-400 .col-lg-1,.factory-bootstrap-400 .col-lg-10,.factory-bootstrap-400 .col-lg-11,.factory-bootstrap-400 .col-lg-12,.factory-bootstrap-400 .col-lg-2,.factory-bootstrap-400 .col-lg-3,.factory-bootstrap-400 .col-lg-4,.factory-bootstrap-400 .col-lg-5,.factory-bootstrap-400 .col-lg-6,.factory-bootstrap-400 .col-lg-7,.factory-bootstrap-400 .col-lg-8,.factory-bootstrap-400 .col-lg-9,.factory-bootstrap-400 .col-md-1,.factory-bootstrap-400 .col-md-10,.factory-bootstrap-400 .col-md-11,.factory-bootstrap-400 .col-md-12,.factory-bootstrap-400 .col-md-2,.factory-bootstrap-400 .col-md-3,.factory-bootstrap-400 .col-md-4,.factory-bootstrap-400 .col-md-5,.factory-bootstrap-400 .col-md-6,.factory-bootstrap-400 .col-md-7,.factory-bootstrap-400 .col-md-8,.factory-bootstrap-400 .col-md-9,.factory-bootstrap-400 .col-sm-1,.factory-bootstrap-400 .col-sm-10,.factory-bootstrap-400 .col-sm-11,.factory-bootstrap-400 .col-sm-12,.factory-bootstrap-400 .col-sm-2,.factory-bootstrap-400 .col-sm-3,.factory-bootstrap-400 .col-sm-4,.factory-bootstrap-400 .col-sm-5,.factory-bootstrap-400 .col-sm-6,.factory-bootstrap-400 .col-sm-7,.factory-bootstrap-400 .col-sm-8,.factory-bootstrap-400 .col-sm-9,.factory-bootstrap-400 .col-xs-1,.factory-bootstrap-400 .col-xs-10,.factory-bootstrap-400 .col-xs-11,.factory-bootstrap-400 .col-xs-12,.factory-bootstrap-400 .col-xs-2,.factory-bootstrap-400 .col-xs-3,.factory-bootstrap-400 .col-xs-4,.factory-bootstrap-400 .col-xs-5,.factory-bootstrap-400 .col-xs-6,.factory-bootstrap-400 .col-xs-7,.factory-bootstrap-400 .col-xs-8,.factory-bootstrap-400 .col-xs-9{position:relative;min-height:1px;padding-right:15px;padding-left:15px}.factory-bootstrap-400 .col-xs-1,.factory-bootstrap-400 .col-xs-10,.factory-bootstrap-400 .col-xs-11,.factory-bootstrap-400 .col-xs-12,.factory-bootstrap-400 .col-xs-2,.factory-bootstrap-400 .col-xs-3,.factory-bootstrap-400 .col-xs-4,.factory-bootstrap-400 .col-xs-5,.factory-bootstrap-400 .col-xs-6,.factory-bootstrap-400 .col-xs-7,.factory-bootstrap-400 .col-xs-8,.factory-bootstrap-400 .col-xs-9{float:left}.factory-bootstrap-400 .col-xs-12{width:100%}.factory-bootstrap-400 .col-xs-11{width:91.66666666666666%}.factory-bootstrap-400 .col-xs-10{width:83.33333333333334%}.factory-bootstrap-400 .col-xs-9{width:75%}.factory-bootstrap-400 .col-xs-8{width:66.66666666666666%}.factory-bootstrap-400 .col-xs-7{width:58.333333333333336%}.factory-bootstrap-400 .col-xs-6{width:50%}.factory-bootstrap-400 .col-xs-5{width:41.66666666666667%}.factory-bootstrap-400 .col-xs-4{width:33.33333333333333%}.factory-bootstrap-400 .col-xs-3{width:25%}.factory-bootstrap-400 .col-xs-2{width:16.666666666666664%}.factory-bootstrap-400 .col-xs-1{width:8.333333333333332%}.factory-bootstrap-400 .col-xs-pull-12{right:100%}.factory-bootstrap-400 .col-xs-pull-11{right:91.66666666666666%}.factory-bootstrap-400 .col-xs-pull-10{right:83.33333333333334%}.factory-bootstrap-400 .col-xs-pull-9{right:75%}.factory-bootstrap-400 .col-xs-pull-8{right:66.66666666666666%}.factory-bootstrap-400 .col-xs-pull-7{right:58.333333333333336%}.factory-bootstrap-400 .col-xs-pull-6{right:50%}.factory-bootstrap-400 .col-xs-pull-5{right:41.66666666666667%}.factory-bootstrap-400 .col-xs-pull-4{right:33.33333333333333%}.factory-bootstrap-400 .col-xs-pull-3{right:25%}.factory-bootstrap-400 .col-xs-pull-2{right:16.666666666666664%}.factory-bootstrap-400 .col-xs-pull-1{right:8.333333333333332%}.factory-bootstrap-400 .col-xs-pull-0{right:0}.factory-bootstrap-400 .col-xs-push-12{left:100%}.factory-bootstrap-400 .col-xs-push-11{left:91.66666666666666%}.factory-bootstrap-400 .col-xs-push-10{left:83.33333333333334%}.factory-bootstrap-400 .col-xs-push-9{left:75%}.factory-bootstrap-400 .col-xs-push-8{left:66.66666666666666%}.factory-bootstrap-400 .col-xs-push-7{left:58.333333333333336%}.factory-bootstrap-400 .col-xs-push-6{left:50%}.factory-bootstrap-400 .col-xs-push-5{left:41.66666666666667%}.factory-bootstrap-400 .col-xs-push-4{left:33.33333333333333%}.factory-bootstrap-400 .col-xs-push-3{left:25%}.factory-bootstrap-400 .col-xs-push-2{left:16.666666666666664%}.factory-bootstrap-400 .col-xs-push-1{left:8.333333333333332%}.factory-bootstrap-400 .col-xs-push-0{left:0}.factory-bootstrap-400 .col-xs-offset-12{margin-left:100%}.factory-bootstrap-400 .col-xs-offset-11{margin-left:91.66666666666666%}.factory-bootstrap-400 .col-xs-offset-10{margin-left:83.33333333333334%}.factory-bootstrap-400 .col-xs-offset-9{margin-left:75%}.factory-bootstrap-400 .col-xs-offset-8{margin-left:66.66666666666666%}.factory-bootstrap-400 .col-xs-offset-7{margin-left:58.333333333333336%}.factory-bootstrap-400 .col-xs-offset-6{margin-left:50%}.factory-bootstrap-400 .col-xs-offset-5{margin-left:41.66666666666667%}.factory-bootstrap-400 .col-xs-offset-4{margin-left:33.33333333333333%}.factory-bootstrap-400 .col-xs-offset-3{margin-left:25%}.factory-bootstrap-400 .col-xs-offset-2{margin-left:16.666666666666664%}.factory-bootstrap-400 .col-xs-offset-1{margin-left:8.333333333333332%}.factory-bootstrap-400 .col-xs-offset-0{margin-left:0}@media (min-width:768px){.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9{float:left}.col-sm-12{width:100%}.col-sm-11{width:91.66666666666666%}.col-sm-10{width:83.33333333333334%}.col-sm-9{width:75%}.col-sm-8{width:66.66666666666666%}.col-sm-7{width:58.333333333333336%}.col-sm-6{width:50%}.col-sm-5{width:41.66666666666667%}.col-sm-4{width:33.33333333333333%}.col-sm-3{width:25%}.col-sm-2{width:16.666666666666664%}.col-sm-1{width:8.333333333333332%}.col-sm-pull-12{right:100%}.col-sm-pull-11{right:91.66666666666666%}.col-sm-pull-10{right:83.33333333333334%}.col-sm-pull-9{right:75%}.col-sm-pull-8{right:66.66666666666666%}.col-sm-pull-7{right:58.333333333333336%}.col-sm-pull-6{right:50%}.col-sm-pull-5{right:41.66666666666667%}.col-sm-pull-4{right:33.33333333333333%}.col-sm-pull-3{right:25%}.col-sm-pull-2{right:16.666666666666664%}.col-sm-pull-1{right:8.333333333333332%}.col-sm-pull-0{right:0}.col-sm-push-12{left:100%}.col-sm-push-11{left:91.66666666666666%}.col-sm-push-10{left:83.33333333333334%}.col-sm-push-9{left:75%}.col-sm-push-8{left:66.66666666666666%}.col-sm-push-7{left:58.333333333333336%}.col-sm-push-6{left:50%}.col-sm-push-5{left:41.66666666666667%}.col-sm-push-4{left:33.33333333333333%}.col-sm-push-3{left:25%}.col-sm-push-2{left:16.666666666666664%}.col-sm-push-1{left:8.333333333333332%}.col-sm-push-0{left:0}.col-sm-offset-12{margin-left:100%}.col-sm-offset-11{margin-left:91.66666666666666%}.col-sm-offset-10{margin-left:83.33333333333334%}.col-sm-offset-9{margin-left:75%}.col-sm-offset-8{margin-left:66.66666666666666%}.col-sm-offset-7{margin-left:58.333333333333336%}.col-sm-offset-6{margin-left:50%}.col-sm-offset-5{margin-left:41.66666666666667%}.col-sm-offset-4{margin-left:33.33333333333333%}.col-sm-offset-3{margin-left:25%}.col-sm-offset-2{margin-left:16.666666666666664%}.col-sm-offset-1{margin-left:8.333333333333332%}.col-sm-offset-0{margin-left:0}}@media (min-width:992px){.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9{float:left}.col-md-12{width:100%}.col-md-11{width:91.66666666666666%}.col-md-10{width:83.33333333333334%}.col-md-9{width:75%}.col-md-8{width:66.66666666666666%}.col-md-7{width:58.333333333333336%}.col-md-6{width:50%}.col-md-5{width:41.66666666666667%}.col-md-4{width:33.33333333333333%}.col-md-3{width:25%}.col-md-2{width:16.666666666666664%}.col-md-1{width:8.333333333333332%}.col-md-pull-12{right:100%}.col-md-pull-11{right:91.66666666666666%}.col-md-pull-10{right:83.33333333333334%}.col-md-pull-9{right:75%}.col-md-pull-8{right:66.66666666666666%}.col-md-pull-7{right:58.333333333333336%}.col-md-pull-6{right:50%}.col-md-pull-5{right:41.66666666666667%}.col-md-pull-4{right:33.33333333333333%}.col-md-pull-3{right:25%}.col-md-pull-2{right:16.666666666666664%}.col-md-pull-1{right:8.333333333333332%}.col-md-pull-0{right:0}.col-md-push-12{left:100%}.col-md-push-11{left:91.66666666666666%}.col-md-push-10{left:83.33333333333334%}.col-md-push-9{left:75%}.col-md-push-8{left:66.66666666666666%}.col-md-push-7{left:58.333333333333336%}.col-md-push-6{left:50%}.col-md-push-5{left:41.66666666666667%}.col-md-push-4{left:33.33333333333333%}.col-md-push-3{left:25%}.col-md-push-2{left:16.666666666666664%}.col-md-push-1{left:8.333333333333332%}.col-md-push-0{left:0}.col-md-offset-12{margin-left:100%}.col-md-offset-11{margin-left:91.66666666666666%}.col-md-offset-10{margin-left:83.33333333333334%}.col-md-offset-9{margin-left:75%}.col-md-offset-8{margin-left:66.66666666666666%}.col-md-offset-7{margin-left:58.333333333333336%}.col-md-offset-6{margin-left:50%}.col-md-offset-5{margin-left:41.66666666666667%}.col-md-offset-4{margin-left:33.33333333333333%}.col-md-offset-3{margin-left:25%}.col-md-offset-2{margin-left:16.666666666666664%}.col-md-offset-1{margin-left:8.333333333333332%}.col-md-offset-0{margin-left:0}}@media (min-width:1200px){.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9{float:left}.col-lg-12{width:100%}.col-lg-11{width:91.66666666666666%}.col-lg-10{width:83.33333333333334%}.col-lg-9{width:75%}.col-lg-8{width:66.66666666666666%}.col-lg-7{width:58.333333333333336%}.col-lg-6{width:50%}.col-lg-5{width:41.66666666666667%}.col-lg-4{width:33.33333333333333%}.col-lg-3{width:25%}.col-lg-2{width:16.666666666666664%}.col-lg-1{width:8.333333333333332%}.col-lg-pull-12{right:100%}.col-lg-pull-11{right:91.66666666666666%}.col-lg-pull-10{right:83.33333333333334%}.col-lg-pull-9{right:75%}.col-lg-pull-8{right:66.66666666666666%}.col-lg-pull-7{right:58.333333333333336%}.col-lg-pull-6{right:50%}.col-lg-pull-5{right:41.66666666666667%}.col-lg-pull-4{right:33.33333333333333%}.col-lg-pull-3{right:25%}.col-lg-pull-2{right:16.666666666666664%}.col-lg-pull-1{right:8.333333333333332%}.col-lg-pull-0{right:0}.col-lg-push-12{left:100%}.col-lg-push-11{left:91.66666666666666%}.col-lg-push-10{left:83.33333333333334%}.col-lg-push-9{left:75%}.col-lg-push-8{left:66.66666666666666%}.col-lg-push-7{left:58.333333333333336%}.col-lg-push-6{left:50%}.col-lg-push-5{left:41.66666666666667%}.col-lg-push-4{left:33.33333333333333%}.col-lg-push-3{left:25%}.col-lg-push-2{left:16.666666666666664%}.col-lg-push-1{left:8.333333333333332%}.col-lg-push-0{left:0}.col-lg-offset-12{margin-left:100%}.col-lg-offset-11{margin-left:91.66666666666666%}.col-lg-offset-10{margin-left:83.33333333333334%}.col-lg-offset-9{margin-left:75%}.col-lg-offset-8{margin-left:66.66666666666666%}.col-lg-offset-7{margin-left:58.333333333333336%}.col-lg-offset-6{margin-left:50%}.col-lg-offset-5{margin-left:41.66666666666667%}.col-lg-offset-4{margin-left:33.33333333333333%}.col-lg-offset-3{margin-left:25%}.col-lg-offset-2{margin-left:16.666666666666664%}.col-lg-offset-1{margin-left:8.333333333333332%}.col-lg-offset-0{margin-left:0}}.factory-bootstrap-400 table{max-width:100%;background-color:transparent}.factory-bootstrap-400 th{text-align:left}.factory-bootstrap-400 .table{width:100%;margin-bottom:20px}.factory-bootstrap-400 .table>tbody>tr>td,.factory-bootstrap-400 .table>tbody>tr>th,.factory-bootstrap-400 .table>tfoot>tr>td,.factory-bootstrap-400 .table>tfoot>tr>th,.factory-bootstrap-400 .table>thead>tr>td,.factory-bootstrap-400 .table>thead>tr>th{padding:8px;line-height:1.428571429;vertical-align:top;border-top:1px solid #ddd}.factory-bootstrap-400 .table>thead>tr>th{vertical-align:bottom;border-bottom:2px solid #ddd}.factory-bootstrap-400 .table>caption+thead>tr:first-child>td,.factory-bootstrap-400 .table>caption+thead>tr:first-child>th,.factory-bootstrap-400 .table>colgroup+thead>tr:first-child>td,.factory-bootstrap-400 .table>colgroup+thead>tr:first-child>th,.factory-bootstrap-400 .table>thead:first-child>tr:first-child>td,.factory-bootstrap-400 .table>thead:first-child>tr:first-child>th{border-top:0}.factory-bootstrap-400 .table>tbody+tbody{border-top:2px solid #ddd}.factory-bootstrap-400 .table .table{background-color:#fff}.factory-bootstrap-400 .table-condensed>tbody>tr>td,.factory-bootstrap-400 .table-condensed>tbody>tr>th,.factory-bootstrap-400 .table-condensed>tfoot>tr>td,.factory-bootstrap-400 .table-condensed>tfoot>tr>th,.factory-bootstrap-400 .table-condensed>thead>tr>td,.factory-bootstrap-400 .table-condensed>thead>tr>th{padding:5px}.factory-bootstrap-400 .table-bordered,.factory-bootstrap-400 .table-bordered>tbody>tr>td,.factory-bootstrap-400 .table-bordered>tbody>tr>th,.factory-bootstrap-400 .table-bordered>tfoot>tr>td,.factory-bootstrap-400 .table-bordered>tfoot>tr>th,.factory-bootstrap-400 .table-bordered>thead>tr>td,.factory-bootstrap-400 .table-bordered>thead>tr>th{border:1px solid #ddd}.factory-bootstrap-400 .table-bordered>thead>tr>td,.factory-bootstrap-400 .table-bordered>thead>tr>th{border-bottom-width:2px}.factory-bootstrap-400 .table-striped>tbody>tr:nth-child(odd)>td,.factory-bootstrap-400 .table-striped>tbody>tr:nth-child(odd)>th{background-color:#f9f9f9}.factory-bootstrap-400 .table-hover>tbody>tr:hover>td,.factory-bootstrap-400 .table-hover>tbody>tr:hover>th{background-color:#f5f5f5}.factory-bootstrap-400 table col[class*=col-]{position:static;display:table-column;float:none}.factory-bootstrap-400 table td[class*=col-],.factory-bootstrap-400 table th[class*=col-]{display:table-cell;float:none}.factory-bootstrap-400 .table>tbody>.active>td,.factory-bootstrap-400 .table>tbody>.active>th,.factory-bootstrap-400 .table>tbody>tr>.active,.factory-bootstrap-400 .table>tfoot>.active>td,.factory-bootstrap-400 .table>tfoot>.active>th,.factory-bootstrap-400 .table>tfoot>tr>.active,.factory-bootstrap-400 .table>thead>.active>td,.factory-bootstrap-400 .table>thead>.active>th,.factory-bootstrap-400 .table>thead>tr>.active{background-color:#f5f5f5}.factory-bootstrap-400 .table-hover>tbody>.active:hover>td,.factory-bootstrap-400 .table-hover>tbody>.active:hover>th,.factory-bootstrap-400 .table-hover>tbody>tr>.active:hover{background-color:#e8e8e8}.factory-bootstrap-400 .table>tbody>.success>td,.factory-bootstrap-400 .table>tbody>.success>th,.factory-bootstrap-400 .table>tbody>tr>.success,.factory-bootstrap-400 .table>tfoot>.success>td,.factory-bootstrap-400 .table>tfoot>.success>th,.factory-bootstrap-400 .table>tfoot>tr>.success,.factory-bootstrap-400 .table>thead>.success>td,.factory-bootstrap-400 .table>thead>.success>th,.factory-bootstrap-400 .table>thead>tr>.success{background-color:#dff0d8}.factory-bootstrap-400 .table-hover>tbody>.success:hover>td,.factory-bootstrap-400 .table-hover>tbody>.success:hover>th,.factory-bootstrap-400 .table-hover>tbody>tr>.success:hover{background-color:#d0e9c6}.factory-bootstrap-400 .table>tbody>.danger>td,.factory-bootstrap-400 .table>tbody>.danger>th,.factory-bootstrap-400 .table>tbody>tr>.danger,.factory-bootstrap-400 .table>tfoot>.danger>td,.factory-bootstrap-400 .table>tfoot>.danger>th,.factory-bootstrap-400 .table>tfoot>tr>.danger,.factory-bootstrap-400 .table>thead>.danger>td,.factory-bootstrap-400 .table>thead>.danger>th,.factory-bootstrap-400 .table>thead>tr>.danger{background-color:#f2dede}.factory-bootstrap-400 .table-hover>tbody>.danger:hover>td,.factory-bootstrap-400 .table-hover>tbody>.danger:hover>th,.factory-bootstrap-400 .table-hover>tbody>tr>.danger:hover{background-color:#ebcccc}.factory-bootstrap-400 .table>tbody>.warning>td,.factory-bootstrap-400 .table>tbody>.warning>th,.factory-bootstrap-400 .table>tbody>tr>.warning,.factory-bootstrap-400 .table>tfoot>.warning>td,.factory-bootstrap-400 .table>tfoot>.warning>th,.factory-bootstrap-400 .table>tfoot>tr>.warning,.factory-bootstrap-400 .table>thead>.warning>td,.factory-bootstrap-400 .table>thead>.warning>th,.factory-bootstrap-400 .table>thead>tr>.warning{background-color:#fcf8e3}.factory-bootstrap-400 .table-hover>tbody>.warning:hover>td,.factory-bootstrap-400 .table-hover>tbody>.warning:hover>th,.factory-bootstrap-400 .table-hover>tbody>tr>.warning:hover{background-color:#faf2cc}@media (max-width:767px){.table-responsive{width:100%;margin-bottom:15px;overflow-x:scroll;overflow-y:hidden;border:1px solid #ddd;-ms-overflow-style:-ms-autohiding-scrollbar;-webkit-overflow-scrolling:touch}.table-responsive>.table{margin-bottom:0}.table-responsive>.table>tbody>tr>td,.table-responsive>.table>tbody>tr>th,.table-responsive>.table>tfoot>tr>td,.table-responsive>.table>tfoot>tr>th,.table-responsive>.table>thead>tr>td,.table-responsive>.table>thead>tr>th{white-space:nowrap}.table-responsive>.table-bordered{border:0}.table-responsive>.table-bordered>tbody>tr>td:first-child,.table-responsive>.table-bordered>tbody>tr>th:first-child,.table-responsive>.table-bordered>tfoot>tr>td:first-child,.table-responsive>.table-bordered>tfoot>tr>th:first-child,.table-responsive>.table-bordered>thead>tr>td:first-child,.table-responsive>.table-bordered>thead>tr>th:first-child{border-left:0}.table-responsive>.table-bordered>tbody>tr>td:last-child,.table-responsive>.table-bordered>tbody>tr>th:last-child,.table-responsive>.table-bordered>tfoot>tr>td:last-child,.table-responsive>.table-bordered>tfoot>tr>th:last-child,.table-responsive>.table-bordered>thead>tr>td:last-child,.table-responsive>.table-bordered>thead>tr>th:last-child{border-right:0}.table-responsive>.table-bordered>tbody>tr:last-child>td,.table-responsive>.table-bordered>tbody>tr:last-child>th,.table-responsive>.table-bordered>tfoot>tr:last-child>td,.table-responsive>.table-bordered>tfoot>tr:last-child>th{border-bottom:0}}.factory-bootstrap-400 fieldset{padding:0;margin:0;border:0}.factory-bootstrap-400 legend{display:block;width:100%;padding:0;margin-bottom:20px;font-size:21px;line-height:inherit;color:#333;border:0;border-bottom:1px solid #e5e5e5;-moz-box-sizing:content-box;box-sizing:content-box}.factory-bootstrap-400 label{display:inline-block;margin-bottom:5px;font-weight:700}.factory-bootstrap-400 input[type=search]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.factory-bootstrap-400 input[type=checkbox],.factory-bootstrap-400 input[type=radio]{margin:4px 0 0;margin-top:1px \9;line-height:normal}.factory-bootstrap-400 input[type=file]{display:block}.factory-bootstrap-400 select[multiple],.factory-bootstrap-400 select[size]{height:auto}.factory-bootstrap-400 select optgroup{font-family:inherit;font-size:inherit;font-style:inherit}.factory-bootstrap-400 input[type=checkbox]:focus,.factory-bootstrap-400 input[type=file]:focus,.factory-bootstrap-400 input[type=radio]:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.factory-bootstrap-400 input[type=number]::-webkit-inner-spin-button,.factory-bootstrap-400 input[type=number]::-webkit-outer-spin-button{height:auto}.factory-bootstrap-400 output{display:block;padding-top:7px;font-size:14px;line-height:1.428571429;color:#555;vertical-align:middle}.factory-bootstrap-400 .form-control{display:block;width:100%;height:34px;padding:6px 12px;font-size:14px;line-height:1.428571429;color:#555;vertical-align:middle;background-color:#fff;background-image:none;border:1px solid #ccc;border-radius:3px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075);-webkit-transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s;transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s}.factory-bootstrap-400 .form-control:focus{border-color:#66afe9;outline:0;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.factory-bootstrap-400 .form-control:-moz-placeholder{color:#999}.factory-bootstrap-400 .form-control::-moz-placeholder{color:#999;opacity:1}.factory-bootstrap-400 .form-control:-ms-input-placeholder{color:#999}.factory-bootstrap-400 .form-control::-webkit-input-placeholder{color:#999}.factory-bootstrap-400 .form-control[disabled],.factory-bootstrap-400 .form-control[readonly],.factory-bootstrap-400 fieldset[disabled] .form-control{cursor:not-allowed;background-color:#eee}.factory-bootstrap-400 textarea.form-control{height:auto}.factory-bootstrap-400 .form-group{margin-bottom:15px}.factory-bootstrap-400 .checkbox,.factory-bootstrap-400 .radio{display:block;min-height:20px;padding-left:20px;margin-top:10px;margin-bottom:10px;vertical-align:middle}.factory-bootstrap-400 .checkbox label,.factory-bootstrap-400 .radio label{display:inline;margin-bottom:0;font-weight:400;cursor:pointer}.factory-bootstrap-400 .checkbox input[type=checkbox],.factory-bootstrap-400 .checkbox-inline input[type=checkbox],.factory-bootstrap-400 .radio input[type=radio],.factory-bootstrap-400 .radio-inline input[type=radio]{float:left;margin-left:-20px}.factory-bootstrap-400 .checkbox+.checkbox,.factory-bootstrap-400 .radio+.radio{margin-top:-5px}.factory-bootstrap-400 .checkbox-inline,.factory-bootstrap-400 .radio-inline{display:inline-block;padding-left:20px;margin-bottom:0;font-weight:400;vertical-align:middle;cursor:pointer}.factory-bootstrap-400 .checkbox-inline+.checkbox-inline,.factory-bootstrap-400 .radio-inline+.radio-inline{margin-top:0;margin-left:10px}.factory-bootstrap-400 .checkbox-inline[disabled],.factory-bootstrap-400 .checkbox[disabled],.factory-bootstrap-400 .radio-inline[disabled],.factory-bootstrap-400 .radio[disabled],.factory-bootstrap-400 fieldset[disabled] .checkbox,.factory-bootstrap-400 fieldset[disabled] .checkbox-inline,.factory-bootstrap-400 fieldset[disabled] .radio,.factory-bootstrap-400 fieldset[disabled] .radio-inline,.factory-bootstrap-400 fieldset[disabled] input[type=checkbox],.factory-bootstrap-400 fieldset[disabled] input[type=radio],.factory-bootstrap-400 input[type=checkbox][disabled],.factory-bootstrap-400 input[type=radio][disabled]{cursor:not-allowed}.factory-bootstrap-400 .input-sm{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.factory-bootstrap-400 select.input-sm{height:30px;line-height:30px}.factory-bootstrap-400 textarea.input-sm{height:auto}.factory-bootstrap-400 .input-lg{height:46px;padding:10px 16px;font-size:18px;line-height:1.33;border-radius:6px}.factory-bootstrap-400 select.input-lg{height:46px;line-height:46px}.factory-bootstrap-400 textarea.input-lg{height:auto}.factory-bootstrap-400 .has-warning .checkbox,.factory-bootstrap-400 .has-warning .checkbox-inline,.factory-bootstrap-400 .has-warning .control-label,.factory-bootstrap-400 .has-warning .help-block,.factory-bootstrap-400 .has-warning .radio,.factory-bootstrap-400 .has-warning .radio-inline{color:#8a6d3b}.factory-bootstrap-400 .has-warning .form-control{border-color:#8a6d3b;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.factory-bootstrap-400 .has-warning .form-control:focus{border-color:#66512c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b}.factory-bootstrap-400 .has-warning .input-group-addon{color:#8a6d3b;background-color:#fcf8e3;border-color:#8a6d3b}.factory-bootstrap-400 .has-error .checkbox,.factory-bootstrap-400 .has-error .checkbox-inline,.factory-bootstrap-400 .has-error .control-label,.factory-bootstrap-400 .has-error .help-block,.factory-bootstrap-400 .has-error .radio,.factory-bootstrap-400 .has-error .radio-inline{color:#a94442}.factory-bootstrap-400 .controls{display:block}.factory-bootstrap-400 .has-error .form-control{border-color:#a94442;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.factory-bootstrap-400 .has-error .form-control:focus{border-color:#843534;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483}.factory-bootstrap-400 .has-error .input-group-addon{color:#a94442;background-color:#f2dede;border-color:#a94442}.factory-bootstrap-400 .has-success .checkbox,.factory-bootstrap-400 .has-success .checkbox-inline,.factory-bootstrap-400 .has-success .control-label,.factory-bootstrap-400 .has-success .help-block,.factory-bootstrap-400 .has-success .radio,.factory-bootstrap-400 .has-success .radio-inline{color:#3c763d}.factory-bootstrap-400 .has-success .form-control{border-color:#3c763d;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.factory-bootstrap-400 .has-success .form-control:focus{border-color:#2b542c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168}.factory-bootstrap-400 .has-success .input-group-addon{color:#3c763d;background-color:#dff0d8;border-color:#3c763d}.factory-bootstrap-400 .form-control-static{margin-bottom:0}.factory-bootstrap-400 .help-block{display:block;margin-top:5px;margin-bottom:10px;color:#737373;font-weight:400}@media (min-width:768px){.form-inline .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.form-inline .form-control{display:inline-block}.form-inline select.form-control{width:auto}.form-inline .checkbox,.form-inline .radio{display:inline-block;padding-left:0;margin-top:0;margin-bottom:0}.form-inline .checkbox input[type=checkbox],.form-inline .radio input[type=radio]{float:none;margin-left:0}}.factory-bootstrap-400 .form-horizontal .checkbox,.factory-bootstrap-400 .form-horizontal .checkbox-inline,.factory-bootstrap-400 .form-horizontal .control-label,.factory-bootstrap-400 .form-horizontal .radio,.factory-bootstrap-400 .form-horizontal .radio-inline{position:relative;padding-top:7px;margin-top:0;margin-bottom:0}.factory-bootstrap-400 .form-horizontal .control-label{max-width:200px}.factory-bootstrap-400 .form-horizontal .checkbox,.factory-bootstrap-400 .form-horizontal .radio{min-height:27px}.factory-bootstrap-400 .form-horizontal .form-group{margin-right:-15px;margin-left:-15px}.factory-bootstrap-400 .form-horizontal .form-group:after,.factory-bootstrap-400 .form-horizontal .form-group:before{display:table;content:" "}.factory-bootstrap-400 .form-horizontal .form-group:after{clear:both}.factory-bootstrap-400 .form-horizontal .form-control-static{padding-top:7px}@media (min-width:768px){.form-horizontal .control-label{text-align:right}}.factory-bootstrap-400 .btn{display:inline-block;padding:5px 12px;margin-bottom:0;font-size:13px;font-weight:400;line-height:1.428571429;text-align:center;white-space:nowrap;vertical-align:middle;cursor:pointer;background-image:none;border:1px solid transparent;border-radius:3px;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;-o-user-select:none;user-select:none}.factory-bootstrap-400 .btn:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.factory-bootstrap-400 .btn{text-decoration:none}.factory-bootstrap-400 .btn:focus,.factory-bootstrap-400 .btn:hover{color:#333;text-decoration:none}.factory-bootstrap-400 .btn.disabled,.factory-bootstrap-400 .btn[disabled],.factory-bootstrap-400 fieldset[disabled] .btn{pointer-events:none;cursor:not-allowed;opacity:.65;filter:alpha(opacity=65);-webkit-box-shadow:none;box-shadow:none}.factory-bootstrap-400 .btn-default.active,.factory-bootstrap-400 .btn-default:active,.factory-bootstrap-400 .btn-default:focus,.factory-bootstrap-400 .btn-default:hover,.factory-bootstrap-400 .open .dropdown-toggle.btn-default{background:#fafafa;border-color:#999;color:#222}.factory-bootstrap-400 .btn-default.active,.factory-bootstrap-400 .btn-default:active,.factory-bootstrap-400 .open .dropdown-toggle.btn-default{background-image:none}.factory-bootstrap-400 .btn-default.disabled,.factory-bootstrap-400 .btn-default.disabled.active,.factory-bootstrap-400 .btn-default.disabled:active,.factory-bootstrap-400 .btn-default.disabled:focus,.factory-bootstrap-400 .btn-default.disabled:hover,.factory-bootstrap-400 .btn-default[disabled],.factory-bootstrap-400 .btn-default[disabled].active,.factory-bootstrap-400 .btn-default[disabled]:active,.factory-bootstrap-400 .btn-default[disabled]:focus,.factory-bootstrap-400 .btn-default[disabled]:hover,.factory-bootstrap-400 fieldset[disabled] .btn-default,.factory-bootstrap-400 fieldset[disabled] .btn-default.active,.factory-bootstrap-400 fieldset[disabled] .btn-default:active,.factory-bootstrap-400 fieldset[disabled] .btn-default:focus,.factory-bootstrap-400 fieldset[disabled] .btn-default:hover{background-color:#fff;border-color:#ccc}.factory-bootstrap-400 .btn-default .badge{color:#fff;background-color:#fff}.factory-bootstrap-400 .btn-primary.active,.factory-bootstrap-400 .btn-primary:active,.factory-bootstrap-400 .btn-primary:focus,.factory-bootstrap-400 .btn-primary:hover,.factory-bootstrap-400 .open .dropdown-toggle.btn-primary{color:#fff;background-color:#3276b1;border-color:#285e8e}.factory-bootstrap-400 .btn-primary.active,.factory-bootstrap-400 .btn-primary:active,.factory-bootstrap-400 .open .dropdown-toggle.btn-primary{background-image:none}.factory-bootstrap-400 .btn-primary.disabled,.factory-bootstrap-400 .btn-primary.disabled.active,.factory-bootstrap-400 .btn-primary.disabled:active,.factory-bootstrap-400 .btn-primary.disabled:focus,.factory-bootstrap-400 .btn-primary.disabled:hover,.factory-bootstrap-400 .btn-primary[disabled],.factory-bootstrap-400 .btn-primary[disabled].active,.factory-bootstrap-400 .btn-primary[disabled]:active,.factory-bootstrap-400 .btn-primary[disabled]:focus,.factory-bootstrap-400 .btn-primary[disabled]:hover,.factory-bootstrap-400 fieldset[disabled] .btn-primary,.factory-bootstrap-400 fieldset[disabled] .btn-primary.active,.factory-bootstrap-400 fieldset[disabled] .btn-primary:active,.factory-bootstrap-400 fieldset[disabled] .btn-primary:focus,.factory-bootstrap-400 fieldset[disabled] .btn-primary:hover{background-color:#428bca;border-color:#357ebd}.factory-bootstrap-400 .btn-primary .badge{color:#428bca;background-color:#fff}.factory-bootstrap-400 .btn-warning{color:#fff;background-color:#f0ad4e}.factory-bootstrap-400 .btn-warning.active,.factory-bootstrap-400 .btn-warning:active,.factory-bootstrap-400 .btn-warning:focus,.factory-bootstrap-400 .btn-warning:hover,.factory-bootstrap-400 .open .dropdown-toggle.btn-warning{color:#fff;background-color:#ed9c28;border-color:#d58512}.factory-bootstrap-400 .btn-warning.active,.factory-bootstrap-400 .btn-warning:active,.factory-bootstrap-400 .open .dropdown-toggle.btn-warning{background-image:none}.factory-bootstrap-400 .btn-warning.disabled,.factory-bootstrap-400 .btn-warning.disabled.active,.factory-bootstrap-400 .btn-warning.disabled:active,.factory-bootstrap-400 .btn-warning.disabled:focus,.factory-bootstrap-400 .btn-warning.disabled:hover,.factory-bootstrap-400 .btn-warning[disabled],.factory-bootstrap-400 .btn-warning[disabled].active,.factory-bootstrap-400 .btn-warning[disabled]:active,.factory-bootstrap-400 .btn-warning[disabled]:focus,.factory-bootstrap-400 .btn-warning[disabled]:hover,.factory-bootstrap-400 fieldset[disabled] .btn-warning,.factory-bootstrap-400 fieldset[disabled] .btn-warning.active,.factory-bootstrap-400 fieldset[disabled] .btn-warning:active,.factory-bootstrap-400 fieldset[disabled] .btn-warning:focus,.factory-bootstrap-400 fieldset[disabled] .btn-warning:hover{background-color:#f0ad4e;border-color:#eea236}.factory-bootstrap-400 .btn-warning .badge{color:#f0ad4e;background-color:#fff}.factory-bootstrap-400 .btn-success{color:#fff;background-color:#5cb85c}.factory-bootstrap-400 .btn-success.active,.factory-bootstrap-400 .btn-success:active,.factory-bootstrap-400 .btn-success:focus,.factory-bootstrap-400 .btn-success:hover,.factory-bootstrap-400 .open .dropdown-toggle.btn-success{color:#fff;background-color:#47a447;border-color:#398439}.factory-bootstrap-400 .btn-success.active,.factory-bootstrap-400 .btn-success:active,.factory-bootstrap-400 .open .dropdown-toggle.btn-success{background-image:none}.factory-bootstrap-400 .btn-success.disabled,.factory-bootstrap-400 .btn-success.disabled.active,.factory-bootstrap-400 .btn-success.disabled:active,.factory-bootstrap-400 .btn-success.disabled:focus,.factory-bootstrap-400 .btn-success.disabled:hover,.factory-bootstrap-400 .btn-success[disabled],.factory-bootstrap-400 .btn-success[disabled].active,.factory-bootstrap-400 .btn-success[disabled]:active,.factory-bootstrap-400 .btn-success[disabled]:focus,.factory-bootstrap-400 .btn-success[disabled]:hover,.factory-bootstrap-400 fieldset[disabled] .btn-success,.factory-bootstrap-400 fieldset[disabled] .btn-success.active,.factory-bootstrap-400 fieldset[disabled] .btn-success:active,.factory-bootstrap-400 fieldset[disabled] .btn-success:focus,.factory-bootstrap-400 fieldset[disabled] .btn-success:hover{background-color:#5cb85c;border-color:#4cae4c}.factory-bootstrap-400 .btn-success .badge{color:#5cb85c;background-color:#fff}.factory-bootstrap-400 .btn-info{color:#fff;background-color:#5bc0de}.factory-bootstrap-400 .btn-info.active,.factory-bootstrap-400 .btn-info:active,.factory-bootstrap-400 .btn-info:focus,.factory-bootstrap-400 .btn-info:hover,.factory-bootstrap-400 .open .dropdown-toggle.btn-info{color:#fff;background-color:#39b3d7;border-color:#269abc}.factory-bootstrap-400 .btn-info.active,.factory-bootstrap-400 .btn-info:active,.factory-bootstrap-400 .open .dropdown-toggle.btn-info{background-image:none}.factory-bootstrap-400 .btn-info.disabled,.factory-bootstrap-400 .btn-info.disabled.active,.factory-bootstrap-400 .btn-info.disabled:active,.factory-bootstrap-400 .btn-info.disabled:focus,.factory-bootstrap-400 .btn-info.disabled:hover,.factory-bootstrap-400 .btn-info[disabled],.factory-bootstrap-400 .btn-info[disabled].active,.factory-bootstrap-400 .btn-info[disabled]:active,.factory-bootstrap-400 .btn-info[disabled]:focus,.factory-bootstrap-400 .btn-info[disabled]:hover,.factory-bootstrap-400 fieldset[disabled] .btn-info,.factory-bootstrap-400 fieldset[disabled] .btn-info.active,.factory-bootstrap-400 fieldset[disabled] .btn-info:active,.factory-bootstrap-400 fieldset[disabled] .btn-info:focus,.factory-bootstrap-400 fieldset[disabled] .btn-info:hover{background-color:#5bc0de;border-color:#46b8da}.factory-bootstrap-400 .btn-info .badge{color:#5bc0de;background-color:#fff}.factory-bootstrap-400 .btn-link{font-weight:400;color:#428bca;cursor:pointer;border-radius:0}.factory-bootstrap-400 .btn-link,.factory-bootstrap-400 .btn-link:active,.factory-bootstrap-400 .btn-link[disabled],.factory-bootstrap-400 fieldset[disabled] .btn-link{background-color:transparent;-webkit-box-shadow:none;box-shadow:none}.factory-bootstrap-400 .btn-link,.factory-bootstrap-400 .btn-link:active,.factory-bootstrap-400 .btn-link:focus,.factory-bootstrap-400 .btn-link:hover{border-color:transparent}.factory-bootstrap-400 .btn-link:focus,.factory-bootstrap-400 .btn-link:hover{color:#2a6496;text-decoration:underline;background-color:transparent}.factory-bootstrap-400 .btn-link[disabled]:focus,.factory-bootstrap-400 .btn-link[disabled]:hover,.factory-bootstrap-400 fieldset[disabled] .btn-link:focus,.factory-bootstrap-400 fieldset[disabled] .btn-link:hover{color:#999;text-decoration:none}.factory-bootstrap-400 .btn-lg{padding:10px 16px;font-size:18px;line-height:1.33;border-radius:6px}.factory-bootstrap-400 .btn-sm{padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.factory-bootstrap-400 .btn-xs{padding:1px 5px;font-size:12px;line-height:1.5;border-radius:3px}.factory-bootstrap-400 .btn-block{display:block;width:100%;padding-right:0;padding-left:0}.factory-bootstrap-400 .btn-block+.btn-block{margin-top:5px}.factory-bootstrap-400 input[type=button].btn-block,.factory-bootstrap-400 input[type=reset].btn-block,.factory-bootstrap-400 input[type=submit].btn-block{width:100%}.factory-bootstrap-400 .fade{opacity:0;-webkit-transition:opacity .15s linear;transition:opacity .15s linear}.factory-bootstrap-400 .fade.in{opacity:1}.factory-bootstrap-400 .collapse{display:none}.factory-bootstrap-400 .collapse.in{display:block}.factory-bootstrap-400 .collapsing{position:relative;height:0;overflow:hidden;-webkit-transition:height .35s ease;transition:height .35s ease}@font-face{font-family:'Glyphicons Halflings';src:url(../fonts/glyphicons-halflings-regular.eot);src:url(../fonts/glyphicons-halflings-regular.eot?#iefix) format('embedded-opentype'),url(../fonts/glyphicons-halflings-regular.woff) format('woff'),url(../fonts/glyphicons-halflings-regular.ttf) format('truetype'),url(../fonts/glyphicons-halflings-regular.svg#glyphicons-halflingsregular) format('svg')}.factory-bootstrap-400 .glyphicon{position:relative;top:1px;display:inline-block;font-family:'Glyphicons Halflings';-webkit-font-smoothing:antialiased;font-style:normal;font-weight:400;line-height:1;-moz-osx-font-smoothing:grayscale}.factory-bootstrap-400 .glyphicon:empty{width:1em}.factory-bootstrap-400 .glyphicon-asterisk:before{content:"\2a"}.factory-bootstrap-400 .glyphicon-plus:before{content:"\2b"}.factory-bootstrap-400 .glyphicon-euro:before{content:"\20ac"}.factory-bootstrap-400 .glyphicon-minus:before{content:"\2212"}.factory-bootstrap-400 .glyphicon-cloud:before{content:"\2601"}.factory-bootstrap-400 .glyphicon-envelope:before{content:"\2709"}.factory-bootstrap-400 .glyphicon-pencil:before{content:"\270f"}.factory-bootstrap-400 .glyphicon-glass:before{content:"\e001"}.factory-bootstrap-400 .glyphicon-music:before{content:"\e002"}.factory-bootstrap-400 .glyphicon-search:before{content:"\e003"}.factory-bootstrap-400 .glyphicon-heart:before{content:"\e005"}.factory-bootstrap-400 .glyphicon-star:before{content:"\e006"}.factory-bootstrap-400 .glyphicon-star-empty:before{content:"\e007"}.factory-bootstrap-400 .glyphicon-user:before{content:"\e008"}.factory-bootstrap-400 .glyphicon-film:before{content:"\e009"}.factory-bootstrap-400 .glyphicon-th-large:before{content:"\e010"}.factory-bootstrap-400 .glyphicon-th:before{content:"\e011"}.factory-bootstrap-400 .glyphicon-th-list:before{content:"\e012"}.factory-bootstrap-400 .glyphicon-ok:before{content:"\e013"}.factory-bootstrap-400 .glyphicon-remove:before{content:"\e014"}.factory-bootstrap-400 .glyphicon-zoom-in:before{content:"\e015"}.factory-bootstrap-400 .glyphicon-zoom-out:before{content:"\e016"}.factory-bootstrap-400 .glyphicon-off:before{content:"\e017"}.factory-bootstrap-400 .glyphicon-signal:before{content:"\e018"}.factory-bootstrap-400 .glyphicon-cog:before{content:"\e019"}.factory-bootstrap-400 .glyphicon-trash:before{content:"\e020"}.factory-bootstrap-400 .glyphicon-home:before{content:"\e021"}.factory-bootstrap-400 .glyphicon-file:before{content:"\e022"}.factory-bootstrap-400 .glyphicon-time:before{content:"\e023"}.factory-bootstrap-400 .glyphicon-road:before{content:"\e024"}.factory-bootstrap-400 .glyphicon-download-alt:before{content:"\e025"}.factory-bootstrap-400 .glyphicon-download:before{content:"\e026"}.factory-bootstrap-400 .glyphicon-upload:before{content:"\e027"}.factory-bootstrap-400 .glyphicon-inbox:before{content:"\e028"}.factory-bootstrap-400 .glyphicon-play-circle:before{content:"\e029"}.factory-bootstrap-400 .glyphicon-repeat:before{content:"\e030"}.factory-bootstrap-400 .glyphicon-refresh:before{content:"\e031"}.factory-bootstrap-400 .glyphicon-list-alt:before{content:"\e032"}.factory-bootstrap-400 .glyphicon-lock:before{content:"\e033"}.factory-bootstrap-400 .glyphicon-flag:before{content:"\e034"}.factory-bootstrap-400 .glyphicon-headphones:before{content:"\e035"}.factory-bootstrap-400 .glyphicon-volume-off:before{content:"\e036"}.factory-bootstrap-400 .glyphicon-volume-down:before{content:"\e037"}.factory-bootstrap-400 .glyphicon-volume-up:before{content:"\e038"}.factory-bootstrap-400 .glyphicon-qrcode:before{content:"\e039"}.factory-bootstrap-400 .glyphicon-barcode:before{content:"\e040"}.factory-bootstrap-400 .glyphicon-tag:before{content:"\e041"}.factory-bootstrap-400 .glyphicon-tags:before{content:"\e042"}.factory-bootstrap-400 .glyphicon-book:before{content:"\e043"}.factory-bootstrap-400 .glyphicon-bookmark:before{content:"\e044"}.factory-bootstrap-400 .glyphicon-print:before{content:"\e045"}.factory-bootstrap-400 .glyphicon-camera:before{content:"\e046"}.factory-bootstrap-400 .glyphicon-font:before{content:"\e047"}.factory-bootstrap-400 .glyphicon-bold:before{content:"\e048"}.factory-bootstrap-400 .glyphicon-italic:before{content:"\e049"}.factory-bootstrap-400 .glyphicon-text-height:before{content:"\e050"}.factory-bootstrap-400 .glyphicon-text-width:before{content:"\e051"}.factory-bootstrap-400 .glyphicon-align-left:before{content:"\e052"}.factory-bootstrap-400 .glyphicon-align-center:before{content:"\e053"}.factory-bootstrap-400 .glyphicon-align-right:before{content:"\e054"}.factory-bootstrap-400 .glyphicon-align-justify:before{content:"\e055"}.factory-bootstrap-400 .glyphicon-list:before{content:"\e056"}.factory-bootstrap-400 .glyphicon-indent-left:before{content:"\e057"}.factory-bootstrap-400 .glyphicon-indent-right:before{content:"\e058"}.factory-bootstrap-400 .glyphicon-facetime-video:before{content:"\e059"}.factory-bootstrap-400 .glyphicon-picture:before{content:"\e060"}.factory-bootstrap-400 .glyphicon-map-marker:before{content:"\e062"}.factory-bootstrap-400 .glyphicon-adjust:before{content:"\e063"}.factory-bootstrap-400 .glyphicon-tint:before{content:"\e064"}.factory-bootstrap-400 .glyphicon-edit:before{content:"\e065"}.factory-bootstrap-400 .glyphicon-share:before{content:"\e066"}.factory-bootstrap-400 .glyphicon-check:before{content:"\e067"}.factory-bootstrap-400 .glyphicon-move:before{content:"\e068"}.factory-bootstrap-400 .glyphicon-step-backward:before{content:"\e069"}.factory-bootstrap-400 .glyphicon-fast-backward:before{content:"\e070"}.factory-bootstrap-400 .glyphicon-backward:before{content:"\e071"}.factory-bootstrap-400 .glyphicon-play:before{content:"\e072"}.factory-bootstrap-400 .glyphicon-pause:before{content:"\e073"}.factory-bootstrap-400 .glyphicon-stop:before{content:"\e074"}.factory-bootstrap-400 .glyphicon-forward:before{content:"\e075"}.factory-bootstrap-400 .glyphicon-fast-forward:before{content:"\e076"}.factory-bootstrap-400 .glyphicon-step-forward:before{content:"\e077"}.factory-bootstrap-400 .glyphicon-eject:before{content:"\e078"}.factory-bootstrap-400 .glyphicon-chevron-left:before{content:"\e079"}.factory-bootstrap-400 .glyphicon-chevron-right:before{content:"\e080"}.factory-bootstrap-400 .glyphicon-plus-sign:before{content:"\e081"}.factory-bootstrap-400 .glyphicon-minus-sign:before{content:"\e082"}.factory-bootstrap-400 .glyphicon-remove-sign:before{content:"\e083"}.factory-bootstrap-400 .glyphicon-ok-sign:before{content:"\e084"}.factory-bootstrap-400 .glyphicon-question-sign:before{content:"\e085"}.factory-bootstrap-400 .glyphicon-info-sign:before{content:"\e086"}.factory-bootstrap-400 .glyphicon-screenshot:before{content:"\e087"}.factory-bootstrap-400 .glyphicon-remove-circle:before{content:"\e088"}.factory-bootstrap-400 .glyphicon-ok-circle:before{content:"\e089"}.factory-bootstrap-400 .glyphicon-ban-circle:before{content:"\e090"}.factory-bootstrap-400 .glyphicon-arrow-left:before{content:"\e091"}.factory-bootstrap-400 .glyphicon-arrow-right:before{content:"\e092"}.factory-bootstrap-400 .glyphicon-arrow-up:before{content:"\e093"}.factory-bootstrap-400 .glyphicon-arrow-down:before{content:"\e094"}.factory-bootstrap-400 .glyphicon-share-alt:before{content:"\e095"}.factory-bootstrap-400 .glyphicon-resize-full:before{content:"\e096"}.factory-bootstrap-400 .glyphicon-resize-small:before{content:"\e097"}.factory-bootstrap-400 .glyphicon-exclamation-sign:before{content:"\e101"}.factory-bootstrap-400 .glyphicon-gift:before{content:"\e102"}.factory-bootstrap-400 .glyphicon-leaf:before{content:"\e103"}.factory-bootstrap-400 .glyphicon-fire:before{content:"\e104"}.factory-bootstrap-400 .glyphicon-eye-open:before{content:"\e105"}.factory-bootstrap-400 .glyphicon-eye-close:before{content:"\e106"}.factory-bootstrap-400 .glyphicon-warning-sign:before{content:"\e107"}.factory-bootstrap-400 .glyphicon-plane:before{content:"\e108"}.factory-bootstrap-400 .glyphicon-calendar:before{content:"\e109"}.factory-bootstrap-400 .glyphicon-random:before{content:"\e110"}.factory-bootstrap-400 .glyphicon-comment:before{content:"\e111"}.factory-bootstrap-400 .glyphicon-magnet:before{content:"\e112"}.factory-bootstrap-400 .glyphicon-chevron-up:before{content:"\e113"}.factory-bootstrap-400 .glyphicon-chevron-down:before{content:"\e114"}.factory-bootstrap-400 .glyphicon-retweet:before{content:"\e115"}.factory-bootstrap-400 .glyphicon-shopping-cart:before{content:"\e116"}.factory-bootstrap-400 .glyphicon-folder-close:before{content:"\e117"}.factory-bootstrap-400 .glyphicon-folder-open:before{content:"\e118"}.factory-bootstrap-400 .glyphicon-resize-vertical:before{content:"\e119"}.factory-bootstrap-400 .glyphicon-resize-horizontal:before{content:"\e120"}.factory-bootstrap-400 .glyphicon-hdd:before{content:"\e121"}.factory-bootstrap-400 .glyphicon-bullhorn:before{content:"\e122"}.factory-bootstrap-400 .glyphicon-bell:before{content:"\e123"}.factory-bootstrap-400 .glyphicon-certificate:before{content:"\e124"}.factory-bootstrap-400 .glyphicon-thumbs-up:before{content:"\e125"}.factory-bootstrap-400 .glyphicon-thumbs-down:before{content:"\e126"}.factory-bootstrap-400 .glyphicon-hand-right:before{content:"\e127"}.factory-bootstrap-400 .glyphicon-hand-left:before{content:"\e128"}.factory-bootstrap-400 .glyphicon-hand-up:before{content:"\e129"}.factory-bootstrap-400 .glyphicon-hand-down:before{content:"\e130"}.factory-bootstrap-400 .glyphicon-circle-arrow-right:before{content:"\e131"}.factory-bootstrap-400 .glyphicon-circle-arrow-left:before{content:"\e132"}.factory-bootstrap-400 .glyphicon-circle-arrow-up:before{content:"\e133"}.factory-bootstrap-400 .glyphicon-circle-arrow-down:before{content:"\e134"}.factory-bootstrap-400 .glyphicon-globe:before{content:"\e135"}.factory-bootstrap-400 .glyphicon-wrench:before{content:"\e136"}.factory-bootstrap-400 .glyphicon-tasks:before{content:"\e137"}.factory-bootstrap-400 .glyphicon-filter:before{content:"\e138"}.factory-bootstrap-400 .glyphicon-briefcase:before{content:"\e139"}.factory-bootstrap-400 .glyphicon-fullscreen:before{content:"\e140"}.factory-bootstrap-400 .glyphicon-dashboard:before{content:"\e141"}.factory-bootstrap-400 .glyphicon-paperclip:before{content:"\e142"}.factory-bootstrap-400 .glyphicon-heart-empty:before{content:"\e143"}.factory-bootstrap-400 .glyphicon-link:before{content:"\e144"}.factory-bootstrap-400 .glyphicon-phone:before{content:"\e145"}.factory-bootstrap-400 .glyphicon-pushpin:before{content:"\e146"}.factory-bootstrap-400 .glyphicon-usd:before{content:"\e148"}.factory-bootstrap-400 .glyphicon-gbp:before{content:"\e149"}.factory-bootstrap-400 .glyphicon-sort:before{content:"\e150"}.factory-bootstrap-400 .glyphicon-sort-by-alphabet:before{content:"\e151"}.factory-bootstrap-400 .glyphicon-sort-by-alphabet-alt:before{content:"\e152"}.factory-bootstrap-400 .glyphicon-sort-by-order:before{content:"\e153"}.factory-bootstrap-400 .glyphicon-sort-by-order-alt:before{content:"\e154"}.factory-bootstrap-400 .glyphicon-sort-by-attributes:before{content:"\e155"}.factory-bootstrap-400 .glyphicon-sort-by-attributes-alt:before{content:"\e156"}.factory-bootstrap-400 .glyphicon-unchecked:before{content:"\e157"}.factory-bootstrap-400 .glyphicon-expand:before{content:"\e158"}.factory-bootstrap-400 .glyphicon-collapse-down:before{content:"\e159"}.factory-bootstrap-400 .glyphicon-collapse-up:before{content:"\e160"}.factory-bootstrap-400 .glyphicon-log-in:before{content:"\e161"}.factory-bootstrap-400 .glyphicon-flash:before{content:"\e162"}.factory-bootstrap-400 .glyphicon-log-out:before{content:"\e163"}.factory-bootstrap-400 .glyphicon-new-window:before{content:"\e164"}.factory-bootstrap-400 .glyphicon-record:before{content:"\e165"}.factory-bootstrap-400 .glyphicon-save:before{content:"\e166"}.factory-bootstrap-400 .glyphicon-open:before{content:"\e167"}.factory-bootstrap-400 .glyphicon-saved:before{content:"\e168"}.factory-bootstrap-400 .glyphicon-import:before{content:"\e169"}.factory-bootstrap-400 .glyphicon-export:before{content:"\e170"}.factory-bootstrap-400 .glyphicon-send:before{content:"\e171"}.factory-bootstrap-400 .glyphicon-floppy-disk:before{content:"\e172"}.factory-bootstrap-400 .glyphicon-floppy-saved:before{content:"\e173"}.factory-bootstrap-400 .glyphicon-floppy-remove:before{content:"\e174"}.factory-bootstrap-400 .glyphicon-floppy-save:before{content:"\e175"}.factory-bootstrap-400 .glyphicon-floppy-open:before{content:"\e176"}.factory-bootstrap-400 .glyphicon-credit-card:before{content:"\e177"}.factory-bootstrap-400 .glyphicon-transfer:before{content:"\e178"}.factory-bootstrap-400 .glyphicon-cutlery:before{content:"\e179"}.factory-bootstrap-400 .glyphicon-header:before{content:"\e180"}.factory-bootstrap-400 .glyphicon-compressed:before{content:"\e181"}.factory-bootstrap-400 .glyphicon-earphone:before{content:"\e182"}.factory-bootstrap-400 .glyphicon-phone-alt:before{content:"\e183"}.factory-bootstrap-400 .glyphicon-tower:before{content:"\e184"}.factory-bootstrap-400 .glyphicon-stats:before{content:"\e185"}.factory-bootstrap-400 .glyphicon-sd-video:before{content:"\e186"}.factory-bootstrap-400 .glyphicon-hd-video:before{content:"\e187"}.factory-bootstrap-400 .glyphicon-subtitles:before{content:"\e188"}.factory-bootstrap-400 .glyphicon-sound-stereo:before{content:"\e189"}.factory-bootstrap-400 .glyphicon-sound-dolby:before{content:"\e190"}.factory-bootstrap-400 .glyphicon-sound-5-1:before{content:"\e191"}.factory-bootstrap-400 .glyphicon-sound-6-1:before{content:"\e192"}.factory-bootstrap-400 .glyphicon-sound-7-1:before{content:"\e193"}.factory-bootstrap-400 .glyphicon-copyright-mark:before{content:"\e194"}.factory-bootstrap-400 .glyphicon-registration-mark:before{content:"\e195"}.factory-bootstrap-400 .glyphicon-cloud-download:before{content:"\e197"}.factory-bootstrap-400 .glyphicon-cloud-upload:before{content:"\e198"}.factory-bootstrap-400 .glyphicon-tree-conifer:before{content:"\e199"}.factory-bootstrap-400 .glyphicon-tree-deciduous:before{content:"\e200"}.factory-bootstrap-400 .caret{display:inline-block;width:0;height:0;margin-left:2px;vertical-align:middle;border-top:4px solid;border-right:4px solid transparent;border-left:4px solid transparent}.factory-bootstrap-400 .dropdown{position:relative}.factory-bootstrap-400 .dropdown-toggle:focus{outline:0}.factory-bootstrap-400 .dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:160px;padding:5px 0;margin:2px 0 0;font-size:14px;list-style:none;background-color:#fff;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);background-clip:padding-box}.factory-bootstrap-400 .dropdown-menu.pull-right{right:0;left:auto}.factory-bootstrap-400 .dropdown-menu .divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.factory-bootstrap-400 .dropdown-menu>li>a{display:block;padding:3px 20px;clear:both;font-weight:400;line-height:1.428571429;color:#333;white-space:nowrap}.factory-bootstrap-400 .dropdown-menu>li>a:focus,.factory-bootstrap-400 .dropdown-menu>li>a:hover{color:#262626;text-decoration:none}.factory-bootstrap-400 .dropdown-menu>.active>a,.factory-bootstrap-400 .dropdown-menu>.active>a:focus,.factory-bootstrap-400 .dropdown-menu>.active>a:hover{color:#fff;text-decoration:none;outline:0}.factory-bootstrap-400 .dropdown-menu>.disabled>a,.factory-bootstrap-400 .dropdown-menu>.disabled>a:focus,.factory-bootstrap-400 .dropdown-menu>.disabled>a:hover{color:#999}.factory-bootstrap-400 .dropdown-menu>.disabled>a:focus,.factory-bootstrap-400 .dropdown-menu>.disabled>a:hover{text-decoration:none;cursor:not-allowed;background-color:transparent;background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.factory-bootstrap-400 .open>.dropdown-menu{display:block}.factory-bootstrap-400 .open>a{outline:0}.factory-bootstrap-400 .dropdown-header{display:block;padding:3px 20px;font-size:12px;line-height:1.428571429;color:#999}.factory-bootstrap-400 .dropdown-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:990}.factory-bootstrap-400 .pull-right>.dropdown-menu{right:0;left:auto}.factory-bootstrap-400 .dropup .caret,.factory-bootstrap-400 .navbar-fixed-bottom .dropdown .caret{border-top:0;border-bottom:4px solid;content:""}.factory-bootstrap-400 .dropup .dropdown-menu,.factory-bootstrap-400 .navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:1px}@media (min-width:768px){.navbar-right .dropdown-menu{right:0;left:auto}}.factory-bootstrap-400 .btn-group,.factory-bootstrap-400 .btn-group-vertical{position:relative;display:inline-block;vertical-align:middle}.factory-bootstrap-400 .btn-group-vertical>.btn,.factory-bootstrap-400 .btn-group>.btn{position:relative;float:left}.factory-bootstrap-400 .btn-group-vertical>.btn.active,.factory-bootstrap-400 .btn-group-vertical>.btn:active,.factory-bootstrap-400 .btn-group-vertical>.btn:focus,.factory-bootstrap-400 .btn-group-vertical>.btn:hover,.factory-bootstrap-400 .btn-group>.btn.active,.factory-bootstrap-400 .btn-group>.btn:active,.factory-bootstrap-400 .btn-group>.btn:focus,.factory-bootstrap-400 .btn-group>.btn:hover{z-index:2}.factory-bootstrap-400 .btn-group-vertical>.btn:focus,.factory-bootstrap-400 .btn-group>.btn:focus{outline:0}.factory-bootstrap-400 .btn-group .btn+.btn,.factory-bootstrap-400 .btn-group .btn+.btn-group,.factory-bootstrap-400 .btn-group .btn-group+.btn,.factory-bootstrap-400 .btn-group .btn-group+.btn-group{margin-left:-1px}.factory-bootstrap-400 .btn-toolbar:after,.factory-bootstrap-400 .btn-toolbar:before{display:table;content:" "}.factory-bootstrap-400 .btn-toolbar:after{clear:both}.factory-bootstrap-400 .btn-toolbar .btn-group{float:left}.factory-bootstrap-400 .btn-toolbar>.btn+.btn,.factory-bootstrap-400 .btn-toolbar>.btn+.btn-group,.factory-bootstrap-400 .btn-toolbar>.btn-group+.btn,.factory-bootstrap-400 .btn-toolbar>.btn-group+.btn-group{margin-left:5px}.factory-bootstrap-400 .btn-group>.btn:not(:first-child):not(:last-child):not(.dropdown-toggle){border-radius:0}.factory-bootstrap-400 .btn-group>.btn:first-child{margin-left:0}.factory-bootstrap-400 .btn-group>.btn:first-child:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.factory-bootstrap-400 .btn-group>.btn:last-child:not(:first-child),.factory-bootstrap-400 .btn-group>.dropdown-toggle:not(:first-child){border-bottom-left-radius:0;border-top-left-radius:0}.factory-bootstrap-400 .btn-group>.btn-group{float:left}.factory-bootstrap-400 .btn-group>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.factory-bootstrap-400 .btn-group>.btn-group:first-child>.btn:last-child,.factory-bootstrap-400 .btn-group>.btn-group:first-child>.dropdown-toggle{border-top-right-radius:0;border-bottom-right-radius:0}.factory-bootstrap-400 .btn-group>.btn-group:last-child>.btn:first-child{border-bottom-left-radius:0;border-top-left-radius:0}.factory-bootstrap-400 .btn-group .dropdown-toggle:active,.factory-bootstrap-400 .btn-group.open .dropdown-toggle{outline:0}.factory-bootstrap-400 .btn-group-xs>.btn{padding:1px 5px;font-size:12px;line-height:1.5;border-radius:3px}.factory-bootstrap-400 .btn-group-sm>.btn{padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.factory-bootstrap-400 .btn-group-lg>.btn{padding:10px 16px;font-size:18px;line-height:1.33;border-radius:6px}.factory-bootstrap-400 .btn-group>.btn+.dropdown-toggle{padding-right:8px;padding-left:8px}.factory-bootstrap-400 .btn-group>.btn-lg+.dropdown-toggle{padding-right:12px;padding-left:12px}.factory-bootstrap-400 .btn-group.open .dropdown-toggle{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.factory-bootstrap-400 .btn-group.open .dropdown-toggle.btn-link{-webkit-box-shadow:none;box-shadow:none}.factory-bootstrap-400 .btn-group{border:4px solid #f9f9f9;border-radius:4px}.factory-bootstrap-400 .btn-group .btn.active.value{text-shadow:none;color:#fff;background-color:#33aad5;-webkit-box-shadow:inset 0 1px 1px #0074a2;box-shadow:inset 0 1px 3px #0074a2;border-top:1px solid #0074a2;border-bottom:1px solid #0074a2;border-left:1px solid #0074a2}.factory-bootstrap-400 .btn .caret{margin-left:0}.factory-bootstrap-400 .btn-lg .caret{border-width:5px 5px 0;border-bottom-width:0}.factory-bootstrap-400 .dropup .btn-lg .caret{border-width:0 5px 5px}.factory-bootstrap-400 .btn-group-vertical>.btn,.factory-bootstrap-400 .btn-group-vertical>.btn-group,.factory-bootstrap-400 .btn-group-vertical>.btn-group>.btn{display:block;float:none;width:100%;max-width:100%}.factory-bootstrap-400 .btn-group-vertical>.btn-group:after,.factory-bootstrap-400 .btn-group-vertical>.btn-group:before{display:table;content:" "}.factory-bootstrap-400 .btn-group-vertical>.btn-group:after{clear:both}.factory-bootstrap-400 .btn-group-vertical>.btn-group>.btn{float:none}.factory-bootstrap-400 .btn-group-vertical>.btn+.btn,.factory-bootstrap-400 .btn-group-vertical>.btn+.btn-group,.factory-bootstrap-400 .btn-group-vertical>.btn-group+.btn,.factory-bootstrap-400 .btn-group-vertical>.btn-group+.btn-group{margin-top:-1px;margin-left:0}.factory-bootstrap-400 .btn-group-vertical>.btn:not(:first-child):not(:last-child){border-radius:0}.factory-bootstrap-400 .btn-group-vertical>.btn:first-child:not(:last-child){border-top-right-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0}.factory-bootstrap-400 .btn-group-vertical>.btn:last-child:not(:first-child){border-top-right-radius:0;border-bottom-left-radius:4px;border-top-left-radius:0}.factory-bootstrap-400 .btn-group-vertical>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.factory-bootstrap-400 .btn-group-vertical>.btn-group:first-child>.btn:last-child,.factory-bootstrap-400 .btn-group-vertical>.btn-group:first-child>.dropdown-toggle{border-bottom-right-radius:0;border-bottom-left-radius:0}.factory-bootstrap-400 .btn-group-vertical>.btn-group:last-child>.btn:first-child{border-top-right-radius:0;border-top-left-radius:0}.factory-bootstrap-400 .btn-group-justified{display:table;width:100%;border-collapse:separate;table-layout:fixed}.factory-bootstrap-400 .btn-group-justified>.btn,.factory-bootstrap-400 .btn-group-justified>.btn-group{display:table-cell;float:none;width:1%}.factory-bootstrap-400 .btn-group-justified>.btn-group .btn{width:100%}[data-toggle=buttons]>.btn>input[type=checkbox],[data-toggle=buttons]>.btn>input[type=radio]{display:none}.factory-bootstrap-400 .input-group{position:relative;display:table;border-collapse:separate}.factory-bootstrap-400 .input-group[class*=col-]{float:none;padding-right:0;padding-left:0}.factory-bootstrap-400 .input-group .form-control{width:100%;margin-bottom:0}.factory-bootstrap-400 .input-group-lg>.form-control,.factory-bootstrap-400 .input-group-lg>.input-group-addon,.factory-bootstrap-400 .input-group-lg>.input-group-btn>.btn{height:46px;padding:10px 16px;font-size:18px;line-height:1.33;border-radius:6px}.factory-bootstrap-400 select.input-group-lg>.form-control,.factory-bootstrap-400 select.input-group-lg>.input-group-addon,.factory-bootstrap-400 select.input-group-lg>.input-group-btn>.btn{height:46px;line-height:46px}.factory-bootstrap-400 textarea.input-group-lg>.form-control,.factory-bootstrap-400 textarea.input-group-lg>.input-group-addon,.factory-bootstrap-400 textarea.input-group-lg>.input-group-btn>.btn{height:auto}.factory-bootstrap-400 .input-group-sm>.form-control,.factory-bootstrap-400 .input-group-sm>.input-group-addon,.factory-bootstrap-400 .input-group-sm>.input-group-btn>.btn{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.factory-bootstrap-400 select.input-group-sm>.form-control,.factory-bootstrap-400 select.input-group-sm>.input-group-addon,.factory-bootstrap-400 select.input-group-sm>.input-group-btn>.btn{height:30px;line-height:30px}.factory-bootstrap-400 textarea.input-group-sm>.form-control,.factory-bootstrap-400 textarea.input-group-sm>.input-group-addon,.factory-bootstrap-400 textarea.input-group-sm>.input-group-btn>.btn{height:auto}.factory-bootstrap-400 .input-group .form-control,.factory-bootstrap-400 .input-group-addon,.factory-bootstrap-400 .input-group-btn{display:table-cell}.factory-bootstrap-400 .input-group .form-control:not(:first-child):not(:last-child),.factory-bootstrap-400 .input-group-addon:not(:first-child):not(:last-child),.factory-bootstrap-400 .input-group-btn:not(:first-child):not(:last-child){border-radius:0}.factory-bootstrap-400 .input-group-addon,.factory-bootstrap-400 .input-group-btn{width:1%;white-space:nowrap;vertical-align:middle}.factory-bootstrap-400 .input-group-addon{padding:6px 12px;font-size:14px;font-weight:400;line-height:1;color:#555;text-align:center;background-color:#eee;border:1px solid #ccc;border-radius:4px}.factory-bootstrap-400 .input-group-addon.input-sm{padding:5px 10px;font-size:12px;border-radius:3px}.factory-bootstrap-400 .input-group-addon.input-lg{padding:10px 16px;font-size:18px;border-radius:6px}.factory-bootstrap-400 .input-group-addon input[type=checkbox],.factory-bootstrap-400 .input-group-addon input[type=radio]{margin-top:0}.factory-bootstrap-400 .input-group .form-control:first-child,.factory-bootstrap-400 .input-group-addon:first-child,.factory-bootstrap-400 .input-group-btn:first-child>.btn,.factory-bootstrap-400 .input-group-btn:first-child>.dropdown-toggle,.factory-bootstrap-400 .input-group-btn:last-child>.btn:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.factory-bootstrap-400 .input-group-addon:first-child{border-right:0}.factory-bootstrap-400 .input-group .form-control:last-child,.factory-bootstrap-400 .input-group-addon:last-child,.factory-bootstrap-400 .input-group-btn:first-child>.btn:not(:first-child),.factory-bootstrap-400 .input-group-btn:last-child>.btn,.factory-bootstrap-400 .input-group-btn:last-child>.dropdown-toggle{border-bottom-left-radius:0;border-top-left-radius:0}.factory-bootstrap-400 .input-group-addon:last-child{border-left:0}.factory-bootstrap-400 .input-group-btn{position:relative;white-space:nowrap}.factory-bootstrap-400 .input-group-btn:first-child>.btn{margin-right:-1px}.factory-bootstrap-400 .input-group-btn:last-child>.btn{margin-left:-1px}.factory-bootstrap-400 .input-group-btn>.btn{position:relative}.factory-bootstrap-400 .input-group-btn>.btn+.btn{margin-left:-4px}.factory-bootstrap-400 .input-group-btn>.btn:active,.factory-bootstrap-400 .input-group-btn>.btn:hover{z-index:2}.factory-bootstrap-400 .nav{padding-left:0;margin-bottom:0;list-style:none}.factory-bootstrap-400 .nav:after,.factory-bootstrap-400 .nav:before{display:table;content:" "}.factory-bootstrap-400 .nav:after{clear:both}.factory-bootstrap-400 .nav>li{position:relative;display:block}.factory-bootstrap-400 .nav>li>a{position:relative;display:block;padding:10px 15px}.factory-bootstrap-400 .nav>li>a:focus,.factory-bootstrap-400 .nav>li>a:hover{text-decoration:none;background-color:#eee}.factory-bootstrap-400 .nav>li.disabled>a{color:#999}.factory-bootstrap-400 .nav>li.disabled>a:focus,.factory-bootstrap-400 .nav>li.disabled>a:hover{color:#999;text-decoration:none;cursor:not-allowed;background-color:transparent}.factory-bootstrap-400 .nav .open>a,.factory-bootstrap-400 .nav .open>a:focus,.factory-bootstrap-400 .nav .open>a:hover{background-color:#eee;border-color:#428bca}.factory-bootstrap-400 .nav .nav-divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.factory-bootstrap-400 .nav>li>a>img{max-width:none}.factory-bootstrap-400 .nav-tabs{border-bottom:1px solid #ddd}.factory-bootstrap-400 .nav-tabs>li{float:left;margin-bottom:-1px}.factory-bootstrap-400 .nav-tabs>li>a{margin-right:2px;line-height:1.428571429;border:1px solid transparent;border-radius:4px 4px 0 0}.factory-bootstrap-400 .nav-tabs>li>a:hover{border-color:#eee #eee #ddd}.factory-bootstrap-400 .nav-tabs>li.active>a,.factory-bootstrap-400 .nav-tabs>li.active>a:focus,.factory-bootstrap-400 .nav-tabs>li.active>a:hover{color:#555;cursor:default;background-color:#fff;border:1px solid #ddd;border-bottom-color:transparent}.factory-bootstrap-400 .nav-tabs.nav-justified{width:100%;border-bottom:0}.factory-bootstrap-400 .nav-tabs.nav-justified>li{float:none}.factory-bootstrap-400 .nav-tabs.nav-justified>li>a{margin-bottom:5px;text-align:center}.factory-bootstrap-400 .nav-tabs.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-tabs.nav-justified>li{display:table-cell;width:1%}.nav-tabs.nav-justified>li>a{margin-bottom:0}}.factory-bootstrap-400 .nav-tabs.nav-justified>li>a{margin-right:0;border-radius:4px}.factory-bootstrap-400 .nav-tabs.nav-justified>.active>a,.factory-bootstrap-400 .nav-tabs.nav-justified>.active>a:focus,.factory-bootstrap-400 .nav-tabs.nav-justified>.active>a:hover{border:1px solid #ddd}@media (min-width:768px){.nav-tabs.nav-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:focus,.nav-tabs.nav-justified>.active>a:hover{border-bottom-color:#fff}}.factory-bootstrap-400 .nav-pills>li{float:left}.factory-bootstrap-400 .nav-pills>li>a{border-radius:4px}.factory-bootstrap-400 .nav-pills>li+li{margin-left:2px}.factory-bootstrap-400 .nav-pills>li.active>a,.factory-bootstrap-400 .nav-pills>li.active>a:focus,.factory-bootstrap-400 .nav-pills>li.active>a:hover{color:#fff;background-color:#428bca}.factory-bootstrap-400 .nav-stacked>li{float:none}.factory-bootstrap-400 .nav-stacked>li+li{margin-top:2px;margin-left:0}.factory-bootstrap-400 .nav-justified{width:100%}.factory-bootstrap-400 .nav-justified>li{float:none}.factory-bootstrap-400 .nav-justified>li>a{margin-bottom:5px;text-align:center}.factory-bootstrap-400 .nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-justified>li{display:table-cell;width:1%}.nav-justified>li>a{margin-bottom:0}}.factory-bootstrap-400 .nav-tabs-justified{border-bottom:0}.factory-bootstrap-400 .nav-tabs-justified>li>a{margin-right:0;border-radius:4px}.factory-bootstrap-400 .nav-tabs-justified>.active>a,.factory-bootstrap-400 .nav-tabs-justified>.active>a:focus,.factory-bootstrap-400 .nav-tabs-justified>.active>a:hover{border:1px solid #ddd}@media (min-width:768px){.nav-tabs-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:focus,.nav-tabs-justified>.active>a:hover{border-bottom-color:#fff}}.factory-bootstrap-400 .tab-content>.tab-pane{display:none}.factory-bootstrap-400 .tab-content>.active{display:block}.factory-bootstrap-400 .nav-tabs .dropdown-menu{margin-top:-1px;border-top-right-radius:0;border-top-left-radius:0}.factory-bootstrap-400 .navbar{position:relative;min-height:50px;margin-bottom:20px;border:1px solid transparent}.factory-bootstrap-400 .navbar:after,.factory-bootstrap-400 .navbar:before{display:table;content:" "}.factory-bootstrap-400 .navbar:after{clear:both}@media (min-width:768px){.navbar{border-radius:4px}}.factory-bootstrap-400 .navbar-header:after,.factory-bootstrap-400 .navbar-header:before{display:table;content:" "}.factory-bootstrap-400 .navbar-header:after{clear:both}@media (min-width:768px){.navbar-header{float:left}}.factory-bootstrap-400 .navbar-collapse{max-height:340px;padding-right:15px;padding-left:15px;overflow-x:visible;border-top:1px solid transparent;box-shadow:inset 0 1px 0 rgba(255,255,255,.1);-webkit-overflow-scrolling:touch}.factory-bootstrap-400 .navbar-collapse:after,.factory-bootstrap-400 .navbar-collapse:before{display:table;content:" "}.factory-bootstrap-400 .navbar-collapse:after{clear:both}.factory-bootstrap-400 .navbar-collapse.in{overflow-y:auto}@media (min-width:768px){.navbar-collapse{width:auto;border-top:0;box-shadow:none}.navbar-collapse.collapse{display:block!important;height:auto!important;padding-bottom:0;overflow:visible!important}.navbar-collapse.in{overflow-y:visible}.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse,.navbar-static-top .navbar-collapse{padding-right:0;padding-left:0}}.factory-bootstrap-400 .container>.navbar-collapse,.factory-bootstrap-400 .container>.navbar-header{margin-right:-15px;margin-left:-15px}@media (min-width:768px){.container>.navbar-collapse,.container>.navbar-header{margin-right:0;margin-left:0}}.factory-bootstrap-400 .navbar-static-top{z-index:1000;border-width:0 0 1px}@media (min-width:768px){.navbar-static-top{border-radius:0}}.factory-bootstrap-400 .navbar-fixed-bottom,.factory-bootstrap-400 .navbar-fixed-top{position:fixed;right:0;left:0;z-index:1030}@media (min-width:768px){.navbar-fixed-bottom,.navbar-fixed-top{border-radius:0}}.factory-bootstrap-400 .navbar-fixed-top{top:0;border-width:0 0 1px}.factory-bootstrap-400 .navbar-fixed-bottom{bottom:0;margin-bottom:0;border-width:1px 0 0}.factory-bootstrap-400 .navbar-brand{float:left;padding:15px;font-size:18px;line-height:20px}.factory-bootstrap-400 .navbar-brand:focus,.factory-bootstrap-400 .navbar-brand:hover{text-decoration:none}@media (min-width:768px){.navbar>.container .navbar-brand{margin-left:-15px}}.factory-bootstrap-400 .navbar-toggle{position:relative;float:right;padding:9px 10px;margin-top:8px;margin-right:15px;margin-bottom:8px;background-color:transparent;background-image:none;border:1px solid transparent;border-radius:4px}.factory-bootstrap-400 .navbar-toggle .icon-bar{display:block;width:22px;height:2px;border-radius:1px}.factory-bootstrap-400 .navbar-toggle .icon-bar+.icon-bar{margin-top:4px}@media (min-width:768px){.navbar-toggle{display:none}}.factory-bootstrap-400 .navbar-nav{margin:7.5px -15px}.factory-bootstrap-400 .navbar-nav>li>a{padding-top:10px;padding-bottom:10px;line-height:20px}@media (max-width:767px){.navbar-nav .open .dropdown-menu{position:static;float:none;width:auto;margin-top:0;background-color:transparent;border:0;box-shadow:none}.navbar-nav .open .dropdown-menu .dropdown-header,.navbar-nav .open .dropdown-menu>li>a{padding:5px 15px 5px 25px}.navbar-nav .open .dropdown-menu>li>a{line-height:20px}.navbar-nav .open .dropdown-menu>li>a:focus,.navbar-nav .open .dropdown-menu>li>a:hover{background-image:none}}@media (min-width:768px){.navbar-nav{float:left;margin:0}.navbar-nav>li{float:left}.navbar-nav>li>a{padding-top:15px;padding-bottom:15px}.navbar-nav.navbar-right:last-child{margin-right:-15px}}@media (min-width:768px){.navbar-left{float:left!important}.navbar-right{float:right!important}}.factory-bootstrap-400 .navbar-form{padding:10px 15px;margin-top:8px;margin-right:-15px;margin-bottom:8px;margin-left:-15px;border-top:1px solid transparent;border-bottom:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 1px 0 rgba(255,255,255,.1)}@media (min-width:768px){.navbar-form .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.navbar-form .form-control{display:inline-block}.navbar-form select.form-control{width:auto}.navbar-form .checkbox,.navbar-form .radio{display:inline-block;padding-left:0;margin-top:0;margin-bottom:0}.navbar-form .checkbox input[type=checkbox],.navbar-form .radio input[type=radio]{float:none;margin-left:0}}@media (max-width:767px){.navbar-form .form-group{margin-bottom:5px}}@media (min-width:768px){.navbar-form{width:auto;padding-top:0;padding-bottom:0;margin-right:0;margin-left:0;border:0;-webkit-box-shadow:none;box-shadow:none}.navbar-form.navbar-right:last-child{margin-right:-15px}}.factory-bootstrap-400 .navbar-nav>li>.dropdown-menu{margin-top:0;border-top-right-radius:0;border-top-left-radius:0}.factory-bootstrap-400 .navbar-fixed-bottom .navbar-nav>li>.dropdown-menu{border-bottom-right-radius:0;border-bottom-left-radius:0}.factory-bootstrap-400 .navbar-nav.pull-right>li>.dropdown-menu,.factory-bootstrap-400 .navbar-nav>li>.dropdown-menu.pull-right{right:0;left:auto}.factory-bootstrap-400 .navbar-btn{margin-top:8px;margin-bottom:8px}.factory-bootstrap-400 .navbar-btn.btn-sm{margin-top:10px;margin-bottom:10px}.factory-bootstrap-400 .navbar-btn.btn-xs{margin-top:14px;margin-bottom:14px}.factory-bootstrap-400 .navbar-text{margin-top:15px;margin-bottom:15px}@media (min-width:768px){.navbar-text{float:left;margin-right:15px;margin-left:15px}.navbar-text.navbar-right:last-child{margin-right:0}}.factory-bootstrap-400 .navbar-default{background-color:#f8f8f8;border-color:#e7e7e7}.factory-bootstrap-400 .navbar-default .navbar-brand{color:#777}.factory-bootstrap-400 .navbar-default .navbar-brand:focus,.factory-bootstrap-400 .navbar-default .navbar-brand:hover{color:#5e5e5e;background-color:transparent}.factory-bootstrap-400 .navbar-default .navbar-nav>li>a,.factory-bootstrap-400 .navbar-default .navbar-text{color:#777}.factory-bootstrap-400 .navbar-default .navbar-nav>li>a:focus,.factory-bootstrap-400 .navbar-default .navbar-nav>li>a:hover{color:#333;background-color:transparent}.factory-bootstrap-400 .navbar-default .navbar-nav>.active>a,.factory-bootstrap-400 .navbar-default .navbar-nav>.active>a:focus,.factory-bootstrap-400 .navbar-default .navbar-nav>.active>a:hover{color:#555;background-color:#e7e7e7}.factory-bootstrap-400 .navbar-default .navbar-nav>.disabled>a,.factory-bootstrap-400 .navbar-default .navbar-nav>.disabled>a:focus,.factory-bootstrap-400 .navbar-default .navbar-nav>.disabled>a:hover{color:#ccc;background-color:transparent}.factory-bootstrap-400 .navbar-default .navbar-toggle{border-color:#ddd}.factory-bootstrap-400 .navbar-default .navbar-toggle:focus,.factory-bootstrap-400 .navbar-default .navbar-toggle:hover{background-color:#ddd}.factory-bootstrap-400 .navbar-default .navbar-toggle .icon-bar{background-color:#ccc}.factory-bootstrap-400 .navbar-default .navbar-collapse,.factory-bootstrap-400 .navbar-default .navbar-form{border-color:#e7e7e7}.factory-bootstrap-400 .navbar-default .navbar-nav>.open>a,.factory-bootstrap-400 .navbar-default .navbar-nav>.open>a:focus,.factory-bootstrap-400 .navbar-default .navbar-nav>.open>a:hover{color:#555;background-color:#e7e7e7}@media (max-width:767px){.navbar-default .navbar-nav .open .dropdown-menu>li>a{color:#777}.navbar-default .navbar-nav .open .dropdown-menu>li>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>li>a:hover{color:#333;background-color:transparent}.navbar-default .navbar-nav .open .dropdown-menu>.active>a,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:hover{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:hover{color:#ccc;background-color:transparent}}.factory-bootstrap-400 .navbar-default .navbar-link{color:#777}.factory-bootstrap-400 .navbar-default .navbar-link:hover{color:#333}.factory-bootstrap-400 .navbar-inverse{background-color:#222;border-color:#080808}.factory-bootstrap-400 .navbar-inverse .navbar-brand{color:#999}.factory-bootstrap-400 .navbar-inverse .navbar-brand:focus,.factory-bootstrap-400 .navbar-inverse .navbar-brand:hover{color:#fff;background-color:transparent}.factory-bootstrap-400 .navbar-inverse .navbar-nav>li>a,.factory-bootstrap-400 .navbar-inverse .navbar-text{color:#999}.factory-bootstrap-400 .navbar-inverse .navbar-nav>li>a:focus,.factory-bootstrap-400 .navbar-inverse .navbar-nav>li>a:hover{color:#fff;background-color:transparent}.factory-bootstrap-400 .navbar-inverse .navbar-nav>.active>a,.factory-bootstrap-400 .navbar-inverse .navbar-nav>.active>a:focus,.factory-bootstrap-400 .navbar-inverse .navbar-nav>.active>a:hover{color:#fff;background-color:#080808}.factory-bootstrap-400 .navbar-inverse .navbar-nav>.disabled>a,.factory-bootstrap-400 .navbar-inverse .navbar-nav>.disabled>a:focus,.factory-bootstrap-400 .navbar-inverse .navbar-nav>.disabled>a:hover{color:#444;background-color:transparent}.factory-bootstrap-400 .navbar-inverse .navbar-toggle{border-color:#333}.factory-bootstrap-400 .navbar-inverse .navbar-toggle:focus,.factory-bootstrap-400 .navbar-inverse .navbar-toggle:hover{background-color:#333}.factory-bootstrap-400 .navbar-inverse .navbar-toggle .icon-bar{background-color:#fff}.factory-bootstrap-400 .navbar-inverse .navbar-collapse,.factory-bootstrap-400 .navbar-inverse .navbar-form{border-color:#101010}.factory-bootstrap-400 .navbar-inverse .navbar-nav>.open>a,.factory-bootstrap-400 .navbar-inverse .navbar-nav>.open>a:focus,.factory-bootstrap-400 .navbar-inverse .navbar-nav>.open>a:hover{color:#fff;background-color:#080808}@media (max-width:767px){.navbar-inverse .navbar-nav .open .dropdown-menu>.dropdown-header{border-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu .divider{background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a{color:#999}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:hover{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:hover{color:#444;background-color:transparent}}.factory-bootstrap-400 .navbar-inverse .navbar-link{color:#999}.factory-bootstrap-400 .navbar-inverse .navbar-link:hover{color:#fff}.factory-bootstrap-400 .breadcrumb{padding:8px 15px;margin-bottom:20px;list-style:none;background-color:#f5f5f5;border-radius:4px}.factory-bootstrap-400 .breadcrumb>li{display:inline-block}.factory-bootstrap-400 .breadcrumb>li+li:before{padding:0 5px;color:#ccc;content:"/\00a0"}.factory-bootstrap-400 .breadcrumb>.active{color:#999}.factory-bootstrap-400 .pagination{display:inline-block;padding-left:0;margin:20px 0;border-radius:4px}.factory-bootstrap-400 .pagination>li{display:inline}.factory-bootstrap-400 .pagination>li>a,.factory-bootstrap-400 .pagination>li>span{position:relative;float:left;padding:6px 12px;margin-left:-1px;line-height:1.428571429;text-decoration:none;background-color:#fff;border:1px solid #ddd}.factory-bootstrap-400 .pagination>li:first-child>a,.factory-bootstrap-400 .pagination>li:first-child>span{margin-left:0;border-bottom-left-radius:4px;border-top-left-radius:4px}.factory-bootstrap-400 .pagination>li:last-child>a,.factory-bootstrap-400 .pagination>li:last-child>span{border-top-right-radius:4px;border-bottom-right-radius:4px}.factory-bootstrap-400 .pagination>li>a:focus,.factory-bootstrap-400 .pagination>li>a:hover,.factory-bootstrap-400 .pagination>li>span:focus,.factory-bootstrap-400 .pagination>li>span:hover{background-color:#eee}.factory-bootstrap-400 .pagination>.active>a,.factory-bootstrap-400 .pagination>.active>a:focus,.factory-bootstrap-400 .pagination>.active>a:hover,.factory-bootstrap-400 .pagination>.active>span,.factory-bootstrap-400 .pagination>.active>span:focus,.factory-bootstrap-400 .pagination>.active>span:hover{z-index:2;color:#fff;cursor:default;background-color:#1e8cbe;border-color:#0074a2}.factory-bootstrap-400 .pagination>.disabled>a,.factory-bootstrap-400 .pagination>.disabled>a:focus,.factory-bootstrap-400 .pagination>.disabled>a:hover,.factory-bootstrap-400 .pagination>.disabled>span,.factory-bootstrap-400 .pagination>.disabled>span:focus,.factory-bootstrap-400 .pagination>.disabled>span:hover{color:#999;cursor:not-allowed;background-color:#fff;border-color:#ddd}.factory-bootstrap-400 .pagination-lg>li>a,.factory-bootstrap-400 .pagination-lg>li>span{padding:10px 16px;font-size:18px}.factory-bootstrap-400 .pagination-lg>li:first-child>a,.factory-bootstrap-400 .pagination-lg>li:first-child>span{border-bottom-left-radius:6px;border-top-left-radius:6px}.factory-bootstrap-400 .pagination-lg>li:last-child>a,.factory-bootstrap-400 .pagination-lg>li:last-child>span{border-top-right-radius:6px;border-bottom-right-radius:6px}.factory-bootstrap-400 .pagination-sm>li>a,.factory-bootstrap-400 .pagination-sm>li>span{padding:5px 10px;font-size:12px}.factory-bootstrap-400 .pagination-sm>li:first-child>a,.factory-bootstrap-400 .pagination-sm>li:first-child>span{border-bottom-left-radius:3px;border-top-left-radius:3px}.factory-bootstrap-400 .pagination-sm>li:last-child>a,.factory-bootstrap-400 .pagination-sm>li:last-child>span{border-top-right-radius:3px;border-bottom-right-radius:3px}.factory-bootstrap-400 .pager{padding-left:0;margin:20px 0;text-align:center;list-style:none}.factory-bootstrap-400 .pager:after,.factory-bootstrap-400 .pager:before{display:table;content:" "}.factory-bootstrap-400 .pager:after{clear:both}.factory-bootstrap-400 .pager li{display:inline}.factory-bootstrap-400 .pager li>a,.factory-bootstrap-400 .pager li>span{display:inline-block;padding:5px 14px;background-color:#fff;border:1px solid #ddd;border-radius:15px}.factory-bootstrap-400 .pager li>a:focus,.factory-bootstrap-400 .pager li>a:hover{text-decoration:none;background-color:#eee}.factory-bootstrap-400 .pager .next>a,.factory-bootstrap-400 .pager .next>span{float:right}.factory-bootstrap-400 .pager .previous>a,.factory-bootstrap-400 .pager .previous>span{float:left}.factory-bootstrap-400 .pager .disabled>a,.factory-bootstrap-400 .pager .disabled>a:focus,.factory-bootstrap-400 .pager .disabled>a:hover,.factory-bootstrap-400 .pager .disabled>span{color:#999;cursor:not-allowed;background-color:#fff}.factory-bootstrap-400 .label{display:inline;padding:.2em .6em .3em;font-size:75%;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25em}.factory-bootstrap-400 .label[href]:focus,.factory-bootstrap-400 .label[href]:hover{color:#fff;text-decoration:none;cursor:pointer}.factory-bootstrap-400 .label:empty{display:none}.factory-bootstrap-400 .btn .label{position:relative;top:-1px}.factory-bootstrap-400 .label-default{background-color:#999}.factory-bootstrap-400 .label-default[href]:focus,.factory-bootstrap-400 .label-default[href]:hover{background-color:gray}.factory-bootstrap-400 .label-primary{background-color:#428bca}.factory-bootstrap-400 .label-primary[href]:focus,.factory-bootstrap-400 .label-primary[href]:hover{background-color:#3071a9}.factory-bootstrap-400 .label-success{background-color:#5cb85c}.factory-bootstrap-400 .label-success[href]:focus,.factory-bootstrap-400 .label-success[href]:hover{background-color:#449d44}.factory-bootstrap-400 .label-info{background-color:#5bc0de}.factory-bootstrap-400 .label-info[href]:focus,.factory-bootstrap-400 .label-info[href]:hover{background-color:#31b0d5}.factory-bootstrap-400 .label-warning{background-color:#f0ad4e}.factory-bootstrap-400 .label-warning[href]:focus,.factory-bootstrap-400 .label-warning[href]:hover{background-color:#ec971f}.factory-bootstrap-400 .label-danger{background-color:#d9534f}.factory-bootstrap-400 .label-danger[href]:focus,.factory-bootstrap-400 .label-danger[href]:hover{background-color:#c9302c}.factory-bootstrap-400 .badge{display:inline-block;min-width:10px;padding:3px 7px;font-size:12px;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;background-color:#999;border-radius:10px}.factory-bootstrap-400 .badge:empty{display:none}.factory-bootstrap-400 .btn .badge{position:relative;top:-1px}.factory-bootstrap-400 a.badge:focus,.factory-bootstrap-400 a.badge:hover{color:#fff;text-decoration:none;cursor:pointer}.factory-bootstrap-400 .nav-pills>.active>a>.badge,.factory-bootstrap-400 a.list-group-item.active>.badge{color:#428bca;background-color:#fff}.factory-bootstrap-400 .nav-pills>li>a>.badge{margin-left:3px}.factory-bootstrap-400 .jumbotron{padding:30px;margin-bottom:30px;font-size:21px;font-weight:200;line-height:2.1428571435;color:inherit;background-color:#eee}.factory-bootstrap-400 .jumbotron .h1,.factory-bootstrap-400 .jumbotron h1{line-height:1;color:inherit}.factory-bootstrap-400 .jumbotron p{line-height:1.4}.factory-bootstrap-400 .container .jumbotron{border-radius:6px}.factory-bootstrap-400 .jumbotron .container{max-width:100%}@media screen and (min-width:768px){.jumbotron{padding-top:48px;padding-bottom:48px}.container .jumbotron{padding-right:60px;padding-left:60px}.jumbotron .h1,.jumbotron h1{font-size:63px}}.factory-bootstrap-400 .thumbnail{display:block;padding:4px;margin-bottom:20px;line-height:1.428571429;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.factory-bootstrap-400 .thumbnail a>img,.factory-bootstrap-400 .thumbnail>img{display:block;height:auto;max-width:100%;margin-right:auto;margin-left:auto}.factory-bootstrap-400 a.thumbnail.active,.factory-bootstrap-400 a.thumbnail:focus,.factory-bootstrap-400 a.thumbnail:hover{border-color:#428bca}.factory-bootstrap-400 .thumbnail .caption{padding:9px;color:#333}.factory-bootstrap-400 .alert{border:1px solid transparent;border-radius:4px}.factory-bootstrap-400 .alert h4{margin-top:0;color:inherit}.factory-bootstrap-400 .alert .alert-link{font-weight:700}.factory-bootstrap-400 .alert>p,.factory-bootstrap-400 .alert>ul{margin-bottom:0}.factory-bootstrap-400 .alert>p+p{margin-top:5px}.factory-bootstrap-400 .alert-dismissable{padding-right:35px}.factory-bootstrap-400 .alert-dismissable .close{position:relative;top:-2px;right:-21px;color:inherit}.factory-bootstrap-400 .alert-info{color:#31708f;background-color:#d9edf7}.factory-bootstrap-400 .alert-info hr{border-top-color:#a6e1ec}.factory-bootstrap-400 .alert-info .alert-link{color:#245269}@-webkit-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}.factory-bootstrap-400 .progress{height:20px;margin-bottom:20px;overflow:hidden;background-color:#f5f5f5;border-radius:4px;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,.1);box-shadow:inset 0 1px 2px rgba(0,0,0,.1)}.factory-bootstrap-400 .progress-bar{float:left;width:0;height:100%;font-size:12px;line-height:20px;color:#fff;text-align:center;background-color:#2ea2cc;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);-webkit-transition:width .6s ease;transition:width .6s ease}.factory-bootstrap-400 .progress-striped .progress-bar{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-size:40px 40px}.factory-bootstrap-400 .progress.active .progress-bar{-webkit-animation:progress-bar-stripes 2s linear infinite;animation:progress-bar-stripes 2s linear infinite}.factory-bootstrap-400 .progress-bar-success{background-color:#5cb85c}.factory-bootstrap-400 .progress-striped .progress-bar-success{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.factory-bootstrap-400 .progress-bar-info{background-color:#5bc0de}.factory-bootstrap-400 .progress-striped .progress-bar-info{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.factory-bootstrap-400 .progress-bar-warning{background-color:#f0ad4e}.factory-bootstrap-400 .progress-striped .progress-bar-warning{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.factory-bootstrap-400 .progress-bar-danger{background-color:#d9534f}.factory-bootstrap-400 .progress-striped .progress-bar-danger{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.factory-bootstrap-400 .media,.factory-bootstrap-400 .media-body{overflow:hidden;zoom:1}.factory-bootstrap-400 .media,.factory-bootstrap-400 .media .media{margin-top:15px}.factory-bootstrap-400 .media:first-child{margin-top:0}.factory-bootstrap-400 .media-object{display:block}.factory-bootstrap-400 .media-heading{margin:0 0 5px}.factory-bootstrap-400 .media>.pull-left{margin-right:10px}.factory-bootstrap-400 .media>.pull-right{margin-left:10px}.factory-bootstrap-400 .media-list{padding-left:0;list-style:none}.factory-bootstrap-400 .list-group{padding-left:0;margin-bottom:20px}.factory-bootstrap-400 .list-group-item{position:relative;display:block;padding:10px 15px;margin-bottom:-1px;background-color:#fff;border:1px solid #ddd}.factory-bootstrap-400 .list-group-item:first-child{border-top-right-radius:4px;border-top-left-radius:4px}.factory-bootstrap-400 .list-group-item:last-child{margin-bottom:0;border-bottom-right-radius:4px;border-bottom-left-radius:4px}.factory-bootstrap-400 .list-group-item>.badge{float:right}.factory-bootstrap-400 .list-group-item>.badge+.badge{margin-right:5px}.factory-bootstrap-400 a.list-group-item{color:#555}.factory-bootstrap-400 a.list-group-item .list-group-item-heading{color:#333}.factory-bootstrap-400 a.list-group-item:focus,.factory-bootstrap-400 a.list-group-item:hover{text-decoration:none;background-color:#f5f5f5}.factory-bootstrap-400 a.list-group-item.active,.factory-bootstrap-400 a.list-group-item.active:focus,.factory-bootstrap-400 a.list-group-item.active:hover{z-index:2;color:#fff;background-color:#428bca;border-color:#428bca}.factory-bootstrap-400 a.list-group-item.active .list-group-item-heading,.factory-bootstrap-400 a.list-group-item.active:focus .list-group-item-heading,.factory-bootstrap-400 a.list-group-item.active:hover .list-group-item-heading{color:inherit}.factory-bootstrap-400 a.list-group-item.active .list-group-item-text,.factory-bootstrap-400 a.list-group-item.active:focus .list-group-item-text,.factory-bootstrap-400 a.list-group-item.active:hover .list-group-item-text{color:#e1edf7}.factory-bootstrap-400 .list-group-item-heading{margin-top:0;margin-bottom:5px}.factory-bootstrap-400 .list-group-item-text{margin-bottom:0;line-height:1.3}.factory-bootstrap-400 .panel{margin-bottom:20px;background-color:#fff;border:1px solid transparent;border-radius:4px}.factory-bootstrap-400 .panel-body{padding:15px}.factory-bootstrap-400 .panel-body:after,.factory-bootstrap-400 .panel-body:before{display:table;content:" "}.factory-bootstrap-400 .panel-body:after{clear:both}.factory-bootstrap-400 .panel>.list-group{margin-bottom:0}.factory-bootstrap-400 .panel>.list-group .list-group-item{border-width:1px 0}.factory-bootstrap-400 .panel>.list-group .list-group-item:first-child{border-top-right-radius:0;border-top-left-radius:0}.factory-bootstrap-400 .panel>.list-group .list-group-item:last-child{border-bottom:0}.factory-bootstrap-400 .panel-heading+.list-group .list-group-item:first-child{border-top-width:0}.factory-bootstrap-400 .panel>.table,.factory-bootstrap-400 .panel>.table-responsive>.table{margin-bottom:0}.factory-bootstrap-400 .panel>.panel-body+.table,.factory-bootstrap-400 .panel>.panel-body+.table-responsive{border-top:1px solid #ddd}.factory-bootstrap-400 .panel>.table>tbody:first-child td,.factory-bootstrap-400 .panel>.table>tbody:first-child th{border-top:0}.factory-bootstrap-400 .panel>.table-bordered,.factory-bootstrap-400 .panel>.table-responsive>.table-bordered{border:0}.factory-bootstrap-400 .panel>.table-bordered>tbody>tr>td:first-child,.factory-bootstrap-400 .panel>.table-bordered>tbody>tr>th:first-child,.factory-bootstrap-400 .panel>.table-bordered>tfoot>tr>td:first-child,.factory-bootstrap-400 .panel>.table-bordered>tfoot>tr>th:first-child,.factory-bootstrap-400 .panel>.table-bordered>thead>tr>td:first-child,.factory-bootstrap-400 .panel>.table-bordered>thead>tr>th:first-child,.factory-bootstrap-400 .panel>.table-responsive>.table-bordered>tbody>tr>td:first-child,.factory-bootstrap-400 .panel>.table-responsive>.table-bordered>tbody>tr>th:first-child,.factory-bootstrap-400 .panel>.table-responsive>.table-bordered>tfoot>tr>td:first-child,.factory-bootstrap-400 .panel>.table-responsive>.table-bordered>tfoot>tr>th:first-child,.factory-bootstrap-400 .panel>.table-responsive>.table-bordered>thead>tr>td:first-child,.factory-bootstrap-400 .panel>.table-responsive>.table-bordered>thead>tr>th:first-child{border-left:0}.factory-bootstrap-400 .panel>.table-bordered>tbody>tr>td:last-child,.factory-bootstrap-400 .panel>.table-bordered>tbody>tr>th:last-child,.factory-bootstrap-400 .panel>.table-bordered>tfoot>tr>td:last-child,.factory-bootstrap-400 .panel>.table-bordered>tfoot>tr>th:last-child,.factory-bootstrap-400 .panel>.table-bordered>thead>tr>td:last-child,.factory-bootstrap-400 .panel>.table-bordered>thead>tr>th:last-child,.factory-bootstrap-400 .panel>.table-responsive>.table-bordered>tbody>tr>td:last-child,.factory-bootstrap-400 .panel>.table-responsive>.table-bordered>tbody>tr>th:last-child,.factory-bootstrap-400 .panel>.table-responsive>.table-bordered>tfoot>tr>td:last-child,.factory-bootstrap-400 .panel>.table-responsive>.table-bordered>tfoot>tr>th:last-child,.factory-bootstrap-400 .panel>.table-responsive>.table-bordered>thead>tr>td:last-child,.factory-bootstrap-400 .panel>.table-responsive>.table-bordered>thead>tr>th:last-child{border-right:0}.factory-bootstrap-400 .panel>.table-bordered>tbody>tr:last-child>td,.factory-bootstrap-400 .panel>.table-bordered>tbody>tr:last-child>th,.factory-bootstrap-400 .panel>.table-bordered>tfoot>tr:last-child>td,.factory-bootstrap-400 .panel>.table-bordered>tfoot>tr:last-child>th,.factory-bootstrap-400 .panel>.table-bordered>thead>tr:last-child>td,.factory-bootstrap-400 .panel>.table-bordered>thead>tr:last-child>th,.factory-bootstrap-400 .panel>.table-responsive>.table-bordered>tbody>tr:last-child>td,.factory-bootstrap-400 .panel>.table-responsive>.table-bordered>tbody>tr:last-child>th,.factory-bootstrap-400 .panel>.table-responsive>.table-bordered>tfoot>tr:last-child>td,.factory-bootstrap-400 .panel>.table-responsive>.table-bordered>tfoot>tr:last-child>th,.factory-bootstrap-400 .panel>.table-responsive>.table-bordered>thead>tr:last-child>td,.factory-bootstrap-400 .panel>.table-responsive>.table-bordered>thead>tr:last-child>th{border-bottom:0}.factory-bootstrap-400 .panel>.table-responsive{margin-bottom:0;border:0}.factory-bootstrap-400 .panel-heading{padding:10px 15px;border-bottom:1px solid transparent;border-top-right-radius:3px;border-top-left-radius:3px}.factory-bootstrap-400 .panel-heading>.dropdown .dropdown-toggle{color:inherit}.factory-bootstrap-400 .panel-title{margin-top:0;margin-bottom:0;font-size:16px;color:inherit}.factory-bootstrap-400 .panel-title>a{color:inherit}.factory-bootstrap-400 .panel-footer{padding:10px 15px;background-color:#f5f5f5;border-top:1px solid #ddd;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.factory-bootstrap-400 .panel-group .panel{margin-bottom:0;overflow:hidden;border-radius:4px}.factory-bootstrap-400 .panel-group .panel+.panel{margin-top:5px}.factory-bootstrap-400 .panel-group .panel-heading{border-bottom:0}.factory-bootstrap-400 .panel-group .panel-heading+.panel-collapse .panel-body{border-top:1px solid #ddd}.factory-bootstrap-400 .panel-group .panel-footer{border-top:0}.factory-bootstrap-400 .panel-group .panel-footer+.panel-collapse .panel-body{border-bottom:1px solid #ddd}.factory-bootstrap-400 .panel-default{border-color:#ddd}.factory-bootstrap-400 .panel-default>.panel-heading{color:#333;background-color:#f5f5f5;border-color:#ddd}.factory-bootstrap-400 .panel-default>.panel-heading+.panel-collapse .panel-body{border-top-color:#ddd}.factory-bootstrap-400 .panel-default>.panel-footer+.panel-collapse .panel-body{border-bottom-color:#ddd}.factory-bootstrap-400 .panel-primary{border-color:#428bca}.factory-bootstrap-400 .panel-primary>.panel-heading{color:#fff;background-color:#428bca;border-color:#428bca}.factory-bootstrap-400 .panel-primary>.panel-heading+.panel-collapse .panel-body{border-top-color:#428bca}.factory-bootstrap-400 .panel-primary>.panel-footer+.panel-collapse .panel-body{border-bottom-color:#428bca}.factory-bootstrap-400 .panel-success{border-color:#d6e9c6}.factory-bootstrap-400 .panel-success>.panel-heading{color:#3c763d;background-color:#dff0d8;border-color:#d6e9c6}.factory-bootstrap-400 .panel-success>.panel-heading+.panel-collapse .panel-body{border-top-color:#d6e9c6}.factory-bootstrap-400 .panel-success>.panel-footer+.panel-collapse .panel-body{border-bottom-color:#d6e9c6}.factory-bootstrap-400 .panel-warning{border-color:#faebcc}.factory-bootstrap-400 .panel-warning>.panel-heading{color:#8a6d3b;background-color:#fcf8e3;border-color:#faebcc}.factory-bootstrap-400 .panel-warning>.panel-heading+.panel-collapse .panel-body{border-top-color:#faebcc}.factory-bootstrap-400 .panel-warning>.panel-footer+.panel-collapse .panel-body{border-bottom-color:#faebcc}.factory-bootstrap-400 .panel-danger{border-color:#ebccd1}.factory-bootstrap-400 .panel-danger>.panel-heading{color:#a94442;background-color:#f2dede;border-color:#ebccd1}.factory-bootstrap-400 .panel-danger>.panel-heading+.panel-collapse .panel-body{border-top-color:#ebccd1}.factory-bootstrap-400 .panel-danger>.panel-footer+.panel-collapse .panel-body{border-bottom-color:#ebccd1}.factory-bootstrap-400 .panel-info{border-color:#bce8f1}.factory-bootstrap-400 .panel-info>.panel-heading{color:#31708f;background-color:#d9edf7;border-color:#bce8f1}.factory-bootstrap-400 .panel-info>.panel-heading+.panel-collapse .panel-body{border-top-color:#bce8f1}.factory-bootstrap-400 .panel-info>.panel-footer+.panel-collapse .panel-body{border-bottom-color:#bce8f1}.factory-bootstrap-400 .well{min-height:20px;padding:19px;margin-bottom:20px;background-color:#f5f5f5;border:1px solid #e3e3e3;border-radius:4px}.factory-bootstrap-400 .well blockquote{border-color:#ddd;border-color:rgba(0,0,0,.15)}.factory-bootstrap-400 .well-lg{padding:24px;border-radius:6px}.factory-bootstrap-400 .well-sm{padding:9px;border-radius:3px}.factory-bootstrap-400 .close{float:right;font-size:14px;font-weight:700;line-height:1;color:#000;text-shadow:0 1px 0 #fff;opacity:.3;filter:alpha(opacity=30)}.factory-bootstrap-400 .alert .close{position:relative;top:-8px;right:-7px}.factory-bootstrap-400 .close:focus,.factory-bootstrap-400 .close:hover{color:#000;text-decoration:none;cursor:pointer;opacity:.5;filter:alpha(opacity=50)}.factory-bootstrap-400 button.close{padding:0;cursor:pointer;background:0 0;border:0;-webkit-appearance:none}.factory-bootstrap-400 .modal-open{overflow:hidden}.factory-bootstrap-400 .modal{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;display:none;overflow:auto;overflow-y:scroll;width:auto;margin-left:0;background-color:transparent;border:0}.factory-bootstrap-400 .modal.fade .modal-dialog{-webkit-transform:translate(0,-25%);-ms-transform:translate(0,-25%);transform:translate(0,-25%);-webkit-transition:-webkit-transform .3s ease-out;-moz-transition:-moz-transform .3s ease-out;-o-transition:-o-transform .3s ease-out;transition:transform .3s ease-out}.factory-bootstrap-400 .modal.in .modal-dialog{-webkit-transform:translate(0,0);-ms-transform:translate(0,0);transform:translate(0,0)}.factory-bootstrap-400 .modal-dialog{position:relative;z-index:1050;width:auto;margin:10px}.factory-bootstrap-400 .modal-content{position:relative;background-color:#fff;border:1px solid #999;border:1px solid rgba(0,0,0,.2);border-radius:6px;outline:0;-webkit-box-shadow:0 3px 9px rgba(0,0,0,.5);box-shadow:0 3px 9px rgba(0,0,0,.5);background-clip:padding-box}.factory-bootstrap-400 .modal-backdrop,.factory-bootstrap-400-modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1030;background-color:#000}.factory-bootstrap-400 .modal-backdrop.fade,.factory-bootstrap-400-modal-backdrop.fade{opacity:0;filter:alpha(opacity=0)}.factory-bootstrap-400 .modal-backdrop.in,.factory-bootstrap-400-modal-backdrop.in{opacity:.5;filter:alpha(opacity=50)}.factory-bootstrap-400 .modal-header{min-height:16.428571429px;padding:15px;border-bottom:1px solid #e5e5e5}.factory-bootstrap-400 .modal-header .close{margin-top:-2px}.factory-bootstrap-400 .modal-title{margin:0;line-height:1.428571429}.factory-bootstrap-400 .modal-body{position:relative;padding:20px;max-height:none}.factory-bootstrap-400 .modal-footer{padding:19px 20px 20px;margin-top:15px;text-align:right;border-top:1px solid #e5e5e5}.factory-bootstrap-400 .modal-footer:after,.factory-bootstrap-400 .modal-footer:before{display:table;content:" "}.factory-bootstrap-400 .modal-footer:after{clear:both}.factory-bootstrap-400 .modal-footer .btn+.btn{margin-bottom:0;margin-left:5px}.factory-bootstrap-400 .modal-footer .btn-group .btn+.btn{margin-left:-1px}.factory-bootstrap-400 .modal-footer .btn-block+.btn-block{margin-left:0}@media screen and (min-width:768px){.factory-bootstrap-400 .modal-dialog{width:600px;margin:30px auto}.factory-bootstrap-400 .modal-content{-webkit-box-shadow:0 5px 15px rgba(0,0,0,.5);box-shadow:0 5px 15px rgba(0,0,0,.5)}}.factory-bootstrap-400 .tooltip{position:absolute;z-index:1030;display:block;font-size:12px;line-height:1.4;opacity:0;filter:alpha(opacity=0);visibility:visible}.factory-bootstrap-400 .tooltip.in{opacity:.9;filter:alpha(opacity=90)}.factory-bootstrap-400 .tooltip.top{padding:5px 0;margin-top:-3px}.factory-bootstrap-400 .tooltip.right{padding:0 5px;margin-left:3px}.factory-bootstrap-400 .tooltip.bottom{padding:5px 0;margin-top:3px}.factory-bootstrap-400 .tooltip.left{padding:0 5px;margin-left:-3px}.factory-bootstrap-400 .tooltip-inner{width:400px;padding:15px 20px;color:#fff;text-align:left;text-decoration:none;background-color:#673ab7;border-radius:3px}.factory-bootstrap-400 .tooltip-arrow{position:absolute;width:0;height:0;border-color:transparent;border-style:solid}.factory-bootstrap-400 .tooltip.top .tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-top-color:#673ab7;border-width:5px 5px 0}.factory-bootstrap-400 .tooltip.top-left .tooltip-arrow{bottom:0;left:5px;border-top-color:#673ab7;border-width:5px 5px 0}.factory-bootstrap-400 .tooltip.top-right .tooltip-arrow{right:5px;bottom:0;border-top-color:#673ab7;border-width:5px 5px 0}.factory-bootstrap-400 .tooltip.right .tooltip-arrow{top:50%;left:0;margin-top:-5px;border-right-color:#673ab7;border-width:5px 5px 5px 0}.factory-bootstrap-400 .tooltip.left .tooltip-arrow{top:50%;right:0;margin-top:-5px;border-left-color:#673ab7;border-width:5px 0 5px 5px}.factory-bootstrap-400 .tooltip.bottom .tooltip-arrow{top:0;left:50%;margin-left:-5px;border-bottom-color:#673ab7;border-width:0 5px 5px}.factory-bootstrap-400 .tooltip.bottom-left .tooltip-arrow{top:0;left:5px;border-bottom-color:#673ab7;border-width:0 5px 5px}.factory-bootstrap-400 .tooltip.bottom-right .tooltip-arrow{top:0;right:5px;border-bottom-color:#673ab7;border-width:0 5px 5px}.factory-bootstrap-400 .popover{position:absolute;top:0;left:0;z-index:1010;display:none;max-width:276px;padding:1px;text-align:left;white-space:normal;background-color:#fff;border:1px solid #ccc;border:1px solid rgba(0,0,0,.2);border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,.2);box-shadow:0 5px 10px rgba(0,0,0,.2);background-clip:padding-box}.factory-bootstrap-400 .popover.top{margin-top:-10px}.factory-bootstrap-400 .popover.right{margin-left:10px}.factory-bootstrap-400 .popover.bottom{margin-top:10px}.factory-bootstrap-400 .popover.left{margin-left:-10px}.factory-bootstrap-400 .popover-title{padding:8px 14px;margin:0;font-size:14px;font-weight:400;line-height:18px;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-radius:5px 5px 0 0}.factory-bootstrap-400 .popover-content{padding:9px 14px}.factory-bootstrap-400 .popover .arrow,.factory-bootstrap-400 .popover .arrow:after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.factory-bootstrap-400 .popover .arrow{border-width:11px}.factory-bootstrap-400 .popover .arrow:after{border-width:10px;content:""}.factory-bootstrap-400 .popover.top .arrow{bottom:-11px;left:50%;margin-left:-11px;border-top-color:#999;border-top-color:rgba(0,0,0,.25);border-bottom-width:0}.factory-bootstrap-400 .popover.top .arrow:after{bottom:1px;margin-left:-10px;border-top-color:#fff;border-bottom-width:0;content:" "}.factory-bootstrap-400 .popover.right .arrow{top:50%;left:-11px;margin-top:-11px;border-right-color:#999;border-right-color:rgba(0,0,0,.25);border-left-width:0}.factory-bootstrap-400 .popover.right .arrow:after{bottom:-10px;left:1px;border-right-color:#fff;border-left-width:0;content:" "}.factory-bootstrap-400 .popover.bottom .arrow{top:-11px;left:50%;margin-left:-11px;border-bottom-color:#999;border-bottom-color:rgba(0,0,0,.25);border-top-width:0}.factory-bootstrap-400 .popover.bottom .arrow:after{top:1px;margin-left:-10px;border-bottom-color:#fff;border-top-width:0;content:" "}.factory-bootstrap-400 .popover.left .arrow{top:50%;right:-11px;margin-top:-11px;border-left-color:#999;border-left-color:rgba(0,0,0,.25);border-right-width:0}.factory-bootstrap-400 .popover.left .arrow:after{right:1px;bottom:-10px;border-left-color:#fff;border-right-width:0;content:" "}.factory-bootstrap-400 .carousel{position:relative}.factory-bootstrap-400 .carousel-inner{position:relative;width:100%;overflow:hidden}.factory-bootstrap-400 .carousel-inner>.item{position:relative;display:none;-webkit-transition:.6s ease-in-out left;transition:.6s ease-in-out left}.factory-bootstrap-400 .carousel-inner>.item>a>img,.factory-bootstrap-400 .carousel-inner>.item>img{display:block;height:auto;max-width:100%;line-height:1}.factory-bootstrap-400 .carousel-inner>.active,.factory-bootstrap-400 .carousel-inner>.next,.factory-bootstrap-400 .carousel-inner>.prev{display:block}.factory-bootstrap-400 .carousel-inner>.active{left:0}.factory-bootstrap-400 .carousel-inner>.next,.factory-bootstrap-400 .carousel-inner>.prev{position:absolute;top:0;width:100%}.factory-bootstrap-400 .carousel-inner>.next{left:100%}.factory-bootstrap-400 .carousel-inner>.prev{left:-100%}.factory-bootstrap-400 .carousel-inner>.next.left,.factory-bootstrap-400 .carousel-inner>.prev.right{left:0}.factory-bootstrap-400 .carousel-inner>.active.left{left:-100%}.factory-bootstrap-400 .carousel-inner>.active.right{left:100%}.factory-bootstrap-400 .carousel-control{position:absolute;top:0;bottom:0;left:0;width:15%;font-size:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,.6);opacity:.5;filter:alpha(opacity=50)}.factory-bootstrap-400 .carousel-control.left{background-image:-webkit-linear-gradient(left,color-stop(rgba(0,0,0,.5) 0),color-stop(rgba(0,0,0,.0001) 100%));background-image:linear-gradient(to right,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1)}.factory-bootstrap-400 .carousel-control.right{right:0;left:auto;background-image:-webkit-linear-gradient(left,color-stop(rgba(0,0,0,.0001) 0),color-stop(rgba(0,0,0,.5) 100%));background-image:linear-gradient(to right,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1)}.factory-bootstrap-400 .carousel-control:focus,.factory-bootstrap-400 .carousel-control:hover{color:#fff;text-decoration:none;outline:0;opacity:.9;filter:alpha(opacity=90)}.factory-bootstrap-400 .carousel-control .glyphicon-chevron-left,.factory-bootstrap-400 .carousel-control .glyphicon-chevron-right,.factory-bootstrap-400 .carousel-control .icon-next,.factory-bootstrap-400 .carousel-control .icon-prev{position:absolute;top:50%;z-index:5;display:inline-block}.factory-bootstrap-400 .carousel-control .glyphicon-chevron-left,.factory-bootstrap-400 .carousel-control .icon-prev{left:50%}.factory-bootstrap-400 .carousel-control .glyphicon-chevron-right,.factory-bootstrap-400 .carousel-control .icon-next{right:50%}.factory-bootstrap-400 .carousel-control .icon-next,.factory-bootstrap-400 .carousel-control .icon-prev{width:20px;height:20px;margin-top:-10px;margin-left:-10px;font-family:serif}.factory-bootstrap-400 .carousel-control .icon-prev:before{content:'\2039'}.factory-bootstrap-400 .carousel-control .icon-next:before{content:'\203a'}.factory-bootstrap-400 .carousel-indicators{position:absolute;bottom:10px;left:50%;z-index:15;width:60%;padding-left:0;margin-left:-30%;text-align:center;list-style:none}.factory-bootstrap-400 .carousel-indicators li{display:inline-block;width:10px;height:10px;margin:1px;text-indent:-999px;cursor:pointer;background-color:#000 \9;background-color:rgba(0,0,0,0);border:1px solid #fff;border-radius:10px}.factory-bootstrap-400 .carousel-indicators .active{width:12px;height:12px;margin:0;background-color:#fff}.factory-bootstrap-400 .carousel-caption{position:absolute;right:15%;bottom:20px;left:15%;z-index:10;padding-top:20px;padding-bottom:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,.6)}.factory-bootstrap-400 .carousel-caption .btn{text-shadow:none}@media screen and (min-width:768px){.carousel-control .glyphicons-chevron-left,.carousel-control .glyphicons-chevron-right,.carousel-control .icon-next,.carousel-control .icon-prev{width:30px;height:30px;margin-top:-15px;margin-left:-15px;font-size:30px}.carousel-caption{right:20%;left:20%;padding-bottom:30px}.carousel-indicators{bottom:20px}}.factory-bootstrap-400 .clearfix:after,.factory-bootstrap-400 .clearfix:before{display:table;content:" "}.factory-bootstrap-400 .clearfix:after{clear:both}.factory-bootstrap-400 .center-block{display:block;margin-right:auto;margin-left:auto}.factory-bootstrap-400 .pull-right{float:right!important}.factory-bootstrap-400 .pull-left{float:left!important}.factory-bootstrap-400 .hide{display:none!important}.factory-bootstrap-400 .show{display:block!important}.factory-bootstrap-400 .invisible{visibility:hidden}.factory-bootstrap-400 .text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.factory-bootstrap-400 .hidden{display:none!important;visibility:hidden!important}.factory-bootstrap-400 .affix{position:fixed}@-ms-viewport{width:device-width}.factory-bootstrap-400 .visible-lg,.factory-bootstrap-400 .visible-md,.factory-bootstrap-400 .visible-sm,.factory-bootstrap-400 .visible-xs,.factory-bootstrap-400 td.visible-lg,.factory-bootstrap-400 td.visible-md,.factory-bootstrap-400 td.visible-sm,.factory-bootstrap-400 td.visible-xs,.factory-bootstrap-400 th.visible-lg,.factory-bootstrap-400 th.visible-md,.factory-bootstrap-400 th.visible-sm,.factory-bootstrap-400 th.visible-xs,.factory-bootstrap-400 tr.visible-lg,.factory-bootstrap-400 tr.visible-md,.factory-bootstrap-400 tr.visible-sm,.factory-bootstrap-400 tr.visible-xs{display:none!important}@media (max-width:767px){.visible-xs{display:block!important}table.visible-xs{display:table}tr.visible-xs{display:table-row!important}td.visible-xs,th.visible-xs{display:table-cell!important}}@media (min-width:768px) and (max-width:991px){.visible-xs.visible-sm{display:block!important}table.visible-xs.visible-sm{display:table}tr.visible-xs.visible-sm{display:table-row!important}td.visible-xs.visible-sm,th.visible-xs.visible-sm{display:table-cell!important}}@media (min-width:992px) and (max-width:1199px){.visible-xs.visible-md{display:block!important}table.visible-xs.visible-md{display:table}tr.visible-xs.visible-md{display:table-row!important}td.visible-xs.visible-md,th.visible-xs.visible-md{display:table-cell!important}}@media (min-width:1200px){.visible-xs.visible-lg{display:block!important}table.visible-xs.visible-lg{display:table}tr.visible-xs.visible-lg{display:table-row!important}td.visible-xs.visible-lg,th.visible-xs.visible-lg{display:table-cell!important}}@media (max-width:767px){.visible-sm.visible-xs{display:block!important}table.visible-sm.visible-xs{display:table}tr.visible-sm.visible-xs{display:table-row!important}td.visible-sm.visible-xs,th.visible-sm.visible-xs{display:table-cell!important}}@media (min-width:768px) and (max-width:991px){.visible-sm{display:block!important}table.visible-sm{display:table}tr.visible-sm{display:table-row!important}td.visible-sm,th.visible-sm{display:table-cell!important}}@media (min-width:992px) and (max-width:1199px){.visible-sm.visible-md{display:block!important}table.visible-sm.visible-md{display:table}tr.visible-sm.visible-md{display:table-row!important}td.visible-sm.visible-md,th.visible-sm.visible-md{display:table-cell!important}}@media (min-width:1200px){.visible-sm.visible-lg{display:block!important}table.visible-sm.visible-lg{display:table}tr.visible-sm.visible-lg{display:table-row!important}td.visible-sm.visible-lg,th.visible-sm.visible-lg{display:table-cell!important}}@media (max-width:767px){.visible-md.visible-xs{display:block!important}table.visible-md.visible-xs{display:table}tr.visible-md.visible-xs{display:table-row!important}td.visible-md.visible-xs,th.visible-md.visible-xs{display:table-cell!important}}@media (min-width:768px) and (max-width:991px){.visible-md.visible-sm{display:block!important}table.visible-md.visible-sm{display:table}tr.visible-md.visible-sm{display:table-row!important}td.visible-md.visible-sm,th.visible-md.visible-sm{display:table-cell!important}}@media (min-width:992px) and (max-width:1199px){.visible-md{display:block!important}table.visible-md{display:table}tr.visible-md{display:table-row!important}td.visible-md,th.visible-md{display:table-cell!important}}@media (min-width:1200px){.visible-md.visible-lg{display:block!important}table.visible-md.visible-lg{display:table}tr.visible-md.visible-lg{display:table-row!important}td.visible-md.visible-lg,th.visible-md.visible-lg{display:table-cell!important}}@media (max-width:767px){.visible-lg.visible-xs{display:block!important}table.visible-lg.visible-xs{display:table}tr.visible-lg.visible-xs{display:table-row!important}td.visible-lg.visible-xs,th.visible-lg.visible-xs{display:table-cell!important}}@media (min-width:768px) and (max-width:991px){.visible-lg.visible-sm{display:block!important}table.visible-lg.visible-sm{display:table}tr.visible-lg.visible-sm{display:table-row!important}td.visible-lg.visible-sm,th.visible-lg.visible-sm{display:table-cell!important}}@media (min-width:992px) and (max-width:1199px){.visible-lg.visible-md{display:block!important}table.visible-lg.visible-md{display:table}tr.visible-lg.visible-md{display:table-row!important}td.visible-lg.visible-md,th.visible-lg.visible-md{display:table-cell!important}}@media (min-width:1200px){.visible-lg{display:block!important}table.visible-lg{display:table}tr.visible-lg{display:table-row!important}td.visible-lg,th.visible-lg{display:table-cell!important}}.factory-bootstrap-400 .hidden-xs{display:block!important}.factory-bootstrap-400 table.hidden-xs{display:table}.factory-bootstrap-400 tr.hidden-xs{display:table-row!important}.factory-bootstrap-400 td.hidden-xs,.factory-bootstrap-400 th.hidden-xs{display:table-cell!important}@media (max-width:767px){.hidden-xs,td.hidden-xs,th.hidden-xs,tr.hidden-xs{display:none!important}}@media (min-width:768px) and (max-width:991px){.hidden-xs.hidden-sm,td.hidden-xs.hidden-sm,th.hidden-xs.hidden-sm,tr.hidden-xs.hidden-sm{display:none!important}}@media (min-width:992px) and (max-width:1199px){.hidden-xs.hidden-md,td.hidden-xs.hidden-md,th.hidden-xs.hidden-md,tr.hidden-xs.hidden-md{display:none!important}}@media (min-width:1200px){.hidden-xs.hidden-lg,td.hidden-xs.hidden-lg,th.hidden-xs.hidden-lg,tr.hidden-xs.hidden-lg{display:none!important}}.factory-bootstrap-400 .hidden-sm{display:block!important}.factory-bootstrap-400 table.hidden-sm{display:table}.factory-bootstrap-400 tr.hidden-sm{display:table-row!important}.factory-bootstrap-400 td.hidden-sm,.factory-bootstrap-400 th.hidden-sm{display:table-cell!important}@media (max-width:767px){.hidden-sm.hidden-xs,td.hidden-sm.hidden-xs,th.hidden-sm.hidden-xs,tr.hidden-sm.hidden-xs{display:none!important}}@media (min-width:768px) and (max-width:991px){.hidden-sm,td.hidden-sm,th.hidden-sm,tr.hidden-sm{display:none!important}}@media (min-width:992px) and (max-width:1199px){.hidden-sm.hidden-md,td.hidden-sm.hidden-md,th.hidden-sm.hidden-md,tr.hidden-sm.hidden-md{display:none!important}}@media (min-width:1200px){.hidden-sm.hidden-lg,td.hidden-sm.hidden-lg,th.hidden-sm.hidden-lg,tr.hidden-sm.hidden-lg{display:none!important}}.factory-bootstrap-400 .hidden-md{display:block!important}.factory-bootstrap-400 table.hidden-md{display:table}.factory-bootstrap-400 tr.hidden-md{display:table-row!important}.factory-bootstrap-400 td.hidden-md,.factory-bootstrap-400 th.hidden-md{display:table-cell!important}@media (max-width:767px){.hidden-md.hidden-xs,td.hidden-md.hidden-xs,th.hidden-md.hidden-xs,tr.hidden-md.hidden-xs{display:none!important}}@media (min-width:768px) and (max-width:991px){.hidden-md.hidden-sm,td.hidden-md.hidden-sm,th.hidden-md.hidden-sm,tr.hidden-md.hidden-sm{display:none!important}}@media (min-width:992px) and (max-width:1199px){.hidden-md,td.hidden-md,th.hidden-md,tr.hidden-md{display:none!important}}@media (min-width:1200px){.hidden-md.hidden-lg,td.hidden-md.hidden-lg,th.hidden-md.hidden-lg,tr.hidden-md.hidden-lg{display:none!important}}.factory-bootstrap-400 .hidden-lg{display:block!important}.factory-bootstrap-400 table.hidden-lg{display:table}.factory-bootstrap-400 tr.hidden-lg{display:table-row!important}.factory-bootstrap-400 td.hidden-lg,.factory-bootstrap-400 th.hidden-lg{display:table-cell!important}@media (max-width:767px){.factory-bootstrap-400 .hidden-lg.hidden-xs,.factory-bootstrap-400 td.hidden-lg.hidden-xs,.factory-bootstrap-400 th.hidden-lg.hidden-xs,.factory-bootstrap-400 tr.hidden-lg.hidden-xs{display:none!important}}@media (min-width:768px) and (max-width:991px){.factory-bootstrap-400 .hidden-lg.hidden-sm,.factory-bootstrap-400 td.hidden-lg.hidden-sm,.factory-bootstrap-400 th.hidden-lg.hidden-sm,.factory-bootstrap-400 tr.hidden-lg.hidden-sm{display:none!important}}@media (min-width:992px) and (max-width:1199px){.factory-bootstrap-400 .hidden-lg.hidden-md,.factory-bootstrap-400 td.hidden-lg.hidden-md,.factory-bootstrap-400 th.hidden-lg.hidden-md,.factory-bootstrap-400 tr.hidden-lg.hidden-md{display:none!important}}@media (min-width:1200px){.factory-bootstrap-400 .hidden-lg,.factory-bootstrap-400 td.hidden-lg,.factory-bootstrap-400 th.hidden-lg,.factory-bootstrap-400 tr.hidden-lg{display:none!important}}.factory-bootstrap-400 .visible-print,.factory-bootstrap-400 td.visible-print,.factory-bootstrap-400 th.visible-print,.factory-bootstrap-400 tr.visible-print{display:none!important}@media print{.factory-bootstrap-400 .visible-print{display:block!important}.factory-bootstrap-400 table.visible-print{display:table}.factory-bootstrap-400 tr.visible-print{display:table-row!important}.factory-bootstrap-400 td.visible-print,.factory-bootstrap-400 th.visible-print{display:table-cell!important}.factory-bootstrap-400 .hidden-print,.factory-bootstrap-400 td.hidden-print,.factory-bootstrap-400 th.hidden-print,.factory-bootstrap-400 tr.hidden-print{display:none!important}}/*!
12
  * Factory Default Bootstrap Theme
13
  *
14
  * The code is based on Bootstrap v2.1.1
@@ -22,4 +22,4 @@
22
  *
23
  * @package factory-bootstrap
24
  * @since 1.0.0
25
- */.factory-bootstrap-400 .btn-danger,.factory-bootstrap-400 .btn-default,.factory-bootstrap-400 .btn-info,.factory-bootstrap-400 .btn-primary,.factory-bootstrap-400 .btn-success,.factory-bootstrap-400 .btn-warning{-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 1px rgba(0,0,0,.075)}.factory-bootstrap-400 .btn-danger.active,.factory-bootstrap-400 .btn-danger:active,.factory-bootstrap-400 .btn-default.active,.factory-bootstrap-400 .btn-default:active,.factory-bootstrap-400 .btn-info.active,.factory-bootstrap-400 .btn-info:active,.factory-bootstrap-400 .btn-primary.active,.factory-bootstrap-400 .btn-primary:active,.factory-bootstrap-400 .btn-success.active,.factory-bootstrap-400 .btn-success:active,.factory-bootstrap-400 .btn-warning.active,.factory-bootstrap-400 .btn-warning:active{-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.1);box-shadow:inset 0 1px 1px rgba(0,0,0,.1)}.factory-bootstrap-400 .btn.active,.factory-bootstrap-400 .btn:active{background-image:none}.factory-bootstrap-400 .btn-default{color:#555;border-color:#ccc;background:#f7f7f7;-webkit-box-shadow:inset 0 1px 0 #fff,0 1px 0 rgba(0,0,0,.08);box-shadow:inset 0 1px 0 #fff,0 1px 0 rgba(0,0,0,.08);vertical-align:top}.factory-bootstrap-400 .btn-default.active,.factory-bootstrap-400 .btn-default:active{background-color:#fff;border-color:#dbdbdb}.factory-bootstrap-400 .btn-gold{font-weight:700;padding:7px 12px;cursor:pointer;line-height:16px;display:inline-block;border-radius:2px;-moz-border-radius:2px;-webkit-border-radius:2px;box-shadow:#e3e3e3 0 1px 1px;-moz-box-shadow:0 1px 1px rgba(000,000,000,.1),inset 0 1px 1px rgba(255,255,255,.7);-webkit-box-shadow:0 1px 1px rgba(000,000,000,.1),inset 0 1px 1px rgba(255,255,255,.7);text-shadow:1px 1px 0 #ffe8b2;color:#7c5d1b;border:1px solid #d6a437;background:#feeb80}.factory-bootstrap-400 .btn-gold:focus,.factory-bootstrap-400 .btn-gold:hover{background:#fef0a1}.factory-bootstrap-400 .btn-gold.active,.factory-bootstrap-400 .btn-gold:active{background:#fef0a1;-webkit-box-shadow:inset 0 3px 8px 0 #f8ba36;box-shadow:inset 0 3px 8px 0 #f8ba36}.factory-bootstrap-400 .btn-primary{background:#2ea2cc;border-color:#0074a2;-webkit-box-shadow:inset 0 1px 0 rgba(120,200,230,.5),0 1px 0 rgba(0,0,0,.15);box-shadow:inset 0 1px 0 rgba(120,200,230,.5),0 1px 0 rgba(0,0,0,.15);color:#fff;text-decoration:none}.factory-bootstrap-400 .btn-primary:focus,.factory-bootstrap-400 .btn-primary:hover{background:#1e8cbe;border-color:#0074a2;-webkit-box-shadow:inset 0 1px 0 rgba(120,200,230,.6);box-shadow:inset 0 1px 0 rgba(120,200,230,.6);color:#fff}.factory-bootstrap-400 .btn-primary.active,.factory-bootstrap-400 .btn-primary:active{background-color:#2d6ca2;border-color:#2b669a}.factory-bootstrap-400 .btn-success{background-image:-webkit-linear-gradient(top,#5cb85c 0,#419641 100%);background-image:linear-gradient(to bottom,#5cb85c 0,#419641 100%);background-repeat:repeat-x;border-color:#3e8f3e;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff419641', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.factory-bootstrap-400 .btn-success:focus,.factory-bootstrap-400 .btn-success:hover{background-color:#419641;background-position:0 -15px}.factory-bootstrap-400 .btn-success.active,.factory-bootstrap-400 .btn-success:active{background-color:#419641;border-color:#3e8f3e}.factory-bootstrap-400 .btn-warning{background-image:-webkit-linear-gradient(top,#f0ad4e 0,#eb9316 100%);background-image:linear-gradient(to bottom,#f0ad4e 0,#eb9316 100%);background-repeat:repeat-x;border-color:#e38d13;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffeb9316', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.factory-bootstrap-400 .btn-warning:focus,.factory-bootstrap-400 .btn-warning:hover{background-color:#eb9316;background-position:0 -15px}.factory-bootstrap-400 .btn-warning.active,.factory-bootstrap-400 .btn-warning:active{background-color:#eb9316;border-color:#e38d13}.factory-bootstrap-400 .btn-danger{color:#fff;background:#d9534f;border-color:#d43f3a}.factory-bootstrap-400 .btn-danger.active,.factory-bootstrap-400 .btn-danger:active,.factory-bootstrap-400 .btn-danger:focus,.factory-bootstrap-400 .btn-danger:hover,.factory-bootstrap-400 .open .dropdown-toggle.btn-danger{color:#fff;background-color:#d2322d;border-color:#ac2925}.factory-bootstrap-400 .btn-info{background-image:-webkit-linear-gradient(top,#5bc0de 0,#2aabd2 100%);background-image:linear-gradient(to bottom,#5bc0de 0,#2aabd2 100%);background-repeat:repeat-x;border-color:#28a4c9;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff2aabd2', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.factory-bootstrap-400 .btn-info:focus,.factory-bootstrap-400 .btn-info:hover{background-color:#2aabd2;background-position:0 -15px}.factory-bootstrap-400 .btn-info.active,.factory-bootstrap-400 .btn-info:active{background-color:#2aabd2;border-color:#28a4c9}.factory-bootstrap-400 .img-thumbnail,.factory-bootstrap-400 .thumbnail{-webkit-box-shadow:0 1px 2px rgba(0,0,0,.075);box-shadow:0 1px 2px rgba(0,0,0,.075)}.factory-bootstrap-400 .dropdown-menu>li>a:focus,.factory-bootstrap-400 .dropdown-menu>li>a:hover{background-color:#e8e8e8;background-image:-webkit-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%);background-image:linear-gradient(to bottom,#f5f5f5 0,#e8e8e8 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0)}.factory-bootstrap-400 .dropdown-menu>.active>a,.factory-bootstrap-400 .dropdown-menu>.active>a:focus,.factory-bootstrap-400 .dropdown-menu>.active>a:hover{background-color:#357ebd;background-image:-webkit-linear-gradient(top,#428bca 0,#357ebd 100%);background-image:linear-gradient(to bottom,#428bca 0,#357ebd 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff357ebd', GradientType=0)}.factory-bootstrap-400 .navbar-default{background-image:-webkit-linear-gradient(top,#fff 0,#f8f8f8 100%);background-image:linear-gradient(to bottom,#fff 0,#f8f8f8 100%);background-repeat:repeat-x;border-radius:4px;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#fff8f8f8', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 5px rgba(0,0,0,.075);box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 5px rgba(0,0,0,.075)}.factory-bootstrap-400 .navbar-default .navbar-nav>.active>a{background-image:-webkit-linear-gradient(top,#ebebeb 0,#f3f3f3 100%);background-image:linear-gradient(to bottom,#ebebeb 0,#f3f3f3 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffebebeb', endColorstr='#fff3f3f3', GradientType=0);-webkit-box-shadow:inset 0 3px 9px rgba(0,0,0,.075);box-shadow:inset 0 3px 9px rgba(0,0,0,.075)}.factory-bootstrap-400 .navbar-brand,.factory-bootstrap-400 .navbar-nav>li>a{text-shadow:0 1px 0 rgba(255,255,255,.25)}.factory-bootstrap-400 .navbar-inverse{background-image:-webkit-linear-gradient(top,#3c3c3c 0,#222 100%);background-image:linear-gradient(to bottom,#3c3c3c 0,#222 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff3c3c3c', endColorstr='#ff222222', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.factory-bootstrap-400 .navbar-inverse .navbar-nav>.active>a{background-image:-webkit-linear-gradient(top,#222 0,#282828 100%);background-image:linear-gradient(to bottom,#222 0,#282828 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff222222', endColorstr='#ff282828', GradientType=0);-webkit-box-shadow:inset 0 3px 9px rgba(0,0,0,.25);box-shadow:inset 0 3px 9px rgba(0,0,0,.25)}.factory-bootstrap-400 .navbar-inverse .navbar-brand,.factory-bootstrap-400 .navbar-inverse .navbar-nav>li>a{text-shadow:0 -1px 0 rgba(0,0,0,.25)}.factory-bootstrap-400 .navbar-fixed-bottom,.factory-bootstrap-400 .navbar-fixed-top,.factory-bootstrap-400 .navbar-static-top{border-radius:0}.factory-bootstrap-400 .alert{-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.25),0 1px 2px rgba(0,0,0,.05)}.factory-bootstrap-400 .alert .actions{padding-top:10px}.factory-bootstrap-400 .alert-success{color:#3c763d;background-color:#dff0d8;border-bottom:2px solid #c8e5bc}.factory-bootstrap-400 .alert-info{background-image:-webkit-linear-gradient(top,#d9edf7 0,#b9def0 100%);background-image:linear-gradient(to bottom,#d9edf7 0,#b9def0 100%);background-repeat:repeat-x;border-color:#9acfea;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffb9def0', GradientType=0)}.factory-bootstrap-400 .alert{text-shadow:none;box-shadow:none;margin:0;margin-top:10px;margin-bottom:10px;padding:10px}.factory-bootstrap-400 .alert-normal,.factory-bootstrap-400 .alert-warning{background:#fcf8e3;color:#8a6d3b;border:1px solid #b8823b}.factory-bootstrap-400 .alert-danger{background:#cf4944;color:#fff;border-bottom:2px solid #b23e3a}.factory-bootstrap-400 .alert-danger a:not(.btn),.factory-bootstrap-400 .alert-error a:not(.btn){color:#fff}.factory-bootstrap-400 .progress{background-image:-webkit-linear-gradient(top,#ebebeb 0,#f5f5f5 100%);background-image:linear-gradient(to bottom,#ebebeb 0,#f5f5f5 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffebebeb', endColorstr='#fff5f5f5', GradientType=0)}.factory-bootstrap-400 .progress-bar{background-image:-webkit-linear-gradient(top,#428bca 0,#3071a9 100%);background-image:linear-gradient(to bottom,#428bca 0,#3071a9 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff3071a9', GradientType=0)}.factory-bootstrap-400 .progress-bar-success{background-image:-webkit-linear-gradient(top,#5cb85c 0,#449d44 100%);background-image:linear-gradient(to bottom,#5cb85c 0,#449d44 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff449d44', GradientType=0)}.factory-bootstrap-400 .progress-bar-info{background-image:-webkit-linear-gradient(top,#5bc0de 0,#31b0d5 100%);background-image:linear-gradient(to bottom,#5bc0de 0,#31b0d5 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff31b0d5', GradientType=0)}.factory-bootstrap-400 .progress-bar-warning{background-image:-webkit-linear-gradient(top,#f0ad4e 0,#ec971f 100%);background-image:linear-gradient(to bottom,#f0ad4e 0,#ec971f 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffec971f', GradientType=0)}.factory-bootstrap-400 .progress-bar-danger{background-image:-webkit-linear-gradient(top,#d9534f 0,#c9302c 100%);background-image:linear-gradient(to bottom,#d9534f 0,#c9302c 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc9302c', GradientType=0)}.factory-bootstrap-400 .list-group{border-radius:4px;-webkit-box-shadow:0 1px 2px rgba(0,0,0,.075);box-shadow:0 1px 2px rgba(0,0,0,.075)}.factory-bootstrap-400 .list-group-item.active,.factory-bootstrap-400 .list-group-item.active:focus,.factory-bootstrap-400 .list-group-item.active:hover{text-shadow:0 -1px 0 #3071a9;background-image:-webkit-linear-gradient(top,#428bca 0,#3278b3 100%);background-image:linear-gradient(to bottom,#428bca 0,#3278b3 100%);background-repeat:repeat-x;border-color:#3278b3;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff3278b3', GradientType=0)}.factory-bootstrap-400 .panel{-webkit-box-shadow:0 1px 2px rgba(0,0,0,.05);box-shadow:0 1px 2px rgba(0,0,0,.05)}.factory-bootstrap-400 .panel-default>.panel-heading{background-image:-webkit-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%);background-image:linear-gradient(to bottom,#f5f5f5 0,#e8e8e8 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0)}.factory-bootstrap-400 .panel-primary>.panel-heading{background-image:-webkit-linear-gradient(top,#428bca 0,#357ebd 100%);background-image:linear-gradient(to bottom,#428bca 0,#357ebd 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff357ebd', GradientType=0)}.factory-bootstrap-400 .panel-success>.panel-heading{background-image:-webkit-linear-gradient(top,#dff0d8 0,#d0e9c6 100%);background-image:linear-gradient(to bottom,#dff0d8 0,#d0e9c6 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffd0e9c6', GradientType=0)}.factory-bootstrap-400 .panel-info>.panel-heading{background-image:-webkit-linear-gradient(top,#d9edf7 0,#c4e3f3 100%);background-image:linear-gradient(to bottom,#d9edf7 0,#c4e3f3 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffc4e3f3', GradientType=0)}.factory-bootstrap-400 .panel-warning>.panel-heading{background-image:-webkit-linear-gradient(top,#fcf8e3 0,#faf2cc 100%);background-image:linear-gradient(to bottom,#fcf8e3 0,#faf2cc 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fffaf2cc', GradientType=0)}.factory-bootstrap-400 .panel-danger>.panel-heading{background-image:-webkit-linear-gradient(top,#f2dede 0,#ebcccc 100%);background-image:linear-gradient(to bottom,#f2dede 0,#ebcccc 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffebcccc', GradientType=0)}.factory-bootstrap-400 .well{background-image:-webkit-linear-gradient(top,#e8e8e8 0,#f5f5f5 100%);background-image:linear-gradient(to bottom,#e8e8e8 0,#f5f5f5 100%);background-repeat:repeat-x;border-color:#dcdcdc;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe8e8e8', endColorstr='#fff5f5f5', GradientType=0);-webkit-box-shadow:inset 0 1px 3px rgba(0,0,0,.05),0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 3px rgba(0,0,0,.05),0 1px 0 rgba(255,255,255,.1)}.factory-bootstrap-400 .factory-after{margin-left:7px;display:inline-block}.factory-bootstrap-400 .factory-hidden{display:none}.factory-bootstrap-400 .factory-ajax-loader{width:25px;height:25px;background:url(../assets/images/loader-sm-tr.gif)}.factory-control-error{background-color:rgba(0,0,0,.8);white-space:normal;z-index:10;font-weight:400;line-height:150%;border-radius:4px;color:#fff;font-size:13px;margin-top:5px;padding:4px 10px 3px;max-width:500px;display:inline-block}.factory-control-error i{margin:0 7px 0 1px}
8
  */
9
 
10
 
11
+ .factory-bootstrap-421 article,.factory-bootstrap-421 aside,.factory-bootstrap-421 details,.factory-bootstrap-421 figcaption,.factory-bootstrap-421 figure,.factory-bootstrap-421 footer,.factory-bootstrap-421 header,.factory-bootstrap-421 hgroup,.factory-bootstrap-421 main,.factory-bootstrap-421 nav,.factory-bootstrap-421 section,.factory-bootstrap-421 summary{display:block}.factory-bootstrap-421 audio,.factory-bootstrap-421 canvas,.factory-bootstrap-421 video{display:inline-block}.factory-bootstrap-421 audio:not([controls]){display:none;height:0}.factory-bootstrap-421 [hidden],.factory-bootstrap-421 template{display:none}.factory-bootstrap-421 body{margin:0}.factory-bootstrap-421 a{background:0 0}.factory-bootstrap-421 a:focus{outline:thin dotted}.factory-bootstrap-421 a:active,.factory-bootstrap-421 a:hover{outline:0}.factory-bootstrap-421 h1{margin:.67em 0}.factory-bootstrap-421 b,.factory-bootstrap-421 strong{font-weight:700}.factory-bootstrap-421 dfn{font-style:italic}.factory-bootstrap-421 hr{height:0;-moz-box-sizing:content-box;box-sizing:content-box}.factory-bootstrap-421 mark{color:#000;background:#ff0}.factory-bootstrap-421 code,.factory-bootstrap-421 kbd,.factory-bootstrap-421 pre,.factory-bootstrap-421 samp{font-size:1em}.factory-bootstrap-421 pre{white-space:pre-wrap}.factory-bootstrap-421 q{quotes:"\201C" "\201D" "\2018" "\2019"}.factory-bootstrap-421 sub,.factory-bootstrap-421 sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}.factory-bootstrap-421 sup{top:-.5em}.factory-bootstrap-421 sub{bottom:-.25em}.factory-bootstrap-421 img{border:0}.factory-bootstrap-421 svg:not(:root){overflow:hidden}.factory-bootstrap-421 figure{margin:0}.factory-bootstrap-421 button,.factory-bootstrap-421 input,.factory-bootstrap-421 select,.factory-bootstrap-421 textarea{margin:0}.factory-bootstrap-421 button,.factory-bootstrap-421 select{text-transform:none}.factory-bootstrap-421 select{padding-right:4px!important}.factory-bootstrap-421 button,.factory-bootstrap-421 input[type=reset],.factory-bootstrap-421 input[type=submit],html .factory-bootstrap-421 input[type=button]{cursor:pointer;-webkit-appearance:button}.factory-bootstrap-421 button[disabled],html .factory-bootstrap-421 input[disabled]{cursor:default}.factory-bootstrap-421 input[type=checkbox],.factory-bootstrap-421 input[type=radio]{padding:0;box-sizing:border-box}.factory-bootstrap-421 input[type=search]{-webkit-appearance:textfield}.factory-bootstrap-421 input[type=search]::-webkit-search-cancel-button,.factory-bootstrap-421 input[type=search]::-webkit-search-decoration{-webkit-appearance:none}.factory-bootstrap-421 button::-moz-focus-inner,.factory-bootstrap-421 input::-moz-focus-inner{padding:0;border:0}.factory-bootstrap-421 textarea{overflow:auto;vertical-align:top}.factory-bootstrap-421 table{border-collapse:collapse;border-spacing:0}@media print{.factory-bootstrap-421 *{color:#000!important;text-shadow:none!important;background:transparent!important;box-shadow:none!important}.factory-bootstrap-421 a,.factory-bootstrap-421 a:visited{text-decoration:underline}.factory-bootstrap-421 a[href]:after{content:" (" attr(href) ")"}.factory-bootstrap-421 abbr[title]:after{content:" (" attr(title) ")"}.factory-bootstrap-421 a[href^="javascript:"]:after,.factory-bootstrap-421 a[href^="#"]:after{content:""}.factory-bootstrap-421 blockquote,.factory-bootstrap-421 pre{border:1px solid #999;page-break-inside:avoid}.factory-bootstrap-421 thead{display:table-header-group}.factory-bootstrap-421 img,.factory-bootstrap-421 tr{page-break-inside:avoid}.factory-bootstrap-421 img{max-width:100%!important}@page{margin:2cm .5cm}.factory-bootstrap-421 h2,.factory-bootstrap-421 h3,.factory-bootstrap-421 p{orphans:3;widows:3}.factory-bootstrap-421 h2,.factory-bootstrap-421 h3{page-break-after:avoid}.factory-bootstrap-421 select{background:#fff!important}.factory-bootstrap-421 .navbar{display:none}.factory-bootstrap-421 .table td,.factory-bootstrap-421 .table th{background-color:#fff!important}.factory-bootstrap-421 .btn>.caret,.factory-bootstrap-421 .dropup>.btn>.caret{border-top-color:#000!important}.factory-bootstrap-421 .label{border:1px solid #000}.factory-bootstrap-421 .table{border-collapse:collapse!important}.factory-bootstrap-421 .table-bordered td,.factory-bootstrap-421 .table-bordered th{border:1px solid #ddd!important}}.factory-bootstrap-421 *,.factory-bootstrap-421 :after,.factory-bootstrap-421 :before{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html .factory-bootstrap-421{-webkit-tap-highlight-color:rgba(0,0,0,0)}.factory-bootstrap-421 body{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;line-height:1.428571429;color:#333;background-color:#fff}.factory-bootstrap-421 button,.factory-bootstrap-421 input,.factory-bootstrap-421 select,.factory-bootstrap-421 textarea{font-family:inherit;font-size:inherit;line-height:inherit}.factory-bootstrap-421 img{vertical-align:middle}.factory-bootstrap-421 .img-responsive{display:block;height:auto;max-width:100%}.factory-bootstrap-421 .img-rounded{border-radius:6px}.factory-bootstrap-421 .img-thumbnail{display:inline-block;height:auto;max-width:100%;padding:4px;line-height:1.428571429;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.factory-bootstrap-421 .img-circle{border-radius:50%}.factory-bootstrap-421 hr{margin-top:20px;margin-bottom:20px;border:0;border-top:1px solid #eee}.factory-bootstrap-421 .sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.factory-bootstrap-421 .h1,.factory-bootstrap-421 .h2,.factory-bootstrap-421 .h3,.factory-bootstrap-421 .h4,.factory-bootstrap-421 .h5,.factory-bootstrap-421 .h6,.factory-bootstrap-421 h1,.factory-bootstrap-421 h2,.factory-bootstrap-421 h3,.factory-bootstrap-421 h4,.factory-bootstrap-421 h5,.factory-bootstrap-421 h6{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-weight:500;line-height:1.1;color:inherit}.factory-bootstrap-421 .h1 .small,.factory-bootstrap-421 .h1 small,.factory-bootstrap-421 .h2 .small,.factory-bootstrap-421 .h2 small,.factory-bootstrap-421 .h3 .small,.factory-bootstrap-421 .h3 small,.factory-bootstrap-421 .h4 .small,.factory-bootstrap-421 .h4 small,.factory-bootstrap-421 .h5 .small,.factory-bootstrap-421 .h5 small,.factory-bootstrap-421 .h6 .small,.factory-bootstrap-421 .h6 small,.factory-bootstrap-421 h1 .small,.factory-bootstrap-421 h1 small,.factory-bootstrap-421 h2 .small,.factory-bootstrap-421 h2 small,.factory-bootstrap-421 h3 .small,.factory-bootstrap-421 h3 small,.factory-bootstrap-421 h4 .small,.factory-bootstrap-421 h4 small,.factory-bootstrap-421 h5 .small,.factory-bootstrap-421 h5 small,.factory-bootstrap-421 h6 .small,.factory-bootstrap-421 h6 small{font-weight:400;line-height:1;color:#999}.factory-bootstrap-421 h1,.factory-bootstrap-421 h2,.factory-bootstrap-421 h3{margin-top:20px;margin-bottom:10px}.factory-bootstrap-421 h1 .small,.factory-bootstrap-421 h1 small,.factory-bootstrap-421 h2 .small,.factory-bootstrap-421 h2 small,.factory-bootstrap-421 h3 .small,.factory-bootstrap-421 h3 small{font-size:65%}.factory-bootstrap-421 h4,.factory-bootstrap-421 h5,.factory-bootstrap-421 h6{margin-top:10px;margin-bottom:10px}.factory-bootstrap-421 h4 .small,.factory-bootstrap-421 h4 small,.factory-bootstrap-421 h5 .small,.factory-bootstrap-421 h5 small,.factory-bootstrap-421 h6 .small,.factory-bootstrap-421 h6 small{font-size:75%}.factory-bootstrap-421 .h1,.factory-bootstrap-421 h1{font-size:36px}.factory-bootstrap-421 .h2,.factory-bootstrap-421 h2{font-size:30px}.factory-bootstrap-421 .h3,.factory-bootstrap-421 h3{font-size:24px}.factory-bootstrap-421 .h4,.factory-bootstrap-421 h4{font-size:18px}.factory-bootstrap-421 .h5,.factory-bootstrap-421 h5{font-size:14px}.factory-bootstrap-421 .h6,.factory-bootstrap-421 h6{font-size:12px}.factory-bootstrap-421 p{margin:0 0 10px}.factory-bootstrap-421 .lead{margin-bottom:20px;font-size:16px;font-weight:200;line-height:1.4}@media (min-width:768px){.lead{font-size:21px}}.factory-bootstrap-421 .small,.factory-bootstrap-421 small{font-size:85%}.factory-bootstrap-421 cite{font-style:normal}.factory-bootstrap-421 .text-muted{color:#999}.factory-bootstrap-421 .text-primary{color:#428bca}.factory-bootstrap-421 .text-primary:hover{color:#3071a9}.factory-bootstrap-421 .text-warning{color:#8a6d3b}.factory-bootstrap-421 .text-warning:hover{color:#66512c}.factory-bootstrap-421 .text-danger{color:#a94442}.factory-bootstrap-421 .text-danger:hover{color:#843534}.factory-bootstrap-421 .text-success{color:#3c763d}.factory-bootstrap-421 .text-success:hover{color:#2b542c}.factory-bootstrap-421 .text-info{color:#31708f}.factory-bootstrap-421 .text-info:hover{color:#245269}.factory-bootstrap-421 .text-left{text-align:left}.factory-bootstrap-421 .text-right{text-align:right}.factory-bootstrap-421 .text-center{text-align:center}.factory-bootstrap-421 .page-header{padding-bottom:9px;margin:40px 0 20px;border-bottom:1px solid #eee}.factory-bootstrap-421 ol,.factory-bootstrap-421 ul{margin-top:0;margin-bottom:10px}.factory-bootstrap-421 ol ol,.factory-bootstrap-421 ol ul,.factory-bootstrap-421 ul ol,.factory-bootstrap-421 ul ul{margin-bottom:0}.factory-bootstrap-421 .list-inline,.factory-bootstrap-421 .list-unstyled{padding-left:0;list-style:none}.factory-bootstrap-421 .list-inline>li{display:inline-block;padding-right:5px;padding-left:5px}.factory-bootstrap-421 .list-inline>li:first-child{padding-left:0}.factory-bootstrap-421 dl{margin-top:0;margin-bottom:20px}.factory-bootstrap-421 dd,.factory-bootstrap-421 dt{line-height:1.428571429}.factory-bootstrap-421 dt{font-weight:700}.factory-bootstrap-421 dd{margin-left:0}@media (min-width:768px){.dl-horizontal dt{float:left;width:160px;overflow:hidden;clear:left;text-align:right;text-overflow:ellipsis;white-space:nowrap}.dl-horizontal dd{margin-left:180px}.dl-horizontal dd:after,.dl-horizontal dd:before{display:table;content:" "}.dl-horizontal dd:after{clear:both}}.factory-bootstrap-421 abbr[data-original-title],.factory-bootstrap-421 abbr[title]{cursor:help;border-bottom:1px dotted #999}.factory-bootstrap-421 .initialism{font-size:90%;text-transform:uppercase}.factory-bootstrap-421 blockquote{padding:10px 20px;margin:0 0 20px;border-left:5px solid #eee}.factory-bootstrap-421 blockquote p{font-size:17.5px;font-weight:300;line-height:1.25}.factory-bootstrap-421 blockquote p:last-child{margin-bottom:0}.factory-bootstrap-421 blockquote .small,.factory-bootstrap-421 blockquote small{display:block;line-height:1.428571429;color:#999}.factory-bootstrap-421 blockquote .small:before,.factory-bootstrap-421 blockquote small:before{content:'\2014 \00A0'}.factory-bootstrap-421 blockquote.pull-right{padding-right:15px;padding-left:0;border-right:5px solid #eee;border-left:0}.factory-bootstrap-421 blockquote.pull-right .small,.factory-bootstrap-421 blockquote.pull-right p,.factory-bootstrap-421 blockquote.pull-right small{text-align:right}.factory-bootstrap-421 blockquote.pull-right .small:before,.factory-bootstrap-421 blockquote.pull-right small:before{content:''}.factory-bootstrap-421 blockquote.pull-right .small:after,.factory-bootstrap-421 blockquote.pull-right small:after{content:'\00A0 \2014'}.factory-bootstrap-421 blockquote:after,.factory-bootstrap-421 blockquote:before{content:""}.factory-bootstrap-421 address{margin-bottom:20px;font-style:normal;line-height:1.428571429}.factory-bootstrap-421 code,.factory-bootstrap-421 kbd,.factory-bootstrap-421 pre,.factory-bootstrap-421 samp{font-family:Menlo,Monaco,Consolas,"Courier New",monospace}.factory-bootstrap-421 code{padding:2px 4px;font-size:90%;color:#c7254e;white-space:nowrap;background-color:#f9f2f4;border-radius:4px}.factory-bootstrap-421 pre{display:block;padding:9.5px;margin:0 0 10px;font-size:13px;line-height:1.428571429;color:#333;word-break:break-all;word-wrap:break-word;background-color:#f5f5f5;border:1px solid #ccc;border-radius:4px}.factory-bootstrap-421 pre code{padding:0;font-size:inherit;color:inherit;white-space:pre-wrap;background-color:transparent;border-radius:0}.factory-bootstrap-421 .pre-scrollable{max-height:340px;overflow-y:scroll}.factory-bootstrap-421 .container{padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}.factory-bootstrap-421 .container:after,.factory-bootstrap-421 .container:before{display:table;content:" "}.factory-bootstrap-421 .container:after{clear:both}@media (min-width:768px){.container{width:750px}}@media (min-width:992px){.container{width:970px}}@media (min-width:1200px){.container{width:1170px}}.factory-bootstrap-421 .row{margin-right:-15px;margin-left:-15px}.factory-bootstrap-421 .row:after,.factory-bootstrap-421 .row:before{display:table;content:" "}.factory-bootstrap-421 .row:after{clear:both}.factory-bootstrap-421 .col-lg-1,.factory-bootstrap-421 .col-lg-10,.factory-bootstrap-421 .col-lg-11,.factory-bootstrap-421 .col-lg-12,.factory-bootstrap-421 .col-lg-2,.factory-bootstrap-421 .col-lg-3,.factory-bootstrap-421 .col-lg-4,.factory-bootstrap-421 .col-lg-5,.factory-bootstrap-421 .col-lg-6,.factory-bootstrap-421 .col-lg-7,.factory-bootstrap-421 .col-lg-8,.factory-bootstrap-421 .col-lg-9,.factory-bootstrap-421 .col-md-1,.factory-bootstrap-421 .col-md-10,.factory-bootstrap-421 .col-md-11,.factory-bootstrap-421 .col-md-12,.factory-bootstrap-421 .col-md-2,.factory-bootstrap-421 .col-md-3,.factory-bootstrap-421 .col-md-4,.factory-bootstrap-421 .col-md-5,.factory-bootstrap-421 .col-md-6,.factory-bootstrap-421 .col-md-7,.factory-bootstrap-421 .col-md-8,.factory-bootstrap-421 .col-md-9,.factory-bootstrap-421 .col-sm-1,.factory-bootstrap-421 .col-sm-10,.factory-bootstrap-421 .col-sm-11,.factory-bootstrap-421 .col-sm-12,.factory-bootstrap-421 .col-sm-2,.factory-bootstrap-421 .col-sm-3,.factory-bootstrap-421 .col-sm-4,.factory-bootstrap-421 .col-sm-5,.factory-bootstrap-421 .col-sm-6,.factory-bootstrap-421 .col-sm-7,.factory-bootstrap-421 .col-sm-8,.factory-bootstrap-421 .col-sm-9,.factory-bootstrap-421 .col-xs-1,.factory-bootstrap-421 .col-xs-10,.factory-bootstrap-421 .col-xs-11,.factory-bootstrap-421 .col-xs-12,.factory-bootstrap-421 .col-xs-2,.factory-bootstrap-421 .col-xs-3,.factory-bootstrap-421 .col-xs-4,.factory-bootstrap-421 .col-xs-5,.factory-bootstrap-421 .col-xs-6,.factory-bootstrap-421 .col-xs-7,.factory-bootstrap-421 .col-xs-8,.factory-bootstrap-421 .col-xs-9{position:relative;min-height:1px;padding-right:15px;padding-left:15px}.factory-bootstrap-421 .col-xs-1,.factory-bootstrap-421 .col-xs-10,.factory-bootstrap-421 .col-xs-11,.factory-bootstrap-421 .col-xs-12,.factory-bootstrap-421 .col-xs-2,.factory-bootstrap-421 .col-xs-3,.factory-bootstrap-421 .col-xs-4,.factory-bootstrap-421 .col-xs-5,.factory-bootstrap-421 .col-xs-6,.factory-bootstrap-421 .col-xs-7,.factory-bootstrap-421 .col-xs-8,.factory-bootstrap-421 .col-xs-9{float:left}.factory-bootstrap-421 .col-xs-12{width:100%}.factory-bootstrap-421 .col-xs-11{width:91.66666666666666%}.factory-bootstrap-421 .col-xs-10{width:83.33333333333334%}.factory-bootstrap-421 .col-xs-9{width:75%}.factory-bootstrap-421 .col-xs-8{width:66.66666666666666%}.factory-bootstrap-421 .col-xs-7{width:58.333333333333336%}.factory-bootstrap-421 .col-xs-6{width:50%}.factory-bootstrap-421 .col-xs-5{width:41.66666666666667%}.factory-bootstrap-421 .col-xs-4{width:33.33333333333333%}.factory-bootstrap-421 .col-xs-3{width:25%}.factory-bootstrap-421 .col-xs-2{width:16.666666666666664%}.factory-bootstrap-421 .col-xs-1{width:8.333333333333332%}.factory-bootstrap-421 .col-xs-pull-12{right:100%}.factory-bootstrap-421 .col-xs-pull-11{right:91.66666666666666%}.factory-bootstrap-421 .col-xs-pull-10{right:83.33333333333334%}.factory-bootstrap-421 .col-xs-pull-9{right:75%}.factory-bootstrap-421 .col-xs-pull-8{right:66.66666666666666%}.factory-bootstrap-421 .col-xs-pull-7{right:58.333333333333336%}.factory-bootstrap-421 .col-xs-pull-6{right:50%}.factory-bootstrap-421 .col-xs-pull-5{right:41.66666666666667%}.factory-bootstrap-421 .col-xs-pull-4{right:33.33333333333333%}.factory-bootstrap-421 .col-xs-pull-3{right:25%}.factory-bootstrap-421 .col-xs-pull-2{right:16.666666666666664%}.factory-bootstrap-421 .col-xs-pull-1{right:8.333333333333332%}.factory-bootstrap-421 .col-xs-pull-0{right:0}.factory-bootstrap-421 .col-xs-push-12{left:100%}.factory-bootstrap-421 .col-xs-push-11{left:91.66666666666666%}.factory-bootstrap-421 .col-xs-push-10{left:83.33333333333334%}.factory-bootstrap-421 .col-xs-push-9{left:75%}.factory-bootstrap-421 .col-xs-push-8{left:66.66666666666666%}.factory-bootstrap-421 .col-xs-push-7{left:58.333333333333336%}.factory-bootstrap-421 .col-xs-push-6{left:50%}.factory-bootstrap-421 .col-xs-push-5{left:41.66666666666667%}.factory-bootstrap-421 .col-xs-push-4{left:33.33333333333333%}.factory-bootstrap-421 .col-xs-push-3{left:25%}.factory-bootstrap-421 .col-xs-push-2{left:16.666666666666664%}.factory-bootstrap-421 .col-xs-push-1{left:8.333333333333332%}.factory-bootstrap-421 .col-xs-push-0{left:0}.factory-bootstrap-421 .col-xs-offset-12{margin-left:100%}.factory-bootstrap-421 .col-xs-offset-11{margin-left:91.66666666666666%}.factory-bootstrap-421 .col-xs-offset-10{margin-left:83.33333333333334%}.factory-bootstrap-421 .col-xs-offset-9{margin-left:75%}.factory-bootstrap-421 .col-xs-offset-8{margin-left:66.66666666666666%}.factory-bootstrap-421 .col-xs-offset-7{margin-left:58.333333333333336%}.factory-bootstrap-421 .col-xs-offset-6{margin-left:50%}.factory-bootstrap-421 .col-xs-offset-5{margin-left:41.66666666666667%}.factory-bootstrap-421 .col-xs-offset-4{margin-left:33.33333333333333%}.factory-bootstrap-421 .col-xs-offset-3{margin-left:25%}.factory-bootstrap-421 .col-xs-offset-2{margin-left:16.666666666666664%}.factory-bootstrap-421 .col-xs-offset-1{margin-left:8.333333333333332%}.factory-bootstrap-421 .col-xs-offset-0{margin-left:0}@media (min-width:768px){.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9{float:left}.col-sm-12{width:100%}.col-sm-11{width:91.66666666666666%}.col-sm-10{width:83.33333333333334%}.col-sm-9{width:75%}.col-sm-8{width:66.66666666666666%}.col-sm-7{width:58.333333333333336%}.col-sm-6{width:50%}.col-sm-5{width:41.66666666666667%}.col-sm-4{width:33.33333333333333%}.col-sm-3{width:25%}.col-sm-2{width:16.666666666666664%}.col-sm-1{width:8.333333333333332%}.col-sm-pull-12{right:100%}.col-sm-pull-11{right:91.66666666666666%}.col-sm-pull-10{right:83.33333333333334%}.col-sm-pull-9{right:75%}.col-sm-pull-8{right:66.66666666666666%}.col-sm-pull-7{right:58.333333333333336%}.col-sm-pull-6{right:50%}.col-sm-pull-5{right:41.66666666666667%}.col-sm-pull-4{right:33.33333333333333%}.col-sm-pull-3{right:25%}.col-sm-pull-2{right:16.666666666666664%}.col-sm-pull-1{right:8.333333333333332%}.col-sm-pull-0{right:0}.col-sm-push-12{left:100%}.col-sm-push-11{left:91.66666666666666%}.col-sm-push-10{left:83.33333333333334%}.col-sm-push-9{left:75%}.col-sm-push-8{left:66.66666666666666%}.col-sm-push-7{left:58.333333333333336%}.col-sm-push-6{left:50%}.col-sm-push-5{left:41.66666666666667%}.col-sm-push-4{left:33.33333333333333%}.col-sm-push-3{left:25%}.col-sm-push-2{left:16.666666666666664%}.col-sm-push-1{left:8.333333333333332%}.col-sm-push-0{left:0}.col-sm-offset-12{margin-left:100%}.col-sm-offset-11{margin-left:91.66666666666666%}.col-sm-offset-10{margin-left:83.33333333333334%}.col-sm-offset-9{margin-left:75%}.col-sm-offset-8{margin-left:66.66666666666666%}.col-sm-offset-7{margin-left:58.333333333333336%}.col-sm-offset-6{margin-left:50%}.col-sm-offset-5{margin-left:41.66666666666667%}.col-sm-offset-4{margin-left:33.33333333333333%}.col-sm-offset-3{margin-left:25%}.col-sm-offset-2{margin-left:16.666666666666664%}.col-sm-offset-1{margin-left:8.333333333333332%}.col-sm-offset-0{margin-left:0}}@media (min-width:992px){.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9{float:left}.col-md-12{width:100%}.col-md-11{width:91.66666666666666%}.col-md-10{width:83.33333333333334%}.col-md-9{width:75%}.col-md-8{width:66.66666666666666%}.col-md-7{width:58.333333333333336%}.col-md-6{width:50%}.col-md-5{width:41.66666666666667%}.col-md-4{width:33.33333333333333%}.col-md-3{width:25%}.col-md-2{width:16.666666666666664%}.col-md-1{width:8.333333333333332%}.col-md-pull-12{right:100%}.col-md-pull-11{right:91.66666666666666%}.col-md-pull-10{right:83.33333333333334%}.col-md-pull-9{right:75%}.col-md-pull-8{right:66.66666666666666%}.col-md-pull-7{right:58.333333333333336%}.col-md-pull-6{right:50%}.col-md-pull-5{right:41.66666666666667%}.col-md-pull-4{right:33.33333333333333%}.col-md-pull-3{right:25%}.col-md-pull-2{right:16.666666666666664%}.col-md-pull-1{right:8.333333333333332%}.col-md-pull-0{right:0}.col-md-push-12{left:100%}.col-md-push-11{left:91.66666666666666%}.col-md-push-10{left:83.33333333333334%}.col-md-push-9{left:75%}.col-md-push-8{left:66.66666666666666%}.col-md-push-7{left:58.333333333333336%}.col-md-push-6{left:50%}.col-md-push-5{left:41.66666666666667%}.col-md-push-4{left:33.33333333333333%}.col-md-push-3{left:25%}.col-md-push-2{left:16.666666666666664%}.col-md-push-1{left:8.333333333333332%}.col-md-push-0{left:0}.col-md-offset-12{margin-left:100%}.col-md-offset-11{margin-left:91.66666666666666%}.col-md-offset-10{margin-left:83.33333333333334%}.col-md-offset-9{margin-left:75%}.col-md-offset-8{margin-left:66.66666666666666%}.col-md-offset-7{margin-left:58.333333333333336%}.col-md-offset-6{margin-left:50%}.col-md-offset-5{margin-left:41.66666666666667%}.col-md-offset-4{margin-left:33.33333333333333%}.col-md-offset-3{margin-left:25%}.col-md-offset-2{margin-left:16.666666666666664%}.col-md-offset-1{margin-left:8.333333333333332%}.col-md-offset-0{margin-left:0}}@media (min-width:1200px){.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9{float:left}.col-lg-12{width:100%}.col-lg-11{width:91.66666666666666%}.col-lg-10{width:83.33333333333334%}.col-lg-9{width:75%}.col-lg-8{width:66.66666666666666%}.col-lg-7{width:58.333333333333336%}.col-lg-6{width:50%}.col-lg-5{width:41.66666666666667%}.col-lg-4{width:33.33333333333333%}.col-lg-3{width:25%}.col-lg-2{width:16.666666666666664%}.col-lg-1{width:8.333333333333332%}.col-lg-pull-12{right:100%}.col-lg-pull-11{right:91.66666666666666%}.col-lg-pull-10{right:83.33333333333334%}.col-lg-pull-9{right:75%}.col-lg-pull-8{right:66.66666666666666%}.col-lg-pull-7{right:58.333333333333336%}.col-lg-pull-6{right:50%}.col-lg-pull-5{right:41.66666666666667%}.col-lg-pull-4{right:33.33333333333333%}.col-lg-pull-3{right:25%}.col-lg-pull-2{right:16.666666666666664%}.col-lg-pull-1{right:8.333333333333332%}.col-lg-pull-0{right:0}.col-lg-push-12{left:100%}.col-lg-push-11{left:91.66666666666666%}.col-lg-push-10{left:83.33333333333334%}.col-lg-push-9{left:75%}.col-lg-push-8{left:66.66666666666666%}.col-lg-push-7{left:58.333333333333336%}.col-lg-push-6{left:50%}.col-lg-push-5{left:41.66666666666667%}.col-lg-push-4{left:33.33333333333333%}.col-lg-push-3{left:25%}.col-lg-push-2{left:16.666666666666664%}.col-lg-push-1{left:8.333333333333332%}.col-lg-push-0{left:0}.col-lg-offset-12{margin-left:100%}.col-lg-offset-11{margin-left:91.66666666666666%}.col-lg-offset-10{margin-left:83.33333333333334%}.col-lg-offset-9{margin-left:75%}.col-lg-offset-8{margin-left:66.66666666666666%}.col-lg-offset-7{margin-left:58.333333333333336%}.col-lg-offset-6{margin-left:50%}.col-lg-offset-5{margin-left:41.66666666666667%}.col-lg-offset-4{margin-left:33.33333333333333%}.col-lg-offset-3{margin-left:25%}.col-lg-offset-2{margin-left:16.666666666666664%}.col-lg-offset-1{margin-left:8.333333333333332%}.col-lg-offset-0{margin-left:0}}.factory-bootstrap-421 table{max-width:100%;background-color:transparent}.factory-bootstrap-421 th{text-align:left}.factory-bootstrap-421 .table{width:100%;margin-bottom:20px}.factory-bootstrap-421 .table>tbody>tr>td,.factory-bootstrap-421 .table>tbody>tr>th,.factory-bootstrap-421 .table>tfoot>tr>td,.factory-bootstrap-421 .table>tfoot>tr>th,.factory-bootstrap-421 .table>thead>tr>td,.factory-bootstrap-421 .table>thead>tr>th{padding:8px;line-height:1.428571429;vertical-align:top;border-top:1px solid #ddd}.factory-bootstrap-421 .table>thead>tr>th{vertical-align:bottom;border-bottom:2px solid #ddd}.factory-bootstrap-421 .table>caption+thead>tr:first-child>td,.factory-bootstrap-421 .table>caption+thead>tr:first-child>th,.factory-bootstrap-421 .table>colgroup+thead>tr:first-child>td,.factory-bootstrap-421 .table>colgroup+thead>tr:first-child>th,.factory-bootstrap-421 .table>thead:first-child>tr:first-child>td,.factory-bootstrap-421 .table>thead:first-child>tr:first-child>th{border-top:0}.factory-bootstrap-421 .table>tbody+tbody{border-top:2px solid #ddd}.factory-bootstrap-421 .table .table{background-color:#fff}.factory-bootstrap-421 .table-condensed>tbody>tr>td,.factory-bootstrap-421 .table-condensed>tbody>tr>th,.factory-bootstrap-421 .table-condensed>tfoot>tr>td,.factory-bootstrap-421 .table-condensed>tfoot>tr>th,.factory-bootstrap-421 .table-condensed>thead>tr>td,.factory-bootstrap-421 .table-condensed>thead>tr>th{padding:5px}.factory-bootstrap-421 .table-bordered,.factory-bootstrap-421 .table-bordered>tbody>tr>td,.factory-bootstrap-421 .table-bordered>tbody>tr>th,.factory-bootstrap-421 .table-bordered>tfoot>tr>td,.factory-bootstrap-421 .table-bordered>tfoot>tr>th,.factory-bootstrap-421 .table-bordered>thead>tr>td,.factory-bootstrap-421 .table-bordered>thead>tr>th{border:1px solid #ddd}.factory-bootstrap-421 .table-bordered>thead>tr>td,.factory-bootstrap-421 .table-bordered>thead>tr>th{border-bottom-width:2px}.factory-bootstrap-421 .table-striped>tbody>tr:nth-child(odd)>td,.factory-bootstrap-421 .table-striped>tbody>tr:nth-child(odd)>th{background-color:#f9f9f9}.factory-bootstrap-421 .table-hover>tbody>tr:hover>td,.factory-bootstrap-421 .table-hover>tbody>tr:hover>th{background-color:#f5f5f5}.factory-bootstrap-421 table col[class*=col-]{position:static;display:table-column;float:none}.factory-bootstrap-421 table td[class*=col-],.factory-bootstrap-421 table th[class*=col-]{display:table-cell;float:none}.factory-bootstrap-421 .table>tbody>.active>td,.factory-bootstrap-421 .table>tbody>.active>th,.factory-bootstrap-421 .table>tbody>tr>.active,.factory-bootstrap-421 .table>tfoot>.active>td,.factory-bootstrap-421 .table>tfoot>.active>th,.factory-bootstrap-421 .table>tfoot>tr>.active,.factory-bootstrap-421 .table>thead>.active>td,.factory-bootstrap-421 .table>thead>.active>th,.factory-bootstrap-421 .table>thead>tr>.active{background-color:#f5f5f5}.factory-bootstrap-421 .table-hover>tbody>.active:hover>td,.factory-bootstrap-421 .table-hover>tbody>.active:hover>th,.factory-bootstrap-421 .table-hover>tbody>tr>.active:hover{background-color:#e8e8e8}.factory-bootstrap-421 .table>tbody>.success>td,.factory-bootstrap-421 .table>tbody>.success>th,.factory-bootstrap-421 .table>tbody>tr>.success,.factory-bootstrap-421 .table>tfoot>.success>td,.factory-bootstrap-421 .table>tfoot>.success>th,.factory-bootstrap-421 .table>tfoot>tr>.success,.factory-bootstrap-421 .table>thead>.success>td,.factory-bootstrap-421 .table>thead>.success>th,.factory-bootstrap-421 .table>thead>tr>.success{background-color:#dff0d8}.factory-bootstrap-421 .table-hover>tbody>.success:hover>td,.factory-bootstrap-421 .table-hover>tbody>.success:hover>th,.factory-bootstrap-421 .table-hover>tbody>tr>.success:hover{background-color:#d0e9c6}.factory-bootstrap-421 .table>tbody>.danger>td,.factory-bootstrap-421 .table>tbody>.danger>th,.factory-bootstrap-421 .table>tbody>tr>.danger,.factory-bootstrap-421 .table>tfoot>.danger>td,.factory-bootstrap-421 .table>tfoot>.danger>th,.factory-bootstrap-421 .table>tfoot>tr>.danger,.factory-bootstrap-421 .table>thead>.danger>td,.factory-bootstrap-421 .table>thead>.danger>th,.factory-bootstrap-421 .table>thead>tr>.danger{background-color:#f2dede}.factory-bootstrap-421 .table-hover>tbody>.danger:hover>td,.factory-bootstrap-421 .table-hover>tbody>.danger:hover>th,.factory-bootstrap-421 .table-hover>tbody>tr>.danger:hover{background-color:#ebcccc}.factory-bootstrap-421 .table>tbody>.warning>td,.factory-bootstrap-421 .table>tbody>.warning>th,.factory-bootstrap-421 .table>tbody>tr>.warning,.factory-bootstrap-421 .table>tfoot>.warning>td,.factory-bootstrap-421 .table>tfoot>.warning>th,.factory-bootstrap-421 .table>tfoot>tr>.warning,.factory-bootstrap-421 .table>thead>.warning>td,.factory-bootstrap-421 .table>thead>.warning>th,.factory-bootstrap-421 .table>thead>tr>.warning{background-color:#fcf8e3}.factory-bootstrap-421 .table-hover>tbody>.warning:hover>td,.factory-bootstrap-421 .table-hover>tbody>.warning:hover>th,.factory-bootstrap-421 .table-hover>tbody>tr>.warning:hover{background-color:#faf2cc}@media (max-width:767px){.table-responsive{width:100%;margin-bottom:15px;overflow-x:scroll;overflow-y:hidden;border:1px solid #ddd;-ms-overflow-style:-ms-autohiding-scrollbar;-webkit-overflow-scrolling:touch}.table-responsive>.table{margin-bottom:0}.table-responsive>.table>tbody>tr>td,.table-responsive>.table>tbody>tr>th,.table-responsive>.table>tfoot>tr>td,.table-responsive>.table>tfoot>tr>th,.table-responsive>.table>thead>tr>td,.table-responsive>.table>thead>tr>th{white-space:nowrap}.table-responsive>.table-bordered{border:0}.table-responsive>.table-bordered>tbody>tr>td:first-child,.table-responsive>.table-bordered>tbody>tr>th:first-child,.table-responsive>.table-bordered>tfoot>tr>td:first-child,.table-responsive>.table-bordered>tfoot>tr>th:first-child,.table-responsive>.table-bordered>thead>tr>td:first-child,.table-responsive>.table-bordered>thead>tr>th:first-child{border-left:0}.table-responsive>.table-bordered>tbody>tr>td:last-child,.table-responsive>.table-bordered>tbody>tr>th:last-child,.table-responsive>.table-bordered>tfoot>tr>td:last-child,.table-responsive>.table-bordered>tfoot>tr>th:last-child,.table-responsive>.table-bordered>thead>tr>td:last-child,.table-responsive>.table-bordered>thead>tr>th:last-child{border-right:0}.table-responsive>.table-bordered>tbody>tr:last-child>td,.table-responsive>.table-bordered>tbody>tr:last-child>th,.table-responsive>.table-bordered>tfoot>tr:last-child>td,.table-responsive>.table-bordered>tfoot>tr:last-child>th{border-bottom:0}}.factory-bootstrap-421 fieldset{padding:0;margin:0;border:0}.factory-bootstrap-421 legend{display:block;width:100%;padding:0;margin-bottom:20px;font-size:21px;line-height:inherit;color:#333;border:0;border-bottom:1px solid #e5e5e5;-moz-box-sizing:content-box;box-sizing:content-box}.factory-bootstrap-421 label{display:inline-block;margin-bottom:5px;font-weight:700}.factory-bootstrap-421 input[type=search]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.factory-bootstrap-421 input[type=checkbox],.factory-bootstrap-421 input[type=radio]{margin:4px 0 0;margin-top:1px \9;line-height:normal}.factory-bootstrap-421 input[type=file]{display:block}.factory-bootstrap-421 select[multiple],.factory-bootstrap-421 select[size]{height:auto}.factory-bootstrap-421 select optgroup{font-family:inherit;font-size:inherit;font-style:inherit}.factory-bootstrap-421 input[type=checkbox]:focus,.factory-bootstrap-421 input[type=file]:focus,.factory-bootstrap-421 input[type=radio]:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.factory-bootstrap-421 input[type=number]::-webkit-inner-spin-button,.factory-bootstrap-421 input[type=number]::-webkit-outer-spin-button{height:auto}.factory-bootstrap-421 output{display:block;padding-top:7px;font-size:14px;line-height:1.428571429;color:#555;vertical-align:middle}.factory-bootstrap-421 .form-control{display:block;width:100%;height:34px;padding:6px 12px;font-size:14px;line-height:1.428571429;color:#555;vertical-align:middle;background-color:#fff;background-image:none;border:1px solid #ccc;border-radius:3px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075);-webkit-transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s;transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s}.factory-bootstrap-421 .form-control:focus{border-color:#66afe9;outline:0;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.factory-bootstrap-421 .form-control:-moz-placeholder{color:#999}.factory-bootstrap-421 .form-control::-moz-placeholder{color:#999;opacity:1}.factory-bootstrap-421 .form-control:-ms-input-placeholder{color:#999}.factory-bootstrap-421 .form-control::-webkit-input-placeholder{color:#999}.factory-bootstrap-421 .form-control[disabled],.factory-bootstrap-421 .form-control[readonly],.factory-bootstrap-421 fieldset[disabled] .form-control{cursor:not-allowed;background-color:#eee}.factory-bootstrap-421 textarea.form-control{height:auto}.factory-bootstrap-421 .form-group{margin-bottom:15px}.factory-bootstrap-421 .checkbox,.factory-bootstrap-421 .radio{display:block;min-height:20px;padding-left:20px;margin-top:10px;margin-bottom:10px;vertical-align:middle}.factory-bootstrap-421 .checkbox label,.factory-bootstrap-421 .radio label{display:inline;margin-bottom:0;font-weight:400;cursor:pointer}.factory-bootstrap-421 .checkbox input[type=checkbox],.factory-bootstrap-421 .checkbox-inline input[type=checkbox],.factory-bootstrap-421 .radio input[type=radio],.factory-bootstrap-421 .radio-inline input[type=radio]{float:left;margin-left:-20px}.factory-bootstrap-421 .checkbox+.checkbox,.factory-bootstrap-421 .radio+.radio{margin-top:-5px}.factory-bootstrap-421 .checkbox-inline,.factory-bootstrap-421 .radio-inline{display:inline-block;padding-left:20px;margin-bottom:0;font-weight:400;vertical-align:middle;cursor:pointer}.factory-bootstrap-421 .checkbox-inline+.checkbox-inline,.factory-bootstrap-421 .radio-inline+.radio-inline{margin-top:0;margin-left:10px}.factory-bootstrap-421 .checkbox-inline[disabled],.factory-bootstrap-421 .checkbox[disabled],.factory-bootstrap-421 .radio-inline[disabled],.factory-bootstrap-421 .radio[disabled],.factory-bootstrap-421 fieldset[disabled] .checkbox,.factory-bootstrap-421 fieldset[disabled] .checkbox-inline,.factory-bootstrap-421 fieldset[disabled] .radio,.factory-bootstrap-421 fieldset[disabled] .radio-inline,.factory-bootstrap-421 fieldset[disabled] input[type=checkbox],.factory-bootstrap-421 fieldset[disabled] input[type=radio],.factory-bootstrap-421 input[type=checkbox][disabled],.factory-bootstrap-421 input[type=radio][disabled]{cursor:not-allowed}.factory-bootstrap-421 .input-sm{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.factory-bootstrap-421 select.input-sm{height:30px;line-height:30px}.factory-bootstrap-421 textarea.input-sm{height:auto}.factory-bootstrap-421 .input-lg{height:46px;padding:10px 16px;font-size:18px;line-height:1.33;border-radius:6px}.factory-bootstrap-421 select.input-lg{height:46px;line-height:46px}.factory-bootstrap-421 textarea.input-lg{height:auto}.factory-bootstrap-421 .has-warning .checkbox,.factory-bootstrap-421 .has-warning .checkbox-inline,.factory-bootstrap-421 .has-warning .control-label,.factory-bootstrap-421 .has-warning .help-block,.factory-bootstrap-421 .has-warning .radio,.factory-bootstrap-421 .has-warning .radio-inline{color:#8a6d3b}.factory-bootstrap-421 .has-warning .form-control{border-color:#8a6d3b;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.factory-bootstrap-421 .has-warning .form-control:focus{border-color:#66512c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b}.factory-bootstrap-421 .has-warning .input-group-addon{color:#8a6d3b;background-color:#fcf8e3;border-color:#8a6d3b}.factory-bootstrap-421 .has-error .checkbox,.factory-bootstrap-421 .has-error .checkbox-inline,.factory-bootstrap-421 .has-error .control-label,.factory-bootstrap-421 .has-error .help-block,.factory-bootstrap-421 .has-error .radio,.factory-bootstrap-421 .has-error .radio-inline{color:#a94442}.factory-bootstrap-421 .controls{display:block}.factory-bootstrap-421 .has-error .form-control{border-color:#a94442;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.factory-bootstrap-421 .has-error .form-control:focus{border-color:#843534;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483}.factory-bootstrap-421 .has-error .input-group-addon{color:#a94442;background-color:#f2dede;border-color:#a94442}.factory-bootstrap-421 .has-success .checkbox,.factory-bootstrap-421 .has-success .checkbox-inline,.factory-bootstrap-421 .has-success .control-label,.factory-bootstrap-421 .has-success .help-block,.factory-bootstrap-421 .has-success .radio,.factory-bootstrap-421 .has-success .radio-inline{color:#3c763d}.factory-bootstrap-421 .has-success .form-control{border-color:#3c763d;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.factory-bootstrap-421 .has-success .form-control:focus{border-color:#2b542c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168}.factory-bootstrap-421 .has-success .input-group-addon{color:#3c763d;background-color:#dff0d8;border-color:#3c763d}.factory-bootstrap-421 .form-control-static{margin-bottom:0}.factory-bootstrap-421 .help-block{display:block;margin-top:5px;margin-bottom:10px;color:#737373;font-weight:400}@media (min-width:768px){.form-inline .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.form-inline .form-control{display:inline-block}.form-inline select.form-control{width:auto}.form-inline .checkbox,.form-inline .radio{display:inline-block;padding-left:0;margin-top:0;margin-bottom:0}.form-inline .checkbox input[type=checkbox],.form-inline .radio input[type=radio]{float:none;margin-left:0}}.factory-bootstrap-421 .form-horizontal .checkbox,.factory-bootstrap-421 .form-horizontal .checkbox-inline,.factory-bootstrap-421 .form-horizontal .control-label,.factory-bootstrap-421 .form-horizontal .radio,.factory-bootstrap-421 .form-horizontal .radio-inline{position:relative;padding-top:7px;margin-top:0;margin-bottom:0}.factory-bootstrap-421 .form-horizontal .control-label{max-width:200px}.factory-bootstrap-421 .form-horizontal .checkbox,.factory-bootstrap-421 .form-horizontal .radio{min-height:27px}.factory-bootstrap-421 .form-horizontal .form-group{margin-right:-15px;margin-left:-15px}.factory-bootstrap-421 .form-horizontal .form-group:after,.factory-bootstrap-421 .form-horizontal .form-group:before{display:table;content:" "}.factory-bootstrap-421 .form-horizontal .form-group:after{clear:both}.factory-bootstrap-421 .form-horizontal .form-control-static{padding-top:7px}@media (min-width:768px){.form-horizontal .control-label{text-align:right}}.factory-bootstrap-421 .btn{display:inline-block;padding:5px 12px;margin-bottom:0;font-size:13px;font-weight:400;line-height:1.428571429;text-align:center;white-space:nowrap;vertical-align:middle;cursor:pointer;background-image:none;border:1px solid transparent;border-radius:3px;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;-o-user-select:none;user-select:none}.factory-bootstrap-421 .btn:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.factory-bootstrap-421 .btn{text-decoration:none}.factory-bootstrap-421 .btn:focus,.factory-bootstrap-421 .btn:hover{color:#333;text-decoration:none}.factory-bootstrap-421 .btn.disabled,.factory-bootstrap-421 .btn[disabled],.factory-bootstrap-421 fieldset[disabled] .btn{pointer-events:none;cursor:not-allowed;opacity:.65;filter:alpha(opacity=65);-webkit-box-shadow:none;box-shadow:none}.factory-bootstrap-421 .btn-default.active,.factory-bootstrap-421 .btn-default:active,.factory-bootstrap-421 .btn-default:focus,.factory-bootstrap-421 .btn-default:hover,.factory-bootstrap-421 .open .dropdown-toggle.btn-default{background:#fafafa;border-color:#999;color:#222}.factory-bootstrap-421 .btn-default.active,.factory-bootstrap-421 .btn-default:active,.factory-bootstrap-421 .open .dropdown-toggle.btn-default{background-image:none}.factory-bootstrap-421 .btn-default.disabled,.factory-bootstrap-421 .btn-default.disabled.active,.factory-bootstrap-421 .btn-default.disabled:active,.factory-bootstrap-421 .btn-default.disabled:focus,.factory-bootstrap-421 .btn-default.disabled:hover,.factory-bootstrap-421 .btn-default[disabled],.factory-bootstrap-421 .btn-default[disabled].active,.factory-bootstrap-421 .btn-default[disabled]:active,.factory-bootstrap-421 .btn-default[disabled]:focus,.factory-bootstrap-421 .btn-default[disabled]:hover,.factory-bootstrap-421 fieldset[disabled] .btn-default,.factory-bootstrap-421 fieldset[disabled] .btn-default.active,.factory-bootstrap-421 fieldset[disabled] .btn-default:active,.factory-bootstrap-421 fieldset[disabled] .btn-default:focus,.factory-bootstrap-421 fieldset[disabled] .btn-default:hover{background-color:#fff;border-color:#ccc}.factory-bootstrap-421 .btn-default .badge{color:#fff;background-color:#fff}.factory-bootstrap-421 .btn-primary.active,.factory-bootstrap-421 .btn-primary:active,.factory-bootstrap-421 .btn-primary:focus,.factory-bootstrap-421 .btn-primary:hover,.factory-bootstrap-421 .open .dropdown-toggle.btn-primary{color:#fff;background-color:#3276b1;border-color:#285e8e}.factory-bootstrap-421 .btn-primary.active,.factory-bootstrap-421 .btn-primary:active,.factory-bootstrap-421 .open .dropdown-toggle.btn-primary{background-image:none}.factory-bootstrap-421 .btn-primary.disabled,.factory-bootstrap-421 .btn-primary.disabled.active,.factory-bootstrap-421 .btn-primary.disabled:active,.factory-bootstrap-421 .btn-primary.disabled:focus,.factory-bootstrap-421 .btn-primary.disabled:hover,.factory-bootstrap-421 .btn-primary[disabled],.factory-bootstrap-421 .btn-primary[disabled].active,.factory-bootstrap-421 .btn-primary[disabled]:active,.factory-bootstrap-421 .btn-primary[disabled]:focus,.factory-bootstrap-421 .btn-primary[disabled]:hover,.factory-bootstrap-421 fieldset[disabled] .btn-primary,.factory-bootstrap-421 fieldset[disabled] .btn-primary.active,.factory-bootstrap-421 fieldset[disabled] .btn-primary:active,.factory-bootstrap-421 fieldset[disabled] .btn-primary:focus,.factory-bootstrap-421 fieldset[disabled] .btn-primary:hover{background-color:#428bca;border-color:#357ebd}.factory-bootstrap-421 .btn-primary .badge{color:#428bca;background-color:#fff}.factory-bootstrap-421 .btn-warning{color:#fff;background-color:#f0ad4e}.factory-bootstrap-421 .btn-warning.active,.factory-bootstrap-421 .btn-warning:active,.factory-bootstrap-421 .btn-warning:focus,.factory-bootstrap-421 .btn-warning:hover,.factory-bootstrap-421 .open .dropdown-toggle.btn-warning{color:#fff;background-color:#ed9c28;border-color:#d58512}.factory-bootstrap-421 .btn-warning.active,.factory-bootstrap-421 .btn-warning:active,.factory-bootstrap-421 .open .dropdown-toggle.btn-warning{background-image:none}.factory-bootstrap-421 .btn-warning.disabled,.factory-bootstrap-421 .btn-warning.disabled.active,.factory-bootstrap-421 .btn-warning.disabled:active,.factory-bootstrap-421 .btn-warning.disabled:focus,.factory-bootstrap-421 .btn-warning.disabled:hover,.factory-bootstrap-421 .btn-warning[disabled],.factory-bootstrap-421 .btn-warning[disabled].active,.factory-bootstrap-421 .btn-warning[disabled]:active,.factory-bootstrap-421 .btn-warning[disabled]:focus,.factory-bootstrap-421 .btn-warning[disabled]:hover,.factory-bootstrap-421 fieldset[disabled] .btn-warning,.factory-bootstrap-421 fieldset[disabled] .btn-warning.active,.factory-bootstrap-421 fieldset[disabled] .btn-warning:active,.factory-bootstrap-421 fieldset[disabled] .btn-warning:focus,.factory-bootstrap-421 fieldset[disabled] .btn-warning:hover{background-color:#f0ad4e;border-color:#eea236}.factory-bootstrap-421 .btn-warning .badge{color:#f0ad4e;background-color:#fff}.factory-bootstrap-421 .btn-success{color:#fff;background-color:#5cb85c}.factory-bootstrap-421 .btn-success.active,.factory-bootstrap-421 .btn-success:active,.factory-bootstrap-421 .btn-success:focus,.factory-bootstrap-421 .btn-success:hover,.factory-bootstrap-421 .open .dropdown-toggle.btn-success{color:#fff;background-color:#47a447;border-color:#398439}.factory-bootstrap-421 .btn-success.active,.factory-bootstrap-421 .btn-success:active,.factory-bootstrap-421 .open .dropdown-toggle.btn-success{background-image:none}.factory-bootstrap-421 .btn-success.disabled,.factory-bootstrap-421 .btn-success.disabled.active,.factory-bootstrap-421 .btn-success.disabled:active,.factory-bootstrap-421 .btn-success.disabled:focus,.factory-bootstrap-421 .btn-success.disabled:hover,.factory-bootstrap-421 .btn-success[disabled],.factory-bootstrap-421 .btn-success[disabled].active,.factory-bootstrap-421 .btn-success[disabled]:active,.factory-bootstrap-421 .btn-success[disabled]:focus,.factory-bootstrap-421 .btn-success[disabled]:hover,.factory-bootstrap-421 fieldset[disabled] .btn-success,.factory-bootstrap-421 fieldset[disabled] .btn-success.active,.factory-bootstrap-421 fieldset[disabled] .btn-success:active,.factory-bootstrap-421 fieldset[disabled] .btn-success:focus,.factory-bootstrap-421 fieldset[disabled] .btn-success:hover{background-color:#5cb85c;border-color:#4cae4c}.factory-bootstrap-421 .btn-success .badge{color:#5cb85c;background-color:#fff}.factory-bootstrap-421 .btn-info{color:#fff;background-color:#5bc0de}.factory-bootstrap-421 .btn-info.active,.factory-bootstrap-421 .btn-info:active,.factory-bootstrap-421 .btn-info:focus,.factory-bootstrap-421 .btn-info:hover,.factory-bootstrap-421 .open .dropdown-toggle.btn-info{color:#fff;background-color:#39b3d7;border-color:#269abc}.factory-bootstrap-421 .btn-info.active,.factory-bootstrap-421 .btn-info:active,.factory-bootstrap-421 .open .dropdown-toggle.btn-info{background-image:none}.factory-bootstrap-421 .btn-info.disabled,.factory-bootstrap-421 .btn-info.disabled.active,.factory-bootstrap-421 .btn-info.disabled:active,.factory-bootstrap-421 .btn-info.disabled:focus,.factory-bootstrap-421 .btn-info.disabled:hover,.factory-bootstrap-421 .btn-info[disabled],.factory-bootstrap-421 .btn-info[disabled].active,.factory-bootstrap-421 .btn-info[disabled]:active,.factory-bootstrap-421 .btn-info[disabled]:focus,.factory-bootstrap-421 .btn-info[disabled]:hover,.factory-bootstrap-421 fieldset[disabled] .btn-info,.factory-bootstrap-421 fieldset[disabled] .btn-info.active,.factory-bootstrap-421 fieldset[disabled] .btn-info:active,.factory-bootstrap-421 fieldset[disabled] .btn-info:focus,.factory-bootstrap-421 fieldset[disabled] .btn-info:hover{background-color:#5bc0de;border-color:#46b8da}.factory-bootstrap-421 .btn-info .badge{color:#5bc0de;background-color:#fff}.factory-bootstrap-421 .btn-link{font-weight:400;color:#428bca;cursor:pointer;border-radius:0}.factory-bootstrap-421 .btn-link,.factory-bootstrap-421 .btn-link:active,.factory-bootstrap-421 .btn-link[disabled],.factory-bootstrap-421 fieldset[disabled] .btn-link{background-color:transparent;-webkit-box-shadow:none;box-shadow:none}.factory-bootstrap-421 .btn-link,.factory-bootstrap-421 .btn-link:active,.factory-bootstrap-421 .btn-link:focus,.factory-bootstrap-421 .btn-link:hover{border-color:transparent}.factory-bootstrap-421 .btn-link:focus,.factory-bootstrap-421 .btn-link:hover{color:#2a6496;text-decoration:underline;background-color:transparent}.factory-bootstrap-421 .btn-link[disabled]:focus,.factory-bootstrap-421 .btn-link[disabled]:hover,.factory-bootstrap-421 fieldset[disabled] .btn-link:focus,.factory-bootstrap-421 fieldset[disabled] .btn-link:hover{color:#999;text-decoration:none}.factory-bootstrap-421 .btn-lg{padding:10px 16px;font-size:18px;line-height:1.33;border-radius:6px}.factory-bootstrap-421 .btn-sm{padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.factory-bootstrap-421 .btn-xs{padding:1px 5px;font-size:12px;line-height:1.5;border-radius:3px}.factory-bootstrap-421 .btn-block{display:block;width:100%;padding-right:0;padding-left:0}.factory-bootstrap-421 .btn-block+.btn-block{margin-top:5px}.factory-bootstrap-421 input[type=button].btn-block,.factory-bootstrap-421 input[type=reset].btn-block,.factory-bootstrap-421 input[type=submit].btn-block{width:100%}.factory-bootstrap-421 .fade{opacity:0;-webkit-transition:opacity .15s linear;transition:opacity .15s linear}.factory-bootstrap-421 .fade.in{opacity:1}.factory-bootstrap-421 .collapse{display:none}.factory-bootstrap-421 .collapse.in{display:block}.factory-bootstrap-421 .collapsing{position:relative;height:0;overflow:hidden;-webkit-transition:height .35s ease;transition:height .35s ease}@font-face{font-family:'Glyphicons Halflings';src:url(../fonts/glyphicons-halflings-regular.eot);src:url(../fonts/glyphicons-halflings-regular.eot?#iefix) format('embedded-opentype'),url(../fonts/glyphicons-halflings-regular.woff) format('woff'),url(../fonts/glyphicons-halflings-regular.ttf) format('truetype'),url(../fonts/glyphicons-halflings-regular.svg#glyphicons-halflingsregular) format('svg')}.factory-bootstrap-421 .glyphicon{position:relative;top:1px;display:inline-block;font-family:'Glyphicons Halflings';-webkit-font-smoothing:antialiased;font-style:normal;font-weight:400;line-height:1;-moz-osx-font-smoothing:grayscale}.factory-bootstrap-421 .glyphicon:empty{width:1em}.factory-bootstrap-421 .glyphicon-asterisk:before{content:"\2a"}.factory-bootstrap-421 .glyphicon-plus:before{content:"\2b"}.factory-bootstrap-421 .glyphicon-euro:before{content:"\20ac"}.factory-bootstrap-421 .glyphicon-minus:before{content:"\2212"}.factory-bootstrap-421 .glyphicon-cloud:before{content:"\2601"}.factory-bootstrap-421 .glyphicon-envelope:before{content:"\2709"}.factory-bootstrap-421 .glyphicon-pencil:before{content:"\270f"}.factory-bootstrap-421 .glyphicon-glass:before{content:"\e001"}.factory-bootstrap-421 .glyphicon-music:before{content:"\e002"}.factory-bootstrap-421 .glyphicon-search:before{content:"\e003"}.factory-bootstrap-421 .glyphicon-heart:before{content:"\e005"}.factory-bootstrap-421 .glyphicon-star:before{content:"\e006"}.factory-bootstrap-421 .glyphicon-star-empty:before{content:"\e007"}.factory-bootstrap-421 .glyphicon-user:before{content:"\e008"}.factory-bootstrap-421 .glyphicon-film:before{content:"\e009"}.factory-bootstrap-421 .glyphicon-th-large:before{content:"\e010"}.factory-bootstrap-421 .glyphicon-th:before{content:"\e011"}.factory-bootstrap-421 .glyphicon-th-list:before{content:"\e012"}.factory-bootstrap-421 .glyphicon-ok:before{content:"\e013"}.factory-bootstrap-421 .glyphicon-remove:before{content:"\e014"}.factory-bootstrap-421 .glyphicon-zoom-in:before{content:"\e015"}.factory-bootstrap-421 .glyphicon-zoom-out:before{content:"\e016"}.factory-bootstrap-421 .glyphicon-off:before{content:"\e017"}.factory-bootstrap-421 .glyphicon-signal:before{content:"\e018"}.factory-bootstrap-421 .glyphicon-cog:before{content:"\e019"}.factory-bootstrap-421 .glyphicon-trash:before{content:"\e020"}.factory-bootstrap-421 .glyphicon-home:before{content:"\e021"}.factory-bootstrap-421 .glyphicon-file:before{content:"\e022"}.factory-bootstrap-421 .glyphicon-time:before{content:"\e023"}.factory-bootstrap-421 .glyphicon-road:before{content:"\e024"}.factory-bootstrap-421 .glyphicon-download-alt:before{content:"\e025"}.factory-bootstrap-421 .glyphicon-download:before{content:"\e026"}.factory-bootstrap-421 .glyphicon-upload:before{content:"\e027"}.factory-bootstrap-421 .glyphicon-inbox:before{content:"\e028"}.factory-bootstrap-421 .glyphicon-play-circle:before{content:"\e029"}.factory-bootstrap-421 .glyphicon-repeat:before{content:"\e030"}.factory-bootstrap-421 .glyphicon-refresh:before{content:"\e031"}.factory-bootstrap-421 .glyphicon-list-alt:before{content:"\e032"}.factory-bootstrap-421 .glyphicon-lock:before{content:"\e033"}.factory-bootstrap-421 .glyphicon-flag:before{content:"\e034"}.factory-bootstrap-421 .glyphicon-headphones:before{content:"\e035"}.factory-bootstrap-421 .glyphicon-volume-off:before{content:"\e036"}.factory-bootstrap-421 .glyphicon-volume-down:before{content:"\e037"}.factory-bootstrap-421 .glyphicon-volume-up:before{content:"\e038"}.factory-bootstrap-421 .glyphicon-qrcode:before{content:"\e039"}.factory-bootstrap-421 .glyphicon-barcode:before{content:"\e040"}.factory-bootstrap-421 .glyphicon-tag:before{content:"\e041"}.factory-bootstrap-421 .glyphicon-tags:before{content:"\e042"}.factory-bootstrap-421 .glyphicon-book:before{content:"\e043"}.factory-bootstrap-421 .glyphicon-bookmark:before{content:"\e044"}.factory-bootstrap-421 .glyphicon-print:before{content:"\e045"}.factory-bootstrap-421 .glyphicon-camera:before{content:"\e046"}.factory-bootstrap-421 .glyphicon-font:before{content:"\e047"}.factory-bootstrap-421 .glyphicon-bold:before{content:"\e048"}.factory-bootstrap-421 .glyphicon-italic:before{content:"\e049"}.factory-bootstrap-421 .glyphicon-text-height:before{content:"\e050"}.factory-bootstrap-421 .glyphicon-text-width:before{content:"\e051"}.factory-bootstrap-421 .glyphicon-align-left:before{content:"\e052"}.factory-bootstrap-421 .glyphicon-align-center:before{content:"\e053"}.factory-bootstrap-421 .glyphicon-align-right:before{content:"\e054"}.factory-bootstrap-421 .glyphicon-align-justify:before{content:"\e055"}.factory-bootstrap-421 .glyphicon-list:before{content:"\e056"}.factory-bootstrap-421 .glyphicon-indent-left:before{content:"\e057"}.factory-bootstrap-421 .glyphicon-indent-right:before{content:"\e058"}.factory-bootstrap-421 .glyphicon-facetime-video:before{content:"\e059"}.factory-bootstrap-421 .glyphicon-picture:before{content:"\e060"}.factory-bootstrap-421 .glyphicon-map-marker:before{content:"\e062"}.factory-bootstrap-421 .glyphicon-adjust:before{content:"\e063"}.factory-bootstrap-421 .glyphicon-tint:before{content:"\e064"}.factory-bootstrap-421 .glyphicon-edit:before{content:"\e065"}.factory-bootstrap-421 .glyphicon-share:before{content:"\e066"}.factory-bootstrap-421 .glyphicon-check:before{content:"\e067"}.factory-bootstrap-421 .glyphicon-move:before{content:"\e068"}.factory-bootstrap-421 .glyphicon-step-backward:before{content:"\e069"}.factory-bootstrap-421 .glyphicon-fast-backward:before{content:"\e070"}.factory-bootstrap-421 .glyphicon-backward:before{content:"\e071"}.factory-bootstrap-421 .glyphicon-play:before{content:"\e072"}.factory-bootstrap-421 .glyphicon-pause:before{content:"\e073"}.factory-bootstrap-421 .glyphicon-stop:before{content:"\e074"}.factory-bootstrap-421 .glyphicon-forward:before{content:"\e075"}.factory-bootstrap-421 .glyphicon-fast-forward:before{content:"\e076"}.factory-bootstrap-421 .glyphicon-step-forward:before{content:"\e077"}.factory-bootstrap-421 .glyphicon-eject:before{content:"\e078"}.factory-bootstrap-421 .glyphicon-chevron-left:before{content:"\e079"}.factory-bootstrap-421 .glyphicon-chevron-right:before{content:"\e080"}.factory-bootstrap-421 .glyphicon-plus-sign:before{content:"\e081"}.factory-bootstrap-421 .glyphicon-minus-sign:before{content:"\e082"}.factory-bootstrap-421 .glyphicon-remove-sign:before{content:"\e083"}.factory-bootstrap-421 .glyphicon-ok-sign:before{content:"\e084"}.factory-bootstrap-421 .glyphicon-question-sign:before{content:"\e085"}.factory-bootstrap-421 .glyphicon-info-sign:before{content:"\e086"}.factory-bootstrap-421 .glyphicon-screenshot:before{content:"\e087"}.factory-bootstrap-421 .glyphicon-remove-circle:before{content:"\e088"}.factory-bootstrap-421 .glyphicon-ok-circle:before{content:"\e089"}.factory-bootstrap-421 .glyphicon-ban-circle:before{content:"\e090"}.factory-bootstrap-421 .glyphicon-arrow-left:before{content:"\e091"}.factory-bootstrap-421 .glyphicon-arrow-right:before{content:"\e092"}.factory-bootstrap-421 .glyphicon-arrow-up:before{content:"\e093"}.factory-bootstrap-421 .glyphicon-arrow-down:before{content:"\e094"}.factory-bootstrap-421 .glyphicon-share-alt:before{content:"\e095"}.factory-bootstrap-421 .glyphicon-resize-full:before{content:"\e096"}.factory-bootstrap-421 .glyphicon-resize-small:before{content:"\e097"}.factory-bootstrap-421 .glyphicon-exclamation-sign:before{content:"\e101"}.factory-bootstrap-421 .glyphicon-gift:before{content:"\e102"}.factory-bootstrap-421 .glyphicon-leaf:before{content:"\e103"}.factory-bootstrap-421 .glyphicon-fire:before{content:"\e104"}.factory-bootstrap-421 .glyphicon-eye-open:before{content:"\e105"}.factory-bootstrap-421 .glyphicon-eye-close:before{content:"\e106"}.factory-bootstrap-421 .glyphicon-warning-sign:before{content:"\e107"}.factory-bootstrap-421 .glyphicon-plane:before{content:"\e108"}.factory-bootstrap-421 .glyphicon-calendar:before{content:"\e109"}.factory-bootstrap-421 .glyphicon-random:before{content:"\e110"}.factory-bootstrap-421 .glyphicon-comment:before{content:"\e111"}.factory-bootstrap-421 .glyphicon-magnet:before{content:"\e112"}.factory-bootstrap-421 .glyphicon-chevron-up:before{content:"\e113"}.factory-bootstrap-421 .glyphicon-chevron-down:before{content:"\e114"}.factory-bootstrap-421 .glyphicon-retweet:before{content:"\e115"}.factory-bootstrap-421 .glyphicon-shopping-cart:before{content:"\e116"}.factory-bootstrap-421 .glyphicon-folder-close:before{content:"\e117"}.factory-bootstrap-421 .glyphicon-folder-open:before{content:"\e118"}.factory-bootstrap-421 .glyphicon-resize-vertical:before{content:"\e119"}.factory-bootstrap-421 .glyphicon-resize-horizontal:before{content:"\e120"}.factory-bootstrap-421 .glyphicon-hdd:before{content:"\e121"}.factory-bootstrap-421 .glyphicon-bullhorn:before{content:"\e122"}.factory-bootstrap-421 .glyphicon-bell:before{content:"\e123"}.factory-bootstrap-421 .glyphicon-certificate:before{content:"\e124"}.factory-bootstrap-421 .glyphicon-thumbs-up:before{content:"\e125"}.factory-bootstrap-421 .glyphicon-thumbs-down:before{content:"\e126"}.factory-bootstrap-421 .glyphicon-hand-right:before{content:"\e127"}.factory-bootstrap-421 .glyphicon-hand-left:before{content:"\e128"}.factory-bootstrap-421 .glyphicon-hand-up:before{content:"\e129"}.factory-bootstrap-421 .glyphicon-hand-down:before{content:"\e130"}.factory-bootstrap-421 .glyphicon-circle-arrow-right:before{content:"\e131"}.factory-bootstrap-421 .glyphicon-circle-arrow-left:before{content:"\e132"}.factory-bootstrap-421 .glyphicon-circle-arrow-up:before{content:"\e133"}.factory-bootstrap-421 .glyphicon-circle-arrow-down:before{content:"\e134"}.factory-bootstrap-421 .glyphicon-globe:before{content:"\e135"}.factory-bootstrap-421 .glyphicon-wrench:before{content:"\e136"}.factory-bootstrap-421 .glyphicon-tasks:before{content:"\e137"}.factory-bootstrap-421 .glyphicon-filter:before{content:"\e138"}.factory-bootstrap-421 .glyphicon-briefcase:before{content:"\e139"}.factory-bootstrap-421 .glyphicon-fullscreen:before{content:"\e140"}.factory-bootstrap-421 .glyphicon-dashboard:before{content:"\e141"}.factory-bootstrap-421 .glyphicon-paperclip:before{content:"\e142"}.factory-bootstrap-421 .glyphicon-heart-empty:before{content:"\e143"}.factory-bootstrap-421 .glyphicon-link:before{content:"\e144"}.factory-bootstrap-421 .glyphicon-phone:before{content:"\e145"}.factory-bootstrap-421 .glyphicon-pushpin:before{content:"\e146"}.factory-bootstrap-421 .glyphicon-usd:before{content:"\e148"}.factory-bootstrap-421 .glyphicon-gbp:before{content:"\e149"}.factory-bootstrap-421 .glyphicon-sort:before{content:"\e150"}.factory-bootstrap-421 .glyphicon-sort-by-alphabet:before{content:"\e151"}.factory-bootstrap-421 .glyphicon-sort-by-alphabet-alt:before{content:"\e152"}.factory-bootstrap-421 .glyphicon-sort-by-order:before{content:"\e153"}.factory-bootstrap-421 .glyphicon-sort-by-order-alt:before{content:"\e154"}.factory-bootstrap-421 .glyphicon-sort-by-attributes:before{content:"\e155"}.factory-bootstrap-421 .glyphicon-sort-by-attributes-alt:before{content:"\e156"}.factory-bootstrap-421 .glyphicon-unchecked:before{content:"\e157"}.factory-bootstrap-421 .glyphicon-expand:before{content:"\e158"}.factory-bootstrap-421 .glyphicon-collapse-down:before{content:"\e159"}.factory-bootstrap-421 .glyphicon-collapse-up:before{content:"\e160"}.factory-bootstrap-421 .glyphicon-log-in:before{content:"\e161"}.factory-bootstrap-421 .glyphicon-flash:before{content:"\e162"}.factory-bootstrap-421 .glyphicon-log-out:before{content:"\e163"}.factory-bootstrap-421 .glyphicon-new-window:before{content:"\e164"}.factory-bootstrap-421 .glyphicon-record:before{content:"\e165"}.factory-bootstrap-421 .glyphicon-save:before{content:"\e166"}.factory-bootstrap-421 .glyphicon-open:before{content:"\e167"}.factory-bootstrap-421 .glyphicon-saved:before{content:"\e168"}.factory-bootstrap-421 .glyphicon-import:before{content:"\e169"}.factory-bootstrap-421 .glyphicon-export:before{content:"\e170"}.factory-bootstrap-421 .glyphicon-send:before{content:"\e171"}.factory-bootstrap-421 .glyphicon-floppy-disk:before{content:"\e172"}.factory-bootstrap-421 .glyphicon-floppy-saved:before{content:"\e173"}.factory-bootstrap-421 .glyphicon-floppy-remove:before{content:"\e174"}.factory-bootstrap-421 .glyphicon-floppy-save:before{content:"\e175"}.factory-bootstrap-421 .glyphicon-floppy-open:before{content:"\e176"}.factory-bootstrap-421 .glyphicon-credit-card:before{content:"\e177"}.factory-bootstrap-421 .glyphicon-transfer:before{content:"\e178"}.factory-bootstrap-421 .glyphicon-cutlery:before{content:"\e179"}.factory-bootstrap-421 .glyphicon-header:before{content:"\e180"}.factory-bootstrap-421 .glyphicon-compressed:before{content:"\e181"}.factory-bootstrap-421 .glyphicon-earphone:before{content:"\e182"}.factory-bootstrap-421 .glyphicon-phone-alt:before{content:"\e183"}.factory-bootstrap-421 .glyphicon-tower:before{content:"\e184"}.factory-bootstrap-421 .glyphicon-stats:before{content:"\e185"}.factory-bootstrap-421 .glyphicon-sd-video:before{content:"\e186"}.factory-bootstrap-421 .glyphicon-hd-video:before{content:"\e187"}.factory-bootstrap-421 .glyphicon-subtitles:before{content:"\e188"}.factory-bootstrap-421 .glyphicon-sound-stereo:before{content:"\e189"}.factory-bootstrap-421 .glyphicon-sound-dolby:before{content:"\e190"}.factory-bootstrap-421 .glyphicon-sound-5-1:before{content:"\e191"}.factory-bootstrap-421 .glyphicon-sound-6-1:before{content:"\e192"}.factory-bootstrap-421 .glyphicon-sound-7-1:before{content:"\e193"}.factory-bootstrap-421 .glyphicon-copyright-mark:before{content:"\e194"}.factory-bootstrap-421 .glyphicon-registration-mark:before{content:"\e195"}.factory-bootstrap-421 .glyphicon-cloud-download:before{content:"\e197"}.factory-bootstrap-421 .glyphicon-cloud-upload:before{content:"\e198"}.factory-bootstrap-421 .glyphicon-tree-conifer:before{content:"\e199"}.factory-bootstrap-421 .glyphicon-tree-deciduous:before{content:"\e200"}.factory-bootstrap-421 .caret{display:inline-block;width:0;height:0;margin-left:2px;vertical-align:middle;border-top:4px solid;border-right:4px solid transparent;border-left:4px solid transparent}.factory-bootstrap-421 .dropdown{position:relative}.factory-bootstrap-421 .dropdown-toggle:focus{outline:0}.factory-bootstrap-421 .dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:160px;padding:5px 0;margin:2px 0 0;font-size:14px;list-style:none;background-color:#fff;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);background-clip:padding-box}.factory-bootstrap-421 .dropdown-menu.pull-right{right:0;left:auto}.factory-bootstrap-421 .dropdown-menu .divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.factory-bootstrap-421 .dropdown-menu>li>a{display:block;padding:3px 20px;clear:both;font-weight:400;line-height:1.428571429;color:#333;white-space:nowrap}.factory-bootstrap-421 .dropdown-menu>li>a:focus,.factory-bootstrap-421 .dropdown-menu>li>a:hover{color:#262626;text-decoration:none}.factory-bootstrap-421 .dropdown-menu>.active>a,.factory-bootstrap-421 .dropdown-menu>.active>a:focus,.factory-bootstrap-421 .dropdown-menu>.active>a:hover{color:#fff;text-decoration:none;outline:0}.factory-bootstrap-421 .dropdown-menu>.disabled>a,.factory-bootstrap-421 .dropdown-menu>.disabled>a:focus,.factory-bootstrap-421 .dropdown-menu>.disabled>a:hover{color:#999}.factory-bootstrap-421 .dropdown-menu>.disabled>a:focus,.factory-bootstrap-421 .dropdown-menu>.disabled>a:hover{text-decoration:none;cursor:not-allowed;background-color:transparent;background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.factory-bootstrap-421 .open>.dropdown-menu{display:block}.factory-bootstrap-421 .open>a{outline:0}.factory-bootstrap-421 .dropdown-header{display:block;padding:3px 20px;font-size:12px;line-height:1.428571429;color:#999}.factory-bootstrap-421 .dropdown-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:990}.factory-bootstrap-421 .pull-right>.dropdown-menu{right:0;left:auto}.factory-bootstrap-421 .dropup .caret,.factory-bootstrap-421 .navbar-fixed-bottom .dropdown .caret{border-top:0;border-bottom:4px solid;content:""}.factory-bootstrap-421 .dropup .dropdown-menu,.factory-bootstrap-421 .navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:1px}@media (min-width:768px){.navbar-right .dropdown-menu{right:0;left:auto}}.factory-bootstrap-421 .btn-group,.factory-bootstrap-421 .btn-group-vertical{position:relative;display:inline-block;vertical-align:middle}.factory-bootstrap-421 .btn-group-vertical>.btn,.factory-bootstrap-421 .btn-group>.btn{position:relative;float:left}.factory-bootstrap-421 .btn-group-vertical>.btn.active,.factory-bootstrap-421 .btn-group-vertical>.btn:active,.factory-bootstrap-421 .btn-group-vertical>.btn:focus,.factory-bootstrap-421 .btn-group-vertical>.btn:hover,.factory-bootstrap-421 .btn-group>.btn.active,.factory-bootstrap-421 .btn-group>.btn:active,.factory-bootstrap-421 .btn-group>.btn:focus,.factory-bootstrap-421 .btn-group>.btn:hover{z-index:2}.factory-bootstrap-421 .btn-group-vertical>.btn:focus,.factory-bootstrap-421 .btn-group>.btn:focus{outline:0}.factory-bootstrap-421 .btn-group .btn+.btn,.factory-bootstrap-421 .btn-group .btn+.btn-group,.factory-bootstrap-421 .btn-group .btn-group+.btn,.factory-bootstrap-421 .btn-group .btn-group+.btn-group{margin-left:-1px}.factory-bootstrap-421 .btn-toolbar:after,.factory-bootstrap-421 .btn-toolbar:before{display:table;content:" "}.factory-bootstrap-421 .btn-toolbar:after{clear:both}.factory-bootstrap-421 .btn-toolbar .btn-group{float:left}.factory-bootstrap-421 .btn-toolbar>.btn+.btn,.factory-bootstrap-421 .btn-toolbar>.btn+.btn-group,.factory-bootstrap-421 .btn-toolbar>.btn-group+.btn,.factory-bootstrap-421 .btn-toolbar>.btn-group+.btn-group{margin-left:5px}.factory-bootstrap-421 .btn-group>.btn:not(:first-child):not(:last-child):not(.dropdown-toggle){border-radius:0}.factory-bootstrap-421 .btn-group>.btn:first-child{margin-left:0}.factory-bootstrap-421 .btn-group>.btn:first-child:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.factory-bootstrap-421 .btn-group>.btn:last-child:not(:first-child),.factory-bootstrap-421 .btn-group>.dropdown-toggle:not(:first-child){border-bottom-left-radius:0;border-top-left-radius:0}.factory-bootstrap-421 .btn-group>.btn-group{float:left}.factory-bootstrap-421 .btn-group>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.factory-bootstrap-421 .btn-group>.btn-group:first-child>.btn:last-child,.factory-bootstrap-421 .btn-group>.btn-group:first-child>.dropdown-toggle{border-top-right-radius:0;border-bottom-right-radius:0}.factory-bootstrap-421 .btn-group>.btn-group:last-child>.btn:first-child{border-bottom-left-radius:0;border-top-left-radius:0}.factory-bootstrap-421 .btn-group .dropdown-toggle:active,.factory-bootstrap-421 .btn-group.open .dropdown-toggle{outline:0}.factory-bootstrap-421 .btn-group-xs>.btn{padding:1px 5px;font-size:12px;line-height:1.5;border-radius:3px}.factory-bootstrap-421 .btn-group-sm>.btn{padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.factory-bootstrap-421 .btn-group-lg>.btn{padding:10px 16px;font-size:18px;line-height:1.33;border-radius:6px}.factory-bootstrap-421 .btn-group>.btn+.dropdown-toggle{padding-right:8px;padding-left:8px}.factory-bootstrap-421 .btn-group>.btn-lg+.dropdown-toggle{padding-right:12px;padding-left:12px}.factory-bootstrap-421 .btn-group.open .dropdown-toggle{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.factory-bootstrap-421 .btn-group.open .dropdown-toggle.btn-link{-webkit-box-shadow:none;box-shadow:none}.factory-bootstrap-421 .btn-group{border:4px solid #f9f9f9;border-radius:4px}.factory-bootstrap-421 .btn-group .btn.active.value{text-shadow:none;color:#fff;background-color:#33aad5;-webkit-box-shadow:inset 0 1px 1px #0074a2;box-shadow:inset 0 1px 3px #0074a2;border-top:1px solid #0074a2;border-bottom:1px solid #0074a2;border-left:1px solid #0074a2}.factory-bootstrap-421 .btn .caret{margin-left:0}.factory-bootstrap-421 .btn-lg .caret{border-width:5px 5px 0;border-bottom-width:0}.factory-bootstrap-421 .dropup .btn-lg .caret{border-width:0 5px 5px}.factory-bootstrap-421 .btn-group-vertical>.btn,.factory-bootstrap-421 .btn-group-vertical>.btn-group,.factory-bootstrap-421 .btn-group-vertical>.btn-group>.btn{display:block;float:none;width:100%;max-width:100%}.factory-bootstrap-421 .btn-group-vertical>.btn-group:after,.factory-bootstrap-421 .btn-group-vertical>.btn-group:before{display:table;content:" "}.factory-bootstrap-421 .btn-group-vertical>.btn-group:after{clear:both}.factory-bootstrap-421 .btn-group-vertical>.btn-group>.btn{float:none}.factory-bootstrap-421 .btn-group-vertical>.btn+.btn,.factory-bootstrap-421 .btn-group-vertical>.btn+.btn-group,.factory-bootstrap-421 .btn-group-vertical>.btn-group+.btn,.factory-bootstrap-421 .btn-group-vertical>.btn-group+.btn-group{margin-top:-1px;margin-left:0}.factory-bootstrap-421 .btn-group-vertical>.btn:not(:first-child):not(:last-child){border-radius:0}.factory-bootstrap-421 .btn-group-vertical>.btn:first-child:not(:last-child){border-top-right-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0}.factory-bootstrap-421 .btn-group-vertical>.btn:last-child:not(:first-child){border-top-right-radius:0;border-bottom-left-radius:4px;border-top-left-radius:0}.factory-bootstrap-421 .btn-group-vertical>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.factory-bootstrap-421 .btn-group-vertical>.btn-group:first-child>.btn:last-child,.factory-bootstrap-421 .btn-group-vertical>.btn-group:first-child>.dropdown-toggle{border-bottom-right-radius:0;border-bottom-left-radius:0}.factory-bootstrap-421 .btn-group-vertical>.btn-group:last-child>.btn:first-child{border-top-right-radius:0;border-top-left-radius:0}.factory-bootstrap-421 .btn-group-justified{display:table;width:100%;border-collapse:separate;table-layout:fixed}.factory-bootstrap-421 .btn-group-justified>.btn,.factory-bootstrap-421 .btn-group-justified>.btn-group{display:table-cell;float:none;width:1%}.factory-bootstrap-421 .btn-group-justified>.btn-group .btn{width:100%}[data-toggle=buttons]>.btn>input[type=checkbox],[data-toggle=buttons]>.btn>input[type=radio]{display:none}.factory-bootstrap-421 .input-group{position:relative;display:table;border-collapse:separate}.factory-bootstrap-421 .input-group[class*=col-]{float:none;padding-right:0;padding-left:0}.factory-bootstrap-421 .input-group .form-control{width:100%;margin-bottom:0}.factory-bootstrap-421 .input-group-lg>.form-control,.factory-bootstrap-421 .input-group-lg>.input-group-addon,.factory-bootstrap-421 .input-group-lg>.input-group-btn>.btn{height:46px;padding:10px 16px;font-size:18px;line-height:1.33;border-radius:6px}.factory-bootstrap-421 select.input-group-lg>.form-control,.factory-bootstrap-421 select.input-group-lg>.input-group-addon,.factory-bootstrap-421 select.input-group-lg>.input-group-btn>.btn{height:46px;line-height:46px}.factory-bootstrap-421 textarea.input-group-lg>.form-control,.factory-bootstrap-421 textarea.input-group-lg>.input-group-addon,.factory-bootstrap-421 textarea.input-group-lg>.input-group-btn>.btn{height:auto}.factory-bootstrap-421 .input-group-sm>.form-control,.factory-bootstrap-421 .input-group-sm>.input-group-addon,.factory-bootstrap-421 .input-group-sm>.input-group-btn>.btn{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.factory-bootstrap-421 select.input-group-sm>.form-control,.factory-bootstrap-421 select.input-group-sm>.input-group-addon,.factory-bootstrap-421 select.input-group-sm>.input-group-btn>.btn{height:30px;line-height:30px}.factory-bootstrap-421 textarea.input-group-sm>.form-control,.factory-bootstrap-421 textarea.input-group-sm>.input-group-addon,.factory-bootstrap-421 textarea.input-group-sm>.input-group-btn>.btn{height:auto}.factory-bootstrap-421 .input-group .form-control,.factory-bootstrap-421 .input-group-addon,.factory-bootstrap-421 .input-group-btn{display:table-cell}.factory-bootstrap-421 .input-group .form-control:not(:first-child):not(:last-child),.factory-bootstrap-421 .input-group-addon:not(:first-child):not(:last-child),.factory-bootstrap-421 .input-group-btn:not(:first-child):not(:last-child){border-radius:0}.factory-bootstrap-421 .input-group-addon,.factory-bootstrap-421 .input-group-btn{width:1%;white-space:nowrap;vertical-align:middle}.factory-bootstrap-421 .input-group-addon{padding:6px 12px;font-size:14px;font-weight:400;line-height:1;color:#555;text-align:center;background-color:#eee;border:1px solid #ccc;border-radius:4px}.factory-bootstrap-421 .input-group-addon.input-sm{padding:5px 10px;font-size:12px;border-radius:3px}.factory-bootstrap-421 .input-group-addon.input-lg{padding:10px 16px;font-size:18px;border-radius:6px}.factory-bootstrap-421 .input-group-addon input[type=checkbox],.factory-bootstrap-421 .input-group-addon input[type=radio]{margin-top:0}.factory-bootstrap-421 .input-group .form-control:first-child,.factory-bootstrap-421 .input-group-addon:first-child,.factory-bootstrap-421 .input-group-btn:first-child>.btn,.factory-bootstrap-421 .input-group-btn:first-child>.dropdown-toggle,.factory-bootstrap-421 .input-group-btn:last-child>.btn:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.factory-bootstrap-421 .input-group-addon:first-child{border-right:0}.factory-bootstrap-421 .input-group .form-control:last-child,.factory-bootstrap-421 .input-group-addon:last-child,.factory-bootstrap-421 .input-group-btn:first-child>.btn:not(:first-child),.factory-bootstrap-421 .input-group-btn:last-child>.btn,.factory-bootstrap-421 .input-group-btn:last-child>.dropdown-toggle{border-bottom-left-radius:0;border-top-left-radius:0}.factory-bootstrap-421 .input-group-addon:last-child{border-left:0}.factory-bootstrap-421 .input-group-btn{position:relative;white-space:nowrap}.factory-bootstrap-421 .input-group-btn:first-child>.btn{margin-right:-1px}.factory-bootstrap-421 .input-group-btn:last-child>.btn{margin-left:-1px}.factory-bootstrap-421 .input-group-btn>.btn{position:relative}.factory-bootstrap-421 .input-group-btn>.btn+.btn{margin-left:-4px}.factory-bootstrap-421 .input-group-btn>.btn:active,.factory-bootstrap-421 .input-group-btn>.btn:hover{z-index:2}.factory-bootstrap-421 .nav{padding-left:0;margin-bottom:0;list-style:none}.factory-bootstrap-421 .nav:after,.factory-bootstrap-421 .nav:before{display:table;content:" "}.factory-bootstrap-421 .nav:after{clear:both}.factory-bootstrap-421 .nav>li{position:relative;display:block}.factory-bootstrap-421 .nav>li>a{position:relative;display:block;padding:10px 15px}.factory-bootstrap-421 .nav>li>a:focus,.factory-bootstrap-421 .nav>li>a:hover{text-decoration:none;background-color:#eee}.factory-bootstrap-421 .nav>li.disabled>a{color:#999}.factory-bootstrap-421 .nav>li.disabled>a:focus,.factory-bootstrap-421 .nav>li.disabled>a:hover{color:#999;text-decoration:none;cursor:not-allowed;background-color:transparent}.factory-bootstrap-421 .nav .open>a,.factory-bootstrap-421 .nav .open>a:focus,.factory-bootstrap-421 .nav .open>a:hover{background-color:#eee;border-color:#428bca}.factory-bootstrap-421 .nav .nav-divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.factory-bootstrap-421 .nav>li>a>img{max-width:none}.factory-bootstrap-421 .nav-tabs{border-bottom:1px solid #ddd}.factory-bootstrap-421 .nav-tabs>li{float:left;margin-bottom:-1px}.factory-bootstrap-421 .nav-tabs>li>a{margin-right:2px;line-height:1.428571429;border:1px solid transparent;border-radius:4px 4px 0 0}.factory-bootstrap-421 .nav-tabs>li>a:hover{border-color:#eee #eee #ddd}.factory-bootstrap-421 .nav-tabs>li.active>a,.factory-bootstrap-421 .nav-tabs>li.active>a:focus,.factory-bootstrap-421 .nav-tabs>li.active>a:hover{color:#555;cursor:default;background-color:#fff;border:1px solid #ddd;border-bottom-color:transparent}.factory-bootstrap-421 .nav-tabs.nav-justified{width:100%;border-bottom:0}.factory-bootstrap-421 .nav-tabs.nav-justified>li{float:none}.factory-bootstrap-421 .nav-tabs.nav-justified>li>a{margin-bottom:5px;text-align:center}.factory-bootstrap-421 .nav-tabs.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-tabs.nav-justified>li{display:table-cell;width:1%}.nav-tabs.nav-justified>li>a{margin-bottom:0}}.factory-bootstrap-421 .nav-tabs.nav-justified>li>a{margin-right:0;border-radius:4px}.factory-bootstrap-421 .nav-tabs.nav-justified>.active>a,.factory-bootstrap-421 .nav-tabs.nav-justified>.active>a:focus,.factory-bootstrap-421 .nav-tabs.nav-justified>.active>a:hover{border:1px solid #ddd}@media (min-width:768px){.nav-tabs.nav-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:focus,.nav-tabs.nav-justified>.active>a:hover{border-bottom-color:#fff}}.factory-bootstrap-421 .nav-pills>li{float:left}.factory-bootstrap-421 .nav-pills>li>a{border-radius:4px}.factory-bootstrap-421 .nav-pills>li+li{margin-left:2px}.factory-bootstrap-421 .nav-pills>li.active>a,.factory-bootstrap-421 .nav-pills>li.active>a:focus,.factory-bootstrap-421 .nav-pills>li.active>a:hover{color:#fff;background-color:#428bca}.factory-bootstrap-421 .nav-stacked>li{float:none}.factory-bootstrap-421 .nav-stacked>li+li{margin-top:2px;margin-left:0}.factory-bootstrap-421 .nav-justified{width:100%}.factory-bootstrap-421 .nav-justified>li{float:none}.factory-bootstrap-421 .nav-justified>li>a{margin-bottom:5px;text-align:center}.factory-bootstrap-421 .nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-justified>li{display:table-cell;width:1%}.nav-justified>li>a{margin-bottom:0}}.factory-bootstrap-421 .nav-tabs-justified{border-bottom:0}.factory-bootstrap-421 .nav-tabs-justified>li>a{margin-right:0;border-radius:4px}.factory-bootstrap-421 .nav-tabs-justified>.active>a,.factory-bootstrap-421 .nav-tabs-justified>.active>a:focus,.factory-bootstrap-421 .nav-tabs-justified>.active>a:hover{border:1px solid #ddd}@media (min-width:768px){.nav-tabs-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:focus,.nav-tabs-justified>.active>a:hover{border-bottom-color:#fff}}.factory-bootstrap-421 .tab-content>.tab-pane{display:none}.factory-bootstrap-421 .tab-content>.active{display:block}.factory-bootstrap-421 .nav-tabs .dropdown-menu{margin-top:-1px;border-top-right-radius:0;border-top-left-radius:0}.factory-bootstrap-421 .navbar{position:relative;min-height:50px;margin-bottom:20px;border:1px solid transparent}.factory-bootstrap-421 .navbar:after,.factory-bootstrap-421 .navbar:before{display:table;content:" "}.factory-bootstrap-421 .navbar:after{clear:both}@media (min-width:768px){.navbar{border-radius:4px}}.factory-bootstrap-421 .navbar-header:after,.factory-bootstrap-421 .navbar-header:before{display:table;content:" "}.factory-bootstrap-421 .navbar-header:after{clear:both}@media (min-width:768px){.navbar-header{float:left}}.factory-bootstrap-421 .navbar-collapse{max-height:340px;padding-right:15px;padding-left:15px;overflow-x:visible;border-top:1px solid transparent;box-shadow:inset 0 1px 0 rgba(255,255,255,.1);-webkit-overflow-scrolling:touch}.factory-bootstrap-421 .navbar-collapse:after,.factory-bootstrap-421 .navbar-collapse:before{display:table;content:" "}.factory-bootstrap-421 .navbar-collapse:after{clear:both}.factory-bootstrap-421 .navbar-collapse.in{overflow-y:auto}@media (min-width:768px){.navbar-collapse{width:auto;border-top:0;box-shadow:none}.navbar-collapse.collapse{display:block!important;height:auto!important;padding-bottom:0;overflow:visible!important}.navbar-collapse.in{overflow-y:visible}.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse,.navbar-static-top .navbar-collapse{padding-right:0;padding-left:0}}.factory-bootstrap-421 .container>.navbar-collapse,.factory-bootstrap-421 .container>.navbar-header{margin-right:-15px;margin-left:-15px}@media (min-width:768px){.container>.navbar-collapse,.container>.navbar-header{margin-right:0;margin-left:0}}.factory-bootstrap-421 .navbar-static-top{z-index:1000;border-width:0 0 1px}@media (min-width:768px){.navbar-static-top{border-radius:0}}.factory-bootstrap-421 .navbar-fixed-bottom,.factory-bootstrap-421 .navbar-fixed-top{position:fixed;right:0;left:0;z-index:1030}@media (min-width:768px){.navbar-fixed-bottom,.navbar-fixed-top{border-radius:0}}.factory-bootstrap-421 .navbar-fixed-top{top:0;border-width:0 0 1px}.factory-bootstrap-421 .navbar-fixed-bottom{bottom:0;margin-bottom:0;border-width:1px 0 0}.factory-bootstrap-421 .navbar-brand{float:left;padding:15px;font-size:18px;line-height:20px}.factory-bootstrap-421 .navbar-brand:focus,.factory-bootstrap-421 .navbar-brand:hover{text-decoration:none}@media (min-width:768px){.navbar>.container .navbar-brand{margin-left:-15px}}.factory-bootstrap-421 .navbar-toggle{position:relative;float:right;padding:9px 10px;margin-top:8px;margin-right:15px;margin-bottom:8px;background-color:transparent;background-image:none;border:1px solid transparent;border-radius:4px}.factory-bootstrap-421 .navbar-toggle .icon-bar{display:block;width:22px;height:2px;border-radius:1px}.factory-bootstrap-421 .navbar-toggle .icon-bar+.icon-bar{margin-top:4px}@media (min-width:768px){.navbar-toggle{display:none}}.factory-bootstrap-421 .navbar-nav{margin:7.5px -15px}.factory-bootstrap-421 .navbar-nav>li>a{padding-top:10px;padding-bottom:10px;line-height:20px}@media (max-width:767px){.navbar-nav .open .dropdown-menu{position:static;float:none;width:auto;margin-top:0;background-color:transparent;border:0;box-shadow:none}.navbar-nav .open .dropdown-menu .dropdown-header,.navbar-nav .open .dropdown-menu>li>a{padding:5px 15px 5px 25px}.navbar-nav .open .dropdown-menu>li>a{line-height:20px}.navbar-nav .open .dropdown-menu>li>a:focus,.navbar-nav .open .dropdown-menu>li>a:hover{background-image:none}}@media (min-width:768px){.navbar-nav{float:left;margin:0}.navbar-nav>li{float:left}.navbar-nav>li>a{padding-top:15px;padding-bottom:15px}.navbar-nav.navbar-right:last-child{margin-right:-15px}}@media (min-width:768px){.navbar-left{float:left!important}.navbar-right{float:right!important}}.factory-bootstrap-421 .navbar-form{padding:10px 15px;margin-top:8px;margin-right:-15px;margin-bottom:8px;margin-left:-15px;border-top:1px solid transparent;border-bottom:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 1px 0 rgba(255,255,255,.1)}@media (min-width:768px){.navbar-form .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.navbar-form .form-control{display:inline-block}.navbar-form select.form-control{width:auto}.navbar-form .checkbox,.navbar-form .radio{display:inline-block;padding-left:0;margin-top:0;margin-bottom:0}.navbar-form .checkbox input[type=checkbox],.navbar-form .radio input[type=radio]{float:none;margin-left:0}}@media (max-width:767px){.navbar-form .form-group{margin-bottom:5px}}@media (min-width:768px){.navbar-form{width:auto;padding-top:0;padding-bottom:0;margin-right:0;margin-left:0;border:0;-webkit-box-shadow:none;box-shadow:none}.navbar-form.navbar-right:last-child{margin-right:-15px}}.factory-bootstrap-421 .navbar-nav>li>.dropdown-menu{margin-top:0;border-top-right-radius:0;border-top-left-radius:0}.factory-bootstrap-421 .navbar-fixed-bottom .navbar-nav>li>.dropdown-menu{border-bottom-right-radius:0;border-bottom-left-radius:0}.factory-bootstrap-421 .navbar-nav.pull-right>li>.dropdown-menu,.factory-bootstrap-421 .navbar-nav>li>.dropdown-menu.pull-right{right:0;left:auto}.factory-bootstrap-421 .navbar-btn{margin-top:8px;margin-bottom:8px}.factory-bootstrap-421 .navbar-btn.btn-sm{margin-top:10px;margin-bottom:10px}.factory-bootstrap-421 .navbar-btn.btn-xs{margin-top:14px;margin-bottom:14px}.factory-bootstrap-421 .navbar-text{margin-top:15px;margin-bottom:15px}@media (min-width:768px){.navbar-text{float:left;margin-right:15px;margin-left:15px}.navbar-text.navbar-right:last-child{margin-right:0}}.factory-bootstrap-421 .navbar-default{background-color:#f8f8f8;border-color:#e7e7e7}.factory-bootstrap-421 .navbar-default .navbar-brand{color:#777}.factory-bootstrap-421 .navbar-default .navbar-brand:focus,.factory-bootstrap-421 .navbar-default .navbar-brand:hover{color:#5e5e5e;background-color:transparent}.factory-bootstrap-421 .navbar-default .navbar-nav>li>a,.factory-bootstrap-421 .navbar-default .navbar-text{color:#777}.factory-bootstrap-421 .navbar-default .navbar-nav>li>a:focus,.factory-bootstrap-421 .navbar-default .navbar-nav>li>a:hover{color:#333;background-color:transparent}.factory-bootstrap-421 .navbar-default .navbar-nav>.active>a,.factory-bootstrap-421 .navbar-default .navbar-nav>.active>a:focus,.factory-bootstrap-421 .navbar-default .navbar-nav>.active>a:hover{color:#555;background-color:#e7e7e7}.factory-bootstrap-421 .navbar-default .navbar-nav>.disabled>a,.factory-bootstrap-421 .navbar-default .navbar-nav>.disabled>a:focus,.factory-bootstrap-421 .navbar-default .navbar-nav>.disabled>a:hover{color:#ccc;background-color:transparent}.factory-bootstrap-421 .navbar-default .navbar-toggle{border-color:#ddd}.factory-bootstrap-421 .navbar-default .navbar-toggle:focus,.factory-bootstrap-421 .navbar-default .navbar-toggle:hover{background-color:#ddd}.factory-bootstrap-421 .navbar-default .navbar-toggle .icon-bar{background-color:#ccc}.factory-bootstrap-421 .navbar-default .navbar-collapse,.factory-bootstrap-421 .navbar-default .navbar-form{border-color:#e7e7e7}.factory-bootstrap-421 .navbar-default .navbar-nav>.open>a,.factory-bootstrap-421 .navbar-default .navbar-nav>.open>a:focus,.factory-bootstrap-421 .navbar-default .navbar-nav>.open>a:hover{color:#555;background-color:#e7e7e7}@media (max-width:767px){.navbar-default .navbar-nav .open .dropdown-menu>li>a{color:#777}.navbar-default .navbar-nav .open .dropdown-menu>li>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>li>a:hover{color:#333;background-color:transparent}.navbar-default .navbar-nav .open .dropdown-menu>.active>a,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:hover{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:hover{color:#ccc;background-color:transparent}}.factory-bootstrap-421 .navbar-default .navbar-link{color:#777}.factory-bootstrap-421 .navbar-default .navbar-link:hover{color:#333}.factory-bootstrap-421 .navbar-inverse{background-color:#222;border-color:#080808}.factory-bootstrap-421 .navbar-inverse .navbar-brand{color:#999}.factory-bootstrap-421 .navbar-inverse .navbar-brand:focus,.factory-bootstrap-421 .navbar-inverse .navbar-brand:hover{color:#fff;background-color:transparent}.factory-bootstrap-421 .navbar-inverse .navbar-nav>li>a,.factory-bootstrap-421 .navbar-inverse .navbar-text{color:#999}.factory-bootstrap-421 .navbar-inverse .navbar-nav>li>a:focus,.factory-bootstrap-421 .navbar-inverse .navbar-nav>li>a:hover{color:#fff;background-color:transparent}.factory-bootstrap-421 .navbar-inverse .navbar-nav>.active>a,.factory-bootstrap-421 .navbar-inverse .navbar-nav>.active>a:focus,.factory-bootstrap-421 .navbar-inverse .navbar-nav>.active>a:hover{color:#fff;background-color:#080808}.factory-bootstrap-421 .navbar-inverse .navbar-nav>.disabled>a,.factory-bootstrap-421 .navbar-inverse .navbar-nav>.disabled>a:focus,.factory-bootstrap-421 .navbar-inverse .navbar-nav>.disabled>a:hover{color:#444;background-color:transparent}.factory-bootstrap-421 .navbar-inverse .navbar-toggle{border-color:#333}.factory-bootstrap-421 .navbar-inverse .navbar-toggle:focus,.factory-bootstrap-421 .navbar-inverse .navbar-toggle:hover{background-color:#333}.factory-bootstrap-421 .navbar-inverse .navbar-toggle .icon-bar{background-color:#fff}.factory-bootstrap-421 .navbar-inverse .navbar-collapse,.factory-bootstrap-421 .navbar-inverse .navbar-form{border-color:#101010}.factory-bootstrap-421 .navbar-inverse .navbar-nav>.open>a,.factory-bootstrap-421 .navbar-inverse .navbar-nav>.open>a:focus,.factory-bootstrap-421 .navbar-inverse .navbar-nav>.open>a:hover{color:#fff;background-color:#080808}@media (max-width:767px){.navbar-inverse .navbar-nav .open .dropdown-menu>.dropdown-header{border-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu .divider{background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a{color:#999}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:hover{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:hover{color:#444;background-color:transparent}}.factory-bootstrap-421 .navbar-inverse .navbar-link{color:#999}.factory-bootstrap-421 .navbar-inverse .navbar-link:hover{color:#fff}.factory-bootstrap-421 .breadcrumb{padding:8px 15px;margin-bottom:20px;list-style:none;background-color:#f5f5f5;border-radius:4px}.factory-bootstrap-421 .breadcrumb>li{display:inline-block}.factory-bootstrap-421 .breadcrumb>li+li:before{padding:0 5px;color:#ccc;content:"/\00a0"}.factory-bootstrap-421 .breadcrumb>.active{color:#999}.factory-bootstrap-421 .pagination{display:inline-block;padding-left:0;margin:20px 0;border-radius:4px}.factory-bootstrap-421 .pagination>li{display:inline}.factory-bootstrap-421 .pagination>li>a,.factory-bootstrap-421 .pagination>li>span{position:relative;float:left;padding:6px 12px;margin-left:-1px;line-height:1.428571429;text-decoration:none;background-color:#fff;border:1px solid #ddd}.factory-bootstrap-421 .pagination>li:first-child>a,.factory-bootstrap-421 .pagination>li:first-child>span{margin-left:0;border-bottom-left-radius:4px;border-top-left-radius:4px}.factory-bootstrap-421 .pagination>li:last-child>a,.factory-bootstrap-421 .pagination>li:last-child>span{border-top-right-radius:4px;border-bottom-right-radius:4px}.factory-bootstrap-421 .pagination>li>a:focus,.factory-bootstrap-421 .pagination>li>a:hover,.factory-bootstrap-421 .pagination>li>span:focus,.factory-bootstrap-421 .pagination>li>span:hover{background-color:#eee}.factory-bootstrap-421 .pagination>.active>a,.factory-bootstrap-421 .pagination>.active>a:focus,.factory-bootstrap-421 .pagination>.active>a:hover,.factory-bootstrap-421 .pagination>.active>span,.factory-bootstrap-421 .pagination>.active>span:focus,.factory-bootstrap-421 .pagination>.active>span:hover{z-index:2;color:#fff;cursor:default;background-color:#1e8cbe;border-color:#0074a2}.factory-bootstrap-421 .pagination>.disabled>a,.factory-bootstrap-421 .pagination>.disabled>a:focus,.factory-bootstrap-421 .pagination>.disabled>a:hover,.factory-bootstrap-421 .pagination>.disabled>span,.factory-bootstrap-421 .pagination>.disabled>span:focus,.factory-bootstrap-421 .pagination>.disabled>span:hover{color:#999;cursor:not-allowed;background-color:#fff;border-color:#ddd}.factory-bootstrap-421 .pagination-lg>li>a,.factory-bootstrap-421 .pagination-lg>li>span{padding:10px 16px;font-size:18px}.factory-bootstrap-421 .pagination-lg>li:first-child>a,.factory-bootstrap-421 .pagination-lg>li:first-child>span{border-bottom-left-radius:6px;border-top-left-radius:6px}.factory-bootstrap-421 .pagination-lg>li:last-child>a,.factory-bootstrap-421 .pagination-lg>li:last-child>span{border-top-right-radius:6px;border-bottom-right-radius:6px}.factory-bootstrap-421 .pagination-sm>li>a,.factory-bootstrap-421 .pagination-sm>li>span{padding:5px 10px;font-size:12px}.factory-bootstrap-421 .pagination-sm>li:first-child>a,.factory-bootstrap-421 .pagination-sm>li:first-child>span{border-bottom-left-radius:3px;border-top-left-radius:3px}.factory-bootstrap-421 .pagination-sm>li:last-child>a,.factory-bootstrap-421 .pagination-sm>li:last-child>span{border-top-right-radius:3px;border-bottom-right-radius:3px}.factory-bootstrap-421 .pager{padding-left:0;margin:20px 0;text-align:center;list-style:none}.factory-bootstrap-421 .pager:after,.factory-bootstrap-421 .pager:before{display:table;content:" "}.factory-bootstrap-421 .pager:after{clear:both}.factory-bootstrap-421 .pager li{display:inline}.factory-bootstrap-421 .pager li>a,.factory-bootstrap-421 .pager li>span{display:inline-block;padding:5px 14px;background-color:#fff;border:1px solid #ddd;border-radius:15px}.factory-bootstrap-421 .pager li>a:focus,.factory-bootstrap-421 .pager li>a:hover{text-decoration:none;background-color:#eee}.factory-bootstrap-421 .pager .next>a,.factory-bootstrap-421 .pager .next>span{float:right}.factory-bootstrap-421 .pager .previous>a,.factory-bootstrap-421 .pager .previous>span{float:left}.factory-bootstrap-421 .pager .disabled>a,.factory-bootstrap-421 .pager .disabled>a:focus,.factory-bootstrap-421 .pager .disabled>a:hover,.factory-bootstrap-421 .pager .disabled>span{color:#999;cursor:not-allowed;background-color:#fff}.factory-bootstrap-421 .label{display:inline;padding:.2em .6em .3em;font-size:75%;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25em}.factory-bootstrap-421 .label[href]:focus,.factory-bootstrap-421 .label[href]:hover{color:#fff;text-decoration:none;cursor:pointer}.factory-bootstrap-421 .label:empty{display:none}.factory-bootstrap-421 .btn .label{position:relative;top:-1px}.factory-bootstrap-421 .label-default{background-color:#999}.factory-bootstrap-421 .label-default[href]:focus,.factory-bootstrap-421 .label-default[href]:hover{background-color:gray}.factory-bootstrap-421 .label-primary{background-color:#428bca}.factory-bootstrap-421 .label-primary[href]:focus,.factory-bootstrap-421 .label-primary[href]:hover{background-color:#3071a9}.factory-bootstrap-421 .label-success{background-color:#5cb85c}.factory-bootstrap-421 .label-success[href]:focus,.factory-bootstrap-421 .label-success[href]:hover{background-color:#449d44}.factory-bootstrap-421 .label-info{background-color:#5bc0de}.factory-bootstrap-421 .label-info[href]:focus,.factory-bootstrap-421 .label-info[href]:hover{background-color:#31b0d5}.factory-bootstrap-421 .label-warning{background-color:#f0ad4e}.factory-bootstrap-421 .label-warning[href]:focus,.factory-bootstrap-421 .label-warning[href]:hover{background-color:#ec971f}.factory-bootstrap-421 .label-danger{background-color:#d9534f}.factory-bootstrap-421 .label-danger[href]:focus,.factory-bootstrap-421 .label-danger[href]:hover{background-color:#c9302c}.factory-bootstrap-421 .badge{display:inline-block;min-width:10px;padding:3px 7px;font-size:12px;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;background-color:#999;border-radius:10px}.factory-bootstrap-421 .badge:empty{display:none}.factory-bootstrap-421 .btn .badge{position:relative;top:-1px}.factory-bootstrap-421 a.badge:focus,.factory-bootstrap-421 a.badge:hover{color:#fff;text-decoration:none;cursor:pointer}.factory-bootstrap-421 .nav-pills>.active>a>.badge,.factory-bootstrap-421 a.list-group-item.active>.badge{color:#428bca;background-color:#fff}.factory-bootstrap-421 .nav-pills>li>a>.badge{margin-left:3px}.factory-bootstrap-421 .jumbotron{padding:30px;margin-bottom:30px;font-size:21px;font-weight:200;line-height:2.1428571435;color:inherit;background-color:#eee}.factory-bootstrap-421 .jumbotron .h1,.factory-bootstrap-421 .jumbotron h1{line-height:1;color:inherit}.factory-bootstrap-421 .jumbotron p{line-height:1.4}.factory-bootstrap-421 .container .jumbotron{border-radius:6px}.factory-bootstrap-421 .jumbotron .container{max-width:100%}@media screen and (min-width:768px){.jumbotron{padding-top:48px;padding-bottom:48px}.container .jumbotron{padding-right:60px;padding-left:60px}.jumbotron .h1,.jumbotron h1{font-size:63px}}.factory-bootstrap-421 .thumbnail{display:block;padding:4px;margin-bottom:20px;line-height:1.428571429;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.factory-bootstrap-421 .thumbnail a>img,.factory-bootstrap-421 .thumbnail>img{display:block;height:auto;max-width:100%;margin-right:auto;margin-left:auto}.factory-bootstrap-421 a.thumbnail.active,.factory-bootstrap-421 a.thumbnail:focus,.factory-bootstrap-421 a.thumbnail:hover{border-color:#428bca}.factory-bootstrap-421 .thumbnail .caption{padding:9px;color:#333}.factory-bootstrap-421 .alert{border:1px solid transparent;border-radius:4px}.factory-bootstrap-421 .alert h4{margin-top:0;color:inherit}.factory-bootstrap-421 .alert .alert-link{font-weight:700}.factory-bootstrap-421 .alert>p,.factory-bootstrap-421 .alert>ul{margin-bottom:0}.factory-bootstrap-421 .alert>p+p{margin-top:5px}.factory-bootstrap-421 .alert-dismissable{padding-right:35px}.factory-bootstrap-421 .alert-dismissable .close{position:relative;top:-2px;right:-21px;color:inherit}.factory-bootstrap-421 .alert-info{color:#31708f;background-color:#d9edf7}.factory-bootstrap-421 .alert-info hr{border-top-color:#a6e1ec}.factory-bootstrap-421 .alert-info .alert-link{color:#245269}@-webkit-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}.factory-bootstrap-421 .progress{height:20px;margin-bottom:20px;overflow:hidden;background-color:#f5f5f5;border-radius:4px;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,.1);box-shadow:inset 0 1px 2px rgba(0,0,0,.1)}.factory-bootstrap-421 .progress-bar{float:left;width:0;height:100%;font-size:12px;line-height:20px;color:#fff;text-align:center;background-color:#2ea2cc;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);-webkit-transition:width .6s ease;transition:width .6s ease}.factory-bootstrap-421 .progress-striped .progress-bar{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-size:40px 40px}.factory-bootstrap-421 .progress.active .progress-bar{-webkit-animation:progress-bar-stripes 2s linear infinite;animation:progress-bar-stripes 2s linear infinite}.factory-bootstrap-421 .progress-bar-success{background-color:#5cb85c}.factory-bootstrap-421 .progress-striped .progress-bar-success{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.factory-bootstrap-421 .progress-bar-info{background-color:#5bc0de}.factory-bootstrap-421 .progress-striped .progress-bar-info{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.factory-bootstrap-421 .progress-bar-warning{background-color:#f0ad4e}.factory-bootstrap-421 .progress-striped .progress-bar-warning{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.factory-bootstrap-421 .progress-bar-danger{background-color:#d9534f}.factory-bootstrap-421 .progress-striped .progress-bar-danger{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.factory-bootstrap-421 .media,.factory-bootstrap-421 .media-body{overflow:hidden;zoom:1}.factory-bootstrap-421 .media,.factory-bootstrap-421 .media .media{margin-top:15px}.factory-bootstrap-421 .media:first-child{margin-top:0}.factory-bootstrap-421 .media-object{display:block}.factory-bootstrap-421 .media-heading{margin:0 0 5px}.factory-bootstrap-421 .media>.pull-left{margin-right:10px}.factory-bootstrap-421 .media>.pull-right{margin-left:10px}.factory-bootstrap-421 .media-list{padding-left:0;list-style:none}.factory-bootstrap-421 .list-group{padding-left:0;margin-bottom:20px}.factory-bootstrap-421 .list-group-item{position:relative;display:block;padding:10px 15px;margin-bottom:-1px;background-color:#fff;border:1px solid #ddd}.factory-bootstrap-421 .list-group-item:first-child{border-top-right-radius:4px;border-top-left-radius:4px}.factory-bootstrap-421 .list-group-item:last-child{margin-bottom:0;border-bottom-right-radius:4px;border-bottom-left-radius:4px}.factory-bootstrap-421 .list-group-item>.badge{float:right}.factory-bootstrap-421 .list-group-item>.badge+.badge{margin-right:5px}.factory-bootstrap-421 a.list-group-item{color:#555}.factory-bootstrap-421 a.list-group-item .list-group-item-heading{color:#333}.factory-bootstrap-421 a.list-group-item:focus,.factory-bootstrap-421 a.list-group-item:hover{text-decoration:none;background-color:#f5f5f5}.factory-bootstrap-421 a.list-group-item.active,.factory-bootstrap-421 a.list-group-item.active:focus,.factory-bootstrap-421 a.list-group-item.active:hover{z-index:2;color:#fff;background-color:#428bca;border-color:#428bca}.factory-bootstrap-421 a.list-group-item.active .list-group-item-heading,.factory-bootstrap-421 a.list-group-item.active:focus .list-group-item-heading,.factory-bootstrap-421 a.list-group-item.active:hover .list-group-item-heading{color:inherit}.factory-bootstrap-421 a.list-group-item.active .list-group-item-text,.factory-bootstrap-421 a.list-group-item.active:focus .list-group-item-text,.factory-bootstrap-421 a.list-group-item.active:hover .list-group-item-text{color:#e1edf7}.factory-bootstrap-421 .list-group-item-heading{margin-top:0;margin-bottom:5px}.factory-bootstrap-421 .list-group-item-text{margin-bottom:0;line-height:1.3}.factory-bootstrap-421 .panel{margin-bottom:20px;background-color:#fff;border:1px solid transparent;border-radius:4px}.factory-bootstrap-421 .panel-body{padding:15px}.factory-bootstrap-421 .panel-body:after,.factory-bootstrap-421 .panel-body:before{display:table;content:" "}.factory-bootstrap-421 .panel-body:after{clear:both}.factory-bootstrap-421 .panel>.list-group{margin-bottom:0}.factory-bootstrap-421 .panel>.list-group .list-group-item{border-width:1px 0}.factory-bootstrap-421 .panel>.list-group .list-group-item:first-child{border-top-right-radius:0;border-top-left-radius:0}.factory-bootstrap-421 .panel>.list-group .list-group-item:last-child{border-bottom:0}.factory-bootstrap-421 .panel-heading+.list-group .list-group-item:first-child{border-top-width:0}.factory-bootstrap-421 .panel>.table,.factory-bootstrap-421 .panel>.table-responsive>.table{margin-bottom:0}.factory-bootstrap-421 .panel>.panel-body+.table,.factory-bootstrap-421 .panel>.panel-body+.table-responsive{border-top:1px solid #ddd}.factory-bootstrap-421 .panel>.table>tbody:first-child td,.factory-bootstrap-421 .panel>.table>tbody:first-child th{border-top:0}.factory-bootstrap-421 .panel>.table-bordered,.factory-bootstrap-421 .panel>.table-responsive>.table-bordered{border:0}.factory-bootstrap-421 .panel>.table-bordered>tbody>tr>td:first-child,.factory-bootstrap-421 .panel>.table-bordered>tbody>tr>th:first-child,.factory-bootstrap-421 .panel>.table-bordered>tfoot>tr>td:first-child,.factory-bootstrap-421 .panel>.table-bordered>tfoot>tr>th:first-child,.factory-bootstrap-421 .panel>.table-bordered>thead>tr>td:first-child,.factory-bootstrap-421 .panel>.table-bordered>thead>tr>th:first-child,.factory-bootstrap-421 .panel>.table-responsive>.table-bordered>tbody>tr>td:first-child,.factory-bootstrap-421 .panel>.table-responsive>.table-bordered>tbody>tr>th:first-child,.factory-bootstrap-421 .panel>.table-responsive>.table-bordered>tfoot>tr>td:first-child,.factory-bootstrap-421 .panel>.table-responsive>.table-bordered>tfoot>tr>th:first-child,.factory-bootstrap-421 .panel>.table-responsive>.table-bordered>thead>tr>td:first-child,.factory-bootstrap-421 .panel>.table-responsive>.table-bordered>thead>tr>th:first-child{border-left:0}.factory-bootstrap-421 .panel>.table-bordered>tbody>tr>td:last-child,.factory-bootstrap-421 .panel>.table-bordered>tbody>tr>th:last-child,.factory-bootstrap-421 .panel>.table-bordered>tfoot>tr>td:last-child,.factory-bootstrap-421 .panel>.table-bordered>tfoot>tr>th:last-child,.factory-bootstrap-421 .panel>.table-bordered>thead>tr>td:last-child,.factory-bootstrap-421 .panel>.table-bordered>thead>tr>th:last-child,.factory-bootstrap-421 .panel>.table-responsive>.table-bordered>tbody>tr>td:last-child,.factory-bootstrap-421 .panel>.table-responsive>.table-bordered>tbody>tr>th:last-child,.factory-bootstrap-421 .panel>.table-responsive>.table-bordered>tfoot>tr>td:last-child,.factory-bootstrap-421 .panel>.table-responsive>.table-bordered>tfoot>tr>th:last-child,.factory-bootstrap-421 .panel>.table-responsive>.table-bordered>thead>tr>td:last-child,.factory-bootstrap-421 .panel>.table-responsive>.table-bordered>thead>tr>th:last-child{border-right:0}.factory-bootstrap-421 .panel>.table-bordered>tbody>tr:last-child>td,.factory-bootstrap-421 .panel>.table-bordered>tbody>tr:last-child>th,.factory-bootstrap-421 .panel>.table-bordered>tfoot>tr:last-child>td,.factory-bootstrap-421 .panel>.table-bordered>tfoot>tr:last-child>th,.factory-bootstrap-421 .panel>.table-bordered>thead>tr:last-child>td,.factory-bootstrap-421 .panel>.table-bordered>thead>tr:last-child>th,.factory-bootstrap-421 .panel>.table-responsive>.table-bordered>tbody>tr:last-child>td,.factory-bootstrap-421 .panel>.table-responsive>.table-bordered>tbody>tr:last-child>th,.factory-bootstrap-421 .panel>.table-responsive>.table-bordered>tfoot>tr:last-child>td,.factory-bootstrap-421 .panel>.table-responsive>.table-bordered>tfoot>tr:last-child>th,.factory-bootstrap-421 .panel>.table-responsive>.table-bordered>thead>tr:last-child>td,.factory-bootstrap-421 .panel>.table-responsive>.table-bordered>thead>tr:last-child>th{border-bottom:0}.factory-bootstrap-421 .panel>.table-responsive{margin-bottom:0;border:0}.factory-bootstrap-421 .panel-heading{padding:10px 15px;border-bottom:1px solid transparent;border-top-right-radius:3px;border-top-left-radius:3px}.factory-bootstrap-421 .panel-heading>.dropdown .dropdown-toggle{color:inherit}.factory-bootstrap-421 .panel-title{margin-top:0;margin-bottom:0;font-size:16px;color:inherit}.factory-bootstrap-421 .panel-title>a{color:inherit}.factory-bootstrap-421 .panel-footer{padding:10px 15px;background-color:#f5f5f5;border-top:1px solid #ddd;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.factory-bootstrap-421 .panel-group .panel{margin-bottom:0;overflow:hidden;border-radius:4px}.factory-bootstrap-421 .panel-group .panel+.panel{margin-top:5px}.factory-bootstrap-421 .panel-group .panel-heading{border-bottom:0}.factory-bootstrap-421 .panel-group .panel-heading+.panel-collapse .panel-body{border-top:1px solid #ddd}.factory-bootstrap-421 .panel-group .panel-footer{border-top:0}.factory-bootstrap-421 .panel-group .panel-footer+.panel-collapse .panel-body{border-bottom:1px solid #ddd}.factory-bootstrap-421 .panel-default{border-color:#ddd}.factory-bootstrap-421 .panel-default>.panel-heading{color:#333;background-color:#f5f5f5;border-color:#ddd}.factory-bootstrap-421 .panel-default>.panel-heading+.panel-collapse .panel-body{border-top-color:#ddd}.factory-bootstrap-421 .panel-default>.panel-footer+.panel-collapse .panel-body{border-bottom-color:#ddd}.factory-bootstrap-421 .panel-primary{border-color:#428bca}.factory-bootstrap-421 .panel-primary>.panel-heading{color:#fff;background-color:#428bca;border-color:#428bca}.factory-bootstrap-421 .panel-primary>.panel-heading+.panel-collapse .panel-body{border-top-color:#428bca}.factory-bootstrap-421 .panel-primary>.panel-footer+.panel-collapse .panel-body{border-bottom-color:#428bca}.factory-bootstrap-421 .panel-success{border-color:#d6e9c6}.factory-bootstrap-421 .panel-success>.panel-heading{color:#3c763d;background-color:#dff0d8;border-color:#d6e9c6}.factory-bootstrap-421 .panel-success>.panel-heading+.panel-collapse .panel-body{border-top-color:#d6e9c6}.factory-bootstrap-421 .panel-success>.panel-footer+.panel-collapse .panel-body{border-bottom-color:#d6e9c6}.factory-bootstrap-421 .panel-warning{border-color:#faebcc}.factory-bootstrap-421 .panel-warning>.panel-heading{color:#8a6d3b;background-color:#fcf8e3;border-color:#faebcc}.factory-bootstrap-421 .panel-warning>.panel-heading+.panel-collapse .panel-body{border-top-color:#faebcc}.factory-bootstrap-421 .panel-warning>.panel-footer+.panel-collapse .panel-body{border-bottom-color:#faebcc}.factory-bootstrap-421 .panel-danger{border-color:#ebccd1}.factory-bootstrap-421 .panel-danger>.panel-heading{color:#a94442;background-color:#f2dede;border-color:#ebccd1}.factory-bootstrap-421 .panel-danger>.panel-heading+.panel-collapse .panel-body{border-top-color:#ebccd1}.factory-bootstrap-421 .panel-danger>.panel-footer+.panel-collapse .panel-body{border-bottom-color:#ebccd1}.factory-bootstrap-421 .panel-info{border-color:#bce8f1}.factory-bootstrap-421 .panel-info>.panel-heading{color:#31708f;background-color:#d9edf7;border-color:#bce8f1}.factory-bootstrap-421 .panel-info>.panel-heading+.panel-collapse .panel-body{border-top-color:#bce8f1}.factory-bootstrap-421 .panel-info>.panel-footer+.panel-collapse .panel-body{border-bottom-color:#bce8f1}.factory-bootstrap-421 .well{min-height:20px;padding:19px;margin-bottom:20px;background-color:#f5f5f5;border:1px solid #e3e3e3;border-radius:4px}.factory-bootstrap-421 .well blockquote{border-color:#ddd;border-color:rgba(0,0,0,.15)}.factory-bootstrap-421 .well-lg{padding:24px;border-radius:6px}.factory-bootstrap-421 .well-sm{padding:9px;border-radius:3px}.factory-bootstrap-421 .close{float:right;font-size:14px;font-weight:700;line-height:1;color:#000;text-shadow:0 1px 0 #fff;opacity:.3;filter:alpha(opacity=30)}.factory-bootstrap-421 .alert .close{position:relative;top:-8px;right:-7px}.factory-bootstrap-421 .close:focus,.factory-bootstrap-421 .close:hover{color:#000;text-decoration:none;cursor:pointer;opacity:.5;filter:alpha(opacity=50)}.factory-bootstrap-421 button.close{padding:0;cursor:pointer;background:0 0;border:0;-webkit-appearance:none}.factory-bootstrap-421 .modal-open{overflow:hidden}.factory-bootstrap-421 .modal{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;display:none;overflow:auto;overflow-y:scroll;width:auto;margin-left:0;background-color:transparent;border:0}.factory-bootstrap-421 .modal.fade .modal-dialog{-webkit-transform:translate(0,-25%);-ms-transform:translate(0,-25%);transform:translate(0,-25%);-webkit-transition:-webkit-transform .3s ease-out;-moz-transition:-moz-transform .3s ease-out;-o-transition:-o-transform .3s ease-out;transition:transform .3s ease-out}.factory-bootstrap-421 .modal.in .modal-dialog{-webkit-transform:translate(0,0);-ms-transform:translate(0,0);transform:translate(0,0)}.factory-bootstrap-421 .modal-dialog{position:relative;z-index:1050;width:auto;margin:10px}.factory-bootstrap-421 .modal-content{position:relative;background-color:#fff;border:1px solid #999;border:1px solid rgba(0,0,0,.2);border-radius:6px;outline:0;-webkit-box-shadow:0 3px 9px rgba(0,0,0,.5);box-shadow:0 3px 9px rgba(0,0,0,.5);background-clip:padding-box}.factory-bootstrap-421 .modal-backdrop,.factory-bootstrap-421-modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1030;background-color:#000}.factory-bootstrap-421 .modal-backdrop.fade,.factory-bootstrap-421-modal-backdrop.fade{opacity:0;filter:alpha(opacity=0)}.factory-bootstrap-421 .modal-backdrop.in,.factory-bootstrap-421-modal-backdrop.in{opacity:.5;filter:alpha(opacity=50)}.factory-bootstrap-421 .modal-header{min-height:16.428571429px;padding:15px;border-bottom:1px solid #e5e5e5}.factory-bootstrap-421 .modal-header .close{margin-top:-2px}.factory-bootstrap-421 .modal-title{margin:0;line-height:1.428571429}.factory-bootstrap-421 .modal-body{position:relative;padding:20px;max-height:none}.factory-bootstrap-421 .modal-footer{padding:19px 20px 20px;margin-top:15px;text-align:right;border-top:1px solid #e5e5e5}.factory-bootstrap-421 .modal-footer:after,.factory-bootstrap-421 .modal-footer:before{display:table;content:" "}.factory-bootstrap-421 .modal-footer:after{clear:both}.factory-bootstrap-421 .modal-footer .btn+.btn{margin-bottom:0;margin-left:5px}.factory-bootstrap-421 .modal-footer .btn-group .btn+.btn{margin-left:-1px}.factory-bootstrap-421 .modal-footer .btn-block+.btn-block{margin-left:0}@media screen and (min-width:768px){.factory-bootstrap-421 .modal-dialog{width:600px;margin:30px auto}.factory-bootstrap-421 .modal-content{-webkit-box-shadow:0 5px 15px rgba(0,0,0,.5);box-shadow:0 5px 15px rgba(0,0,0,.5)}}.factory-bootstrap-421 .tooltip{position:absolute;z-index:1030;display:block;font-size:12px;line-height:1.4;opacity:0;filter:alpha(opacity=0);visibility:visible}.factory-bootstrap-421 .tooltip.in{opacity:.9;filter:alpha(opacity=90)}.factory-bootstrap-421 .tooltip.top{padding:5px 0;margin-top:-3px}.factory-bootstrap-421 .tooltip.right{padding:0 5px;margin-left:3px}.factory-bootstrap-421 .tooltip.bottom{padding:5px 0;margin-top:3px}.factory-bootstrap-421 .tooltip.left{padding:0 5px;margin-left:-3px}.factory-bootstrap-421 .tooltip-inner{width:400px;padding:15px 20px;color:#fff;text-align:left;text-decoration:none;background-color:#673ab7;border-radius:3px}.factory-bootstrap-421 .tooltip-arrow{position:absolute;width:0;height:0;border-color:transparent;border-style:solid}.factory-bootstrap-421 .tooltip.top .tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-top-color:#673ab7;border-width:5px 5px 0}.factory-bootstrap-421 .tooltip.top-left .tooltip-arrow{bottom:0;left:5px;border-top-color:#673ab7;border-width:5px 5px 0}.factory-bootstrap-421 .tooltip.top-right .tooltip-arrow{right:5px;bottom:0;border-top-color:#673ab7;border-width:5px 5px 0}.factory-bootstrap-421 .tooltip.right .tooltip-arrow{top:50%;left:0;margin-top:-5px;border-right-color:#673ab7;border-width:5px 5px 5px 0}.factory-bootstrap-421 .tooltip.left .tooltip-arrow{top:50%;right:0;margin-top:-5px;border-left-color:#673ab7;border-width:5px 0 5px 5px}.factory-bootstrap-421 .tooltip.bottom .tooltip-arrow{top:0;left:50%;margin-left:-5px;border-bottom-color:#673ab7;border-width:0 5px 5px}.factory-bootstrap-421 .tooltip.bottom-left .tooltip-arrow{top:0;left:5px;border-bottom-color:#673ab7;border-width:0 5px 5px}.factory-bootstrap-421 .tooltip.bottom-right .tooltip-arrow{top:0;right:5px;border-bottom-color:#673ab7;border-width:0 5px 5px}.factory-bootstrap-421 .popover{position:absolute;top:0;left:0;z-index:1010;display:none;max-width:276px;padding:1px;text-align:left;white-space:normal;background-color:#fff;border:1px solid #ccc;border:1px solid rgba(0,0,0,.2);border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,.2);box-shadow:0 5px 10px rgba(0,0,0,.2);background-clip:padding-box}.factory-bootstrap-421 .popover.top{margin-top:-10px}.factory-bootstrap-421 .popover.right{margin-left:10px}.factory-bootstrap-421 .popover.bottom{margin-top:10px}.factory-bootstrap-421 .popover.left{margin-left:-10px}.factory-bootstrap-421 .popover-title{padding:8px 14px;margin:0;font-size:14px;font-weight:400;line-height:18px;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-radius:5px 5px 0 0}.factory-bootstrap-421 .popover-content{padding:9px 14px}.factory-bootstrap-421 .popover .arrow,.factory-bootstrap-421 .popover .arrow:after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.factory-bootstrap-421 .popover .arrow{border-width:11px}.factory-bootstrap-421 .popover .arrow:after{border-width:10px;content:""}.factory-bootstrap-421 .popover.top .arrow{bottom:-11px;left:50%;margin-left:-11px;border-top-color:#999;border-top-color:rgba(0,0,0,.25);border-bottom-width:0}.factory-bootstrap-421 .popover.top .arrow:after{bottom:1px;margin-left:-10px;border-top-color:#fff;border-bottom-width:0;content:" "}.factory-bootstrap-421 .popover.right .arrow{top:50%;left:-11px;margin-top:-11px;border-right-color:#999;border-right-color:rgba(0,0,0,.25);border-left-width:0}.factory-bootstrap-421 .popover.right .arrow:after{bottom:-10px;left:1px;border-right-color:#fff;border-left-width:0;content:" "}.factory-bootstrap-421 .popover.bottom .arrow{top:-11px;left:50%;margin-left:-11px;border-bottom-color:#999;border-bottom-color:rgba(0,0,0,.25);border-top-width:0}.factory-bootstrap-421 .popover.bottom .arrow:after{top:1px;margin-left:-10px;border-bottom-color:#fff;border-top-width:0;content:" "}.factory-bootstrap-421 .popover.left .arrow{top:50%;right:-11px;margin-top:-11px;border-left-color:#999;border-left-color:rgba(0,0,0,.25);border-right-width:0}.factory-bootstrap-421 .popover.left .arrow:after{right:1px;bottom:-10px;border-left-color:#fff;border-right-width:0;content:" "}.factory-bootstrap-421 .carousel{position:relative}.factory-bootstrap-421 .carousel-inner{position:relative;width:100%;overflow:hidden}.factory-bootstrap-421 .carousel-inner>.item{position:relative;display:none;-webkit-transition:.6s ease-in-out left;transition:.6s ease-in-out left}.factory-bootstrap-421 .carousel-inner>.item>a>img,.factory-bootstrap-421 .carousel-inner>.item>img{display:block;height:auto;max-width:100%;line-height:1}.factory-bootstrap-421 .carousel-inner>.active,.factory-bootstrap-421 .carousel-inner>.next,.factory-bootstrap-421 .carousel-inner>.prev{display:block}.factory-bootstrap-421 .carousel-inner>.active{left:0}.factory-bootstrap-421 .carousel-inner>.next,.factory-bootstrap-421 .carousel-inner>.prev{position:absolute;top:0;width:100%}.factory-bootstrap-421 .carousel-inner>.next{left:100%}.factory-bootstrap-421 .carousel-inner>.prev{left:-100%}.factory-bootstrap-421 .carousel-inner>.next.left,.factory-bootstrap-421 .carousel-inner>.prev.right{left:0}.factory-bootstrap-421 .carousel-inner>.active.left{left:-100%}.factory-bootstrap-421 .carousel-inner>.active.right{left:100%}.factory-bootstrap-421 .carousel-control{position:absolute;top:0;bottom:0;left:0;width:15%;font-size:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,.6);opacity:.5;filter:alpha(opacity=50)}.factory-bootstrap-421 .carousel-control.left{background-image:-webkit-linear-gradient(left,color-stop(rgba(0,0,0,.5) 0),color-stop(rgba(0,0,0,.0001) 100%));background-image:linear-gradient(to right,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1)}.factory-bootstrap-421 .carousel-control.right{right:0;left:auto;background-image:-webkit-linear-gradient(left,color-stop(rgba(0,0,0,.0001) 0),color-stop(rgba(0,0,0,.5) 100%));background-image:linear-gradient(to right,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1)}.factory-bootstrap-421 .carousel-control:focus,.factory-bootstrap-421 .carousel-control:hover{color:#fff;text-decoration:none;outline:0;opacity:.9;filter:alpha(opacity=90)}.factory-bootstrap-421 .carousel-control .glyphicon-chevron-left,.factory-bootstrap-421 .carousel-control .glyphicon-chevron-right,.factory-bootstrap-421 .carousel-control .icon-next,.factory-bootstrap-421 .carousel-control .icon-prev{position:absolute;top:50%;z-index:5;display:inline-block}.factory-bootstrap-421 .carousel-control .glyphicon-chevron-left,.factory-bootstrap-421 .carousel-control .icon-prev{left:50%}.factory-bootstrap-421 .carousel-control .glyphicon-chevron-right,.factory-bootstrap-421 .carousel-control .icon-next{right:50%}.factory-bootstrap-421 .carousel-control .icon-next,.factory-bootstrap-421 .carousel-control .icon-prev{width:20px;height:20px;margin-top:-10px;margin-left:-10px;font-family:serif}.factory-bootstrap-421 .carousel-control .icon-prev:before{content:'\2039'}.factory-bootstrap-421 .carousel-control .icon-next:before{content:'\203a'}.factory-bootstrap-421 .carousel-indicators{position:absolute;bottom:10px;left:50%;z-index:15;width:60%;padding-left:0;margin-left:-30%;text-align:center;list-style:none}.factory-bootstrap-421 .carousel-indicators li{display:inline-block;width:10px;height:10px;margin:1px;text-indent:-999px;cursor:pointer;background-color:#000 \9;background-color:rgba(0,0,0,0);border:1px solid #fff;border-radius:10px}.factory-bootstrap-421 .carousel-indicators .active{width:12px;height:12px;margin:0;background-color:#fff}.factory-bootstrap-421 .carousel-caption{position:absolute;right:15%;bottom:20px;left:15%;z-index:10;padding-top:20px;padding-bottom:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,.6)}.factory-bootstrap-421 .carousel-caption .btn{text-shadow:none}@media screen and (min-width:768px){.carousel-control .glyphicons-chevron-left,.carousel-control .glyphicons-chevron-right,.carousel-control .icon-next,.carousel-control .icon-prev{width:30px;height:30px;margin-top:-15px;margin-left:-15px;font-size:30px}.carousel-caption{right:20%;left:20%;padding-bottom:30px}.carousel-indicators{bottom:20px}}.factory-bootstrap-421 .clearfix:after,.factory-bootstrap-421 .clearfix:before{display:table;content:" "}.factory-bootstrap-421 .clearfix:after{clear:both}.factory-bootstrap-421 .center-block{display:block;margin-right:auto;margin-left:auto}.factory-bootstrap-421 .pull-right{float:right!important}.factory-bootstrap-421 .pull-left{float:left!important}.factory-bootstrap-421 .hide{display:none!important}.factory-bootstrap-421 .show{display:block!important}.factory-bootstrap-421 .invisible{visibility:hidden}.factory-bootstrap-421 .text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.factory-bootstrap-421 .hidden{display:none!important;visibility:hidden!important}.factory-bootstrap-421 .affix{position:fixed}@-ms-viewport{width:device-width}.factory-bootstrap-421 .visible-lg,.factory-bootstrap-421 .visible-md,.factory-bootstrap-421 .visible-sm,.factory-bootstrap-421 .visible-xs,.factory-bootstrap-421 td.visible-lg,.factory-bootstrap-421 td.visible-md,.factory-bootstrap-421 td.visible-sm,.factory-bootstrap-421 td.visible-xs,.factory-bootstrap-421 th.visible-lg,.factory-bootstrap-421 th.visible-md,.factory-bootstrap-421 th.visible-sm,.factory-bootstrap-421 th.visible-xs,.factory-bootstrap-421 tr.visible-lg,.factory-bootstrap-421 tr.visible-md,.factory-bootstrap-421 tr.visible-sm,.factory-bootstrap-421 tr.visible-xs{display:none!important}@media (max-width:767px){.visible-xs{display:block!important}table.visible-xs{display:table}tr.visible-xs{display:table-row!important}td.visible-xs,th.visible-xs{display:table-cell!important}}@media (min-width:768px) and (max-width:991px){.visible-xs.visible-sm{display:block!important}table.visible-xs.visible-sm{display:table}tr.visible-xs.visible-sm{display:table-row!important}td.visible-xs.visible-sm,th.visible-xs.visible-sm{display:table-cell!important}}@media (min-width:992px) and (max-width:1199px){.visible-xs.visible-md{display:block!important}table.visible-xs.visible-md{display:table}tr.visible-xs.visible-md{display:table-row!important}td.visible-xs.visible-md,th.visible-xs.visible-md{display:table-cell!important}}@media (min-width:1200px){.visible-xs.visible-lg{display:block!important}table.visible-xs.visible-lg{display:table}tr.visible-xs.visible-lg{display:table-row!important}td.visible-xs.visible-lg,th.visible-xs.visible-lg{display:table-cell!important}}@media (max-width:767px){.visible-sm.visible-xs{display:block!important}table.visible-sm.visible-xs{display:table}tr.visible-sm.visible-xs{display:table-row!important}td.visible-sm.visible-xs,th.visible-sm.visible-xs{display:table-cell!important}}@media (min-width:768px) and (max-width:991px){.visible-sm{display:block!important}table.visible-sm{display:table}tr.visible-sm{display:table-row!important}td.visible-sm,th.visible-sm{display:table-cell!important}}@media (min-width:992px) and (max-width:1199px){.visible-sm.visible-md{display:block!important}table.visible-sm.visible-md{display:table}tr.visible-sm.visible-md{display:table-row!important}td.visible-sm.visible-md,th.visible-sm.visible-md{display:table-cell!important}}@media (min-width:1200px){.visible-sm.visible-lg{display:block!important}table.visible-sm.visible-lg{display:table}tr.visible-sm.visible-lg{display:table-row!important}td.visible-sm.visible-lg,th.visible-sm.visible-lg{display:table-cell!important}}@media (max-width:767px){.visible-md.visible-xs{display:block!important}table.visible-md.visible-xs{display:table}tr.visible-md.visible-xs{display:table-row!important}td.visible-md.visible-xs,th.visible-md.visible-xs{display:table-cell!important}}@media (min-width:768px) and (max-width:991px){.visible-md.visible-sm{display:block!important}table.visible-md.visible-sm{display:table}tr.visible-md.visible-sm{display:table-row!important}td.visible-md.visible-sm,th.visible-md.visible-sm{display:table-cell!important}}@media (min-width:992px) and (max-width:1199px){.visible-md{display:block!important}table.visible-md{display:table}tr.visible-md{display:table-row!important}td.visible-md,th.visible-md{display:table-cell!important}}@media (min-width:1200px){.visible-md.visible-lg{display:block!important}table.visible-md.visible-lg{display:table}tr.visible-md.visible-lg{display:table-row!important}td.visible-md.visible-lg,th.visible-md.visible-lg{display:table-cell!important}}@media (max-width:767px){.visible-lg.visible-xs{display:block!important}table.visible-lg.visible-xs{display:table}tr.visible-lg.visible-xs{display:table-row!important}td.visible-lg.visible-xs,th.visible-lg.visible-xs{display:table-cell!important}}@media (min-width:768px) and (max-width:991px){.visible-lg.visible-sm{display:block!important}table.visible-lg.visible-sm{display:table}tr.visible-lg.visible-sm{display:table-row!important}td.visible-lg.visible-sm,th.visible-lg.visible-sm{display:table-cell!important}}@media (min-width:992px) and (max-width:1199px){.visible-lg.visible-md{display:block!important}table.visible-lg.visible-md{display:table}tr.visible-lg.visible-md{display:table-row!important}td.visible-lg.visible-md,th.visible-lg.visible-md{display:table-cell!important}}@media (min-width:1200px){.visible-lg{display:block!important}table.visible-lg{display:table}tr.visible-lg{display:table-row!important}td.visible-lg,th.visible-lg{display:table-cell!important}}.factory-bootstrap-421 .hidden-xs{display:block!important}.factory-bootstrap-421 table.hidden-xs{display:table}.factory-bootstrap-421 tr.hidden-xs{display:table-row!important}.factory-bootstrap-421 td.hidden-xs,.factory-bootstrap-421 th.hidden-xs{display:table-cell!important}@media (max-width:767px){.hidden-xs,td.hidden-xs,th.hidden-xs,tr.hidden-xs{display:none!important}}@media (min-width:768px) and (max-width:991px){.hidden-xs.hidden-sm,td.hidden-xs.hidden-sm,th.hidden-xs.hidden-sm,tr.hidden-xs.hidden-sm{display:none!important}}@media (min-width:992px) and (max-width:1199px){.hidden-xs.hidden-md,td.hidden-xs.hidden-md,th.hidden-xs.hidden-md,tr.hidden-xs.hidden-md{display:none!important}}@media (min-width:1200px){.hidden-xs.hidden-lg,td.hidden-xs.hidden-lg,th.hidden-xs.hidden-lg,tr.hidden-xs.hidden-lg{display:none!important}}.factory-bootstrap-421 .hidden-sm{display:block!important}.factory-bootstrap-421 table.hidden-sm{display:table}.factory-bootstrap-421 tr.hidden-sm{display:table-row!important}.factory-bootstrap-421 td.hidden-sm,.factory-bootstrap-421 th.hidden-sm{display:table-cell!important}@media (max-width:767px){.hidden-sm.hidden-xs,td.hidden-sm.hidden-xs,th.hidden-sm.hidden-xs,tr.hidden-sm.hidden-xs{display:none!important}}@media (min-width:768px) and (max-width:991px){.hidden-sm,td.hidden-sm,th.hidden-sm,tr.hidden-sm{display:none!important}}@media (min-width:992px) and (max-width:1199px){.hidden-sm.hidden-md,td.hidden-sm.hidden-md,th.hidden-sm.hidden-md,tr.hidden-sm.hidden-md{display:none!important}}@media (min-width:1200px){.hidden-sm.hidden-lg,td.hidden-sm.hidden-lg,th.hidden-sm.hidden-lg,tr.hidden-sm.hidden-lg{display:none!important}}.factory-bootstrap-421 .hidden-md{display:block!important}.factory-bootstrap-421 table.hidden-md{display:table}.factory-bootstrap-421 tr.hidden-md{display:table-row!important}.factory-bootstrap-421 td.hidden-md,.factory-bootstrap-421 th.hidden-md{display:table-cell!important}@media (max-width:767px){.hidden-md.hidden-xs,td.hidden-md.hidden-xs,th.hidden-md.hidden-xs,tr.hidden-md.hidden-xs{display:none!important}}@media (min-width:768px) and (max-width:991px){.hidden-md.hidden-sm,td.hidden-md.hidden-sm,th.hidden-md.hidden-sm,tr.hidden-md.hidden-sm{display:none!important}}@media (min-width:992px) and (max-width:1199px){.hidden-md,td.hidden-md,th.hidden-md,tr.hidden-md{display:none!important}}@media (min-width:1200px){.hidden-md.hidden-lg,td.hidden-md.hidden-lg,th.hidden-md.hidden-lg,tr.hidden-md.hidden-lg{display:none!important}}.factory-bootstrap-421 .hidden-lg{display:block!important}.factory-bootstrap-421 table.hidden-lg{display:table}.factory-bootstrap-421 tr.hidden-lg{display:table-row!important}.factory-bootstrap-421 td.hidden-lg,.factory-bootstrap-421 th.hidden-lg{display:table-cell!important}@media (max-width:767px){.factory-bootstrap-421 .hidden-lg.hidden-xs,.factory-bootstrap-421 td.hidden-lg.hidden-xs,.factory-bootstrap-421 th.hidden-lg.hidden-xs,.factory-bootstrap-421 tr.hidden-lg.hidden-xs{display:none!important}}@media (min-width:768px) and (max-width:991px){.factory-bootstrap-421 .hidden-lg.hidden-sm,.factory-bootstrap-421 td.hidden-lg.hidden-sm,.factory-bootstrap-421 th.hidden-lg.hidden-sm,.factory-bootstrap-421 tr.hidden-lg.hidden-sm{display:none!important}}@media (min-width:992px) and (max-width:1199px){.factory-bootstrap-421 .hidden-lg.hidden-md,.factory-bootstrap-421 td.hidden-lg.hidden-md,.factory-bootstrap-421 th.hidden-lg.hidden-md,.factory-bootstrap-421 tr.hidden-lg.hidden-md{display:none!important}}@media (min-width:1200px){.factory-bootstrap-421 .hidden-lg,.factory-bootstrap-421 td.hidden-lg,.factory-bootstrap-421 th.hidden-lg,.factory-bootstrap-421 tr.hidden-lg{display:none!important}}.factory-bootstrap-421 .visible-print,.factory-bootstrap-421 td.visible-print,.factory-bootstrap-421 th.visible-print,.factory-bootstrap-421 tr.visible-print{display:none!important}@media print{.factory-bootstrap-421 .visible-print{display:block!important}.factory-bootstrap-421 table.visible-print{display:table}.factory-bootstrap-421 tr.visible-print{display:table-row!important}.factory-bootstrap-421 td.visible-print,.factory-bootstrap-421 th.visible-print{display:table-cell!important}.factory-bootstrap-421 .hidden-print,.factory-bootstrap-421 td.hidden-print,.factory-bootstrap-421 th.hidden-print,.factory-bootstrap-421 tr.hidden-print{display:none!important}}/*!
12
  * Factory Default Bootstrap Theme
13
  *
14
  * The code is based on Bootstrap v2.1.1
22
  *
23
  * @package factory-bootstrap
24
  * @since 1.0.0
25
+ */.factory-bootstrap-421 .btn-danger,.factory-bootstrap-421 .btn-default,.factory-bootstrap-421 .btn-info,.factory-bootstrap-421 .btn-primary,.factory-bootstrap-421 .btn-success,.factory-bootstrap-421 .btn-warning{-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 1px rgba(0,0,0,.075)}.factory-bootstrap-421 .btn-danger.active,.factory-bootstrap-421 .btn-danger:active,.factory-bootstrap-421 .btn-default.active,.factory-bootstrap-421 .btn-default:active,.factory-bootstrap-421 .btn-info.active,.factory-bootstrap-421 .btn-info:active,.factory-bootstrap-421 .btn-primary.active,.factory-bootstrap-421 .btn-primary:active,.factory-bootstrap-421 .btn-success.active,.factory-bootstrap-421 .btn-success:active,.factory-bootstrap-421 .btn-warning.active,.factory-bootstrap-421 .btn-warning:active{-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.1);box-shadow:inset 0 1px 1px rgba(0,0,0,.1)}.factory-bootstrap-421 .btn.active,.factory-bootstrap-421 .btn:active{background-image:none}.factory-bootstrap-421 .btn-default{color:#555;border-color:#ccc;background:#f7f7f7;-webkit-box-shadow:inset 0 1px 0 #fff,0 1px 0 rgba(0,0,0,.08);box-shadow:inset 0 1px 0 #fff,0 1px 0 rgba(0,0,0,.08);vertical-align:top}.factory-bootstrap-421 .btn-default.active,.factory-bootstrap-421 .btn-default:active{background-color:#fff;border-color:#dbdbdb}.factory-bootstrap-421 .btn-gold{font-weight:700;padding:7px 12px;cursor:pointer;line-height:16px;display:inline-block;border-radius:2px;-moz-border-radius:2px;-webkit-border-radius:2px;box-shadow:#e3e3e3 0 1px 1px;-moz-box-shadow:0 1px 1px rgba(000,000,000,.1),inset 0 1px 1px rgba(255,255,255,.7);-webkit-box-shadow:0 1px 1px rgba(000,000,000,.1),inset 0 1px 1px rgba(255,255,255,.7);text-shadow:1px 1px 0 #ffe8b2;color:#7c5d1b;border:1px solid #d6a437;background:#feeb80}.factory-bootstrap-421 .btn-gold:focus,.factory-bootstrap-421 .btn-gold:hover{background:#fef0a1}.factory-bootstrap-421 .btn-gold.active,.factory-bootstrap-421 .btn-gold:active{background:#fef0a1;-webkit-box-shadow:inset 0 3px 8px 0 #f8ba36;box-shadow:inset 0 3px 8px 0 #f8ba36}.factory-bootstrap-421 .btn-primary{background:#2ea2cc;border-color:#0074a2;-webkit-box-shadow:inset 0 1px 0 rgba(120,200,230,.5),0 1px 0 rgba(0,0,0,.15);box-shadow:inset 0 1px 0 rgba(120,200,230,.5),0 1px 0 rgba(0,0,0,.15);color:#fff;text-decoration:none}.factory-bootstrap-421 .btn-primary:focus,.factory-bootstrap-421 .btn-primary:hover{background:#1e8cbe;border-color:#0074a2;-webkit-box-shadow:inset 0 1px 0 rgba(120,200,230,.6);box-shadow:inset 0 1px 0 rgba(120,200,230,.6);color:#fff}.factory-bootstrap-421 .btn-primary.active,.factory-bootstrap-421 .btn-primary:active{background-color:#2d6ca2;border-color:#2b669a}.factory-bootstrap-421 .btn-success{background-image:-webkit-linear-gradient(top,#5cb85c 0,#419641 100%);background-image:linear-gradient(to bottom,#5cb85c 0,#419641 100%);background-repeat:repeat-x;border-color:#3e8f3e;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff419641', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.factory-bootstrap-421 .btn-success:focus,.factory-bootstrap-421 .btn-success:hover{background-color:#419641;background-position:0 -15px}.factory-bootstrap-421 .btn-success.active,.factory-bootstrap-421 .btn-success:active{background-color:#419641;border-color:#3e8f3e}.factory-bootstrap-421 .btn-warning{background-image:-webkit-linear-gradient(top,#f0ad4e 0,#eb9316 100%);background-image:linear-gradient(to bottom,#f0ad4e 0,#eb9316 100%);background-repeat:repeat-x;border-color:#e38d13;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffeb9316', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.factory-bootstrap-421 .btn-warning:focus,.factory-bootstrap-421 .btn-warning:hover{background-color:#eb9316;background-position:0 -15px}.factory-bootstrap-421 .btn-warning.active,.factory-bootstrap-421 .btn-warning:active{background-color:#eb9316;border-color:#e38d13}.factory-bootstrap-421 .btn-danger{color:#fff;background:#d9534f;border-color:#d43f3a}.factory-bootstrap-421 .btn-danger.active,.factory-bootstrap-421 .btn-danger:active,.factory-bootstrap-421 .btn-danger:focus,.factory-bootstrap-421 .btn-danger:hover,.factory-bootstrap-421 .open .dropdown-toggle.btn-danger{color:#fff;background-color:#d2322d;border-color:#ac2925}.factory-bootstrap-421 .btn-info{background-image:-webkit-linear-gradient(top,#5bc0de 0,#2aabd2 100%);background-image:linear-gradient(to bottom,#5bc0de 0,#2aabd2 100%);background-repeat:repeat-x;border-color:#28a4c9;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff2aabd2', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.factory-bootstrap-421 .btn-info:focus,.factory-bootstrap-421 .btn-info:hover{background-color:#2aabd2;background-position:0 -15px}.factory-bootstrap-421 .btn-info.active,.factory-bootstrap-421 .btn-info:active{background-color:#2aabd2;border-color:#28a4c9}.factory-bootstrap-421 .img-thumbnail,.factory-bootstrap-421 .thumbnail{-webkit-box-shadow:0 1px 2px rgba(0,0,0,.075);box-shadow:0 1px 2px rgba(0,0,0,.075)}.factory-bootstrap-421 .dropdown-menu>li>a:focus,.factory-bootstrap-421 .dropdown-menu>li>a:hover{background-color:#e8e8e8;background-image:-webkit-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%);background-image:linear-gradient(to bottom,#f5f5f5 0,#e8e8e8 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0)}.factory-bootstrap-421 .dropdown-menu>.active>a,.factory-bootstrap-421 .dropdown-menu>.active>a:focus,.factory-bootstrap-421 .dropdown-menu>.active>a:hover{background-color:#357ebd;background-image:-webkit-linear-gradient(top,#428bca 0,#357ebd 100%);background-image:linear-gradient(to bottom,#428bca 0,#357ebd 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff357ebd', GradientType=0)}.factory-bootstrap-421 .navbar-default{background-image:-webkit-linear-gradient(top,#fff 0,#f8f8f8 100%);background-image:linear-gradient(to bottom,#fff 0,#f8f8f8 100%);background-repeat:repeat-x;border-radius:4px;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#fff8f8f8', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 5px rgba(0,0,0,.075);box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 5px rgba(0,0,0,.075)}.factory-bootstrap-421 .navbar-default .navbar-nav>.active>a{background-image:-webkit-linear-gradient(top,#ebebeb 0,#f3f3f3 100%);background-image:linear-gradient(to bottom,#ebebeb 0,#f3f3f3 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffebebeb', endColorstr='#fff3f3f3', GradientType=0);-webkit-box-shadow:inset 0 3px 9px rgba(0,0,0,.075);box-shadow:inset 0 3px 9px rgba(0,0,0,.075)}.factory-bootstrap-421 .navbar-brand,.factory-bootstrap-421 .navbar-nav>li>a{text-shadow:0 1px 0 rgba(255,255,255,.25)}.factory-bootstrap-421 .navbar-inverse{background-image:-webkit-linear-gradient(top,#3c3c3c 0,#222 100%);background-image:linear-gradient(to bottom,#3c3c3c 0,#222 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff3c3c3c', endColorstr='#ff222222', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.factory-bootstrap-421 .navbar-inverse .navbar-nav>.active>a{background-image:-webkit-linear-gradient(top,#222 0,#282828 100%);background-image:linear-gradient(to bottom,#222 0,#282828 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff222222', endColorstr='#ff282828', GradientType=0);-webkit-box-shadow:inset 0 3px 9px rgba(0,0,0,.25);box-shadow:inset 0 3px 9px rgba(0,0,0,.25)}.factory-bootstrap-421 .navbar-inverse .navbar-brand,.factory-bootstrap-421 .navbar-inverse .navbar-nav>li>a{text-shadow:0 -1px 0 rgba(0,0,0,.25)}.factory-bootstrap-421 .navbar-fixed-bottom,.factory-bootstrap-421 .navbar-fixed-top,.factory-bootstrap-421 .navbar-static-top{border-radius:0}.factory-bootstrap-421 .alert{-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.25),0 1px 2px rgba(0,0,0,.05)}.factory-bootstrap-421 .alert .actions{padding-top:10px}.factory-bootstrap-421 .alert-success{color:#3c763d;background-color:#dff0d8;border-bottom:2px solid #c8e5bc}.factory-bootstrap-421 .alert-info{background-image:-webkit-linear-gradient(top,#d9edf7 0,#b9def0 100%);background-image:linear-gradient(to bottom,#d9edf7 0,#b9def0 100%);background-repeat:repeat-x;border-color:#9acfea;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffb9def0', GradientType=0)}.factory-bootstrap-421 .alert{text-shadow:none;box-shadow:none;margin:0;margin-top:10px;margin-bottom:10px;padding:10px}.factory-bootstrap-421 .alert-normal,.factory-bootstrap-421 .alert-warning{background:#fcf8e3;color:#8a6d3b;border:1px solid #b8823b}.factory-bootstrap-421 .alert-danger{background:#cf4944;color:#fff;border-bottom:2px solid #b23e3a}.factory-bootstrap-421 .alert-danger a:not(.btn),.factory-bootstrap-421 .alert-error a:not(.btn){color:#fff}.factory-bootstrap-421 .progress{background-image:-webkit-linear-gradient(top,#ebebeb 0,#f5f5f5 100%);background-image:linear-gradient(to bottom,#ebebeb 0,#f5f5f5 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffebebeb', endColorstr='#fff5f5f5', GradientType=0)}.factory-bootstrap-421 .progress-bar{background-image:-webkit-linear-gradient(top,#428bca 0,#3071a9 100%);background-image:linear-gradient(to bottom,#428bca 0,#3071a9 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff3071a9', GradientType=0)}.factory-bootstrap-421 .progress-bar-success{background-image:-webkit-linear-gradient(top,#5cb85c 0,#449d44 100%);background-image:linear-gradient(to bottom,#5cb85c 0,#449d44 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff449d44', GradientType=0)}.factory-bootstrap-421 .progress-bar-info{background-image:-webkit-linear-gradient(top,#5bc0de 0,#31b0d5 100%);background-image:linear-gradient(to bottom,#5bc0de 0,#31b0d5 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff31b0d5', GradientType=0)}.factory-bootstrap-421 .progress-bar-warning{background-image:-webkit-linear-gradient(top,#f0ad4e 0,#ec971f 100%);background-image:linear-gradient(to bottom,#f0ad4e 0,#ec971f 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffec971f', GradientType=0)}.factory-bootstrap-421 .progress-bar-danger{background-image:-webkit-linear-gradient(top,#d9534f 0,#c9302c 100%);background-image:linear-gradient(to bottom,#d9534f 0,#c9302c 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc9302c', GradientType=0)}.factory-bootstrap-421 .list-group{border-radius:4px;-webkit-box-shadow:0 1px 2px rgba(0,0,0,.075);box-shadow:0 1px 2px rgba(0,0,0,.075)}.factory-bootstrap-421 .list-group-item.active,.factory-bootstrap-421 .list-group-item.active:focus,.factory-bootstrap-421 .list-group-item.active:hover{text-shadow:0 -1px 0 #3071a9;background-image:-webkit-linear-gradient(top,#428bca 0,#3278b3 100%);background-image:linear-gradient(to bottom,#428bca 0,#3278b3 100%);background-repeat:repeat-x;border-color:#3278b3;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff3278b3', GradientType=0)}.factory-bootstrap-421 .panel{-webkit-box-shadow:0 1px 2px rgba(0,0,0,.05);box-shadow:0 1px 2px rgba(0,0,0,.05)}.factory-bootstrap-421 .panel-default>.panel-heading{background-image:-webkit-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%);background-image:linear-gradient(to bottom,#f5f5f5 0,#e8e8e8 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0)}.factory-bootstrap-421 .panel-primary>.panel-heading{background-image:-webkit-linear-gradient(top,#428bca 0,#357ebd 100%);background-image:linear-gradient(to bottom,#428bca 0,#357ebd 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff357ebd', GradientType=0)}.factory-bootstrap-421 .panel-success>.panel-heading{background-image:-webkit-linear-gradient(top,#dff0d8 0,#d0e9c6 100%);background-image:linear-gradient(to bottom,#dff0d8 0,#d0e9c6 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffd0e9c6', GradientType=0)}.factory-bootstrap-421 .panel-info>.panel-heading{background-image:-webkit-linear-gradient(top,#d9edf7 0,#c4e3f3 100%);background-image:linear-gradient(to bottom,#d9edf7 0,#c4e3f3 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffc4e3f3', GradientType=0)}.factory-bootstrap-421 .panel-warning>.panel-heading{background-image:-webkit-linear-gradient(top,#fcf8e3 0,#faf2cc 100%);background-image:linear-gradient(to bottom,#fcf8e3 0,#faf2cc 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fffaf2cc', GradientType=0)}.factory-bootstrap-421 .panel-danger>.panel-heading{background-image:-webkit-linear-gradient(top,#f2dede 0,#ebcccc 100%);background-image:linear-gradient(to bottom,#f2dede 0,#ebcccc 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffebcccc', GradientType=0)}.factory-bootstrap-421 .well{background-image:-webkit-linear-gradient(top,#e8e8e8 0,#f5f5f5 100%);background-image:linear-gradient(to bottom,#e8e8e8 0,#f5f5f5 100%);background-repeat:repeat-x;border-color:#dcdcdc;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe8e8e8', endColorstr='#fff5f5f5', GradientType=0);-webkit-box-shadow:inset 0 1px 3px rgba(0,0,0,.05),0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 3px rgba(0,0,0,.05),0 1px 0 rgba(255,255,255,.1)}.factory-bootstrap-421 .factory-after{margin-left:7px;display:inline-block}.factory-bootstrap-421 .factory-hidden{display:none}.factory-bootstrap-421 .factory-ajax-loader{width:25px;height:25px;background:url(../assets/images/loader-sm-tr.gif)}.factory-control-error{background-color:rgba(0,0,0,.8);white-space:normal;z-index:10;font-weight:400;line-height:150%;border-radius:4px;color:#fff;font-size:13px;margin-top:5px;padding:4px 10px 3px;max-width:500px;display:inline-block}.factory-control-error i{margin:0 7px 0 1px}
libs/factory/bootstrap/assets/css-min/bootstrap.ectoplasm.min.css CHANGED
@@ -8,4 +8,4 @@
8
  */
9
 
10
 
11
- .factory-bootstrap-400 .btn-primary{background:#a3b745;border-color:#839237;color:#fff;-webkit-box-shadow:inset 0 1px 0 #c0cd7b,0 1px 0 rgba(0,0,0,.15);box-shadow:inset 0 1px 0 #c0cd7b,0 1px 0 rgba(0,0,0,.15)}.factory-bootstrap-400 .btn-primary:focus,.factory-bootstrap-400 .btn-primary:hover{background:#89993a;border-color:#727f30;color:#fff;-webkit-box-shadow:inset 0 1px 0 #b7c669,0 1px 0 rgba(0,0,0,.15);box-shadow:inset 0 1px 0 #b7c669,0 1px 0 rgba(0,0,0,.15)}.factory-bootstrap-400 .btn-primary:active{background:#89993a;border-color:#727f30;color:#fff;-webkit-box-shadow:inset 0 2px 5px -3px rgba(0,0,0,.5);box-shadow:inset 0 2px 5px -3px rgba(0,0,0,.5)}.factory-bootstrap-400 .btn-primary:disabled,.factory-bootstrap-400 .btn-primary[disabled]{color:#cfd1c7!important;background:#89993a!important;border-color:#727f30!important;text-shadow:none!important}.factory-bootstrap-400 .btn-group .btn.active.value{background-color:#a3b745;-webkit-box-shadow:inset 0 1px 2px #839237;box-shadow:inset 0 1px 2px #839237;border-top:1px solid #839237;border-bottom:1px solid #839237;border-left:1px solid #839237}.factory-bootstrap-400 .pagination>.active>a,.factory-bootstrap-400 .pagination>.active>a:focus,.factory-bootstrap-400 .pagination>.active>a:hover,.factory-bootstrap-400 .pagination>.active>span,.factory-bootstrap-400 .pagination>.active>span:focus,.factory-bootstrap-400 .pagination>.active>span:hover{background-color:#a3b745;border-color:#839237}
8
  */
9
 
10
 
11
+ .factory-bootstrap-421 .btn-primary{background:#a3b745;border-color:#839237;color:#fff;-webkit-box-shadow:inset 0 1px 0 #c0cd7b,0 1px 0 rgba(0,0,0,.15);box-shadow:inset 0 1px 0 #c0cd7b,0 1px 0 rgba(0,0,0,.15)}.factory-bootstrap-421 .btn-primary:focus,.factory-bootstrap-421 .btn-primary:hover{background:#89993a;border-color:#727f30;color:#fff;-webkit-box-shadow:inset 0 1px 0 #b7c669,0 1px 0 rgba(0,0,0,.15);box-shadow:inset 0 1px 0 #b7c669,0 1px 0 rgba(0,0,0,.15)}.factory-bootstrap-421 .btn-primary:active{background:#89993a;border-color:#727f30;color:#fff;-webkit-box-shadow:inset 0 2px 5px -3px rgba(0,0,0,.5);box-shadow:inset 0 2px 5px -3px rgba(0,0,0,.5)}.factory-bootstrap-421 .btn-primary:disabled,.factory-bootstrap-421 .btn-primary[disabled]{color:#cfd1c7!important;background:#89993a!important;border-color:#727f30!important;text-shadow:none!important}.factory-bootstrap-421 .btn-group .btn.active.value{background-color:#a3b745;-webkit-box-shadow:inset 0 1px 2px #839237;box-shadow:inset 0 1px 2px #839237;border-top:1px solid #839237;border-bottom:1px solid #839237;border-left:1px solid #839237}.factory-bootstrap-421 .pagination>.active>a,.factory-bootstrap-421 .pagination>.active>a:focus,.factory-bootstrap-421 .pagination>.active>a:hover,.factory-bootstrap-421 .pagination>.active>span,.factory-bootstrap-421 .pagination>.active>span:focus,.factory-bootstrap-421 .pagination>.active>span:hover{background-color:#a3b745;border-color:#839237}
libs/factory/bootstrap/assets/css-min/bootstrap.form-group.min.css CHANGED
@@ -8,4 +8,4 @@
8
  */
9
 
10
 
11
- .factory-bootstrap-400 .factory-form-group .factory-legend{padding:9px 12px;background-color:#f9f9f9}.factory-bootstrap-400 .factory-form-group .factory-title{font-weight:700;font-size:14px;line-height:14px;color:#555;margin:0}.factory-bootstrap-400 .factory-form-group .factory-hint-icon{display:block;width:16px;height:16px;line-height:13px;padding:0;font-size:11px;text-align:center;position:absolute;top:-5px;right:-3px;color:#fff;background:#E91E63;border-radius:3px}.factory-bootstrap-400 .factory-form-group .factory-hint-icon.factory-hint-icon-green{background:#8bc34a}.factory-bootstrap-400 .factory-form-group .factory-hint-icon.factory-hint-icon-grey{background:#9e9e9e}.factory-bootstrap-400 .factory-form-group .factory-hint-icon.factory-hint-icon-red{background:#E91E63}.factory-bootstrap-400 .factory-form-group .factory-hint{margin:0;font-size:12px;line-height:16px;margin-top:6px}.factory-bootstrap-400 .factory-form-group+.factory-form-group{margin-top:30px}.factory-bootstrap-400 .factory-form-group legend+.control-group{margin-top:0}
8
  */
9
 
10
 
11
+ .factory-bootstrap-421 .factory-form-group .factory-legend{padding:9px 12px;background-color:#f9f9f9}.factory-bootstrap-421 .factory-form-group .factory-title{font-weight:700;font-size:14px;line-height:14px;color:#555;margin:0}.factory-bootstrap-421 .factory-form-group .factory-hint-icon{display:block;width:16px;height:16px;line-height:13px;padding:0;font-size:11px;text-align:center;position:absolute;top:-5px;right:-3px;color:#fff;background:#E91E63;border-radius:3px}.factory-bootstrap-421 .factory-form-group .factory-hint-icon.factory-hint-icon-green{background:#8bc34a}.factory-bootstrap-421 .factory-form-group .factory-hint-icon.factory-hint-icon-grey{background:#9e9e9e}.factory-bootstrap-421 .factory-form-group .factory-hint-icon.factory-hint-icon-red{background:#E91E63}.factory-bootstrap-421 .factory-form-group .factory-hint{margin:0;font-size:12px;line-height:16px;margin-top:6px}.factory-bootstrap-421 .factory-form-group+.factory-form-group{margin-top:30px}.factory-bootstrap-421 .factory-form-group legend+.control-group{margin-top:0}
libs/factory/bootstrap/assets/css-min/bootstrap.light.min.css CHANGED
@@ -8,4 +8,4 @@
8
  */
9
 
10
 
11
- .factory-bootstrap-400 .btn-primary{background:#04a4cc;border-color:#037c9a;color:#fff;-webkit-box-shadow:inset 0 1px 0 #22cffb,0 1px 0 rgba(0,0,0,.15);box-shadow:inset 0 1px 0 #22cffb,0 1px 0 rgba(0,0,0,.15)}.factory-bootstrap-400 .btn-primary:focus,.factory-bootstrap-400 .btn-primary:hover{background:#0384a4;border-color:#036881;color:#fff;-webkit-box-shadow:inset 0 1px 0 #09cafa,0 1px 0 rgba(0,0,0,.15);box-shadow:inset 0 1px 0 #09cafa,0 1px 0 rgba(0,0,0,.15)}.factory-bootstrap-400 .btn-primary:active{background:#0384a4;border-color:#036881;color:#fff;-webkit-box-shadow:inset 0 2px 5px -3px rgba(0,0,0,.5);box-shadow:inset 0 2px 5px -3px rgba(0,0,0,.5)}.factory-bootstrap-400 .btn-primary:disabled,.factory-bootstrap-400 .btn-primary[disabled]{color:#c7cfd1!important;background:#0384a4!important;border-color:#036881!important;text-shadow:none!important}.factory-bootstrap-400 .btn-group .btn.active.value{background-color:#04a4cc;-webkit-box-shadow:inset 0 1px 2px #037c9a;box-shadow:inset 0 1px 2px #037c9a;border-top:1px solid #037c9a;border-bottom:1px solid #037c9a;border-left:1px solid #037c9a}.factory-bootstrap-400 .pagination>.active>a,.factory-bootstrap-400 .pagination>.active>a:focus,.factory-bootstrap-400 .pagination>.active>a:hover,.factory-bootstrap-400 .pagination>.active>span,.factory-bootstrap-400 .pagination>.active>span:focus,.factory-bootstrap-400 .pagination>.active>span:hover{background-color:#04a4cc;border-color:#037c9a}
8
  */
9
 
10
 
11
+ .factory-bootstrap-421 .btn-primary{background:#04a4cc;border-color:#037c9a;color:#fff;-webkit-box-shadow:inset 0 1px 0 #22cffb,0 1px 0 rgba(0,0,0,.15);box-shadow:inset 0 1px 0 #22cffb,0 1px 0 rgba(0,0,0,.15)}.factory-bootstrap-421 .btn-primary:focus,.factory-bootstrap-421 .btn-primary:hover{background:#0384a4;border-color:#036881;color:#fff;-webkit-box-shadow:inset 0 1px 0 #09cafa,0 1px 0 rgba(0,0,0,.15);box-shadow:inset 0 1px 0 #09cafa,0 1px 0 rgba(0,0,0,.15)}.factory-bootstrap-421 .btn-primary:active{background:#0384a4;border-color:#036881;color:#fff;-webkit-box-shadow:inset 0 2px 5px -3px rgba(0,0,0,.5);box-shadow:inset 0 2px 5px -3px rgba(0,0,0,.5)}.factory-bootstrap-421 .btn-primary:disabled,.factory-bootstrap-421 .btn-primary[disabled]{color:#c7cfd1!important;background:#0384a4!important;border-color:#036881!important;text-shadow:none!important}.factory-bootstrap-421 .btn-group .btn.active.value{background-color:#04a4cc;-webkit-box-shadow:inset 0 1px 2px #037c9a;box-shadow:inset 0 1px 2px #037c9a;border-top:1px solid #037c9a;border-bottom:1px solid #037c9a;border-left:1px solid #037c9a}.factory-bootstrap-421 .pagination>.active>a,.factory-bootstrap-421 .pagination>.active>a:focus,.factory-bootstrap-421 .pagination>.active>a:hover,.factory-bootstrap-421 .pagination>.active>span,.factory-bootstrap-421 .pagination>.active>span:focus,.factory-bootstrap-421 .pagination>.active>span:hover{background-color:#04a4cc;border-color:#037c9a}
libs/factory/bootstrap/assets/css-min/bootstrap.midnight.min.css CHANGED
@@ -8,4 +8,4 @@
8
  */
9
 
10
 
11
- .factory-bootstrap-400 .btn-primary{background:#e14d43;border-color:#d02a21;color:#fff;-webkit-box-shadow:inset 0 1px 0 #ec8a85,0 1px 0 rgba(0,0,0,.15);box-shadow:inset 0 1px 0 #ec8a85,0 1px 0 rgba(0,0,0,.15)}.factory-bootstrap-400 .btn-primary:focus,.factory-bootstrap-400 .btn-primary:hover{background:#d92c23;border-color:#ba251e;color:#fff;-webkit-box-shadow:inset 0 1px 0 #e8756f,0 1px 0 rgba(0,0,0,.15);box-shadow:inset 0 1px 0 #e8756f,0 1px 0 rgba(0,0,0,.15)}.factory-bootstrap-400 .btn-primary:active{background:#d92c23;border-color:#ba251e;color:#fff;-webkit-box-shadow:inset 0 2px 5px -3px rgba(0,0,0,.5);box-shadow:inset 0 2px 5px -3px rgba(0,0,0,.5)}.factory-bootstrap-400 .btn-primary:disabled,.factory-bootstrap-400 .btn-primary[disabled]{color:#d1c7c7!important;background:#d92c23!important;border-color:#ba251e!important;text-shadow:none!important}.factory-bootstrap-400 .btn-group .btn.active.value{background-color:#e14d43;-webkit-box-shadow:inset 0 1px 2px #d02a21;box-shadow:inset 0 1px 2px #d02a21;border-top:1px solid #d02a21;border-bottom:1px solid #d02a21;border-left:1px solid #d02a21}.factory-bootstrap-400 .pagination>.active>a,.factory-bootstrap-400 .pagination>.active>a:focus,.factory-bootstrap-400 .pagination>.active>a:hover,.factory-bootstrap-400 .pagination>.active>span,.factory-bootstrap-400 .pagination>.active>span:focus,.factory-bootstrap-400 .pagination>.active>span:hover{background-color:#e14d43;border-color:#d02a21}
8
  */
9
 
10
 
11
+ .factory-bootstrap-421 .btn-primary{background:#e14d43;border-color:#d02a21;color:#fff;-webkit-box-shadow:inset 0 1px 0 #ec8a85,0 1px 0 rgba(0,0,0,.15);box-shadow:inset 0 1px 0 #ec8a85,0 1px 0 rgba(0,0,0,.15)}.factory-bootstrap-421 .btn-primary:focus,.factory-bootstrap-421 .btn-primary:hover{background:#d92c23;border-color:#ba251e;color:#fff;-webkit-box-shadow:inset 0 1px 0 #e8756f,0 1px 0 rgba(0,0,0,.15);box-shadow:inset 0 1px 0 #e8756f,0 1px 0 rgba(0,0,0,.15)}.factory-bootstrap-421 .btn-primary:active{background:#d92c23;border-color:#ba251e;color:#fff;-webkit-box-shadow:inset 0 2px 5px -3px rgba(0,0,0,.5);box-shadow:inset 0 2px 5px -3px rgba(0,0,0,.5)}.factory-bootstrap-421 .btn-primary:disabled,.factory-bootstrap-421 .btn-primary[disabled]{color:#d1c7c7!important;background:#d92c23!important;border-color:#ba251e!important;text-shadow:none!important}.factory-bootstrap-421 .btn-group .btn.active.value{background-color:#e14d43;-webkit-box-shadow:inset 0 1px 2px #d02a21;box-shadow:inset 0 1px 2px #d02a21;border-top:1px solid #d02a21;border-bottom:1px solid #d02a21;border-left:1px solid #d02a21}.factory-bootstrap-421 .pagination>.active>a,.factory-bootstrap-421 .pagination>.active>a:focus,.factory-bootstrap-421 .pagination>.active>a:hover,.factory-bootstrap-421 .pagination>.active>span,.factory-bootstrap-421 .pagination>.active>span:focus,.factory-bootstrap-421 .pagination>.active>span:hover{background-color:#e14d43;border-color:#d02a21}
libs/factory/bootstrap/assets/css-min/bootstrap.ocean.min.css CHANGED
@@ -8,4 +8,4 @@
8
  */
9
 
10
 
11
- .factory-bootstrap-400 .btn-primary{background:#9ebaa0;border-color:#80a583;color:#fff;-webkit-box-shadow:inset 0 1px 0 #cbdacc,0 1px 0 rgba(0,0,0,.15);box-shadow:inset 0 1px 0 #cbdacc,0 1px 0 rgba(0,0,0,.15)}.factory-bootstrap-400 .btn-primary:focus,.factory-bootstrap-400 .btn-primary:hover{background:#86a988;border-color:#719a74;color:#fff;-webkit-box-shadow:inset 0 1px 0 #bccfbd,0 1px 0 rgba(0,0,0,.15);box-shadow:inset 0 1px 0 #bccfbd,0 1px 0 rgba(0,0,0,.15)}.factory-bootstrap-400 .btn-primary:active{background:#86a988;border-color:#719a74;color:#fff;-webkit-box-shadow:inset 0 2px 5px -3px rgba(0,0,0,.5);box-shadow:inset 0 2px 5px -3px rgba(0,0,0,.5)}.factory-bootstrap-400 .btn-primary:disabled,.factory-bootstrap-400 .btn-primary[disabled]{color:#c7d1c8!important;background:#86a988!important;border-color:#719a74!important;text-shadow:none!important}.factory-bootstrap-400 .btn-group .btn.active.value{background-color:#9ebaa0;-webkit-box-shadow:inset 0 1px 2px #80a583;box-shadow:inset 0 1px 2px #80a583;border-top:1px solid #80a583;border-bottom:1px solid #80a583;border-left:1px solid #80a583}.factory-bootstrap-400 .pagination>.active>a,.factory-bootstrap-400 .pagination>.active>a:focus,.factory-bootstrap-400 .pagination>.active>a:hover,.factory-bootstrap-400 .pagination>.active>span,.factory-bootstrap-400 .pagination>.active>span:focus,.factory-bootstrap-400 .pagination>.active>span:hover{background-color:#9ebaa0;border-color:#80a583}
8
  */
9
 
10
 
11
+ .factory-bootstrap-421 .btn-primary{background:#9ebaa0;border-color:#80a583;color:#fff;-webkit-box-shadow:inset 0 1px 0 #cbdacc,0 1px 0 rgba(0,0,0,.15);box-shadow:inset 0 1px 0 #cbdacc,0 1px 0 rgba(0,0,0,.15)}.factory-bootstrap-421 .btn-primary:focus,.factory-bootstrap-421 .btn-primary:hover{background:#86a988;border-color:#719a74;color:#fff;-webkit-box-shadow:inset 0 1px 0 #bccfbd,0 1px 0 rgba(0,0,0,.15);box-shadow:inset 0 1px 0 #bccfbd,0 1px 0 rgba(0,0,0,.15)}.factory-bootstrap-421 .btn-primary:active{background:#86a988;border-color:#719a74;color:#fff;-webkit-box-shadow:inset 0 2px 5px -3px rgba(0,0,0,.5);box-shadow:inset 0 2px 5px -3px rgba(0,0,0,.5)}.factory-bootstrap-421 .btn-primary:disabled,.factory-bootstrap-421 .btn-primary[disabled]{color:#c7d1c8!important;background:#86a988!important;border-color:#719a74!important;text-shadow:none!important}.factory-bootstrap-421 .btn-group .btn.active.value{background-color:#9ebaa0;-webkit-box-shadow:inset 0 1px 2px #80a583;box-shadow:inset 0 1px 2px #80a583;border-top:1px solid #80a583;border-bottom:1px solid #80a583;border-left:1px solid #80a583}.factory-bootstrap-421 .pagination>.active>a,.factory-bootstrap-421 .pagination>.active>a:focus,.factory-bootstrap-421 .pagination>.active>a:hover,.factory-bootstrap-421 .pagination>.active>span,.factory-bootstrap-421 .pagination>.active>span:focus,.factory-bootstrap-421 .pagination>.active>span:hover{background-color:#9ebaa0;border-color:#80a583}
libs/factory/bootstrap/assets/css-min/bootstrap.separator.min.css CHANGED
@@ -8,4 +8,4 @@
8
  */
9
 
10
 
11
- .factory-bootstrap-400 .factory-separator{border-bottom:1px solid #f9f9f9;border-top:1px solid #d1d1d1;margin-bottom:25px}
8
  */
9
 
10
 
11
+ .factory-bootstrap-421 .factory-separator{border-bottom:1px solid #f9f9f9;border-top:1px solid #d1d1d1;margin-bottom:25px}
libs/factory/bootstrap/assets/css-min/bootstrap.sunrise.min.css CHANGED
@@ -8,4 +8,4 @@
8
  */
9
 
10
 
11
- .factory-bootstrap-400 .btn-primary{background:#dd823b;border-color:#c36822;color:#fff;-webkit-box-shadow:inset 0 1px 0 #e8ab7c,0 1px 0 rgba(0,0,0,.15);box-shadow:inset 0 1px 0 #e8ab7c,0 1px 0 rgba(0,0,0,.15)}.factory-bootstrap-400 .btn-primary:focus,.factory-bootstrap-400 .btn-primary:hover{background:#cc6c23;border-color:#ad5c1e;color:#fff;-webkit-box-shadow:inset 0 1px 0 #e59d66,0 1px 0 rgba(0,0,0,.15);box-shadow:inset 0 1px 0 #e59d66,0 1px 0 rgba(0,0,0,.15)}.factory-bootstrap-400 .btn-primary:active{background:#cc6c23;border-color:#ad5c1e;color:#fff;-webkit-box-shadow:inset 0 2px 5px -3px rgba(0,0,0,.5);box-shadow:inset 0 2px 5px -3px rgba(0,0,0,.5)}.factory-bootstrap-400 .btn-primary:disabled,.factory-bootstrap-400 .btn-primary[disabled]{color:#d1cbc7!important;background:#cc6c23!important;border-color:#ad5c1e!important;text-shadow:none!important}.factory-bootstrap-400 .btn-group .btn.active.value{background-color:#dd823b;-webkit-box-shadow:inset 0 1px 2px #c36822;box-shadow:inset 0 1px 2px #c36822;border-top:1px solid #c36822;border-bottom:1px solid #c36822;border-left:1px solid #c36822}.factory-bootstrap-400 .pagination>.active>a,.factory-bootstrap-400 .pagination>.active>a:focus,.factory-bootstrap-400 .pagination>.active>a:hover,.factory-bootstrap-400 .pagination>.active>span,.factory-bootstrap-400 .pagination>.active>span:focus,.factory-bootstrap-400 .pagination>.active>span:hover{background-color:#dd823b;border-color:#c36822}
8
  */
9
 
10
 
11
+ .factory-bootstrap-421 .btn-primary{background:#dd823b;border-color:#c36822;color:#fff;-webkit-box-shadow:inset 0 1px 0 #e8ab7c,0 1px 0 rgba(0,0,0,.15);box-shadow:inset 0 1px 0 #e8ab7c,0 1px 0 rgba(0,0,0,.15)}.factory-bootstrap-421 .btn-primary:focus,.factory-bootstrap-421 .btn-primary:hover{background:#cc6c23;border-color:#ad5c1e;color:#fff;-webkit-box-shadow:inset 0 1px 0 #e59d66,0 1px 0 rgba(0,0,0,.15);box-shadow:inset 0 1px 0 #e59d66,0 1px 0 rgba(0,0,0,.15)}.factory-bootstrap-421 .btn-primary:active{background:#cc6c23;border-color:#ad5c1e;color:#fff;-webkit-box-shadow:inset 0 2px 5px -3px rgba(0,0,0,.5);box-shadow:inset 0 2px 5px -3px rgba(0,0,0,.5)}.factory-bootstrap-421 .btn-primary:disabled,.factory-bootstrap-421 .btn-primary[disabled]{color:#d1cbc7!important;background:#cc6c23!important;border-color:#ad5c1e!important;text-shadow:none!important}.factory-bootstrap-421 .btn-group .btn.active.value{background-color:#dd823b;-webkit-box-shadow:inset 0 1px 2px #c36822;box-shadow:inset 0 1px 2px #c36822;border-top:1px solid #c36822;border-bottom:1px solid #c36822;border-left:1px solid #c36822}.factory-bootstrap-421 .pagination>.active>a,.factory-bootstrap-421 .pagination>.active>a:focus,.factory-bootstrap-421 .pagination>.active>a:hover,.factory-bootstrap-421 .pagination>.active>span,.factory-bootstrap-421 .pagination>.active>span:focus,.factory-bootstrap-421 .pagination>.active>span:hover{background-color:#dd823b;border-color:#c36822}
libs/factory/bootstrap/assets/css-min/control.checkbox.min.css CHANGED
@@ -8,4 +8,4 @@
8
  */
9
 
10
 
11
- #side-sortables .factory-bootstrap-400 .factory-buttons-way{float:right;position:relative;top:-25px;left:5px;border:3px solid #f9f9f9;border-radius:4px}.factory-bootstrap-400 .factory-buttons-way{border:3px solid #f9f9f9;border-radius:4px}.factory-bootstrap-400 .factory-buttons-way button{padding-left:10px;padding-right:10px}.factory-bootstrap-400 .factory-buttons-way .factory-on.active{text-shadow:none;color:#fff;background-color:#33aad5;-webkit-box-shadow:inset 0 1px 1px #0074a2;box-shadow:inset 0 1px 3px #0074a2;border-top:1px solid #0074a2;border-bottom:1px solid #0074a2;border-left:1px solid #0074a2}.factory-bootstrap-400 .factory-checkbox-tumbler-hint{margin-top:5px}.factory-bootstrap-400 .factory-checkbox-tumbler-hint .factory-tumbler-content{display:inline-block;background-color:#ffd;padding:1px 5px}.admin-color-light .factory-bootstrap-400 .factory-buttons-way .factory-on.active{background-color:#04a4cc;-webkit-box-shadow:inset 0 1px 2px #037c9a;box-shadow:inset 0 1px 2px #037c9a;border-top:1px solid #037c9a;border-bottom:1px solid #037c9a;border-left:1px solid #037c9a}.admin-color-blue .factory-bootstrap-400 .factory-buttons-way .factory-on.active{background-color:#e1a948;-webkit-box-shadow:inset 0 1px 2px #d39323;box-shadow:inset 0 1px 2px #d39323;border-top:1px solid #d39323;border-bottom:1px solid #d39323;border-left:1px solid #d39323}.admin-color-coffee .factory-bootstrap-400 .factory-buttons-way .factory-on.active{background-color:#c7a589;-webkit-box-shadow:inset 0 1px 2px #b78a66;box-shadow:inset 0 1px 2px #b78a66;border-top:1px solid #b78a66;border-bottom:1px solid #b78a66;border-left:1px solid #b78a66}.admin-color-ectoplasm .factory-bootstrap-400 .factory-buttons-way .factory-on.active{background-color:#a3b745;-webkit-box-shadow:inset 0 1px 2px #839237;box-shadow:inset 0 1px 2px #839237;border-top:1px solid #839237;border-bottom:1px solid #839237;border-left:1px solid #839237}.admin-color-midnight .factory-bootstrap-400 .factory-buttons-way .factory-on.active{background-color:#e14d43;-webkit-box-shadow:inset 0 1px 2px #d02a21;box-shadow:inset 0 1px 2px #d02a21;border-top:1px solid #d02a21;border-bottom:1px solid #d02a21;border-left:1px solid #d02a21}.admin-color-ocean .factory-bootstrap-400 .factory-buttons-way .factory-on.active{background-color:#9ebaa0;-webkit-box-shadow:inset 0 1px 2px #80a583;box-shadow:inset 0 1px 2px #80a583;border-top:1px solid #80a583;border-bottom:1px solid #80a583;border-left:1px solid #80a583}.admin-color-sunrise .factory-bootstrap-400 .factory-buttons-way .factory-on.active{background-color:#dd823b;-webkit-box-shadow:inset 0 1px 2px #c36822;box-shadow:inset 0 1px 2px #c36822;border-top:1px solid #c36822;border-bottom:1px solid #c36822;border-left:1px solid #c36822}
8
  */
9
 
10
 
11
+ #side-sortables .factory-bootstrap-421 .factory-buttons-way{float:right;position:relative;top:-25px;left:5px;border:3px solid #f9f9f9;border-radius:4px}.factory-bootstrap-421 .factory-buttons-way{border:3px solid #f9f9f9;border-radius:4px}.factory-bootstrap-421 .factory-buttons-way button{padding-left:10px;padding-right:10px}.factory-bootstrap-421 .factory-buttons-way .factory-on.active{text-shadow:none;color:#fff;background-color:#33aad5;-webkit-box-shadow:inset 0 1px 1px #0074a2;box-shadow:inset 0 1px 3px #0074a2;border-top:1px solid #0074a2;border-bottom:1px solid #0074a2;border-left:1px solid #0074a2}.factory-bootstrap-421 .factory-checkbox-tumbler-hint{margin-top:5px}.factory-bootstrap-421 .factory-checkbox-tumbler-hint .factory-tumbler-content{display:inline-block;background-color:#ffd;padding:1px 5px}.admin-color-light .factory-bootstrap-421 .factory-buttons-way .factory-on.active{background-color:#04a4cc;-webkit-box-shadow:inset 0 1px 2px #037c9a;box-shadow:inset 0 1px 2px #037c9a;border-top:1px solid #037c9a;border-bottom:1px solid #037c9a;border-left:1px solid #037c9a}.admin-color-blue .factory-bootstrap-421 .factory-buttons-way .factory-on.active{background-color:#e1a948;-webkit-box-shadow:inset 0 1px 2px #d39323;box-shadow:inset 0 1px 2px #d39323;border-top:1px solid #d39323;border-bottom:1px solid #d39323;border-left:1px solid #d39323}.admin-color-coffee .factory-bootstrap-421 .factory-buttons-way .factory-on.active{background-color:#c7a589;-webkit-box-shadow:inset 0 1px 2px #b78a66;box-shadow:inset 0 1px 2px #b78a66;border-top:1px solid #b78a66;border-bottom:1px solid #b78a66;border-left:1px solid #b78a66}.admin-color-ectoplasm .factory-bootstrap-421 .factory-buttons-way .factory-on.active{background-color:#a3b745;-webkit-box-shadow:inset 0 1px 2px #839237;box-shadow:inset 0 1px 2px #839237;border-top:1px solid #839237;border-bottom:1px solid #839237;border-left:1px solid #839237}.admin-color-midnight .factory-bootstrap-421 .factory-buttons-way .factory-on.active{background-color:#e14d43;-webkit-box-shadow:inset 0 1px 2px #d02a21;box-shadow:inset 0 1px 2px #d02a21;border-top:1px solid #d02a21;border-bottom:1px solid #d02a21;border-left:1px solid #d02a21}.admin-color-ocean .factory-bootstrap-421 .factory-buttons-way .factory-on.active{background-color:#9ebaa0;-webkit-box-shadow:inset 0 1px 2px #80a583;box-shadow:inset 0 1px 2px #80a583;border-top:1px solid #80a583;border-bottom:1px solid #80a583;border-left:1px solid #80a583}.admin-color-sunrise .factory-bootstrap-421 .factory-buttons-way .factory-on.active{background-color:#dd823b;-webkit-box-shadow:inset 0 1px 2px #c36822;box-shadow:inset 0 1px 2px #c36822;border-top:1px solid #c36822;border-bottom:1px solid #c36822;border-left:1px solid #c36822}
libs/factory/bootstrap/assets/css-min/control.dropdown.min.css CHANGED
@@ -8,4 +8,4 @@
8
  */
9
 
10
 
11
- .factory-bootstrap-400 .factory-dropdown.factory-buttons-way .fa{margin-right:6px;position:relative}.factory-bootstrap-400 .factory-dropdown.factory-buttons-way{border:0;border-radius:0}.factory-bootstrap-400 .factory-hints .factory-hint{margin-top:5px;display:inline-block;background-color:#ffd;padding:1px 5px}.admin-color-light .factory-bootstrap-400 .factory-dropdown.factory-buttons-way .active{background-color:#04a4cc;-webkit-box-shadow:inset 0 1px 2px #037c9a;box-shadow:inset 0 1px 2px #037c9a;border-top:1px solid #037c9a;border-bottom:1px solid #037c9a;border-left:1px solid #037c9a}.admin-color-blue .factory-bootstrap-400 .factory-dropdown.factory-buttons-way .active{background-color:#e1a948;-webkit-box-shadow:inset 0 1px 2px #d39323;box-shadow:inset 0 1px 2px #d39323;border-top:1px solid #d39323;border-bottom:1px solid #d39323;border-left:1px solid #d39323}.admin-color-coffee .factory-bootstrap-400 .factory-dropdown.factory-buttons-way .active{background-color:#c7a589;-webkit-box-shadow:inset 0 1px 2px #b78a66;box-shadow:inset 0 1px 2px #b78a66;border-top:1px solid #b78a66;border-bottom:1px solid #b78a66;border-left:1px solid #b78a66}.admin-color-ectoplasm .factory-bootstrap-400 .factory-dropdown.factory-buttons-way .active{background-color:#a3b745;-webkit-box-shadow:inset 0 1px 2px #839237;box-shadow:inset 0 1px 2px #839237;border-top:1px solid #839237;border-bottom:1px solid #839237;border-left:1px solid #839237}.admin-color-midnight .factory-bootstrap-400 .factory-dropdown.factory-buttons-way .active{background-color:#e14d43;-webkit-box-shadow:inset 0 1px 2px #d02a21;box-shadow:inset 0 1px 2px #d02a21;border-top:1px solid #d02a21;border-bottom:1px solid #d02a21;border-left:1px solid #d02a21}.admin-color-ocean .factory-bootstrap-400 .factory-dropdown.factory-buttons-way .active{background-color:#9ebaa0;-webkit-box-shadow:inset 0 1px 2px #80a583;box-shadow:inset 0 1px 2px #80a583;border-top:1px solid #80a583;border-bottom:1px solid #80a583;border-left:1px solid #80a583}.admin-color-sunrise .factory-bootstrap-400 .factory-dropdown.factory-buttons-way .active{background-color:#dd823b;-webkit-box-shadow:inset 0 1px 2px #c36822;box-shadow:inset 0 1px 2px #c36822;border-top:1px solid #c36822;border-bottom:1px solid #c36822;border-left:1px solid #c36822}.factory-bootstrap-400 .factory-dropdown.factory-ddslick-way .dd-select{background-color:#fff!important}.factory-bootstrap-400 .factory-dropdown.factory-ddslick-way label{margin-bottom:1px}.factory-bootstrap-400 .factory-dropdown.factory-ddslick-way .dd-option,.factory-bootstrap-400 .factory-dropdown.factory-ddslick-way .dd-selected{padding:8px 12px 8px 11px!important}
8
  */
9
 
10
 
11
+ .factory-bootstrap-421 .factory-dropdown.factory-buttons-way .fa{margin-right:6px;position:relative}.factory-bootstrap-421 .factory-dropdown.factory-buttons-way{border:0;border-radius:0}.factory-bootstrap-421 .factory-hints .factory-hint{margin-top:5px;display:inline-block;background-color:#ffd;padding:1px 5px}.admin-color-light .factory-bootstrap-421 .factory-dropdown.factory-buttons-way .active{background-color:#04a4cc;-webkit-box-shadow:inset 0 1px 2px #037c9a;box-shadow:inset 0 1px 2px #037c9a;border-top:1px solid #037c9a;border-bottom:1px solid #037c9a;border-left:1px solid #037c9a}.admin-color-blue .factory-bootstrap-421 .factory-dropdown.factory-buttons-way .active{background-color:#e1a948;-webkit-box-shadow:inset 0 1px 2px #d39323;box-shadow:inset 0 1px 2px #d39323;border-top:1px solid #d39323;border-bottom:1px solid #d39323;border-left:1px solid #d39323}.admin-color-coffee .factory-bootstrap-421 .factory-dropdown.factory-buttons-way .active{background-color:#c7a589;-webkit-box-shadow:inset 0 1px 2px #b78a66;box-shadow:inset 0 1px 2px #b78a66;border-top:1px solid #b78a66;border-bottom:1px solid #b78a66;border-left:1px solid #b78a66}.admin-color-ectoplasm .factory-bootstrap-421 .factory-dropdown.factory-buttons-way .active{background-color:#a3b745;-webkit-box-shadow:inset 0 1px 2px #839237;box-shadow:inset 0 1px 2px #839237;border-top:1px solid #839237;border-bottom:1px solid #839237;border-left:1px solid #839237}.admin-color-midnight .factory-bootstrap-421 .factory-dropdown.factory-buttons-way .active{background-color:#e14d43;-webkit-box-shadow:inset 0 1px 2px #d02a21;box-shadow:inset 0 1px 2px #d02a21;border-top:1px solid #d02a21;border-bottom:1px solid #d02a21;border-left:1px solid #d02a21}.admin-color-ocean .factory-bootstrap-421 .factory-dropdown.factory-buttons-way .active{background-color:#9ebaa0;-webkit-box-shadow:inset 0 1px 2px #80a583;box-shadow:inset 0 1px 2px #80a583;border-top:1px solid #80a583;border-bottom:1px solid #80a583;border-left:1px solid #80a583}.admin-color-sunrise .factory-bootstrap-421 .factory-dropdown.factory-buttons-way .active{background-color:#dd823b;-webkit-box-shadow:inset 0 1px 2px #c36822;box-shadow:inset 0 1px 2px #c36822;border-top:1px solid #c36822;border-bottom:1px solid #c36822;border-left:1px solid #c36822}.factory-bootstrap-421 .factory-dropdown.factory-ddslick-way .dd-select{background-color:#fff!important}.factory-bootstrap-421 .factory-dropdown.factory-ddslick-way label{margin-bottom:1px}.factory-bootstrap-421 .factory-dropdown.factory-ddslick-way .dd-option,.factory-bootstrap-421 .factory-dropdown.factory-ddslick-way .dd-selected{padding:8px 12px 8px 11px!important}
libs/factory/bootstrap/assets/css-min/control.multiple-textbox.min.css CHANGED
@@ -8,4 +8,4 @@
8
  */
9
 
10
 
11
- .factory-bootstrap-400 .factory-mtextbox-item{position:relative;margin-bottom:5px}.factory-bootstrap-400 .factory-mtextbox-item input,.factory-mtextbox-remove-item{display:inline-block}.factory-bootstrap-400 .factory-mtextbox-item .factory-mtextbox-remove-item{position:absolute;top:0;right:0;bottom:0;width:40px;border-radius:0 3px 3px 0;outline:0}.factory-bootstrap-400 .factory-mtextbox-item .factory-mtextbox-remove-item:focus,.factory-bootstrap-400 .factory-mtextbox-item .factory-mtextbox-remove-item:hover{box-shadow:none;outline:0}.factory-bootstrap-400 .factory-mtextbox-add-item{display:block;margin-top:10px}
8
  */
9
 
10
 
11
+ .factory-bootstrap-421 .factory-mtextbox-item{position:relative;margin-bottom:5px}.factory-bootstrap-421 .factory-mtextbox-item input,.factory-mtextbox-remove-item{display:inline-block}.factory-bootstrap-421 .factory-mtextbox-item .factory-mtextbox-remove-item{position:absolute;top:0;right:0;bottom:0;width:40px;border-radius:0 3px 3px 0;outline:0}.factory-bootstrap-421 .factory-mtextbox-item .factory-mtextbox-remove-item:focus,.factory-bootstrap-421 .factory-mtextbox-item .factory-mtextbox-remove-item:hover{box-shadow:none;outline:0}.factory-bootstrap-421 .factory-mtextbox-add-item{display:block;margin-top:10px}
libs/factory/bootstrap/assets/css-min/holder.more-link.min.css CHANGED
@@ -8,4 +8,4 @@
8
  */
9
 
10
 
11
- .factory-bootstrap-400 .factory-more-link-content{border-top:1px dashed #DDD;padding-top:25px;width:100%;padding-right:20px;position:relative}.factory-bootstrap-400 .factory-tab .factory-more-link-show{display:inline-block;text-decoration:none;border-bottom:1px dotted #21759b;position:relative}.factory-bootstrap-400 .factory-tab .factory-more-link-show:hover{border-color:#d54e21}.factory-bootstrap-400 .factory-tab .factory-more-link-hide{position:absolute;margin-top:-35px;background-color:#fff;padding:0 5px;right:20px;color:#bbb;text-decoration:none}.factory-bootstrap-400 .factory-tab .factory-more-link-hide:hover{color:#999}
8
  */
9
 
10
 
11
+ .factory-bootstrap-421 .factory-more-link-content{border-top:1px dashed #DDD;padding-top:25px;width:100%;padding-right:20px;position:relative}.factory-bootstrap-421 .factory-tab .factory-more-link-show{display:inline-block;text-decoration:none;border-bottom:1px dotted #21759b;position:relative}.factory-bootstrap-421 .factory-tab .factory-more-link-show:hover{border-color:#d54e21}.factory-bootstrap-421 .factory-tab .factory-more-link-hide{position:absolute;margin-top:-35px;background-color:#fff;padding:0 5px;right:20px;color:#bbb;text-decoration:none}.factory-bootstrap-421 .factory-tab .factory-more-link-hide:hover{color:#999}
libs/factory/bootstrap/assets/js-min/bootstrap.dropdown.min.js CHANGED
@@ -7,4 +7,4 @@
7
  * Support: http://webcraftic.com/contact-us/
8
  */
9
 
10
- +function(a){"use strict";function b(){a(d).remove(),a(e).each(function(b){var d=c(a(this));d.hasClass("open")&&(d.trigger(b=a.Event("hide.bs.dropdown")),b.isDefaultPrevented()||d.removeClass("open").trigger("hidden.bs.dropdown"))})}function c(b){var c=b.attr("data-target");c||(c=b.attr("href"),c=c&&/#/.test(c)&&c.replace(/.*(?=#[^\s]*$)/,""));var d=c&&a(c);return d&&d.length?d:b.parent()}var d=".dropdown-backdrop",e="[data-toggle=factory-dropdown]",f=function(b){a(b).on("click.bs.dropdown",this.toggle)};f.prototype.toggle=function(d){var e=a(this);if(!e.is(".disabled, :disabled")){var f=c(e),g=f.hasClass("open");if(b(),!g){if("ontouchstart"in document.documentElement&&!f.closest(".navbar-nav").length&&a('<div class="dropdown-backdrop"/>').insertAfter(a(this)).on("click",b),f.trigger(d=a.Event("show.bs.dropdown")),d.isDefaultPrevented())return;f.toggleClass("open").trigger("shown.bs.dropdown"),e.focus()}return!1}},f.prototype.keydown=function(b){if(/(38|40|27)/.test(b.keyCode)){var d=a(this);if(b.preventDefault(),b.stopPropagation(),!d.is(".disabled, :disabled")){var f=c(d),g=f.hasClass("open");if(!g||g&&27==b.keyCode)return 27==b.which&&f.find(e).focus(),d.click();var h=a("[role=menu] li:not(.divider):visible a",f);if(h.length){var i=h.index(h.filter(":focus"));38==b.keyCode&&i>0&&i--,40==b.keyCode&&i<h.length-1&&i++,~i||(i=0),h.eq(i).focus()}}}},a.fn.factoryBootstrap400_dropdown=function(b){return this.each(function(){var c=a(this),d=c.data("bs.dropdown");d||c.data("bs.dropdown",d=new f(this)),"string"==typeof b&&d[b].call(c)})},a.fn.factoryBootstrap400_dropdown.Constructor=f,a(document).on("click.bs.dropdown.data-api",b).on("click.bs.dropdown.data-api",".dropdown form",function(a){a.stopPropagation()}).on("click.bs.dropdown.data-api",e,f.prototype.toggle).on("keydown.bs.dropdown.data-api",e+", [role=menu]",f.prototype.keydown)}(jQuery);
7
  * Support: http://webcraftic.com/contact-us/
8
  */
9
 
10
+ +function(a){"use strict";function b(){a(d).remove(),a(e).each(function(b){var d=c(a(this));d.hasClass("open")&&(d.trigger(b=a.Event("hide.bs.dropdown")),b.isDefaultPrevented()||d.removeClass("open").trigger("hidden.bs.dropdown"))})}function c(b){var c=b.attr("data-target");c||(c=b.attr("href"),c=c&&/#/.test(c)&&c.replace(/.*(?=#[^\s]*$)/,""));var d=c&&a(c);return d&&d.length?d:b.parent()}var d=".dropdown-backdrop",e="[data-toggle=factory-dropdown]",f=function(b){a(b).on("click.bs.dropdown",this.toggle)};f.prototype.toggle=function(d){var e=a(this);if(!e.is(".disabled, :disabled")){var f=c(e),g=f.hasClass("open");if(b(),!g){if("ontouchstart"in document.documentElement&&!f.closest(".navbar-nav").length&&a('<div class="dropdown-backdrop"/>').insertAfter(a(this)).on("click",b),f.trigger(d=a.Event("show.bs.dropdown")),d.isDefaultPrevented())return;f.toggleClass("open").trigger("shown.bs.dropdown"),e.focus()}return!1}},f.prototype.keydown=function(b){if(/(38|40|27)/.test(b.keyCode)){var d=a(this);if(b.preventDefault(),b.stopPropagation(),!d.is(".disabled, :disabled")){var f=c(d),g=f.hasClass("open");if(!g||g&&27==b.keyCode)return 27==b.which&&f.find(e).focus(),d.click();var h=a("[role=menu] li:not(.divider):visible a",f);if(h.length){var i=h.index(h.filter(":focus"));38==b.keyCode&&i>0&&i--,40==b.keyCode&&i<h.length-1&&i++,~i||(i=0),h.eq(i).focus()}}}},a.fn.factoryBootstrap421_dropdown=function(b){return this.each(function(){var c=a(this),d=c.data("bs.dropdown");d||c.data("bs.dropdown",d=new f(this)),"string"==typeof b&&d[b].call(c)})},a.fn.factoryBootstrap421_dropdown.Constructor=f,a(document).on("click.bs.dropdown.data-api",b).on("click.bs.dropdown.data-api",".dropdown form",function(a){a.stopPropagation()}).on("click.bs.dropdown.data-api",e,f.prototype.toggle).on("keydown.bs.dropdown.data-api",e+", [role=menu]",f.prototype.keydown)}(jQuery);
libs/factory/bootstrap/assets/js-min/control.checkbox.min.js CHANGED
@@ -7,4 +7,4 @@
7
  * Support: http://webcraftic.com/contact-us/
8
  */
9
 
10
- !function(a){var b=function(b){var c=this;this.$element=a(b),this.$result=this.$element.find(".factory-result"),this.$on=this.$element.find(".factory-on"),this.$off=this.$element.find(".factory-off");var d=this.$element.is(".factory-tumbler"),e=this.$element.is(".factory-has-tumbler-hint"),f=this.$element.data("tumbler-function"),g=this.$element.data("tumbler-delay");g||(g=3e3),this.callByPath=function(a,b){for(var c=a.split("."),d=window,e=0;e<c.length;e++)d=d[c[e]];d.apply(d,b)},this.$on.click(function(){return c.$off.removeClass("active"),c.$on.addClass("active"),d?setTimeout(function(){c.$on.removeClass("active"),c.$off.addClass("active");var a=e?c.$element.next():null;f?c.callByPath(f,[c.$element,a]):e&&(c.$element.next().fadeIn(300),setTimeout(function(){c.$element.next().fadeOut(500)},g))},300):(c.$result.attr("checked","checked"),c.$result.val(1),c.$result.trigger("change")),!1}),this.$off.click(function(){return c.$on.removeClass("active"),c.$off.addClass("active"),d?setTimeout(function(){c.$off.removeClass("active"),c.$on.addClass("active");var a=e?c.$element.next():null;f?c.callByPath(f,[c.$element,a]):e&&(c.$element.next().fadeIn(300),setTimeout(function(){c.$element.next().fadeOut(500)},g))},300):(c.$result.removeAttr("checked"),c.$result.val(0),c.$result.trigger("change")),!1}),this.hashCode=function(a){var b=0;if(!a||0===a.length)return b;for(var c=0;c<a.length;c++){var d=a.charCodeAt(c);b=(b<<5)-b+d,b&=b}return b=b.toString(16),b=b.replace("-","")},this.executeEvents=function(a){(void 0!==window.__factory_checkbox_control_events_off_data||void 0!==window.__factory_checkbox_control_events_on_data)&&(a.change(function(){c.eventsProcess(a)}),c.eventsProcess(a))},this.eventsProcess=function(b){var d=b.attr("name"),e=b.prop("checked"),f=window.__factory_checkbox_control_events_on_data[d],g=window.__factory_checkbox_control_events_off_data[d];if(f||g){var h,i;void 0===window.__factory_checkbox_control_detach_elements&&(window.__factory_checkbox_control_detach_elements={}),h=window.__factory_checkbox_control_detach_elements,i=e?f:g;for(var j in i)if(i.hasOwnProperty(j)){var k,l=i[j];a.isArray(l)||(k=c.hashCode(d+l));var m;switch(j){case"hide":"string"==typeof l&&a(l).hide(0);break;case"show":"string"==typeof l&&a(l).fadeIn(200);break;case"detach":"string"==typeof l&&a(l).each(function(b){h[k]||(h[k]={}),h[k][b]||(h[k][b]={}),h[k][b].recovery_contanier=a(this).parent(),h[k][b].element=a(this).clone(!0),a(this).remove()});break;case"recovery":if(h[k]){for(var n in h[k])h[k].hasOwnProperty(n)&&h[k][n].recovery_contanier&&h[k][n].element&&h[k][n].recovery_contanier.append(h[k][n].element);delete h[k]}break;case"removeClasses":if("object"==typeof l)for(m in l)l.hasOwnProperty(m)&&l[m]&&a(m).removeClass(l[m]);break;case"addClasses":if("object"==typeof l)for(m in l)l.hasOwnProperty(m)&&l[m]&&a(m).addClass(l[m]);break;case"setValue":if("object"==typeof l)for(m in l)l.hasOwnProperty(m)&&void 0!==l[m]&&null!==l[m]&&(console.log(l[m]),a(m).val(l[m]))}}}},this.executeEvents(this.$result)};a.fn.factoryBootstrap400_checkboxControl=function(c){if("string"==typeof c){var d=a(this).data("factory.checkbox.control");return d?d[c]():null}return this.each(function(){var c=a(this),d=c.data("factory.checkbox.control");d||c.data("factory.checkbox.control",d=new b(this))})},a.fn.factoryBootstrap400_checkboxControl.Constructor=b,a(function(){a(".factory-bootstrap-400 .factory-checkbox.factory-buttons-way").factoryBootstrap400_checkboxControl()})}(jQuery);
7
  * Support: http://webcraftic.com/contact-us/
8
  */
9
 
10
+ !function(a){var b=function(b){var c=this;this.$element=a(b),this.$result=this.$element.find(".factory-result"),this.$on=this.$element.find(".factory-on"),this.$off=this.$element.find(".factory-off");var d=this.$element.is(".factory-tumbler"),e=this.$element.is(".factory-has-tumbler-hint"),f=this.$element.data("tumbler-function"),g=this.$element.data("tumbler-delay");g||(g=3e3),this.callByPath=function(a,b){for(var c=a.split("."),d=window,e=0;e<c.length;e++)d=d[c[e]];d.apply(d,b)},this.$on.click(function(){return c.$off.removeClass("active"),c.$on.addClass("active"),d?setTimeout(function(){c.$on.removeClass("active"),c.$off.addClass("active");var a=e?c.$element.next():null;f?c.callByPath(f,[c.$element,a]):e&&(c.$element.next().fadeIn(300),setTimeout(function(){c.$element.next().fadeOut(500)},g))},300):(c.$result.attr("checked","checked"),c.$result.val(1),c.$result.trigger("change")),!1}),this.$off.click(function(){return c.$on.removeClass("active"),c.$off.addClass("active"),d?setTimeout(function(){c.$off.removeClass("active"),c.$on.addClass("active");var a=e?c.$element.next():null;f?c.callByPath(f,[c.$element,a]):e&&(c.$element.next().fadeIn(300),setTimeout(function(){c.$element.next().fadeOut(500)},g))},300):(c.$result.removeAttr("checked"),c.$result.val(0),c.$result.trigger("change")),!1}),this.hashCode=function(a){var b=0;if(!a||0===a.length)return b;for(var c=0;c<a.length;c++){var d=a.charCodeAt(c);b=(b<<5)-b+d,b&=b}return b=b.toString(16),b=b.replace("-","")},this.executeEvents=function(a){(void 0!==window.__factory_checkbox_control_events_off_data||void 0!==window.__factory_checkbox_control_events_on_data)&&(a.change(function(){c.eventsProcess(a)}),c.eventsProcess(a))},this.eventsProcess=function(b){var d=b.attr("name"),e=b.prop("checked"),f=window.__factory_checkbox_control_events_on_data[d],g=window.__factory_checkbox_control_events_off_data[d];if(f||g){var h,i;void 0===window.__factory_checkbox_control_detach_elements&&(window.__factory_checkbox_control_detach_elements={}),h=window.__factory_checkbox_control_detach_elements,i=e?f:g;for(var j in i)if(i.hasOwnProperty(j)){var k,l=i[j];a.isArray(l)||(k=c.hashCode(d+l));var m;switch(j){case"hide":"string"==typeof l&&a(l).hide(0);break;case"show":"string"==typeof l&&a(l).fadeIn(200);break;case"detach":"string"==typeof l&&a(l).each(function(b){h[k]||(h[k]={}),h[k][b]||(h[k][b]={}),h[k][b].recovery_contanier=a(this).parent(),h[k][b].element=a(this).clone(!0),a(this).remove()});break;case"recovery":if(h[k]){for(var n in h[k])h[k].hasOwnProperty(n)&&h[k][n].recovery_contanier&&h[k][n].element&&h[k][n].recovery_contanier.append(h[k][n].element);delete h[k]}break;case"removeClasses":if("object"==typeof l)for(m in l)l.hasOwnProperty(m)&&l[m]&&a(m).removeClass(l[m]);break;case"addClasses":if("object"==typeof l)for(m in l)l.hasOwnProperty(m)&&l[m]&&a(m).addClass(l[m]);break;case"setValue":if("object"==typeof l)for(m in l)l.hasOwnProperty(m)&&void 0!==l[m]&&null!==l[m]&&(console.log(l[m]),a(m).val(l[m]))}}}},this.executeEvents(this.$result)};a.fn.factoryBootstrap421_checkboxControl=function(c){if("string"==typeof c){var d=a(this).data("factory.checkbox.control");return d?d[c]():null}return this.each(function(){var c=a(this),d=c.data("factory.checkbox.control");d||c.data("factory.checkbox.control",d=new b(this))})},a.fn.factoryBootstrap421_checkboxControl.Constructor=b,a(function(){a(".factory-bootstrap-421 .factory-checkbox.factory-buttons-way").factoryBootstrap421_checkboxControl()})}(jQuery);
libs/factory/bootstrap/assets/js-min/control.dropdown.min.js CHANGED
@@ -7,4 +7,4 @@
7
  * Support: http://webcraftic.com/contact-us/
8
  */
9
 
10
- !function(a){var b=function(b){var c=this;if(this.$element=a(b),this.way=this.$element.data("way"),this.name=this.$element.data("name")||this.$element.attr("name"),this.hashCode=function(a){var b=0;if(!a||0===a.length)return b;for(var c=0;c<a.length;c++){var d=a.charCodeAt(c);b=(b<<5)-b+d,b&=b}return b=b.toString(16),b=b.replace("-","")},this.executeEvents=function(a){void 0!==window.factory_dropdown_control_events_data&&(a.change(function(){c.eventsProcess(a)}),c.eventsProcess(a))},this.eventsProcess=function(b){var d=b.attr("name"),e=b.val(),f=window.factory_dropdown_control_events_data[d];if(f&&f[e]){var g;void 0===window.__factory_dropdown_control_detach_elements&&(window.__factory_dropdown_control_detach_elements={}),g=window.__factory_dropdown_control_detach_elements;for(var h in f[e])if(f[e].hasOwnProperty(h)){var i,j=f[e][h];switch(a.isArray(j)||(i=c.hashCode(d+j)),h){case"hide":"string"==typeof j&&a(j).hide(0);break;case"show":"string"==typeof j&&a(j).fadeIn(200);break;case"detach":"string"==typeof j&&a(j).each(function(b){g[i]||(g[i]={}),g[i][b]||(g[i][b]={}),g[i][b].recovery_contanier=a(this).parent(),g[i][b].element=a(this).clone(!0),a(this).remove()});break;case"recovery":if(g[i]){for(var k in g[i])g[i].hasOwnProperty(k)&&g[i][k].recovery_contanier&&g[i][k].element&&g[i][k].recovery_contanier.append(g[i][k].element);delete g[i]}break;case"removeClasses":if("object"==typeof j)for(var l in j)j.hasOwnProperty(l)&&j[l]&&a(l).removeClass(j[l]);break;case"addClasses":if("object"==typeof j)for(var l in j)j.hasOwnProperty(l)&&j[l]&&a(l).addClass(j[l])}}}},"buttons"===this.way)this.$result=this.$element.find(".factory-result"),this.$hints=this.$element.find(".factory-hints"),this.$buttons=this.$element.find(".btn"),c.executeEvents(this.$result),this.$buttons.click(function(){var b=a(this).data("value");return c.$buttons.removeClass("active"),a(this).addClass("active"),c.$hints.find(".factory-hint").hide(),c.$hints.find(".factory-hint-"+b).fadeIn(),c.$result.val(b),c.$result.trigger("change"),!1});else if("ddslick"===this.way){c.executeEvents(c.$element.find(".factory-result"));var d=window["factory_"+this.name+"_data"],e=this.$element.find(".factory-ddslick"),f=this.$element.data("width")||300,g=this.$element.data("align")||"right";a(d).each(function(){return this.imageHoverSrc?void(a("<img/>")[0].src=this.imageHoverSrc):!0}),e.ddslick({data:d,width:f,imagePosition:g,selectText:"- select -",onSelected:function(a){a.selectedData.imageHoverSrc&&c.$element.find(".dd-selected-image").attr("src",a.selectedData.imageHoverSrc);var b=c.$element.find(".factory-result").val(a.selectedData.value);b.change()}})}else{c.executeEvents(this.$element),this.$hints=this.$element.next(),this.$hints.hasClass("factory-hints")&&(this.$element.change(function(){return c.updateHints(),!1}),this.updateHints=function(){var a=c.$element.val();c.$hints.find(".factory-hint").hide(),c.$hints.find(".factory-hint-"+a).show()},c.updateHints()),this.getAjaxData=function(){var a=c.$element.data("ajax-data-id");return window[a]},this.loadData=function(){var b=c.getAjaxData();a.ajax({url:b.url,data:b.data,dataType:"json",success:function(a){return a.error?c.showError(a.error):void c.fill(a.items)},error:function(a){console&&console.log&&console.log(a.responseText),c.showError("Unexpected error occurred during the ajax request.")},complete:function(){c.removeLoader()}})},this.fill=function(a){this.clearList();var b=c.getAjaxData();if(a&&a.length)for(var d in a){var e=a[d];c.addListItem(e)}else this.$element.append("<option>"+b.emptyList+"</li>");this.$element.trigger("factory-loaded")},this.clearList=function(){this.$element.html("")},this.addListItem=function(b){var d=a("<option />").attr("value",b.value).text(b.title).appendTo(this.$element),e=c.getAjaxData();e.selected&&e.selected==b.value&&d.attr("selected","selected")},this.showError=function(b){this.clearList();var d=a("<div class='factory-control-error'></div>").append(a("<i class='fa fa-exclamation-triangle'></i>")).append(b),e=c.getAjaxData();this.$element.append("<option>"+e.emptyList+"</li>"),this.$element.after(d),this.$element.addClass("factory-has-error")},this.removeLoader=function(){this.$element.removeClass("factory-hidden");var b=c.getAjaxData();a(b.loader).remove()};var h=this.$element.data("ajax");h&&this.loadData()}};a.fn.factoryBootstrap400_dropdownControl=function(c){if("string"==typeof c){var d=a(this).data("factory.dropdown.control");return d?d[c]():null}return this.each(function(){var c=a(this),d=c.data("factory.dropdown.control");d||c.data("factory.dropdown.control",d=new b(this))})},a.fn.factoryBootstrap400_dropdownControl.Constructor=b,a(function(){a(".factory-bootstrap-400 .factory-dropdown").factoryBootstrap400_dropdownControl()})}(jQuery);
7
  * Support: http://webcraftic.com/contact-us/
8
  */
9
 
10
+ !function(a){var b=function(b){var c=this;if(this.$element=a(b),this.way=this.$element.data("way"),this.name=this.$element.data("name")||this.$element.attr("name"),this.hashCode=function(a){var b=0;if(!a||0===a.length)return b;for(var c=0;c<a.length;c++){var d=a.charCodeAt(c);b=(b<<5)-b+d,b&=b}return b=b.toString(16),b=b.replace("-","")},this.executeEvents=function(a){void 0!==window.factory_dropdown_control_events_data&&(a.change(function(){c.eventsProcess(a)}),c.eventsProcess(a))},this.eventsProcess=function(b){var d=b.attr("name"),e=b.val(),f=window.factory_dropdown_control_events_data[d];if(f&&f[e]){var g;void 0===window.__factory_dropdown_control_detach_elements&&(window.__factory_dropdown_control_detach_elements={}),g=window.__factory_dropdown_control_detach_elements;for(var h in f[e])if(f[e].hasOwnProperty(h)){var i,j=f[e][h];switch(a.isArray(j)||(i=c.hashCode(d+j)),h){case"hide":"string"==typeof j&&a(j).hide(0);break;case"show":"string"==typeof j&&a(j).fadeIn(200);break;case"detach":"string"==typeof j&&a(j).each(function(b){g[i]||(g[i]={}),g[i][b]||(g[i][b]={}),g[i][b].recovery_contanier=a(this).parent(),g[i][b].element=a(this).clone(!0),a(this).remove()});break;case"recovery":if(g[i]){for(var k in g[i])g[i].hasOwnProperty(k)&&g[i][k].recovery_contanier&&g[i][k].element&&g[i][k].recovery_contanier.append(g[i][k].element);delete g[i]}break;case"removeClasses":if("object"==typeof j)for(var l in j)j.hasOwnProperty(l)&&j[l]&&a(l).removeClass(j[l]);break;case"addClasses":if("object"==typeof j)for(var l in j)j.hasOwnProperty(l)&&j[l]&&a(l).addClass(j[l])}}}},"buttons"===this.way)this.$result=this.$element.find(".factory-result"),this.$hints=this.$element.find(".factory-hints"),this.$buttons=this.$element.find(".btn"),c.executeEvents(this.$result),this.$buttons.click(function(){var b=a(this).data("value");return c.$buttons.removeClass("active"),a(this).addClass("active"),c.$hints.find(".factory-hint").hide(),c.$hints.find(".factory-hint-"+b).fadeIn(),c.$result.val(b),c.$result.trigger("change"),!1});else if("ddslick"===this.way){c.executeEvents(c.$element.find(".factory-result"));var d=window["factory_"+this.name+"_data"],e=this.$element.find(".factory-ddslick"),f=this.$element.data("width")||300,g=this.$element.data("align")||"right";a(d).each(function(){return this.imageHoverSrc?void(a("<img/>")[0].src=this.imageHoverSrc):!0}),e.ddslick({data:d,width:f,imagePosition:g,selectText:"- select -",onSelected:function(a){a.selectedData.imageHoverSrc&&c.$element.find(".dd-selected-image").attr("src",a.selectedData.imageHoverSrc);var b=c.$element.find(".factory-result").val(a.selectedData.value);b.change()}})}else{c.executeEvents(this.$element),this.$hints=this.$element.next(),this.$hints.hasClass("factory-hints")&&(this.$element.change(function(){return c.updateHints(),!1}),this.updateHints=function(){var a=c.$element.val();c.$hints.find(".factory-hint").hide(),c.$hints.find(".factory-hint-"+a).show()},c.updateHints()),this.getAjaxData=function(){var a=c.$element.data("ajax-data-id");return window[a]},this.loadData=function(){var b=c.getAjaxData();a.ajax({url:b.url,data:b.data,dataType:"json",success:function(a){return a.error?c.showError(a.error):void c.fill(a.items)},error:function(a){console&&console.log&&console.log(a.responseText),c.showError("Unexpected error occurred during the ajax request.")},complete:function(){c.removeLoader()}})},this.fill=function(a){this.clearList();var b=c.getAjaxData();if(a&&a.length)for(var d in a){var e=a[d];c.addListItem(e)}else this.$element.append("<option>"+b.emptyList+"</li>");this.$element.trigger("factory-loaded")},this.clearList=function(){this.$element.html("")},this.addListItem=function(b){var d=a("<option />").attr("value",b.value).text(b.title).appendTo(this.$element),e=c.getAjaxData();e.selected&&e.selected==b.value&&d.attr("selected","selected")},this.showError=function(b){this.clearList();var d=a("<div class='factory-control-error'></div>").append(a("<i class='fa fa-exclamation-triangle'></i>")).append(b),e=c.getAjaxData();this.$element.append("<option>"+e.emptyList+"</li>"),this.$element.after(d),this.$element.addClass("factory-has-error")},this.removeLoader=function(){this.$element.removeClass("factory-hidden");var b=c.getAjaxData();a(b.loader).remove()};var h=this.$element.data("ajax");h&&this.loadData()}};a.fn.factoryBootstrap421_dropdownControl=function(c){if("string"==typeof c){var d=a(this).data("factory.dropdown.control");return d?d[c]():null}return this.each(function(){var c=a(this),d=c.data("factory.dropdown.control");d||c.data("factory.dropdown.control",d=new b(this))})},a.fn.factoryBootstrap421_dropdownControl.Constructor=b,a(function(){a(".factory-bootstrap-421 .factory-dropdown").factoryBootstrap421_dropdownControl()})}(jQuery);
libs/factory/bootstrap/assets/js-min/control.list.min.js CHANGED
@@ -7,4 +7,4 @@
7
  * Support: http://webcraftic.com/contact-us/
8
  */
9
 
10
- !function(a){var b=function(b){var c=this;if(this.$element=a(b),this.way=this.$element.data("way"),this.name=this.$element.data("name"),"checklist"===this.way){this.getAjaxData=function(){var a=c.$element.data("ajax-data-id");return window[a]},this.loadData=function(){var b=c.getAjaxData();a.ajax({url:b.url,data:b.data,dataType:"json",success:function(a){return a.error?c.showError(a.error):void c.fill(a.items)},error:function(){c.showError("Unexpected error occurred during the ajax request.")},complete:function(){c.removeLoader()}})},this.fill=function(a){this.clearList();var b=c.getAjaxData();if(a&&a.length){this.$element.removeClass("factory-empty");for(var d in a){var e=a[d];c.addListItem(e)}}else this.$element.addClass("factory-empty"),this.$element.append("<li>"+b.emptyList+"</li>")},this.clearList=function(){this.$element.html("")},this.addListItem=function(b){var d=a("<li>"),e=a("<label>").attr("for","factory-checklist-"+c.name+"-"+b.value).appendTo(d),f=a("<span>").appendTo(e),g=a("<input />").attr("type","checkbox").attr("name",c.name+"[]").val(b.value).attr("id","factory-checklist-"+c.name+"-"+b.value).appendTo(f),h=(a("<span>"+b.title+"</span>").appendTo(e),c.getAjaxData());h.selected.length&&a.inArray(b.value,h.selected)>=0&&g.attr("checked","checked"),this.$element.append(d)},this.showError=function(b){this.$element.html("").append(a("<i class='fa fa-exclamation-triangle'></i>")).append(b),this.$element.addClass("factory-list-error")},this.removeLoader=function(){this.$element.removeClass("factory-hidden");var b=c.getAjaxData();a(b.loader).remove()};var d=this.$element.data("ajax");d&&this.loadData()}};a.fn.factoryBootstrap400_listControl=function(c){if("string"==typeof c){var d=a(this).data("factory.list.control");return d?d[c]():null}return this.each(function(){var c=a(this),d=c.data("factory.list.control");d||c.data("factory.list.control",d=new b(this))})},a.fn.factoryBootstrap400_listControl.Constructor=b,a(function(){a(".factory-bootstrap-400 .factory-list").factoryBootstrap400_listControl()})}(jQuery);
7
  * Support: http://webcraftic.com/contact-us/
8
  */
9
 
10
+ !function(a){var b=function(b){var c=this;if(this.$element=a(b),this.way=this.$element.data("way"),this.name=this.$element.data("name"),"checklist"===this.way){this.getAjaxData=function(){var a=c.$element.data("ajax-data-id");return window[a]},this.loadData=function(){var b=c.getAjaxData();a.ajax({url:b.url,data:b.data,dataType:"json",success:function(a){return a.error?c.showError(a.error):void c.fill(a.items)},error:function(){c.showError("Unexpected error occurred during the ajax request.")},complete:function(){c.removeLoader()}})},this.fill=function(a){this.clearList();var b=c.getAjaxData();if(a&&a.length){this.$element.removeClass("factory-empty");for(var d in a){var e=a[d];c.addListItem(e)}}else this.$element.addClass("factory-empty"),this.$element.append("<li>"+b.emptyList+"</li>")},this.clearList=function(){this.$element.html("")},this.addListItem=function(b){var d=a("<li>"),e=a("<label>").attr("for","factory-checklist-"+c.name+"-"+b.value).appendTo(d),f=a("<span>").appendTo(e),g=a("<input />").attr("type","checkbox").attr("name",c.name+"[]").val(b.value).attr("id","factory-checklist-"+c.name+"-"+b.value).appendTo(f),h=(a("<span>"+b.title+"</span>").appendTo(e),c.getAjaxData());h.selected.length&&a.inArray(b.value,h.selected)>=0&&g.attr("checked","checked"),this.$element.append(d)},this.showError=function(b){this.$element.html("").append(a("<i class='fa fa-exclamation-triangle'></i>")).append(b),this.$element.addClass("factory-list-error")},this.removeLoader=function(){this.$element.removeClass("factory-hidden");var b=c.getAjaxData();a(b.loader).remove()};var d=this.$element.data("ajax");d&&this.loadData()}};a.fn.factoryBootstrap421_listControl=function(c){if("string"==typeof c){var d=a(this).data("factory.list.control");return d?d[c]():null}return this.each(function(){var c=a(this),d=c.data("factory.list.control");d||c.data("factory.list.control",d=new b(this))})},a.fn.factoryBootstrap421_listControl.Constructor=b,a(function(){a(".factory-bootstrap-421 .factory-list").factoryBootstrap421_listControl()})}(jQuery);
libs/factory/bootstrap/assets/js-min/control.multiple-textbox.min.js CHANGED
@@ -7,4 +7,4 @@
7
  * Support: http://webcraftic.com/contact-us/
8
  */
9
 
10
- !function(a){"use strict";var b=function(b){this.$element=a(b);var c=a(".factory-mtextbox-item",this.$element).eq(0).clone(!0);a(".factory-mtextbox-add-item",this.$element).on("click",function(){var b=a(this).closest(".factory-multiple-textbox-group").find(".factory-mtextbox-items"),d=c.clone(!0),e=a('<button class="btn btn-default btn-small factory-mtextbox-remove-item"><i class="fa fa-times" aria-hidden="true"></i></button>');return b.append(d.append(e)),d.find('input[type="text"]').val("").focus(),!1}),a(document).on("click",".factory-mtextbox-remove-item",function(){return a(this).closest(".factory-mtextbox-item").remove(),!1})};a.fn.factoryBootstrap400_MultipleTextboxControl=function(){return this.each(function(){new b(this)})},a(function(){a(".factory-bootstrap-400 .factory-multiple-textbox-group").factoryBootstrap400_MultipleTextboxControl()})}(jQuery);
7
  * Support: http://webcraftic.com/contact-us/
8
  */
9
 
10
+ !function(a){"use strict";var b=function(b){this.$element=a(b);var c=a(".factory-mtextbox-item",this.$element).eq(0).clone(!0);a(".factory-mtextbox-add-item",this.$element).on("click",function(){var b=a(this).closest(".factory-multiple-textbox-group").find(".factory-mtextbox-items"),d=c.clone(!0),e=a('<button class="btn btn-default btn-small factory-mtextbox-remove-item"><i class="fa fa-times" aria-hidden="true"></i></button>');return b.append(d.append(e)),d.find('input[type="text"]').val("").focus(),!1}),a(document).on("click",".factory-mtextbox-remove-item",function(){return a(this).closest(".factory-mtextbox-item").remove(),!1})};a.fn.factoryBootstrap421_MultipleTextboxControl=function(){return this.each(function(){new b(this)})},a(function(){a(".factory-bootstrap-421 .factory-multiple-textbox-group").factoryBootstrap421_MultipleTextboxControl()})}(jQuery);
libs/factory/bootstrap/boot.php CHANGED
@@ -1,37 +1,46 @@
1
  <?php
2
- /**
3
- * Factory Bootstrap
4
- *
5
- * @author Alex Kovalev <alex.kovalevv@gmail.com>
6
- * @copyright (c) 2018, Webcraftic Ltd
7
- *
8
- * @package factory-bootstrap
9
- * @since 1.0.0
10
- */
11
-
12
- // Exit if accessed directly
13
- if( !defined('ABSPATH') ) {
14
- exit;
15
- }
16
-
17
- // module provides function only for the admin area
18
- if( !is_admin() ) {
19
- return;
20
- }
21
-
22
- if( defined('FACTORY_BOOTSTRAP_400_LOADED') ) {
23
- return;
24
- }
25
- define('FACTORY_BOOTSTRAP_400_LOADED', true);
26
-
27
- define('FACTORY_BOOTSTRAP_400_DIR', dirname(__FILE__));
28
- define('FACTORY_BOOTSTRAP_400_URL', plugins_url(null, __FILE__));
29
-
30
- // sets version of admin interface
31
- define('FACTORY_BOOTSTRAP_400_VERSION', 'FACTORY_BOOTSTRAP_400');
32
-
33
- if( !defined('FACTORY_FLAT_ADMIN') ) {
34
- define('FACTORY_FLAT_ADMIN', true);
35
- }
36
-
37
- include_once(FACTORY_BOOTSTRAP_400_DIR . '/includes/functions.php');
 
 
 
 
 
 
 
 
 
1
  <?php
2
+ /**
3
+ * Factory Bootstrap
4
+ *
5
+ * @author Alex Kovalev <alex.kovalevv@gmail.com>
6
+ * @since 1.0.0
7
+ * @package factory-bootstrap
8
+ * @copyright (c) 2018, Webcraftic Ltd
9
+ *
10
+ */
11
+
12
+ // Exit if accessed directly
13
+ if ( ! defined( 'ABSPATH' ) ) {
14
+ exit;
15
+ }
16
+
17
+ // module provides function only for the admin area
18
+ if ( ! is_admin() ) {
19
+ return;
20
+ }
21
+
22
+ if ( defined( 'FACTORY_BOOTSTRAP_421_LOADED' ) ) {
23
+ return;
24
+ }
25
+
26
+ define( 'FACTORY_BOOTSTRAP_421_VERSION', '4.2.1' );
27
+ define( 'FACTORY_BOOTSTRAP_421_LOADED', true );
28
+
29
+ if ( ! defined( 'FACTORY_FLAT_ADMIN' ) ) {
30
+ define( 'FACTORY_FLAT_ADMIN', true );
31
+ }
32
+
33
+ define( 'FACTORY_BOOTSTRAP_421_DIR', dirname( __FILE__ ) );
34
+ define( 'FACTORY_BOOTSTRAP_421_URL', plugins_url( null, __FILE__ ) );
35
+
36
+ require_once( FACTORY_BOOTSTRAP_421_DIR . '/includes/functions.php' );
37
+
38
+ /**
39
+ * @param Wbcr_Factory420_Plugin $plugin
40
+ */
41
+ add_action( 'wbcr_factory_bootstrap_421_plugin_created', function ( $plugin ) {
42
+ $manager = new Wbcr_FactoryBootstrap421_Manager( $plugin );
43
+ $plugin->setBootstap( $manager );
44
+ } );
45
+
46
+
libs/factory/bootstrap/includes/functions.php CHANGED
@@ -1,292 +1,286 @@
1
  <?php
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2
  /**
3
- * This file manages assets of the Factory Bootstap.
4
  *
5
- * @author Alex Kovalev <alex@byonepress.com>
6
- * @author Paul Kashtanoff <paul@byonepress.com>
7
- * @copyright (c) 2018, OnePress Ltd
 
 
 
 
8
  *
9
- * @package factory-bootstrap
10
- * @since 1.0.0
11
  */
12
-
13
- add_action('wbcr_factory_bootstrap_400_plugin_created', 'wbcr_factory_bootstrap_400_plugin_created');
14
-
 
 
 
 
 
 
 
15
  /**
16
- * @param Wbcr_Factory400_Plugin $plugin
 
 
17
  */
18
- function wbcr_factory_bootstrap_400_plugin_created($plugin)
19
- {
20
- $manager = new Wbcr_FactoryBootstrap400_Manager($plugin);
21
- $plugin->setBootstap($manager);
 
22
  }
23
-
24
- if( !class_exists('Wbcr_FactoryBootstrap400_Manager') ) {
25
-
26
- /**
27
- * The Bootstrap Manager class.
28
- *
29
- * @since 3.2.0
30
- */
31
- class Wbcr_FactoryBootstrap400_Manager {
32
-
33
- /**
34
- * A plugin for which the manager was created.
35
- *
36
- * @since 3.2.0
37
- * @var Wbcr_Factory400_Plugin
38
- */
39
- public $plugin;
40
-
41
- /**
42
- * Contains scripts to include.
43
- *
44
- * @since 3.2.0
45
- * @var string[]
46
- */
47
- public $scripts = array();
48
-
49
- /**
50
- * Contains styles to include.
51
- *
52
- * @since 3.2.0
53
- * @var string[]
54
- */
55
- public $styles = array();
56
-
57
- /**
58
- * Createas a new instance of the license api for a given plugin.
59
- *
60
- * @since 1.0.0
61
- */
62
- public function __construct(Wbcr_Factory400_Plugin $plugin)
63
- {
64
- $this->plugin = $plugin;
65
-
66
- add_action('admin_enqueue_scripts', array($this, 'loadAssets'));
67
- add_filter('admin_body_class', array($this, 'adminBodyClass'));
68
- }
69
-
70
- /**
71
- * Includes the Bootstrap scripts.
72
- * @since 3.2.0
73
- * @param array|string $scripts
74
- */
75
- public function enqueueScript($scripts)
76
- {
77
- if( is_array($scripts) ) {
78
- foreach($scripts as $script) {
79
- if( !in_array($script, $this->scripts) ) {
80
- $this->scripts[] = $script;
81
- }
82
- }
83
- } else {
84
- if( !in_array($scripts, $this->scripts) ) {
85
- $this->scripts[] = $scripts;
86
- }
87
  }
88
  }
89
-
90
- /**
91
- * * Includes the Bootstrap styles.
92
- *
93
- * @since 3.2.0
94
- * @param array|string $styles
95
- */
96
- public function enqueueStyle($styles)
97
- {
98
-
99
- if( is_array($styles) ) {
100
- foreach($styles as $style) {
101
- if( !in_array($style, $this->styles) ) {
102
- $this->styles[] = $style;
103
- }
104
- }
105
- } else {
106
- if( !in_array($styles, $this->styles) ) {
107
- $this->styles[] = $styles;
108
- }
109
  }
110
  }
111
-
112
- /**
113
- * Loads Bootstrap assets.
114
- *
115
- * @see admin_enqueue_scripts
116
- *
117
- * @since 3.2.0
118
- * @return void
119
- */
120
- public function loadAssets($hook)
121
- {
122
-
123
- do_action('wbcr_factory_400_bootstrap_enqueue_scripts', $hook);
124
- do_action('wbcr_factory_400_bootstrap_enqueue_scripts_' . $this->plugin->getPluginName(), $hook);
 
 
 
 
 
125
 
126
- $dependencies = array();
127
- if( !empty($this->scripts) ) {
128
- $dependencies[] = 'jquery';
129
- $dependencies[] = 'jquery-ui-core';
 
 
 
 
 
 
130
  $dependencies[] = 'jquery-ui-widget';
131
- }
132
-
133
- foreach($this->scripts as $script) {
134
- switch( $script ) {
135
- case 'plugin.iris':
136
- $dependencies[] = 'jquery-ui-widget';
137
- $dependencies[] = 'jquery-ui-slider';
138
- $dependencies[] = 'jquery-ui-draggable';
139
- break;
140
- }
141
- }
142
 
143
- if( !empty($this->scripts) ) {
144
- $this->enqueueScripts($this->scripts, 'js', $dependencies);
145
- }
146
- if( !empty($this->styles) ) {
147
- $this->enqueueScripts($this->styles, 'css', $dependencies);
148
- }
149
 
150
- $user_id = get_current_user_id();
151
- $color_name = get_user_meta($user_id, 'admin_color', true);
152
-
153
- if( $color_name !== 'fresh' ) {
154
- if( file_exists(FACTORY_BOOTSTRAP_400_DIR . '/assets/flat/css/bootstrap.' . $color_name . '.css') ) {
155
- wp_enqueue_style('wbcr-factory-bootstrap-400-colors', FACTORY_BOOTSTRAP_400_URL . '/assets/flat/css/bootstrap.' . $color_name . '.css');
156
- }
157
- }
158
-
159
- if( $color_name == 'light' ) {
160
- $primary_dark = '#037c9a';
161
- $primary_light = '#04a4cc';
162
- } elseif( $color_name == 'blue' ) {
163
- $primary_dark = '#d39323';
164
- $primary_light = '#e1a948';
165
- } elseif( $color_name == 'coffee' ) {
166
- $primary_dark = '#b78a66';
167
- $primary_light = '#c7a589';
168
- } elseif( $color_name == 'ectoplasm' ) {
169
- $primary_dark = '#839237';
170
- $primary_light = '#a3b745';
171
- } elseif( $color_name == 'ocean' ) {
172
- $primary_dark = '#80a583';
173
- $primary_light = '#9ebaa0';
174
- } elseif( $color_name == 'midnight' ) {
175
- $primary_dark = '#d02a21';
176
- $primary_light = '#e14d43';
177
- } elseif( $color_name == 'sunrise' ) {
178
- $primary_dark = '#c36822';
179
- $primary_light = '#dd823b';
180
- } else {
181
- $primary_dark = '#0074a2';
182
- $primary_light = '#2ea2cc';
183
- }
184
-
185
- ?>
186
-
187
- <script>
188
- if( !window.factory ) {
189
- window.factory = {};
190
- }
191
- if( !window.factory.factoryBootstrap400 ) {
192
- window.factory.factoryBootstrap400 = {};
193
- }
194
- window.factory.factoryBootstrap400.colors = {
195
- primaryDark: '<?php echo $primary_dark ?>',
196
- primaryLight: '<?php echo $primary_light ?>'
197
- };
198
- </script>
199
- <?php
200
  }
 
201
 
202
- /**
203
- * @param array $sripts
204
- * @param string $type
205
- * @param array $dependencies
206
- */
207
- protected function enqueueScripts(array $sripts, $type = 'js', array $dependencies)
208
- {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
209
 
210
- $is_first = true;
211
- $cache_id = md5(implode(',', $this->scripts) . $type . $this->plugin->getPluginVersion());
212
- $cache_dir_path = FACTORY_BOOTSTRAP_400_DIR . '/assets/cache/';
213
- $cache_dir_url = FACTORY_BOOTSTRAP_400_URL . '/assets/cache/';
 
 
214
 
215
- $cache_filepath = $cache_dir_path . $cache_id . ".min." . $type;
216
- $cache_fileurl = $cache_dir_url . $cache_id . ".min." . $type;
217
 
218
- if( file_exists($cache_filepath) ) {
219
- if( $type == 'js' ) {
220
- wp_enqueue_script('wbcr-factory-bootstrap-' . $cache_id, $cache_fileurl, $dependencies, $this->plugin->getPluginVersion());
221
- } else {
222
- wp_enqueue_style('wbcr-factory-bootstrap-' . $cache_id, $cache_fileurl, array(), $this->plugin->getPluginVersion());
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
223
  }
224
  } else {
225
- $cache_dir_exists = false;
226
- if( !file_exists($cache_dir_path) ) {
227
- if( @mkdir($cache_dir_path, 0777) && is_writable($cache_dir_path) ) {
228
- $cache_dir_exists = true;
229
- }
230
  } else {
231
- if( is_writable($cache_dir_path) ) {
232
- $cache_dir_exists = true;
233
- }
234
- }
235
-
236
- $concat_files = array();
237
- foreach($sripts as $script_to_load) {
238
- $script_to_load = sanitize_text_field($script_to_load);
239
- if( $cache_dir_exists ) {
240
- $fname = FACTORY_BOOTSTRAP_400_DIR . "/assets/$type-min/$script_to_load.min." . $type;
241
- if( file_exists($fname) ) {
242
- $f = @fopen($fname, 'r');
243
- $concat_files[] = @fread($f, filesize($fname));
244
- @fclose($f);
245
- }
246
- } else {
247
- if( $type == 'js' ) {
248
- wp_enqueue_script(md5($script_to_load), FACTORY_BOOTSTRAP_400_URL . "/assets/$type-min/$script_to_load.min." . $type, $is_first
249
- ? $dependencies
250
- : false, $this->plugin->getPluginVersion());
251
- } else {
252
- wp_enqueue_style(md5($script_to_load), FACTORY_BOOTSTRAP_400_URL . "/assets/$type-min/$script_to_load.min." . $type, array(), $this->plugin->getPluginVersion());
253
- }
254
- $is_first = false;
255
- }
256
  }
 
 
 
257
 
258
- if( $cache_dir_exists && !empty($concat_files) ) {
259
 
260
- $cf = @fopen($cache_filepath, 'w');
261
- $write_content = implode(PHP_EOL, $concat_files);
262
- @fwrite($cf, $write_content);
263
- @fclose($cf);
 
264
 
265
- if( file_exists($cache_filepath) ) {
266
- if( $type == 'js' ) {
267
- wp_enqueue_script('wbcr-factory-bootstrap-' . $cache_id, $cache_fileurl, $dependencies, $this->plugin->getPluginVersion());
268
- } else {
269
- wp_enqueue_style('wbcr-factory-bootstrap-' . $cache_id, $cache_fileurl, array(), $this->plugin->getPluginVersion());
270
- }
271
- }
272
  }
273
  }
274
  }
 
 
275
 
276
- /**
277
- * Adds the body classes: 'factory-flat or 'factory-volumetric'.
278
- *
279
- * @since 3.2.0
280
- * @param string $classes
281
- * @return string
282
- */
283
- public function adminBodyClass($classes)
284
- {
285
- $classes .= FACTORY_FLAT_ADMIN
286
- ? ' factory-flat '
287
- : ' factory-volumetric ';
288
 
289
- return $classes;
290
- }
291
- }
292
- }
1
  <?php
2
+ /**
3
+ * This file manages assets of the Factory Bootstap.
4
+ *
5
+ * @author Alex Kovalev <alex@byonepress.com>
6
+ * @author Paul Kashtanoff <paul@byonepress.com>
7
+ * @since 1.0.0
8
+ * @package factory-bootstrap
9
+ * @copyright (c) 2018, OnePress Ltd
10
+ *
11
+ */
12
+
13
+ // Exit if accessed directly
14
+ if ( ! defined( 'ABSPATH' ) ) {
15
+ exit;
16
+ }
17
+
18
+ /**
19
+ * The Bootstrap Manager class.
20
+ *
21
+ * @since 3.2.0
22
+ */
23
+ class Wbcr_FactoryBootstrap421_Manager {
24
+
25
  /**
26
+ * A plugin for which the manager was created.
27
  *
28
+ * @since 3.2.0
29
+ * @var Wbcr_Factory420_Plugin
30
+ */
31
+ public $plugin;
32
+
33
+ /**
34
+ * Contains scripts to include.
35
  *
36
+ * @since 3.2.0
37
+ * @var string[]
38
  */
39
+ public $scripts = [];
40
+
41
+ /**
42
+ * Contains styles to include.
43
+ *
44
+ * @since 3.2.0
45
+ * @var string[]
46
+ */
47
+ public $styles = [];
48
+
49
  /**
50
+ * Createas a new instance of the license api for a given plugin.
51
+ *
52
+ * @since 1.0.0
53
  */
54
+ public function __construct( Wbcr_Factory420_Plugin $plugin ) {
55
+ $this->plugin = $plugin;
56
+
57
+ add_action( 'admin_enqueue_scripts', [ $this, 'loadAssets' ] );
58
+ add_filter( 'admin_body_class', [ $this, 'adminBodyClass' ] );
59
  }
60
+
61
+ /**
62
+ * Includes the Bootstrap scripts.
63
+ *
64
+ * @since 3.2.0
65
+ *
66
+ * @param array|string $scripts
67
+ */
68
+ public function enqueueScript( $scripts ) {
69
+ if ( is_array( $scripts ) ) {
70
+ foreach ( $scripts as $script ) {
71
+ if ( ! in_array( $script, $this->scripts ) ) {
72
+ $this->scripts[] = $script;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
73
  }
74
  }
75
+ } else {
76
+ if ( ! in_array( $scripts, $this->scripts ) ) {
77
+ $this->scripts[] = $scripts;
78
+ }
79
+ }
80
+ }
81
+
82
+ /**
83
+ * * Includes the Bootstrap styles.
84
+ *
85
+ * @since 3.2.0
86
+ *
87
+ * @param array|string $styles
88
+ */
89
+ public function enqueueStyle( $styles ) {
90
+
91
+ if ( is_array( $styles ) ) {
92
+ foreach ( $styles as $style ) {
93
+ if ( ! in_array( $style, $this->styles ) ) {
94
+ $this->styles[] = $style;
95
  }
96
  }
97
+ } else {
98
+ if ( ! in_array( $styles, $this->styles ) ) {
99
+ $this->styles[] = $styles;
100
+ }
101
+ }
102
+ }
103
+
104
+ /**
105
+ * Loads Bootstrap assets.
106
+ *
107
+ * @since 3.2.0
108
+ * @return void
109
+ * @see admin_enqueue_scripts
110
+ *
111
+ */
112
+ public function loadAssets( $hook ) {
113
+
114
+ do_action( 'wbcr_factory_420_bootstrap_enqueue_scripts', $hook );
115
+ do_action( 'wbcr_factory_420_bootstrap_enqueue_scripts_' . $this->plugin->getPluginName(), $hook );
116
 
117
+ $dependencies = [];
118
+ if ( ! empty( $this->scripts ) ) {
119
+ $dependencies[] = 'jquery';
120
+ $dependencies[] = 'jquery-ui-core';
121
+ $dependencies[] = 'jquery-ui-widget';
122
+ }
123
+
124
+ foreach ( $this->scripts as $script ) {
125
+ switch ( $script ) {
126
+ case 'plugin.iris':
127
  $dependencies[] = 'jquery-ui-widget';
128
+ $dependencies[] = 'jquery-ui-slider';
129
+ $dependencies[] = 'jquery-ui-draggable';
130
+ break;
131
+ }
132
+ }
 
 
 
 
 
 
133
 
134
+ if ( ! empty( $this->scripts ) ) {
135
+ $this->enqueueScripts( $this->scripts, 'js', $dependencies );
136
+ }
137
+ if ( ! empty( $this->styles ) ) {
138
+ $this->enqueueScripts( $this->styles, 'css', $dependencies );
139
+ }
140
 
141
+ $user_id = get_current_user_id();
142
+ $color_name = get_user_meta( $user_id, 'admin_color', true );
143
+
144
+ if ( $color_name !== 'fresh' ) {
145
+ if ( file_exists( FACTORY_BOOTSTRAP_421_DIR . '/assets/flat/css/bootstrap.' . $color_name . '.css' ) ) {
146
+ wp_enqueue_style( 'wbcr-factory-bootstrap-421-colors', FACTORY_BOOTSTRAP_421_URL . '/assets/flat/css/bootstrap.' . $color_name . '.css' );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
147
  }
148
+ }
149
 
150
+ if ( $color_name == 'light' ) {
151
+ $primary_dark = '#037c9a';
152
+ $primary_light = '#04a4cc';
153
+ } else if ( $color_name == 'blue' ) {
154
+ $primary_dark = '#d39323';
155
+ $primary_light = '#e1a948';
156
+ } else if ( $color_name == 'coffee' ) {
157
+ $primary_dark = '#b78a66';
158
+ $primary_light = '#c7a589';
159
+ } else if ( $color_name == 'ectoplasm' ) {
160
+ $primary_dark = '#839237';
161
+ $primary_light = '#a3b745';
162
+ } else if ( $color_name == 'ocean' ) {
163
+ $primary_dark = '#80a583';
164
+ $primary_light = '#9ebaa0';
165
+ } else if ( $color_name == 'midnight' ) {
166
+ $primary_dark = '#d02a21';
167
+ $primary_light = '#e14d43';
168
+ } else if ( $color_name == 'sunrise' ) {
169
+ $primary_dark = '#c36822';
170
+ $primary_light = '#dd823b';
171
+ } else {
172
+ $primary_dark = '#0074a2';
173
+ $primary_light = '#2ea2cc';
174
+ }
175
+
176
+ ?>
177
+ <script>
178
+ if( !window.factory ) {
179
+ window.factory = {};
180
+ }
181
+ if( !window.factory.factoryBootstrap421 ) {
182
+ window.factory.factoryBootstrap421 = {};
183
+ }
184
+ window.factory.factoryBootstrap421.colors = {
185
+ primaryDark: '<?php echo $primary_dark ?>',
186
+ primaryLight: '<?php echo $primary_light ?>'
187
+ };
188
+ </script>
189
+ <?php
190
+ }
191
 
192
+ /**
193
+ * @param array $sripts
194
+ * @param string $type
195
+ * @param array $dependencies
196
+ */
197
+ protected function enqueueScripts( array $sripts, $type = 'js', array $dependencies ) {
198
 
199
+ $is_first = true;
 
200
 
201
+ /**
202
+ * Sets permission for file caching and combining into one file.
203
+ *
204
+ * @since 4.1.0
205
+ */
206
+ $cache_enable = apply_filters( 'wbcr/factory/bootstrap/cache_enable', true );
207
+
208
+ $cache_id = md5( implode( ',', $this->scripts ) . $type . $this->plugin->getPluginVersion() );
209
+ $cache_dir_path = FACTORY_BOOTSTRAP_421_DIR . '/assets/cache/';
210
+ $cache_dir_url = FACTORY_BOOTSTRAP_421_URL . '/assets/cache/';
211
+
212
+ $cache_filepath = $cache_dir_path . $cache_id . ".min." . $type;
213
+ $cache_fileurl = $cache_dir_url . $cache_id . ".min." . $type;
214
+
215
+ if ( $cache_enable && file_exists( $cache_filepath ) ) {
216
+ if ( $type == 'js' ) {
217
+ wp_enqueue_script( 'wbcr-factory-bootstrap-' . $cache_id, $cache_fileurl, $dependencies, $this->plugin->getPluginVersion() );
218
+ } else {
219
+ wp_enqueue_style( 'wbcr-factory-bootstrap-' . $cache_id, $cache_fileurl, [], $this->plugin->getPluginVersion() );
220
+ }
221
+ } else {
222
+ $cache_dir_exists = false;
223
+ if ( ! file_exists( $cache_dir_path ) ) {
224
+ if ( @mkdir( $cache_dir_path, 0755 ) && wp_is_writable( $cache_dir_path ) ) {
225
+ $cache_dir_exists = true;
226
+ }
227
+ } else {
228
+ if ( wp_is_writable( $cache_dir_path ) ) {
229
+ $cache_dir_exists = true;
230
+ }
231
+ }
232
+
233
+ $concat_files = [];
234
+ foreach ( $sripts as $script_to_load ) {
235
+ $script_to_load = sanitize_text_field( $script_to_load );
236
+ if ( $cache_enable && $cache_dir_exists ) {
237
+ $fname = FACTORY_BOOTSTRAP_421_DIR . "/assets/$type-min/$script_to_load.min." . $type;
238
+ if ( file_exists( $fname ) ) {
239
+ $f = @fopen( $fname, 'r' );
240
+ $concat_files[] = @fread( $f, filesize( $fname ) );
241
+ @fclose( $f );
242
  }
243
  } else {
244
+ if ( $type == 'js' ) {
245
+ wp_enqueue_script( md5( $script_to_load ), FACTORY_BOOTSTRAP_421_URL . "/assets/$type-min/$script_to_load.min." . $type, $is_first ? $dependencies : false, $this->plugin->getPluginVersion() );
 
 
 
246
  } else {
247
+ wp_enqueue_style( md5( $script_to_load ), FACTORY_BOOTSTRAP_421_URL . "/assets/$type-min/$script_to_load.min." . $type, [], $this->plugin->getPluginVersion() );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
248
  }
249
+ $is_first = false;
250
+ }
251
+ }
252
 
253
+ if ( $cache_enable && $cache_dir_exists && ! empty( $concat_files ) ) {
254
 
255
+ $cf = @fopen( $cache_filepath, 'w' );
256
+ $write_content = implode( PHP_EOL, $concat_files );
257
+ @fwrite( $cf, $write_content );
258
+ @fclose( $cf );
259
+ chmod( $cache_filepath, 0755 );
260
 
261
+ if ( file_exists( $cache_filepath ) ) {
262
+ if ( $type == 'js' ) {
263
+ wp_enqueue_script( 'wbcr-factory-bootstrap-' . $cache_id, $cache_fileurl, $dependencies, $this->plugin->getPluginVersion() );
264
+ } else {
265
+ wp_enqueue_style( 'wbcr-factory-bootstrap-' . $cache_id, $cache_fileurl, [], $this->plugin->getPluginVersion() );
 
 
266
  }
267
  }
268
  }
269
+ }
270
+ }
271
 
272
+ /**
273
+ * Adds the body classes: 'factory-flat or 'factory-volumetric'.
274
+ *
275
+ * @since 3.2.0
276
+ *
277
+ * @param string $classes
278
+ *
279
+ * @return string
280
+ */
281
+ public function adminBodyClass( $classes ) {
282
+ $classes .= FACTORY_FLAT_ADMIN ? ' factory-flat ' : ' factory-volumetric ';
 
283
 
284
+ return $classes;
285
+ }
286
+ }
 
libs/factory/bootstrap/includes/index.php ADDED
@@ -0,0 +1,2 @@
 
 
1
+ <?php
2
+ // Silence is golden.
libs/factory/bootstrap/index.php ADDED
@@ -0,0 +1,2 @@
 
 
1
+ <?php
2
+ // Silence is golden.
libs/factory/clearfy/assets/css/clearfy-base.css ADDED
@@ -0,0 +1,181 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * Базовые стили для всех копомпонентов Clearfy
3
+
4
+ * @author Webcraftic <wordpress.webraftic@gmail.com>
5
+ * @copyright Webcraftic 06.10.2018
6
+ * @sicne 2.0.5
7
+ */
8
+ #WBCR .wbcr-factory-pages-420-impressive-page-template .wbcr-factory-clearfy-212-multisite-suggetion {
9
+ padding: 30px 80px;
10
+ }
11
+ #WBCR .wbcr-factory-pages-420-impressive-page-template .wbcr-factory-clearfy-212-multisite-suggetion h3 {
12
+ margin: 0 0 20px;
13
+ }
14
+ #WBCR .wbcr-factory-pages-420-impressive-page-template .wbcr-factory-clearfy-212-multisite-suggetion .wbcr-factory-inner-contanier {
15
+ border: 2px dashed #8bc34a;
16
+ background: #fff;
17
+ padding: 20px;
18
+ }
19
+ #WBCR .wbcr-factory-pages-420-impressive-page-template .wbcr-factory-clearfy-212-multisite-suggetion .wbcr-factory-activate-premium {
20
+ display: inline-block;
21
+ cursor: pointer;
22
+ line-height: 16px;
23
+ font-size: 13px;
24
+ font-weight: 600;
25
+ padding: 12px 20px;
26
+ text-align: center;
27
+ text-decoration: none;
28
+ text-transform: uppercase;
29
+ border-radius: 2px;
30
+ -moz-border-radius: 2px;
31
+ -webkit-border-radius: 2px;
32
+ color: #353535;
33
+ background: #e8e8e8;
34
+ box-shadow: 0 1px 0 rgba(0, 0, 0, 0.2);
35
+ -moz-box-shadow: 0 1px 0 rgba(0, 0, 0, 0.2);
36
+ -webkit-box-shadow: 0 1px 0 rgba(0, 0, 0, 0.2);
37
+ }
38
+ #WBCR .wbcr-factory-pages-420-impressive-page-template .wbcr-factory-clearfy-212-multisite-suggetion .wbcr-factory-activate-premium:active {
39
+ box-shadow: inset 0 1px 0 rgba(0, 0, 0, 0.2);
40
+ -moz-box-shadow: inset 0 1px 0 rgba(0, 0, 0, 0.2);
41
+ -webkit-box-shadow: inset 0 1px 0 rgba(0, 0, 0, 0.2);
42
+ }
43
+ #WBCR .wbcr-factory-pages-420-impressive-page-template .wbcr-factory-clearfy-212-multisite-suggetion .wbcr-factory-activate-premium:focus {
44
+ outline: none;
45
+ border: 0;
46
+ }
47
+ #WBCR .wbcr-factory-pages-420-impressive-page-template .wbcr-factory-clearfy-212-multisite-suggetion .wbcr-factory-purchase-premium {
48
+ display: inline-block;
49
+ cursor: pointer;
50
+ line-height: 16px;
51
+ font-size: 13px;
52
+ font-weight: 600;
53
+ padding: 12px 20px;
54
+ text-align: center;
55
+ text-decoration: none;
56
+ text-transform: uppercase;
57
+ border-radius: 2px;
58
+ -moz-border-radius: 2px;
59
+ -webkit-border-radius: 2px;
60
+ color: #755c0e;
61
+ background: #fdd868;
62
+ box-shadow: 0 1px 0 rgba(60, 45, 2, 0.31);
63
+ -moz-box-shadow: 0 1px 0 rgba(60, 45, 2, 0.31);
64
+ -webkit-box-shadow: 0 1px 0 rgba(60, 45, 2, 0.31);
65
+ }
66
+ #WBCR .wbcr-factory-pages-420-impressive-page-template .wbcr-factory-clearfy-212-multisite-suggetion .wbcr-factory-purchase-premium:active {
67
+ box-shadow: inset 0 1px 0 rgba(60, 45, 2, 0.31);
68
+ -moz-box-shadow: inset 0 1px 0 rgba(60, 45, 2, 0.31);
69
+ -webkit-box-shadow: inset 0 1px 0 rgba(60, 45, 2, 0.31);
70
+ }
71
+ #WBCR .wbcr-factory-pages-420-impressive-page-template .wbcr-factory-clearfy-212-multisite-suggetion .wbcr-factory-purchase-premium:focus {
72
+ outline: none;
73
+ border: 0;
74
+ }
75
+ #WBCR .wbcr-factory-pages-420-impressive-page-template .wbcr-factory-right-sidebar-section .wbcr-factory-clearfy-212-pro-suggettion {
76
+ background: #fff;
77
+ color: #353535;
78
+ font-weight: 600;
79
+ border: 2px dashed #8bc34a;
80
+ }
81
+ #WBCR .wbcr-factory-pages-420-impressive-page-template .wbcr-factory-right-sidebar-section .wbcr-factory-clearfy-212-pro-suggettion h3 {
82
+ margin: 0 0 20px;
83
+ padding: 10px 0;
84
+ text-align: center;
85
+ border-bottom: 2px solid #e6e6e6;
86
+ color: #636363;
87
+ font-size: 17px;
88
+ font-weight: 600;
89
+ vertical-align: middle;
90
+ text-transform: uppercase;
91
+ }
92
+ #WBCR .wbcr-factory-pages-420-impressive-page-template .wbcr-factory-right-sidebar-section .wbcr-factory-clearfy-212-pro-suggettion ul {
93
+ position: relative;
94
+ margin-bottom: 20px;
95
+ }
96
+ #WBCR .wbcr-factory-pages-420-impressive-page-template .wbcr-factory-right-sidebar-section .wbcr-factory-clearfy-212-pro-suggettion ul li {
97
+ font-size: 15px;
98
+ padding: 7px;
99
+ padding-left: 20px;
100
+ }
101
+ #WBCR .wbcr-factory-pages-420-impressive-page-template .wbcr-factory-right-sidebar-section .wbcr-factory-clearfy-212-pro-suggettion ul li:before {
102
+ content: " ";
103
+ display: inline-block;
104
+ width: 0.4em;
105
+ height: 0.7em;
106
+ border: solid #8bc34a;
107
+ border-width: 0 0.2em 0.2em 0;
108
+ left: 0;
109
+ margin-right: 10px;
110
+ -webkit-transform: rotate(45deg);
111
+ -moz-transform: rotate(45deg);
112
+ -o-transform: rotate(45deg);
113
+ transform: rotate(45deg);
114
+ }
115
+ #WBCR .wbcr-factory-pages-420-impressive-page-template .wbcr-factory-right-sidebar-section .wbcr-factory-clearfy-212-pro-suggettion .wbcr-factory-purchase-premium {
116
+ display: block;
117
+ cursor: pointer;
118
+ line-height: 16px;
119
+ font-size: 13px;
120
+ font-weight: 600;
121
+ padding: 12px 20px;
122
+ text-align: center;
123
+ text-decoration: none;
124
+ text-transform: uppercase;
125
+ border-radius: 2px;
126
+ -moz-border-radius: 2px;
127
+ -webkit-border-radius: 2px;
128
+ color: #353535;
129
+ background: #e8e8e8;
130
+ box-shadow: 0 1px 0 rgba(0, 0, 0, 0.2);
131
+ -moz-box-shadow: 0 1px 0 rgba(0, 0, 0, 0.2);
132
+ -webkit-box-shadow: 0 1px 0 rgba(0, 0, 0, 0.2);
133
+ }
134
+ #WBCR .wbcr-factory-pages-420-impressive-page-template .wbcr-factory-right-sidebar-section .wbcr-factory-clearfy-212-pro-suggettion .wbcr-factory-purchase-premium:active {
135
+ box-shadow: inset 0 1px 0 rgba(0, 0, 0, 0.2);
136
+ -moz-box-shadow: inset 0 1px 0 rgba(0, 0, 0, 0.2);
137
+ -webkit-box-shadow: inset 0 1px 0 rgba(0, 0, 0, 0.2);
138
+ }
139
+ #WBCR .wbcr-factory-pages-420-impressive-page-template .wbcr-factory-right-sidebar-section .wbcr-factory-clearfy-212-pro-suggettion .wbcr-factory-purchase-premium:focus {
140
+ outline: none;
141
+ border: 0;
142
+ }
143
+ @media screen and (max-width: 1550px) {
144
+ #WBCR .wbcr-factory-pages-420-impressive-page-template .wbcr-factory-clearfy-212-multisite-pro-suggetion {
145
+ padding: 10px 80px;
146
+ }
147
+ #WBCR .wbcr-factory-pages-420-impressive-page-template .wbcr-factory-right-sidebar-section .wbcr-factory-clearfy-212-pro-suggettion {
148
+ padding: 10px;
149
+ }
150
+ #WBCR .wbcr-factory-pages-420-impressive-page-template .wbcr-factory-right-sidebar-section .wbcr-factory-clearfy-212-pro-suggettion h3 {
151
+ margin: 0 0 20px;
152
+ padding: 10px 0;
153
+ font-size: 13px;
154
+ font-weight: 600;
155
+ }
156
+ #WBCR .wbcr-factory-pages-420-impressive-page-template .wbcr-factory-right-sidebar-section .wbcr-factory-clearfy-212-pro-suggettion ul {
157
+ margin-bottom: 20px;
158
+ }
159
+ #WBCR .wbcr-factory-pages-420-impressive-page-template .wbcr-factory-right-sidebar-section .wbcr-factory-clearfy-212-pro-suggettion ul li {
160
+ font-size: 13px;
161
+ padding: 2px;
162
+ padding-left: 10px;
163
+ }
164
+ #WBCR .wbcr-factory-pages-420-impressive-page-template .wbcr-factory-right-sidebar-section .wbcr-factory-clearfy-212-pro-suggettion ul li:before {
165
+ width: 0.4em;
166
+ height: 0.7em;
167
+ border-width: 0 0.2em 0.2em 0;
168
+ left: 0;
169
+ margin-right: 10px;
170
+ }
171
+ #WBCR .wbcr-factory-pages-420-impressive-page-template .wbcr-factory-right-sidebar-section .wbcr-factory-clearfy-212-pro-suggettion .wbcr-factory-purchase-premium {
172
+ font-weight: 700;
173
+ line-height: 16px;
174
+ font-size: 12px;
175
+ padding: 8px 12px;
176
+ border-radius: 2px;
177
+ -moz-border-radius: 2px;
178
+ -webkit-border-radius: 2px;
179
+ }
180
+ }
181
+ /*# sourceMappingURL=clearfy-base.css.map */
libs/factory/clearfy/assets/css/clearfy-base.less ADDED
@@ -0,0 +1,170 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * Базовые стили для всех копомпонентов Clearfy
3
+
4
+ * @author Webcraftic <wordpress.webraftic@gmail.com>
5
+ * @copyright Webcraftic 06.10.2018
6
+ * @sicne 2.0.5
7
+ */
8
+
9
+ .button(@backgroundColor: #e8e8e8,@color:#353535, @boxShadow:rgba(0, 0, 0, 0.2)) {
10
+ cursor: pointer;
11
+ line-height: 16px;
12
+ font-size: 13px;
13
+ font-weight: 600;
14
+ padding: 12px 20px;
15
+ text-align: center;
16
+ text-decoration: none;
17
+ text-transform: uppercase;
18
+ border-radius: 2px;
19
+ -moz-border-radius: 2px;
20
+ -webkit-border-radius: 2px;
21
+ color: @color;
22
+ background: @backgroundColor;
23
+ box-shadow: 0 1px 0 @boxShadow;
24
+ -moz-box-shadow: 0 1px 0 @boxShadow;
25
+ -webkit-box-shadow: 0 1px 0 @boxShadow;
26
+ &:active {
27
+ box-shadow: inset 0 1px 0 @boxShadow;
28
+ -moz-box-shadow: inset 0 1px 0 @boxShadow;
29
+ -webkit-box-shadow: inset 0 1px 0 @boxShadow;
30
+ }
31
+ &:focus {
32
+ outline: none;
33
+ border: 0;
34
+ }
35
+ }
36
+
37
+ #WBCR {
38
+
39
+ .wbcr-factory-pages-000-impressive-page-template {
40
+ .wbcr-factory-clearfy-000-multisite-suggetion {
41
+ padding: 30px 80px;
42
+
43
+ h3 {
44
+ margin: 0 0 20px;
45
+ }
46
+
47
+ .wbcr-factory-inner-contanier {
48
+ border: 2px dashed #8bc34a;
49
+ background: #fff;
50
+ padding: 20px;
51
+ }
52
+
53
+ .wbcr-factory-activate-premium {
54
+ display: inline-block;
55
+ .button();
56
+ }
57
+ .wbcr-factory-purchase-premium {
58
+ display: inline-block;
59
+ .button(#fdd868, #755c0e, rgba(60, 45, 2, 0.31));
60
+ }
61
+ }
62
+
63
+ .wbcr-factory-right-sidebar-section {
64
+ .wbcr-factory-clearfy-000-pro-suggettion {
65
+ background: #fff;
66
+ color: #353535;
67
+ font-weight: 600;
68
+ border: 2px dashed #8bc34a;
69
+
70
+ h3 {
71
+ margin: 0 0 20px;
72
+ padding: 10px 0;
73
+ text-align: center;
74
+ border-bottom: 2px solid #e6e6e6;
75
+ color: #636363;
76
+ font-size: 17px;
77
+ font-weight: 600;
78
+ vertical-align: middle;
79
+ text-transform: uppercase;
80
+ }
81
+
82
+ ul {
83
+ //list-style: circle;
84
+ position: relative;
85
+ margin-bottom: 20px;
86
+
87
+ li {
88
+ font-size: 15px;
89
+ padding: 7px;
90
+ padding-left: 20px;
91
+ &:before {
92
+ }
93
+
94
+ &:before {
95
+ content: " ";
96
+ display: inline-block;
97
+ width: 0.4em;
98
+ height: 0.7em;
99
+ border: solid #8bc34a;
100
+ border-width: 0 0.2em 0.2em 0;
101
+ left: 0;
102
+ margin-right: 10px;
103
+ -webkit-transform: rotate(45deg);
104
+ -moz-transform: rotate(45deg);
105
+ -o-transform: rotate(45deg);
106
+ transform: rotate(45deg);
107
+ }
108
+
109
+ }
110
+ }
111
+
112
+ .wbcr-factory-purchase-premium {
113
+ display: block;
114
+ .button();
115
+ }
116
+ }
117
+ }
118
+ }
119
+ }
120
+
121
+ @media screen and (max-width: 1550px) {
122
+ #WBCR {
123
+ .wbcr-factory-pages-000-impressive-page-template {
124
+ .wbcr-factory-clearfy-000-multisite-pro-suggetion {
125
+ padding: 10px 80px;
126
+ }
127
+
128
+ .wbcr-factory-right-sidebar-section {
129
+ .wbcr-factory-clearfy-000-pro-suggettion {
130
+ padding: 10px;
131
+
132
+ h3 {
133
+ margin: 0 0 20px;
134
+ padding: 10px 0;
135
+ font-size: 13px;
136
+ font-weight: 600;
137
+ }
138
+
139
+ ul {
140
+ margin-bottom: 20px;
141
+
142
+ li {
143
+ font-size: 13px;
144
+ padding: 2px;
145
+ padding-left: 10px;
146
+
147
+ &:before {
148
+ width: 0.4em;
149
+ height: 0.7em;
150
+ border-width: 0 0.2em 0.2em 0;
151
+ left: 0;
152
+ margin-right: 10px;
153
+ }
154
+ }
155
+ }
156
+
157
+ .wbcr-factory-purchase-premium {
158
+ font-weight: 700;
159
+ line-height: 16px;
160
+ font-size: 12px;
161
+ padding: 8px 12px;
162
+ border-radius: 2px;
163
+ -moz-border-radius: 2px;
164
+ -webkit-border-radius: 2px;
165
+ }
166
+ }
167
+ }
168
+ }
169
+ }
170
+ }
libs/factory/clearfy/assets/css/license-manager.css ADDED
@@ -0,0 +1,663 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ .not-visible-in-manager {
3
+ display: none;
4
+ }
5
+
6
+ /**
7
+ * Global License Message
8
+ */
9
+ .global-license-message {
10
+ width: 600px;
11
+ margin: auto;
12
+ /*margin-top: 100px;*/
13
+ font-size: 14px;
14
+ line-height: 170%;
15
+ }
16
+
17
+ .global-license-message h2, .global-license-message h3 {
18
+ padding: 0px;
19
+ margin: 5px 0;
20
+ }
21
+
22
+ .onp-page-wrap {
23
+ max-width: 720px;
24
+ margin: auto;
25
+ margin-top: 40px;
26
+ font-size: 14px;
27
+ line-height: 170%;
28
+ }
29
+
30
+ .onp-container {
31
+ border: 0px;
32
+ padding: 0px;
33
+ border-radius: 5px;
34
+ background: rgb(255, 255, 255) !important;
35
+ box-shadow: 0 0 5px rgba(0, 0, 0, 0.2);
36
+ -moz-box-sizing: border-box;
37
+ box-sizing: border-box;
38
+ }
39
+
40
+ #license-manager {
41
+ padding: 0 0 40px;
42
+ }
43
+
44
+ #license-manager .onp-container {
45
+ background: -moz-linear-gradient(top, rgba(255, 255, 255, 1) 63%, rgba(246, 246, 246, 1) 100%); /* FF3.6+ */
46
+ background: -webkit-gradient(linear, left top, left bottom, color-stop(63%, rgba(255, 255, 255, 1)), color-stop(100%, rgba(246, 246, 246, 1))); /* Chrome,Safari4+ */
47
+ background: -webkit-linear-gradient(top, rgba(255, 255, 255, 1) 63%, rgba(246, 246, 246, 1) 100%); /* Chrome10+,Safari5.1+ */
48
+ background: -o-linear-gradient(top, rgba(255, 255, 255, 1) 63%, rgba(246, 246, 246, 1) 100%); /* Opera 11.10+ */
49
+ background: -ms-linear-gradient(top, rgba(255, 255, 255, 1) 63%, rgba(246, 246, 246, 1) 100%); /* IE10+ */
50
+ background: linear-gradient(to bottom, rgba(255, 255, 255, 1) 63%, rgba(246, 246, 246, 1) 100%); /* W3C */
51
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff', endColorstr='#f6f6f6', GradientType=0); /* IE6-9 */
52
+ }
53
+
54
+ .onp-container h2 {
55
+ margin: 0px;
56
+ padding: 0px;
57
+ }
58
+
59
+ .onp-container p {
60
+ margin: 0 0 2px 0;
61
+ padding: 0px;
62
+ line-height: 170%;
63
+ }
64
+
65
+ .btn-uppercase {
66
+ font-size: 12px;
67
+ letter-spacing: 1px;
68
+ text-transform: uppercase;
69
+ text-decoration: none;
70
+ }
71
+
72
+ .btn-uppercase *[class^=icon] {
73
+ position: relative;
74
+ top: -1px;
75
+ left: -1px;
76
+ }
77
+
78
+ .onp-page-wrap .license-message {
79
+ margin-bottom: 20px;
80
+ overflow: hidden;
81
+ }
82
+
83
+ .onp-page-wrap .license-message .alert {
84
+ margin: 0px;
85
+ }
86
+
87
+ .onp-page-wrap .license-message strong {
88
+ display: block;
89
+ margin-bottom: 0px;
90
+ }
91
+
92
+ .onp-page-wrap .license-message p {
93
+ margin: 1px 0 1px 0;
94
+ padding: 0px;
95
+ }
96
+
97
+ .onp-page-wrap .license-message a {
98
+ font-weight: bold;
99
+ }
100
+
101
+ .license-message .alert-warning-icon {
102
+ padding-left: 60px;
103
+ background-image: url("../img/warning.png");
104
+ background-position: 15px 11px;
105
+ background-repeat: no-repeat;
106
+ }
107
+
108
+ #onp-hide-license-manager {
109
+ position: absolute;
110
+ top: 2px;
111
+ right: 15px;
112
+ font-size: 12px;
113
+ color: #777;
114
+ font-weight: bold;
115
+ }
116
+
117
+ #onp-hide-license-manager:hover {
118
+ text-decoration: none;
119
+ }
120
+
121
+ #onp-hide-license-manager,
122
+ #onp-hide-license-manager:focus,
123
+ #onp-hide-license-manager:hover {
124
+ outline: none;
125
+ border: 0px;
126
+ box-shadow: none;
127
+ }
128
+
129
+ #onp-hide-license-manager .fa {
130
+ margin-right: 5px;
131
+ }
132
+
133
+ #license-manager .license-details-wrap {
134
+ border: 1px solid #e9e9e9;
135
+ padding: 0px;
136
+ border-radius: 5px;
137
+
138
+ background: rgb(255, 255, 255); /* Old browsers */
139
+ background: -moz-linear-gradient(top, rgba(255, 255, 255, 1) 63%, rgba(246, 246, 246, 1) 100%); /* FF3.6+ */
140
+ background: -webkit-gradient(linear, left top, left bottom, color-stop(63%, rgba(255, 255, 255, 1)), color-stop(100%, rgba(246, 246, 246, 1))); /* Chrome,Safari4+ */
141
+ background: -webkit-linear-gradient(top, rgba(255, 255, 255, 1) 63%, rgba(246, 246, 246, 1) 100%); /* Chrome10+,Safari5.1+ */
142
+ background: -o-linear-gradient(top, rgba(255, 255, 255, 1) 63%, rgba(246, 246, 246, 1) 100%); /* Opera 11.10+ */
143
+ background: -ms-linear-gradient(top, rgba(255, 255, 255, 1) 63%, rgba(246, 246, 246, 1) 100%); /* IE10+ */
144
+ background: linear-gradient(to bottom, rgba(255, 255, 255, 1) 63%, rgba(246, 246, 246, 1) 100%); /* W3C */
145
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff', endColorstr='#f6f6f6', GradientType=0); /* IE6-9 */
146
+
147
+ box-shadow: 0px 2px 1px #c9c9c9;
148
+ }
149
+
150
+ #license-manager .activate-trial-hint {
151
+ background-color: #f8f8f8;
152
+ padding: 10px 20px;
153
+ position: relative;
154
+ -moz-box-sizing: content-box;
155
+ box-sizing: content-box;
156
+ }
157
+
158
+ #license-manager .activate-error-hint {
159
+ background-color: #fb7976;
160
+ color: #f5f5f5;
161
+ text-shadow: none;
162
+ padding: 2px 9px;
163
+ width: 100%;
164
+ position: relative;
165
+ margin-left: -9px;
166
+ -moz-box-sizing: content-box;
167
+ box-sizing: content-box;
168
+ }
169
+
170
+ #license-manager .license-details {
171
+ padding: 20px;
172
+ padding-bottom: 0px;
173
+ -webkit-border-top-left-radius: 5px;
174
+ -webkit-border-top-right-radius: 5px;
175
+ -moz-border-radius-topleft: 5px;
176
+ -moz-border-radius-topright: 5px;
177
+ border-top-left-radius: 5px;
178
+ border-top-right-radius: 5px;
179
+
180
+ position: relative;
181
+ z-index: 10;
182
+ }
183
+
184
+ #license-manager .license-key-identity {
185
+ font-style: italic;
186
+ position: relative;
187
+ top: -6px;
188
+ }
189
+
190
+ #license-manager .license-key-identity code {
191
+ display: inline-block;
192
+ padding: 2px 5px;
193
+ font-size: 16px;
194
+ }
195
+
196
+ #license-manager .license-key-description {
197
+ font-size: 12px;
198
+ }
199
+
200
+ #license-manager .license-delete-button {
201
+ float: right;
202
+ text-decoration: none;
203
+ position: relative;
204
+ top: -7px;
205
+ left: 10px;
206
+ }
207
+
208
+ #license-manager .license-synchronization-button {
209
+ float: right;
210
+ text-decoration: none;
211
+ position: relative;
212
+ top: -7px;
213
+ left: 5px;
214
+ }
215
+
216
+ #license-manager .license-details-block {
217
+ padding: 28px 35px 15px 35px;
218
+ margin-left: -35px;
219
+ width: 100%;
220
+ position: relative;
221
+ margin-top: 20px;
222
+
223
+ background: #fff;
224
+ border: 0px;
225
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
226
+ color: #333;
227
+
228
+ border-radius: 5px;
229
+
230
+ -webkit-box-sizing: content-box;
231
+ -moz-box-sizing: content-box;
232
+ box-sizing: content-box;
233
+ }
234
+
235
+ #license-manager .license-details-block p + p {
236
+ margin-top: 10px;
237
+ }
238
+
239
+ #license-manager .license-details-block a {
240
+ font-weight: bold;
241
+ }
242
+
243
+ #license-manager .license-details-block.trial-details-block {
244
+ background: #ffdede;
245
+
246
+ border: 0;
247
+ box-shadow: 0 0 7px #cf4944;
248
+ color: #a04342;
249
+ text-shadow: 1px 1px 2px #fff2f2;
250
+ }
251
+
252
+ #license-manager .license-details-block.trial-details-block a {
253
+ color: #a04342;
254
+ }
255
+
256
+ #license-manager .license-details-block.paid-details-block {
257
+ border: 0;
258
+ box-shadow: 0 0 7px #b8823b;
259
+ color: #8a6d3b;
260
+ background: #fcf8e3;
261
+ }
262
+
263
+ #license-manager .license-details-block.paid-details-block a {
264
+ color: #7a4c00;
265
+ }
266
+
267
+ #license-manager .license-details-block.gift-details-block {
268
+ background: #DFF0D8;
269
+ border: 1px solid #D6E9C6;
270
+ box-shadow: 0px 0px 5px #D6E9C6;
271
+ color: #468847;
272
+ }
273
+
274
+ #license-manager .license-details-block.gift-details-block a {
275
+ color: #468847;
276
+ }
277
+
278
+ #license-manager .license-params {
279
+ margin-top: 15px;
280
+ position: relative;
281
+ left: -2px;
282
+ }
283
+
284
+ #license-manager .license-value {
285
+ display: block;
286
+ font-size: 16px;
287
+ font-weight: bold;
288
+ }
289
+
290
+ #license-manager .license-value small {
291
+ font-weight: normal;
292
+ }
293
+
294
+ #license-manager .license-value-name {
295
+ display: block;
296
+ font-size: 12px;
297
+ }
298
+
299
+ #license-manager .license-param {
300
+ white-space: nowrap;
301
+ line-height: 130%;
302
+ padding: 10px 0 10px 35px;
303
+ vertical-align: top;
304
+ }
305
+
306
+ #license-manager .license-param-domain {
307
+ padding-left: 65px;
308
+ background: url('../img/free-license-chip.png') -3px 0px no-repeat;
309
+ }
310
+
311
+ #license-manager .trial-details-block .license-param-domain {
312
+ background: url('../img/trial-license-chip.png') -3px 0px no-repeat;
313
+ }
314
+
315
+ #license-manager .paid-details-block .license-param-domain {
316
+ background: url('../img/paid-license-chip.png') -3px 0px no-repeat;
317
+ }
318
+
319
+ #license-manager .license-details-block h3 {
320
+ margin: 0px;
321
+ padding: 0px;
322
+ font-size: 22px;
323
+ margin-bottom: 10px;
324
+ }
325
+
326
+ #license-manager .license-details-block a {
327
+ color: #a04342;
328
+ }
329
+
330
+ #license-manager .license-input {
331
+
332
+ padding: 20px;
333
+ -webkit-border-bottom-right-radius: 5px;
334
+ -webkit-border-bottom-left-radius: 5px;
335
+ -moz-border-radius-bottomright: 5px;
336
+ -moz-border-radius-bottomleft: 5px;
337
+ border-bottom-right-radius: 5px;
338
+ border-bottom-left-radius: 5px;
339
+ }
340
+
341
+ #license-manager .license-input .btn {
342
+ text-decoration: none;
343
+ }
344
+
345
+ #license-manager .license-key-wrap {
346
+ padding-right: 110px;
347
+ }
348
+
349
+ #license-key {
350
+ width: 100%;
351
+ position: relative;
352
+ font-size: 18px;
353
+ line-height: 20px;
354
+ position: relative;
355
+ top: -1px;
356
+ height: 36px;
357
+ color: #000;
358
+ }
359
+
360
+ #license-submit {
361
+ float: right;
362
+ padding: 7px 14px 6px 14px;
363
+ }
364
+
365
+ #plugin-update-block {
366
+ padding-top: 10px;
367
+ font-size: 10px;
368
+ color: #666;
369
+ max-width: 700px;
370
+ margin: auto;
371
+ }
372
+
373
+ #plugin-update-block a {
374
+ color: #000;
375
+ }
376
+
377
+ .purchase-premium {
378
+ float: right;
379
+ position: relative;
380
+ top: -11px;
381
+ left: 8px;
382
+ text-decoration: none;
383
+ font-weight: bold;
384
+ background: #fffaea;
385
+ padding: 0px;
386
+ border-radius: 4px;
387
+ outline: none;
388
+ margin-top: 4px;
389
+ box-shadow: 0 0 8px #fddf67;
390
+ }
391
+
392
+ .purchase-premium .fa {
393
+ position: relative;
394
+ margin-right: 3px;
395
+ margin-left: 3px;
396
+ }
397
+
398
+ /*
399
+ * Manual Trial Activation
400
+ */
401
+ #trial-manual .onp-container {
402
+ padding: 20px;
403
+ overflow: hidden;
404
+ }
405
+
406
+ #trial-manual ul {
407
+ margin: 0px;
408
+ padding: 0px;
409
+ margin-top: 10px;
410
+ }
411
+
412
+ #trial-manual ul li {
413
+ margin-bottom: 10px;
414
+ }
415
+
416
+ #trial-manual .license-reponse-code {
417
+ width: 100%;
418
+ height: 150px;
419
+ margin-top: 5px;
420
+ }
421
+
422
+ /*
423
+ * Manual Key Activation
424
+ */
425
+ #activate-key-manual .onp-container {
426
+ padding: 20px;
427
+ overflow: hidden;
428
+ }
429
+
430
+ #activate-key-manual ul {
431
+ margin: 0px;
432
+ padding: 0px;
433
+ margin-top: 10px;
434
+ }
435
+
436
+ #activate-key-manual ul li {
437
+ margin-bottom: 10px;
438
+ }
439
+
440
+ #activate-key-manual .license-reponse-code {
441
+ width: 100%;
442
+ height: 150px;
443
+ margin-top: 5px;
444
+ }
445
+
446
+ /**
447
+ * FAQ
448
+ */
449
+
450
+ #faq-block {
451
+ border-top: 1px solid #d7d7d7;
452
+
453
+ margin-top: 20px;
454
+ width: 100%;
455
+
456
+ padding: 10px 20px;
457
+ position: relative;
458
+ }
459
+
460
+ #faq-block .faq-header {
461
+ border-bottom: 1px dotted #333;
462
+ display: inline-block;
463
+ cursor: pointer;
464
+ font-weight: bold;
465
+ line-height: 16px;
466
+ font-size: 13px;
467
+ color: #333;
468
+ }
469
+
470
+ #faq-block .faq-header:hover {
471
+ border-bottom: 0px;
472
+ }
473
+
474
+ #faq-block .faq-header:focus, #faq-block .faq-header:active {
475
+ outline: 0;
476
+ }
477
+
478
+ #faq-block li > div {
479
+ display: none;
480
+ }
481
+
482
+ #faq-block p {
483
+ margin: 6px 0 10px 0;
484
+ font-size: 13px;
485
+ line-height: 170%;
486
+ }
487
+
488
+ #open-faq {
489
+ color: #000 !important;
490
+ text-decoration: none;
491
+ border-bottom: 1px dotted #000;
492
+ margin-left: 4px;
493
+ }
494
+
495
+ #open-faq:hover {
496
+ border-bottom: 0px;
497
+ }
498
+
499
+ .gray-link, .gray-link a {
500
+ color: #666666 !important;
501
+ }
502
+
503
+ /**
504
+ * A form to create a customer account
505
+ */
506
+
507
+ .onp-single-block .onp-header {
508
+ text-align: center;
509
+ padding: 10px;
510
+ }
511
+
512
+ .onp-single-block .onp-header h4 {
513
+ font-size: 26px;
514
+ line-height: 130%;
515
+ }
516
+
517
+ .onp-single-block .onp-container {
518
+ padding: 50px 60px;
519
+ border: 1px solid #bbb;
520
+ position: relative;
521
+ }
522
+
523
+ .onp-single-block .onp-container .onp-container-header {
524
+ margin-bottom: 20px;
525
+ }
526
+
527
+ .onp-single-block .onp-container .onp-container-header h4 {
528
+ color: #000;
529
+ margin: 0px;
530
+ font-size: 20px;
531
+ }
532
+
533
+ .onp-single-block .onp-container .onp-container-header .onp-key-info {
534
+ color: #666;
535
+ }
536
+
537
+ .onp-single-block .onp-container .onp-container-header .onp-key-info .fa {
538
+ color: #777;
539
+ }
540
+
541
+ .onp-single-block .onp-container .onp-container-header .onp-icon {
542
+ position: absolute;
543
+ top: 30px;
544
+ right: 30px;
545
+ }
546
+
547
+ .onp-single-block .onp-container p,
548
+ .onp-single-block .onp-container li {
549
+ color: #333;
550
+ font-size: 14px;
551
+ }
552
+
553
+ .onp-single-block .onp-container p + p {
554
+ margin-top: 15px;
555
+ }
556
+
557
+ .onp-single-block .onp-container .onp-form {
558
+ text-align: left;
559
+ padding: 10px 0 0 0;
560
+ }
561
+
562
+ .onp-single-block #email {
563
+ font-size: 26px;
564
+ line-height: 26px;
565
+ height: 50px;
566
+ }
567
+
568
+ .onp-single-block .checkbox {
569
+ padding-left: 25px;
570
+ color: #999;
571
+ font-style: italic;
572
+ }
573
+
574
+ .onp-single-block .checkbox input {
575
+ margin-left: -25px;
576
+ }
577
+
578
+ .onp-single-block .onp-actions {
579
+ padding-top: 20px;
580
+ }
581
+
582
+ .onp-single-block .onp-actions .btn-primary {
583
+ margin-right: 15px;
584
+ }
585
+
586
+ .onp-single-block .onp-actions a.onp-cancel {
587
+ text-decoration: none;
588
+ color: #111;
589
+ }
590
+
591
+ .onp-single-block .onp-actions a.onp-cancel:hover {
592
+ text-decoration: none;
593
+ border-bottom: 1px solid #111;
594
+ background-color: #f9f9f9;
595
+ }
596
+
597
+ .onp-single-block .onp-benefits {
598
+ padding-left: 25px;
599
+ margin-top: 15px;
600
+ list-style: initial;
601
+ }
602
+
603
+ .onp-single-block .onp-login-details {
604
+
605
+ }
606
+
607
+ .onp-single-block .onp-text-seporator {
608
+ border-top: 1px solid #eee;
609
+ margin: 30px 0;
610
+ }
611
+
612
+ #create-account .onp-container {
613
+ background: #fff url("../img/create-account-bg.png") no-repeat 370px 230px !important;
614
+ }
615
+
616
+ #account-created .onp-step {
617
+ overflow: hidden;
618
+ }
619
+
620
+ #account-created .onp-steps {
621
+ padding: 25px 0 20px 10px;
622
+ }
623
+
624
+ #account-created .onp-step + .onp-step {
625
+ margin-top: 20px;
626
+ }
627
+
628
+ #account-created .onp-step .onp-num {
629
+ font-size: 25px;
630
+ line-height: 40px;
631
+ background-color: #f5f5f5;
632
+ width: 40px;
633
+ height: 40px;
634
+ display: inline-block;
635
+ border-radius: 7px;
636
+ text-align: center;
637
+ -moz-box-sizing: border-box;
638
+ box-sizing: border-box;
639
+ margin-right: 10px;
640
+ vertical-align: middle;
641
+ font-weight: bolder;
642
+ font-family: Arial, sans-serif;
643
+ }
644
+
645
+ #account-created .onp-step .onp-desc {
646
+ width: 490px;
647
+ display: inline-block;
648
+ vertical-align: middle;
649
+ line-height: 150%;
650
+ }
651
+
652
+ #finish .onp-container {
653
+ background: #fff url("../img/finish.png") no-repeat 0 -90px !important;
654
+ padding-left: 260px;
655
+ min-height: 250px;
656
+
657
+ border-bottom: 3px solid #ccc;
658
+ }
659
+
660
+ .wcl-loader {
661
+ float: right;
662
+ width: 32px;
663
+ }
libs/factory/clearfy/assets/img/loader.gif ADDED
Binary file
libs/factory/clearfy/assets/js/globals.js ADDED
@@ -0,0 +1,203 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*!
2
+ * Глобальный JS файл, который регистрирует глобальные переменные с общими методами для всех компонентов Clearfy
3
+ * и самого Clearfy.
4
+ *
5
+ * $.wbcr_factory_clearfy_212.app - методы для работы с приложением. Скрыть, показать уведомления.
6
+ * $.wbcr_factory_clearfy_212.hooks - это иммитация хуков и фильтров аналогично тем, что используются в Wordpress
7
+ *
8
+ * Copyright 2018, Webcraftic, http://webcraftic.com
9
+ *
10
+ * @since 2.0.5
11
+ * @pacakge clearfy
12
+ */
13
+ (function($) {
14
+ 'use strict';
15
+
16
+ if( !$.wbcr_factory_clearfy_212 ) {
17
+ $.wbcr_factory_clearfy_212 = {};
18
+ }
19
+
20
+ $.wbcr_factory_clearfy_212.app = $.wbcr_factory_clearfy_212.app || {
21
+ /**
22
+ * Создает и показывает уведомление внутри интерфейса Clearfy
23
+ *
24
+ * @param {string} message - сообщение об ошибке или предупреждение
25
+ * @param {string} type - тип уведомления (error, warning, success)
26
+ */
27
+ showNotice: function(message, type) {
28
+ var noticeContanier = $('<div></div>'),
29
+ noticeInnerWrap = $('<p></p>'),
30
+ dashicon = $('<span></span>'),
31
+ dashiconClass,
32
+ noticeId = this.makeid();
33
+
34
+ if( !type ) {
35
+ type = 'warning';
36
+ }
37
+
38
+ noticeContanier.addClass('alert', 'wbcr-factory-warning-notice')
39
+ .addClass('alert-' + type).addClass('wbcr-factory-' + type + '-notice');
40
+
41
+ noticeContanier.append(noticeInnerWrap);
42
+ noticeContanier.attr('id', 'uq-' + noticeId);
43
+
44
+ if( type == 'success' ) {
45
+ dashiconClass = 'dashicons-plus';
46
+ } else if( type == 'error' ) {
47
+ dashiconClass = 'dashicons-no';
48
+ } else {
49
+ dashiconClass = 'dashicons-warning';
50
+ }
51
+
52
+ dashicon.addClass('dashicons').addClass(dashiconClass);
53
+ noticeInnerWrap.prepend(dashicon);
54
+ dashicon.after(message);
55
+
56
+ $([document.documentElement, document.body]).animate({
57
+ scrollTop: $('.wbcr-factory-content').offset().top - 100
58
+ }, 300, function() {
59
+ noticeContanier.hide();
60
+ $('.wbcr-factory-content').prepend(noticeContanier);
61
+ noticeContanier.fadeIn();
62
+
63
+ /**
64
+ * Хук выполняет проивольную функцию, после того как уведомление отображено
65
+ * Реализация системы фильтров и хуков в файле libs/clearfy/admin/assests/js/global.js
66
+ * Пример регистрации хука $.wbcr_factory_clearfy_212.hooks.add('wbcr/factory_clearfy_212/updated',
67
+ * function(noticeId) {});
68
+ * @param {string} noticeId - id уведомления
69
+ */
70
+ $.wbcr_factory_clearfy_212.hooks.run('wbcr/factory_clearfy_212/showed_notice', [noticeId]);
71
+ $.wbcr_factory_clearfy_212.hooks.run('wbcr/clearfy/showed_notice', [noticeId]);
72
+ });
73
+
74
+ return noticeId;
75
+ },
76
+
77
+ /**
78
+ * Удаляет уведомление из интерфейса Clearfy
79
+ *
80
+ * @param {string} noticeId - id уведомления
81
+ */
82
+ hideNotice: function(noticeId) {
83
+ var el;
84
+ if( !noticeId ) {
85
+ el = $('.wbcr-factory-content').find('.alert');
86
+ } else {
87
+ el = $('#uq-' + noticeId);
88
+ }
89
+
90
+ el.fadeOut(500, function(e) {
91
+ $(e).remove();
92
+
93
+ /**
94
+ * Хук выполняет проивольную функцию, после того как уведомление скрыто
95
+ * Реализация системы фильтров и хуков в файле libs/clearfy/admin/assests/js/global.js
96
+ * Пример регистрации хука $.wbcr_factory_clearfy_212.hooks.add('wbcr/factory_clearfy_212/updated',
97
+ * function(noticeId)
98
+ * {});
99
+ * @param {string} noticeId - id уведомления
100
+ */
101
+ $.wbcr_factory_clearfy_212.hooks.run('wbcr/factory_clearfy_212/hidded_notice', [noticeId]);
102
+ $.wbcr_factory_clearfy_212.hooks.run('wbcr/clearfy/hidded_notice', [noticeId]);
103
+ });
104
+ },
105
+
106
+ makeid: function() {
107
+ var text = "";
108
+ var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
109
+
110
+ for( var i = 0; i < 32; i++ ) {
111
+ text += possible.charAt(Math.floor(Math.random() * possible.length));
112
+ }
113
+
114
+ return text;
115
+ }
116
+
117
+ };
118
+
119
+ $.wbcr_factory_clearfy_212.filters = $.wbcr_factory_clearfy_212.filters || {
120
+
121
+ /**
122
+ * A set of registered filters.
123
+ */
124
+ _items: {},
125
+
126
+ /**
127
+ * A set of priorities of registered filters.
128
+ */
129
+ _priorities: {},
130
+
131
+ /**
132
+ * Applies filters to a given input value.
133
+ */
134
+ run: function(filterName, args) {
135
+ var input = args && args.length > 0 ? args[0] : null;
136
+ if( !this._items[filterName] ) {
137
+ return input;
138
+ }
139
+
140
+ for( var i in this._priorities[filterName] ) {
141
+ if( !this._priorities[filterName].hasOwnProperty(i) ) {
142
+ continue;
143
+ }
144
+
145
+ var priority = this._priorities[filterName][i];
146
+
147
+ for( var k = 0; k < this._items[filterName][priority].length; k++ ) {
148
+ var f = this._items[filterName][priority][k];
149
+ input = f.apply(f, args);
150
+ }
151
+ }
152
+
153
+ return input;
154
+ },
155
+
156
+ /**
157
+ * Registers a new filter.
158
+ */
159
+ add: function(filterName, callback, priority) {
160
+
161
+ if( !priority ) {
162
+ priority = 10;
163
+ }
164
+
165
+ if( !this._items[filterName] ) {
166
+ this._items[filterName] = {};
167
+ }
168
+ if( !this._items[filterName][priority] ) {
169
+ this._items[filterName][priority] = [];
170
+ }
171
+ this._items[filterName][priority].push(callback);
172
+
173
+ if( !this._priorities[filterName] ) {
174
+ this._priorities[filterName] = [];
175
+ }
176
+ if( $.inArray(priority, this._priorities[filterName]) === -1 ) {
177
+ this._priorities[filterName].push(priority);
178
+ }
179
+
180
+ this._priorities[filterName].sort(function(a, b) {
181
+ return a - b;
182
+ });
183
+ }
184
+ };
185
+
186
+ $.wbcr_factory_clearfy_212.hooks = $.wbcr_factory_clearfy_212.hooks || {
187
+
188
+ /**
189
+ * Applies filters to a given input value.
190
+ */
191
+ run: function(filterName, args) {
192
+ $.wbcr_factory_clearfy_212.filters.run(filterName, args);
193
+ },
194
+
195
+ /**
196
+ * Registers a new filter.
197
+ */
198
+ add: function(filterName, callback, priority) {
199
+ $.wbcr_factory_clearfy_212.filters.add(filterName, callback, priority);
200
+ }
201
+ };
202
+
203
+ })(jQuery);
libs/factory/clearfy/assets/js/license-manager.js ADDED
@@ -0,0 +1,96 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * Этот файл содержит скрипт исполняелся во время процедур с формой лицензирования.
3
+ * Его основная роль отправка ajax запросов на проверку, активацию, деактивацию лицензии
4
+ * и вывод уведомлений об ошибка или успешно выполнении проверок.
5
+ *
6
+ * @author Webcraftic <wordpress.webraftic@gmail.com>
7
+ * @copyright (c) 05.10.2018, Webcraftic
8
+ * @version 1.1
9
+ * @since 1.4.0
10
+ */
11
+
12
+
13
+ jQuery(function($) {
14
+
15
+ var allNotices = [];
16
+
17
+ $(document).on('click', '.wcl-control-btn', function() {
18
+
19
+ // Скрываем все открытые этим событием уведомления
20
+ // Глобальные уведомления не трогаем
21
+
22
+ for( i = 0; i < allNotices.length; i++ ) {
23
+ $.wbcr_factory_clearfy_212.app.hideNotice(allNotices[i]);
24
+ }
25
+
26
+ $('.wcl-control-btn').hide();
27
+
28
+ var wrapper = $('#wcl-license-wrapper'),
29
+ loader = wrapper.data('loader'),
30
+ pluginClass = wrapper.data('plugin');
31
+
32
+ $(this).after('<img class="wcl-loader" src="' + loader + '">');
33
+
34
+ var data = {
35
+ action: 'wbcr-clearfy-activate-license',
36
+ _wpnonce: $('#_wpnonce').val(),
37
+ license_action: $(this).data('action'),
38
+ licensekey: ''
39
+ };
40
+
41
+ if( $(this).data('action').trim() === 'activate' ) {
42
+ data.licensekey = $('#license-key').val().trim();
43
+ data.plugin_class = pluginClass;
44
+ }
45
+
46
+ $.ajax(ajaxurl, {
47
+ type: 'post',
48
+ dataType: 'json',
49
+ data: data,
50
+ success: function(response) {
51
+ var noticeId;
52
+
53
+ if( !response || !response.success ) {
54
+
55
+ $('.wcl-control-btn').show();
56
+ $('.wcl-loader').remove();
57
+
58
+ if( response.data ) {
59
+ console.log(response.data.error_message);
60
+ noticeId = $.wbcr_factory_clearfy_212.app.showNotice('Error: [' + response.data.error_message + ']', 'danger');
61
+ allNotices.push(noticeId);
62
+ } else {
63
+ console.log(response);
64
+ }
65
+
66
+ return;
67
+ }
68
+
69
+ if( response.data && response.data.message ) {
70
+ noticeId = $.wbcr_factory_clearfy_212.app.showNotice(response.data.message, 'success');
71
+ allNotices.push(noticeId);
72
+
73
+ // todo: доработать генерацию формы, вместо перезагрузки страницы
74
+ window.location.reload();
75
+ }
76
+
77
+ },
78
+ error: function(xhr, ajaxOptions, thrownError) {
79
+
80
+ $('.wcl-control-btn').show();
81
+ $('.wcl-loader').remove();
82
+
83
+ console.log(xhr.status);
84
+ console.log(xhr.responseText);
85
+ console.log(thrownError);
86
+
87
+ var noticeId = $.wbcr_factory_clearfy_212.app.showNotice('Error: [' + thrownError + '] Status: [' + xhr.status + '] Error massage: [' + xhr.responseText + ']', 'danger');
88
+
89
+ allNotices.push(noticeId);
90
+ }
91
+ });
92
+
93
+ return false;
94
+ });
95
+
96
+ });
libs/factory/clearfy/boot.php CHANGED
@@ -1,37 +1,49 @@
1
  <?php
2
- /**
3
- * Factory clearfy
4
- *
5
- * @author Alex Kovalev <alex.kovalevv@gmail.com>
6
- * @copyright (c) 2018, Webcraftic Ltd
7
- *
8
- * @package clearfy
9
- * @since 1.0.0
10
- */
11
 
12
- // Exit if accessed directly
13
- if( !defined('ABSPATH') ) {
14
- exit;
15
- }
16
 
17
- if( defined('FACTORY_CLEARFY_200_LOADED') ) {
18
- return;
19
- }
20
- define('FACTORY_CLEARFY_200_LOADED', true);
21
 
22
- define('FACTORY_CLEARFY_200_DIR', dirname(__FILE__));
23
- define('FACTORY_CLEARFY_200_URL', plugins_url(null, __FILE__));
24
 
25
- load_plugin_textdomain('wbcr_factory_clearfy_200', false, dirname(plugin_basename(__FILE__)) . '/langs');
26
 
27
- require(FACTORY_CLEARFY_200_DIR . '/includes/class.helpers.php');
28
- require(FACTORY_CLEARFY_200_DIR . '/includes/class.configurate.php');
29
 
30
- // module provides function only for the admin area
31
- if( !is_admin() ) {
32
- return;
33
- }
34
 
35
- if( defined('FACTORY_PAGES_401_LOADED') ) {
36
- require(FACTORY_CLEARFY_200_DIR . '/pages/more-features.php');
37
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  <?php
2
+ /**
3
+ * Factory clearfy
4
+ *
5
+ * @author Alex Kovalev <alex.kovalevv@gmail.com>, Github: https://github.com/alexkovalevv
6
+ * @since 1.0.0
7
+ * @package clearfy
8
+ * @copyright (c) 2018, Webcraftic Ltd
9
+ *
10
+ */
11
 
12
+ // Exit if accessed directly
13
+ if ( ! defined( 'ABSPATH' ) ) {
14
+ exit;
15
+ }
16
 
17
+ if ( defined( 'FACTORY_CLEARFY_212_LOADED' ) ) {
18
+ return;
19
+ }
 
20
 
21
+ define( 'FACTORY_CLEARFY_212_LOADED', true );
 
22
 
23
+ define( 'FACTORY_CLEARFY_212', '2.1.2' );
24
 
25
+ define( 'FACTORY_CLEARFY_212_DIR', dirname( __FILE__ ) );
26
+ define( 'FACTORY_CLEARFY_212_URL', plugins_url( null, __FILE__ ) );
27
 
28
+ load_plugin_textdomain( 'wbcr_factory_clearfy_212', false, dirname( plugin_basename( __FILE__ ) ) . '/langs' );
 
 
 
29
 
30
+ require( FACTORY_CLEARFY_212_DIR . '/includes/ajax-handlers.php' );
31
+ require( FACTORY_CLEARFY_212_DIR . '/includes/class-helpers.php' );
32
+ require( FACTORY_CLEARFY_212_DIR . '/includes/class-configurate.php' );
33
+
34
+ // module provides function only for the admin area
35
+ if ( is_admin() ) {
36
+ /**
37
+ * Подключаем скрипты для установки компонентов Clearfy
38
+ * на все страницы админпанели.
39
+ */
40
+ add_action( 'admin_enqueue_scripts', function () {
41
+ wp_enqueue_script( 'wbcr-factory-clearfy-212-global', FACTORY_CLEARFY_212_URL . '/assets/js/globals.js', [ 'jquery' ], FACTORY_CLEARFY_212 );
42
+ } );
43
+
44
+ if ( defined( 'FACTORY_PAGES_420_LOADED' ) ) {
45
+ require( FACTORY_CLEARFY_212_DIR . '/pages/class-pages.php' );
46
+ require( FACTORY_CLEARFY_212_DIR . '/pages/class-page-more-features.php' );
47
+ require( FACTORY_CLEARFY_212_DIR . '/pages/class-page-license.php' );
48
+ }
49
+ }
libs/factory/clearfy/includes/ajax-handlers.php ADDED
@@ -0,0 +1,92 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Ajax handlers
4
+ *
5
+ * @author Alex Kovalev <alex.kovalevv@gmail.com>, Github: https://github.com/alexkovalevv
6
+ * @copyright (c) 2017 Webraftic Ltd
7
+ * @version 1.0
8
+ */
9
+
10
+ // Exit if accessed directly
11
+ if ( ! defined( 'ABSPATH' ) ) {
12
+ exit;
13
+ }
14
+
15
+ /**
16
+ * Обработчик ajax запросов для проверки, активации, деактивации лицензионного ключа
17
+ *
18
+ * @since 2.0.7
19
+ *
20
+ * @param Wbcr_Factory420_Plugin $plugin_instance
21
+ *
22
+ */
23
+ function wbcr_factory_clearfy_212_check_license( $plugin_instance ) {
24
+ check_admin_referer( 'license' );
25
+
26
+ $action = $plugin_instance->request->post( 'license_action', false, true );
27
+ $license_key = $plugin_instance->request->post( 'licensekey', null );
28
+
29
+ if ( empty( $action ) || ! in_array( $action, [ 'activate', 'deactivate', 'sync', 'unsubscribe' ] ) ) {
30
+ wp_send_json_error( [ 'error_message' => __( 'Licensing action not passed or this action is prohibited!', 'wbcr_factory_clearfy_212' ) ] );
31
+ die();
32
+ }
33
+
34
+ $result = null;
35
+ $success_message = '';
36
+
37
+ try {
38
+ switch ( $action ) {
39
+ case 'activate':
40
+ if ( empty( $license_key ) || strlen( $license_key ) > 32 ) {
41
+ wp_send_json_error( [ 'error_message' => __( 'License key is empty or license key too long (license key is 32 characters long)', 'wbcr_factory_clearfy_212' ) ] );
42
+ } else {
43
+ $plugin_instance->premium->activate( $license_key );
44
+ $success_message = __( 'Your license has been successfully activated', 'wbcr_factory_clearfy_212' );
45
+ }
46
+ break;
47
+ case 'deactivate':
48
+ $plugin_instance->premium->deactivate();
49
+ $success_message = __( 'The license is deactivated', 'wbcr_factory_clearfy_212' );
50
+ break;
51
+ case 'sync':
52
+ $plugin_instance->premium->sync();
53
+ $success_message = __( 'The license has been updated', 'wbcr_factory_clearfy_212' );
54
+ break;
55
+ case 'unsubscribe':
56
+ $plugin_instance->premium->cancel_paid_subscription();
57
+ $success_message = __( 'Subscription success cancelled', 'wbcr_factory_clearfy_212' );
58
+ break;
59
+ }
60
+ } catch( Exception $e ) {
61
+
62
+ /**
63
+ * Экшен выполняетяс, когда проверка лицензии вернула ошибку
64
+ *
65
+ * @since 2.0.7
66
+ *
67
+ * @param string $license_key
68
+ * @param string $error_message
69
+ *
70
+ * @param string $action
71
+ */
72
+ do_action( 'wbcr/clearfy/check_license_error', $action, $license_key, $e->getMessage() );
73
+
74
+ wp_send_json_error( [ 'error_message' => $e->getMessage() ] );
75
+ die();
76
+ }
77
+
78
+ /**
79
+ * Экшен выполняет, когда проверка лицензии успешно завершена
80
+ *
81
+ * @since 2.0.7
82
+ *
83
+ * @param string $license_key
84
+ *
85
+ * @param string $action
86
+ */
87
+ do_action( 'wbcr/clearfy/check_license_success', $action, $license_key );
88
+
89
+ wp_send_json_success( [ 'message' => $success_message ] );
90
+
91
+ die();
92
+ }
libs/factory/clearfy/includes/class-configurate.php ADDED
@@ -0,0 +1,116 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ // Exit if accessed directly
3
+ if ( ! defined( 'ABSPATH' ) ) {
4
+ exit;
5
+ }
6
+
7
+ /**
8
+ * Configurate clearfy plugins
9
+ *
10
+ * @author Alex Kovalev <alex.kovalevv@gmail.com>, Github: https://github.com/alexkovalevv
11
+ * @since 1.0.0
12
+ * @package clearfy
13
+ * @copyright (c) 2018, Webcraftic Ltd
14
+ *
15
+ */
16
+ abstract class Wbcr_FactoryClearfy212_Configurate {
17
+
18
+ /**
19
+ * @param Wbcr_Factory420_Plugin $plugin
20
+ */
21
+ public function __construct( Wbcr_Factory420_Plugin $plugin ) {
22
+ $this->plugin = $plugin;
23
+ $this->registerActionsAndFilters();
24
+ }
25
+
26
+ /**
27
+ * Registers filters and actions
28
+ *
29
+ * @return mixed
30
+ */
31
+ abstract protected function registerActionsAndFilters();
32
+
33
+ /**
34
+ * Get options with namespace
35
+ *
36
+ * @param $option_name
37
+ * @param bool $default
38
+ *
39
+ * @return mixed|void
40
+ */
41
+ public function getPopulateOption( $option_name, $default = false ) {
42
+ return $this->plugin->getPopulateOption( $option_name, $default );
43
+ }
44
+
45
+ /**
46
+ * Get options with namespace
47
+ *
48
+ * @param $option_name
49
+ * @param bool $default
50
+ *
51
+ * @return mixed|void
52
+ */
53
+ public function getOption( $option_name, $default = false ) {
54
+ return $this->plugin->getOption( $option_name, $default );
55
+ }
56
+
57
+ /**
58
+ * Get network options with namespace
59
+ *
60
+ * @param $option_name
61
+ * @param bool $default
62
+ *
63
+ * @return mixed|void
64
+ */
65
+ public function getNetworkOption( $option_name, $default = false ) {
66
+ return $this->plugin->getNetworkOption( $option_name, $default );
67
+ }
68
+
69
+ /**
70
+ * @param $option_name
71
+ * @param $value
72
+ *
73
+ * @return bool
74
+ */
75
+ public function updatePopulateOption( $option_name, $value ) {
76
+ $this->plugin->updatePopulateOption( $option_name, $value );
77
+ }
78
+
79
+ /**
80
+ * @param $option_name
81
+ * @param $value
82
+ *
83
+ * @return bool
84
+ */
85
+ public function updateNetworkOption( $option_name, $value ) {
86
+ $this->plugin->updateNetworkOption( $option_name, $value );
87
+ }
88
+
89
+ /**
90
+ * @param $option_name
91
+ * @param $value
92
+ *
93
+ * @return bool
94
+ */
95
+ public function updateOption( $option_name, $value ) {
96
+ $this->plugin->updateOption( $option_name, $value );
97
+ }
98
+
99
+ /**
100
+ * @param $option_name
101
+ *
102
+ * @return bool
103
+ */
104
+ public function deletePopulateOption( $option_name ) {
105
+ $this->plugin->deletePopulateOption( $option_name );
106
+ }
107
+
108
+ /**
109
+ * @param $option_name
110
+ *
111
+ * @return bool
112
+ */
113
+ public function deleteOption( $option_name ) {
114
+ $this->plugin->deleteOption( $option_name );
115
+ }
116
+ }
libs/factory/clearfy/includes/class-helpers.php ADDED
@@ -0,0 +1,362 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ // Exit if accessed directly
3
+ if ( ! defined( 'ABSPATH' ) ) {
4
+ exit;
5
+ }
6
+
7
+
8
+ /**
9
+ * Helpers functions
10
+ *
11
+ * @author Alex Kovalev <alex.kovalevv@gmail.com>, Github: https://github.com/alexkovalevv
12
+ * @since 1.0.0
13
+ * @package clearfy
14
+ * @copyright (c) 2018, Webcraftic Ltd
15
+ *
16
+ */
17
+ class WbcrFactoryClearfy212_Helpers {
18
+
19
+ /**
20
+ * Ссылка по умолчанию (анг)
21
+ */
22
+ const WEBCRAFTIC_SITE_URL = 'https://clearfy.pro';
23
+
24
+ /**
25
+ * Русская локализация сайта
26
+ */
27
+ const WEBCRAFTIC_RU_SITE_URL = 'https://ru.clearfy.pro';
28
+ /**
29
+ * Украинская локализация сайта
30
+ */
31
+ const WEBCRAFTIC_UA_SITE_URL = 'https://ua.clearfy.pro';
32
+ /**
33
+ * Испанская
34
+ */
35
+ const WEBCRAFTIC_ES_SITE_URL = 'https://es.clearfy.pro';
36
+ /**
37
+ * Французкая
38
+ */
39
+ const WEBCRAFTIC_DE_SITE_URL = 'https://de.clearfy.pro';
40
+
41
+ /**
42
+ * @since 2.0.5
43
+ *
44
+ * @param int $price
45
+ *
46
+ * @return int
47
+ */
48
+ public static function getClearfyBusinessPrice( $price = 19 ) {
49
+ return (int) apply_filters( 'wbcr/clearfy/business_price', $price );
50
+ }
51
+
52
+ /**
53
+ * @since 2.0.5
54
+ *
55
+ * @param int $price
56
+ *
57
+ * @return int
58
+ */
59
+ public static function getClearfyBusinessRevPrice( $price = 69 ) {
60
+ return (int) apply_filters( 'wbcr/clearfy/business_rev_price', $price );
61
+ }
62
+
63
+ /**
64
+ * Get a link to the official website of the developer
65
+ *
66
+ * @return string|null
67
+ */
68
+ public static function getWebcrafticSiteUrl() {
69
+ if ( get_locale() == 'ru_RU' ) {
70
+ return self::WEBCRAFTIC_RU_SITE_URL;
71
+ }
72
+
73
+ return self::WEBCRAFTIC_SITE_URL;
74
+ }
75
+
76
+ /**
77
+ * /**
78
+ * Get a link to the official website of the developer
79
+ *
80
+ * @since 2.0.5
81
+ *
82
+ * @param string $plugin_name
83
+ * @param string $page - page address
84
+ * @param string $utm_content - from which page or part of the plugin user moved to the site
85
+ * @param string $urm_source
86
+ *
87
+ * @return string
88
+ */
89
+ public static function getWebcrafticSitePageUrl( $plugin_name, $page, $utm_content = null, $urm_source = 'wordpress.org' ) {
90
+ $args = [ 'utm_source' => $urm_source ];
91
+
92
+ if ( ! empty( $plugin_name ) ) {
93
+ $args['utm_campaign'] = $plugin_name;
94
+ }
95
+
96
+ if ( ! empty( $utm_content ) ) {
97
+ $args['utm_content'] = $utm_content;
98
+ }
99
+
100
+ $raw_url = add_query_arg( $args, self::getWebcrafticSiteUrl() . '/' . $page . '/' );
101
+ $url = esc_url( $raw_url );
102
+
103
+ /**
104
+ * @param string $url
105
+ * @param string $raw_url
106
+ * @param string $plugin_name
107
+ * @param string $page - page address
108
+ * @param string $utm_content - from which page or part of the plugin user moved to the site
109
+ * @param string $urm_source
110
+ */
111
+
112
+ return apply_filters( 'wbcr/clearfy/webcraftic_site_page_url', $url, $raw_url, $plugin_name, $page, $utm_content, $urm_source );
113
+ }
114
+
115
+ /**
116
+ * Recursive sanitation for an array
117
+ *
118
+ * @since 2.0.5
119
+ *
120
+ * @param $array
121
+ *
122
+ * @return mixed
123
+ */
124
+ public static function recursiveSanitizeArray( $array, $function ) {
125
+ foreach ( $array as $key => &$value ) {
126
+ if ( is_array( $value ) ) {
127
+ $value = self::recursiveSanitizeArray( $value, $function );
128
+ } else {
129
+ if ( function_exists( $function ) ) {
130
+ $value = $function( $value );
131
+ }
132
+ }
133
+ }
134
+
135
+ return $array;
136
+ }
137
+
138
+ /**
139
+ * Is permalink enabled?
140
+ *
141
+ * @since 1.0.0
142
+ * @return bool
143
+ * @global WP_Rewrite $wp_rewrite
144
+ */
145
+ public static function isPermalink() {
146
+ global $wp_rewrite;
147
+
148
+ if ( ! isset( $wp_rewrite ) || ! is_object( $wp_rewrite ) || ! $wp_rewrite->using_permalinks() ) {
149
+ return false;
150
+ }
151
+
152
+ return true;
153
+ }
154
+
155
+ /**
156
+ * Display 404 page to bump bots and bad guys
157
+ *
158
+ * @param bool $simple If true force displaying basic 404 page
159
+ */
160
+ public static function setError404() {
161
+ global $wp_query;
162
+
163
+ if ( function_exists( 'status_header' ) ) {
164
+ status_header( '404' );
165
+ nocache_headers();
166
+ }
167
+
168
+ if ( $wp_query && is_object( $wp_query ) ) {
169
+ $wp_query->set_404();
170
+ get_template_part( 404 );
171
+ } else {
172
+ global $pagenow;
173
+
174
+ $pagenow = 'index.php';
175
+
176
+ if ( ! defined( 'WP_USE_THEMES' ) ) {
177
+ define( 'WP_USE_THEMES', true );
178
+ }
179
+
180
+ wp();
181
+
182
+ $_SERVER['REQUEST_URI'] = self::userTrailingslashit( '/hmwp_404' );
183
+
184
+ require_once( ABSPATH . WPINC . '/template-loader.php' );
185
+ }
186
+
187
+ exit();
188
+ }
189
+
190
+ public static function useTrailingSlashes() {
191
+ return ( '/' === substr( get_option( 'permalink_structure' ), - 1, 1 ) );
192
+ }
193
+
194
+ public static function userTrailingslashit( $string ) {
195
+ return self::useTrailingSlashes() ? trailingslashit( $string ) : untrailingslashit( $string );
196
+ }
197
+
198
+ /**
199
+ * Returns true if a needle can be found in a haystack
200
+ *
201
+ * @param string $string
202
+ * @param string $find
203
+ * @param bool $case_sensitive
204
+ *
205
+ * @return bool
206
+ */
207
+ public static function strContains( $string, $find, $case_sensitive = true ) {
208
+ if ( empty( $string ) || empty( $find ) ) {
209
+ return false;
210
+ }
211
+
212
+ $pos = $case_sensitive ? strpos( $string, $find ) : stripos( $string, $find );
213
+
214
+ return ! ( $pos === false );
215
+ }
216
+
217
+ /**
218
+ * Tests if a text starts with an given string.
219
+ *
220
+ * @param string $string
221
+ * @param string $find
222
+ * @param bool $case_sensitive
223
+ *
224
+ * @return bool
225
+ */
226
+ public static function strStartsWith( $string, $find, $case_sensitive = true ) {
227
+ if ( $case_sensitive ) {
228
+ return strpos( $string, $find ) === 0;
229
+ }
230
+
231
+ return stripos( $string, $find ) === 0;
232
+ }
233
+
234
+ /**
235
+ * Tests if a text ends with an given string.
236
+ *
237
+ * @param $string
238
+ * @param $find
239
+ * @param bool $case_sensitive
240
+ *
241
+ * @return bool
242
+ */
243
+ public static function strEndsWith( $string, $find, $case_sensitive = true ) {
244
+ $expected_position = strlen( $string ) - strlen( $find );
245
+
246
+ if ( $case_sensitive ) {
247
+ return strrpos( $string, $find, 0 ) === $expected_position;
248
+ }
249
+
250
+ return strripos( $string, $find, 0 ) === $expected_position;
251
+ }
252
+
253
+ public static function arrayMergeInsert( array $arr, array $inserted, $position = 'bottom', $key = null ) {
254
+ if ( $position == 'top' ) {
255
+ return array_merge( $inserted, $arr );
256
+ }
257
+ $key_position = ( $key === null ) ? false : array_search( $key, array_keys( $arr ) );
258
+ if ( $key_position === false OR ( $position != 'before' AND $position != 'after' ) ) {
259
+ return array_merge( $arr, $inserted );
260
+ }
261
+ if ( $position == 'after' ) {
262
+ $key_position ++;
263
+ }
264
+
265
+ return array_merge( array_slice( $arr, 0, $key_position, true ), $inserted, array_slice( $arr, $key_position, null, true ) );
266
+ }
267
+
268
+ public static function maybeGetPostJson( $name ) {
269
+ if ( isset( $_POST[ $name ] ) AND is_string( $_POST[ $name ] ) ) {
270
+ $result = json_decode( stripslashes( $_POST[ $name ] ), true );
271
+ if ( ! is_array( $result ) ) {
272
+ $result = [];
273
+ }
274
+
275
+ return $result;
276
+ } else {
277
+ return [];
278
+ }
279
+ }
280
+
281
+ public static function getEscapeJson( array $data ) {
282
+ return htmlspecialchars( json_encode( $data ), ENT_QUOTES, 'UTF-8' );
283
+ }
284
+
285
+ /**
286
+ * Replace url for multisite
287
+ *
288
+ * @param $string
289
+ *
290
+ * @return string
291
+ */
292
+ public static function replaceMsUrl( $string ) {
293
+ if ( is_multisite() && BLOG_ID_CURRENT_SITE != get_current_blog_id() ) {
294
+ return str_replace( get_site_url( BLOG_ID_CURRENT_SITE ), get_site_url( get_current_blog_id() ), $string );
295
+ }
296
+
297
+ return $string;
298
+ }
299
+
300
+ /*
301
+ * Flushes as many page cache plugin's caches as possible.
302
+ *
303
+ * @return void
304
+ */
305
+ public static function flushPageCache() {
306
+ if ( function_exists( 'wp_cache_clear_cache' ) ) {
307
+ if ( is_multisite() ) {
308
+ $blog_id = get_current_blog_id();
309
+ wp_cache_clear_cache( $blog_id );
310
+ } else {
311
+ wp_cache_clear_cache();
312
+ }
313
+ } else if ( has_action( 'cachify_flush_cache' ) ) {
314
+ do_action( 'cachify_flush_cache' );
315
+ } else if ( function_exists( 'w3tc_pgcache_flush' ) ) {
316
+ w3tc_pgcache_flush();
317
+ } else if ( function_exists( 'wp_fast_cache_bulk_delete_all' ) ) {
318
+ wp_fast_cache_bulk_delete_all();
319
+ } else if ( class_exists( 'WpFastestCache' ) ) {
320
+ $wpfc = new WpFastestCache();
321
+ $wpfc->deleteCache();
322
+ } else if ( class_exists( 'c_ws_plugin__qcache_purging_routines' ) ) {
323
+ c_ws_plugin__qcache_purging_routines::purge_cache_dir(); // quick cache
324
+ } else if ( class_exists( 'zencache' ) ) {
325
+ zencache::clear();
326
+ } else if ( class_exists( 'comet_cache' ) ) {
327
+ comet_cache::clear();
328
+ } else if ( class_exists( 'WpeCommon' ) ) {
329
+ // WPEngine cache purge/flush methods to call by default
330
+ $wpe_methods = [
331
+ 'purge_varnish_cache',
332
+ ];
333
+
334
+ // More agressive clear/flush/purge behind a filter
335
+ if ( apply_filters( 'wbcr/factory/flush_wpengine_aggressive', false ) ) {
336
+ $wpe_methods = array_merge( $wpe_methods, [ 'purge_memcached', 'clear_maxcdn_cache' ] );
337
+ }
338
+
339
+ // Filtering the entire list of WpeCommon methods to be called (for advanced usage + easier testing)
340
+ $wpe_methods = apply_filters( 'wbcr/factory/wpengine_methods', $wpe_methods );
341
+
342
+ foreach ( $wpe_methods as $wpe_method ) {
343
+ if ( method_exists( 'WpeCommon', $wpe_method ) ) {
344
+ WpeCommon::$wpe_method();
345
+ }
346
+ }
347
+ } else if ( function_exists( 'sg_cachepress_purge_cache' ) ) {
348
+ sg_cachepress_purge_cache();
349
+ } else if ( file_exists( WP_CONTENT_DIR . '/wp-cache-config.php' ) && function_exists( 'prune_super_cache' ) ) {
350
+ // fallback for WP-Super-Cache
351
+ global $cache_path;
352
+ if ( is_multisite() ) {
353
+ $blog_id = get_current_blog_id();
354
+ prune_super_cache( get_supercache_dir( $blog_id ), true );
355
+ prune_super_cache( $cache_path . 'blogs/', true );
356
+ } else {
357
+ prune_super_cache( $cache_path . 'supercache/', true );
358
+ prune_super_cache( $cache_path, true );
359
+ }
360
+ }
361
+ }
362
+ }
libs/factory/clearfy/includes/class.configurate.php DELETED
@@ -1,67 +0,0 @@
1
- <?php
2
- /**
3
- * Configurate clearfy plugins
4
- *
5
- * @author Alex Kovalev <alex.kovalevv@gmail.com>
6
- * @copyright (c) 2018, Webcraftic Ltd
7
- *
8
- * @package clearfy
9
- * @since 1.0.0
10
- */
11
-
12
- // Exit if accessed directly
13
- if( !defined('ABSPATH') ) {
14
- exit;
15
- }
16
-
17
- if( !class_exists('Wbcr_FactoryClearfy200_Configurate') ) {
18
-
19
- abstract class Wbcr_FactoryClearfy200_Configurate {
20
-
21
- /**
22
- * @param Wbcr_Factory400_Plugin $plugin
23
- */
24
- public function __construct(Wbcr_Factory400_Plugin $plugin)
25
- {
26
- $this->plugin = $plugin;
27
- $this->registerActionsAndFilters();
28
- }
29
-
30
- /**
31
- * Registers filters and actions
32
- * @return mixed
33
- */
34
- abstract protected function registerActionsAndFilters();
35
-
36
- /**
37
- * Get options with namespace
38
- *
39
- * @param $option_name
40
- * @param bool $default
41
- * @return mixed|void
42
- */
43
- public function getOption($option_name, $default = false)
44
- {
45
- return $this->plugin->getOption($option_name, $default);
46
- }
47
-
48
- /**
49
- * @param $option_name
50
- * @param $value
51
- * @return bool
52
- */
53
- public function updateOption($option_name, $value)
54
- {
55
- $this->plugin->updateOption($option_name, $value);
56
- }
57
-
58
- /**
59
- * @param $option_name
60
- * @return bool
61
- */
62
- public function deleteOption($option_name)
63
- {
64
- $this->plugin->deleteOption($option_name);
65
- }
66
- }
67
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
libs/factory/clearfy/includes/class.helpers.php DELETED
@@ -1,180 +0,0 @@
1
- <?php
2
-
3
- /**
4
- * Helpers functions
5
- *
6
- * @author Alex Kovalev <alex.kovalevv@gmail.com>
7
- * @copyright (c) 2018, Webcraftic Ltd
8
- *
9
- * @package clearfy
10
- * @since 1.0.0
11
- */
12
-
13
- // Exit if accessed directly
14
- if( !defined('ABSPATH') ) {
15
- exit;
16
- }
17
-
18
- if( !class_exists('WbcrFactoryClearfy200_Helpers') ) {
19
- class WbcrFactoryClearfy200_Helpers {
20
-
21
- /**
22
- * Is permalink enabled?
23
- * @global WP_Rewrite $wp_rewrite
24
- * @since 1.0.0
25
- * @return bool
26
- */
27
- public static function isPermalink()
28
- {
29
- global $wp_rewrite;
30
-
31
- if( !isset($wp_rewrite) || !is_object($wp_rewrite) || !$wp_rewrite->using_permalinks() ) {
32
- return false;
33
- }
34
-
35
- return true;
36
- }
37
-
38
- /**
39
- * Display 404 page to bump bots and bad guys
40
- *
41
- * @param bool $simple If true force displaying basic 404 page
42
- */
43
- public static function setError404()
44
- {
45
- global $wp_query;
46
-
47
- if( function_exists('status_header') ) {
48
- status_header('404');
49
- nocache_headers();
50
- }
51
-
52
- if( $wp_query && is_object($wp_query) ) {
53
- $wp_query->set_404();
54
- get_template_part(404);
55
- } else {
56
- global $pagenow;
57
-
58
- $pagenow = 'index.php';
59
-
60
- if( !defined('WP_USE_THEMES') ) {
61
- define('WP_USE_THEMES', true);
62
- }
63
-
64
- wp();
65
-
66
- $_SERVER['REQUEST_URI'] = self::userTrailingslashit('/hmwp_404');
67
-
68
- require_once(ABSPATH . WPINC . '/template-loader.php');
69
- }
70
-
71
- exit();
72
- }
73
-
74
- public static function useTrailingSlashes()
75
- {
76
- return ('/' === substr(get_option('permalink_structure'), -1, 1));
77
- }
78
-
79
- public static function userTrailingslashit($string)
80
- {
81
- return self::useTrailingSlashes()
82
- ? trailingslashit($string)
83
- : untrailingslashit($string);
84
- }
85
-
86
- /**
87
- * Returns true if a needle can be found in a haystack
88
- *
89
- * @param string $string
90
- * @param string $find
91
- * @param bool $case_sensitive
92
- * @return bool
93
- */
94
- public static function strContains($string, $find, $case_sensitive = true)
95
- {
96
- if( empty($string) || empty($find) ) {
97
- return false;
98
- }
99
-
100
- $pos = $case_sensitive
101
- ? strpos($string, $find)
102
- : stripos($string, $find);
103
-
104
- return !($pos === false);
105
- }
106
-
107
- /**
108
- * Tests if a text starts with an given string.
109
- *
110
- * @param string $string
111
- * @param string $find
112
- * @param bool $case_sensitive
113
- * @return bool
114
- */
115
- public static function strStartsWith($string, $find, $case_sensitive = true)
116
- {
117
- if( $case_sensitive ) {
118
- return strpos($string, $find) === 0;
119
- }
120
-
121
- return stripos($string, $find) === 0;
122
- }
123
-
124
- /**
125
- * Tests if a text ends with an given string.
126
- *
127
- * @param $string
128
- * @param $find
129
- * @param bool $case_sensitive
130
- * @return bool
131
- */
132
- public static function strEndsWith($string, $find, $case_sensitive = true)
133
- {
134
- $expected_position = strlen($string) - strlen($find);
135
-
136
- if( $case_sensitive ) {
137
- return strrpos($string, $find, 0) === $expected_position;
138
- }
139
-
140
- return strripos($string, $find, 0) === $expected_position;
141
- }
142
-
143
- public static function arrayMergeInsert(array $arr, array $inserted, $position = 'bottom', $key = null)
144
- {
145
- if( $position == 'top' ) {
146
- return array_merge($inserted, $arr);
147
- }
148
- $key_position = ($key === null)
149
- ? false
150
- : array_search($key, array_keys($arr));
151
- if( $key_position === false OR ($position != 'before' AND $position != 'after') ) {
152
- return array_merge($arr, $inserted);
153
- }
154
- if( $position == 'after' ) {
155
- $key_position++;
156
- }
157
-
158
- return array_merge(array_slice($arr, 0, $key_position, true), $inserted, array_slice($arr, $key_position, null, true));
159
- }
160
-
161
- public static function maybeGetPostJson($name)
162
- {
163
- if( isset($_POST[$name]) AND is_string($_POST[$name]) ) {
164
- $result = json_decode(stripslashes($_POST[$name]), true);
165
- if( !is_array($result) ) {
166
- $result = array();
167
- }
168
-
169
- return $result;
170
- } else {
171
- return array();
172
- }
173
- }
174
-
175
- public static function getEscapeJson(array $data)
176
- {
177
- return htmlspecialchars(json_encode($data), ENT_QUOTES, 'UTF-8');
178
- }
179
- }
180
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
{admin/assets/css → libs/factory/clearfy/includes}/index.php RENAMED
File without changes
{admin/assets → libs/factory/clearfy}/index.php RENAMED
File without changes
libs/factory/clearfy/langs/wbcr_factory_clearfy_200-fr-FR.mo DELETED
Binary file
libs/factory/clearfy/langs/wbcr_factory_clearfy_200-fr-FR.po DELETED
@@ -1,129 +0,0 @@
1
- msgid ""
2
- msgstr ""
3
- "Project-Id-Version: clearfy\n"
4
- "POT-Creation-Date: 2017-11-09 10:35+0300\n"
5
- "PO-Revision-Date: 2017-11-09 13:50+0100\n"
6
- "Last-Translator: alex.kovalevv@gmail.com <alex.kovalevv@gmail.com>\n"
7
- "Language-Team: Alex Kovalev <alex.kovalevv@gmail.com>\n"
8
- "Language: fr\n"
9
- "MIME-Version: 1.0\n"
10
- "Content-Type: text/plain; charset=UTF-8\n"
11
- "Content-Transfer-Encoding: 8bit\n"
12
- "X-Generator: Poedit 2.0.4\n"
13
- "X-Poedit-Basepath: ..\n"
14
- "Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
15
- "%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
16
- "X-Poedit-SourceCharset: UTF-8\n"
17
- "X-Poedit-KeywordsList: __;_e;_n:1,2;_x:1,2c;_ex:1,2c\n"
18
- "X-Poedit-SearchPath-0: .\n"
19
-
20
- #: pages/more-features.php:29
21
- msgid "More features (<b>free</b>)"
22
- msgstr "Plus de fonctionnalités (<b>gratuit</b>)"
23
-
24
- #: pages/more-features.php:36
25
- msgid "install the ultimate version of the plugin for free!"
26
- msgstr "installez la version ultime du plugin gratuitement!"
27
-
28
- #: pages/more-features.php:47
29
- msgid "Code cleaning"
30
- msgstr "Nettoyage du code"
31
-
32
- #: pages/more-features.php:49
33
- msgid "Clears the source code of the page from unused code."
34
- msgstr "Efface le code source de la page du code inutilisé."
35
-
36
- #: pages/more-features.php:56
37
- msgid "Improve SEO"
38
- msgstr "Améliorer le référencement"
39
-
40
- #: pages/more-features.php:58
41
- msgid ""
42
- "Removes duplicate pages, closes external links, changes the headers of the "
43
- "server."
44
- msgstr ""
45
- "Supprime les pages en double, ferme les liens externes, modifie les en-têtes "
46
- "du serveur."
47
-
48
- #: pages/more-features.php:65
49
- msgid "Site ptotection"
50
- msgstr "Protection du site"
51
-
52
- #: pages/more-features.php:67
53
- msgid "Enables and disables features that improve the protection of your site."
54
- msgstr ""
55
- "Active et désactive les fonctionnalités qui améliorent la protection de "
56
- "votre site."
57
-
58
- #: pages/more-features.php:74
59
- msgid "Disable comments"
60
- msgstr "Désactiver les commentaires"
61
-
62
- #: pages/more-features.php:76
63
- msgid "Disables comments on the entire site or on specific pages."
64
- msgstr ""
65
- "Désactive les commentaires sur l'intégralité du site ou sur des pages "
66
- "spécifiques."
67
-
68
- #: pages/more-features.php:83
69
- msgid "Manage updates"
70
- msgstr "Gérer les mises à jour"
71
-
72
- #: pages/more-features.php:85
73
- msgid ""
74
- "Enables or disables automatically updates for plugins, themes and core. It "
75
- "is also possible\n"
76
- "\t\t\t\t\t\t\tto disable all updates."
77
- msgstr ""
78
- "Active ou désactive automatiquement les mises à jour pour les plugins, les "
79
- "thèmes et le core. C'est aussi possible\n"
80
- "\t\t\t\t\t\t\tdésactiver toutes les mises à jour."
81
-
82
- #: pages/more-features.php:93
83
- msgid "Manage widgets"
84
- msgstr "Gérer les widgets"
85
-
86
- #: pages/more-features.php:95
87
- msgid "Allows you to remove unused widgets."
88
- msgstr "Vous permet de supprimer les widgets inutilisés."
89
-
90
- #: pages/more-features.php:102
91
- msgid "Speed Optimization"
92
- msgstr "Optimisation de la vitesse"
93
-
94
- #: pages/more-features.php:104
95
- msgid ""
96
- "Increases performance by disabling unused functions and reducing the number "
97
- "of requests."
98
- msgstr ""
99
- "Augmente les performances en désactivant les fonctions inutilisées et en "
100
- "réduisant le nombre de requêtes."
101
-
102
- #: pages/more-features.php:111
103
- msgid "Site privacy"
104
- msgstr "Confidentialité du site"
105
-
106
- #: pages/more-features.php:113
107
- msgid ""
108
- "Allows you to hide the version of the site and plugins. Allows you to hide "
109
- "your\n"
110
- "\t\t\t\t\t\t\tWordPress."
111
- msgstr ""
112
- "Vous permet de masquer la version du site et des plugins. Vous permet de "
113
- "cacher votre\n"
114
- "\t\t\t\t\t\t\tWordPress."
115
-
116
- #: pages/more-features.php:121
117
- msgid "Easy setup"
118
- msgstr "Configuration facile"
119
-
120
- #: pages/more-features.php:123
121
- msgid ""
122
- "In quick mode, you can easily configure the plugin according to your needs."
123
- msgstr ""
124
- "En mode rapide, vous pouvez facilement configurer le plugin en fonction de "
125
- "vos besoins."
126
-
127
- #: pages/more-features.php:130
128
- msgid "Get the ultimate plugin 100% FREE"
129
- msgstr "Obtenez le plugin ultime 100% GRATUIT"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
libs/factory/clearfy/langs/wbcr_factory_clearfy_200-ru_RU.mo DELETED
Binary file
libs/factory/clearfy/langs/wbcr_factory_clearfy_200-ru_RU.po DELETED
@@ -1,124 +0,0 @@
1
- msgid ""
2
- msgstr ""
3
- "Project-Id-Version: clearfy\n"
4
- "POT-Creation-Date: 2017-10-14 13:50+0300\n"
5
- "PO-Revision-Date: 2017-10-14 13:50+0300\n"
6
- "Last-Translator: alex.kovalevv@gmail.com <alex.kovalevv@gmail.com>\n"
7
- "Language-Team: Alex Kovalev <alex.kovalevv@gmail.com>\n"
8
- "Language: ru_RU\n"
9
- "MIME-Version: 1.0\n"
10
- "Content-Type: text/plain; charset=UTF-8\n"
11
- "Content-Transfer-Encoding: 8bit\n"
12
- "X-Generator: Poedit 1.8.8\n"
13
- "X-Poedit-Basepath: ..\n"
14
- "Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
15
- "%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
16
- "X-Poedit-SourceCharset: UTF-8\n"
17
- "X-Poedit-KeywordsList: __;_e;_n:1,2;_x:1,2c;_ex:1,2c\n"
18
- "X-Poedit-SearchPath-0: .\n"
19
-
20
- #: pages/more-features.php:27
21
- msgid "More features (<b>free</b>)"
22
- msgstr "Дополнительно"
23
-
24
- #: pages/more-features.php:34
25
- msgid "install the ultimate version of the plugin for free!"
26
- msgstr "установите полную версию плагина бесплатно!"
27
-
28
- #: pages/more-features.php:45
29
- msgid "Code cleaning"
30
- msgstr "Очищает код"
31
-
32
- #: pages/more-features.php:47
33
- msgid "Clears the source code of the page from unused code."
34
- msgstr "Очищает исходный код страницы от неиспользуемого кода."
35
-
36
- #: pages/more-features.php:54
37
- msgid "Improve SEO"
38
- msgstr "Улучшает SEO"
39
-
40
- #: pages/more-features.php:56
41
- msgid ""
42
- "Removes duplicate pages, closes external links, changes the headers of the "
43
- "server."
44
- msgstr ""
45
- "Удаляет дубликаты страниц, закрывает внешние ссылки, изменяет заголовки "
46
- "сервера."
47
-
48
- #: pages/more-features.php:63
49
- msgid "Site ptotection"
50
- msgstr "Защищает ваш сайт"
51
-
52
- #: pages/more-features.php:65
53
- msgid "Enables and disables features that improve the protection of your site."
54
- msgstr "Включает и отключает функции, которые улучшают защиту вашего сайта."
55
-
56
- #: pages/more-features.php:72
57
- msgid "Disable comments"
58
- msgstr "Отключает комментарии"
59
-
60
- #: pages/more-features.php:74
61
- msgid "Disables comments on the entire site or on specific pages."
62
- msgstr "Отключает комментарии на всем сайте или у определенных страниц."
63
-
64
- #: pages/more-features.php:81
65
- msgid "Manage updates"
66
- msgstr "Менеджер обновлений"
67
-
68
- #: pages/more-features.php:83
69
- msgid ""
70
- "Enables or disables automatically updates for plugins, themes and core. It "
71
- "is also possible\n"
72
- "\t\t\t\t\t\t\tto disable all updates."
73
- msgstr ""
74
- "Включает или отключает автоматические обновление плагинов, тем и ядра. Также "
75
- "возможно\n"
76
- "отключение всех обновлений."
77
-
78
- #: pages/more-features.php:91
79
- msgid "Manage widgets"
80
- msgstr "Управление виджетами"
81
-
82
- #: pages/more-features.php:93
83
- msgid "Allows you to remove unused widgets."
84
- msgstr "Позволяет удалить неиспользуемые виджеты."
85
-
86
- #: pages/more-features.php:100
87
- msgid "Speed Optimization"
88
- msgstr "Оптимизация производительности"
89
-
90
- #: pages/more-features.php:102
91
- msgid ""
92
- "Increases performance by disabling unused functions and reducing the number "
93
- "of requests."
94
- msgstr ""
95
- "Повышает производительность, отключая неиспользуемые функции и уменьшая "
96
- "количество запросов."
97
-
98
- #: pages/more-features.php:109
99
- msgid "Site privacy"
100
- msgstr "Конфиденциальность сайта"
101
-
102
- #: pages/more-features.php:111
103
- msgid ""
104
- "Allows you to hide the version of the site and plugins. Allows you to hide "
105
- "your\n"
106
- "\t\t\t\t\t\t\tWordPress."
107
- msgstr ""
108
- "Позволяет скрыть версию сайта и плагинов. Позволяет скрыть ваш\n"
109
- "WordPress."
110
-
111
- #: pages/more-features.php:119
112
- msgid "Easy setup"
113
- msgstr "Простая настройка"
114
-
115
- #: pages/more-features.php:121
116
- msgid ""
117
- "In quick mode, you can easily configure the plugin according to your needs."
118
- msgstr ""
119
- "В быстром режиме вы можете легко настроить плагин в соответствии с вашими "
120
- "потребностями."
121
-
122
- #: pages/more-features.php:128
123
- msgid "Get the ultimate plugin 100% FREE"
124
- msgstr "Получить полную версию бесплатно на 100%"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
libs/factory/clearfy/langs/wbcr_factory_clearfy_212-ru_RU.mo ADDED
Binary file
libs/factory/clearfy/langs/wbcr_factory_clearfy_212-ru_RU.po ADDED
@@ -0,0 +1,307 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ msgid ""
2
+ msgstr ""
3
+ "Project-Id-Version: clearfy\n"
4
+ "POT-Creation-Date: 2018-10-16 22:37+0300\n"
5
+ "PO-Revision-Date: 2018-10-16 22:41+0300\n"
6
+ "Last-Translator: alex.kovalevv@gmail.com <alex.kovalevv@gmail.com>\n"
7
+ "Language-Team: Alex Kovalev <alex.kovalevv@gmail.com>\n"
8
+ "Language: ru_RU\n"
9
+ "MIME-Version: 1.0\n"
10
+ "Content-Type: text/plain; charset=UTF-8\n"
11
+ "Content-Transfer-Encoding: 8bit\n"
12
+ "X-Generator: Poedit 2.1.1\n"
13
+ "X-Poedit-Basepath: ..\n"
14
+ "Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
15
+ "%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
16
+ "X-Poedit-SourceCharset: UTF-8\n"
17
+ "X-Poedit-KeywordsList: __;_e;_n:1,2;_x:1,2c;_ex:1,2c\n"
18
+ "X-Poedit-SearchPath-0: .\n"
19
+
20
+ #: includes/check-clearfy-compatibility.php:265
21
+ msgid "Clearfy warning"
22
+ msgstr "Clearfy предупреждение"
23
+
24
+ #: includes/check-clearfy-compatibility.php:266
25
+ #, php-format
26
+ msgid "The %s component"
27
+ msgstr "Работа компонента %s"
28
+
29
+ #: includes/check-clearfy-compatibility.php:268
30
+ msgid "warning"
31
+ msgstr "предупреждение"
32
+
33
+ #: includes/check-clearfy-compatibility.php:269
34
+ #, php-format
35
+ msgid "The %s plugin"
36
+ msgstr "Работа плагина %s"
37
+
38
+ #: includes/check-clearfy-compatibility.php:272
39
+ msgid "has stopped."
40
+ msgstr "была остановлена."
41
+
42
+ #: includes/check-clearfy-compatibility.php:273
43
+ msgid "Possible reasons:"
44
+ msgstr "Возможные причины:"
45
+
46
+ #: includes/check-clearfy-compatibility.php:279
47
+ #, php-format
48
+ msgid "You need to update the PHP version to %s or higher!"
49
+ msgstr "Вам нужно обновить версию PHP до %s или выше!"
50
+
51
+ #: includes/check-clearfy-compatibility.php:284
52
+ #, php-format
53
+ msgid "You need to update WordPress to %s or higher!"
54
+ msgstr "Вам нужно обновить WordPress до %s или выше!"
55
+
56
+ #: includes/check-clearfy-compatibility.php:289
57
+ #, php-format
58
+ msgid "You need to update the Clearfy plugin version to %s or higher!"
59
+ msgstr "Вам нужно обновить версию плагина Clearfy до %s или выше!"
60
+
61
+ #: includes/check-clearfy-compatibility.php:294
62
+ msgid "This plugin is already activated, you are trying to activate it again."
63
+ msgstr "Этот плагин уже активирован, вы пытаетесь активировать его снова."
64
+
65
+ #: includes/check-clearfy-compatibility.php:299
66
+ #, php-format
67
+ msgid ""
68
+ "Clearfy has the features of the %s plugin. Please, deactivate %s to avoid "
69
+ "conflicts of plugins!"
70
+ msgstr ""
71
+ "Плагин Clearfy уже включает в себя функции плагина %s. Пожалуйста, "
72
+ "деактивируйте плагин %s, чтобы не создавать конфликтов!"
73
+
74
+ #: pages/class.pages.php:212
75
+ msgid "Upgrade to Clearfy Business"
76
+ msgstr "Перейти на Clearfy Бизнес"
77
+
78
+ #: pages/class.pages.php:213
79
+ msgid "Oops... Sorry for the inconvenience caused!"
80
+ msgstr "Упс... Мы приносим свои извинения за неудобства!"
81
+
82
+ #: pages/class.pages.php:214
83
+ msgid ""
84
+ "Complete multisite support is available in Clearfy Business and Clearfy "
85
+ "Business Revolution packages only!"
86
+ msgstr ""
87
+ "Полная поддержка мультисайтов доступна только в пакете Clearfy Бизнес и "
88
+ "Clearfy Бизнес Революция!"
89
+
90
+ #: pages/class.pages.php:215
91
+ msgid ""
92
+ "You can activate the plugin on each website and use it with zero "
93
+ "limitations. But you can’t save the plugin’s settings under the Super "
94
+ "Administrator role!"
95
+ msgstr ""
96
+ "Вы можете активировать плагин отдельно для каждого сайта и использовать его "
97
+ "без ограничений, но в режиме суперадминистратора, вы не можете сохранять "
98
+ "настройки плагина!"
99
+
100
+ #: pages/class.pages.php:217
101
+ msgid "Activate license "
102
+ msgstr "Активировать лицензию "
103
+
104
+ #: pages/class.pages.php:218
105
+ #, php-format
106
+ msgid "Upgrade to Clearfy Business for $%d"
107
+ msgstr "Обновить до Clearfy Бизнес за $%d"
108
+
109
+ #: pages/class.pages.php:273
110
+ msgid "MORE IN CLEARFY <span>BUSINESS</span>"
111
+ msgstr "ЛУЧШЕЕ В CLEARFY <span>БИЗНЕС</span>"
112
+
113
+ #: pages/class.pages.php:275
114
+ msgid "4 premium components now;"
115
+ msgstr "4 премиум компонента сейчас;"
116
+
117
+ #: pages/class.pages.php:276
118
+ msgid "40 new premium components within a year for the single price;"
119
+ msgstr "40 новых премиум компонентов в год по одной цене;"
120
+
121
+ #: pages/class.pages.php:277
122
+ msgid "Multisite support;"
123
+ msgstr "Поддержка мультисайтов;"
124
+
125
+ #: pages/class.pages.php:278
126
+ msgid "Advanced settings;"
127
+ msgstr "Дополнительные настройки;"
128
+
129
+ #: pages/class.pages.php:279
130
+ msgid "No ads;"
131
+ msgstr "Нет рекламы;"
132
+
133
+ #: pages/class.pages.php:280
134
+ msgid "Perfect support."
135
+ msgstr "Лучшая поддержка."
136
+
137
+ #: pages/class.pages.php:283
138
+ #, php-format
139
+ msgid "Upgrade for $%s"
140
+ msgstr "Обновиться за $%s"
141
+
142
+ #: pages/class.pages.php:299
143
+ msgid ""
144
+ "A neutral setting that can not harm your site, but you must be sure that you "
145
+ "need to use it."
146
+ msgstr ""
147
+ "Нейтральная настройка, которая не может нанести вред вашему сайту, но вы "
148
+ "должны быть уверены, что вам нужно ее использовать."
149
+
150
+ #: pages/class.pages.php:305
151
+ msgid ""
152
+ "When set this option, you must be careful. Plugins and themes may depend on "
153
+ "this function. You must be sure that you can disable this feature for the "
154
+ "site."
155
+ msgstr ""
156
+ "При включении этой настройки, вы должны быть осторожны. Некоторые плагины и "
157
+ "темы могут зависеть от этой функции. Вы должны быть уверены, что эту функцию "
158
+ "можно отключить для сайта."
159
+
160
+ #: pages/class.pages.php:311
161
+ msgid "Absolutely safe setting, We recommend to use."
162
+ msgstr "Абсолютно безопасная настройка, рекомендуем использовать."
163
+
164
+ #: pages/class.pages.php:316
165
+ msgid "Hover to the icon to get help for the feature you selected."
166
+ msgstr ""
167
+ "Наведите указатель мыши на значок, чтобы получить справку по выбранной "
168
+ "функции."
169
+
170
+ #: pages/class.pages.php:334
171
+ msgid "Do you want the plugin to improved and update?"
172
+ msgstr "Вы хотите, чтобы плагин улучшался и обновлялся?"
173
+
174
+ #: pages/class.pages.php:337
175
+ msgid ""
176
+ "Help the author, leave a review on wordpress.org. Thanks to feedback, I will "
177
+ "know that the plugin is really useful to you and is needed."
178
+ msgstr ""
179
+ "Помогите автору, оставьте отзыв на wordpress.org. Благодаря отзывам, я буду "
180
+ "знать, что плагин действительно полезен для вас и необходим."
181
+
182
+ #: pages/class.pages.php:339
183
+ msgid "And also write your ideas on how to extend or improve the plugin."
184
+ msgstr "А также напишите свои идеи о том, как расширить или улучшить плагин."
185
+
186
+ #: pages/class.pages.php:344
187
+ msgid "Go rate us and push ideas"
188
+ msgstr "Оставить отзыв или поделиться идеей"
189
+
190
+ #: pages/class.pages.php:356
191
+ msgid "Donation for plugin development"
192
+ msgstr "Пожертвования на развитие плагина"
193
+
194
+ #: pages/more-features.php:31
195
+ msgid "More features (<b>free</b>)"
196
+ msgstr "Дополнительно"
197
+
198
+ #: pages/more-features.php:40
199
+ msgid "install the ultimate version of the plugin for free!"
200
+ msgstr "установите полную версию плагина бесплатно!"
201
+
202
+ #: pages/more-features.php:51
203
+ msgid "Code cleaning"
204
+ msgstr "Очищает код"
205
+
206
+ #: pages/more-features.php:53
207
+ msgid "Clears the source code of the page from unused code."
208
+ msgstr "Очищает исходный код страницы от неиспользуемого кода."
209
+
210
+ #: pages/more-features.php:60
211
+ msgid "Improve SEO"
212
+ msgstr "Улучшает SEO"
213
+
214
+ #: pages/more-features.php:62
215
+ msgid ""
216
+ "Removes duplicate pages, closes external links, changes the headers of the "
217
+ "server."
218
+ msgstr ""
219
+ "Удаляет дубликаты страниц, закрывает внешние ссылки, изменяет заголовки "
220
+ "сервера."
221
+
222
+ #: pages/more-features.php:69
223
+ msgid "Site protection"
224
+ msgstr "Защита сайта"
225
+
226
+ #: pages/more-features.php:71
227
+ msgid "Enables and disables features that improve the protection of your site."
228
+ msgstr "Включает и отключает функции, которые улучшают защиту вашего сайта."
229
+
230
+ #: pages/more-features.php:78
231
+ msgid "Disable comments"
232
+ msgstr "Отключает комментарии"
233
+
234
+ #: pages/more-features.php:80
235
+ msgid "Disables comments on the entire site or on specific pages."
236
+ msgstr "Отключает комментарии на всем сайте или у определенных страниц."
237
+
238
+ #: pages/more-features.php:87
239
+ msgid "Manage updates"
240
+ msgstr "Менеджер обновлений"
241
+
242
+ #: pages/more-features.php:89
243
+ msgid ""
244
+ "Enables or disables automatically updates for plugins, themes and core. It "
245
+ "is also possible\n"
246
+ "\t\t\t\t\t\t\tto disable all updates."
247
+ msgstr ""
248
+ "Включает или отключает автоматические обновление плагинов, тем и ядра. Также "
249
+ "возможно\n"
250
+ "отключение всех обновлений."
251
+
252
+ #: pages/more-features.php:97
253
+ msgid "Manage widgets"
254
+ msgstr "Управление виджетами"
255
+
256
+ #: pages/more-features.php:99
257
+ msgid "Allows you to remove unused widgets."
258
+ msgstr "Позволяет удалить неиспользуемые виджеты."
259
+
260
+ #: pages/more-features.php:106
261
+ msgid "Speed Optimization"
262
+ msgstr "Оптимизация производительности"
263
+
264
+ #: pages/more-features.php:108
265
+ msgid ""
266
+ "Increases performance by disabling unused functions and reducing the number "
267
+ "of requests."
268
+ msgstr ""
269
+ "Повышает производительность, отключая неиспользуемые функции и уменьшая "
270
+ "количество запросов."
271
+
272
+ #: pages/more-features.php:115
273
+ msgid "Site privacy"
274
+ msgstr "Конфиденциальность сайта"
275
+
276
+ #: pages/more-features.php:117
277
+ msgid ""
278
+ "Allows you to hide the version of the site and plugins. Allows you to hide "
279
+ "your\n"
280
+ "\t\t\t\t\t\t\tWordPress."
281
+ msgstr ""
282
+ "Позволяет скрыть версию сайта и плагинов. Позволяет скрыть ваш\n"
283
+ "WordPress."
284
+
285
+ #: pages/more-features.php:125
286
+ msgid "Easy setup"
287
+ msgstr "Простая настройка"
288
+
289
+ #: pages/more-features.php:127
290
+ msgid ""
291
+ "In quick mode, you can easily configure the plugin according to your needs."
292
+ msgstr ""
293
+ "В быстром режиме вы можете легко настроить плагин в соответствии с вашими "
294
+ "потребностями."
295
+
296
+ #: pages/more-features.php:142
297
+ msgid "Get the ultimate plugin 100% FREE"
298
+ msgstr "Получить полную версию бесплатно на 100%."
299
+
300
+ #~ msgid "component"
301
+ #~ msgstr "компонент"
302
+
303
+ #~ msgid "plugin"
304
+ #~ msgstr "плагин"
305
+
306
+ #~ msgid "Site ptotection"
307
+ #~ msgstr "Защищает ваш сайт"
libs/factory/clearfy/pages/class-page-license.php ADDED
@@ -0,0 +1,365 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ // Exit if accessed directly
4
+ if ( ! defined( 'ABSPATH' ) ) {
5
+ exit;
6
+ }
7
+
8
+ /**
9
+ * Class Wbcr_FactoryLicense000_LicensePage is used as template to display form to active premium functionality.
10
+ *
11
+ * @author Alex Kovalev <alex.kovalevv@gmail.com>, Github: https://github.com/alexkovalevv
12
+ * @since 2.0.7
13
+ */
14
+ class Wbcr_FactoryClearfy212_LicensePage extends Wbcr_FactoryClearfy212_PageBase {
15
+
16
+ /**
17
+ * {@inheritdoc}
18
+ */
19
+ public $type = "page";
20
+
21
+ /**
22
+ * {@inheritdoc}
23
+ */
24
+ public $page_menu_dashicon = 'dashicons-admin-network';
25
+
26
+ /**
27
+ * {@inheritdoc}
28
+ */
29
+ public $show_right_sidebar_in_options = false;
30
+
31
+ /**
32
+ * {@inheritdoc}
33
+ */
34
+ public $page_menu_position = 0;
35
+
36
+ /**
37
+ * {@inheritdoc}
38
+ */
39
+ public $available_for_multisite = true;
40
+
41
+ /**
42
+ * @var string Name of the paid plan.
43
+ */
44
+ public $plan_name;
45
+
46
+ // PREMIUM SECTION
47
+ // ------------------------------------------------------------------
48
+ /**
49
+ * @since 2.0.7
50
+ * @var bool
51
+ */
52
+ protected $is_premium;
53
+
54
+ /**
55
+ * @since 2.0.7
56
+ * @var \WBCR\Factory_420\Premium\Provider
57
+ */
58
+ protected $premium;
59
+
60
+ /**
61
+ * @since 2.0.7
62
+ * @var bool
63
+ */
64
+ protected $is_premium_active;
65
+
66
+ /**
67
+ * @since 2.0.7
68
+ * @var bool
69
+ */
70
+ protected $premium_has_subscription;
71
+
72
+ /**
73
+ * @since 2.0.7
74
+ * @var \WBCR\Factory_420\Premium\Interfaces\License
75
+ */
76
+ protected $premium_license;
77
+
78
+ // END PREMIUM SECTION
79
+ // ------------------------------------------------------------------
80
+
81
+ /**
82
+ * {@inheritdoc}
83
+ * @param Wbcr_Factory420_Plugin $plugin
84
+ */
85
+ public function __construct( Wbcr_Factory420_Plugin $plugin ) {
86
+ $this->plugin = $plugin;
87
+
88
+ parent::__construct( $plugin );
89
+
90
+ if ( ! $this->id ) {
91
+ $this->id = $this->plugin->getPrefix() . 'license';
92
+ }
93
+ $this->premium = WRIO_Plugin::app()->premium;
94
+ $this->is_premium = $this->premium->is_activate();
95
+ $this->is_premium_active = $this->premium->is_active();
96
+ $this->premium_has_subscription = $this->premium->has_paid_subscription();
97
+ $this->premium_license = $this->premium->get_license();
98
+
99
+ add_action( 'wp_ajax_wbcr-clearfy-activate-license', [ $this, 'ajax_handler' ] );
100
+ }
101
+
102
+ /**
103
+ * [MAGIC] Magic method that configures assets for a page.
104
+ */
105
+ public function assets( $scripts, $styles ) {
106
+ parent::assets( $scripts, $styles );
107
+
108
+ $this->styles->add( FACTORY_CLEARFY_212_URL . '/assets/css/license-manager.css' );
109
+ $this->scripts->add( FACTORY_CLEARFY_212_URL . '/assets/js/license-manager.js' );
110
+ }
111
+
112
+ /**
113
+ * Регистрируем ajax обработчик для текущей страницы
114
+ *
115
+ * @since 2.0.7
116
+ */
117
+ public function ajax_handler() {
118
+ wbcr_factory_clearfy_212_check_license( $this->plugin );
119
+ }
120
+
121
+ /**
122
+ * {@inheritdoc}
123
+ */
124
+ public function showPageContent() {
125
+ ?>
126
+ <?php wp_nonce_field( 'license' ); ?>
127
+ <div id="wcl-license-wrapper"
128
+ data-loader="<?php echo FACTORY_CLEARFY_212_URL . '/assets/img/loader.gif'; ?>"
129
+ data-plugin="<?php echo get_class( $this->plugin ) ?>">
130
+ <?php $this->show_license_form(); ?>
131
+ </div>
132
+ <?php
133
+ }
134
+
135
+ /**
136
+ * Get before content.
137
+ *
138
+ * @return string Before content.
139
+ */
140
+ protected function get_plan_description() {
141
+ return '';
142
+ }
143
+
144
+ /**
145
+ * @return string
146
+ */
147
+ protected function get_hidden_license_key() {
148
+ if ( ! $this->is_premium ) {
149
+ return '';
150
+ }
151
+
152
+ return $this->premium_license->get_hidden_key();
153
+ }
154
+
155
+ /**
156
+ * @return string
157
+ */
158
+ protected function get_plan() {
159
+ if ( ! $this->is_premium ) {
160
+ return 'free';
161
+ }
162
+
163
+ return $this->premium->get_plan();
164
+ }
165
+
166
+ /**
167
+ * @return mixed
168
+ */
169
+ protected function get_expiration_days() {
170
+ return $this->premium_license->get_expiration_time( 'days' );
171
+ }
172
+
173
+ /**
174
+ * @return string
175
+ */
176
+ protected function get_billing_cycle_readable() {
177
+ if ( ! $this->is_premium ) {
178
+ return '';
179
+ }
180
+
181
+ $billing_cycle = $this->premium->get_billing_cycle();
182
+ $billing = 'lifetime';
183
+
184
+ if ( 1 == $billing_cycle ) {
185
+ $billing = 'month';
186
+ } else if ( 12 == $billing_cycle ) {
187
+ $billing = 'year';
188
+ }
189
+
190
+ return $billing;
191
+ }
192
+
193
+ /**
194
+ * Тип лицензии, цветовое оформление для формы лицензирования
195
+ * free - бесплатная
196
+ * gift - пожизненная лицензия, лицензия на особых условиях
197
+ * trial - красный цвет, применяется для триалов, если лиценизия истекла или заблокирована
198
+ * paid - обычная оплаченная лицензия, в данный момент активна.
199
+ *
200
+ * @return string
201
+ */
202
+ protected function get_license_type() {
203
+ if ( ! $this->is_premium ) {
204
+ return 'free';
205
+ }
206
+
207
+ $license = $this->premium_license;
208
+
209
+ if ( $license->is_lifetime() ) {
210
+ return 'gift';
211
+ } else if ( $license->get_expiration_time( 'days' ) < 1 ) {
212
+ return 'trial';
213
+ }
214
+
215
+ return 'paid';
216
+ }
217
+
218
+ /**
219
+ * @param bool|WP_Error $notice
220
+ */
221
+ public function show_license_form( $notice = false ) {
222
+ ?>
223
+ <div class="factory-bootstrap-421 onp-page-wrap <?= $this->get_license_type() ?>-license-manager-content"
224
+ id="license-manager">
225
+ <div>
226
+ <h3><?php printf( __( 'Activate %s', 'wbcr_factory_clearfy_212' ), $this->plan_name ) ?></h3>
227
+ <?php echo $this->get_plan_description() ?>
228
+ </div>
229
+ <br>
230
+ <?php if ( is_wp_error( $notice ) ) : ?>
231
+ <div class="license-message <?= $this->get_license_type() ?>-license-message">
232
+ <div class="alert <?php echo esc_attr( $notice->get_error_code() ); ?>">
233
+ <h4 class="alert-heading"><?php _e( $notice->get_error_message(), 'wbcr_factory_clearfy_212' ) ?></h4>
234
+ </div>
235
+ </div>
236
+ <?php endif; ?>
237
+ <div class="onp-container">
238
+ <div class="license-details">
239
+ <?php if ( $this->get_license_type() == 'free' ): ?>
240
+ <a href="<?php echo $this->plugin->get_support()->get_pricing_url( true, 'license_page' ); ?>"
241
+ class="purchase-premium" target="_blank" rel="noopener">
242
+ <span class="btn btn-gold btn-inner-wrap">
243
+ <?php printf( __( 'Upgrade to Premium for $%s', 'wbcr_factory_clearfy_212' ), $this->premium->get_price() ) ?>
244
+ </span>
245
+ </a>
246
+ <p><?php printf( __( 'Your current license for %1$s:', 'wbcr_factory_clearfy_212' ), $this->plugin->getPluginTitle() ) ?></p>
247
+ <?php endif; ?>
248
+ <div class="license-details-block <?= $this->get_license_type() ?>-details-block">
249
+ <?php if ( $this->is_premium ): ?>
250
+ <a data-action="deactivate" href="#"
251
+ class="btn btn-default btn-small license-delete-button wcl-control-btn">
252
+ <?php _e( 'Delete Key', 'wbcr_factory_clearfy_212' ) ?>
253
+ </a>
254
+ <a data-action="sync" href="#"
255
+ class="btn btn-default btn-small license-synchronization-button wcl-control-btn">
256
+ <?php _e( 'Synchronization', 'wbcr_factory_clearfy_212' ) ?>
257
+ </a>
258
+ <?php endif; ?>
259
+ <h3>
260
+ <?php echo ucfirst( $this->get_plan() ); ?>
261
+
262
+ <?php if ( $this->is_premium && $this->premium_has_subscription ): ?>
263
+ <span style="font-size: 15px;">
264
+ (<?php printf( __( 'Automatic renewal, every %s', '' ), esc_attr( $this->get_billing_cycle_readable() ) ); ?>)
265
+ </span>
266
+ <?php endif; ?>
267
+ </h3>
268
+ <?php if ( $this->is_premium ): ?>
269
+ <div class="license-key-identity">
270
+ <code><?= esc_attr( $this->get_hidden_license_key() ) ?></code>
271
+ </div>
272
+ <?php endif; ?>
273
+ <div class="license-key-description">
274
+ <p><?php _e( 'Public License is a GPLv2 compatible license allowing you to change and use this version of the plugin for free. Please keep in mind this license covers only free edition of the plugin. Premium versions are distributed with other type of a license.', 'wbcr_factory_clearfy_212' ) ?>
275
+ </p>
276
+ <?php if ( $this->is_premium && $this->premium_has_subscription ): ?>
277
+ <p class="activate-trial-hint">
278
+ <?php _e( 'You use a paid subscription for the plugin updates. In case you don’t want to receive paid updates, please, click <a data-action="unsubscribe" class="wcl-control-btn" href="#">cancel subscription</a>', 'wbcr_factory_clearfy_212' ) ?>
279
+ </p>
280
+ <?php endif; ?>
281
+
282
+ <?php if ( $this->get_license_type() == 'trial' ): ?>
283
+ <p class="activate-error-hint">
284
+ <?php printf( __( 'Your license has expired, please extend the license to get updates and support.', 'wbcr_factory_clearfy_212' ), '' ) ?>
285
+ </p>
286
+ <?php endif; ?>
287
+ </div>
288
+ <table class="license-params" colspacing="0" colpadding="0">
289
+ <tr>
290
+ <!--<td class="license-param license-param-domain">
291
+ <span class="license-value"><?php echo esc_attr( $_SERVER['SERVER_NAME'] ); ?></span>
292
+ <span class="license-value-name"><?php _e( 'domain', 'wbcr_factory_clearfy_212' ) ?></span>
293
+ </td>-->
294
+ <td class="license-param license-param-days">
295
+ <span class="license-value"><?= $this->get_plan() ?></span>
296
+ <span class="license-value-name"><?php _e( 'plan', 'wbcr_factory_clearfy_212' ) ?></span>
297
+ </td>
298
+ <?php if ( $this->is_premium ) : ?>
299
+ <td class="license-param license-param-sites">
300
+ <span class="license-value">
301
+ <?php echo esc_attr( $this->premium_license->get_count_active_sites() ); ?>
302
+ <?php _e( 'of', 'wbcr_factory_clearfy_212' ) ?>
303
+ <?php echo esc_attr( $this->premium_license->get_sites_quota() ); ?></span>
304
+ <span class="license-value-name"><?php _e( 'active sites', 'wbcr_factory_clearfy_212' ) ?></span>
305
+ </td>
306
+ <?php endif; ?>
307
+ <td class="license-param license-param-version">
308
+ <span class="license-value"><?= $this->plugin->getPluginVersion() ?></span>
309
+ <span class="license-value-name"><span>version</span></span>
310
+ </td>
311
+ <?php if ( $this->is_premium ): ?>
312
+ <td class="license-param license-param-days">
313
+ <?php if ( $this->get_license_type() == 'trial' ): ?>
314
+ <span class="license-value"><?php _e( 'EXPIRED!', 'wbcr_factory_clearfy_212' ) ?></span>
315
+ <span class="license-value-name"><?php _e( 'please update the key', 'wbcr_factory_clearfy_212' ) ?></span>
316
+ <?php else: ?>
317
+ <span class="license-value">
318
+ <?php
319
+ if ( $this->premium_license->is_lifetime() ) {
320
+ echo 'infiniate';
321
+ } else {
322
+ echo $this->get_expiration_days();
323
+ }
324
+ ?>
325
+ <small> <?php _e( 'day(s)', 'wbcr_factory_clearfy_212' ) ?></small>
326
+ </span>
327
+ <span class="license-value-name"><?php _e( 'remained', 'wbcr_factory_clearfy_212' ) ?></span>
328
+ <?php endif; ?>
329
+ </td>
330
+ <?php endif; ?>
331
+ </tr>
332
+ </table>
333
+ </div>
334
+ </div>
335
+ <div class="license-input">
336
+ <form action="" method="post">
337
+ <?php if ( $this->is_premium ): ?>
338
+ <p><?php _e( 'Have a key to activate the premium version? Paste it here:', 'wbcr_factory_clearfy_212' ) ?><p>
339
+ <?php else: ?>
340
+ <p><?php _e( 'Have a key to activate the plugin? Paste it here:', 'wbcr_factory_clearfy_212' ) ?>
341
+ <p>
342
+ <?php endif; ?>
343
+ <button data-action="activate" class="btn btn-default wcl-control-btn" type="button"
344
+ id="license-submit">
345
+ <?php _e( 'Submit Key', 'wbcr_factory_clearfy_212' ) ?>
346
+ </button>
347
+ <div class="license-key-wrap">
348
+ <input type="text" id="license-key" name="licensekey" value="" class="form-control"/>
349
+ </div>
350
+ <?php if ( $this->is_premium ): ?>
351
+ <p style="margin-top: 10px;">
352
+ <?php printf( __( '<a href="%s" target="_blank" rel="noopener">Lean more</a> about the premium version and get the license key to activate it now!', 'wbcr_factory_clearfy_212' ), $this->plugin->get_support()->get_pricing_url( true, 'license_page' ) ); ?>
353
+ </p>
354
+ <?php else: ?>
355
+ <p style="margin-top: 10px;">
356
+ <?php printf( __( 'Can’t find your key? Go to <a href="%s" target="_blank" rel="noopener">this page</a> and login using the e-mail address associated with your purchase.', 'wbcr_factory_clearfy_212' ), $this->plugin->get_support()->get_contacts_url( true, 'license_page' ) ) ?>
357
+ </p>
358
+ <?php endif; ?>
359
+ </form>
360
+ </div>
361
+ </div>
362
+ </div>
363
+ <?php
364
+ }
365
+ }
libs/factory/clearfy/pages/class-page-more-features.php ADDED
@@ -0,0 +1,170 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The page Settings.
4
+ *
5
+ * @author Alex Kovalev <alex.kovalevv@gmail.com>, Github: https://github.com/alexkovalevv
6
+ * @since 1.0.1
7
+ * @package clearfy
8
+ * @copyright (c) 2018, Webcraftic Ltd
9
+ *
10
+ */
11
+
12
+ // Exit if accessed directly
13
+ if ( ! defined( 'ABSPATH' ) ) {
14
+ exit;
15
+ }
16
+
17
+
18
+ class Wbcr_FactoryClearfy212_MoreFeaturesPage extends Wbcr_FactoryPages420_ImpressiveThemplate {
19
+
20
+ /**
21
+ * {@inheritDoc}
22
+ *
23
+ * @var string
24
+ */
25
+ public $id = "more_features";
26
+
27
+ /**
28
+ * {@inheritDoc}
29
+ *
30
+ * @var string
31
+ */
32
+ public $page_menu_dashicon = 'dashicons-star-filled wbcr-factory-orange-color';
33
+
34
+ /**
35
+ * {@inheritDoc}
36
+ *
37
+ * @var string
38
+ */
39
+ public $page_menu_position = 5;
40
+
41
+ /**
42
+ * {@inheritDoc}
43
+ *
44
+ * @var string
45
+ */
46
+ public $type = 'page';
47
+
48
+ /**
49
+ * {@inheritDoc}
50
+ *
51
+ * @var bool
52
+ */
53
+ public $available_for_multisite = true;
54
+
55
+ /**
56
+ * {@inheritDoc}
57
+ *
58
+ * @since 2.0.6 - добавлен
59
+ * @var bool
60
+ */
61
+ public $internal = true;
62
+
63
+ public function __construct( Wbcr_Factory420_Plugin $plugin ) {
64
+ $this->menu_title = __( 'More features (<b>free</b>)', 'wbcr_factory_clearfy_212' );
65
+
66
+ parent::__construct( $plugin );
67
+
68
+ $this->plugin = $plugin;
69
+ }
70
+
71
+ /**
72
+ * {@inheritDoc}
73
+ *
74
+ * @return string
75
+ */
76
+ public function getPageTitle() {
77
+ return __( 'More features', 'wbcr_factory_clearfy_212' );
78
+ }
79
+
80
+ /**
81
+ * {@inheritDoc}
82
+ *
83
+ * @return void
84
+ */
85
+ public function showPageContent() {
86
+ ?>
87
+ <div class="row">
88
+ <div class="col-sm-4">
89
+ <div class="wbcr-factory-feature-box">
90
+ <span class="dashicons dashicons-yes"></span>
91
+ <h3><?php _e( 'Code cleaning', 'wbcr_factory_clearfy_212' ) ?></h3>
92
+ <p><?php _e( 'Clears the source code of the page from unused code.', 'wbcr_factory_clearfy_212' ) ?></p>
93
+ </div>
94
+ </div>
95
+ <div class="col-sm-4">
96
+ <div class="wbcr-factory-feature-box">
97
+ <span class="dashicons dashicons-chart-bar"></span>
98
+ <h3><?php _e( 'Improve SEO', 'wbcr_factory_clearfy_212' ) ?></h3>
99
+ <p><?php _e( 'Removes duplicate pages, closes external links, changes the headers of the server.', 'wbcr_factory_clearfy_212' ) ?></p>
100
+ </div>
101
+ </div>
102
+ <div class="col-sm-4">
103
+ <div class="wbcr-factory-feature-box">
104
+ <span class="dashicons dashicons-shield-alt"></span>
105
+ <h3><?php _e( 'Site protection', 'wbcr_factory_clearfy_212' ) ?></h3>
106
+ <p><?php _e( 'Enables and disables features that improve the protection of your site.', 'wbcr_factory_clearfy_212' ) ?></p>
107
+ </div>
108
+ </div>
109
+ <div class="col-sm-4">
110
+ <div class="wbcr-factory-feature-box">
111
+ <span class="dashicons dashicons-welcome-comments"></span>
112
+ <h3><?php _e( 'Disable comments', 'wbcr_factory_clearfy_212' ) ?></h3>
113
+ <p><?php _e( 'Disables comments on the entire site or on specific pages.', 'wbcr_factory_clearfy_212' ) ?></p>
114
+ </div>
115
+ </div>
116
+ <div class="col-sm-4">
117
+ <div class="wbcr-factory-feature-box">
118
+ <span class="dashicons dashicons-update"></span>
119
+ <h3><?php _e( 'Manage updates', 'wbcr_factory_clearfy_212' ) ?></h3>
120
+ <p><?php _e( 'Enables or disables automatically updates for plugins, themes and core. It is also possible
121
+ to disable all updates.', 'wbcr_factory_clearfy_212' ) ?></p>
122
+ </div>
123
+ </div>
124
+ <div class="col-sm-4">
125
+ <div class="wbcr-factory-feature-box">
126
+ <span class="dashicons dashicons-admin-plugins"></span>
127
+ <h3><?php _e( 'Manage widgets', 'wbcr_factory_clearfy_212' ) ?></h3>
128
+ <p><?php _e( 'Allows you to remove unused widgets.', 'wbcr_factory_clearfy_212' ) ?></p>
129
+ </div>
130
+ </div>
131
+ <div class="col-sm-4">
132
+ <div class="wbcr-factory-feature-box">
133
+ <span class="dashicons dashicons-dashboard"></span>
134
+ <h3><?php _e( 'Speed Optimization', 'wbcr_factory_clearfy_212' ) ?></h3>
135
+ <p><?php _e( 'Increases performance by disabling unused functions and reducing the number of requests.', 'wbcr_factory_clearfy_212' ) ?></p>
136
+ </div>
137
+ </div>
138
+ <div class="col-sm-4">
139
+ <div class="wbcr-factory-feature-box">
140
+ <span class="dashicons dashicons-visibility"></span>
141
+ <h3><?php _e( 'Site privacy', 'wbcr_factory_clearfy_212' ) ?></h3>
142
+ <p><?php _e( 'Allows you to hide the version of the site and plugins. Allows you to hide your
143
+ WordPress.', 'wbcr_factory_clearfy_212' ) ?></p>
144
+ </div>
145
+ </div>
146
+ <div class="col-sm-4">
147
+ <div class="wbcr-factory-feature-box">
148
+ <span class="dashicons dashicons-admin-settings"></span>
149
+ <h3><?php _e( 'Easy setup', 'wbcr_factory_clearfy_212' ) ?></h3>
150
+ <p><?php _e( 'In quick mode, you can easily configure the plugin according to your needs.', 'wbcr_factory_clearfy_212' ) ?></p>
151
+ </div>
152
+ </div>
153
+ </div>
154
+ <div class="wbcr-factory-buttons-wrap">
155
+ <?php
156
+ $url = 'https://clearfy.pro';
157
+
158
+ if ( get_locale() == 'ru_RU' ) {
159
+ $url = 'https://ru.clearfy.pro';
160
+ }
161
+ $url .= '?utm_source=wordpress.org&utm_campaign=' . $this->plugin->getPluginName();
162
+ ?>
163
+ <a href="<?= $url ?>" class="wbcr-factory-premium-button" target="_blank">
164
+ <?php _e( 'Get the ultimate plugin 100% FREE', 'wbcr_factory_clearfy_212' ) ?>
165
+ </a>
166
+ </div>
167
+ <?php
168
+ }
169
+ }
170
+
libs/factory/clearfy/pages/class-pages.php ADDED
@@ -0,0 +1,440 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Общий класс прослойка для страниц Clearfy и его компоннетов.
5
+ * В этом классе добавляются общие ресурсы и элементы, необходимые для всех связанных плагинов.
6
+ *
7
+ * @author Alex Kovalev <alex.kovalevv@gmail.com>, Github: https://github.com/alexkovalevv
8
+ * @since 2.0.5
9
+ */
10
+
11
+ // Exit if accessed directly
12
+ if ( ! defined( 'ABSPATH' ) ) {
13
+ exit;
14
+ }
15
+
16
+ /**
17
+ * Class Wbcr_FactoryPages420_ImpressiveThemplate
18
+ *
19
+ * @method string getInfoWidget() - get widget content information
20
+ * @method string getRatingWidget( array $args = [] ) - get widget content rating
21
+ * @method string getDonateWidget() - get widget content donate
22
+ * @method string getBusinessSuggetionWidget()
23
+ * @method string getSupportWidget
24
+ */
25
+ class Wbcr_FactoryClearfy212_PageBase extends Wbcr_FactoryPages420_ImpressiveThemplate {
26
+
27
+ /**
28
+ * {@inheritDoc}
29
+ *
30
+ * @since 2.0.5 - добавлен
31
+ * @var bool
32
+ */
33
+ public $show_right_sidebar_in_options = true;
34
+
35
+ /**
36
+ * {@inheritDoc}
37
+ *
38
+ * @since 2.0.5 - добавлен
39
+ * @var bool
40
+ */
41
+ public $available_for_multisite = true;
42
+
43
+ /**
44
+ * {@inheritDoc}
45
+ *
46
+ * @since 2.0.6 - добавлен
47
+ * @var bool
48
+ */
49
+ public $internal = true;
50
+
51
+ /**
52
+ * @param Wbcr_Factory420_Plugin $plugin
53
+ */
54
+ public function __construct( Wbcr_Factory420_Plugin $plugin ) {
55
+ parent::__construct( $plugin );
56
+ }
57
+
58
+ /**
59
+ * @param $name
60
+ * @param $arguments
61
+ *
62
+ * @return null|string
63
+ */
64
+ public function __call( $name, $arguments ) {
65
+ if ( substr( $name, 0, 3 ) == 'get' ) {
66
+ $called_method_name = 'show' . substr( $name, 3 );
67
+ if ( method_exists( $this, $called_method_name ) ) {
68
+ ob_start();
69
+
70
+ $this->$called_method_name( $arguments );
71
+ $content = ob_get_contents();
72
+ ob_end_clean();
73
+
74
+ return $content;
75
+ }
76
+ }
77
+
78
+ return null;
79
+ }
80
+
81
+ /**
82
+ * Requests assets (js and css) for the page.
83
+ *
84
+ * @param Wbcr_Factory420_ScriptList $scripts
85
+ * @param Wbcr_Factory420_StyleList $styles
86
+ *
87
+ * @return void
88
+ * @see Wbcr_FactoryPages420_AdminPage
89
+ *
90
+ */
91
+ public function assets( $scripts, $styles ) {
92
+ parent::assets( $scripts, $styles );
93
+
94
+ $this->styles->add( FACTORY_CLEARFY_212_URL . '/assets/css/clearfy-base.css' );
95
+
96
+ // todo: вынести все общие скрипты и стили фреймворка, продумать совместимость с другими плагинами
97
+ if ( defined( 'WCL_PLUGIN_URL' ) ) {
98
+ $this->styles->add( WCL_PLUGIN_URL . '/admin/assets/css/general.css' );
99
+ }
100
+
101
+ wbcr_factory_420_do_action_deprecated( 'wbcr_clearfy_page_enqueue_scripts', [
102
+ $this->getResultId(),
103
+ $scripts,
104
+ $styles
105
+ ], '1.4.0', 'wbcr/clearfy/page_assets' );
106
+
107
+ /**
108
+ * Allows you to enqueue scripts to the internal pages of the plugin.
109
+ * $this->getResultId() - page id + plugin name = quick_start-wbcr_clearfy
110
+ *
111
+ * @since 2.0.5
112
+ */
113
+ do_action( 'wbcr/clearfy/page_assets', $this->getResultId(), $scripts, $styles );
114
+ }
115
+
116
+ /**
117
+ * @return Wbcr_Factory420_Request
118
+ */
119
+ public function request() {
120
+ return $this->plugin->request;
121
+ }
122
+
123
+ /**
124
+ * @since 2.0.5
125
+ *
126
+ * @param $option_name
127
+ * @param bool $default *
128
+ *
129
+ * @return mixed|void
130
+ */
131
+ public function getPopulateOption( $option_name, $default = false ) {
132
+ return $this->plugin->getPopulateOption( $option_name, $default );
133
+ }
134
+
135
+ /**
136
+ * @param $option_name
137
+ * @param bool $default
138
+ *
139
+ * @return mixed|void
140
+ */
141
+ public function getOption( $option_name, $default = false ) {
142
+ return $this->plugin->getOption( $option_name, $default );
143
+ }
144
+
145
+ /**
146
+ * @param $option_name
147
+ * @param $value
148
+ *
149
+ * @return void
150
+ */
151
+ public function updatePopulateOption( $option_name, $value ) {
152
+ $this->plugin->updatePopulateOption( $option_name, $value );
153
+ }
154
+
155
+ /**
156
+ * @param $option_name
157
+ * @param $value
158
+ *
159
+ * @return void
160
+ */
161
+ public function updateOption( $option_name, $value ) {
162
+ $this->plugin->updateOption( $option_name, $value );
163
+ }
164
+
165
+ /**
166
+ * @param $option_name
167
+ *
168
+ * @return void
169
+ */
170
+ public function deletePopulateOption( $option_name ) {
171
+ $this->plugin->deletePopulateOption( $option_name );
172
+ }
173
+
174
+ /**
175
+ * @param $option_name
176
+ *
177
+ * @return void
178
+ */
179
+ public function deleteOption( $option_name ) {
180
+ $this->plugin->deleteOption( $option_name );
181
+ }
182
+
183
+
184
+ /**
185
+ * Действие выполняется для всех страниц Clearfy и его компонентах.
186
+ * Это простое предложение перейти на PRO версию.
187
+ */
188
+ public function multisiteProAction() {
189
+ if ( is_multisite() && $this->plugin->isNetworkActive() ) {
190
+
191
+ $license_page_url = $this->getBaseUrl( 'license' );
192
+ $upgrade_url = WbcrFactoryClearfy212_Helpers::getWebcrafticSitePageUrl( $this->plugin->getPluginName(), 'pricing', 'multisite_save_settings' );
193
+ $upgrade_price = WbcrFactoryClearfy212_Helpers::getClearfyBusinessPrice();
194
+
195
+ $html = '<div class="wbcr-factory-clearfy-212-multisite-suggetion">';
196
+ $html .= '<div class="wbcr-factory-inner-contanier">';
197
+ $html .= '<h3>' . __( 'Upgrade to Clearfy Business', 'wbcr_factory_clearfy_212' ) . '</h3>';
198
+ $html .= '<p>' . __( 'Oops... Sorry for the inconvenience caused!', 'wbcr_factory_clearfy_212' ) . '</p>';
199
+ $html .= '<p>' . __( 'Complete multisite support is available in Clearfy Business and Clearfy Business Revolution packages only!', 'wbcr_factory_clearfy_212' ) . '</p>';
200
+ $html .= '<p>' . __( 'You can activate the plugin on each website and use it with zero limitations. But you can’t save the plugin’s settings under the Super Administrator role!', 'wbcr_factory_clearfy_212' ) . '</p>';
201
+ $html .= '<p style="margin-top:20px">';
202
+ $html .= '<a href="' . $license_page_url . '" class="wbcr-factory-activate-premium" rel="noopener">' . __( 'Activate license ', 'wbcr_factory_clearfy_212' ) . '</a> ';
203
+ $html .= '<a href="' . $upgrade_url . '" class="wbcr-factory-purchase-premium" target="_blank" rel="noopener">' . sprintf( __( 'Upgrade to Clearfy Business for $%d', 'wbcr_factory_clearfy_212' ), $upgrade_price ) . '</a>';
204
+ $html .= '</p>';
205
+ $html .= '</div>';
206
+ $html .= '</div>';
207
+
208
+ $this->showPage( $html );
209
+
210
+ return;
211
+ }
212
+
213
+ $this->redirectToAction( 'index' );
214
+ }
215
+
216
+ /**
217
+ * @param string $position
218
+ *
219
+ * @return mixed|void
220
+ */
221
+ protected function getPageWidgets( $position = 'bottom' ) {
222
+ $widgets = [];
223
+
224
+ if ( $position == 'bottom' ) {
225
+ $widgets['info_widget'] = $this->getInfoWidget();
226
+ $widgets['rating_widget'] = $this->getRatingWidget();
227
+ $widgets['support_widget'] = $this->getSupportWidget();
228
+ //$widgets['donate_widget'] = $this->getDonateWidget();
229
+ } else if ( $position == 'right' ) {
230
+ $widgets['business_suggetion'] = $this->getBusinessSuggetionWidget();
231
+ $widgets['info_widget'] = $this->getInfoWidget();
232
+ $widgets['rating_widget'] = $this->getRatingWidget();
233
+ }
234
+
235
+ /**
236
+ * @since 4.0.9 - является устаревшим
237
+ */
238
+ $widgets = wbcr_factory_420_apply_filters_deprecated( 'wbcr_factory_pages_420_imppage_get_widgets', [
239
+ $widgets,
240
+ $position,
241
+ $this->plugin,
242
+ $this
243
+ ], '4.0.9', 'wbcr/factory/pages/impressive/widgets' );
244
+
245
+ /**
246
+ * @since 4.0.1 - добавлен
247
+ * @since 4.0.9 - изменено имя
248
+ */
249
+ $widgets = apply_filters( 'wbcr/factory/pages/impressive/widgets', $widgets, $position, $this->plugin, $this );
250
+
251
+ return $widgets;
252
+ }
253
+
254
+ /**
255
+ * Создает Html разметку виджета для рекламы премиум версии
256
+ *
257
+ * @author Alexander Kovalev <alex.kovalevv@gmail.com>
258
+ * @since 2.0.2
259
+ */
260
+ public function showBusinessSuggetionWidget() {
261
+ $plugin_name = $this->plugin->getPluginName();
262
+ $upgrade_price = $this->plugin->has_premium() ? $this->plugin->premium->get_price() : 0;
263
+ $purchase_url = $this->plugin->get_support()->get_pricing_url( true, 'right_sidebar_ads' );
264
+
265
+ $default_features = [
266
+ '4_premium' => __( '4 premium components now;', 'wbcr_factory_clearfy_212' ),
267
+ '40_premium' => __( '40 new premium components within a year for the single price;', 'wbcr_factory_clearfy_212' ),
268
+ 'multisite_support' => __( 'Multisite support;', 'wbcr_factory_clearfy_212' ),
269
+ 'advance_settings' => __( 'Advanced settings;', 'wbcr_factory_clearfy_212' ),
270
+ 'no_ads' => __( 'No ads;', 'wbcr_factory_clearfy_212' ),
271
+ 'perfect_support' => __( 'Perfect support.', 'wbcr_factory_clearfy_212' )
272
+ ];
273
+
274
+ /**
275
+ * @since 2.0.8 - added
276
+ */
277
+ $suggetion_title = __( 'MORE IN CLEARFY <span>BUSINESS</span>', 'wbcr_factory_clearfy_212' );
278
+ $suggetion_title = apply_filters( 'wbcr/clearfy/pages/suggetion_title', $suggetion_title, $plugin_name, $this->id );
279
+
280
+ /**
281
+ * @since 2.0.8 - deprecated
282
+ */
283
+ $suggetion_features = wbcr_factory_420_apply_filters_deprecated( 'wbcr/clearfy/page_bussines_suggetion_features', [
284
+ $default_features,
285
+ $this->plugin->getPluginName(),
286
+ $this->id
287
+ ], '2.0.8', 'wbcr/clearfy/pages/suggetion_features' );
288
+
289
+ /**
290
+ * @since 2.0.8 - renamed
291
+ * @since 2.0.6
292
+ */
293
+ $suggetion_features = apply_filters( 'wbcr/clearfy/pages/suggetion_features', $suggetion_features, $plugin_name, $this->id );
294
+
295
+ if ( empty( $suggetion_features ) ) {
296
+ $suggetion_features = $default_features;
297
+ }
298
+ ?>
299
+ <div class="wbcr-factory-sidebar-widget wbcr-factory-clearfy-212-pro-suggettion">
300
+ <h3><?php echo $suggetion_title; ?></h3>
301
+ <ul>
302
+ <?php if ( ! empty( $suggetion_features ) ): ?>
303
+ <?php foreach ( $suggetion_features as $feature ): ?>
304
+ <li><?= $feature ?></li>
305
+ <?php endforeach; ?>
306
+ <?php endif; ?>
307
+ </ul>
308
+ <a href="<?php echo $purchase_url ?>" class="wbcr-factory-purchase-premium" target="_blank" rel="noopener">
309
+ <?php printf( __( 'Upgrade for $%s', 'wbcr_factory_clearfy_212' ), $upgrade_price ) ?>
310
+ </a>
311
+ </div>
312
+ <?php
313
+ }
314
+
315
+ /**
316
+ * Создает html разметку виджета с информационными маркерами
317
+ *
318
+ * @author Alexander Kovalev <alex.kovalevv@gmail.com>
319
+ * @since 2.0.0
320
+ */
321
+ public function showInfoWidget() {
322
+ ?>
323
+ <div class="wbcr-factory-sidebar-widget">
324
+ <ul>
325
+ <li>
326
+ <span class="wbcr-factory-hint-icon-simple wbcr-factory-simple-red">
327
+ <img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAkAAAAJCAQAAABKmM6bAAAAUUlEQVQIHU3BsQ1AQABA0X/komIrnQHYwyhqQ1hBo9KZRKL9CBfeAwy2ri42JA4mPQ9rJ6OVt0BisFM3Po7qbEliru7m/FkY+TN64ZVxEzh4ndrMN7+Z+jXCAAAAAElFTkSuQmCC" alt=""/>
328
+ </span>
329
+ - <?php _e( 'A neutral setting that can not harm your site, but you must be sure that you need to use it.', 'wbcr_factory_clearfy_212' ); ?>
330
+ </li>
331
+ <li>
332
+ <span class="wbcr-factory-hint-icon-simple wbcr-factory-simple-grey">
333
+ <img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAkAAAAJCAQAAABKmM6bAAAAUUlEQVQIHU3BsQ1AQABA0X/komIrnQHYwyhqQ1hBo9KZRKL9CBfeAwy2ri42JA4mPQ9rJ6OVt0BisFM3Po7qbEliru7m/FkY+TN64ZVxEzh4ndrMN7+Z+jXCAAAAAElFTkSuQmCC" alt=""/>
334
+ </span>
335
+ - <?php _e( 'When set this option, you must be careful. Plugins and themes may depend on this function. You must be sure that you can disable this feature for the site.', 'wbcr_factory_clearfy_212' ); ?>
336
+ </li>
337
+ <li>
338
+ <span class="wbcr-factory-hint-icon-simple wbcr-factory-simple-green">
339
+ <img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAkAAAAJCAQAAABKmM6bAAAAUUlEQVQIHU3BsQ1AQABA0X/komIrnQHYwyhqQ1hBo9KZRKL9CBfeAwy2ri42JA4mPQ9rJ6OVt0BisFM3Po7qbEliru7m/FkY+TN64ZVxEzh4ndrMN7+Z+jXCAAAAAElFTkSuQmCC" alt=""/>
340
+ </span>
341
+ - <?php _e( 'Absolutely safe setting, We recommend to use.', 'wbcr_factory_clearfy_212' ); ?>
342
+ </li>
343
+ </ul>
344
+ ----------<br>
345
+ <p><?php _e( 'Hover to the icon to get help for the feature you selected.', 'wbcr_factory_clearfy_212' ); ?></p>
346
+ </div>
347
+ <?php
348
+ }
349
+
350
+ /**
351
+ * Создает html разметку виджета рейтинга
352
+ *
353
+ * @author Alexander Kovalev <alex.kovalevv@gmail.com>
354
+ * @since 2.0.0
355
+ *
356
+ * @param array $args
357
+ */
358
+ public function showRatingWidget( array $args ) {
359
+ if ( ! isset( $args[0] ) || empty( $args[0] ) ) {
360
+ $page_url = "https://goo.gl/tETE2X";
361
+ } else {
362
+ $page_url = $args[0];
363
+ }
364
+
365
+ $page_url = apply_filters( 'wbcr_factory_pages_420_imppage_rating_widget_url', $page_url, $this->plugin->getPluginName(), $this->getResultId() );
366
+
367
+ ?>
368
+ <div class="wbcr-factory-sidebar-widget">
369
+ <p>
370
+ <strong><?php _e( 'Do you want the plugin to improved and update?', 'wbcr_factory_clearfy_212' ); ?></strong>
371
+ </p>
372
+ <p><?php _e( 'Help the author, leave a review on wordpress.org. Thanks to feedback, I will know that the plugin is really useful to you and is needed.', 'wbcr_factory_clearfy_212' ); ?></p>
373
+ <p><?php _e( 'And also write your ideas on how to extend or improve the plugin.', 'wbcr_factory_clearfy_212' ); ?></p>
374
+ <p>
375
+ <i class="wbcr-factory-icon-5stars"></i>
376
+ <a href="<?= $page_url ?>" title="Go rate us" target="_blank">
377
+ <strong><?php _e( 'Go rate us and push ideas', 'wbcr_factory_clearfy_212' ); ?></strong>
378
+ </a>
379
+ </p>
380
+ </div>
381
+ <?php
382
+ }
383
+
384
+ /**
385
+ * Создает html размету виджета доната
386
+ *
387
+ * @author Alexander Kovalev <alex.kovalevv@gmail.com>
388
+ * @since 2.0.0
389
+ */
390
+ public function showDonateWidget() {
391
+ ?>
392
+ <div class="wbcr-factory-sidebar-widget">
393
+ <p>
394
+ <strong><?php _e( 'Donation for plugin development', 'wbcr_factory_clearfy_212' ); ?></strong>
395
+ </p>
396
+ <?php if ( get_locale() !== 'ru_RU' ): ?>
397
+ <form id="wbcr-factory-paypal-donation-form" action="https://www.paypal.com/cgi-bin/webscr" method="post" target="_blank">
398
+ <input type="hidden" name="cmd" value="_s-xclick">
399
+ <input type="hidden" name="hosted_button_id" value="VDX7JNTQPNPFW">
400
+ <div class="wbcr-factory-donation-price">5$</div>
401
+ <input type="image" src="<?= FACTORY_PAGES_420_URL ?>/templates/assets/img/paypal-donate.png" border="0" name="submit" alt="PayPal – The safer, easier way to pay online!">
402
+ </form>
403
+ <?php else: ?>
404
+ <iframe frameborder="0" allowtransparency="true" scrolling="no" src="https://money.yandex.ru/embed/donate.xml?account=410011242846510&quickpay=donate&payment-type-choice=on&mobile-payment-type-choice=on&default-sum=300&targets=%D0%9D%D0%B0+%D0%BF%D0%BE%D0%B4%D0%B4%D0%B5%D1%80%D0%B6%D0%BA%D1%83+%D0%BF%D0%BB%D0%B0%D0%B3%D0%B8%D0%BD%D0%B0+%D0%B8+%D1%80%D0%B0%D0%B7%D1%80%D0%B0%D0%B1%D0%BE%D1%82%D0%BA%D1%83+%D0%BD%D0%BE%D0%B2%D1%8B%D1%85+%D1%84%D1%83%D0%BD%D0%BA%D1%86%D0%B8%D0%B9.+&target-visibility=on&project-name=Webcraftic&project-site=&button-text=05&comment=on&hint=%D0%9A%D0%B0%D0%BA%D1%83%D1%8E+%D1%84%D1%83%D0%BD%D0%BA%D1%86%D0%B8%D1%8E+%D0%BD%D1%83%D0%B6%D0%BD%D0%BE+%D0%B4%D0%BE%D0%B1%D0%B0%D0%B2%D0%B8%D1%82%D1%8C+%D0%B2+%D0%BF%D0%BB%D0%B0%D0%B3%D0%B8%D0%BD%3F&mail=on&successURL=" width="508" height="187"></iframe>
405
+ <?php endif; ?>
406
+ </div>
407
+ <?php
408
+ }
409
+
410
+ /**
411
+ * Создает html разметку виджета поддержки
412
+ *
413
+ * @author Alexander Kovalev <alex.kovalevv@gmail.com>
414
+ * @since 2.0.8
415
+ */
416
+ public function showSupportWidget() {
417
+ $free_support_url = $this->plugin->get_support()->get_contacts_url();
418
+ $hot_support_url = 'https://webcraftic.com/other-questions-support/';
419
+ ?>
420
+ <div id="wbcr-clr-support-widget" class="wbcr-factory-sidebar-widget">
421
+ <p><strong><?php _e( 'Having Issues?', 'clearfy' ); ?></strong></p>
422
+ <div class="wbcr-clr-support-widget-body">
423
+ <p>
424
+ <?php _e( 'We provide free support for this plugin. If you are pushed with a problem, just create a new ticket. We will definitely help you!', 'clearfy' ); ?>
425
+ </p>
426
+ <ul>
427
+ <li><span class="dashicons dashicons-sos"></span>
428
+ <a href="<?= $free_support_url ?>" target="_blank" rel="noopener"><?php _e( 'Get starting free support', 'clearfy' ); ?></a>
429
+ </li>
430
+ <li style="margin-top: 15px;background: #fff4f1;padding: 10px;color: #a58074;">
431
+ <span class="dashicons dashicons-warning"></span>
432
+ <?php printf( __( 'If you find a php error or a vulnerability in plugin, you can <a href="%s" target="_blank" rel="noopener">create ticket</a> in hot support that we responded instantly.', 'clearfy' ), $hot_support_url ); ?>
433
+ </li>
434
+ </ul>
435
+ </div>
436
+ </div>
437
+ <?php
438
+ }
439
+ }
440
+
{admin/assets/js → libs/factory/clearfy/pages}/index.php RENAMED
File without changes
libs/factory/clearfy/pages/more-features.php DELETED
@@ -1,148 +0,0 @@
1
- <?php
2
- /**
3
- * The page Settings.
4
- *
5
- * @author Alex Kovalev <alex.kovalevv@gmail.com>
6
- * @copyright (c) 2018, Webcraftic Ltd
7
- *
8
- * @package clearfy
9
- * @since 1.0.1
10
- */
11
-
12
- // Exit if accessed directly
13
- if( !defined('ABSPATH') ) {
14
- exit;
15
- }
16
-
17
- if( !class_exists('Wbcr_FactoryClearfy200_MoreFeaturesPage') ) {
18
-
19
- class Wbcr_FactoryClearfy200_MoreFeaturesPage extends Wbcr_FactoryPages401_ImpressiveThemplate {
20
-
21
- public $id = "more_features";
22
-
23
- public $page_menu_dashicon = 'dashicons-star-filled wbcr-factory-premium-color';
24
-
25
- public $page_menu_position = 5;
26
-
27
- public $type = 'page';
28
-
29
- public function __construct(Wbcr_Factory400_Plugin $plugin)
30
- {
31
- $this->menu_title = __('More features (<b>free</b>)', 'wbcr_factory_clearfy_200');
32
-
33
- parent::__construct($plugin);
34
-
35
- $this->plugin = $plugin;
36
- }
37
-
38
- public function getPageTitle()
39
- {
40
- return __('install the ultimate version of the plugin for free!', 'wbcr_factory_clearfy_200');
41
- }
42
-
43
- public function showPageContent()
44
- {
45
- ?>
46
- <div class="row">
47
- <div class="col-sm-4">
48
- <div class="wbcr-factory-feature-box">
49
- <span class="dashicons dashicons-yes"></span>
50
-
51
- <h3><?php _e('Code cleaning', 'wbcr_factory_clearfy_200')?></h3>
52
-
53
- <p><?php _e('Clears the source code of the page from unused code.', 'wbcr_factory_clearfy_200')?></p>
54
- </div>
55
- </div>
56
- <div class="col-sm-4">
57
- <div class="wbcr-factory-feature-box">
58
- <span class="dashicons dashicons-chart-bar"></span>
59
-
60
- <h3><?php _e('Improve SEO', 'wbcr_factory_clearfy_200')?></h3>
61
-
62
- <p><?php _e('Removes duplicate pages, closes external links, changes the headers of the server.', 'wbcr_factory_clearfy_200')?></p>
63
- </div>
64
- </div>
65
- <div class="col-sm-4">
66
- <div class="wbcr-factory-feature-box">
67
- <span class="dashicons dashicons-shield-alt"></span>
68
-
69
- <h3><?php _e('Site protection', 'wbcr_factory_clearfy_200')?></h3>
70
-
71
- <p><?php _e('Enables and disables features that improve the protection of your site.', 'wbcr_factory_clearfy_200')?></p>
72
- </div>
73
- </div>
74
- <div class="col-sm-4">
75
- <div class="wbcr-factory-feature-box">
76
- <span class="dashicons dashicons-welcome-comments"></span>
77
-
78
- <h3><?php _e('Disable comments', 'wbcr_factory_clearfy_200')?></h3>
79
-
80
- <p><?php _e('Disables comments on the entire site or on specific pages.', 'wbcr_factory_clearfy_200')?></p>
81
- </div>
82
- </div>
83
- <div class="col-sm-4">
84
- <div class="wbcr-factory-feature-box">
85
- <span class="dashicons dashicons-update"></span>
86
-
87
- <h3><?php _e('Manage updates', 'wbcr_factory_clearfy_200')?></h3>
88
-
89
- <p><?php _e('Enables or disables automatically updates for plugins, themes and core. It is also possible
90
- to disable all updates.', 'wbcr_factory_clearfy_200')?></p>
91
- </div>
92
- </div>
93
- <div class="col-sm-4">
94
- <div class="wbcr-factory-feature-box">
95
- <span class="dashicons dashicons-admin-plugins"></span>
96
-
97
- <h3><?php _e('Manage widgets', 'wbcr_factory_clearfy_200')?></h3>
98
-
99
- <p><?php _e('Allows you to remove unused widgets.', 'wbcr_factory_clearfy_200')?></p>
100
- </div>
101
- </div>
102
- <div class="col-sm-4">
103
- <div class="wbcr-factory-feature-box">
104
- <span class="dashicons dashicons-dashboard"></span>
105
-
106
- <h3><?php _e('Speed Optimization', 'wbcr_factory_clearfy_200')?></h3>
107
-
108
- <p><?php _e('Increases performance by disabling unused functions and reducing the number of requests.', 'wbcr_factory_clearfy_200')?></p>
109
- </div>
110
- </div>
111
- <div class="col-sm-4">
112
- <div class="wbcr-factory-feature-box">
113
- <span class="dashicons dashicons-visibility"></span>
114
-
115
- <h3><?php _e('Site privacy', 'wbcr_factory_clearfy_200')?></h3>
116
-
117
- <p><?php _e('Allows you to hide the version of the site and plugins. Allows you to hide your
118
- WordPress.', 'wbcr_factory_clearfy_200')?></p>
119
- </div>
120
- </div>
121
- <div class="col-sm-4">
122
- <div class="wbcr-factory-feature-box">
123
- <span class="dashicons dashicons-admin-settings"></span>
124
-
125
- <h3><?php _e('Easy setup', 'wbcr_factory_clearfy_200')?></h3>
126
-
127
- <p><?php _e('In quick mode, you can easily configure the plugin according to your needs.', 'wbcr_factory_clearfy_200')?></p>
128
- </div>
129
- </div>
130
- </div>
131
-
132
- <div class="wbcr-factory-buttons-wrap">
133
- <?php
134
- $url = 'https://clearfy.pro';
135
-
136
- if( get_locale() == 'ru_RU' ) {
137
- $url = 'https://ru.clearfy.pro';
138
- }
139
- $url .= '?utm_source=wordpress.org&utm_campaign=' . $this->plugin->getPluginName();
140
- ?>
141
- <a href="<?= $url ?>" class="wbcr-factory-premium-button" target="_blank">
142
- <?php _e('Get the ultimate plugin 100% FREE', 'wbcr_factory_clearfy_200')?>
143
- </a>
144
- </div>
145
- <?php
146
- }
147
- }
148
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
libs/factory/core/README.md ADDED
@@ -0,0 +1,3 @@
 
 
 
1
+ # Core Factory Framework
2
+
3
+ It performs the connection of system modules of the framework, is responsible for migrations, plugin updates, admin notifications, initialization of the plugin.
libs/factory/core/boot.php CHANGED
@@ -1,40 +1,62 @@
1
  <?php
2
- /**
3
- * Factory Plugin
4
- *
5
- * @author Alex Kovalev <alex.kovalevv@gmail.com>
6
- * @copyright (c) 2018, Webcraftic Ltd
7
- *
8
- * @package core
9
- * @since 1.0.0
10
- */
11
-
12
- // Exit if accessed directly
13
- if( !defined('ABSPATH') ) {
14
- exit;
15
- }
16
-
17
- if( defined('FACTORY_400_LOADED') ) {
18
- return;
19
- }
20
- define('FACTORY_400_LOADED', true);
21
-
22
- define('FACTORY_400_VERSION', '000');
23
-
24
- define('FACTORY_400_DIR', dirname(__FILE__));
25
- define('FACTORY_400_URL', plugins_url(null, __FILE__));
26
-
27
- #comp merge
28
- require_once(FACTORY_400_DIR . '/includes/functions.php');
29
- require_once(FACTORY_400_DIR . '/includes/request.class.php');
30
- require_once(FACTORY_400_DIR . '/includes/base.class.php');
31
-
32
- require_once(FACTORY_400_DIR . '/includes/assets-managment/assets-list.class.php');
33
- require_once(FACTORY_400_DIR . '/includes/assets-managment/script-list.class.php');
34
- require_once(FACTORY_400_DIR . '/includes/assets-managment/style-list.class.php');
35
-
36
- require_once(FACTORY_400_DIR . '/includes/plugin.class.php');
37
-
38
- require_once(FACTORY_400_DIR . '/includes/activation/activator.class.php');
39
- require_once(FACTORY_400_DIR . '/includes/activation/update.class.php');
40
- #endcomp
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  <?php
2
+ /**
3
+ * Factory Plugin
4
+ *
5
+ * @author @author Alex Kovalev <alex.kovalevv@gmail.com>, repo: https://github.com/alexkovalevv
6
+ * @since 1.0.0
7
+ * @package core
8
+ * @copyright (c) 2018, Webcraftic Ltd
9
+ *
10
+ */
11
+
12
+ // Exit if accessed directly
13
+ if ( ! defined( 'ABSPATH' ) ) {
14
+ exit;
15
+ }
16
+
17
+ if ( defined( 'FACTORY_420_LOADED' ) ) {
18
+ return;
19
+ }
20
+
21
+ define( 'FACTORY_420_LOADED', true );
22
+
23
+ define( 'FACTORY_420_VERSION', '4.2.0' );
24
+
25
+ define( 'FACTORY_420_DIR', dirname( __FILE__ ) );
26
+ define( 'FACTORY_420_URL', plugins_url( null, __FILE__ ) );
27
+
28
+ load_plugin_textdomain( 'wbcr_factory_420', false, dirname( plugin_basename( __FILE__ ) ) . '/langs' );
29
+
30
+ #comp merge
31
+ require_once( FACTORY_420_DIR . '/includes/functions.php' );
32
+
33
+ require_once( FACTORY_420_DIR . '/includes/entities/class-factory-paths.php' );
34
+ require_once( FACTORY_420_DIR . '/includes/entities/class-factory-support.php' );
35
+
36
+ require_once( FACTORY_420_DIR . '/includes/class-factory-requests.php' );
37
+ require_once( FACTORY_420_DIR . '/includes/class-factory-options.php' );
38
+ require_once( FACTORY_420_DIR . '/includes/class-factory-plugin-base.php' );
39
+ require_once( FACTORY_420_DIR . '/includes/class-factory-migrations.php' );
40
+ require_once( FACTORY_420_DIR . '/includes/class-factory-notices.php' );
41
+
42
+ // ASSETS
43
+ require_once( FACTORY_420_DIR . '/includes/assets-managment/class-factory-assets-list.php' );
44
+ require_once( FACTORY_420_DIR . '/includes/assets-managment/class-factory-script-list.php' );
45
+ require_once( FACTORY_420_DIR . '/includes/assets-managment/class-factory-style-list.php' );
46
+
47
+ // PREMIUM
48
+ require_once( FACTORY_420_DIR . '/includes/premium/class-factory-license-interface.php' );
49
+ require_once( FACTORY_420_DIR . '/includes/premium/class-factory-provider-abstract.php' );
50
+ require_once( FACTORY_420_DIR . '/includes/premium/class-factory-manager.php' );
51
+
52
+ // UPDATES
53
+ require_once( FACTORY_420_DIR . '/includes/updates/repositories/class-factory-repository-abstract.php' );
54
+ require_once( FACTORY_420_DIR . '/includes/updates/repositories/class-factory-wordpress.php' );
55
+ require_once( FACTORY_420_DIR . '/includes/updates/class-factory-upgrader.php' );
56
+ require_once( FACTORY_420_DIR . '/includes/updates/class-factory-premium-upgrader.php' );
57
+
58
+ require_once( FACTORY_420_DIR . '/includes/class-factory-plugin-abstract.php' );
59
+
60
+ require_once( FACTORY_420_DIR . '/includes/activation/class-factory-activator.php' );
61
+ require_once( FACTORY_420_DIR . '/includes/activation/class-factory-update.php' );
62
+ #endcomp
libs/factory/core/includes/activation/activator.class.php DELETED
@@ -1,187 +0,0 @@
1
- <?php
2
- /**
3
- * The file contains a base class for plugin activators.
4
- *
5
- * @author Alex Kovalev <alex.kovalevv@gmail.com>
6
- * @copyright (c) 2018, Webcraftic Ltd
7
- *
8
- * @package factory-core
9
- * @since 1.0.0
10
- */
11
- // Exit if accessed directly
12
- if( !defined('ABSPATH') ) {
13
- exit;
14
- }
15
-
16
- if( !class_exists('Wbcr_Factory400_Activator') ) {
17
- /**
18
- * Plugin Activator
19
- *
20
- * @since 1.0.0
21
- */
22
- abstract class Wbcr_Factory400_Activator {
23
-
24
- /**
25
- * Curent plugin.
26
- * @var Wbcr_Factory400_Plugin
27
- */
28
- public $plugin;
29
-
30
- public function __construct(Wbcr_Factory400_Plugin $plugin)
31
- {
32
- $this->plugin = $plugin;
33
- }
34
-
35
- public function activate()
36
- {
37
- }
38
-
39
- public function deactivate()
40
- {
41
- }
42
-
43
- public function update()
44
- {
45
- }
46
-
47
- // --------------------------------------------------------------------------------
48
- // Posts and pages
49
- // --------------------------------------------------------------------------------
50
-
51
- /**
52
- * Adds post on activation.
53
- * @return array Post info.
54
- */
55
- public function addPost()
56
- {
57
-
58
- $args_count = func_num_args();
59
-
60
- $post_info_base = array();
61
- $meta_info_base = array();
62
-
63
- if( $args_count == 4 ) {
64
-
65
- $base = func_get_arg(0);
66
-
67
- $post_info_base = $base['post'];
68
- $meta_info_base = $base['meta'];
69
- }
70
-
71
- $option_name = ($args_count == 4)
72
- ? func_get_arg(1)
73
- : func_get_arg(0);
74
- $post_info = ($args_count == 4)
75
- ? func_get_arg(2)
76
- : func_get_arg(1);
77
- $meta_info = ($args_count == 4)
78
- ? func_get_arg(3)
79
- : func_get_arg(2);
80
-
81
- if( $post_info == null ) {
82
- $post_info = array();
83
- }
84
- if( $meta_info == null ) {
85
- $meta_info = array();
86
- }
87
-
88
- $post_info = array_merge($post_info_base, $post_info);
89
- $meta_info = array_merge($meta_info_base, $meta_info);
90
-
91
- $insert_id = $this->createPost($post_info, $meta_info, $option_name);
92
-
93
- return array(
94
- 'post_id' => $insert_id,
95
- 'post' => $post_info,
96
- 'meta' => $meta_info
97
- );
98
- }
99
-
100
- /**
101
- * * Adds a page on activation.
102
- *
103
- * @return int|null|string|WP_Error
104
- */
105
- public function addPage()
106
- {
107
- $option_name = func_get_arg(0);
108
- $post_info = func_get_arg(1);
109
- $meta_info = func_get_arg(2);
110
-
111
- if( $post_info == null ) {
112
- $post_info = array();
113
- }
114
- if( $meta_info == null ) {
115
- $meta_info = array();
116
- }
117
-
118
- $post_info['post_type'] = 'page';
119
-
120
- return $this->createPost($post_info, $meta_info, $option_name);
121
- }
122
-
123
- /**
124
- * Creates post by using the specified info.
125
- *
126
- * @param array $post_info
127
- * @param array $meta_info
128
- * @param string $option_name
129
- * @return int|null|string|WP_Error
130
- */
131
- public function createPost($post_info, $meta_info, $option_name)
132
- {
133
- global $wpdb;
134
-
135
- $slug = $post_info['post_name'];
136
- $post_type = $post_info['post_type'];
137
-
138
- $postId = $wpdb->get_var($wpdb->prepare("SELECT ID FROM " . $wpdb->posts . " WHERE post_name = '%s' AND
139
- post_type = '%s' LIMIT 1", $slug, $post_type));
140
-
141
- $option_value = $this->plugin->getOption($option_name);
142
-
143
- if( !$postId ) {
144
- $create = true;
145
-
146
- if( !empty($option_value) ) {
147
- $post_id = $wpdb->get_var($wpdb->prepare("SELECT ID FROM " . $wpdb->posts . " WHERE ID = '%d' AND
148
- post_type = '%s' LIMIT 1", $option_value, $post_type));
149
- if( $post_id ) {
150
- $create = false;
151
- }
152
- };
153
-
154
- if( $create ) :
155
- if( !isset($post_info['post_status']) ) {
156
- $post_info['post_status'] = 'publish';
157
- }
158
-
159
- // '@' here is to hide unexpected output while plugin activation
160
- $option_value = @wp_insert_post($post_info);
161
- $postId = $option_value;
162
- $this->plugin->updateOption($option_name, $option_value);
163
- endif;
164
- } else {
165
- if( empty ($option_value) ) {
166
- $this->plugin->updateOption($option_name, $postId);
167
- }
168
- }
169
-
170
- $this->plugin->updateOption($option_name, $postId);
171
-
172
- // adds meta
173
- foreach($meta_info as $key => $value) {
174
- if( $value === true ) {
175
- $value = 'true';
176
- }
177
- if( $value === false ) {
178
- $value = 'false';
179
- }
180
-
181
- add_post_meta($postId, $key, $value);
182
- }
183
-
184
- return $postId;
185
- }
186
- }
187
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
libs/factory/core/includes/activation/class-factory-activator.php ADDED
@@ -0,0 +1,43 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The file contains a base class for plugin activators.
4
+ *
5
+ * @author Alex Kovalev <alex.kovalevv@gmail.com>, repo: https://github.com/alexkovalevv
6
+ * @author Webcraftic <wordpress.webraftic@gmail.com>, site: https://webcraftic.com
7
+ *
8
+ * @package factory-core
9
+ * @since 1.0.0
10
+ */
11
+ // Exit if accessed directly
12
+ if ( ! defined( 'ABSPATH' ) ) {
13
+ exit;
14
+ }
15
+
16
+
17
+ /**
18
+ * Plugin Activator
19
+ *
20
+ * @since 1.0.0
21
+ */
22
+ abstract class Wbcr_Factory420_Activator {
23
+
24
+ /**
25
+ * Curent plugin.
26
+ *
27
+ * @var Wbcr_Factory420_Plugin
28
+ */
29
+ public $plugin;
30
+
31
+ public function __construct( Wbcr_Factory420_Plugin $plugin ) {
32
+ $this->plugin = $plugin;
33
+ }
34
+
35
+ public function activate() {
36
+ }
37
+
38
+ public function deactivate() {
39
+ }
40
+
41
+ public function update() {
42
+ }
43
+ }
libs/factory/core/includes/activation/class-factory-update.php ADDED
@@ -0,0 +1,39 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The file contains a base class for update items of plugins.
4
+ *
5
+ * @author Alex Kovalev <alex.kovalevv@gmail.com>, repo: https://github.com/alexkovalevv
6
+ * @author Webcraftic <wordpress.webraftic@gmail.com>, site: https://webcraftic.com
7
+ *
8
+ * @package factory-core
9
+ * @since 1.0.0
10
+ */
11
+
12
+ // Exit if accessed directly
13
+ if ( ! defined( 'ABSPATH' ) ) {
14
+ exit;
15
+ }
16
+
17
+
18
+ /**
19
+ * Plugin Activator
20
+ *
21
+ * @since 1.0.0
22
+ */
23
+ abstract class Wbcr_Factory420_Update {
24
+
25
+ /**
26
+ * Current plugin
27
+ *
28
+ * @var Wbcr_Factory420_Plugin
29
+ */
30
+ var $plugin;
31
+
32
+ public function __construct( Wbcr_Factory420_Plugin $plugin ) {
33
+ $this->plugin = $plugin;
34
+ }
35
+
36
+ abstract function install();
37
+
38
+ //abstract function rollback();
39
+ }
libs/factory/core/includes/activation/index.php ADDED
@@ -0,0 +1,2 @@
 
 
1
+ <?php
2
+ // Silence is golden.
libs/factory/core/includes/activation/update.class.php DELETED
@@ -1,38 +0,0 @@
1
- <?php
2
- /**
3
- * The file contains a base class for update items of plugins.
4
- *
5
- * @author Alex Kovalev <alex.kovalevv@gmail.com>
6
- * @copyright (c) 2018, Webcraftic Ltd
7
- *
8
- * @package factory-core
9
- * @since 1.0.0
10
- */
11
-
12
- // Exit if accessed directly
13
- if( !defined('ABSPATH') ) {
14
- exit;
15
- }
16
-
17
- if( !class_exists('Wbcr_Factory400_Update') ) {
18
- /**
19
- * Plugin Activator
20
- *
21
- * @since 1.0.0
22
- */
23
- abstract class Wbcr_Factory400_Update {
24
-
25
- /**
26
- * Current plugin
27
- * @var Factory400_Plugin
28
- */
29
- var $plugin;
30
-
31
- public function __construct(Wbcr_Factory400_Plugin $plugin)
32
- {
33
- $this->plugin = $plugin;
34
- }
35
-
36
- abstract function install();
37
- }
38
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
libs/factory/core/includes/assets-managment/assets-list.class.php DELETED
@@ -1,173 +0,0 @@
1
- <?php
2
- /**
3
- * The class contains a base class for all lists of assets.
4
- *
5
- * @author Alex Kovalev <alex.kovalevv@gmail.com>
6
- * @copyright (c) 2018, Webcraftic Ltd
7
- *
8
- * @package factory-core
9
- * @since 1.0.0
10
- */
11
-
12
- // Exit if accessed directly
13
- if( !defined('ABSPATH') ) {
14
- exit;
15
- }
16
- if( !class_exists('Wbcr_Factory400_AssetsList') ) {
17
- /**
18
- * Assets List
19
- *
20
- * @since 1.0.0
21
- */
22
- class Wbcr_Factory400_AssetsList {
23
-
24
- protected $all = array();
25
- public $header_place = array();
26
- public $footer_place = array();
27
- public $required = array();
28
-
29
- protected $default_place;
30
-
31
- /**
32
- * @var Wbcr_Factory400_Plugin
33
- */
34
- protected $plugin;
35
-
36
- /**
37
- * @param Wbcr_Factory400_Plugin $plugin
38
- * @param bool $defaultIsFooter
39
- */
40
- public function __construct(Wbcr_Factory400_Plugin $plugin, $defaultIsFooter = true)
41
- {
42
- $this->plugin = $plugin;
43
-
44
- if( $defaultIsFooter ) {
45
- $this->default_place = &$this->footer_place;
46
- }
47
- if( !$defaultIsFooter ) {
48
- $this->default_place = &$this->header_place;
49
- }
50
- }
51
-
52
- /**
53
- * Adds new items to the collection (default place).
54
- * @param mixed
55
- */
56
- public function add()
57
- {
58
- foreach(func_get_args() as $item) {
59
- $this->all[] = $item;
60
- $this->default_place[] = $item;
61
- }
62
-
63
- return $this;
64
- }
65
-
66
- /**
67
- * Remove items from the collection
68
- * @return $this
69
- */
70
- public function deregister()
71
- {
72
- foreach(func_get_args() as $item) {
73
-
74
- if( !is_string($item) ) {
75
- return $this;
76
- }
77
-
78
- $key_in_all = array_search($item, $this->all);
79
- $key_in_default_place = array_search($item, $this->default_place);
80
- $key_in_header_place = array_search($item, $this->header_place);
81
- $key_inFooterPlace = array_search($item, $this->footer_place);
82
-
83
- if( $key_in_all ) {
84
- unset($this->all[$key_in_all]);
85
- }
86
- if( $key_in_default_place ) {
87
- unset($this->default_place[$key_in_default_place]);
88
- }
89
- if( $key_in_header_place ) {
90
- unset($this->header_place[$key_in_header_place]);
91
- }
92
- if( $key_inFooterPlace ) {
93
- unset($this->footer_place[$key_inFooterPlace]);
94
- }
95
- }
96
-
97
- return $this;
98
- }
99
-
100
- /**
101
- * Adds new items to the collection (header).
102
- * @param mixed
103
- */
104
- public function addToHeader()
105
- {
106
-
107
- foreach(func_get_args() as $item) {
108
- $this->all[] = $item;
109
- $this->header_place[] = $item;
110
- }
111
-
112
- return $this;
113
- }
114
-
115
- /**
116
- * Adds new items to the collection (footer).
117
- * @param mixed
118
- */
119
- public function addToFooter()
120
- {
121
-
122
- foreach(func_get_args() as $item) {
123
- $this->all[] = $item;
124
- $this->footer_place[] = $item;
125
- }
126
-
127
- return $this;
128
- }
129
-
130
- /**
131
- * Checks whether the collection is empty.
132
- *
133
- * @param string $source if the 'bootstrap' specified, checks only whether the bootstrap assets were required.
134
- * @return boolean
135
- */
136
- public function isEmpty($source = 'wordpress')
137
- {
138
- if( 'bootstrap' === $source ) {
139
- return empty($this->required[$source]);
140
- }
141
-
142
- return empty($this->all) && empty($this->required);
143
- }
144
-
145
- public function IsHeaderEmpty()
146
- {
147
- return empty($this->header_place);
148
- }
149
-
150
- public function IsFooterEmpty()
151
- {
152
- return empty($this->footer_place);
153
- }
154
-
155
- /**
156
- * Adds new items to the requried collection.
157
- * @param mixed
158
- */
159
- public function request($items, $source = 'wordpress')
160
- {
161
-
162
- if( is_array($items) ) {
163
- foreach($items as $item) {
164
- $this->required[$source][] = $item;
165
- }
166
- } else {
167
- $this->required[$source][] = $items;
168
- }
169
-
170
- return $this;
171
- }
172
- }
173
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
libs/factory/core/includes/assets-managment/class-factory-assets-list.php ADDED
@@ -0,0 +1,126 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The class contains a base class for all lists of assets.
4
+ *
5
+ * @author Alex Kovalev <alex.kovalevv@gmail.com>, repo: https://github.com/alexkovalevv
6
+ * @author Webcraftic <wordpress.webraftic@gmail.com>, site: https://webcraftic.com
7
+ *
8
+ * @package factory-core
9
+ * @since 1.0.0
10
+ */
11
+
12
+ // Exit if accessed directly
13
+ if ( ! defined( 'ABSPATH' ) ) {
14
+ exit;
15
+ }
16
+
17
+ /**
18
+ * Assets List
19
+ *
20
+ * @since 1.0.0
21
+ */
22
+ class Wbcr_Factory420_AssetsList {
23
+
24
+ protected $all = [];
25
+ public $header_place = [];
26
+ public $footer_place = [];
27
+ public $required = [];
28
+
29
+ protected $default_place;
30
+
31
+ /**
32
+ * @var Wbcr_Factory420_Plugin
33
+ */
34
+ protected $plugin;
35
+
36
+ /**
37
+ * @param Wbcr_Factory420_Plugin $plugin
38
+ * @param bool $defaultIsFooter
39
+ */
40
+ public function __construct( Wbcr_Factory420_Plugin $plugin, $defaultIsFooter = true ) {
41
+ $this->plugin = $plugin;
42
+
43
+ if ( $defaultIsFooter ) {
44
+ $this->default_place = &$this->footer_place;
45
+ }
46
+ if ( ! $defaultIsFooter ) {
47
+ $this->default_place = &$this->header_place;
48
+ }
49
+ }
50
+
51
+ /**
52
+ * Remove items from the collection
53
+ *
54
+ * @return $this
55
+ */
56
+ public function deregister() {
57
+ foreach ( func_get_args() as $item ) {
58
+
59
+ if ( ! is_string( $item ) ) {
60
+ return $this;
61
+ }
62
+
63
+ $key_in_all = array_search( $item, $this->all );
64
+ $key_in_default_place = array_search( $item, $this->default_place );
65
+ $key_in_header_place = array_search( $item, $this->header_place );
66
+ $key_inFooterPlace = array_search( $item, $this->footer_place );
67
+
68
+ if ( $key_in_all ) {
69
+ unset( $this->all[ $key_in_all ] );
70
+ }
71
+ if ( $key_in_default_place ) {
72
+ unset( $this->default_place[ $key_in_default_place ] );
73
+ }
74
+ if ( $key_in_header_place ) {
75
+ unset( $this->header_place[ $key_in_header_place ] );
76
+ }
77
+ if ( $key_inFooterPlace ) {
78
+ unset( $this->footer_place[ $key_inFooterPlace ] );
79
+ }
80
+ }
81
+
82
+ return $this;
83
+ }
84
+
85
+ /**
86
+ * Checks whether the collection is empty.
87
+ *
88
+ * @param string $source if the 'bootstrap' specified, checks only whether the bootstrap assets were required.
89
+ *
90
+ * @return boolean
91
+ */
92
+ public function isEmpty( $source = 'wordpress' ) {
93
+ if ( 'bootstrap' === $source ) {
94
+ return empty( $this->required[ $source ] );
95
+ }
96
+
97
+ return empty( $this->all ) && empty( $this->required );
98
+ }
99
+
100
+ public function IsHeaderEmpty() {
101
+ return empty( $this->header_place );
102
+ }
103
+
104
+ public function IsFooterEmpty() {
105
+ return empty( $this->footer_place );
106
+ }
107
+
108
+ /**
109
+ * Adds new items to the requried collection.
110
+ *
111
+ * @param mixed
112
+ */
113
+ public function request( $items, $source = 'wordpress' ) {
114
+
115
+ if ( is_array( $items ) ) {
116
+ foreach ( $items as $item ) {
117
+ $this->required[ $source ][] = $item;
118
+ }
119
+ } else {
120
+ $this->required[ $source ][] = $items;
121
+ }
122
+
123
+ return $this;
124
+ }
125
+ }
126
+
libs/factory/core/includes/assets-managment/class-factory-script-list.php ADDED
@@ -0,0 +1,166 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The file contains a class to manage script assets.
4
+ *
5
+ * @author Alex Kovalev <alex.kovalevv@gmail.com>, repo: https://github.com/alexkovalevv
6
+ * @author Webcraftic <wordpress.webraftic@gmail.com>, site: https://webcraftic.com
7
+ *
8
+ * @package factory-core
9
+ * @since 1.0.0
10
+ */
11
+
12
+ // Exit if accessed directly
13
+ if ( ! defined( 'ABSPATH' ) ) {
14
+ exit;
15
+ }
16
+
17
+
18
+ /**
19
+ * Script List
20
+ *
21
+ * @since 1.0.0
22
+ */
23
+ class Wbcr_Factory420_ScriptList extends Wbcr_Factory420_AssetsList {
24
+
25
+ public $localize_data = [];
26
+ public $use_ajax = false;
27
+
28
+ /**
29
+ * Adds new items to the collection (default place).
30
+ *
31
+ * @param mixed
32
+ *
33
+ * @version 2.0
34
+ */
35
+ public function add( $file_url, $deps = [ 'jquery' ], $handle = null, $version = false, $place = 'default' ) {
36
+
37
+ if ( empty( $file_url ) ) {
38
+ return $this;
39
+ }
40
+
41
+ $resource = [];
42
+ $resource['file_url'] = $file_url;
43
+ $resource['deps'] = $deps;
44
+ $resource['handle'] = $handle;
45
+ $resource['version'] = $version;
46
+
47
+ $this->all[] = $resource;
48
+
49
+ switch ( $place ) {
50
+ case 'header':
51
+ $this->header_place[] = $resource;
52
+ break;
53
+ case 'footer':
54
+ $this->footer_place[] = $resource;
55
+ break;
56
+ default:
57
+ $this->default_place[] = $resource;
58
+ break;
59
+ }
60
+
61
+ return $this;
62
+ }
63
+
64
+ /**
65
+ * Adds new items to the collection (header).
66
+ *
67
+ * @param mixed
68
+ */
69
+ public function addToHeader( $file_url, $deps = [ 'jquery' ], $handle = null ) {
70
+ return $this->add( $file_url, $deps, $handle, 'header' );
71
+ }
72
+
73
+ /**
74
+ * Adds new items to the collection (footer).
75
+ *
76
+ * @param mixed
77
+ */
78
+ public function addToFooter( $file_url, $deps = [ 'jquery' ], $handle = null ) {
79
+ return $this->add( $file_url, $deps, $handle, 'footer' );
80
+ }
81
+
82
+ /**
83
+ * Осуществляет подключение всех зарегистрированных скриптов
84
+ *
85
+ * @param string $source
86
+ */
87
+ public function connect( $source = 'wordpress' ) {
88
+
89
+ // register all global required scripts
90
+ if ( ! empty( $this->required[ $source ] ) ) {
91
+ foreach ( $this->required[ $source ] as $script ) {
92
+ if ( 'wordpress' === $source ) {
93
+ wp_enqueue_script( $script );
94
+ } else if ( 'bootstrap' === $source ) {
95
+ $this->plugin->bootstrap->enqueueScript( $script );
96
+ }
97
+ }
98
+ }
99
+
100
+ if ( $source == 'bootstrap' ) {
101
+ return;
102
+ }
103
+
104
+ $is_first_script = true;
105
+ $is_footer = false;
106
+
107
+ // register all other scripts
108
+ foreach ( [ $this->header_place, $this->footer_place ] as $script_place ) {
109
+ foreach ( $script_place as $script ) {
110
+
111
+ if ( empty( $script['file_url'] ) ) {
112
+ continue;
113
+ }
114
+
115
+ $handle = ! empty( $script['handle'] ) ? $script['handle'] : $script['file_url'];
116
+ $deps = ! is_array( $script['deps'] ) ? [] : $script['deps'];
117
+ $version = ! empty( $script['version'] ) ? $script['version'] : $this->plugin->getPluginVersion();
118
+
119
+ wp_register_script( $handle, $script['file_url'], $deps, $version, $is_footer );
120
+
121
+ if ( $is_first_script && $this->use_ajax ) {
122
+ wp_localize_script( $handle, 'factory', [ 'ajaxurl' => admin_url( 'admin-ajax.php' ) ] );
123
+ }
124
+
125
+ if ( ! empty( $this->localize_data[ $handle ] ) ) {
126
+ wp_localize_script( $handle, $this->localize_data[ $handle ][0], $this->localize_data[ $handle ][1] );
127
+ }
128
+
129
+ wp_enqueue_script( $handle );
130
+
131
+ $is_first_script = false;
132
+ }
133
+
134
+ $is_footer = true;
135
+ }
136
+ }
137
+
138
+ /**
139
+ * Если вызвать этот метод, на странице будет обязательно добавлена
140
+ * глобальная JS переменная с ссылкой на ajax обработчик
141
+ */
142
+ public function useAjax() {
143
+ $this->use_ajax = true;
144
+ }
145
+
146
+ /**
147
+ * Регистрирует глобальную JS переменную с пользовательскими данными
148
+ *
149
+ * @param string $varname
150
+ * @param string $data
151
+ *
152
+ * @return Wbcr_Factory420_ScriptList $this
153
+ */
154
+ public function localize( $varname, $data ) {
155
+ $bindTo = count( $this->all ) == 0 ? null : end( $this->all );
156
+
157
+ if ( ! $bindTo ) {
158
+ return $this;
159
+ }
160
+
161
+ $this->localize_data[ $bindTo ] = [ $varname, $data ];
162
+
163
+ return $this;
164
+ }
165
+ }
166
+
libs/factory/core/includes/assets-managment/class-factory-style-list.php ADDED
@@ -0,0 +1,86 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The file contains a class to manage style assets.
4
+ *
5
+ * @author Alex Kovalev <alex.kovalevv@gmail.com>, repo: https://github.com/alexkovalevv
6
+ * @author Webcraftic <wordpress.webraftic@gmail.com>, site: https://webcraftic.com
7
+ *
8
+ * @package factory-core
9
+ * @since 1.0.0
10
+ */
11
+
12
+ // Exit if accessed directly
13
+ if ( ! defined( 'ABSPATH' ) ) {
14
+ exit;
15
+ }
16
+
17
+
18
+ /**
19
+ * Style List
20
+ *
21
+ * @since 1.0.0
22
+ */
23
+ class Wbcr_Factory420_StyleList extends Wbcr_Factory420_AssetsList {
24
+
25
+ /**
26
+ * Adds new items to the collection (default place).
27
+ *
28
+ * @param mixed
29
+ *
30
+ * @version 2.0
31
+ */
32
+ public function add( $file_url, $deps = [], $handle = null, $version = false, $media = 'all' ) {
33
+
34
+ if ( empty( $file_url ) ) {
35
+ return $this;
36
+ }
37
+
38
+ $resource = [];
39
+ $resource['file_url'] = $file_url;
40
+ $resource['deps'] = $deps;
41
+ $resource['handle'] = $handle;
42
+ $resource['version'] = $version;
43
+ $resource['media'] = $media;
44
+
45
+ $this->all[] = $resource;
46
+
47
+ return $this;
48
+ }
49
+
50
+ public function connect( $source = 'wordpress' ) {
51
+ // register all global required scripts
52
+ if ( ! empty( $this->required[ $source ] ) ) {
53
+
54
+ foreach ( $this->required[ $source ] as $style ) {
55
+ if ( 'wordpress' === $source ) {
56
+ wp_enqueue_style( $style );
57
+ } else if ( 'bootstrap' === $source ) {
58
+ $this->plugin->bootstrap->enqueueStyle( $style );
59
+ }
60
+ }
61
+ }
62
+
63
+ if ( $source == 'bootstrap' ) {
64
+ return;
65
+ }
66
+
67
+ if ( empty( $this->all ) ) {
68
+ return;
69
+ }
70
+
71
+ // register all other styles
72
+ foreach ( $this->all as $style ) {
73
+
74
+ if ( empty( $style['file_url'] ) ) {
75
+ continue;
76
+ }
77
+
78
+ $handle = ! empty( $style['handle'] ) ? $style['handle'] : md5( $style['file_url'] );
79
+ $deps = ! is_array( $style['deps'] ) ? [] : $style['deps'];
80
+ $version = ! empty( $style['version'] ) ? $style['version'] : $this->plugin->getPluginVersion();
81
+
82
+ wp_enqueue_style( $handle, $style['file_url'], $deps, $version );
83
+ }
84
+ }
85
+ }
86
+
libs/factory/core/includes/assets-managment/index.php ADDED
@@ -0,0 +1,2 @@
 
 
1
+ <?php
2
+ // Silence is golden.
libs/factory/core/includes/assets-managment/script-list.class.php DELETED
@@ -1,97 +0,0 @@
1
- <?php
2
- /**
3
- * The file contains a class to manage script assets.
4
- *
5
- * @author Alex Kovalev <alex.kovalevv@gmail.com>
6
- * @copyright (c) 2018, Webcraftic Ltd
7
- *
8
- * @package factory-core
9
- * @since 1.0.0
10
- */
11
-
12
- // Exit if accessed directly
13
- if( !defined('ABSPATH') ) {
14
- exit;
15
- }
16
-
17
- if( !class_exists('Wbcr_Factory400_ScriptList') ) {
18
-
19
- /**
20
- * Script List
21
- *
22
- * @since 1.0.0
23
- */
24
- class Wbcr_Factory400_ScriptList extends Wbcr_Factory400_AssetsList {
25
-
26
- public $localize_data = array();
27
- public $use_ajax = false;
28
-
29
- /**
30
- * @param string $source
31
- */
32
- public function connect($source = 'wordpress')
33
- {
34
-
35
- // register all global required scripts
36
- if( !empty($this->required[$source]) ) {
37
- foreach($this->required[$source] as $script) {
38
- if( 'wordpress' === $source ) {
39
- wp_enqueue_script($script);
40
- } elseif( 'bootstrap' === $source ) {
41
- $this->plugin->bootstrap->enqueueScript($script);
42
- }
43
- }
44
- }
45
-
46
- if( $source == 'bootstrap' ) {
47
- return;
48
- }
49
-
50
- $is_first_script = true;
51
- $is_footer = false;
52
-
53
- // register all other scripts
54
- foreach(array($this->header_place, $this->footer_place) as $scriptPlace) {
55
- foreach($scriptPlace as $script) {
56
-
57
- wp_register_script($script, $script, array(), $this->plugin->getPluginVersion(), $is_footer);
58
-
59
- if( $is_first_script && $this->use_ajax ) {
60
- wp_localize_script($script, 'factory', array('ajaxurl' => admin_url('admin-ajax.php')));
61
- }
62
-
63
- if( !empty($this->localize_data[$script]) ) {
64
-
65
- wp_localize_script($script, $this->localize_data[$script][0], $this->localize_data[$script][1]);
66
- }
67
-
68
- wp_enqueue_script($script);
69
-
70
- $is_first_script = false;
71
- }
72
-
73
- $is_footer = true;
74
- }
75
- }
76
-
77
- public function useAjax()
78
- {
79
- $this->use_ajax = true;
80
- }
81
-
82
- public function localize($varname, $data)
83
- {
84
- $bindTo = count($this->all) == 0
85
- ? null
86
- : end($this->all);
87
-
88
- if( !$bindTo ) {
89
- return;
90
- }
91
-
92
- $this->localize_data[$bindTo] = array($varname, $data);
93
-
94
- return $this;
95
- }
96
- }
97
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
libs/factory/core/includes/assets-managment/style-list.class.php DELETED
@@ -1,51 +0,0 @@
1
- <?php
2
- /**
3
- * The file contains a class to manage style assets.
4
- *
5
- * @author Alex Kovalev <alex.kovalevv@gmail.com>
6
- * @copyright (c) 2018, Webcraftic Ltd
7
- *
8
- * @package factory-core
9
- * @since 1.0.0
10
- */
11
-
12
- // Exit if accessed directly
13
- if( !defined('ABSPATH') ) {
14
- exit;
15
- }
16
-
17
- if( !class_exists('Wbcr_Factory400_StyleList') ) {
18
-
19
- /**
20
- * Style List
21
- *
22
- * @since 1.0.0
23
- */
24
- class Wbcr_Factory400_StyleList extends Wbcr_Factory400_AssetsList {
25
-
26
- public function connect($source = 'wordpress')
27
- {
28
-
29
- // register all global required scripts
30
- if( !empty($this->required[$source]) ) {
31
-
32
- foreach($this->required[$source] as $style) {
33
- if( 'wordpress' === $source ) {
34
- wp_enqueue_style($style);
35
- } elseif( 'bootstrap' === $source ) {
36
- $this->plugin->bootstrap->enqueueStyle($style);
37
- }
38
- }
39
- }
40
-
41
- if( $source == 'bootstrap' ) {
42
- return;
43
- }
44
-
45
- // register all other styles
46
- foreach($this->all as $style) {
47
- wp_enqueue_style(md5($style), $style, array(), $this->plugin->getPluginVersion());
48
- }
49
- }
50
- }
51
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
libs/factory/core/includes/base.class.php DELETED
@@ -1,378 +0,0 @@
1
- <?php
2
- // Exit if accessed directly
3
- if( !defined('ABSPATH') ) {
4
- exit;
5
- }
6
-
7
- if( !class_exists('Wbcr_Factory400_Base') ) {
8
- class Wbcr_Factory400_Base {
9
-
10
- /**
11
- * Буферизуем опции плагинов в этот атрибут, для быстрого доступа
12
- *
13
- * @var array
14
- */
15
- private static $_opt_buffer = array();
16
-
17
- /**
18
- * Префикс для пространства имен среди опций Wordpress
19
- *
20
- * @var string
21
- */
22
- protected $prefix;
23
-
24
- /**
25
- * Экзамеляр класса Wbcr_Factory400_Request, необходим управляет http запросами
26
- *
27
- * @var Wbcr_Factory400_Request
28
- */
29
- public $request;
30
-
31
- public function __construct($plugin_path, $data)
32
- {
33
- $this->prefix = isset($data['prefix'])
34
- ? $data['prefix']
35
- : null;
36
-
37
- if( empty($this->prefix) || !is_string($this->prefix) ) {
38
- throw new Exception('Не передан один из обязательных атрибутов (prefix) или атрибует не соотвествует типу данных string.');
39
- }
40
-
41
- $this->request = new Wbcr_Factory400_Request();
42
-
43
- if( !isset(self::$_opt_buffer[$this->prefix]) ) {
44
- $cache_options = get_option($this->prefix . 'cache_options', array());
45
-
46
- if( empty($cache_options) || !is_array($cache_options) ) {
47
- $cache_options = array();
48
- delete_option($this->prefix . 'cache_options');
49
- }
50
-
51
- self::$_opt_buffer[$this->prefix] = $cache_options;
52
- }
53
- }
54
-
55
- /**
56
- * Получает опцию из кеша или из базы данные, если опция не кешируемая,
57
- * то опция тянется только из базы данных. Не кешируемые опции это массивы,
58
- * сериализованные массивы, строки больше 150 символов
59
- *
60
- * @param string $option_name
61
- * @param bool $default
62
- * @return mixed|void
63
- */
64
- public function getOption($option_name, $default = false)
65
- {
66
- if( $option_name == 'cache_options' ) {
67
- return $default;
68
- }
69
-
70
- $get_cache_option = $this->getOptionFromCache($option_name);
71
-
72
- if( !is_null($get_cache_option) ) {
73
- return $get_cache_option === false
74
- ? $default
75
- : $get_cache_option;
76
- }
77
-
78
- $option_value = get_option($this->prefix . $option_name);
79
-
80
- if( $this->isCacheable($option_value) ) {
81
- $this->setCacheOption($option_name, $this->normalizeValue($option_value));
82
- }
83
-
84
- return $option_value === false
85
- ? $default
86
- : $this->normalizeValue($option_value);
87
- }
88
-
89
- /**
90
- * Обновляет опцию в базе данных и в кеше, кеш обновляется только кешируемых опций.
91
- * Не кешируемые опции это массивы, сериализованные массивы, строки больше 150 символов
92
- *
93
- * @param string $option_name
94
- * @param string $value
95
- * @return void
96
- */
97
- public function updateOption($option_name, $value)
98
- {
99
- if( $this->isCacheable($value) ) {
100
- $this->setCacheOption($option_name, $this->normalizeValue($value));
101
- } else {
102
- if( isset(self::$_opt_buffer[$this->prefix][$option_name]) ) {
103
- unset(self::$_opt_buffer[$this->prefix][$option_name]);
104
-
105
- $this->updateOption('cache_options', self::$_opt_buffer[$this->prefix]);
106
- }
107
- }
108
-
109
- update_option($this->prefix . $option_name, $value);
110
- }
111
-
112
- /**
113
- * Пакетное обновление опций, также метод пакетно обновляет кеш в базе данных
114
- * и в буфере опций, кеш обновляется только кешируемых опций. Не кешируемые опции это массивы,
115
- * сериализованные массивы, строки больше 150 символов
116
- *
117
- * @param array $options
118
- * @return bool
119
- */
120
- public function updateOptions($options)
121
- {
122
- if( empty($options) ) {
123
- return false;
124
- }
125
-
126
- foreach((array)$options as $option_name => $option_value) {
127
- $this->updateOption($option_name, $option_value);
128
- }
129
-
130
- $this->updateCacheOptions($options);
131
-
132
- return true;
133
- }
134
-
135
- /**
136
- * Удаляет опцию из базы данных, если опция есть в кеше,
137
- * индивидуально удаляет опцию из кеша.
138
- *
139
- * @param string $option_name
140
- * @return void
141
- */
142
- public function deleteOption($option_name)
143
- {
144
- if( isset(self::$_opt_buffer[$this->prefix][$option_name]) ) {
145
- unset(self::$_opt_buffer[$this->prefix][$option_name]);
146
-
147
- $this->updateOption('cache_options', self::$_opt_buffer[$this->prefix]);
148
- }
149
-
150
- delete_option($this->prefix . $option_name . '_is_active');
151
- delete_option($this->prefix . $option_name);
152
- }
153
-
154
- /**
155
- * Пакетное удаление опций, после удаления опции происходит очистка кеша и буфера опций
156
- *
157
- * @param array $options
158
- * @return void
159
- */
160
- public function deleteOptions($options)
161
- {
162
- if( !empty($options) ) {
163
- foreach((array)$options as $option_name) {
164
- if( isset(self::$_opt_buffer[$this->prefix]) ) {
165
- unset(self::$_opt_buffer[$this->prefix]);
166
- }
167
-
168
- delete_option($this->prefix . $option_name . '_is_active');
169
- delete_option($this->prefix . $option_name);
170
- }
171
-
172
- $this->updateOption('cache_options', self::$_opt_buffer[$this->prefix]);
173
- }
174
- }
175
-
176
- /**
177
- * Сбрасывает кеш опций, удаляет кеш из базы данных и буфер опций
178
- *
179
- * @return bool
180
- */
181
- public function flushOptionsCache()
182
- {
183
- if( isset(self::$_opt_buffer[$this->prefix]) ) {
184
- unset(self::$_opt_buffer[$this->prefix]);
185
- self::$_opt_buffer[$this->prefix] = array();
186
- }
187
-
188
- $this->deleteOption('cache_options');
189
- }
190
-
191
- /**
192
- * Получает все опций текущего плагина
193
- *
194
- * @param bool $is_cacheable - только кешируемые опции, кешируемые опции это массивы,
195
- * сериализованные массивы, строки больше 150 символов
196
- * @return array
197
- */
198
- protected function getAllPluginOptions($is_cacheable = true)
199
- {
200
- global $wpdb;
201
- $options = array();
202
-
203
- $request = $wpdb->get_results($wpdb->prepare("
204
- SELECT option_name, option_value
205
- FROM {$wpdb->prefix}options
206
- WHERE option_name
207
- LIKE '%s'", $this->prefix . "%"));
208
-
209
- if( !empty($request) ) {
210
- foreach((array)$request as $option) {
211
- if( $is_cacheable && !$this->isCacheable($option->option_value) ) {
212
- continue;
213
- }
214
- $options[$option->option_name] = $this->normalizeValue($option->option_value);
215
- }
216
- }
217
-
218
- return $options;
219
- }
220
-
221
-
222
- /**
223
- * Записывает только одну опцию в кеш базы данных и в буфер
224
- *
225
- * @param string $option_name
226
- * @param string $value
227
- * @return void
228
- * @throws Exception
229
- */
230
- protected function setCacheOption($option_name, $value)
231
- {
232
- $this->setBufferOption($option_name, $value);
233
-
234
- if( !empty(self::$_opt_buffer[$this->prefix]) ) {
235
- $this->updateOption('cache_options', self::$_opt_buffer[$this->prefix]);
236
- }
237
- }
238
-
239
- /**
240
- * Пакетное обновление опций в кеше и буфер опций,
241
- * все записываемые опции приводятся к регламентированному типу данных
242
- *
243
- * @param array $options
244
- * @return bool
245
- * @throws Exception
246
- */
247
- protected function updateCacheOptions($options)
248
- {
249
- foreach((array)$options as $option_name => $value) {
250
- $option_name = str_replace($this->prefix, '', $option_name);
251
- $this->setBufferOption($option_name, $this->normalizeValue($value));
252
- }
253
-
254
- if( !empty(self::$_opt_buffer[$this->prefix]) ) {
255
- $this->updateOption('cache_options', self::$_opt_buffer[$this->prefix]);
256
- }
257
-
258
- return false;
259
- }
260
-
261
- /**
262
- * Получает опцию из кеша или буфера, если опция не найдена и буфер пуст,
263
- * то заполняет буфер кеширумыми опциями, которые уже записаны в базу данных.
264
- *
265
- * @param string $option_name
266
- * @return null
267
- * @throws Exception
268
- */
269
- protected function getOptionFromCache($option_name)
270
- {
271
- if( empty(self::$_opt_buffer[$this->prefix]) ) {
272
- $all_options = $this->getAllPluginOptions();
273
-
274
- if( !empty($all_options) ) {
275
- $this->updateCacheOptions($all_options);
276
- }
277
- }
278
-
279
- $buffer_option = $this->getBufferOption($option_name);
280
-
281
- if( !is_null($buffer_option) ) {
282
- return $buffer_option;
283
- }
284
-
285
- return null;
286
- }
287
-
288
- /**
289
- * Получает опцию из буфера опций
290
- *
291
- * @param string $option_name
292
- * @return null|mixed
293
- */
294
- private function getBufferOption($option_name)
295
- {
296
- if( isset(self::$_opt_buffer[$this->prefix][$option_name]) ) {
297
- return self::$_opt_buffer[$this->prefix][$option_name];
298
- }
299
-
300
- return null;
301
- }
302
-
303
- /**
304
- * Записывает опции в буфер опций, если опция уже есть в буфере и их значения не совпадают,
305
- * то новое значение перезаписывает старое
306
- *
307
- * @param string $option_name
308
- * @param string $option_value
309
- */
310
- private function setBufferOption($option_name, $option_value)
311
- {
312
- if( !isset(self::$_opt_buffer[$this->prefix][$option_name]) ) {
313
- self::$_opt_buffer[$this->prefix][$option_name] = $option_value;
314
- } else {
315
- if( self::$_opt_buffer[$this->prefix][$option_name] !== $option_value ) {
316
- self::$_opt_buffer[$this->prefix][$option_name] = $option_value;
317
- }
318
- }
319
- }
320
-
321
- /**
322
- * Возвращает название опции в пространстве имен плагина
323
- *
324
- * @param string $option_name
325
- * @return null|string
326
- */
327
- public function getOptionName($option_name)
328
- {
329
- $option_name = trim(rtrim($option_name));
330
- if( empty($option_name) || !is_string($option_name) ) {
331
- return null;
332
- }
333
-
334
- return $this->prefix . $option_name;
335
- }
336
-
337
- /**
338
- * Проверяет является ли опция кешируемой. Кешируемые опции это массивы,
339
- * сериализованные массивы, строки больше 150 символов.
340
- *
341
- * @param string $data - переданое значение опции
342
- * @return bool
343
- */
344
- public function isCacheable($data)
345
- {
346
- if( (is_string($data) && (is_serialized($data) || strlen($data) > 150)) || is_array($data) ) {
347
- return false;
348
- }
349
-
350
- return true;
351
- }
352
-
353
- /**
354
- * Приведение значений опций к строгому типу данных
355
- *
356
- * @param $string
357
- * @return bool|int
358
- */
359
- public function normalizeValue($string)
360
- {
361
- if( is_numeric($string) ) {
362
- $number = intval($string);
363
-
364
- if( strlen($number) != strlen($string) ) {
365
- throw new Exception('Error converting data type to a number.');
366
- }
367
-
368
- return $number;
369
- } else if( $string === 'false' ) {
370
- return false;
371
- } else if( $string === 'true' ) {
372
- return true;
373
- }
374
-
375
- return $string;
376
- }
377
- }
378
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
libs/factory/core/includes/class-check-compatibility.php ADDED
@@ -0,0 +1,122 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Проверяет совместимость с плагинами Webcraftic, с версиями php, с версиями Wordpress
5
+ *
6
+ * @author Alex Kovalev <alex.kovalevv@gmail.com>, repo: https://github.com/alexkovalevv
7
+ * @author Webcraftic <wordpress.webraftic@gmail.com>, site: https://webcraftic.com
8
+ *
9
+ * @version 1.0.0
10
+ * @since 4.0.8
11
+ */
12
+
13
+ if ( ! class_exists( 'Wbcr_Factory_Compatibility' ) ) {
14
+ class Wbcr_Factory_Compatibility {
15
+
16
+ protected $plugin_prefix;
17
+ protected $plugin_class_prefix;
18
+ protected $plugin_name;
19
+ protected $plugin_title = "(no title)";
20
+ protected $required_php_version = '5.3';
21
+ protected $required_wp_version = '4.2.0';
22
+
23
+ function __construct( array $plugin_info ) {
24
+ foreach ( (array) $plugin_info as $property => $value ) {
25
+ $this->$property = $value;
26
+ }
27
+
28
+ add_action( 'admin_init', [ $this, 'registerNotices' ] );
29
+ }
30
+
31
+ /**
32
+ * Метод проверяет совместимость плагина с php и wordpress версией
33
+ *
34
+ * @return bool
35
+ */
36
+ public function check() {
37
+ if ( ! $this->isPhpCompatibility() ) {
38
+ return false;
39
+ }
40
+
41
+ if ( ! $this->isWpCompatibility() ) {
42
+ return false;
43
+ }
44
+
45
+ return true;
46
+ }
47
+
48
+ /**
49
+ * Метод проверяет совместимость плагина с php версией сервера
50
+ *
51
+ * @return mixed
52
+ */
53
+ public function isPhpCompatibility() {
54
+ return version_compare( PHP_VERSION, $this->required_php_version, '>=' );
55
+ }
56
+
57
+ /**
58
+ * Метод проверяет совместимость плагина с Wordpress версией сайта
59
+ *
60
+ * @return mixed
61
+ */
62
+ public function isWpCompatibility() {
63
+ // Get the WP Version global.
64
+ global $wp_version;
65
+
66
+ return version_compare( $wp_version, $this->required_wp_version, '>=' );
67
+ }
68
+
69
+ /**
70
+ * Метод возвращает текст уведомления
71
+ *
72
+ * @return string
73
+ */
74
+ public function getNoticeText() {
75
+ $notice_text = $notice_default_text = '';
76
+ $notice_default_text .= '<b>' . $this->plugin_title . ' ' . __( 'warning', '' ) . ':</b>' . '<br>';
77
+
78
+ $notice_default_text .= sprintf( __( 'The %s plugin has stopped.', 'wbcr_factory_clearfy_212' ), $this->plugin_title ) . ' ';
79
+ $notice_default_text .= __( 'Possible reasons:', '' ) . ' <br>';
80
+
81
+ $has_one = false;
82
+
83
+ if ( ! $this->isPhpCompatibility() ) {
84
+ $has_one = true;
85
+ $notice_text .= '- ' . sprintf( __( 'You need to update the PHP version to %s or higher!', 'wbcr_factory_420' ), $this->required_php_version ) . '<br>';
86
+ }
87
+
88
+ if ( ! $this->isWpCompatibility() ) {
89
+ $has_one = true;
90
+ $notice_text .= '- ' . sprintf( __( 'You need to update WordPress to %s or higher!', 'wbcr_factory_420' ), $this->required_wp_version ) . '<br>';
91
+ }
92
+
93
+ if ( $has_one ) {
94
+ $notice_text = $notice_default_text . $notice_text;
95
+ }
96
+
97
+ return $notice_text;
98
+ }
99
+
100
+ public function registerNotices() {
101
+ if ( current_user_can( 'activate_plugins' ) && current_user_can( 'edit_plugins' ) && current_user_can( 'install_plugins' ) ) {
102
+ if ( is_multisite() ) {
103
+ add_action( 'network_admin_notices', [ $this, 'showNotice' ] );
104
+ }
105
+
106
+ add_action( 'admin_notices', [ $this, 'showNotice' ] );
107
+ }
108
+ }
109
+
110
+ public function showNotice() {
111
+ $notice_text = $this->getNoticeText();
112
+
113
+ if ( empty( $notice_text ) ) {
114
+ return;
115
+ }
116
+
117
+ $notice_text = '<p>' . $this->getNoticeText() . '</p>';
118
+
119
+ echo '<div class="notice notice-error">' . apply_filters( 'wbcr/factory/check_compatibility/notice_text', $notice_text, $this->plugin_name ) . '</div>';
120
+ }
121
+ }
122
+ }
libs/factory/core/includes/class-factory-migrations.php ADDED
@@ -0,0 +1,541 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace WBCR\Factory_420;
4
+
5
+ use Exception;
6
+ use Wbcr_Factory420_Plugin;
7
+
8
+ if ( ! defined( 'ABSPATH' ) ) {
9
+ exit;
10
+ }
11
+
12
+ /**
13
+ * Often when updating plugins, you need to make some changes to the database.
14
+ * This class automatically checks for plugin migrations and executes them when
15
+ * updating.
16
+ *
17
+ * The class has a debug mode, to enable the debug mode add constants to your plugin:
18
+ * define ('FACTORY_MIGRATIONS_DEBUG', true) - enables/disables debugging mode
19
+ * define ('FACTORY_MIGRATIONS_FORCE_OLD_VERSION', '1.1.9') - sets previous version
20
+ * for the plugin, if constant isn't set, then the previous version is taken from
21
+ * the database.
22
+ *
23
+ * todo: get_option and get_site_option are used because some caching plugins caching options, which causes problems
24
+ *
25
+ *
26
+ * @author Alex Kovalev <alex.kovalevv@gmail.com>, repo: https://github.com/alexkovalevv
27
+ * @author Webcraftic <wordpress.webraftic@gmail.com>, site: https://webcraftic.com
28
+ *
29
+ * @since 4.1.1
30
+ */
31
+ class Migrations {
32
+
33
+ protected $plugin;
34
+
35
+ /**
36
+ * Migrations constructor.
37
+ *
38
+ * @param Wbcr_Factory420_Plugin $plugin
39
+ *
40
+ * @throws Exception
41
+ */
42
+ public function __construct( Wbcr_Factory420_Plugin $plugin ) {
43
+
44
+ $this->plugin = $plugin;
45
+ $plugin_name = $plugin->getPluginName();
46
+
47
+ if ( ! file_exists( $this->plugin->get_paths()->migrations ) ) {
48
+ throw new Exception( 'Starting with version 4.1.1 of the Core for Factory framework module, you must create a "migrations" folder in the root of your plugin to store the migration of the plugin.' );
49
+ }
50
+
51
+ if ( is_admin() ) {
52
+ add_action( "admin_init", [ $this, "check_migrations" ] );
53
+
54
+ add_action( "wbcr/factory/plugin_{$plugin_name}_activated", [ $this, 'activation_hook' ] );
55
+ add_action( "wbcr/factory/admin_notices", [ $this, "debug_bar_notice" ], 10, 2 );
56
+ add_action( "wbcr/factory/admin_notices", [ $this, "migration_error_notice" ], 10, 2 );
57
+ }
58
+ }
59
+
60
+ /**
61
+ * @author Alexander Kovalev <alex.kovalevv@gmail.com>
62
+ * @since 4.1.1
63
+ * @return mixed|void
64
+ */
65
+ public function get_plugin_activated_time() {
66
+ if ( $this->plugin->isNetworkActive() ) {
67
+ return get_site_option( $this->plugin->getOptionName( 'plugin_activated' ), 0 );
68
+ }
69
+
70
+ return get_option( $this->plugin->getOptionName( 'plugin_activated' ), 0 );
71
+ }
72
+
73
+ /**
74
+ * Check if migration is necessary for plugin and if there are errors from previous migrations.
75
+ * In debug mode, migrations are not performed automatically.
76
+ */
77
+ public function check_migrations() {
78
+ if ( $this->is_migration_error() && isset( $_GET['wbcr_factory_fix_migration_error'] ) ) {
79
+ $this->fix_migration_error();
80
+ wp_redirect( remove_query_arg( 'wbcr_factory_fix_migration_error' ) );
81
+ die();
82
+ }
83
+
84
+ if ( $this->is_debug() && isset( $_GET['wbcr_factory_test_migration'] ) ) {
85
+ $this->make_migration();
86
+ wp_redirect( remove_query_arg( 'wbcr_factory_test_migration' ) );
87
+ die();
88
+ }
89
+
90
+ if ( $this->need_migration() && ! $this->is_debug() ) {
91
+ $this->make_migration();
92
+ }
93
+ }
94
+
95
+ /**
96
+ * Notification displays the errors of outstanding migrations to fix errors
97
+ * you need to follow the instructions in the notification and click
98
+ * "I fixed, confirm migration".
99
+ *
100
+ * What is it for. Migrations are performed in background and on some sites,
101
+ * due to php errors or for some other reason, migration may be
102
+ * interrupted, because of what plugin will work incorrectly, you may lose settings.
103
+ *
104
+ * When creating new migrations, developer will add error handlers,
105
+ * and framework will intercept them safely for user and display them
106
+ * in this notice.
107
+ *
108
+ * @param array $notices
109
+ * @param static $plugin_name
110
+ *
111
+ * @return array
112
+ */
113
+ public function migration_error_notice( $notices, $plugin_name ) {
114
+
115
+ if ( $this->plugin->getPluginName() !== $plugin_name ) {
116
+ return $notices;
117
+ }
118
+
119
+ if ( ! $this->is_migration_error() || ! current_user_can( 'update_plugins' ) ) {
120
+ return $notices;
121
+ }
122
+
123
+ if ( $this->plugin->isNetworkActive() ) {
124
+ $migration_error_text = get_site_option( $this->plugin->getOptionName( 'plugin_migration_error' ), '' );
125
+ } else {
126
+ $migration_error_text = get_option( $this->plugin->getOptionName( 'plugin_migration_error' ), '' );
127
+ }
128
+
129
+ $fix_migration_error_url = add_query_arg( 'wbcr_factory_fix_migration_error', 1 );
130
+
131
+ $notice_text = $migration_error_text;
132
+ $notice_text .= "<br><br><a href='{$fix_migration_error_url}' class='button button-default'>" . __( 'I fixed, confirm migration', 'wbcr_factory_420' ) . "</a>";
133
+
134
+ $notices[] = [
135
+ 'id' => 'migration_debug_bar',
136
+ 'type' => 'error',
137
+ 'dismissible' => false,
138
+ 'dismiss_expires' => 0,
139
+ 'text' => '<p><b>' . $this->plugin->getPluginTitle() . ' ' . __( 'migration error', 'wbcr_factory_420' ) . '</b><br>' . $notice_text . '</p>'
140
+ ];
141
+
142
+ return $notices;
143
+ }
144
+
145
+ /**
146
+ * Debug panel, display some information from the database. Also allows
147
+ * perform manual migrations to test new migrations.
148
+ *
149
+ * @param array $notices
150
+ * @param string $plugin_name
151
+ *
152
+ * @return array
153
+ */
154
+ public function debug_bar_notice( $notices, $plugin_name ) {
155
+
156
+ if ( $this->plugin->getPluginName() !== $plugin_name ) {
157
+ return $notices;
158
+ }
159
+ if ( ! $this->is_debug() || ! current_user_can( 'update_plugins' ) ) {
160
+ return $notices;
161
+ }
162
+
163
+ $migrate_url = add_query_arg( 'wbcr_factory_test_migration', 1 );
164
+
165
+ $notice_text = __( "Plugin activated:", "wbcr_factory_420" ) . ' ' . date( "Y-m-d H:i:s", $this->get_plugin_activated_time() ) . "<br>";
166
+
167
+ $notice_text .= __( "Old plugin version (debug):", "wbcr_factory_420" ) . ' ' . $this->get_old_plugin_version() . "<br>";
168
+ $notice_text .= __( "Current plugin version:", "wbcr_factory_420" ) . ' ' . $this->get_current_plugin_version() . "<br>";
169
+ $notice_text .= __( "Need migration:", "wbcr_factory_420" ) . ' ' . ( $this->need_migration() ? "true" : "false" ) . "<br><br>";
170
+ $notice_text .= "<a href='{$migrate_url}' class='button button-default'>" . __( "Migrate now", "wbcr_factory_420" ) . "</a><br>";
171
+
172
+ $notices[] = [
173
+ 'id' => 'migration_debug_bar',
174
+ 'type' => 'warning',
175
+ 'dismissible' => false,
176
+ 'dismiss_expires' => 0,
177
+ 'text' => '<p><b style="color:red;">' . $this->plugin->getPluginTitle() . ' ' . __( 'migrations DEBUG bar', 'wbcr_factory_420' ) . '</b><br>' . $notice_text . '</p>'
178
+ ];
179
+
180
+ return $notices;
181
+ }
182
+
183
+ /**
184
+ * Runs when plugin is activated. Checks if you need to migrate
185
+ * and if necessary it does it. Also adds a option when the plugin
186
+ * was activated for the first time.
187
+ */
188
+ public function activation_hook() {
189
+ /*if ( $this->need_migration() && ! $this->is_debug() ) {
190
+ $this->make_migration();
191
+ }*/
192
+
193
+ // just time to know when the plugin was activated the first time
194
+ $activated = $this->get_plugin_activated_time();
195
+
196
+ if ( ! $activated ) {
197
+ if ( $this->plugin->isNetworkActive() ) {
198
+ update_site_option( $this->plugin->getOptionName( 'plugin_activated' ), time() );
199
+ update_site_option( $this->plugin->getOptionName( 'plugin_version' ), $this->get_current_plugin_version() );
200
+ } else {
201
+ update_option( $this->plugin->getOptionName( 'plugin_activated' ), time() );
202
+ update_option( $this->plugin->getOptionName( 'plugin_version' ), $this->get_current_plugin_version() );
203
+ }
204
+ }
205
+ }
206
+
207
+ /**
208
+ * Checks if debug mode of migrations from version x.x.x to x.x.y is enabled.
209
+ *
210
+ * @return bool
211
+ */
212
+ protected function is_debug() {
213
+ return defined( 'FACTORY_MIGRATIONS_DEBUG' ) && FACTORY_MIGRATIONS_DEBUG;
214
+ }
215
+
216
+ /**
217
+ * Gets previous version of plugin that plugin had before updating to the new version.
218
+ *
219
+ * @return string|null
220
+ */
221
+ protected function get_old_plugin_version() {
222
+
223
+ if ( $this->is_debug() && defined( 'FACTORY_MIGRATIONS_FORCE_OLD_VERSION' ) ) {
224
+ return FACTORY_MIGRATIONS_FORCE_OLD_VERSION;
225
+ }
226
+
227
+ if ( $this->plugin->isNetworkActive() ) {
228
+ $plugin_version = get_site_option( $this->plugin->getOptionName( 'plugin_version' ), null );
229
+ } else {
230
+ $plugin_version = get_option( $this->plugin->getOptionName( 'plugin_version' ), null );
231
+ }
232
+
233
+ if ( ! empty( $plugin_version ) ) {
234
+ return $plugin_version;
235
+ }
236
+
237
+ # TODO: Remove after few releases
238
+ # This block for compatibility code with old version of framework < 4.1.1
239
+ #-------------------------------------------
240
+ if ( $this->plugin->isNetworkActive() ) {
241
+ $plugin_versions = get_site_option( 'factory_plugin_versions', [] );
242
+ } else {
243
+ $plugin_versions = get_option( 'factory_plugin_versions', [] );
244
+ }
245
+
246
+ $plugin_version = isset( $plugin_versions[ $this->plugin->getPluginName() ] ) ? $plugin_versions[ $this->plugin->getPluginName() ] : null;
247
+
248
+ if ( ! empty( $plugin_version ) ) {
249
+ $plugin_version = str_replace( [ 'free-', 'premium-', 'offline-' ], '', $plugin_version );
250
+ }
251
+
252
+ #-------------------------------------------
253
+
254
+ return $plugin_version;
255
+ }
256
+
257
+ /**
258
+ * Gets the current version of plugin.
259
+ *
260
+ * @return string
261
+ */
262
+ protected function get_current_plugin_version() {
263
+ return $this->plugin->getPluginVersion();
264
+ }
265
+
266
+ /**
267
+ * Do I need migration for plugin? If previous migration was with a error, then
268
+ * method will always return false to prevent looping.
269
+ *
270
+ * @return mixed
271
+ */
272
+ protected function need_migration() {
273
+ if ( $this->is_migration_error() ) {
274
+ return false;
275
+ }
276
+
277
+ return version_compare( $this->get_old_plugin_version(), $this->get_current_plugin_version(), '<' );
278
+ }
279
+
280
+ /**
281
+ * Are there errors from previous migrations?
282
+ *
283
+ * @return bool
284
+ */
285
+ protected function is_migration_error() {
286
+ if ( $this->plugin->isNetworkActive() ) {
287
+ $error = get_site_option( $this->plugin->getOptionName( 'plugin_migration_error' ), false );
288
+ } else {
289
+ $error = get_option( $this->plugin->getOptionName( 'plugin_migration_error' ), false );
290
+ }
291
+
292
+ return $error !== false;
293
+ }
294
+
295
+ /**
296
+ * Remove an option in database, thereby fix errors of the previous migration.
297
+ */
298
+ protected function fix_migration_error() {
299
+ if ( $this->plugin->isNetworkActive() ) {
300
+ delete_site_option( $this->plugin->getOptionName( 'plugin_migration_error' ) );
301
+
302
+ return;
303
+ }
304
+
305
+ delete_option( $this->plugin->getOptionName( 'plugin_migration_error' ) );
306
+ }
307
+
308
+ /**
309
+ * Migrates the plugin from version x.x.x to x.x.y. Automatically searches for files
310
+ * migrations to the plugin's root directory and executes them. Default files
311
+ * migrations are stored in wp-content/plugins/plugin-name/migrations and have names
312
+ * 0x0x0x.php, which corresponds to the version x.x.x. Method executes those migration files
313
+ * versions of which are between the previous version of plugin and current one.
314
+ *
315
+ */
316
+ protected function make_migration() {
317
+
318
+ if ( ! current_user_can( 'update_plugins' ) ) {
319
+ return;
320
+ }
321
+
322
+ $old_plugin_version = $this->get_old_plugin_version();
323
+ $new_plugin_version = $this->get_current_plugin_version();
324
+
325
+ if ( empty( $old_plugin_version ) ) {
326
+ $this->update_plugin_version_in_db();
327
+ }
328
+
329
+ // converts versions like 0.0.0 to 000000
330
+ $old_number = $this->get_version_number( $old_plugin_version );
331
+ $new_number = $this->get_version_number( $new_plugin_version );
332
+
333
+ try {
334
+
335
+ $update_files = $this->plugin->get_paths()->migrations;
336
+ $files = $this->find_files( $update_files );
337
+
338
+ if ( empty( $files ) ) {
339
+ $this->update_plugin_version_in_db();
340
+
341
+ return;
342
+ }
343
+
344
+ // finds updates that has intermediate version
345
+ foreach ( (array) $files as $item ) {
346
+ if ( ! preg_match( '/^\d+$/', $item['name'] ) ) {
347
+ continue;
348
+ }
349
+
350
+ $item_number = intval( $item['name'] );
351
+
352
+ if ( $item_number > $old_number && $item_number <= $new_number ) {
353
+ $classes = $this->get_classes( $item['path'] );
354
+
355
+ if ( count( $classes ) == 0 ) {
356
+ continue;
357
+ }
358
+
359
+ foreach ( $classes as $path => $class_data ) {
360
+ include_once( $path );
361
+ $update_class = $class_data['name'];
362
+
363
+ $update = new $update_class( $this->plugin );
364
+ $update->install();
365
+ }
366
+ }
367
+ }
368
+
369
+ $this->update_plugin_version_in_db();
370
+ } catch( Exception $e ) {
371
+ if ( $this->plugin->isNetworkActive() ) {
372
+ update_site_option( $this->plugin->getOptionName( 'plugin_migration_error' ), $e->getMessage() );
373
+
374
+ return;
375
+ }
376
+ update_option( $this->plugin->getOptionName( 'plugin_migration_error' ), $e->getMessage() );
377
+ }
378
+ }
379
+
380
+ /**
381
+ * Updates version of plugin in database. So that we can track which
382
+ * previous version of plugin was at the user, before he updated
383
+ * plugin.
384
+ */
385
+ protected function update_plugin_version_in_db() {
386
+
387
+ # TODO: Delete after few releases
388
+ # This block for compatibility code with the old version of framework.
389
+ # Cleans up old data, after the transition to new version of framework.
390
+ #-------------------------------------------
391
+ if ( $this->plugin->isNetworkActive() ) {
392
+ $plugin_versions = get_site_option( 'factory_plugin_versions', [] );
393
+ } else {
394
+ $plugin_versions = get_option( 'factory_plugin_versions', [] );
395
+ }
396
+
397
+ if ( isset( $plugin_versions[ $this->plugin->getPluginName() ] ) ) {
398
+ unset( $plugin_versions[ $this->plugin->getPluginName() ] );
399
+ }
400
+
401
+ if ( $this->plugin->isNetworkActive() ) {
402
+ if ( empty( $plugin_versions ) ) {
403
+ delete_site_option( 'factory_plugin_versions' );
404
+ }
405
+ update_site_option( 'factory_plugin_versions', $plugin_versions );
406
+ update_site_option( $this->plugin->getOptionName( 'plugin_version' ), $this->get_current_plugin_version() );
407
+
408
+ return;
409
+ }
410
+
411
+ if ( empty( $plugin_versions ) ) {
412
+ delete_option( 'factory_plugin_versions' );
413
+ }
414
+
415
+ update_option( 'factory_plugin_versions', $plugin_versions );
416
+ update_option( $this->plugin->getOptionName( 'plugin_version' ), $this->get_current_plugin_version() );
417
+ }
418
+
419
+ /**
420
+ * Converts string representation of the version to the numeric.
421
+ *
422
+ * @since 1.0.0
423
+ *
424
+ * @param string $version A string version to convert.
425
+ *
426
+ * @return integer
427
+ */
428
+ protected function get_version_number( $version ) {
429
+ preg_match( '/(\d+)\.(\d+)\.(\d+)/', $version, $matches );
430
+ if ( count( $matches ) == 0 ) {
431
+ return false;
432
+ }
433
+
434
+ $number = '';
435
+ $number .= ( strlen( $matches[1] ) == 1 ) ? '0' . $matches[1] : $matches[1];
436
+ $number .= ( strlen( $matches[2] ) == 1 ) ? '0' . $matches[2] : $matches[2];
437
+ $number .= ( strlen( $matches[3] ) == 1 ) ? '0' . $matches[3] : $matches[3];
438
+
439
+ return intval( $number );
440
+ }
441
+
442
+ /**
443
+ * Returns a list of files at a given path.
444
+ *
445
+ * @param string $path path for search
446
+ */
447
+ private function find_files( $path ) {
448
+ return $this->find_file_or_folders( $path, true );
449
+ }
450
+
451
+ /**
452
+ * Returns a list of folders at a given path.
453
+ *
454
+ * @param string $path path for search
455
+ */
456
+ /*private function find_folders( $path ) {
457
+ return $this->find_file_or_folders( $path, false );
458
+ }*/
459
+
460
+ /**
461
+ * Returns a list of files or folders at a given path.
462
+ *
463
+ * @param string $path path for search
464
+ * @param bool $files files or folders?
465
+ */
466
+ private function find_file_or_folders( $path, $areFiles = true ) {
467
+ if ( ! is_dir( $path ) ) {
468
+ return [];
469
+ }
470
+
471
+ $entries = scandir( $path );
472
+ if ( empty( $entries ) ) {
473
+ return [];
474
+ }
475
+
476
+ $files = [];
477
+ foreach ( $entries as $entryName ) {
478
+ if ( $entryName == '.' || $entryName == '..' ) {
479
+ continue;
480
+ }
481
+
482
+ $filename = $path . '/' . $entryName;
483
+ if ( ( $areFiles && is_file( $filename ) ) || ( ! $areFiles && is_dir( $filename ) ) ) {
484
+ $files[] = [
485
+ 'path' => str_replace( "\\", "/", $filename ),
486
+ 'name' => $areFiles ? str_replace( '.php', '', $entryName ) : $entryName
487
+ ];
488
+ }
489
+ }
490
+
491
+ return $files;
492
+ }
493
+
494
+ /**
495
+ * Gets php classes defined in a specified file.
496
+ *
497
+ * @param string $path
498
+ *
499
+ * @throws Exception
500
+ */
501
+ private function get_classes( $path ) {
502
+
503
+ $phpCode = file_get_contents( $path );
504
+
505
+ $classes = [];
506
+
507
+ if ( ! function_exists( 'token_get_all' ) ) {
508
+ throw new Exception( __( 'There is no PHP Tokenizer extension installed on your server, you cannot use the token_get_all function.', 'wbcr_factory_420' ) );
509
+ }
510
+
511
+ $tokens = token_get_all( $phpCode );
512
+
513
+ $count = count( $tokens );
514
+ for ( $i = 2; $i < $count; $i ++ ) {
515
+ if ( is_array( $tokens ) && $tokens[ $i - 2 ][0] == T_CLASS && $tokens[ $i - 1 ][0] == T_WHITESPACE && $tokens[ $i ][0] == T_STRING ) {
516
+
517
+ $extends = null;
518
+ if ( $tokens[ $i + 2 ][0] == T_EXTENDS && $tokens[ $i + 4 ][0] == T_STRING ) {
519
+ $extends = $tokens[ $i + 4 ][1];
520
+ }
521
+
522
+ $class_name = $tokens[ $i ][1];
523
+ $classes[ $path ] = [
524
+ 'name' => $class_name,
525
+ 'extends' => $extends
526
+ ];
527
+ }
528
+ }
529
+
530
+ /**
531
+ * result example:
532
+ *
533
+ * $classes['/plugin/items/filename.php'] = array(
534
+ * 'name' => 'PluginNameItem',
535
+ * 'extendes' => 'PluginNameItemBase'
536
+ * )
537
+ */
538
+
539
+ return $classes;
540
+ }
541
+ }
libs/factory/core/includes/class-factory-notices.php ADDED
@@ -0,0 +1,291 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace WBCR\Factory_420;
4
+
5
+ use Wbcr_Factory420_Plugin;
6
+
7
+ // Exit if accessed directly
8
+ if ( ! defined( 'ABSPATH' ) ) {
9
+ exit;
10
+ }
11
+
12
+ /**
13
+ * A class to manage notices.
14
+ *
15
+ * @since 1.0.0
16
+ */
17
+
18
+ /**
19
+ * A group of classes and methods to create and manage notices.
20
+ *
21
+ * @author Alex Kovalev <alex.kovalevv@gmail.com>, repo: https://github.com/alexkovalevv
22
+ * @author Webcraftic <wordpress.webraftic@gmail.com>, site: https://webcraftic.com
23
+ *
24
+ * @package factory-notices
25
+ * @since 1.0.0
26
+ */
27
+ class Notices {
28
+
29
+ /**
30
+ * @var Wbcr_Factory420_Plugin
31
+ */
32
+ protected $plugin;
33
+ /**
34
+ * @var array
35
+ */
36
+ protected $notices = [];
37
+
38
+ /**
39
+ * @var array
40
+ */
41
+ protected $default_where = [
42
+ 'plugins',
43
+ 'themes',
44
+ 'dashboard',
45
+ 'edit',
46
+ 'settings',
47
+ 'dashboard-network',
48
+ 'plugins-network',
49
+ 'themes-network',
50
+ 'settings-network',
51
+ ];
52
+
53
+ /**
54
+ * @var array
55
+ */
56
+ private $dissmised_notices;
57
+
58
+ /**
59
+ * Инициализируем уведомлений сразу после загрузки модуля уведомлений
60
+ *
61
+ * @param Wbcr_Factory420_Plugin $plugin
62
+ */
63
+ public function __construct( $plugin ) {
64
+ //default notices
65
+ //---
66
+
67
+ $this->plugin = $plugin;
68
+ $this->dissmised_notices = $this->plugin->getPopulateOption( 'factory_dismissed_notices', [] );
69
+
70
+ add_action( 'current_screen', [ $this, 'currentScreenAction' ] );
71
+
72
+ if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) {
73
+ add_action( 'wp_ajax_' . $this->plugin->getPluginName() . '_dismiss_notice', [
74
+ $this,
75
+ 'dismiss_notice'
76
+ ] );
77
+ }
78
+ }
79
+
80
+ /**
81
+ * Регистрирует экшены для работы с уведомлениями на текущем экране странице.
82
+ * Уведомления собираются через фильтр wbcr_factory_admin_notices, если в массиве уведомлений,
83
+ * хотя бы одно, соответствует условиям в параметре $notice['where'], то метод печает вспомогательные скрипты и уведомления.
84
+ */
85
+ public function currentScreenAction() {
86
+ /**
87
+ * @since 2.1.2 - является устаревшим
88
+ */
89
+ $this->notices = wbcr_factory_420_apply_filters_deprecated( 'wbcr_factory_notices_000_list', [
90
+ $this->notices,
91
+ $this->plugin->getPluginName(),
92
+ ], '2.1.2', 'wbcr/factory/admin_notices' );
93
+
94
+ /**
95
+ * @since 2.1.2 - Добавлен, модуль factory_notices_000 был удален. Поэтому в этому хуке мы заменили префикс на factory_420
96
+ */
97
+ $this->notices = apply_filters( 'wbcr/factory/admin_notices', $this->notices, $this->plugin->getPluginName() );
98
+
99
+ if ( count( $this->notices ) == 0 ) {
100
+ return;
101
+ }
102
+
103
+ $screen = get_current_screen();
104
+
105
+ $has_notices = false;
106
+ foreach ( (array) $this->notices as $notice ) {
107
+ if ( ! isset( $notice['id'] ) ) {
108
+ continue;
109
+ }
110
+
111
+ $where = ! isset( $notice['where'] ) || empty( $notice['where'] ) ? $this->default_where : $notice['where'];
112
+
113
+ if ( in_array( $screen->base, $where ) && ! $this->is_dissmissed( $notice['id'] ) ) {
114
+ $has_notices = true;
115
+ break;
116
+ };
117
+ }
118
+
119
+ if ( $has_notices ) {
120
+ add_action( 'admin_footer', [ $this, 'print_js_code' ] );
121
+
122
+ if ( $this->plugin->isNetworkActive() ) {
123
+ if ( current_user_can( 'manage_network' ) ) {
124
+ add_action( 'network_admin_notices', [ $this, 'show_notices' ] );
125
+ add_action( 'admin_notices', [ $this, 'show_notices' ] );
126
+ }
127
+ } else {
128
+ add_action( 'admin_notices', [ $this, 'show_notices' ] );
129
+ }
130
+ }
131
+ }
132
+
133
+ /**
134
+ * Показывает все зарегистрированные уведомления для текущего плагина.
135
+ * Уведомления показываются только на определенных страницах через параметр $notice['where'],
136
+ * если уведомление ранее было скрыто или не соотвествует правилам $notice['where'], оно не будет показано!
137
+ */
138
+ public function show_notices() {
139
+ if ( count( $this->notices ) == 0 ) {
140
+ return;
141
+ }
142
+
143
+ if ( ! current_user_can( 'activate_plugins' ) || ! current_user_can( 'edit_plugins' ) || ! current_user_can( 'install_plugins' ) ) {
144
+ return;
145
+ }
146
+
147
+ $screen = get_current_screen();
148
+
149
+ foreach ( $this->notices as $notice ) {
150
+
151
+ if ( ! isset( $notice['id'] ) ) {
152
+ continue;
153
+ }
154
+
155
+ $where = ! isset( $notice['where'] ) || empty( $notice['where'] ) ? $this->default_where : $notice['where'];
156
+
157
+ if ( in_array( $screen->base, $where ) && ! $this->is_dissmissed( $notice['id'] ) ) {
158
+ $this->show_notice( $notice );
159
+ };
160
+ }
161
+ }
162
+
163
+ /**
164
+ * Показывает уведомление, по переданным параметрам
165
+ *
166
+ * @param array $data - Параметры уведомления
167
+ * $data['id'] - Индентификатор уведомления
168
+ * $data['type'] - Тип уведомления (error, warning, success)
169
+ * $notice['where'] - На каких страницах показывать уведомление ('plugins', 'dashboard', 'edit')
170
+ * $data['text'] - Текст уведомления
171
+ * $data['dismissible'] - Если true, уведомление будет с кнопкой закрыть
172
+ * $data['dismiss_expires'] - Когда снова показать уведомление, нужно указывать время в unix timestamp.
173
+ * Пример time() + 3600 (1ч), уведомление будет скрыто на 1 час.
174
+ * $data['classes'] - Произвольный классы для контейнера уведомления.
175
+ */
176
+ public function show_notice( $data ) {
177
+ $settings = wp_parse_args( $data, [
178
+ 'id' => null,
179
+ 'text' => null,
180
+ 'type' => 'error',
181
+ 'dismissible' => false,
182
+ 'dismiss_expires' => 0,
183
+ 'classes' => []
184
+ ] );
185
+
186
+ if ( empty( $settings['id'] ) || empty( $settings['text'] ) ) {
187
+ return;
188
+ }
189
+
190
+ $plugin_name = str_replace( '_', '-', $this->plugin->getPluginName() );
191
+
192
+ $classes = array_merge( [
193
+ 'notice',
194
+ 'notice-' . $settings['type'],
195
+ $plugin_name . '-factory-notice'
196
+ ], $settings['classes'] );
197
+
198
+ if ( $settings['dismissible'] ) {
199
+ $classes[] = 'is-dismissible';
200
+ $classes[] = $plugin_name . '-factory-notice-dismiss';
201
+ }
202
+ ?>
203
+ <div data-name="wbcr_factory_notice_<?php echo esc_attr( $data['id'] ) ?>" data-expires="<?= esc_attr( $settings['dismiss_expires'] ) ?>" data-nonce="<?php echo wp_create_nonce( $this->plugin->getPluginName() . '_factory_dismiss_notice' ); ?>" class="<?php echo esc_attr( implode( ' ', $classes ) ) ?>">
204
+ <?= $data['text'] ?>
205
+ </div>
206
+ <?php
207
+ }
208
+
209
+ /**
210
+ * Когда пользователь нажимает кнопку закрыть уведомление,
211
+ * отправляется ajax запрос с вызовом текущего метода
212
+ */
213
+ public function dismiss_notice() {
214
+ if ( ! current_user_can( 'activate_plugins' ) || ! current_user_can( 'edit_plugins' ) || ! current_user_can( 'install_plugins' ) ) {
215
+ wp_die( - 1, 403 );
216
+ }
217
+
218
+ check_admin_referer( $this->plugin->getPluginName() . '_factory_dismiss_notice', 'nonce' );
219
+
220
+ // Имя уведомления (идентификатор)
221
+ $name = $this->plugin->request->post( 'name', null, true );
222
+
223
+ // Время в Unix timestamp, по истечению, которого уведомление снова будет показано
224
+ // Если передан 0, то уведомление будет скрыто навсегда
225
+ $expires = $this->plugin->request->post( 'expires', 0, 'intval' );
226
+
227
+ if ( empty( $name ) ) {
228
+ wp_send_json_error( [ 'error_message' => 'You must pass the notification "Name"! Action was rejected.' ] );
229
+ }
230
+
231
+ $notices = $this->plugin->getPopulateOption( "factory_dismissed_notices", [] );
232
+
233
+ if ( ! empty( $notices ) ) {
234
+ foreach ( (array) $notices as $notice_id => $notice_expires ) {
235
+ if ( $notice_expires !== 0 && $notice_expires < time() ) {
236
+ unset( $notices[ $notice_id ] );
237
+ }
238
+ }
239
+ }
240
+
241
+ $notices[ $name ] = $expires;
242
+
243
+ $this->plugin->updatePopulateOption( 'factory_dismissed_notices', $notices );
244
+
245
+ wp_send_json_success();
246
+ }
247
+
248
+ /**
249
+ * Javascript code
250
+ * Печает в подвале страницы код, для взаимодействия с сервером через ajax,
251
+ * код используется при нажатии на кнопку закрыть уведомление. *
252
+ */
253
+ public function print_js_code() {
254
+ $plugin_name = str_replace( '_', '-', $this->plugin->getPluginName() );
255
+
256
+ ?>
257
+ <script type="text/javascript">
258
+ jQuery(function($) {
259
+
260
+ $(document).on('click', '.<?php echo $plugin_name; ?>-factory-notice-dismiss .notice-dismiss', function() {
261
+ $.post(ajaxurl, {
262
+ 'action': '<?php echo $this->plugin->getPluginName(); ?>_dismiss_notice',
263
+ 'name': $(this).parent().data('name'),
264
+ 'expires': $(this).parent().data('expires'),
265
+ 'nonce': $(this).parent().attr('data-nonce')
266
+ });
267
+ });
268
+
269
+ });
270
+ </script>
271
+ <?php
272
+ }
273
+
274
+
275
+ /**
276
+ * Проверяет скрыто уведоление или нет
277
+ *
278
+ * @param string $notice_id - имя уведомления
279
+ *
280
+ * @return bool
281
+ */
282
+ protected function is_dissmissed( $notice_id ) {
283
+ if ( ! empty( $this->dissmised_notices ) && isset( $this->dissmised_notices[ 'wbcr_factory_notice_' . $notice_id ] ) ) {
284
+ $expires = (int) $this->dissmised_notices[ 'wbcr_factory_notice_' . $notice_id ];
285
+
286
+ return $expires === 0 || $expires > time();
287
+ }
288
+
289
+ return false;
290
+ }
291
+ }
libs/factory/core/includes/class-factory-options.php ADDED
@@ -0,0 +1,432 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace WBCR\Factory_420;
4
+
5
+ // Exit if accessed directly
6
+ use Exception;
7
+
8
+ if ( ! defined( 'ABSPATH' ) ) {
9
+ exit;
10
+ }
11
+
12
+ /**
13
+ * Трейт используется для расширения базового класса плагина Wbcr_Factory420_Base, позволяя работать с опциями плагина.
14
+ *
15
+ * Этот трейт является оберткой для Wordpress функций get_option, get_site_option, update_option, update_site_option,
16
+ * delete_option, delete_site_option. Основная задача была получать, обновлять, удалять опции без использования префиксов,
17
+ * чтобы класс выполнял эту работу за программиста. В дополнение, трейт содержит методы для полной выгрузки всех опций
18
+ * плагина, что позволяет при инициализации плагина автоматически выгрузить все существующие опции плагина в объектный
19
+ * кеш. Все опции, с которыми работает плагин, могут быть отфильтрованы.
20
+ *
21
+ * Документация по трейту: https://webcraftic.atlassian.net/wiki/spaces/FFD/pages/393805831/
22
+ * Документация по созданию плагина: https://webcraftic.atlassian.net/wiki/spaces/CNCFC/pages/327828
23
+ * Репозиторий: https://github.com/alexkovalevv
24
+ *
25
+ * @author Alex Kovalev <alex.kovalevv@gmail.com>, repo: https://github.com/alexkovalevv
26
+ * @author Webcraftic <wordpress.webraftic@gmail.com>, site: https://webcraftic.com
27
+ *
28
+ * @since 4.0.8 - Добавлен
29
+ * @package factory-core
30
+ */
31
+ trait Options {
32
+
33
+ /**
34
+ * Абстрактный метод, должен быть реализован в классе использующем этот трейт. Метод позволяет получить префикс
35
+ * плагина для формирования имен опций в базе данных Wordpress. У опций должно быть свое пространство имен,
36
+ * иначе может быть конфликт с другими плагинами или с сами ядром Wordpress.
37
+ *
38
+ * @since 4.0.8 - Добавлен
39
+ * @return string Возвращает префикс плагина. Пример: wbcr_clearfy_
40
+ */
41
+ abstract public function getPrefix();
42
+
43
+ /**
44
+ * Выгружает все опции плагина в объектный кеш. Плагин может получить любую свою опцию без запроса к базе данных.
45
+ * Метод ускоряет работу плагина, если опций очень много.
46
+ *
47
+ * Используется только один раз при инициализации плагина.
48
+ *
49
+ * @since 4.0.8 - Добавлен
50
+ */
51
+ public function loadAllOptions() {
52
+ global $wpdb;
53
+
54
+ $is_option_loaded = wp_cache_get( $this->getPrefix() . 'all_options_loaded', $this->getPrefix() . 'options' );
55
+
56
+ if ( false === $is_option_loaded ) {
57
+ $result = $wpdb->get_results( "SELECT option_name, option_value FROM {$wpdb->options} WHERE option_name LIKE '{$this->getPrefix()}%'" );
58
+
59
+ $options = [];
60
+
61
+ if ( ! empty( $result ) ) {
62
+ wp_cache_add( $this->getPrefix() . 'all_options_loaded', 1, $this->getPrefix() . 'options' );
63
+
64
+ foreach ( $result as $option ) {
65
+ $value = maybe_unserialize( $option->option_value );
66
+ $value = $this->normalizeValue( $value );
67
+
68
+ wp_cache_add( $option->option_name, $value, $this->getPrefix() . 'options' );
69
+ $options[ $option->option_name ] = $value;
70
+ }
71
+
72
+ /**
73
+ * Действие, которое будет выполнено, когда все опции плагина будут выгружены.
74
+ *
75
+ * @since 4.0.9 - Добавлен
76
+ *
77
+ * @param string $plugin_name Имя плагина
78
+ * @param array $options Ассоциативный массив опций плагина
79
+ */
80
+ do_action( 'wbcr/factory/all_options_loaded', $options, $this->plugin_name );
81
+ }
82
+ }
83
+ }
84
+
85
+ /**
86
+ * Выгружает все сетевые опции плагина в объектный кеш. Плагин может получить любую свою опцию без запроса к базе
87
+ * данных. Метод ускоряет работу плагина, если опций очень много.
88
+ *
89
+ * Используется и работает только в режиме мультисайтов, один раз при инициализации плагина.!
90
+ *
91
+ * @since 4.0.8 - Добавлен
92
+ * @return void
93
+ */
94
+ public function loadAllNetworkOptions() {
95
+ global $wpdb;
96
+
97
+ $network_id = (int) get_current_network_id();
98
+
99
+ $is_option_loaded = wp_cache_get( $network_id . ":" . $this->getPrefix() . 'all_options_loaded', $this->getPrefix() . 'network_options' );
100
+
101
+ if ( false === $is_option_loaded ) {
102
+ wp_cache_add_global_groups( [ $this->getPrefix() . 'network_options' ] );
103
+
104
+ $result = $wpdb->get_results( "SELECT meta_key, meta_value FROM {$wpdb->sitemeta} WHERE site_id='{$network_id}' AND meta_key LIKE '{$this->getPrefix()}%'" );
105
+
106
+ $options = [];
107
+ if ( ! empty( $result ) ) {
108
+ wp_cache_add( $network_id . ":" . $this->getPrefix() . 'all_options_loaded', 1, $this->getPrefix() . 'network_options' );
109
+
110
+ foreach ( $result as $option ) {
111
+ $value = maybe_unserialize( $option->meta_value );
112
+ $value = $this->normalizeValue( $value );
113
+
114
+ $cache_key = $network_id . ":" . $option->meta_key;
115
+ wp_cache_add( $cache_key, $value, $this->getPrefix() . 'network_options' );
116
+ $options[ $option->meta_key ] = $value;
117
+ }
118
+
119
+ /**
120
+ *
121
+ * Действие, которое будет выполнено, когда все сетевые опции плагина будут выгружены.
122
+ *
123
+ * @since 4.0.9 - Добавлен
124
+ *
125
+ * @param array $options Ассоциативный массив опций плагина
126
+ * @param string $plugin_name Имя плагина
127
+ */
128
+ do_action( 'wbcr/factory/all_network_options_loaded', $options, $this->plugin_name );
129
+ }
130
+ }
131
+ }
132
+
133
+ /**
134
+ * Позволяет получить популярную опцию. В случае если плагин установлен для сети (в режиме мультисайтов),
135
+ * то метод возвращает опции только для сети, иначе метод возвращает опцию для текущего сайта. Работает
136
+ * на основе self::getOption и self::getNetworkOption, смотрите полную реализацию в этих методах.
137
+ *
138
+ * @since 4.0.8 - Добавлен
139
+ *
140
+ * @param string $option_name Имя опции без префикса.
141
+ * @param mixed $default Значение по умолчанию. Если опции нет в базе данных, будет возвращено это значение. По умолчанию false
142
+ *
143
+ * @return mixed Возвращает значение опции, если это сериализованная строка, то автоматически распаковывает ее.
144
+ */
145
+ public function getPopulateOption( $option_name, $default = false ) {
146
+ if ( $this->isNetworkActive() ) {
147
+ $option_value = $this->getNetworkOption( $option_name, $default );
148
+ } else {
149
+ $option_value = $this->getOption( $option_name, $default );
150
+ }
151
+
152
+ /**
153
+ * Фильтр позволяет отфильтровать возвращаемое значение популярной опции.
154
+ *
155
+ * @since 4.0.9 - Добавлен
156
+ *
157
+ * @param mixed $option_value Значение опции
158
+ * @param string $option_name Имя опции
159
+ * @param mixed $default Значение опции по умолчанию
160
+ */
161
+ return apply_filters( "wbcr/factory/populate_option_{$option_name}", $option_value, $option_name, $default );
162
+ }
163
+
164
+ /**
165
+ * Позволяет получить сетевые опции. Если плагин установлен для сети (в режиме мультисайтов), то
166
+ * метод возвращает опции только для сети, иначе метод возвращает опцию для текущего сайта.
167
+ *
168
+ * Опция вытаскивается из объектного кеша, после выполнения метода self:loadAllNetworkOptions,
169
+ * а не напрямую из базы данных, из-за чего при работе с некоторыми кеширующими плагинами,
170
+ * может быть странное поведение в работе плагина.
171
+ *
172
+ * @since 4.0.8 - Добавлен
173
+ *
174
+ * @param string $option_name Имя опции без префикса.
175
+ * @param mixed $default Значение по умолчанию. Если опции нет в базе данных, будет возвращено это значение. По умолчанию false
176
+ *
177
+ * @return mixed Возвращает значение опции, если это сериализованная строка, то автоматически распаковывает ее.
178
+ */
179
+ public function getNetworkOption( $option_name, $default = false ) {
180
+ if ( empty( $option_name ) || ! is_string( $option_name ) ) {
181
+ throw new Exception( 'Option name must be a string and must not be empty.' );
182
+ }
183
+
184
+ if ( ! is_multisite() ) {
185
+ return $this->getOption( $option_name, $default );
186
+ }
187
+
188
+ $this->loadAllNetworkOptions();
189
+
190
+ $network_id = (int) get_current_network_id();
191
+ $cache_key = $network_id . ':' . $this->getPrefix() . $option_name;
192
+ $option_value = wp_cache_get( $cache_key, $this->getPrefix() . 'network_options' );
193
+
194
+ if ( false === $option_value ) {
195
+ $option_value = $default;
196
+ }
197
+
198
+ /**
199
+ * Фильтр позволяет отфильтровать возвращаемое значение сетевой опции.
200
+ *
201
+ * @since 4.0.9 - Добавлен
202
+ *
203
+ * @param mixed $option_value Значение опции
204
+ * @param string $option_name Имя опции
205
+ * @param mixed $default Значение опции по умолчанию
206
+ * @param int $network_id ID сети
207
+ */
208
+
209
+ return apply_filters( "wbcr/factory/network_option_{$option_name}", $option_value, $option_name, $default, $network_id );
210
+ }
211
+
212
+ /**
213
+ * Метод позволяет получить опцию для текущего сайта. Опция вытаскивается из объектного кеша, после выполнения метода
214
+ * self:loadAllOptions, а не напрямую из базы данных, из-за чего при работе с некоторыми кеширующими плагинами,
215
+ * может быть странное поведение в работе плагина.
216
+ *
217
+ * @since 4.0.0 - Добавлен
218
+ * @since 4.0.8 - Полностью переделан
219
+ *
220
+ * @param string $option_name Имя опции без префикса.
221
+ * @param mixed $default Значение по умолчанию. Если опции нет в базе данных, будет возвращено это значение. По умолчанию false
222
+ *
223
+ * @return mixed
224
+ */
225
+ public function getOption( $option_name, $default = false ) {
226
+ if ( empty( $option_name ) || ! is_string( $option_name ) ) {
227
+ throw new Exception( 'Option name must be a string and must not be empty.' );
228
+ }
229
+
230
+ $this->loadAllOptions();
231
+
232
+ $option_value = wp_cache_get( $this->getPrefix() . $option_name, $this->getPrefix() . 'options' );
233
+
234
+ if ( false === $option_value ) {
235
+ $option_value = $default;
236
+ }
237
+
238
+ /**
239
+ * Фильтр позволяет отфильтровать возвращаемое значение опции сайта.
240
+ *
241
+ * @since 4.0.9 - Добавлен
242
+ *
243
+ * @param mixed $option_value Значение опции
244
+ * @param string $option_name Имя опции
245
+ * @param mixed $default Значение опции по умолчанию
246
+ */
247
+
248
+ return apply_filters( "wbcr/factory/option_{$option_name}", $option_value, $option_name, $default );
249
+ }
250
+
251
+ /**
252
+ * Позволяет обновить популярную опцию в базе данных. Если плагин установлен для сети (в режиме мультисайтов), то метод обновляет опцию
253
+ * только в таблице sitemeta, иначе в таблице options для текущего сайта.
254
+ *
255
+ * @param string $option_name Имя опции без префикса.
256
+ * @param mixed $option_value Значение опции. Может принимать массив или объект.
257
+ */
258
+ public function updatePopulateOption( $option_name, $option_value ) {
259
+ if ( $this->isNetworkActive() ) {
260
+ $this->updateNetworkOption( $option_name, $option_value );
261
+ } else {
262
+ $this->updateOption( $option_name, $option_value );
263
+ }
264
+ }
265
+
266
+ /**
267
+ * Обновляет сетевую опцию в БД таблица sitemeta. После успешного обновления опции в базе данных, метод добавляет опцию в объектный кеш,
268
+ * чтобы плагин мог приступить к работе с этой опцией незамедлительно.
269
+ *
270
+ * @since 4.0.8 - Добавлен
271
+ *
272
+ * @param string $option_name Имя опции без префикса.
273
+ * @param mixed $option_value Значение опции. Может принимать массив или объект.
274
+ */
275
+ public function updateNetworkOption( $option_name, $option_value ) {
276
+ $network_id = (int) get_current_network_id();
277
+ $cache_key = $network_id . ':' . $this->getPrefix() . $option_name;
278
+ wp_cache_set( $cache_key, $option_value, $this->getPrefix() . 'network_options' );
279
+
280
+ update_site_option( $this->getPrefix() . $option_name, $option_value );
281
+
282
+ /**
283
+ * Действие будет выполнено, когда сетевая опция будет обновлена.
284
+ *
285
+ * @since 4.0.8 - Добавлен
286
+ *
287
+ * @param string $option_name Имя опции без префикса.
288
+ * @param mixed $option_value Значение опции. Может принимать массив или объект.
289
+ */
290
+ do_action( "wbcr/factory/update_network_option", $option_name, $option_value );
291
+ }
292
+
293
+ /**
294
+ * Обновляет опцию сайта в БД таблица options. После успешного обновления опции в базе данных, метод добавляет опцию в объектный кеш,
295
+ * чтобы плагин мог приступить к работе с этой опцией незамедлительно.
296
+ *
297
+ * @since 4.0.0 - Добавлен
298
+ * @since 4.0.8 - Полностью переделан
299
+ *
300
+ * @param string $option_name Имя опции без префикса.
301
+ * @param mixed $option_value Значение опции. Может принимать массив или объект.
302
+ *
303
+ * @return bool
304
+ */
305
+ public function updateOption( $option_name, $option_value ) {
306
+ wp_cache_set( $this->getPrefix() . $option_name, $option_value, $this->getPrefix() . 'options' );
307
+ $result = update_option( $this->getPrefix() . $option_name, $option_value );
308
+
309
+ /**
310
+ * @since 4.0.8
311
+ *
312
+ * @param string $option_name
313
+ *
314
+ * @param mixed $option_value
315
+ */
316
+ do_action( "wbcr/factory/update_option", $option_name, $option_value );
317
+
318
+ return $result;
319
+ }
320
+
321
+ /**
322
+ * Позволяет удалять популярную опцию в базе данных. Если плагин установлен для сети (в режиме мультисайтов), то метод удаляет опцию
323
+ * только в таблице sitemeta, иначе в таблице options для текущего сайта.
324
+ *
325
+ * @since 4.0.0 - Добавлен
326
+ *
327
+ * @param string $option_name Имя опции без префикса.
328
+ */
329
+ public function deletePopulateOption( $option_name ) {
330
+ if ( $this->isNetworkActive() ) {
331
+ $this->deleteNetworkOption( $option_name );
332
+ } else {
333
+ $this->deleteOption( $option_name );
334
+ }
335
+ }
336
+
337
+ /**
338
+ * Удаляет сетевую.опцию в БД таблица sitemeta, а если опция есть в кеше, индивидуально удаляет опцию из кеша.
339
+ *
340
+ * @since 4.0.0 - Добавлен
341
+ *
342
+ * @param string $option_name Имя опции без префикса.
343
+ *
344
+ * @return bool Возвращает true, если опция удалена успешно, false в случае ошибки.
345
+ */
346
+ public function deleteNetworkOption( $option_name ) {
347
+ $network_id = (int) get_current_network_id();
348
+ $cache_key = $network_id . ':' . $this->getPrefix() . $option_name;
349
+ $delete_cache = wp_cache_delete( $cache_key, $this->getPrefix() . 'network_options' );
350
+
351
+ $delete_opt1 = delete_site_option( $this->getPrefix() . $option_name );
352
+
353
+ return $delete_cache && $delete_opt1;
354
+ }
355
+
356
+ /**
357
+ * Удаляет опцию сайта в БД таблица options, а если опция есть в кеше, индивидуально удаляет опцию из кеша.
358
+ *
359
+ * @since 4.0.0 - Добавлен
360
+ *
361
+ * @param string $option_name Имя опции без префикса.
362
+ *
363
+ * @return bool Возвращает true, если опция удалена успешно, false в случае ошибки.
364
+ */
365
+ public function deleteOption( $option_name ) {
366
+ $delete_cache = wp_cache_delete( $this->getPrefix() . $option_name, $this->getPrefix() . 'options' );
367
+
368
+ // todo: удалить, когда большая часть пользователей обновятся до современных релизов
369
+ $delete_opt1 = delete_option( $this->getPrefix() . $option_name . '_is_active' );
370
+ $delete_opt2 = delete_option( $this->getPrefix() . $option_name );
371
+
372
+ return $delete_cache && $delete_opt1 && $delete_opt2;
373
+ }
374
+
375
+ /**
376
+ * Сбрасывает объектный кеш. Может использоваться для перезагрузки опций плагина и Wordpress в целом.
377
+ *
378
+ * @since 4.0.0 - Добавлен
379
+ * @return bool Возвращает true, если кеш сброшен успешно, false в случае ошибки.
380
+ */
381
+ public function flushOptionsCache() {
382
+ return wp_cache_flush();
383
+ }
384
+
385
+ /**
386
+ * Позволяет получить полное имя опции с префиксом. Может быть использовано в тех случаях, где нужно получить
387
+ * полное имя опции.
388
+ *
389
+ * @since 4.0.0 - Добавлен
390
+ *
391
+ * @param string $option_name Имя опции без префикса.
392
+ *
393
+ * @return null|string Возвращает имя опции с префиксом. Например wbcr_clearfy_{options_name}
394
+ */
395
+ public function getOptionName( $option_name ) {
396
+ $option_name = trim( rtrim( $option_name ) );
397
+ if ( empty( $option_name ) || ! is_string( $option_name ) ) {
398
+ return null;
399
+ }
400
+
401
+ return $this->getPrefix() . $option_name;
402
+ }
403
+
404
+ /**
405
+ * Позволяет нормализовать данные. В некоторых методах этого трейта, ожидаются данные определенного типа, чтобы
406
+ * выполнить различные логические операции. Как раз в этом случае этот метод можно использовать, чтобы привести
407
+ * все сырые данные в строгий тип. Такое решение позволит избежать ошибок в работе программиста.
408
+ *
409
+ * @since 4.0.0 - Добавлен
410
+ *
411
+ * @param mixed $data Данные, которые нужно нормализовать.
412
+ *
413
+ * @return mixed Возвращает нормализованное значение.
414
+ * - Если передана строка "true" или "false" вернет булево значение.
415
+ * - Если передана строка "1" или "0" вернет число.
416
+ */
417
+ public function normalizeValue( $data ) {
418
+ if ( is_string( $data ) ) {
419
+ $check_string = rtrim( trim( $data ) );
420
+
421
+ if ( $check_string == "1" || $check_string == "0" ) {
422
+ return intval( $data );
423
+ } else if ( $check_string === 'false' ) {
424
+ return false;
425
+ } else if ( $check_string === 'true' ) {
426
+ return true;
427
+ }
428
+ }
429
+
430
+ return $data;
431
+ }
432
+ }
libs/factory/core/includes/class-factory-plugin-abstract.php ADDED
@@ -0,0 +1,674 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ // Exit if accessed directly
3
+ if ( ! defined( 'ABSPATH' ) ) {
4
+ exit;
5
+ }
6
+
7
+ /**
8
+ * Основной класс для создания плагина.
9
+ *
10
+ * Это основной класс плагина. который отвечает за подключение модулей фреймворка, линзирование, обновление,
11
+ * миграции разрабатываемого плагина. При создании нового плагина, вы должны создать основной класс реализующий
12
+ * функции плагина, этот класс будет наследовать текущий.
13
+ *
14
+ * Смотрите подробную инструкцию по созданию плагина и экземпляра основного класса в документации по созданию
15
+ * плагина для Wordpress.
16
+ *
17
+ * Документация по классу: https://webcraftic.atlassian.net/wiki/spaces/FFD/pages/393052164
18
+ * Документация по созданию плагина: https://webcraftic.atlassian.net/wiki/spaces/CNCFC/pages/327828
19
+ *
20
+ * @author Alex Kovalev <alex.kovalevv@gmail.com>, repo: https://github.com/alexkovalevv
21
+ * @author Webcraftic <wordpress.webraftic@gmail.com>, site: https://webcraftic.com
22
+ *
23
+ * @since 1.0.0
24
+ * @package factory-core
25
+ *
26
+ */
27
+ abstract class Wbcr_Factory420_Plugin extends Wbcr_Factory420_Base {
28
+
29
+ /**
30
+ * Instance class Wbcr_Factory420_Request, required manages http requests
31
+ *
32
+ * @see https://webcraftic.atlassian.net/wiki/spaces/FFD/pages/390561806
33
+ * @var Wbcr_Factory420_Request
34
+ */
35
+ public $request;
36
+
37
+ /**
38
+ * @see https://webcraftic.atlassian.net/wiki/spaces/FFD/pages/393936924
39
+ * @var \WBCR\Factory_420\Premium\Provider
40
+ */
41
+ public $premium;
42
+
43
+ /**
44
+ * The Bootstrap Manager class
45
+ *
46
+ * @var Wbcr_FactoryBootstrap421_Manager
47
+ */
48
+ public $bootstrap;
49
+
50
+ /**
51
+ * The Bootstrap Manager class
52
+ *
53
+ * @var Wbcr_FactoryForms418_Manager
54
+ */
55
+ public $forms;
56
+
57
+ /**
58
+ * Простой массив со списком зарегистрированных классов унаследованных от Wbcr_Factory420_Activator.
59
+ * Классы активации используются для упаковки набора функций, которые нужно выполнить во время
60
+ * активации плагина.
61
+ *
62
+ * @var array[] Wbcr_Factory420_Activator
63
+ */
64
+ protected $activator_class = [];
65
+
66
+ /**
67
+ * Ассоциативный массив со списком уже загруженных модулей фреймворка. Используется для того, чтобы
68
+ * проверить, каких модули уже были загружены, а какие еще нет.
69
+ *
70
+ * @var array
71
+ */
72
+ private $loaded_factory_modules = [];
73
+
74
+ /**
75
+ * Ассоциативный массив со списком аддонов плагина. Аддоны плагина являются частью одного проекта,
76
+ * но не как отдельный плагин.
77
+ *
78
+ * @var array[] Wbcr_Factory420_Plugin
79
+ */
80
+ private $plugin_addons;
81
+
82
+ /**
83
+ * The Adverts Manager class
84
+ *
85
+ * @author Alexander Kovalev <alex.kovalevv@gmail.com>
86
+ * @since 4.1.9
87
+ * @var WBCR\Factory_Adverts_102\Base
88
+ */
89
+ private $adverts;
90
+
91
+ /**
92
+ * Инициализирует компоненты фреймворка и плагина.
93
+ *
94
+ * @since 1.0.0
95
+ *
96
+ * @param array $data A set of plugin data.
97
+ *
98
+ * @param string $plugin_path A full path to the main plugin file.
99
+ *
100
+ * @throws Exception
101
+ */
102
+ public function __construct( $plugin_path, $data ) {
103
+
104
+ parent::__construct( $plugin_path, $data );
105
+
106
+ $this->request = new Wbcr_Factory420_Request();
107
+ //$this->route = new Wbcr_Factory420_Route();
108
+
109
+ // INIT PLUGIN FRAMEWORK MODULES
110
+ // Framework modules should always be loaded first,
111
+ // since all other functions depend on them.
112
+ $this->init_framework_modules();
113
+
114
+ // INIT PLUGIN MIGRATIONS
115
+ $this->init_plugin_migrations();
116
+
117
+ // INIT PLUGIN NOTICES
118
+ $this->init_plugin_notices();
119
+
120
+ // INIT PLUGIN PREMIUM FEATURES
121
+ // License manager should be installed earlier
122
+ // so that other modules can access it.
123
+ $this->init_plugin_premium_features();
124
+
125
+ // INIT PLUGIN UPDATES
126
+ $this->init_plugin_updates();
127
+
128
+ // init actions
129
+ $this->register_plugin_hooks();
130
+ }
131
+
132
+ /* Services region
133
+ /* -------------------------------------------------------------*/
134
+
135
+ /**
136
+ * Устанавливает класс менеджер, которому плагин будет делегировать подключение ресурсов (картинок,
137
+ * скриптов, стилей) фреймворка.
138
+ *
139
+ * @param Wbcr_FactoryBootstrap421_Manager $bootstrap
140
+ */
141
+ public function setBootstap( Wbcr_FactoryBootstrap421_Manager $bootstrap ) {
142
+ $this->bootstrap = $bootstrap;
143
+ }
144
+
145
+ /**
146
+ * Устанавливает класс менеджер, которому будет делегирована работа с html формами фреймворка.
147
+ *
148
+ * @param Wbcr_FactoryForms418_Manager $forms
149
+ */
150
+ public function setForms( Wbcr_FactoryForms418_Manager $forms ) {
151
+ $this->forms = $forms;
152
+ }
153
+
154
+ /**
155
+ * Устанавливает класс менеджер, которому будет делегирована работа с объявлениями в Wordpress
156
+ *
157
+ * @author Alexander Kovalev <alex.kovalevv@gmail.com>
158
+ * @since 4.1.9
159
+ */
160
+ public function set_adverts_manager( $class_name ) {
161
+ if ( empty( $this->adverts ) && $this->render_adverts ) {
162
+ $this->adverts = new $class_name( $this, $this->adverts_settings );
163
+ }
164
+ }
165
+
166
+ /**
167
+ * Устанавливает класс провайдера лицензий
168
+ *
169
+ * С помощью этого класса, мы проверяем валидность лицензий и получаем дополнительную информацию
170
+ * о лицензии и ее покупателе. Класс используется в премиум менеджере.
171
+ *
172
+ * @since 4.1.6 - Добавлен
173
+ *
174
+ * @param string $name Имя провайдер
175
+ * @param string $class_name Имя класса провайдера
176
+ */
177
+ public function set_license_provider( $name, $class_name ) {
178
+ if ( ! isset( WBCR\Factory_420\Premium\Manager::$providers[ $name ] ) ) {
179
+ WBCR\Factory_420\Premium\Manager::$providers[ $name ] = $class_name;
180
+ }
181
+ }
182
+
183
+ /**
184
+ * Регистрируем класс репозитория
185
+ *
186
+ * С помощью этого класса мы реализиуем доставку и откат обновлений плагина, на сайт пользователя.
187
+ * Скачиваение премиум версий происходит по защенному каналу. Класс используется в менеджере обновлений.
188
+ *
189
+ * @since 4.1.7 - Добавлен
190
+ *
191
+ * @param string $name Имя репозитория
192
+ * @param string $class_name Имя класса репозитория
193
+ */
194
+ public function set_update_repository( $name, $class_name ) {
195
+ if ( ! isset( WBCR\Factory_420\Updates\Upgrader::$repositories[ $name ] ) ) {
196
+ WBCR\Factory_420\Updates\Upgrader::$repositories[ $name ] = $class_name;
197
+ }
198
+ }
199
+
200
+ /**
201
+ * Позволяет получить экземпляр менеджера объявления
202
+ *
203
+ * Доступен глобально через метод app(), чаще всего используется для создания точек для ротации
204
+ * рекламных объявлений.
205
+ *
206
+ * @author Alexander Kovalev <alex.kovalevv@gmail.com>
207
+ * @since 1.1
208
+ * @return \WBCR\Factory_Adverts_102\Base
209
+ */
210
+ public function get_adverts_manager() {
211
+ return $this->adverts;
212
+ }
213
+
214
+ /**
215
+ * Устанавливает текстовый домен для плагина. Текстовый домен берется из заголовка входного
216
+ * файла плагина.
217
+ *
218
+ * @since 4.0.8 - Добавлен
219
+ *
220
+ * @see https://codex.wordpress.org/I18n_for_WordPress_Developers
221
+ * @see https://webcraftic.atlassian.net/wiki/spaces/CNCFC/pages/327828 - документация по входному файлу
222
+ */
223
+ public function set_text_domain() {
224
+ if ( empty( $this->plugin_text_domain ) ) {
225
+ return;
226
+ }
227
+
228
+ $locale = apply_filters( 'plugin_locale', is_admin() ? get_user_locale() : get_locale(), $this->plugin_text_domain );
229
+
230
+ $mofile = $this->plugin_text_domain . '-' . $locale . '.mo';
231
+
232
+ if ( ! load_textdomain( $this->plugin_text_domain, $this->paths->absolute . '/languages/' . $mofile ) ) {
233
+ load_muplugin_textdomain( $this->plugin_text_domain );
234
+ }
235
+ }
236
+
237
+ /**
238
+ * Все страницы плагина создаются через специальную обертку, за которую отвечает модуль
239
+ * фреймворка pages. Разработчик создает собственный класс, унаследованный от
240
+ * Wbcr_FactoryPages420_AdminPage, а затем регистрирует его через этот метод.
241
+ * Метод выполняет подключение класса страницы и регистрирует его в модуле фреймворка
242
+ * pages.
243
+ *
244
+ * Больше информации о создании и регистрации страниц, вы можете узнать из документации по созданию
245
+ * страниц плагина.
246
+ *
247
+ * @see https://webcraftic.atlassian.net/wiki/spaces/CNCFC/pages/222887949 - документация по созданию страниц
248
+ *
249
+ * @param string $class_name Имя регистрируемого класса страницы. Пример: WCL_Page_Name.
250
+ * Регистрируемый класс должен быть унаследован от класса Wbcr_FactoryPages420_AdminPage.
251
+ * @param string $file_path Абсолютный путь к файлу с классом страницы.
252
+ *
253
+ * @throws Exception
254
+ */
255
+ public function registerPage( $class_name, $file_path ) {
256
+ // todo: https://webcraftic.atlassian.net/projects/PCS/issues/PCS-88
257
+ // if ( $this->isNetworkActive() && ! is_network_admin() ) {
258
+ // return;
259
+ // }
260
+
261
+ if ( ! file_exists( $file_path ) ) {
262
+ throw new Exception( 'The page file was not found by the path {' . $file_path . '} you set.' );
263
+ }
264
+
265
+ require_once( $file_path );
266
+
267
+ if ( ! class_exists( $class_name ) ) {
268
+ throw new Exception( 'A class with this name {' . $class_name . '} does not exist.' );
269
+ }
270
+
271
+ if ( ! class_exists( 'Wbcr_FactoryPages420' ) ) {
272
+ throw new Exception( 'The factory_pages_420 module is not included.' );
273
+ }
274
+
275
+ Wbcr_FactoryPages420::register( $this, $class_name );
276
+ }
277
+
278
+ /**
279
+ * Произвольные типы записей в плагине, создаются через специальную обертку, за которую отвечает
280
+ * модуль фреймворка types. Разработчик создает собственный класс, унаследованный от
281
+ * Wbcr_FactoryTypes000_Type, а затем регистрирует его через этот метод. Метод выполняет
282
+ * подключение класса с новым типом записи и регистрирует его в модуле фреймворка types. *
283
+ *
284
+ * @param string $class_name Имя регистрируемого класса страницы. Пример: WCL_Type_Name.
285
+ * Регистрируемый класс должен быть унаследован от класса Wbcr_FactoryTypes000_Type.
286
+ * @param string $file_path Абсолютный путь к файлу с классом страницы.
287
+ *
288
+ * @throws Exception
289
+ * @deprecated 4.1.7 You cannot use it!
290
+ */
291
+ public function registerType( $class_name, $file_path ) {
292
+ throw new Exception( 'As of factory core module 4.1.7, the "registerType" method is deprecated. You cannot use it!' );
293
+ }
294
+
295
+ /**
296
+ * Registers a class to activate the plugin.
297
+ *
298
+ * @since 1.0.0
299
+ *
300
+ * @param string $className class name of the plugin activator.
301
+ *
302
+ * @return void
303
+ */
304
+ public function registerActivation( $className ) {
305
+ $this->activator_class[] = $className;
306
+ }
307
+
308
+ /* end services region
309
+ /* -------------------------------------------------------------*/
310
+
311
+ /**
312
+ * It's invoked on plugin activation. Don't excite it directly.
313
+ *
314
+ * @since 1.0.0
315
+ * @return void
316
+ */
317
+ public function activation_hook() {
318
+
319
+ /**
320
+ * @since 4.1.1 - change hook name
321
+ */
322
+ if ( apply_filters( "wbcr/factory_420/cancel_plugin_activation_{$this->plugin_name}", false ) ) {
323
+ return;
324
+ }
325
+
326
+ /**
327
+ * wbcr_factory_420_plugin_activation
328
+ *
329
+ * @since 4.1.1 - deprecated
330
+ */
331
+ wbcr_factory_420_do_action_deprecated( 'wbcr_factory_420_plugin_activation', [
332
+ $this
333
+ ], '4.1.1', "wbcr/factory/plugin_activation" );
334
+
335
+ /**
336
+ * wbcr/factory/plugin_activation
337
+ *
338
+ * @since 4.1.2 - deprecated
339
+ */
340
+ wbcr_factory_420_do_action_deprecated( 'wbcr/factory/plugin_activation', [
341
+ $this
342
+ ], '4.1.2', "wbcr/factory/before_plugin_activation" );
343
+
344
+ /**
345
+ * wbcr/factory/before_plugin_activation
346
+ *
347
+ * @since 4.1.2 - added
348
+ */
349
+ do_action( 'wbcr/factory/before_plugin_activation', $this );
350
+
351
+ /**
352
+ * # wbcr/factory/plugin_{$this->plugin_name}_activation
353
+ *
354
+ * @since 4.1.2 - deprecated
355
+ */
356
+ wbcr_factory_420_do_action_deprecated( "wbcr/factory/plugin_{$this->plugin_name}_activation", [
357
+ $this
358
+ ], '4.1.2', "wbcr/factory/before_plugin_{$this->plugin_name}_activation" );
359
+
360
+ /**
361
+ * wbcr_factory_420_plugin_activation_' . $this->plugin_name
362
+ *
363
+ * @since 4.1.1 - deprecated
364
+ */
365
+ wbcr_factory_420_do_action_deprecated( 'wbcr_factory_420_plugin_activation_' . $this->plugin_name, [
366
+ $this
367
+ ], '4.1.1', "wbcr/factory/before_plugin_{$this->plugin_name}_activation" );
368
+
369
+ /**
370
+ * wbcr/factory/plugin_{$this->plugin_name}_activation
371
+ *
372
+ * @since 4.1.2 - added
373
+ */
374
+ do_action( "wbcr/factory/plugin_{$this->plugin_name}_activation", $this );
375
+
376
+ if ( ! empty( $this->activator_class ) ) {
377
+ foreach ( (array) $this->activator_class as $activator_class ) {
378
+ $activator = new $activator_class( $this );
379
+ $activator->activate();
380
+ }
381
+ }
382
+
383
+ /**
384
+ * @since 4.1.2 - added
385
+ */
386
+ do_action( 'wbcr/factory/plugin_activated', $this );
387
+
388
+ /**
389
+ * @since 4.1.2 - added
390
+ */
391
+ do_action( "wbcr/factory/plugin_{$this->plugin_name}_activated", $this );
392
+ }
393
+
394
+ /**
395
+ * It's invoked on plugin deactionvation. Don't excite it directly.
396
+ *
397
+ * @since 1.0.0
398
+ * @return void
399
+ */
400
+ public function deactivation_hook() {
401
+
402
+ /**
403
+ * @since 4.1.1 - change hook name
404
+ */
405
+ if ( apply_filters( "wbcr/factory_420/cancel_plugin_deactivation_{$this->plugin_name}", false ) ) {
406
+ return;
407
+ }
408
+
409
+ /**
410
+ * wbcr_factory_420_plugin_deactivation
411
+ *
412
+ * @since 4.1.1 - deprecated
413
+ */
414
+ wbcr_factory_420_do_action_deprecated( 'wbcr_factory_420_plugin_deactivation', [
415
+ $this
416
+ ], '4.1.1', "wbcr/factory/plugin_deactivation" );
417
+
418
+ /**
419
+ * wbcr/factory/plugin_deactivation
420
+ *
421
+ * @since 4.1.2 - deprecated
422
+ */
423
+ wbcr_factory_420_do_action_deprecated( 'wbcr/factory/plugin_deactivation', [
424
+ $this
425
+ ], '4.1.2', "wbcr/factory/before_plugin_deactivation" );
426
+
427
+ /**
428
+ * wbcr/factory/plugin_deactivation
429
+ *
430
+ * @since 4.1.2 - added
431
+ */
432
+ do_action( 'wbcr/factory/plugin_deactivation', $this );
433
+
434
+ /**
435
+ * wbcr_factory_420_plugin_deactivation_ . $this->plugin_name
436
+ *
437
+ * @since 4.1.1 - deprecated
438
+ */
439
+ wbcr_factory_420_do_action_deprecated( 'wbcr_factory_420_plugin_deactivation_' . $this->plugin_name, [
440
+ $this
441
+ ], '4.1.1', "wbcr/factory/before_plugin_{$this->plugin_name}_deactivation" );
442
+
443
+ /**
444
+ * wbcr/factory/plugin_{$this->plugin_name}_deactivation
445
+ *
446
+ * @since 4.1.2 - deprecated
447
+ */
448
+ wbcr_factory_420_do_action_deprecated( "wbcr/factory/plugin_{$this->plugin_name}_deactivation", [
449
+ $this
450
+ ], '4.1.2', "wbcr/factory/before_plugin_{$this->plugin_name}_deactivation" );
451
+
452
+ /**
453
+ * @since 4.1.2 - added
454
+ */
455
+ do_action( "wbcr/factory/before_plugin_{$this->plugin_name}_deactivation" );
456
+
457
+ if ( ! empty( $this->activator_class ) ) {
458
+ foreach ( (array) $this->activator_class as $activator_class ) {
459
+ $activator = new $activator_class( $this );
460
+ $activator->deactivate();
461
+ }
462
+ }
463
+
464
+ /**
465
+ * @since 4.1.2 - added
466
+ */
467
+ do_action( 'wbcr/factory/plugin_deactivated', $this );
468
+
469
+ /**
470
+ * @since 4.1.2 - added
471
+ */
472
+ do_action( "wbcr/factory/plugin_{$this->plugin_name}_deactivated", $this );
473
+ }
474
+
475
+ /**
476
+ * Возвращает ссылку на внутреннюю страницу плагина
477
+ *
478
+ * @param string $page_id
479
+ *
480
+ * @sicne: 4.0.8
481
+ * @return string|void
482
+ * @throws Exception
483
+ */
484
+ public function getPluginPageUrl( $page_id, $args = [] ) {
485
+ if ( ! class_exists( 'Wbcr_FactoryPages420' ) ) {
486
+ throw new Exception( 'The factory_pages_420 module is not included.' );
487
+ }
488
+
489
+ if ( ! is_admin() ) {
490
+ _doing_it_wrong( __METHOD__, __( 'You cannot use this feature on the frontend.' ), '4.0.8' );
491
+
492
+ return null;
493
+ }
494
+
495
+ return Wbcr_FactoryPages420::getPageUrl( $this, $page_id, $args );
496
+ }
497
+
498
+
499
+ /**
500
+ * Загружает аддоны для плагина, как часть проекта, а не как отдельный плагин
501
+ */
502
+ protected function loadAddons( $addons ) {
503
+ if ( empty( $addons ) ) {
504
+ return;
505
+ }
506
+
507
+ foreach ( $addons as $addon_name => $addon_path ) {
508
+ if ( ! isset( $this->plugin_addons[ $addon_name ] ) ) {
509
+
510
+ // При подключении аддона, мы объявляем константу, что такой аддон уже загружен
511
+ // $addon_name индентификатор аддона в вверхнем регистре
512
+ $const_name = strtoupper( 'LOADING_' . str_replace( '-', '_', $addon_name ) . '_AS_ADDON' );
513
+
514
+ if ( ! defined( $const_name ) ) {
515
+ define( $const_name, true );
516
+ }
517
+
518
+ require_once( $addon_path[1] );
519
+
520
+ // Передаем аддону информацию о родительском плагине
521
+ $plugin_data = $this->getPluginInfo();
522
+
523
+ // Устанавливаем метку для аддона, которая указывает на то, что это аддон
524
+ $plugin_data['as_addon'] = true;
525
+
526
+ // Передаем класс родителя в аддон, для того,
527
+ // чтобы аддон использовал экземпляр класса родителя, а не создавал свой собственный.
528
+ $plugin_data['plugin_parent'] = $this;
529
+
530
+ // Создаем экземпляр класса аддона и записываем его в список загруженных аддонов
531
+ if ( class_exists( $addon_path[0] ) ) {
532
+ $this->plugin_addons[ $addon_name ] = new $addon_path[0]( $this->get_paths()->main_file, $plugin_data );
533
+ }
534
+ }
535
+ }
536
+ }
537
+
538
+ /**
539
+ * Загружает специальные модули для расширения Factory фреймворка.
540
+ * Разработчик плагина сам выбирает, какие модули ему нужны для
541
+ * создания плагина.
542
+ *
543
+ * Модули фреймворка хранятся в libs/factory/framework
544
+ *
545
+ * @return void
546
+ * @throws Exception
547
+ */
548
+ private function init_framework_modules() {
549
+
550
+ if ( ! empty( $this->load_factory_modules ) ) {
551
+ foreach ( (array) $this->load_factory_modules as $module ) {
552
+ $scope = isset( $module[2] ) ? $module[2] : 'all';
553
+
554
+ if ( $scope == 'all' || ( is_admin() && $scope == 'admin' ) || ( ! is_admin() && $scope == 'public' ) ) {
555
+
556
+ if ( ! file_exists( $this->get_paths()->absolute . '/' . $module[0] . '/boot.php' ) ) {
557
+ throw new Exception( 'Module ' . $module[1] . ' is not included.' );
558
+ }
559
+
560
+ $module_boot_file = $this->get_paths()->absolute . '/' . $module[0] . '/boot.php';
561
+ require_once $module_boot_file;
562
+
563
+ $this->loaded_factory_modules[ $module[1] ] = $module_boot_file;
564
+
565
+ do_action( 'wbcr_' . $module[1] . '_plugin_created', $this );
566
+ }
567
+ }
568
+ }
569
+
570
+ /**
571
+ * @since 4.1.1 - deprecated
572
+ */
573
+ wbcr_factory_420_do_action_deprecated( 'wbcr_factory_420_core_modules_loaded-' . $this->plugin_name, [], '4.1.1', "wbcr/factory_420/modules_loaded-" . $this->plugin_name );
574
+
575
+ /**
576
+ * @since 4.1.1 - add
577
+ */
578
+ do_action( 'wbcr/factory_420/modules_loaded-' . $this->plugin_name );
579
+ }
580
+
581
+
582
+ /**
583
+ * Setups actions related with the Factory Plugin.
584
+ *
585
+ * @since 1.0.0
586
+ */
587
+ private function register_plugin_hooks() {
588
+
589
+ add_action( 'plugins_loaded', [ $this, 'set_text_domain' ] );
590
+
591
+ if ( is_admin() ) {
592
+ add_filter( 'wbcr_factory_420_core_admin_allow_multisite', '__return_true' );
593
+
594
+ register_activation_hook( $this->get_paths()->main_file, [ $this, 'activation_hook' ] );
595
+ register_deactivation_hook( $this->get_paths()->main_file, [ $this, 'deactivation_hook' ] );
596
+ }
597
+ }
598
+
599
+ /**
600
+ * Инициализируем миграции плагина
601
+ *
602
+ * @since 4.1.1
603
+ * @return void
604
+ * @throws Exception
605
+ */
606
+ protected function init_plugin_migrations() {
607
+ new WBCR\Factory_420\Migrations( $this );
608
+ }
609
+
610
+ /**
611
+ * Инициализируем уведомления плагина
612
+ *
613
+ * @since 4.1.1
614
+ * @return void
615
+ */
616
+ protected function init_plugin_notices() {
617
+ new Wbcr\Factory_420\Notices( $this );
618
+ }
619
+
620
+ /**
621
+ * Создает нового рабочего для проверки обновлений и апгрейда текущего плагина.
622
+ *
623
+ * @since 4.1.1
624
+ *
625
+ * @param array $data
626
+ *
627
+ * @return void
628
+ * @throws Exception
629
+ */
630
+ protected function init_plugin_updates() {
631
+ if ( $this->has_updates ) {
632
+ new WBCR\Factory_420\Updates\Upgrader( $this );
633
+ }
634
+ }
635
+
636
+ /**
637
+ * Начинает инициализацию лицензирования текущего плагина. Доступ к менеджеру лицензий можно
638
+ * получить через свойство license_manager.
639
+ *
640
+ * Дополнительно создает рабочего, чтобы совершить апгрейд до премиум версии
641
+ * и запустить проверку обновлений для этого модуля.
642
+ *
643
+ * @since 4.1.1
644
+ * @throws Exception
645
+ */
646
+ protected function init_plugin_premium_features() {
647
+ if ( ! $this->has_premium || ! $this->license_settings ) {
648
+ $this->premium = null;
649
+
650
+ return;
651
+ }
652
+
653
+ // Создаем экземляр премиум менеджера, мы сможем к нему обращаться глобально.
654
+ $this->premium = WBCR\Factory_420\Premium\Manager::instance( $this, $this->license_settings );
655
+
656
+ // Подключаем премиум апгрейдер
657
+ if ( isset( $this->license_settings['has_updates'] ) && $this->license_settings['has_updates'] ) {
658
+ new WBCR\Factory_420\Updates\Premium_Upgrader( $this );
659
+ }
660
+ }
661
+
662
+ // ----------------------------------------------------------------------
663
+ // Public methods
664
+ // ----------------------------------------------------------------------
665
+
666
+ public function newScriptList() {
667
+ return new Wbcr_Factory420_ScriptList( $this );
668
+ }
669
+
670
+ public function newStyleList() {
671
+ return new Wbcr_Factory420_StyleList( $this );
672
+ }
673
+ }
674
+
libs/factory/core/includes/class-factory-plugin-base.php ADDED
@@ -0,0 +1,519 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ // Exit if accessed directly
3
+ if ( ! defined( 'ABSPATH' ) ) {
4
+ exit;
5
+ }
6
+
7
+ /**
8
+ * Базовый класс для создания нового плагина. Полную реализацию класса смотрите в Wbcr_Factory420_Plugin
9
+ *
10
+ * Документация по классу: https://webcraftic.atlassian.net/wiki/spaces/FFD/pages/392724484
11
+ * Документация по созданию плагина: https://webcraftic.atlassian.net/wiki/spaces/CNCFC/pages/327828
12
+ * Репозиторий: https://github.com/alexkovalevv
13
+ *
14
+ * @author Alex Kovalev <alex.kovalevv@gmail.com>, repo: https://github.com/alexkovalevv
15
+ * @author Webcraftic <wordpress.webraftic@gmail.com>, site: https://webcraftic.com
16
+ *
17
+ * @since 1.0.0
18
+ * @package factory-core
19
+ */
20
+ class Wbcr_Factory420_Base {
21
+
22
+ use WBCR\Factory_420\Options;
23
+
24
+ /**
25
+ * Обязательное свойство. Префикс, используется для создания пространство имен.
26
+ * Чаще всего используется на именования опций в базе данных. Также может быть
27
+ * использован для именования полей html форм, создания уникальных имен, хуков.
28
+ * Пример: wrio_
29
+ *
30
+ * Для префикса всегда используете нижнее подчеркивание справа!
31
+ *
32
+ * @var string
33
+ */
34
+ protected $prefix;
35
+
36
+ /**
37
+ * Обязательное свойство. Заголовок плагина. Используете в интерфейсе плагина,
38
+ * может быть использован в уведомлениях для администратора, чтобы пользователь
39
+ * мог понять, с каким плагином он ведет коммуникацию. Пример: Robin image optimizer
40
+ *
41
+ * @var string
42
+ */
43
+ protected $plugin_title;
44
+
45
+ /**
46
+ * Обязательное свойство. Имя плагина. Используется аналогично префиксу, но с небольшим
47
+ * отличием. Имя плагина имеет человеку понятную строку, которую можно использовать в
48
+ * именовании хуков, созданию условной логики. Допустимые символы [A-z0-9_].
49
+ * Пример: wbcr_clearfy
50
+ *
51
+ * @var string
52
+ */
53
+ protected $plugin_name;
54
+
55
+ /**
56
+ * Обязательное свойство. Версия плагина в формате 0.0.0. Допустимые символы [0-9.]
57
+ *
58
+ * @var string
59
+ */
60
+ protected $plugin_version;
61
+
62
+ /**
63
+ * Обязательное свойство. Текстовый домен плагина, используется для подключения файлов
64
+ * переводов. Рекомендуется использовать slug плагина, идентичный slug в репозитории
65
+ * Wordpress.org
66
+ *
67
+ * @since 4.1.1
68
+ * @var string
69
+ */
70
+ protected $plugin_text_domain;
71
+
72
+ /**
73
+ * Обязательное свойство. Информация для поддержки клиента. Для начала работы плагина,
74
+ * достаточно только указать адрес лендинга в атрибут url. На лендинге должны быть
75
+ * созданы страницы features, pricing, support, docs. Если страницы (features, pricing,
76
+ * support, docs) не могут иметь такие же адреса, вы можете наложить карту адресов в
77
+ * атрибуте pages_map. К примеру: я создал страницу "Pro Features" и она имеет адрес
78
+ * {site}/premium-features, для pages_map в атрибуте features, я указал, что адрес
79
+ * страницы со списком функций имеет слаг premium-features. Теперь плагин будет понимать,
80
+ * что адрес страницы со списком функций будет таким:
81
+ * https://robin-image-optimizer.webcraftic.com/premium-features.
82
+ *
83
+ * Это свойство заполняется для того, чтобы в процессе разработки вы могли использовать
84
+ * экземпляр класса \WBCR\Factory_420\Entities\Support, для получения информации о сайте плагина.
85
+ * Тем самым вы избавляете себя от жесткого прописывания ссылок на лендинг плагина и
86
+ * можете изменить все ссылки в одном месте.
87
+ *
88
+ * @var array
89
+ */
90
+ protected $support_details;
91
+
92
+ /**
93
+ * Включение/отключение обновлений для бесплатного плагина. Если вашего плагина нет в репозитори
94
+ * Wordpress.org, вы можете включить собственный режим обновлений, например через GitHub или
95
+ * собственный репозиторий. Если установлено true, плагин будет проверять наличие обновлений
96
+ * для этого плагина.
97
+ *
98
+ * @var bool
99
+ */
100
+ protected $has_updates = false;
101
+
102
+ /**
103
+ * Настройка обновлений для бесплатного плагина. Если вы хотите настроить обновления для
104
+ * бесплатного плагина через собственный репозиторий (например: github), вам нужно указать имя
105
+ * репозитория и slug плагина. Slug может быть идентичен имени репозитория в github. Для Wordpress.org
106
+ * эти настройки не обязательны, так как в wordpress ядре есть встроенные функции для обновлений
107
+ * плагинов и тем.
108
+ *
109
+ * @var array
110
+ */
111
+ protected $updates_settings = [];
112
+
113
+ /**
114
+ * Включение/отключение премиум версии для плагина. Если вы создаете бесплатный плагин и хотите
115
+ * реализовать для него премиум версию, вам нужно начать с этого свойства. Если свойство установлено,
116
+ * как true, при инициализации плагина будут подключены функции лицензирования, проверки обновлений
117
+ * для премиум версии.
118
+ *
119
+ * @var bool
120
+ */
121
+ protected $has_premium = false;
122
+
123
+ /**
124
+ * Настройки лицензирования
125
+ *
126
+ * Лицензирование плагина может быть реализовано для любого провайдера,
127
+ * к примеру: freemius, codecanyon, templatemonster, вам нужно указать только настройки для
128
+ * взаимодействия с выбранным вами провайдером. Каждая реализация провайдера лицензий может иметь
129
+ * индивидуальный настройки, в этом примере приведены настройки для freemius провайдера
130
+ * WBCR\Factory_420\Premium\Provider > WBCR\Factory_Freemius_000\Premium\Provider
131
+ *
132
+ * На текущий момент существует только реализация для freemius провайдера.
133
+ *
134
+ * Для премиум плагина вы должны также указать настройки обновлений. Атрибут has_updates
135
+ * включает/отключает обновления для премиум плагина, в атрибуте updates_settings вы указываете
136
+ * дополнительные настройки обновлений.
137
+ *
138
+ * @var array
139
+ */
140
+ protected $license_settings = [];
141
+
142
+ /**
143
+ * Переключатель внутренней рекламы в плагине
144
+ *
145
+ * Если установить true, то плагин будет показывать рекламу компании в интерфейсе Wordpress.
146
+ * Рекламный модуль может отображать рекламу внутри инрефейса плагина, на странице dashboard
147
+ * и создавать сквозные уведомления на всех страницах админ панели Wordpress.
148
+ *
149
+ * @author Alexander Kovalev <alex.kovalevv@gmail.com>
150
+ * @since 4.1.9
151
+ * @var bool
152
+ */
153
+ protected $render_adverts = false;
154
+
155
+ /**
156
+ * Настройки внутренней рекламы компании
157
+ *
158
+ * @author Alexander Kovalev <alex.kovalevv@gmail.com>
159
+ * @since 4.1.9
160
+ * @var array
161
+ */
162
+ protected $adverts_settings = [];
163
+
164
+ /**
165
+ * Обязательное свойство. Подключаемые модули фреймворка. Модули фреймворка позволяют расширять его
166
+ * функциональность.
167
+ *
168
+ * @var array {
169
+ * Array with information about the loadable module
170
+ * {type} string $module [0] Relative path to the module directory
171
+ * {type} string $module [1] Module name with prefix 000
172
+ * {type} string $module [2] Scope:
173
+ * admin - Module will be loaded only in the admin panel,
174
+ * public - Module will be loaded only on the frontend
175
+ * all - Module will be loaded everywhere
176
+ * }
177
+ */
178
+ protected $load_factory_modules = [
179
+ [ 'libs/factory/bootstrap', 'factory_bootstrap_421', 'admin' ],
180
+ [ 'libs/factory/forms', 'factory_forms_418', 'admin' ],
181
+ [ 'libs/factory/pages', 'factory_pages_420', 'admin' ],
182
+ ];
183
+
184
+
185
+ /**
186
+ * Экземпляр класса \WBCR\Factory_420\Entities\Support используется для получения информации
187
+ * о сайте плагина. Чаще всего используется для получения ссылки на страницу с тарифами или
188
+ * ссылки на форму обратной связи. Встроен механизм отслеживания по utm меткам.
189
+ *
190
+ * @var \WBCR\Factory_420\Entities\Support
191
+ */
192
+ protected $support;
193
+
194
+ /**
195
+ * Экземпляр класса \WBCR\Factory_420\Entities\Paths используется для получения информации о
196
+ * путях плагина. Часто используется для получения путей или ссылок на место хранения плагина
197
+ * или его входного файла.
198
+ *
199
+ * @var \WBCR\Factory_420\Entities\Paths
200
+ */
201
+ protected $paths;
202
+
203
+ /**
204
+ * Абсолютный путь к входному файлу плагина: C://server/site.dev/wp-content/plugins/plugin_name/plugin_name.php
205
+ *
206
+ * @var string
207
+ */
208
+ private $plugin_file;
209
+
210
+ /**
211
+ * Свойство хранит сырые настройки плагина, а также дополнительные настройки, которые не описаны
212
+ * в интерфейсе класса.
213
+ *
214
+ * @var array
215
+ */
216
+ private $plugin_data;
217
+
218
+ /**
219
+ * Конструктор:
220
+ * - Заполняет свойства класса из сырых данных плагина
221
+ * - Выполняет проверку на обязательные настройки
222
+ * - Инициализирует сущности support и paths
223
+ *
224
+ * @since 4.1.1 - добавил две сущности support, paths. Удалил свойства, plugin_build
225
+ * plugin_assembly, main_file, plugin_root, relative_path, plugin_url
226
+ * @since 4.0.8 - добавлена дополнительная логика
227
+ *
228
+ * @param string $plugin_file
229
+ * @param array $data
230
+ *
231
+ * @throws Exception
232
+ */
233
+ public function __construct( $plugin_file, $data ) {
234
+ $this->plugin_file = $plugin_file;
235
+ $this->plugin_data = $data;
236
+
237
+ foreach ( (array) $data as $option_name => $option_value ) {
238
+ if ( property_exists( $this, $option_name ) ) {
239
+ $this->$option_name = $option_value;
240
+ }
241
+ }
242
+
243
+ if ( empty( $this->prefix ) || empty( $this->plugin_name ) || empty( $this->plugin_title ) || empty( $this->plugin_version ) || empty( $this->plugin_text_domain ) ) {
244
+ throw new Exception( 'One of the required attributes has not been passed (prefix, plugin_title, plugin_name, plugin_version, plugin_text_domain).' );
245
+ }
246
+
247
+ $this->support = new \WBCR\Factory_420\Entities\Support( $this->support_details );
248
+ $this->paths = new \WBCR\Factory_420\Entities\Paths( $plugin_file );
249
+
250
+ // used only in the module 'updates'
251
+ $this->plugin_slug = ! empty( $this->plugin_name ) ? $this->plugin_name : basename( $plugin_file );
252
+ }
253
+
254
+ /**
255
+ * При обновлении фреймворка, некоторые свойства класса были удалены. Однако плагины на старом
256
+ * фреймворке по прежнему используют удаленные свойства. С помощью этого магического метода мы
257
+ * добавляем совместимость со старыми плагинами, но при этом выводим предупреждение, что нужно
258
+ * обновить некоторые свойства.
259
+ *
260
+ * @param string $name Имя свойства класса.
261
+ *
262
+ * @return mixed
263
+ */
264
+ public function __get( $name ) {
265
+
266
+ $deprecated_props = [
267
+ 'plugin_build',
268
+ 'plugin_assembly',
269
+ 'main_file',
270
+ 'plugin_root',
271
+ 'relative_path',
272
+ 'plugin_url'
273
+ ];
274
+
275
+ if ( in_array( $name, $deprecated_props ) ) {
276
+ $deprecated_message = 'In version 4.1.1 of the Factory framework, the class properties ';
277
+ $deprecated_message .= '(' . implode( ',', $deprecated_props ) . ')';
278
+ $deprecated_message .= 'have been removed. To get plugin paths, use the new paths property.' . PHP_EOL;
279
+
280
+ $backtrace = debug_backtrace();
281
+ if ( ! empty( $backtrace ) && isset( $backtrace[1] ) ) {
282
+ $deprecated_message .= 'BACKTRACE:(';
283
+ $deprecated_message .= 'File: ' . $backtrace[1]['file'];
284
+ $deprecated_message .= 'Function: ' . $backtrace[1]['function'];
285
+ $deprecated_message .= 'Line: ' . $backtrace[1]['line'];
286
+ $deprecated_message .= ')';
287
+ }
288
+
289
+ _deprecated_argument( __METHOD__, '4.1.1', $deprecated_message );
290
+
291
+ switch ( $name ) {
292
+ case 'plugin_build':
293
+ return null;
294
+ break;
295
+ case 'plugin_assembly':
296
+ return null;
297
+ break;
298
+ case 'main_file':
299
+ return $this->get_paths()->main_file;
300
+ break;
301
+ case 'plugin_root':
302
+ return $this->get_paths()->absolute;
303
+ break;
304
+ case 'relative_path':
305
+ return $this->get_paths()->basename;
306
+ break;
307
+ case 'plugin_url':
308
+ return $this->get_paths()->url;
309
+ break;
310
+ }
311
+ }
312
+
313
+ return null;
314
+ }
315
+
316
+ /**
317
+ * При обновлении фреймворка, некоторые методы класса были удалены. Однако плагины на старом фреймворке
318
+ * по прежнему используют удаленные методы. С помощью этого магического метода мы добавляем совместимость
319
+ * со старыми плагинами, но при этом выводим предупреждение, что нужно обновить некоторые методы.
320
+ *
321
+ * @param string $name Имя метода класса.
322
+ * @param array $arguments Массив аргументов метода класса.
323
+ *
324
+ * @return stdClass|null
325
+ * @throws Exception
326
+ */
327
+ public function __call( $name, $arguments ) {
328
+
329
+ $deprecated_methods = [
330
+ 'getPluginBuild',
331
+ 'getPluginAssembly',
332
+ 'getPluginPathInfo'
333
+ ];
334
+
335
+ if ( in_array( $name, $deprecated_methods ) ) {
336
+ $deprecated_message = 'In version 4.1.1 of the Factory framework, methods (' . implode( ',', $deprecated_methods ) . ') have been removed.';
337
+
338
+ $backtrace = debug_backtrace();
339
+ if ( ! empty( $backtrace ) && isset( $backtrace[1] ) ) {
340
+ $deprecated_message .= 'BACKTRACE:(';
341
+ $deprecated_message .= 'File: ' . $backtrace[1]['file'];
342
+ $deprecated_message .= 'Function: ' . $backtrace[1]['function'];
343
+ $deprecated_message .= 'Line: ' . $backtrace[1]['line'];
344
+ $deprecated_message .= ')';
345
+ }
346
+
347
+ _deprecated_argument( __METHOD__, '4.1.1', $deprecated_message );
348
+
349
+ if ( 'getPluginPathInfo' == $name ) {
350
+ $object = new stdClass;
351
+
352
+ $object->main_file = $this->get_paths()->main_file;
353
+ $object->plugin_root = $this->get_paths()->absolute;
354
+ $object->relative_path = $this->get_paths()->basename;
355
+ $object->plugin_url = $this->get_paths()->url;
356
+
357
+ return $object;
358
+ }
359
+ }
360
+
361
+ throw new Exception( "Method {$name} does not exist" );
362
+ }
363
+
364
+ /**
365
+ * Проверяет, включен ли премиум для этого плагина или нет.
366
+ *
367
+ * @return bool Возвращает true, если премиум пакет включен для этого плагина.
368
+ * См. Wbcr_Factory420_Base::has_premium
369
+ */
370
+ public function has_premium() {
371
+ return $this->has_premium;
372
+ }
373
+
374
+ /**
375
+ * Позволяет получить заголовок плагина.
376
+ *
377
+ * @return string Возвращает заголовок плагина. См. Wbcr_Factory420_Base::plugin_title
378
+ */
379
+ public function getPluginTitle() {
380
+ return $this->plugin_title;
381
+ }
382
+
383
+ /**
384
+ * Позволяет получить префикс плагина.
385
+ *
386
+ * @return string Возвращает префикс плагина.См. Wbcr_Factory420_Base::prefix
387
+ */
388
+ public function getPrefix() {
389
+ return $this->prefix;
390
+ }
391
+
392
+ /**
393
+ * Позволяет получить имя плагина.
394
+ *
395
+ * @return string Возвращает имя плагина. См. Wbcr_Factory420_Base::plugin_name
396
+ */
397
+ public function getPluginName() {
398
+ return $this->plugin_name;
399
+ }
400
+
401
+ /**
402
+ * Позволяет получить версию плагина.
403
+ *
404
+ * @return string Возвращает версию плагина. См. Wbcr_Factory420_Base::plugin_version
405
+ */
406
+ public function getPluginVersion() {
407
+ return $this->plugin_version;
408
+ }
409
+
410
+ /**
411
+ * Предоставляет доступ к сырым данным плагина. Может быть полезен, если вы хотите получить
412
+ * какие-то данные не описанные в интерфейсе этого плагина.
413
+ *
414
+ * @param string $attr_name Имя атрибута, который нужно получить. Идентично ключу в массиве
415
+ * Wbcr_Factory420_Base::plugin_data
416
+ *
417
+ * @return null
418
+ */
419
+ public function getPluginInfoAttr( $attr_name ) {
420
+ if ( isset( $this->plugin_data[ $attr_name ] ) ) {
421
+ return $this->plugin_data[ $attr_name ];
422
+ }
423
+
424
+ return null;
425
+ }
426
+
427
+ /**
428
+ * Предоставляет доступ к экземпляру класса \WBCR\Factory_420\Entities\Support.
429
+ *
430
+ * @return \WBCR\Factory_420\Entities\Support
431
+ */
432
+ public function get_support() {
433
+ return $this->support;
434
+ }
435
+
436
+ /**
437
+ * Предоставляет доступ к экземпляру класса \WBCR\Factory_420\Entities\Paths.
438
+ *
439
+ * @return \WBCR\Factory_420\Entities\Paths
440
+ */
441
+ public function get_paths() {
442
+ return $this->paths;
443
+ }
444
+
445
+ /**
446
+ * Позволяет получить сырые данные плагина в виде объекта StdClass.
447
+ *
448
+ * @return object Возвращает объект с сырыми данными плагина. См. Wbcr_Factory420_Base::plugin_data
449
+ */
450
+ public function getPluginInfo() {
451
+ return (object) $this->plugin_data;
452
+ }
453
+
454
+ /**
455
+ * TODO: Вынести метод в функции
456
+ *
457
+ * @since 4.0.8 Добавлен
458
+ *
459
+ * @return bool
460
+ */
461
+ public function isNetworkAdmin() {
462
+ return is_multisite() && is_network_admin();
463
+ }
464
+
465
+ /**
466
+ * Проверяет активирован ли плагин для сети. Если проект работает в режиме мультисайтов..
467
+ * TODO: Вынести метод в функции
468
+ *
469
+ * @since 4.0.8 Добавлен
470
+ * @return bool Если true, плагин активирован для сети или в текущий момент активируется для сети.
471
+ */
472
+ public function isNetworkActive() {
473
+ // Makes sure the plugin is defined before trying to use it
474
+ if ( ! function_exists( 'is_plugin_active_for_network' ) ) {
475
+ require_once( ABSPATH . '/wp-admin/includes/plugin.php' );
476
+ }
477
+
478
+ $activate = is_plugin_active_for_network( $this->get_paths()->basename );
479
+
480
+ if ( ! $activate && $this->isNetworkAdmin() && isset( $_GET['action'] ) && $_GET['action'] == 'activate' ) {
481
+ return isset( $_GET['networkwide'] ) && 1 == (int) $_GET['networkwide'];
482
+ }
483
+
484
+ return $activate;
485
+ }
486
+
487
+ /**
488
+ * Позволяет получить все активные сайты сети. Если проект работает в режиме мультисайтов.
489
+ * TODO: Вынести метод в функции
490
+ *
491
+ * @since 4.0.8
492
+ * @return array|int
493
+ */
494
+ public function getActiveSites( $args = [ 'archived' => 0, 'mature' => 0, 'spam' => 0, 'deleted' => 0 ] ) {
495
+ global $wp_version;
496
+
497
+ if ( version_compare( $wp_version, '4.6', '>=' ) ) {
498
+ return get_sites( $args );
499
+ } else {
500
+ $converted_array = [];
501
+
502
+ $sites = wp_get_sites( $args );
503
+
504
+ if ( empty( $sites ) ) {
505
+ return $converted_array;
506
+ }
507
+
508
+ foreach ( (array) $sites as $key => $site ) {
509
+ $obj = new stdClass();
510
+ foreach ( $site as $attr => $value ) {
511
+ $obj->$attr = $value;
512
+ }
513
+ $converted_array[ $key ] = $obj;
514
+ }
515
+
516
+ return $converted_array;
517
+ }
518
+ }
519
+ }
libs/factory/core/includes/class-factory-requests.php ADDED
@@ -0,0 +1,150 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ // Exit if accessed directly
3
+ if ( ! defined( 'ABSPATH' ) ) {
4
+ exit;
5
+ }
6
+
7
+ /*
8
+ * @author Alex Kovalev <alex.kovalevv@gmail.com>, repo: https://github.com/alexkovalevv
9
+ * @author Webcraftic <wordpress.webraftic@gmail.com>, site: https://webcraftic.com
10
+ *
11
+ * @package factory-core
12
+ */
13
+
14
+ class Wbcr_Factory420_Request {
15
+
16
+ /**
17
+ * @param null $param
18
+ * @param bool|string $sanitize true/false or sanitize function name
19
+ * @param bool $default
20
+ * @param string $method_name
21
+ *
22
+ * @return array|bool|mixed
23
+ */
24
+ private function getBody( $param = null, $sanitize = false, $default = false, $method_name = 'REQUEST' ) {
25
+ $sanitize_function_name = 'sanitize_text_field';
26
+ $method = $_REQUEST;
27
+
28
+ switch ( strtoupper( $method_name ) ) {
29
+ case 'GET':
30
+ $method = $_GET;
31
+ break;
32
+ case 'POST':
33
+ $method = $_POST;
34
+ break;
35
+ case 'REQUEST':
36
+ $method = $_REQUEST;
37
+ break;
38
+ }
39
+
40
+ if ( ! empty( $sanitize ) && is_string( $sanitize ) && $sanitize !== $sanitize_function_name ) {
41
+ $sanitize_function_name = $sanitize;
42
+ }
43
+
44
+ if ( ! function_exists( $sanitize_function_name ) ) {
45
+ throw new Exception( 'Function ' . $sanitize_function_name . 'is undefined.' );
46
+ }
47
+
48
+ if ( ! empty( $param ) ) {
49
+ if ( isset( $method[ $param ] ) && ! empty( $method[ $param ] ) ) {
50
+ if ( is_array( $method[ $param ] ) ) {
51
+ return ! empty( $sanitize ) ? $this->recursiveArrayMap( $sanitize_function_name, $method[ $param ] ) : $method[ $param ];
52
+ } else {
53
+ return ! empty( $sanitize ) ? call_user_func( $sanitize_function_name, $method[ $param ] ) : $method[ $param ];
54
+ }
55
+ }
56
+
57
+ return $default;
58
+ }
59
+
60
+ return ! empty( $sanitize ) ? array_map( $sanitize_function_name, $method ) : $method;
61
+ }
62
+
63
+ /**
64
+ * Recursive sanitation for an array
65
+ *
66
+ * @param string $function_name
67
+ * @param $array
68
+ *
69
+ * @return mixed
70
+ */
71
+ public function recursiveArrayMap( $function_name, $array ) {
72
+ foreach ( $array as $key => &$value ) {
73
+ if ( is_array( $value ) ) {
74
+ $value = $this->recursiveArrayMap( $function_name, $value );
75
+ } else {
76
+ if ( ! function_exists( $function_name ) ) {
77
+ throw new Exception( 'Function ' . $function_name . 'is undefined.' );
78
+ }
79
+
80
+ $value = $function_name( $value );
81
+ }
82
+ }
83
+
84
+ return $array;
85
+ }
86
+
87
+ /**
88
+ * @param bool|string see method getBody
89
+ * @param array $default
90
+ *
91
+ * @return mixed|null
92
+ */
93
+ public function requestAll( $sanitize = false, $default = [] ) {
94
+ return $this->getBody( null, $sanitize, $default );
95
+ }
96
+
97
+ /**
98
+ * @param $param
99
+ * @param bool|string see method getBody
100
+ * @param bool $default
101
+ *
102
+ * @return mixed|null
103
+ */
104
+ public function request( $param, $default = false, $sanitize = false ) {
105
+ return $this->getBody( $param, $sanitize, $default );
106
+ }
107
+
108
+ /**
109
+ * @param bool|string see method getBody
110
+ * @param array $default
111
+ *
112
+ * @return mixed|null
113
+ */
114
+ public function getAll( $sanitize = false, $default = [] ) {
115
+ return $this->getBody( null, $sanitize, $default, 'get' );
116
+ }
117
+
118
+ /**
119
+ * @param null $param
120
+ * @param bool|string see method getBody
121
+ * @param bool $default
122
+ *
123
+ * @return mixed|null
124
+ */
125
+ public function get( $param, $default = false, $sanitize = false ) {
126
+ return $this->getBody( $param, $sanitize, $default, 'get' );
127
+ }
128
+
129
+ /**
130
+ * @param bool|string see method getBody
131
+ * @param array $default
132
+ *
133
+ * @return mixed|null
134
+ */
135
+ public function postAll( $sanitize = false, $default = [] ) {
136
+ return $this->getBody( null, $sanitize, $default, 'post' );
137
+ }
138
+
139
+ /**
140
+ * @param $param
141
+ * @param bool|string see method getBody
142
+ * @param bool $default
143
+ *
144
+ * @return mixed|null
145
+ */
146
+ public function post( $param, $default = false, $sanitize = false ) {
147
+ return $this->getBody( $param, $sanitize, $default, 'post' );
148
+ }
149
+ }
150
+
libs/factory/core/includes/class-factory-requirements.php ADDED
@@ -0,0 +1,293 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Class to check if the current WordPress and PHP versions meet our requirements
5
+ *
6
+ * @see Docs https://webcraftic.atlassian.net/wiki/spaces/FFD/pages/21692485/WFF+Requirements
7
+ *
8
+ * @author Alex Kovalev <alex.kovalevv@gmail.com>, repo: https://github.com/alexkovalevv
9
+ * @author Webcraftic <wordpress.webraftic@gmail.com>, site: https://webcraftic.com
10
+ *
11
+ * @version 2.0.0
12
+ * @since 4.0.9
13
+ */
14
+
15
+ if ( ! class_exists( 'Wbcr_Factory420_Requirements' ) ) {
16
+ class Wbcr_Factory420_Requirements {
17
+
18
+ /**
19
+ * Factory framework version
20
+ *
21
+ * @var string
22
+ */
23
+ protected $factory_version;
24
+
25
+ /**
26
+ * @var string
27
+ */
28
+ protected $plugin_version;
29
+
30
+ /**
31
+ * Plugin file path
32
+ *
33
+ * @var string
34
+ */
35
+ protected $plugin_file;
36
+
37
+ /**
38
+ * Plugin dir
39
+ *
40
+ * @var string
41
+ */
42
+ protected $plugin_abs_path;
43
+
44
+ /**
45
+ * Plugin base dir
46
+ *
47
+ * @var string
48
+ */
49
+ protected $plugin_basename;
50
+
51
+ /**
52
+ * Plugin url
53
+ *
54
+ * @var string
55
+ */
56
+ protected $plugin_url;
57
+
58
+ /**
59
+ * Plugin prefix
60
+ *
61
+ * @var string
62
+ */
63
+ protected $plugin_prefix;
64
+
65
+ /**
66
+ * Plugin name
67
+ *
68
+ * @var string
69
+ */
70
+ protected $plugin_name;
71
+
72
+ /**
73
+ * Plugin title
74
+ *
75
+ * @var string
76
+ */
77
+ protected $plugin_title = "(no title)";
78
+
79
+ /**
80
+ * @var string
81
+ */
82
+ protected $plugin_text_domain;
83
+
84
+ /**
85
+ * Required PHP version
86
+ *
87
+ * @var string
88
+ */
89
+ protected $required_php_version = '5.3';
90
+
91
+ /**
92
+ * Required WordPress version
93
+ *
94
+ * @var string
95
+ */
96
+ protected $required_wp_version = '4.2.0';
97
+
98
+ /**
99
+ * Is this plugin already activated?
100
+ *
101
+ * @var bool
102
+ */
103
+ protected $plugin_already_activate = false;
104
+
105
+ /**
106
+ * WFF_Requirements constructor.
107
+ *
108
+ * @param string $plugin_file
109
+ * @param array $plugin_info
110
+ */
111
+ public function __construct( $plugin_file, array $plugin_info ) {
112
+
113
+ foreach ( (array) $plugin_info as $property => $value ) {
114
+ if ( property_exists( $this, $property ) ) {
115
+ $this->$property = $value;
116
+ }
117
+ }
118
+
119
+ $this->plugin_file = $plugin_file;
120
+ $this->plugin_abs_path = dirname( $plugin_file );
121
+ $this->plugin_basename = plugin_basename( $plugin_file );
122
+ $this->plugin_url = plugins_url( null, $plugin_file );
123
+
124
+ $plugin_info = get_file_data( $this->plugin_file, [
125
+ 'Version' => 'Version',
126
+ 'FrameworkVersion' => 'Framework Version',
127
+ 'TextDomain' => 'Text Domain'
128
+ ], 'plugin' );
129
+
130
+ if ( isset( $plugin_info['FrameworkVersion'] ) ) {
131
+ $this->factory_version = $plugin_info['FrameworkVersion'];
132
+ }
133
+
134
+ if ( isset( $plugin_info['Version'] ) ) {
135
+ $this->plugin_version = $plugin_info['Version'];
136
+ }
137
+
138
+ if ( isset( $plugin_info['TextDomain'] ) ) {
139
+ $this->plugin_text_domain = $plugin_info['TextDomain'];
140
+ }
141
+
142
+ add_action( 'admin_init', [ $this, 'register_notices' ] );
143
+ }
144
+
145
+ public function get_plugin_version() {
146
+ return $this->plugin_version;
147
+ }
148
+
149
+ public function get_text_domain() {
150
+ return $this->plugin_text_domain;
151
+ }
152
+
153
+ /**
154
+ * @since 4.1.1
155
+ * @return void
156
+ */
157
+ public function register_notices() {
158
+ if ( current_user_can( 'activate_plugins' ) && current_user_can( 'edit_plugins' ) && current_user_can( 'install_plugins' ) ) {
159
+
160
+ if ( is_multisite() ) {
161
+ add_action( 'network_admin_notices', [ $this, 'show_notice' ] );
162
+
163
+ if ( ! empty( $this->plugin_basename ) && in_array( $this->plugin_basename, (array) get_option( 'active_plugins', [] ) ) ) {
164
+ add_action( 'admin_notices', [ $this, 'show_notice' ] );
165
+ }
166
+ } else {
167
+ add_action( 'admin_notices', [ $this, 'show_notice' ] );
168
+ }
169
+ }
170
+ }
171
+
172
+ /**
173
+ * Shows the incompatibility notification.
174
+ *
175
+ * @since 4.1.1
176
+ * @return void
177
+ */
178
+ public function show_notice() {
179
+ if ( $this->check() ) {
180
+ return;
181
+ }
182
+
183
+ echo '<div class="notice notice-error"><p>' . $this->get_notice_text() . '</p></div>';
184
+ }
185
+
186
+
187
+ /**
188
+ * The method checks the compatibility of the plugin with php and wordpress version.
189
+ *
190
+ * @since 4.1.1
191
+ * @return bool
192
+ */
193
+ public function check() {
194
+
195
+ // Fix for ithemes sync. When the ithemes sync plugin accepts the request, set the WP_ADMIN constant,
196
+ // after which the plugin Clearfy begins to create errors, and how the logic of its work is broken.
197
+ // Solution to simply terminate the plugin if there is a request from ithemes sync
198
+ // --------------------------------------
199
+ if ( defined( 'DOING_AJAX' ) && DOING_AJAX && isset( $_REQUEST['action'] ) && $_REQUEST['action'] == 'ithemes_sync_request' ) {
200
+ return false;
201
+ }
202
+
203
+ if ( isset( $_GET['ithemes-sync-request'] ) && ! empty( $_GET['ithemes-sync-request'] ) ) {
204
+ return false;
205
+ }
206
+ // ----------------------------------------
207
+
208
+ if ( ! $this->check_php_compat() || ! $this->check_wp_compat() || $this->plugin_already_activate ) {
209
+ return false;
210
+ }
211
+
212
+ return true;
213
+ }
214
+
215
+ /**
216
+ * The method checks the compatibility of the plugin with the php version of the server.
217
+ *
218
+ * @return mixed
219
+ */
220
+ public function check_php_compat() {
221
+ return version_compare( PHP_VERSION, $this->required_php_version, '>=' );
222
+ }
223
+
224
+ /**
225
+ * The method checks the compatibility of the plugin with the Wordpress version of the site.
226
+ *
227
+ * @return mixed
228
+ */
229
+ public function check_wp_compat() {
230
+ // Get the WP Version global.
231
+ global $wp_version;
232
+
233
+ return version_compare( $wp_version, $this->required_wp_version, '>=' );
234
+ }
235
+
236
+ /**
237
+ * Method returns notification text
238
+ *
239
+ * @return string
240
+ */
241
+ protected function get_notice_text() {
242
+ $notice_text = $notice_default_text = '';
243
+ $notice_default_text .= '<b>' . $this->plugin_title . ' ' . __( 'warning', '' ) . ':</b>' . '<br>';
244
+
245
+ $notice_default_text .= sprintf( __( 'The %s plugin has stopped.', 'wbcr_factory_clearfy_212' ), $this->plugin_title ) . ' ';
246
+ $notice_default_text .= __( 'Possible reasons:', '' ) . ' <br>';
247
+
248
+ $has_one = false;
249
+
250
+ if ( ! $this->check_php_compat() ) {
251
+ $has_one = true;
252
+ $notice_text .= '- ' . $this->get_php_incompat_text() . '<br>';
253
+ }
254
+
255
+ if ( ! $this->check_wp_compat() ) {
256
+ $has_one = true;
257
+ $notice_text .= '- ' . $this->get_wp_incompat_text() . '<br>';
258
+ }
259
+
260
+ if ( $this->plugin_already_activate ) {
261
+ $has_one = true;
262
+ $notice_text = '- ' . $this->get_plugin_already_activate_text() . '<br>';
263
+ }
264
+
265
+ if ( $has_one ) {
266
+ $notice_text = $notice_default_text . $notice_text;
267
+ }
268
+
269
+ return $notice_text;
270
+ }
271
+
272
+ /**
273
+ * @return string
274
+ */
275
+ protected function get_php_incompat_text() {
276
+ return sprintf( __( 'You need to update the PHP version to %s or higher!', 'wbcr_factory_420' ), $this->required_php_version );
277
+ }
278
+
279
+ /**
280
+ * @return string
281
+ */
282
+ protected function get_wp_incompat_text() {
283
+ return sprintf( __( 'You need to update WordPress to %s or higher!', 'wbcr_factory_420' ), $this->required_wp_version );
284
+ }
285
+
286
+ /**
287
+ * @return string
288
+ */
289
+ protected function get_plugin_already_activate_text() {
290
+ return sprintf( __( 'Plugin %s is already activated, you are trying to activate it again.', 'wbcr_factory_420' ), $this->plugin_title );
291
+ }
292
+ }
293
+ }
libs/factory/core/includes/entities/class-factory-paths.php ADDED
@@ -0,0 +1,33 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace WBCR\Factory_420\Entities;
4
+
5
+ if ( ! defined( 'ABSPATH' ) ) {
6
+ exit;
7
+ }
8
+
9
+ /*
10
+ * @author Alex Kovalev <alex.kovalevv@gmail.com>, repo: https://github.com/alexkovalevv
11
+ * @author Webcraftic <wordpress.webraftic@gmail.com>, site: https://webcraftic.com
12
+ * @since 4.1.1
13
+ */
14
+
15
+ class Paths {
16
+
17
+ public $absolute;
18
+ public $main_file;
19
+ public $relative;
20
+ public $url;
21
+
22
+ protected $plugin_path;
23
+
24
+ public function __construct( $plugin_file ) {
25
+ $this->plugin_path = $plugin_file;
26
+
27
+ $this->main_file = $plugin_file;
28
+ $this->absolute = dirname( $plugin_file );
29
+ $this->basename = plugin_basename( $plugin_file );
30
+ $this->url = plugins_url( null, $plugin_file );
31
+ $this->migrations = $this->absolute . '/migrations';
32
+ }
33
+ }
libs/factory/core/includes/entities/class-factory-support.php ADDED
@@ -0,0 +1,124 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace WBCR\Factory_420\Entities;
4
+
5
+ if ( ! defined( 'ABSPATH' ) ) {
6
+ exit;
7
+ }
8
+
9
+ /*
10
+ * @author Alex Kovalev <alex.kovalevv@gmail.com>, repo: https://github.com/alexkovalevv
11
+ * @author Webcraftic <wordpress.webraftic@gmail.com>, site: https://webcraftic.com
12
+ * @since 4.1.1
13
+ */
14
+
15
+ class Support {
16
+
17
+ protected $plugin_name;
18
+ protected $site_url;
19
+
20
+ protected $features_page_slug = 'premium-features';
21
+ protected $pricing_page_slug = 'pricing';
22
+ protected $support_page_slug = 'support';
23
+ protected $docs_page_slug = 'docs';
24
+
25
+ /**
26
+ * Plugin_Site constructor.
27
+ *
28
+ * @param array $data
29
+ */
30
+ public function __construct( array $data ) {
31
+ $this->site_url = isset( $data['url'] ) ? $data['url'] : null;
32
+
33
+ if ( isset( $data['pages_map'] ) && is_array( $data['pages_map'] ) ) {
34
+ foreach ( $data['pages_map'] as $key => $def_value ) {
35
+ $attr = $key . '_page_slug';
36
+ $this->{$attr} = isset( $data[ $key ] ) ? $data[ $key ] : $def_value;
37
+ }
38
+ }
39
+ }
40
+
41
+ /**
42
+ * @return string
43
+ */
44
+ public function get_site_url( $track = false, $utm_content = null ) {
45
+ if ( $track ) {
46
+ return $this->get_tracking_page_url( $this->site_url, $utm_content );
47
+ }
48
+
49
+ return $this->site_url;
50
+ }
51
+
52
+
53
+ /**
54
+ * @return string
55
+ */
56
+ public function get_features_url( $track = false, $utm_content = null ) {
57
+ if ( $track ) {
58
+ return $this->get_tracking_page_url( $this->features_page_slug, $utm_content );
59
+ }
60
+
61
+ return $this->get_site_url() . '/' . $this->features_page_slug;
62
+ }
63
+
64
+
65
+ /**
66
+ * @return string
67
+ */
68
+ public function get_pricing_url( $track = false, $utm_content = null ) {
69
+ if ( $track ) {
70
+ return $this->get_tracking_page_url( $this->pricing_page_slug, $utm_content );
71
+ }
72
+
73
+ return $this->get_site_url() . '/' . $this->pricing_page_slug;
74
+ }
75
+
76
+
77
+ /**
78
+ * @return string
79
+ */
80
+ public function get_contacts_url( $track = false, $utm_content = null ) {
81
+ if ( $track ) {
82
+ return $this->get_tracking_page_url( $this->support_page_slug, $utm_content );
83
+ }
84
+
85
+ return $this->get_site_url() . '/' . $this->support_page_slug;
86
+ }
87
+
88
+
89
+ /**
90
+ * @return string
91
+ */
92
+ public function get_docs_url( $track = false, $utm_content = null ) {
93
+ if ( $track ) {
94
+ return $this->get_tracking_page_url( $this->docs_page_slug, $utm_content );
95
+ }
96
+
97
+ return $this->get_site_url() . '/' . $this->docs_page_slug;
98
+ }
99
+
100
+
101
+ /**
102
+ * @param null $page
103
+ * @param null $utm_content
104
+ * @param string $urm_source
105
+ *
106
+ * @return string
107
+ */
108
+ public function get_tracking_page_url( $page = null, $utm_content = null, $urm_source = 'wordpress.org' ) {
109
+
110
+ $args = [ 'utm_source' => $urm_source ];
111
+
112
+ if ( ! empty( $plugin_name ) ) {
113
+ $args['utm_campaign'] = $plugin_name;
114
+ }
115
+
116
+ if ( ! empty( $utm_content ) ) {
117
+ $args['utm_content'] = $utm_content;
118
+ }
119
+
120
+ $raw_url = add_query_arg( $args, $this->get_site_url() . '/' . $page . '/' );
121
+
122
+ return esc_url( $raw_url );
123
+ }
124
+ }
libs/factory/core/includes/functions.php CHANGED
@@ -1,169 +1,205 @@
1
  <?php
2
- /**
3
- * Factory Function Library
4
- *
5
- * @author Alex Kovalev <alex.kovalevv@gmail.com>
6
- * @copyright (c) 2018, Webcraftic Ltd
7
- *
8
- * @package factory-core
9
- * @since 1.0.0
10
- */
11
-
12
- // Exit if accessed directly
13
- if( !defined('ABSPATH') ) {
14
- exit;
15
- }
16
-
17
- if( function_exists('wbcr_factory_400_set_lazy_redirect') ) {
18
- /**
19
- * Sets a lazy redirect.
20
- *
21
- * @since 3.0.6
22
- * @return void
23
- */
24
- function wbcr_factory_400_set_lazy_redirect($url)
25
- {
26
- update_option('wbcr_factory_400_lazy_redirect', $url);
27
  }
28
- }
29
-
30
- if( function_exists('wbcr_factory_400_do_lazy_redirect') ) {
31
- function wbcr_factory_400_do_lazy_redirect()
32
- {
33
- $url = get_option('wbcr_factory_400_lazy_redirect', null);
34
-
35
- if( empty($url) ) {
36
- return;
37
- }
38
-
39
- delete_option('wbcr_factory_400_lazy_redirect');
40
- wp_redirect($url);
41
  }
42
-
43
- add_action('admin_init', 'wbcr_factory_400_do_lazy_redirect');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
44
  }
45
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
46
  /**
47
- * Fires functions attached to a deprecated filter hook.
48
- *
49
- * When a filter hook is deprecated, the apply_filters() call is replaced with
50
- * apply_filters_deprecated(), which triggers a deprecation notice and then fires
51
- * the original filter hook.
52
- *
53
- * This is a copy of `apply_filters_deprecated` introduced in WP 4.6.
54
  *
55
  * @since 1.0.0
56
  *
57
- * @see wbcr_factory_400_deprecated_hook()
58
- *
59
- * @param string $tag The name of the filter hook.
60
- * @param array $args Array of additional function arguments to be passed to apply_filters().
61
- * @param string $version The version of BP Block Users that deprecated the hook.
62
- * @param string $replacement Optional. The hook that should have been used.
63
- * @param string $message Optional. A message regarding the change.
64
- *
65
- * @return mixed
66
  */
67
- function wbcr_factory_400_apply_filters_deprecated($tag, $args, $version, $replacement = false, $message = null)
68
- {
69
- if( function_exists('apply_filters_deprecated') ) {
70
- return apply_filters_deprecated($tag, $args, $version, $replacement, $message);
71
- }
72
- if( !has_filter($tag) ) {
73
- return $args[0];
74
- }
75
- wbcr_factory_400_deprecated_hook($tag, $version, $replacement, $message);
76
-
77
- return apply_filters_ref_array($tag, $args);
78
- }
79
-
80
  /**
81
- * Fires functions attached to a deprecated action hook.
82
- *
83
- * When an action hook is deprecated, the do_action() call is replaced with
84
- * do_action_deprecated(), which triggers a deprecation notice and then fires
85
- * the original hook.
86
- *
87
- * This is a copy of `do_action_deprecated` introduced in WP 4.6.
88
  *
89
  * @since 1.0.0
90
  *
91
- * @see _deprecated_hook()
92
- *
93
- * @param string $tag The name of the action hook.
94
- * @param array $args Array of additional function arguments to be passed to do_action().
95
- * @param string $version The version of BP Block Users that deprecated the hook.
96
- * @param string $replacement Optional. The hook that should have been used.
97
- * @param string $message Optional. A message regarding the change.
98
- *
99
- * @return void
100
  */
101
- function wbcr_factory_400_do_action_deprecated($tag, $args, $version, $replacement = false, $message = null)
102
- {
103
- if( function_exists('do_action_deprecated') ) {
104
- do_action_deprecated($tag, $args, $version, $replacement, $message);
105
-
106
- return;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
107
  }
108
- if( !has_action($tag) ) {
109
- return;
 
 
110
  }
111
- wbcr_factory_400_deprecated_hook($tag, $version, $replacement, $message);
112
- do_action_ref_array($tag, $args);
113
  }
114
-
115
- /**
116
- * Marks a deprecated action or filter hook as deprecated and throws a notice.
117
- *
118
- * Use the 'wbcr_factory_400_deprecated_hook_run' action to get the backtrace describing where the
119
- * deprecated hook was called.
120
- *
121
- * Default behavior is to trigger a user error if WP_DEBUG is true.
122
- *
123
- * This function is called by the do_action_deprecated() and apply_filters_deprecated()
124
- * functions, and so generally does not need to be called directly.
125
- *
126
- * This is a copy of `_deprecated_hook` introduced in WP 4.6.
127
- *
128
- * @since 1.0.0
129
- * @access private
130
- *
131
- * @param string $hook The hook that was used.
132
- * @param string $version The version of WordPress that deprecated the hook.
133
- * @param string $replacement Optional. The hook that should have been used.
134
- * @param string $message Optional. A message regarding the change.
135
- */
136
- function wbcr_factory_400_deprecated_hook($hook, $version, $replacement = null, $message = null)
137
- {
138
- /**
139
- * Fires when a deprecated hook is called.
140
- *
141
- * @since 1.0.0
142
- *
143
- * @param string $hook The hook that was called.
144
- * @param string $replacement The hook that should be used as a replacement.
145
- * @param string $version The version of BP Block Users that deprecated the argument used.
146
- * @param string $message A message regarding the change.
147
- */
148
- do_action('deprecated_hook_run', $hook, $replacement, $version, $message);
149
 
150
  /**
151
- * Filter whether to trigger deprecated hook errors.
152
  *
153
- * @since 1.0.0
154
  *
155
- * @param bool $trigger Whether to trigger deprecated hook errors. Requires
156
- * `WP_DEBUG` to be defined true.
157
  */
158
- if( WP_DEBUG && apply_filters('deprecated_hook_trigger_error', true) ) {
159
- $message = empty($message)
160
- ? ''
161
- : ' ' . $message;
162
- if( !is_null($replacement) ) {
163
- trigger_error(sprintf(__('%1$s is <strong>deprecated</strong> since version %2$s! Use %3$s instead.'), $hook, $version, $replacement) . $message);
164
- } else {
165
- trigger_error(sprintf(__('%1$s is <strong>deprecated</strong> since version %2$s with no alternative available.'), $hook, $version) . $message);
166
- }
167
- }
168
  }
169
-
1
  <?php
2
+ /**
3
+ * Factory Function Library
4
+ *
5
+ * @author Alex Kovalev <alex.kovalevv@gmail.com>, repo: https://github.com/alexkovalevv
6
+ * @author Webcraftic <wordpress.webraftic@gmail.com>, site: https://webcraftic.com
7
+ *
8
+ * @package factory-core
9
+ * @since 1.0.0
10
+ */
11
+
12
+ // Exit if accessed directly
13
+ if ( ! defined( 'ABSPATH' ) ) {
14
+ exit;
15
+ }
16
+
17
+ if ( ! function_exists( 'get_user_locale' ) ) {
18
+ function get_user_locale( $user_id = 0 ) {
19
+ $user = false;
20
+ if ( 0 === $user_id && function_exists( 'wp_get_current_user' ) ) {
21
+ $user = wp_get_current_user();
22
+ } else if ( $user_id instanceof WP_User ) {
23
+ $user = $user_id;
24
+ } else if ( $user_id && is_numeric( $user_id ) ) {
25
+ $user = get_user_by( 'id', $user_id );
 
26
  }
27
+
28
+ if ( ! $user ) {
29
+ return get_locale();
 
 
 
 
 
 
 
 
 
 
30
  }
31
+
32
+ $locale = $user->locale;
33
+
34
+ return $locale ? $locale : get_locale();
35
+ }
36
+ }
37
+
38
+ /**
39
+ * Fires functions attached to a deprecated filter hook.
40
+ *
41
+ * When a filter hook is deprecated, the apply_filters() call is replaced with
42
+ * apply_filters_deprecated(), which triggers a deprecation notice and then fires
43
+ * the original filter hook.
44
+ *
45
+ * This is a copy of `apply_filters_deprecated` introduced in WP 4.6.
46
+ *
47
+ * @since 1.0.0
48
+ *
49
+ * @param string $tag The name of the filter hook.
50
+ * @param array $args Array of additional function arguments to be passed to apply_filters().
51
+ * @param string $version The version of BP Block Users that deprecated the hook.
52
+ * @param string $replacement Optional. The hook that should have been used.
53
+ * @param string $message Optional. A message regarding the change.
54
+ *
55
+ * @return mixed
56
+ * @see wbcr_factory_420_deprecated_hook()
57
+ *
58
+ */
59
+ function wbcr_factory_420_apply_filters_deprecated( $tag, $args, $version, $replacement = false, $message = null ) {
60
+ if ( function_exists( 'apply_filters_deprecated' ) ) {
61
+ return apply_filters_deprecated( $tag, $args, $version, $replacement, $message );
62
+ }
63
+ if ( ! has_filter( $tag ) ) {
64
+ return $args[0];
65
+ }
66
+ wbcr_factory_420_deprecated_hook( $tag, $version, $replacement, $message );
67
+
68
+ return apply_filters_ref_array( $tag, $args );
69
+ }
70
+
71
+ /**
72
+ * Fires functions attached to a deprecated action hook.
73
+ *
74
+ * When an action hook is deprecated, the do_action() call is replaced with
75
+ * do_action_deprecated(), which triggers a deprecation notice and then fires
76
+ * the original hook.
77
+ *
78
+ * This is a copy of `do_action_deprecated` introduced in WP 4.6.
79
+ *
80
+ * @since 1.0.0
81
+ *
82
+ * @param string $tag The name of the action hook.
83
+ * @param array $args Array of additional function arguments to be passed to do_action().
84
+ * @param string $version The version of BP Block Users that deprecated the hook.
85
+ * @param string $replacement Optional. The hook that should have been used.
86
+ * @param string $message Optional. A message regarding the change.
87
+ *
88
+ * @return void
89
+ * @see _deprecated_hook()
90
+ *
91
+ */
92
+ function wbcr_factory_420_do_action_deprecated( $tag, $args, $version, $replacement = false, $message = null ) {
93
+ if ( function_exists( 'do_action_deprecated' ) ) {
94
+ do_action_deprecated( $tag, $args, $version, $replacement, $message );
95
+
96
+ return;
97
  }
98
+ if ( ! has_action( $tag ) ) {
99
+ return;
100
+ }
101
+ wbcr_factory_420_deprecated_hook( $tag, $version, $replacement, $message );
102
+ do_action_ref_array( $tag, $args );
103
+ }
104
+
105
+ /**
106
+ * Marks a deprecated action or filter hook as deprecated and throws a notice.
107
+ *
108
+ * Use the 'wbcr_factory_420_deprecated_hook_run' action to get the backtrace describing where the
109
+ * deprecated hook was called.
110
+ *
111
+ * Default behavior is to trigger a user error if WP_DEBUG is true.
112
+ *
113
+ * This function is called by the do_action_deprecated() and apply_filters_deprecated()
114
+ * functions, and so generally does not need to be called directly.
115
+ *
116
+ * This is a copy of `_deprecated_hook` introduced in WP 4.6.
117
+ *
118
+ * @since 1.0.0
119
+ * @access private
120
+ *
121
+ * @param string $hook The hook that was used.
122
+ * @param string $version The version of WordPress that deprecated the hook.
123
+ * @param string $replacement Optional. The hook that should have been used.
124
+ * @param string $message Optional. A message regarding the change.
125
+ */
126
+ function wbcr_factory_420_deprecated_hook( $hook, $version, $replacement = null, $message = null ) {
127
  /**
128
+ * Fires when a deprecated hook is called.
 
 
 
 
 
 
129
  *
130
  * @since 1.0.0
131
  *
132
+ * @param string $hook The hook that was called.
133
+ * @param string $replacement The hook that should be used as a replacement.
134
+ * @param string $version The version of BP Block Users that deprecated the argument used.
135
+ * @param string $message A message regarding the change.
 
 
 
 
 
136
  */
137
+ do_action( 'deprecated_hook_run', $hook, $replacement, $version, $message );
138
+
 
 
 
 
 
 
 
 
 
 
 
139
  /**
140
+ * Filter whether to trigger deprecated hook errors.
 
 
 
 
 
 
141
  *
142
  * @since 1.0.0
143
  *
144
+ * @param bool $trigger Whether to trigger deprecated hook errors. Requires
145
+ * `WP_DEBUG` to be defined true.
 
 
 
 
 
 
 
146
  */
147
+ if ( WP_DEBUG && apply_filters( 'deprecated_hook_trigger_error', true ) ) {
148
+ $message = empty( $message ) ? '' : ' ' . $message;
149
+ if ( ! is_null( $replacement ) ) {
150
+ trigger_error( sprintf( __( '%1$s is <strong>deprecated</strong> since version %2$s! Use %3$s instead.' ), $hook, $version, $replacement ) . $message );
151
+ } else {
152
+ trigger_error( sprintf( __( '%1$s is <strong>deprecated</strong> since version %2$s with no alternative available.' ), $hook, $version ) . $message );
153
+ }
154
+ }
155
+ }
156
+
157
+ if ( ! function_exists( '_sanitize_text_fields' ) ) {
158
+ function _sanitize_text_fields( $str, $keep_newlines = false ) {
159
+ $filtered = wp_check_invalid_utf8( $str );
160
+
161
+ if ( strpos( $filtered, '<' ) !== false ) {
162
+ $filtered = wp_pre_kses_less_than( $filtered );
163
+ // This will strip extra whitespace for us.
164
+ $filtered = wp_strip_all_tags( $filtered, false );
165
+
166
+ // Use html entities in a special case to make sure no later
167
+ // newline stripping stage could lead to a functional tag
168
+ $filtered = str_replace( "<\n", "&lt;\n", $filtered );
169
+ }
170
+
171
+ if ( ! $keep_newlines ) {
172
+ $filtered = preg_replace( '/[\r\n\t ]+/', ' ', $filtered );
173
+ }
174
+ $filtered = trim( $filtered );
175
+
176
+ $found = false;
177
+ while( preg_match( '/%[a-f0-9]{2}/i', $filtered, $match ) ) {
178
+ $filtered = str_replace( $match[0], '', $filtered );
179
+ $found = true;
180
  }
181
+
182
+ if ( $found ) {
183
+ // Strip out the whitespace that may now exist after removing the octets.
184
+ $filtered = trim( preg_replace( '/ +/', ' ', $filtered ) );
185
  }
186
+
187
+ return $filtered;
188
  }
189
+ }
190
+
191
+ if ( ! function_exists( 'sanitize_textarea_field' ) ) {
192
+ function sanitize_textarea_field( $str ) {
193
+ $filtered = _sanitize_text_fields( $str, true );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
194
 
195
  /**
196
+ * Filters a sanitized textarea field string.
197
  *
198
+ * @since 4.7.0
199
  *
200
+ * @param string $filtered The sanitized string.
201
+ * @param string $str The string prior to being sanitized.
202
  */
203
+ return apply_filters( 'sanitize_textarea_field', $filtered, $str );
 
 
 
 
 
 
 
 
 
204
  }
205
+ }
libs/factory/core/includes/index.php ADDED
@@ -0,0 +1,2 @@
 
 
1
+ <?php
2
+ // Silence is golden.
libs/factory/core/includes/plugin.class.php DELETED
@@ -1,833 +0,0 @@
1
- <?php
2
- /**
3
- * The file contains the class to register a plugin in the Factory.
4
- *
5
- * @author Alex Kovalev <alex.kovalevv@gmail.com>
6
- * @copyright (c) 2018, Webcraftic Ltd
7
- *
8
- * @package factory-core
9
- * @since 1.0.0
10
- */
11
-
12
- // Exit if accessed directly
13
- if( !defined('ABSPATH') ) {
14
- exit;
15
- }
16
-
17
- if( !class_exists('Wbcr_Factory400_Plugin') ) {
18
-
19
- abstract class Wbcr_Factory400_Plugin extends Wbcr_Factory400_Base {
20
-
21
- /**
22
- * Is a current page one of the admin pages?
23
- *
24
- * @since 1.0.0
25
- * @var bool
26
- */
27
- public $is_admin;
28
-
29
- /**
30
- * The Bootstrap Manager class.n.
31
- *
32
- * @var Wbcr_FactoryBootstrap400_Manager
33
- */
34
- public $bootstrap;
35
-
36
- /**
37
- * The Bootstrap Manager class.n.
38
- *
39
- * @var Wbcr_FactoryForms400_Manager
40
- */
41
- public $forms;
42
-
43
- /**
44
- * @var string
45
- */
46
- protected $plugin_title;
47
-
48
- /**
49
- * @var string
50
- */
51
- protected $plugin_name;
52
-
53
- /**
54
- * @var string
55
- */
56
- protected $plugin_version;
57
-
58
- /**
59
- * @var string
60
- */
61
- protected $plugin_build;
62
-
63
- /**
64
- * @var string
65
- */
66
- protected $plugin_assembly;
67
-
68
- /**
69
- * @var string
70
- */
71
- protected $main_file;
72
-
73
- /**
74
- * @var string
75
- */
76
- protected $plugin_root;
77
-
78
- /**
79
- * @var string
80
- */
81
- protected $relative_path;
82
-
83
- /**
84
- * @var string
85
- */
86
- protected $plugin_url;
87
-
88
- /**
89
- * A class name of an activator to activate the plugin.
90
- *
91
- * @var string
92
- */
93
- protected $activator_class = array();
94
-
95
- /**
96
- * @var string
97
- */
98
- protected $updates;
99
-
100
- /**
101
- * @var array[] Wbcr_Factory400_Plugin
102
- */
103
- private $plugin_addons;
104
-
105
- /**
106
- * @var array
107
- */
108
- private $plugin_data;
109
-
110
- /**
111
- * Creates an instance of Factory plugin.
112
- *
113
- * @param string $plugin_path A full path to the main plugin file.
114
- * @param array $data A set of plugin data.
115
- * @since 1.0.0
116
- * @throws Exception
117
- */
118
- public function __construct($plugin_path, $data)
119
- {
120
- $this->plugin_data = $data;
121
-
122
- parent::__construct($plugin_path, $data);
123
-
124
- foreach((array)$data as $option_name => $option_value) {
125
- if( !isset($this->$option_name) ) {
126
- $this->$option_name = $option_value;
127
- }
128
- }
129
-
130
- $this->is_admin = is_admin();
131
-
132
- if( empty($this->prefix) || empty($this->plugin_title) || empty($this->plugin_version) || empty($this->plugin_build) ) {
133
- throw new Exception('One of the required attributes has not been passed (prefix,plugin_title,plugin_name,plugin_version,plugin_build).');
134
- }
135
-
136
- // saves plugin basic paramaters
137
- $this->main_file = $plugin_path;
138
- $this->plugin_root = dirname($plugin_path);
139
- $this->relative_path = plugin_basename($plugin_path);
140
- $this->plugin_url = plugins_url(null, $plugin_path);
141
-
142
- // used only in the module 'updates'
143
- $this->plugin_slug = !empty($this->plugin_name)
144
- ? $this->plugin_name
145
- : basename($plugin_path);
146
-
147
- // init actions
148
- $this->setupActions();
149
-
150
- // register activation hooks
151
- if( is_admin() ) {
152
- register_activation_hook($this->main_file, array($this, 'forceActivationHook'));
153
- register_deactivation_hook($this->main_file, array($this, 'deactivationHook'));
154
- }
155
- }
156
-
157
- /**
158
- * @return string
159
- */
160
- public function getPluginTitle()
161
- {
162
- return $this->plugin_title;
163
- }
164
-
165
- /**
166
- * @return string
167
- */
168
- public function getPrefix()
169
- {
170
- return $this->prefix;
171
- }
172
-
173
- /**
174
- * @return string
175
- */
176
- public function getPluginName()
177
- {
178
- return $this->plugin_name;
179
- }
180
-
181
- /**
182
- * @return string
183
- */
184
- public function getPluginVersion()
185
- {
186
- return $this->plugin_version;
187
- }
188
-
189
- /**
190
- * @return string
191
- */
192
- public function getPluginBuild()
193
- {
194
- return $this->plugin_build;
195
- }
196
-
197
- /**
198
- * @return string
199
- */
200
- public function getPluginAssembly()
201
- {
202
- return $this->plugin_assembly;
203
- }
204
-
205
- /**
206
- * @return stdClass
207
- */
208
- public function getPluginPathInfo()
209
- {
210
-
211
- $object = new stdClass;
212
-
213
- $object->main_file = $this->main_file;
214
- $object->plugin_root = $this->plugin_root;
215
- $object->relative_path = $this->relative_path;
216
- $object->plugin_url = $this->plugin_url;
217
-
218
- return $object;
219
- }
220
-
221
- /**
222
- * @param Wbcr_FactoryBootstrap400_Manager $bootstrap
223
- */
224
- public function setBootstap(Wbcr_FactoryBootstrap400_Manager $bootstrap)
225
- {
226
- $this->bootstrap = $bootstrap;
227
- }
228
-
229
- /**
230
- * @param Wbcr_FactoryForms400_Manager $forms
231
- */
232
- public function setForms(Wbcr_FactoryForms400_Manager $forms)
233
- {
234
- $this->forms = $forms;
235
- }
236
-
237
- //protected abstract function setTextDomain();
238
-
239
- //protected abstract function setModules();
240
-
241
- /**
242
- * @param string $class_name
243
- * @param string $path
244
- */
245
- public function registerPage($class_name, $file_path)
246
- {
247
-
248
- if( !file_exists($file_path) ) {
249
- throw new Exception('The page file was not found by the path {' . $file_path . '} you set.');
250
- }
251
-
252
- require_once($file_path);
253
-
254
- if( !class_exists($class_name) ) {
255
- throw new Exception('A class with this name {' . $class_name . '} does not exist.');
256
- }
257
- Wbcr_FactoryPages401::register($this, $class_name);
258
- }
259
-
260
- /**
261
- * @param string $class_name
262
- * @param string $path
263
- */
264
- public function registerType($class_name, $file_path)
265
- {
266
-
267
- if( !file_exists($file_path) ) {
268
- throw new Exception('The page file was not found by the path {' . $file_path . '} you set.');
269
- }
270
-
271
- require_once($file_path);
272
-
273
- if( !class_exists($class_name) ) {
274
- throw new Exception('A class with this name {' . $class_name . '} does not exist.');
275
- }
276
-
277
- Wbcr_FactoryTypes000::register($class_name, $this);
278
- }
279
-
280
- /**
281
- * Loads modules required for a plugin.
282
- *
283
- * @since 3.2.0
284
- * @param mixed[] $modules
285
- * @return void
286
- */
287
- protected function load($modules = array())
288
- {
289
- foreach($modules as $module) {
290
- $this->loadModule($module);
291
- }
292
-
293
- do_action('wbcr_factory_400_core_modules_loaded-' . $this->plugin_name);
294
- }
295
-
296
- /**
297
- * Loads add-ons for the plugin.
298
- */
299
- protected function loadAddons($addons)
300
- {
301
- if( empty($addons) ) {
302
- return;
303
- }
304
-
305
- foreach($addons as $addon_name => $addon_path) {
306
- if( !isset($this->plugin_addons[$addon_name]) ) {
307
- $const_name = strtoupper('LOADING_' . $addon_name . '_AS_ADDON');
308
-
309
- if( !defined($const_name) ) {
310
- define($const_name, true);
311
- }
312
- require_once($addon_path[1]);
313
-
314
- $plugin_data = $this->plugin_data;
315
- $plugin_data['as_addon'] = true;
316
- $plugin_data['plugin_parent'] = $this;
317
-
318
- $this->plugin_addons[$addon_name] = new $addon_path[0]($this->main_file, $plugin_data);
319
- }
320
- }
321
- }
322
-
323
- /**
324
- * Loads a specified module.
325
- *
326
- * @since 3.2.0
327
- * @param string $modulePath
328
- * @param string $moduleVersion
329
- * @return void
330
- */
331
- protected function loadModule($module)
332
- {
333
- $scope = isset($module[2])
334
- ? $module[2]
335
- : 'all';
336
-
337
- if( $scope == 'all' || (is_admin() && $scope == 'admin') || (!is_admin() && $scope == 'public') ) {
338
-
339
- require $this->plugin_root . '/' . $module[0] . '/boot.php';
340
- do_action('wbcr_' . $module[1] . '_plugin_created', $this);
341
- }
342
- }
343
-
344
- /**
345
- * Registers a class to activate the plugin.
346
- *
347
- * @since 1.0.0
348
- * @param string $className class name of the plugin activator.
349
- * @return void
350
- */
351
- public function registerActivation($className)
352
- {
353
- $this->activator_class[] = $className;
354
- }
355
-
356
- /**
357
- * Setups actions related with the Factory Plugin.
358
- *
359
- * @since 1.0.0
360
- */
361
- private function setupActions()
362
- {
363
- add_action('init', array($this, 'checkPluginVersioninDatabase'));
364
-
365
- if( $this->is_admin ) {
366
- add_action('admin_init', array($this, 'customizePluginRow'), 20);
367
- /*add_action('wbcr_factory_400_core_modules_loaded-' . $this->plugin_name, array(
368
- $this,
369
- 'modulesLoaded'
370
- ));*/
371
- }
372
- }
373
-
374
- /**
375
- * Checks the plugin version in database. If it's not the same as the currernt,
376
- * it means that the plugin was updated and we need to execute the update hook.
377
- *
378
- * Calls on the hook "plugins_loaded".
379
- *
380
- * @since 1.0.0
381
- * @return void
382
- */
383
- public function checkPluginVersioninDatabase()
384
- {
385
-
386
- // checks whether the plugin needs to run updates.
387
- if( $this->is_admin ) {
388
- $plugin_version = $this->getPluginVersionFromDatabase();
389
-
390
- if( $plugin_version != $this->plugin_build . '-' . $this->plugin_version ) {
391
- $this->activationOrUpdateHook(false);
392
- }
393
- }
394
- }
395
-
396
- /**
397
- * Returns the plugin version from database.
398
- *
399
- * @since 1.0.0
400
- * @return string|null The plugin version registered in the database.
401
- */
402
- public function getPluginVersionFromDatabase()
403
- {
404
- $plugin_versions = get_option('factory_plugin_versions', array());
405
- $plugin_version = isset ($plugin_versions[$this->plugin_name])
406
- ? $plugin_versions[$this->plugin_name]
407
- : null;
408
-
409
- return $plugin_version;
410
- }
411
-
412
- /**
413
- * Registers in the database a new version of the plugin.
414
- *
415
- * @since 1.0.0
416
- * @return void
417
- */
418
- public function updatePluginVersionInDatabase()
419
- {
420
- $plugin_versions = get_option('factory_plugin_versions', array());
421
- $plugin_versions[$this->plugin_name] = $this->plugin_build . '-' . $this->plugin_version;
422
- update_option('factory_plugin_versions', $plugin_versions);
423
- }
424
-
425
- /**
426
- * Customize the plugin row (on the page plugins.php).
427
- *
428
- * Calls on the hook "admin_init".
429
- *
430
- * @since 1.0.0
431
- * @return void
432
- */
433
- public function customizePluginRow()
434
- {
435
- remove_action("after_plugin_row_" . $this->relative_path, 'wp_plugin_update_row');
436
- add_action("after_plugin_row_" . $this->relative_path, array($this, 'showCustomPluginRow'), 10, 2);
437
- }
438
-
439
- public function activate()
440
- {
441
- $this->forceActivationHook();
442
- }
443
-
444
- public function deactivate()
445
- {
446
- $this->deactivationHook();
447
- }
448
-
449
- /**
450
- * Executes an activation hook for this plugin immediately.
451
- *
452
- * @since 1.0.0
453
- * @return void
454
- */
455
- public function forceActivationHook()
456
- {
457
- $this->activationOrUpdateHook(true);
458
- }
459
-
460
- /**
461
- * Executes an activation hook or an update hook.
462
- *
463
- * @param bool $forceActivation If true, then executes an activation hook.
464
- * @since 1.0.0
465
- * @return void
466
- */
467
- public function activationOrUpdateHook($force_activation = false)
468
- {
469
-
470
- $db_version = $this->getPluginVersionFromDatabase();
471
- do_action('wbcr_factory_400_plugin_activation_or_update_' . $this->plugin_name, $force_activation, $db_version, $this);
472
-
473
- // there are not any previous version of the plugin in the past
474
- if( !$db_version ) {
475
- $this->activationHook();
476
-
477
- $this->updatePluginVersionInDatabase();
478
-
479
- return;
480
- }
481
-
482
- $parts = explode('-', $db_version);
483
- $prevous_build = $parts[0];
484
- $prevous_version = $parts[1];
485
-
486
- // if another build was used previously
487
- if( $prevous_build != $this->plugin_build ) {
488
- $this->migrationHook($prevous_build, $this->plugin_build);
489
- $this->activationHook();
490
-
491
- $this->updatePluginVersionInDatabase();
492
-
493
- return;
494
- }
495
-
496
- // if another less version was used previously
497
- if( version_compare($prevous_version, $this->plugin_version, '<') ) {
498
- $this->updateHook($prevous_version, $this->plugin_version);
499
- }
500
-
501
- // standart plugin activation
502
- if( $force_activation ) {
503
- $this->activationHook();
504
- }
505
-
506
- // else nothing to do
507
- $this->updatePluginVersionInDatabase();
508
-
509
- return;
510
- }
511
-
512
- /**
513
- * It's invoked on plugin activation. Don't excite it directly.
514
- *
515
- * @since 1.0.0
516
- * @return void
517
- */
518
- public function activationHook()
519
- {
520
- $cancelled = apply_filters('wbcr_factory_400_cancel_plugin_activation_' . $this->plugin_name, false);
521
-
522
- if( $cancelled ) {
523
- return;
524
- }
525
-
526
- if( !empty($this->activator_class) ) {
527
- foreach((array)$this->activator_class as $activator_class) {
528
- $activator = new $activator_class($this);
529
- $activator->activate();
530
- }
531
- }
532
-
533
- do_action('wbcr_factory_400_plugin_activation', $this);
534
- do_action('wbcr_factory_400_plugin_activation_' . $this->plugin_name, $this);
535
-
536
- // just time to know when the plugin was activated the first time
537
- $activated = $this->getOption('factory_400_plugin_activated_' . $this->plugin_name, 0);
538
-
539
- if( !$activated ) {
540
- $this->updateOption('factory_400_plugin_activated_' . $this->plugin_name, time());
541
- }
542
- }
543
-
544
- /**
545
- * It's invoked on plugin deactionvation. Don't excite it directly.
546
- *
547
- * @since 1.0.0
548
- * @return void
549
- */
550
- public function deactivationHook()
551
- {
552
- $cancelled = apply_filters('wbcr_factory_400_cancel_plugin_deactivation_' . $this->plugin_name, false);
553
-
554
- if( $cancelled ) {
555
- return;
556
- }
557
-
558
- do_action('wbcr_factory_400_plugin_deactivation', $this);
559
- do_action('wbcr_factory_400_plugin_deactivation_' . $this->plugin_name, $this);
560
-
561
- if( !empty($this->activator_class) ) {
562
- foreach((array)$this->activator_class as $activator_class) {
563
- $activator = new $activator_class($this);
564
- $activator->deactivate();
565
- }
566
- }
567
- }
568
-
569
- /**
570
- * Finds migration items and install ones.
571
- *
572
- * @since 1.0.0
573
- * @return void
574
- */
575
- public function migrationHook($previos_build, $current_build)
576
- {
577
- $migration_file = $this->updates . $previos_build . '-' . $current_build . '.php';
578
- if( !file_exists($migration_file) ) {
579
- return;
580
- }
581
-
582
- $classes = $this->getClasses($migration_file);
583
- if( count($classes) == 0 ) {
584
- return;
585
- }
586
-
587
- include_once($migration_file);
588
- $migrationClass = $classes[0]['name'];
589
-
590
- $migrationItem = new $migrationClass($this);
591
- $migrationItem->install();
592
- }
593
-
594
- /**
595
- * Finds upate items and install the ones.
596
- *
597
- * @since 1.0.0
598
- * @return void
599
- */
600
- public function updateHook($old, $new)
601
- {
602
-
603
- // converts versions like 0.0.0 to 000000
604
- $old_number = $this->getVersionNumber($old);
605
- $new_number = $this->getVersionNumber($new);
606
-
607
- $update_files = $this->updates;
608
- $files = $this->findFiles($update_files);
609
-
610
- if( empty($files) ) {
611
- return;
612
- }
613
-
614
- // finds updates that has intermediate version
615
- foreach($files as $item) {
616
- if( !preg_match('/^\d+$/', $item['name']) ) {
617
- continue;
618
- }
619
-
620
- $item_number = intval($item['name']);
621
- if( $item_number > $old_number && $item_number <= $new_number ) {
622
-
623
- $classes = $this->getClasses($item['path']);
624
- if( count($classes) == 0 ) {
625
- return;
626
- }
627
-
628
- foreach($classes as $path => $class_data) {
629
- include_once($path);
630
- $update_class = $class_data['name'];
631
-
632
- $update = new $update_class($this);
633
- $update->install();
634
- }
635
- }
636
- }
637
-
638
- // just time to know when the plugin was activated the first time
639
- $activated = $this->getOption('factory_400_plugin_activated_' . $this->plugin_name, 0);
640
-
641
- if( !$activated ) {
642
- $this->updateOption('factory_400_plugin_activated_' . $this->plugin_name, time());
643
- }
644
- }
645
-
646
- /**
647
- * Converts string representation of the version to the numeric.
648
- *
649
- * @since 1.0.0
650
- * @param string $version A string version to convert.
651
- * @return integer
652
- */
653
- protected function getVersionNumber($version)
654
- {
655
- preg_match('/(\d+)\.(\d+)\.(\d+)/', $version, $matches);
656
- if( count($matches) == 0 ) {
657
- return false;
658
- }
659
-
660
- $number = '';
661
- $number .= (strlen($matches[1]) == 1)
662
- ? '0' . $matches[1]
663
- : $matches[1];
664
- $number .= (strlen($matches[2]) == 1)
665
- ? '0' . $matches[2]
666
- : $matches[2];
667
- $number .= (strlen($matches[3]) == 1)
668
- ? '0' . $matches[3]
669
- : $matches[3];
670
-
671
- return intval($number);
672
- }
673
-
674
- /**
675
- * Forces modules.
676
- *
677
- * @since 1.0.0
678
- * @return void
679
- */
680
- //public function modulesLoaded()
681
- //{
682
- // factory_core_000_modules_loaded( $this );
683
- //}
684
-
685
- // ----------------------------------------------------------------------
686
- // Plugin row on plugins.php page
687
- // ----------------------------------------------------------------------
688
-
689
- public function showCustomPluginRow($file, $plugin_data)
690
- {
691
- if( !is_network_admin() && is_multisite() ) {
692
- return;
693
- }
694
-
695
- $messages = apply_filters('wbcr_factory_400_plugin_row_' . $this->plugin_name, array(), $file, $plugin_data);
696
-
697
- // if nothign to show then, use default handle
698
- /*if( count($messages) == 0 ) {
699
- wp_plugin_update_row($file, $plugin_data);
700
-
701
- return;
702
- }*/
703
-
704
- if( empty($messages) ) {
705
- return;
706
- }
707
-
708
- $wp_list_table = _get_list_table('WP_Plugins_List_Table');
709
-
710
- foreach($messages as $message) {
711
- echo '<tr class="plugin-update-tr active">';
712
- echo '<td colspan="' . $wp_list_table->get_column_count() . '" class="plugin-update colspanchange">';
713
- echo '<div class="update-message notice inline notice-error notice-alt">';
714
- echo '<p>' . $message . '</p>';
715
- echo '</div>';
716
- echo '</td></tr>';
717
- }
718
- }
719
-
720
- // ----------------------------------------------------------------------
721
- // Finding files
722
- // ----------------------------------------------------------------------
723
-
724
- /**
725
- * Returns a list of files at a given path.
726
- * @param string $path path for search
727
- */
728
- private function findFiles($path)
729
- {
730
- return $this->findFileOrFolders($path, true);
731
- }
732
-
733
- /**
734
- * Returns a list of folders at a given path.
735
- * @param string $path path for search
736
- */
737
- private function findFolders($path)
738
- {
739
- return $this->findFileOrFolders($path, false);
740
- }
741
-
742
- /**
743
- * Returns a list of files or folders at a given path.
744
- * @param string $path path for search
745
- * @param bool $files files or folders?
746
- */
747
- private function findFileOrFolders($path, $areFiles = true)
748
- {
749
- if( !is_dir($path) ) {
750
- return array();
751
- }
752
-
753
- $entries = scandir($path);
754
- if( empty($entries) ) {
755
- return array();
756
- }
757
-
758
- $files = array();
759
- foreach($entries as $entryName) {
760
- if( $entryName == '.' || $entryName == '..' ) {
761
- continue;
762
- }
763
-
764
- $filename = $path . '/' . $entryName;
765
- if( ($areFiles && is_file($filename)) || (!$areFiles && is_dir($filename)) ) {
766
- $files[] = array(
767
- 'path' => str_replace("\\", "/", $filename),
768
- 'name' => $areFiles
769
- ? str_replace('.php', '', $entryName)
770
- : $entryName
771
- );
772
- }
773
- }
774
-
775
- return $files;
776
- }
777
-
778
- /**
779
- * Gets php classes defined in a specified file.
780
- * @param string $path
781
- */
782
- private function getClasses($path)
783
- {
784
-
785
- $phpCode = file_get_contents($path);
786
-
787
- $classes = array();
788
- $tokens = token_get_all($phpCode);
789
-
790
- $count = count($tokens);
791
- for($i = 2; $i < $count; $i++) {
792
- if( is_array($tokens) && $tokens[$i - 2][0] == T_CLASS && $tokens[$i - 1][0] == T_WHITESPACE && $tokens[$i][0] == T_STRING ) {
793
-
794
- $extends = null;
795
- if( $tokens[$i + 2][0] == T_EXTENDS && $tokens[$i + 4][0] == T_STRING ) {
796
- $extends = $tokens[$i + 4][1];
797
- }
798
-
799
- $class_name = $tokens[$i][1];
800
- $classes[$path] = array(
801
- 'name' => $class_name,
802
- 'extends' => $extends
803
- );
804
- }
805
- }
806
-
807
- /**
808
- * result example:
809
- *
810
- * $classes['/plugin/items/filename.php'] = array(
811
- * 'name' => 'PluginNameItem',
812
- * 'extendes' => 'PluginNameItemBase'
813
- * )
814
- */
815
-
816
- return $classes;
817
- }
818
-
819
- // ----------------------------------------------------------------------
820
- // Public methods
821
- // ----------------------------------------------------------------------
822
-
823
- public function newScriptList()
824
- {
825
- return new Wbcr_Factory400_ScriptList($this);
826
- }
827
-
828
- public function newStyleList()
829
- {
830
- return new Wbcr_Factory400_StyleList($this);
831
- }
832
- }
833
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
libs/factory/core/includes/premium/class-factory-license-interface.php ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace WBCR\Factory_420\Premium\Interfaces;
4
+
5
+ // Exit if accessed directly
6
+ if ( ! defined( 'ABSPATH' ) ) {
7
+ exit;
8
+ }
9
+
10
+ /**
11
+ * @author Alex Kovalev <alex.kovalevv@gmail.com>, repo: https://github.com/alexkovalevv
12
+ * @author Webcraftic <wordpress.webraftic@gmail.com>, site: https://webcraftic.com
13
+ * @copyright (c) 2018 Webraftic Ltd
14
+ * @version 1.0
15
+ */
16
+ interface License {
17
+
18
+ public function get_key();
19
+
20
+ public function get_hidden_key();
21
+
22
+ public function get_expiration_time( $format = 'time' );
23
+
24
+ public function get_sites_quota();
25
+
26
+ public function get_count_active_sites();
27
+
28
+ public function is_valid();
29
+
30
+ public function is_lifetime();
31
+
32
+ }
libs/factory/core/includes/premium/class-factory-manager.php ADDED
@@ -0,0 +1,90 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace WBCR\Factory_420\Premium;
4
+
5
+ use Exception;
6
+ use Wbcr_Factory420_Plugin;
7
+
8
+ // Exit if accessed directly
9
+ if ( ! defined( 'ABSPATH' ) ) {
10
+ exit;
11
+ }
12
+
13
+ /**
14
+ * @author Alex Kovalev <alex.kovalevv@gmail.com>, repo: https://github.com/alexkovalevv
15
+ * @author Webcraftic <wordpress.webraftic@gmail.com>, site: https://webcraftic.com
16
+ */
17
+ class Manager {
18
+
19
+ /**
20
+ * @author Alexander Kovalev <alex.kovalevv@gmail.com>
21
+ * @since 4.1.6
22
+ * @var array
23
+ */
24
+ public static $providers;
25
+
26
+ /**
27
+ * @var Wbcr_Factory420_Plugin
28
+ */
29
+ protected $plugin;
30
+
31
+ /**
32
+ * @var array
33
+ */
34
+ protected $settings;
35
+
36
+ /**
37
+ * Manager constructor.
38
+ *
39
+ * @param Wbcr_Factory420_Plugin $plugin
40
+ * @param array $settings
41
+ *
42
+ * @throws Exception
43
+ */
44
+ public function __construct( Wbcr_Factory420_Plugin $plugin, array $settings ) {
45
+ $this->plugin = $plugin;
46
+ $this->settings = $settings;
47
+ }
48
+
49
+ /**
50
+ * @param Wbcr_Factory420_Plugin $plugin
51
+ * @param array $settings
52
+ *
53
+ * @return \WBCR\Factory_Freemius_000\Premium\Provider
54
+ * @throws Exception
55
+ */
56
+ public static function instance( Wbcr_Factory420_Plugin $plugin, array $settings ) {
57
+ $premium_manager = new Manager( $plugin, $settings );
58
+
59
+ return $premium_manager->instance_provider();
60
+ }
61
+
62
+ /**
63
+ * @param $provider_name
64
+ *
65
+ * @return \WBCR\Factory_Freemius_000\Premium\Provider
66
+ * @throws Exception
67
+ */
68
+ public function instance_provider() {
69
+ $provider_name = $this->get_setting( 'provider' );
70
+
71
+ if ( isset( self::$providers[ $provider_name ] ) && class_exists( self::$providers[ $provider_name ] ) ) {
72
+ if ( self::$providers[ $provider_name ] instanceof Provider ) {
73
+ throw new Exception( "Provider {$provider_name} must extend the class WBCR\Factory_420\Premium\Provider interface!" );
74
+ }
75
+
76
+ return new self::$providers[ $provider_name ]( $this->plugin, $this->settings );
77
+ }
78
+
79
+ throw new Exception( "Provider {$provider_name} is not supported!" );
80
+ }
81
+
82
+ /**
83
+ * @param string $name
84
+ *
85
+ * @return mixed
86
+ */
87
+ protected function get_setting( $name ) {
88
+ return isset( $this->settings[ $name ] ) ? $this->settings[ $name ] : null;
89
+ }
90
+ }
libs/factory/core/includes/premium/class-factory-provider-abstract.php ADDED
@@ -0,0 +1,235 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace WBCR\Factory_420\Premium;
4
+
5
+ use Exception;
6
+ use Wbcr_Factory420_Plugin;
7
+
8
+ // Exit if accessed directly
9
+ if ( ! defined( 'ABSPATH' ) ) {
10
+ exit;
11
+ }
12
+
13
+ /**
14
+ * Выполняет проверку обновлений, обновления, скачивание плагинов
15
+ *
16
+ * @author Alex Kovalev <alex.kovalevv@gmail.com>, repo: https://github.com/alexkovalevv
17
+ * @author Webcraftic <wordpress.webraftic@gmail.com>, site: https://webcraftic.com
18
+ *
19
+ * @version 1.0
20
+ */
21
+ abstract class Provider {
22
+
23
+ /**
24
+ * @var Wbcr_Factory420_Plugin
25
+ */
26
+ protected $plugin;
27
+
28
+ /**
29
+ * @var array
30
+ */
31
+ protected $settings;
32
+
33
+ /**
34
+ * @var bool
35
+ */
36
+ private $is_install_package;
37
+
38
+ /**
39
+ * Provider constructor.
40
+ *
41
+ * @param Wbcr_Factory420_Plugin $plugin
42
+ * @param array $settings
43
+ */
44
+ public function __construct( Wbcr_Factory420_Plugin $plugin, array $settings ) {
45
+ $this->plugin = $plugin;
46
+ $this->settings = $settings;
47
+
48
+ add_action( 'wbcr/factory/license_activate', [ $this, 'register_cron_hooks' ], 10, 2 );
49
+ add_action( 'wbcr/factory/license_deactivate', [ $this, 'register_cron_hooks' ], 10, 2 );
50
+ add_action( "{$this->plugin->getPluginName()}_license_autosync", [ $this, 'license_cron_sync' ] );
51
+ }
52
+
53
+ /**
54
+ * @return array
55
+ */
56
+ public function get_settings() {
57
+ return $this->settings;
58
+ }
59
+
60
+ /**
61
+ * @param $name
62
+ * @param bool $default
63
+ *
64
+ * @return bool|mixed
65
+ */
66
+ public function get_setting( $name, $default = false ) {
67
+ return isset( $this->settings[ $name ] ) && ! empty( $this->settings[ $name ] ) ? $this->settings[ $name ] : $default;
68
+ }
69
+
70
+ /**
71
+ * @return bool|mixed
72
+ */
73
+ public function get_price() {
74
+ return $this->get_setting( 'price' );
75
+ }
76
+
77
+ /**
78
+ * todo: Вынести с лицензионный менеджер
79
+ *
80
+ * @param array $license_info
81
+ * @param string $plugin_name
82
+ */
83
+ public function register_cron_hooks( $license_info, $plugin_name ) {
84
+ if ( $this->plugin->getPluginName() == $plugin_name ) {
85
+ if ( ! wp_next_scheduled( "{$plugin_name}_license_autosync" ) ) {
86
+ wp_schedule_event( time(), 'twicedaily', "{$plugin_name}_license_autosync" );
87
+ }
88
+ }
89
+ }
90
+
91
+ /**
92
+ * todo: вынести в лицензионный менеджер
93
+ *
94
+ * @param array $license_info
95
+ * @param string $plugin_name
96
+ */
97
+ public function clear_cron_hooks( $license_info, $plugin_name ) {
98
+ if ( $this->plugin->getPluginName() == $plugin_name ) {
99
+ if ( wp_next_scheduled( "{$plugin_name}_license_autosync" ) ) {
100
+ wp_clear_scheduled_hook( "{$plugin_name}_license_autosync" );
101
+ }
102
+ }
103
+ }
104
+
105
+ public function license_cron_sync() {
106
+ $this->sync();
107
+ }
108
+
109
+ /**
110
+ * @return bool
111
+ */
112
+ public function is_install_package() {
113
+ if ( ! is_null( $this->is_install_package ) ) {
114
+ return $this->is_install_package;
115
+ }
116
+
117
+ $premium_package = $this->get_package_data();
118
+
119
+ if ( ! empty( $premium_package ) && ! empty( $premium_package['basename'] ) ) {
120
+ $basename_part = explode( '/', $premium_package['basename'] );
121
+ $is_valid_basename = sizeof( $basename_part ) === 2;
122
+
123
+ if ( $is_valid_basename && ! file_exists( WP_PLUGIN_DIR . '/' . $premium_package['basename'] ) ) {
124
+ $this->delete_package();
125
+ $this->is_install_package = false;
126
+
127
+ return false;
128
+ }
129
+ }
130
+
131
+ $this->is_install_package = ! empty( $premium_package );
132
+
133
+ return $this->is_install_package;
134
+ }
135
+
136
+ /**
137
+ * @return bool|mixed|null
138
+ */
139
+ public function get_package_data() {
140
+ $premium_package = $this->plugin->getPopulateOption( 'premium_package' );
141
+
142
+ if ( ! empty( $premium_package ) ) {
143
+ return wp_parse_args( $premium_package, [
144
+ 'basename' => null,
145
+ 'version' => null,
146
+ 'framework_version' => null
147
+ ] );
148
+ }
149
+
150
+ return null;
151
+ }
152
+
153
+ /**
154
+ * @param $plugin_data
155
+ *
156
+ * @throws Exception
157
+ */
158
+ public function update_package_data( array $package ) {
159
+ $parsed_args = wp_parse_args( $package, [
160
+ 'basename' => null,
161
+ 'version' => null,
162
+ 'framework_version' => null
163
+ ] );
164
+
165
+ if ( empty( $parsed_args['basename'] ) || empty( $parsed_args['version'] ) ) {
166
+ throw new Exception( 'You must pass the required attributes (basename, version).' );
167
+ }
168
+
169
+ $this->plugin->updatePopulateOption( 'premium_package', $parsed_args );
170
+ $this->is_install_package = true;
171
+ }
172
+
173
+ public function delete_package() {
174
+ $this->plugin->deletePopulateOption( 'premium_package' );
175
+ $this->is_install_package = false;
176
+ }
177
+
178
+ /**
179
+ * @return bool
180
+ */
181
+ abstract public function is_activate();
182
+
183
+ /**
184
+ * @return bool
185
+ */
186
+ abstract public function is_active();
187
+
188
+ /**
189
+ * @return string|null
190
+ */
191
+ abstract public function get_plan();
192
+
193
+ /**
194
+ * @return string|null
195
+ */
196
+ abstract public function get_billing_cycle();
197
+
198
+ /**
199
+ * @return \WBCR\Factory_420\Premium\Interfaces\License
200
+ */
201
+ abstract public function get_license();
202
+
203
+ /**
204
+ * @return string|null
205
+ */
206
+ abstract public function get_package_download_url();
207
+
208
+ /**
209
+ * @param string $key
210
+ *
211
+ * @return mixed
212
+ */
213
+ abstract public function activate( $key );
214
+
215
+ /**
216
+ * @return bool
217
+ */
218
+ abstract public function deactivate();
219
+
220
+ /**
221
+ * @return bool
222
+ */
223
+ abstract public function sync();
224
+
225
+ /**
226
+ * @return bool
227
+ */
228
+ abstract public function has_paid_subscription();
229
+
230
+ /**
231
+ * @return bool
232
+ */
233
+ abstract public function cancel_paid_subscription();
234
+
235
+ }
libs/factory/core/includes/premium/index.php ADDED
@@ -0,0 +1,2 @@
 
 
1
+ <?php
2
+ // Silence is golden.
libs/factory/core/includes/request.class.php DELETED
@@ -1,126 +0,0 @@
1
- <?php
2
- // Exit if accessed directly
3
- if( !defined('ABSPATH') ) {
4
- exit;
5
- }
6
-
7
- if( !class_exists('Wbcr_Factory400_Plugin') ) {
8
- class Wbcr_Factory400_Request {
9
-
10
- /**
11
- * @param null $param
12
- * @param bool|string $sanitize true/false or sanitize function name
13
- * @param bool $default
14
- * @param string $method_name
15
- * @return array|bool|mixed
16
- */
17
- private function getBody($param = null, $sanitize = false, $default = false, $method_name = 'REQUEST')
18
- {
19
- $sanitize_function_name = 'sanitize_text_field';
20
- $method = $_REQUEST;
21
-
22
- switch( strtoupper($method_name) ) {
23
- case 'GET':
24
- $method = $_GET;
25
- break;
26
- case 'POST':
27
- $method = $_POST;
28
- break;
29
- case 'REQUEST':
30
- $method = $_REQUEST;
31
- break;
32
- }
33
-
34
- if( !empty($sanitize) && is_string($sanitize) && $sanitize !== $sanitize_function_name ) {
35
- $sanitize_function_name = $sanitize;
36
- }
37
-
38
- if( !function_exists($sanitize_function_name) ) {
39
- throw new Exception('Function ' . $sanitize_function_name . 'is undefined.');
40
- }
41
-
42
- if( !empty($param) ) {
43
- if( isset($method[$param]) && !empty($method[$param]) ) {
44
- if( is_array($method[$param]) ) {
45
- return !empty($sanitize)
46
- ? array_map($sanitize_function_name, $method[$param])
47
- : $method[$param];
48
- } else {
49
- return !empty($sanitize)
50
- ? call_user_func($sanitize_function_name, $method[$param])
51
- : $method[$param];
52
- }
53
- }
54
-
55
- return $default;
56
- }
57
-
58
- return !empty($sanitize)
59
- ? array_map($sanitize_function_name, $method)
60
- : $method;
61
- }
62
-
63
- /**
64
- * @param bool|string see method getBody
65
- * @param array $default
66
- * @return mixed|null
67
- */
68
- public function requestAll($sanitize = false, $default = array())
69
- {
70
- return $this->getBody(null, $sanitize, $default);
71
- }
72
-
73
- /**
74
- * @param $param
75
- * @param bool|string see method getBody
76
- * @param bool $default
77
- * @return mixed|null
78
- */
79
- public function request($param, $default = false, $sanitize = false)
80
- {
81
- return $this->getBody($param, $sanitize, $default);
82
- }
83
-
84
- /**
85
- * @param bool|string see method getBody
86
- * @param array $default
87
- * @return mixed|null
88
- */
89
- public function getAll($sanitize = false, $default = array())
90
- {
91
- return $this->getBody(null, $sanitize, $default, 'get');
92
- }
93
-
94
- /**
95
- * @param null $param
96
- * @param bool|string see method getBody
97
- * @param bool $default
98
- * @return mixed|null
99
- */
100
- public function get($param, $default = false, $sanitize = false)
101
- {
102
- return $this->getBody($param, $sanitize, $default, 'get');
103
- }
104
-
105
- /**
106
- * @param bool|string see method getBody
107
- * @param array $default
108
- * @return mixed|null
109
- */
110
- public function postAll($sanitize = false, $default = array())
111
- {
112
- return $this->getBody(null, $sanitize, $default, 'post');
113
- }
114
-
115
- /**
116
- * @param $param
117
- * @param bool|string see method getBody
118
- * @param bool $default
119
- * @return mixed|null
120
- */
121
- public function post($param, $default = false, $sanitize = false)
122
- {
123
- return $this->getBody($param, $sanitize, $default, 'post');
124
- }
125
- }
126
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
libs/factory/core/includes/updates/class-factory-premium-upgrader.php ADDED
@@ -0,0 +1,778 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace WBCR\Factory_420\Updates;
4
+
5
+ use Exception;
6
+ use Plugin_Installer_Skin;
7
+ use Plugin_Upgrader;
8
+ use Wbcr_Factory420_Plugin;
9
+ use Wbcr_FactoryPages420_ImpressiveThemplate;
10
+ use WP_Filesystem_Base;
11
+ use WP_Upgrader;
12
+ use WP_Upgrader_Skin;
13
+
14
+ // Exit if accessed directly
15
+ if ( ! defined( 'ABSPATH' ) ) {
16
+ exit;
17
+ }
18
+
19
+ /**
20
+ * @author Alex Kovalev <alex.kovalevv@gmail.com>, repo: https://github.com/alexkovalevv
21
+ * @author Webcraftic <wordpress.webraftic@gmail.com>, site: https://webcraftic.com
22
+ * @copyright (c) 2018 Webraftic Ltd
23
+ * @version 1.0
24
+ */
25
+ class Premium_Upgrader extends Upgrader {
26
+
27
+ /**
28
+ * Тип апгрейдера, может быть default, premium
29
+ *
30
+ * @var string
31
+ */
32
+ protected $type = 'premium';
33
+
34
+ /**
35
+ * Manager constructor.
36
+ *
37
+ * @since 4.1.1
38
+ *
39
+ * @param $args
40
+ * @param bool $is_premium
41
+ *
42
+ * @param Wbcr_Factory420_Plugin $plugin
43
+ *
44
+ * @throws Exception
45
+ */
46
+ public function __construct( Wbcr_Factory420_Plugin $plugin ) {
47
+ parent::__construct( $plugin );
48
+
49
+ $this->plugin_basename = null;
50
+ $this->plugin_main_file = null;
51
+ $this->plugin_absolute_path = null;
52
+
53
+ if ( $this->plugin->premium->is_activate() && $this->plugin->premium->is_install_package() ) {
54
+ $premium_package = $this->plugin->premium->get_package_data();
55
+
56
+ if ( $premium_package ) {
57
+ $this->plugin_basename = $premium_package['basename'];
58
+ $this->plugin_main_file = WP_PLUGIN_DIR . '/' . $premium_package['basename'];
59
+ $this->plugin_absolute_path = dirname( WP_PLUGIN_DIR . '/' . $premium_package['basename'] );
60
+ }
61
+ }
62
+
63
+ if ( ! $this->repository->is_support_premium() ) {
64
+ $settings = $this->get_settings();
65
+ throw new Exception( "Repository {$settings['repository']} does not have support premium." );
66
+ }
67
+ }
68
+
69
+ /**
70
+ * @throws Exception
71
+ */
72
+ protected function set_repository() {
73
+ $settings = $this->get_settings();
74
+ $this->repository = $this->get_repository( $settings['repository'] );
75
+
76
+ if ( $this->plugin->premium->is_activate() ) {
77
+ $this->repository->init();
78
+ }
79
+ }
80
+
81
+ /**
82
+ * @since 4.1.1
83
+ * @throws Exception
84
+ */
85
+ protected function init_hooks() {
86
+ parent::init_hooks();
87
+
88
+ if ( $this->need_intall_or_activate_premium() || $this->need_renew_license() || $this->need_activate_license() ) {
89
+ // Показываем уведомление под бесплатным плагином, если требуется установить или активировать премиум пакет
90
+ if ( $this->need_intall_or_activate_premium() ) {
91
+ $free_plugin_base = $this->plugin->get_paths()->basename;
92
+
93
+ add_action( "after_plugin_row_{$free_plugin_base}", [ $this, "notice_in_plugin_row" ], 100, 3 );
94
+ }
95
+
96
+ // Если установлен премиум пакет, то показываем уведомление под премиум плагином.
97
+ if ( ( $this->need_renew_license() || $this->need_activate_license() ) && $this->plugin->premium->is_install_package() ) {
98
+ $package = $this->plugin->premium->get_package_data();
99
+ $premium_plugin_base = $package['basename'];
100
+
101
+ add_action( "after_plugin_row_{$premium_plugin_base}", [ $this, "notice_in_plugin_row" ], 100, 3 );
102
+ }
103
+
104
+ add_action( "admin_print_styles-plugins.php", [ $this, "print_styles_for_plugin_row" ] );
105
+ add_action( "wbcr/factory/admin_notices", [ $this, "admin_notices_hook" ], 10, 2 );
106
+ add_action( 'wbcr/factory/pages/impressive/print_all_notices', [
107
+ $this,
108
+ 'install_notice_in_plugin_interface'
109
+ ], 10, 2 );
110
+ }
111
+
112
+ add_action( 'admin_init', [ $this, 'init_admin_actions' ] );
113
+
114
+ add_action( 'deleted_plugin', [ $this, 'delete_plugin_hook' ], 10, 2 );
115
+ add_action( 'upgrader_process_complete', [ $this, 'upgrader_process_complete_hook' ], 10, 2 );
116
+ }
117
+
118
+ /**
119
+ * @since 4.1.1
120
+ */
121
+ public function init_admin_actions() {
122
+ if ( isset( $_GET['wbcr_factory_premium_updates_action'] ) ) {
123
+ $action = $this->plugin->request->get( 'wbcr_factory_premium_updates_action' );
124
+
125
+ check_admin_referer( "factory_premium_{$action}" );
126
+ try {
127
+ switch ( $action ) {
128
+ case 'install':
129
+ $this->install();
130
+ break;
131
+ case 'deactivate':
132
+ $this->deactivate();
133
+ break;
134
+ case 'delete':
135
+ $this->delete();
136
+ break;
137
+ case 'check_updates':
138
+ $this->check_updates();
139
+ break;
140
+ case 'cancel_license':
141
+ $this->plugin->premium->deactivate();
142
+
143
+ break;
144
+ }
145
+ } catch( Exception $e ) {
146
+ wp_die( $e->getMessage() );
147
+ }
148
+ }
149
+ }
150
+
151
+ /**
152
+ * Удаляет данные о пакете, если пользовать удалил премиум плагин
153
+ *
154
+ * @since 4.1.1
155
+ *
156
+ * @param $success
157
+ *
158
+ * @param $plugin_basename
159
+ */
160
+ public function delete_plugin_hook( $plugin_basename, $success ) {
161
+ if ( ! $this->plugin->premium->is_install_package() ) {
162
+ return;
163
+ }
164
+
165
+ $package = $this->plugin->premium->get_package_data();
166
+
167
+ if ( $package['basename'] == $plugin_basename && $success ) {
168
+ $this->plugin->premium->delete_package();
169
+ }
170
+ }
171
+
172
+ /**
173
+ * Выводит уведомление на всех страницах админ панели Wordpress
174
+ *
175
+ * @since 4.1.1
176
+ *
177
+ * @param $notices
178
+ *
179
+ * @return array
180
+ */
181
+ public function admin_notices_hook( $notices, $plugin_name ) {
182
+
183
+ if ( $plugin_name !== $this->plugin->getPluginName() || ! current_user_can( 'update_plugins' ) ) {
184
+ return $notices;
185
+ }
186
+
187
+ if ( $this->need_intall_or_activate_premium() ) {
188
+ $notice_text = $this->get_notice_text( 'please_activate_premium' );
189
+
190
+ if ( ! $this->plugin->premium->is_install_package() ) {
191
+ $notice_text = $this->get_notice_text( 'please_install_premium' );
192
+ }
193
+
194
+ $notices[] = [
195
+ 'id' => 'please_install_premium_for_' . $this->plugin->getPluginName(),
196
+ 'type' => 'warning',
197
+ 'dismissible' => false,
198
+ 'dismiss_expires' => 0,
199
+ 'text' => "<p><b>{$this->plugin->getPluginTitle()}:</b> " . $notice_text . '</p>'
200
+ ];
201
+ } else if ( $this->need_activate_license() ) {
202
+ $notices[] = [
203
+ 'id' => 'need_activate_premium_for_' . $this->plugin->getPluginName(),
204
+ 'type' => 'warning',
205
+ 'dismissible' => false,
206
+ 'dismiss_expires' => 0,
207
+ 'text' => "<p><b>{$this->plugin->getPluginTitle()}:</b> " . $this->get_notice_text( 'need_activate_license' ) . '</p>'
208
+ ];
209
+ } else if ( $this->need_renew_license() ) {
210
+ // todo: может быть перенести уведомление в премиум менеджер?
211
+ $notices[] = [
212
+ 'id' => 'license_exired_for_' . $this->plugin->getPluginName(),
213
+ 'type' => 'warning',
214
+ 'dismissible' => false,
215
+ 'dismiss_expires' => 0,
216
+ 'text' => "<p><b>{$this->plugin->getPluginTitle()}:</b> " . $this->get_notice_text( 'need_renew_license' ) . '</p>'
217
+ ];
218
+ }
219
+
220
+ return $notices;
221
+ }
222
+
223
+ /**
224
+ * Выводит уведомление внутри интерфейса плагина, на всех страницах плагина.
225
+ *
226
+ * @since 4.1.1
227
+ *
228
+ * @param Wbcr_FactoryPages420_ImpressiveThemplate $obj
229
+ *
230
+ * @param Wbcr_Factory420_Plugin $plugin
231
+ *
232
+ * @return void
233
+ */
234
+ public function install_notice_in_plugin_interface( $plugin, $obj ) {
235
+ if ( $plugin->getPluginName() != $this->plugin->getPluginName() ) {
236
+ return;
237
+ }
238
+
239
+ $notice_text = '';
240
+
241
+ if ( $this->need_intall_or_activate_premium() ) {
242
+ $notice_text = $this->get_notice_text( 'please_activate_premium' );
243
+
244
+ if ( ! $this->plugin->premium->is_install_package() ) {
245
+ $notice_text = $this->get_notice_text( 'please_install_premium' );
246
+ }
247
+ } else if ( $this->need_activate_license() ) {
248
+ $notice_text = $this->get_notice_text( 'need_activate_license' );
249
+ } else if ( $this->need_renew_license() ) {
250
+ $notice_text = $this->get_notice_text( 'need_renew_license' );
251
+ }
252
+
253
+ $obj->printWarningNotice( $notice_text );
254
+ }
255
+
256
+ /**
257
+ * Выводит уведомление в строке плагина (на странице плагинов),
258
+ * что нужно установить премиум плагин.
259
+ *
260
+ * @since 4.1.1
261
+ *
262
+ * @param array $plugin_data
263
+ * @param string $status
264
+ *
265
+ * @param string $plugin_file
266
+ *
267
+ * @return void
268
+ * @see WP_Plugins_List_Table
269
+ *
270
+ */
271
+ public function notice_in_plugin_row( $plugin_file, $plugin_data, $status ) {
272
+
273
+ if ( ! current_user_can( 'update_plugins' ) ) {
274
+ return;
275
+ };
276
+
277
+ $notice_text = '';
278
+
279
+ if ( $this->need_intall_or_activate_premium() ) {
280
+ $notice_text = $this->get_notice_text( 'please_activate_premium' );
281
+
282
+ if ( ! $this->plugin->premium->is_install_package() ) {
283
+ $notice_text = $this->get_notice_text( 'please_install_premium' );
284
+ }
285
+ } else if ( $this->need_activate_license() ) {
286
+ $notice_text = $this->get_notice_text( 'need_activate_license' );
287
+ } else if ( $this->need_renew_license() ) {
288
+ $notice_text = $this->get_notice_text( 'need_renew_license' );
289
+ }
290
+
291
+ ?>
292
+ <tr class="plugin-update-tr active update wbcr-factory-updates">
293
+ <td colspan="3" class="plugin-update colspanchange">
294
+ <div class="update-message notice inline notice-warning notice-alt">
295
+ <p>
296
+ <?php echo $notice_text; ?>
297
+ </p>
298
+ </div>
299
+ </td>
300
+ </tr>
301
+ <?php
302
+ }
303
+
304
+ /**
305
+ * Печатает стили для уведомления о загрузке премиум версии на странице плагинов.
306
+ *
307
+ * @since 4.1.1
308
+ * @return void
309
+ */
310
+ public function print_styles_for_plugin_row() {
311
+
312
+ if ( ! current_user_can( 'update_plugins' ) ) {
313
+ return;
314
+ }
315
+
316
+ $plugin_base = $this->plugin->get_paths()->basename;
317
+
318
+ if ( $this->need_intall_or_activate_premium() ) {
319
+ $message_background_color = '#f5e9f5';
320
+ $message_border_color = '#dab9da';
321
+ } else if ( $this->need_renew_license() || $this->need_activate_license() ) {
322
+ $message_background_color = '#ffe2e0';
323
+ $message_border_color = '#F44336';
324
+ if ( $this->plugin->premium->is_install_package() ) {
325
+ $package = $this->plugin->premium->get_package_data();
326
+ $plugin_base = $package['basename'];
327
+ }
328
+ }
329
+
330
+ ?>
331
+ <style>
332
+ tr[data-plugin="<?php echo $plugin_base; ?>"] th,
333
+ tr[data-plugin="<?php echo $plugin_base; ?>"] td {
334
+ box-shadow: none !important;
335
+ }
336
+
337
+ .wbcr-factory-updates .update-message {
338
+ background-color: <?php echo esc_attr($message_background_color); ?> !important;
339
+ border-color: <?php echo esc_attr($message_border_color); ?> !important;
340
+ }
341
+ </style>
342
+ <?php
343
+ }
344
+
345
+ /**
346
+ * Обновляет данные о премиум пакете в базе данных, после обновления плагина.
347
+ *
348
+ * @since 4.1.1
349
+ *
350
+ * @param array $options
351
+ *
352
+ * @param WP_Upgrader $upgrader_object
353
+ *
354
+ * @throws Exception
355
+ */
356
+ public function upgrader_process_complete_hook( $upgrader_object, $options ) {
357
+ if ( ! empty( $options ) && $options['action'] == 'update' && $options['type'] == 'plugin' ) {
358
+ if ( is_array( $options['plugins'] ) && in_array( $this->plugin_basename, $options['plugins'] ) ) {
359
+ $this->update_package_data();
360
+ }
361
+ }
362
+ }
363
+
364
+ /**
365
+ * @since 4.1.1
366
+ * @return array
367
+ */
368
+ protected function get_settings() {
369
+ $settings = $this->plugin->getPluginInfoAttr( 'license_settings' );
370
+
371
+ $updates_settings = isset( $settings['updates_settings'] ) ? $settings['updates_settings'] : [];
372
+
373
+ if ( is_array( $settings ) ) {
374
+ $updates_settings['repository'] = $settings['provider'];
375
+ $updates_settings['slug'] = $settings['slug'];
376
+ }
377
+
378
+ return wp_parse_args( $updates_settings, [
379
+ 'repository' => 'wordpress',
380
+ 'slug' => '',
381
+ 'maybe_rollback' => false,
382
+ 'rollback_settings' => [
383
+ 'prev_stable_version' => '0.0.0'
384
+ ]
385
+ ] );
386
+ }
387
+
388
+ /**
389
+ * @since 4.1.1
390
+ * @return string
391
+ */
392
+ protected function get_plugin_version() {
393
+ if ( ! $this->plugin->premium->is_install_package() ) {
394
+ return '0.0.0';
395
+ }
396
+
397
+ $package = $this->plugin->premium->get_package_data();
398
+
399
+ return $package['version'];
400
+ }
401
+
402
+ /**
403
+ * @since 4.1.1
404
+ *
405
+ * @param $args
406
+ *
407
+ * @return string
408
+ */
409
+ protected function get_admin_url( $args ) {
410
+ $url = admin_url( 'plugins.php', $args );
411
+
412
+ if ( $this->plugin->isNetworkActive() ) {
413
+ $url = network_admin_url( 'plugins.php', $args );
414
+ }
415
+
416
+ return add_query_arg( $args, $url );
417
+ }
418
+
419
+ /**
420
+ * @since 4.1.1
421
+ *
422
+ * @param string $action
423
+ *
424
+ * @return string
425
+ */
426
+ protected function get_action_url( $action ) {
427
+ $args = [ 'wbcr_factory_premium_updates_action' => $action ];
428
+
429
+ return wp_nonce_url( $this->get_admin_url( $args ), "factory_premium_{$action}" );
430
+ }
431
+
432
+ /**
433
+ * @since 4.1.1
434
+ * @return string
435
+ */
436
+ protected function get_activate_premium_url() {
437
+ $args = [
438
+ 'action' => 'activate',
439
+ 'plugin' => $this->plugin_basename,
440
+ ];
441
+
442
+ return wp_nonce_url( $this->get_admin_url( $args ), "activate-plugin_{$this->plugin_basename}" );
443
+ }
444
+
445
+ /**
446
+ * Нужно установить или обновить премиум?
447
+ *
448
+ * @since 4.1.1
449
+ * @return bool
450
+ */
451
+ protected function need_intall_or_activate_premium() {
452
+ if ( $this->plugin->premium->is_activate() && $this->plugin->premium->is_active() ) {
453
+ if ( $this->plugin->premium->is_install_package() && is_plugin_active( $this->plugin_basename ) ) {
454
+ return false;
455
+ }
456
+
457
+ return true;
458
+ }
459
+
460
+ return false;
461
+ }
462
+
463
+ /**
464
+ * Требуется активировать лицензию?
465
+ *
466
+ * @since 4.1.1
467
+ * @return bool
468
+ */
469
+ protected function need_activate_license() {
470
+ return ! $this->plugin->premium->is_activate() && $this->plugin->premium->is_install_package();
471
+ }
472
+
473
+ /**
474
+ * Нужно продлить лицензию?
475
+ *
476
+ * @since 4.1.1
477
+ * @return bool
478
+ */
479
+ protected function need_renew_license() {
480
+ return $this->plugin->premium->is_activate() && ! $this->plugin->premium->is_active();
481
+ }
482
+
483
+ /**
484
+ * @since 4.1.1
485
+ * @throws Exception
486
+ */
487
+ protected function install() {
488
+ global $wp_filesystem;
489
+
490
+ if ( ! current_user_can( 'install_plugins' ) ) {
491
+ throw new Exception( 'Sorry, you are not allowed to install plugins on this site.', 'not_allowed_install_plugin' );
492
+ }
493
+
494
+ if ( $this->plugin->premium->is_install_package() ) {
495
+ return;
496
+ }
497
+
498
+ if ( ! $wp_filesystem ) {
499
+ if ( ! function_exists( 'WP_Filesystem' ) ) {
500
+ require_once( ABSPATH . 'wp-admin/includes/file.php' );
501
+ }
502
+ WP_Filesystem();
503
+ }
504
+
505
+ if ( ! WP_Filesystem( false, WP_PLUGIN_DIR ) ) {
506
+ throw new Exception( 'You are not allowed to edt folders/files on this site', 'not_allowed_edit_filesystem' );
507
+ } else {
508
+
509
+ $download_url = $this->repository->get_download_url();
510
+
511
+ /**
512
+ * @since 4.1.1
513
+ *
514
+ * @param string $plugin_name Имя плагина
515
+ *
516
+ * @param string $package Дополнительная информация о лицензии
517
+ */
518
+ do_action( 'wbcr/factory/premium/install_package', $download_url, $this->plugin->getPluginName() );
519
+
520
+ // If plugin is installed before we update the premium package in database.
521
+ // ------------------------------------------------------------------------
522
+ $plugins = get_plugins( $plugin_folder = '' );
523
+
524
+ if ( ! empty( $plugins ) ) {
525
+ foreach ( (array) $plugins as $plugin_base => $plugin ) {
526
+ $basename_parts = explode( '/', $plugin_base );
527
+ if ( sizeof( $basename_parts ) == 2 && $basename_parts[0] == $this->plugin_slug ) {
528
+
529
+ $this->plugin_basename = $plugin_base;
530
+ $this->plugin_main_file = WP_PLUGIN_DIR . '/' . $plugin_base;
531
+ $this->plugin_absolute_path = dirname( WP_PLUGIN_DIR . '/' . $plugin_base );
532
+
533
+ $this->update_package_data();
534
+
535
+ $package = $this->plugin->premium->get_package_data();
536
+
537
+ /**
538
+ * @since 4.1.1
539
+ *
540
+ * @param string $plugin_name Имя плагина
541
+ *
542
+ * @param string $package Дополнительная информация о лицензии
543
+ */
544
+ do_action( 'wbcr/factory/premium/installed_package', $package, $this->plugin->getPluginName() );
545
+
546
+ return;
547
+ }
548
+ }
549
+ }
550
+ // ------------------------------------------------------------------------
551
+
552
+ require_once( ABSPATH . 'wp-admin/includes/file.php' );
553
+ require_once( ABSPATH . 'wp-admin/includes/misc.php' );
554
+
555
+ if ( ! class_exists( 'Plugin_Upgrader', false ) ) {
556
+ // Include required resources for the installation.
557
+ require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
558
+ }
559
+
560
+ $skin_args = [
561
+ 'type' => 'web',
562
+ 'title' => sprintf( 'Installing plugin: %s', $this->plugin->getPluginTitle() . ' Premium' ),
563
+ 'url' => esc_url_raw( $download_url ),
564
+ 'nonce' => 'install-plugin_' . $this->plugin_slug,
565
+ 'plugin' => '',
566
+ 'api' => null,
567
+ 'extra' => [
568
+ 'slug' => $this->plugin_slug
569
+ ],
570
+ ];
571
+
572
+ require_once( ABSPATH . 'wp-admin/admin-header.php' );
573
+
574
+ if ( ! $this->plugin->premium->is_install_package() ) {
575
+ $skin = new Plugin_Installer_Skin( $skin_args );
576
+ } else {
577
+ $skin = new WP_Upgrader_Skin( $skin_args );
578
+ }
579
+
580
+ $upgrader = new Plugin_Upgrader( $skin );
581
+
582
+ if ( empty( $download_url ) ) {
583
+ throw new Exception( 'You must pass the download url to upgrade up premium package.', "not_passed_download_url" );
584
+ }
585
+
586
+ $install_result = $upgrader->install( $download_url );
587
+
588
+ include( ABSPATH . 'wp-admin/admin-footer.php' );
589
+
590
+ if ( is_wp_error( $install_result ) ) {
591
+ throw new Exception( $install_result->get_error_message(), $install_result->get_error_code() );
592
+ } else if ( is_wp_error( $skin->result ) ) {
593
+ throw new Exception( $skin->result->get_error_message(), $skin->result->get_error_code() );
594
+ } else if ( is_null( $install_result ) ) {
595
+ global $wp_filesystem;
596
+
597
+ $error_code = 'unable_to_connect_to_filesystem';
598
+ $error_message = 'Unable to connect to the filesystem. Please confirm your credentials.';
599
+
600
+ // Pass through the error from WP_Filesystem if one was raised.
601
+ if ( $wp_filesystem instanceof WP_Filesystem_Base && is_wp_error( $wp_filesystem->errors ) && $wp_filesystem->errors->get_error_code() ) {
602
+ $error_message = $wp_filesystem->errors->get_error_message();
603
+ }
604
+
605
+ throw new Exception( $error_message, $error_code );
606
+ }
607
+
608
+ $this->plugin_basename = $upgrader->plugin_info();
609
+ $this->plugin_main_file = WP_PLUGIN_DIR . '/' . $this->plugin_basename;
610
+ $this->plugin_absolute_path = dirname( WP_PLUGIN_DIR . '/' . $this->plugin_basename );
611
+
612
+ $this->update_package_data();
613
+
614
+ $package = $this->plugin->premium->get_package_data();
615
+
616
+ /**
617
+ * @since 4.1.1
618
+ *
619
+ * @param string $plugin_name Имя плагина
620
+ *
621
+ * @param string $package Дополнительная информация о лицензии
622
+ */
623
+ do_action( 'wbcr/factory/premium/installed_package', $package, $this->plugin->getPluginName() );
624
+
625
+ die();
626
+ }
627
+ }
628
+
629
+ /**
630
+ * @return bool
631
+ * @throws Exception
632
+ */
633
+ protected function delete() {
634
+ if ( ! $this->plugin->premium->is_install_package() ) {
635
+ return false;
636
+ }
637
+
638
+ $package = $this->plugin->premium->get_package_data();
639
+
640
+ /**
641
+ * @since 4.1.1
642
+ *
643
+ * @param string $plugin_name Имя плагина
644
+ *
645
+ * @param string $package Дополнительная информация о лицензии
646
+ */
647
+ do_action( 'wbcr/factory/premium/delete_package', $package, $this->plugin->getPluginName() );
648
+
649
+ if ( is_plugin_active( $package['basename'] ) ) {
650
+ if ( is_multisite() && is_plugin_active_for_network( $package['basename'] ) ) {
651
+ deactivate_plugins( $package['basename'], false, true );
652
+ } else {
653
+ deactivate_plugins( $package['basename'] );
654
+ }
655
+ }
656
+
657
+ $result = delete_plugins( [ $package['basename'] ] );
658
+
659
+ if ( is_wp_error( $result ) ) {
660
+ throw new Exception( $result->get_error_message(), $result->get_error_code() );
661
+ }
662
+
663
+ $this->plugin->premium->delete_package();
664
+
665
+ /**
666
+ * @since 4.1.1
667
+ *
668
+ * @param string $plugin_name Имя плагина
669
+ *
670
+ * @param string $package Дополнительная информация о лицензии
671
+ */
672
+ do_action( 'wbcr/factory/premium/deleted_package', $package, $this->plugin->getPluginName() );
673
+
674
+ return true;
675
+ }
676
+
677
+ /**
678
+ * @since 4.1.1
679
+ * @return bool
680
+ */
681
+ protected function deactivate() {
682
+ if ( ! $this->plugin->premium->is_install_package() || ! is_plugin_active( $this->plugin_basename ) ) {
683
+ return false;
684
+ }
685
+
686
+ $package = $this->plugin->premium->get_package_data();
687
+
688
+ /**
689
+ * @since 4.1.1
690
+ *
691
+ * @param string $plugin_name Имя плагина
692
+ *
693
+ * @param string $package Дополнительная информация о лицензии
694
+ */
695
+ do_action( 'wbcr/factory/premium/deactivate_package', $package, $this->plugin->getPluginName() );
696
+
697
+ if ( is_multisite() && is_plugin_active_for_network( $this->plugin_basename ) ) {
698
+ deactivate_plugins( $this->plugin_basename, false, true );
699
+ } else {
700
+ deactivate_plugins( $this->plugin_basename );
701
+ }
702
+
703
+ /**
704
+ * @since 4.1.1
705
+ *
706
+ * @param string $plugin_name Имя плагина
707
+ *
708
+ * @param string $package Дополнительная информация о лицензии
709
+ */
710
+ do_action( 'wbcr/factory/premium/deactivated_package', $package, $this->plugin->getPluginName() );
711
+
712
+ return true;
713
+ }
714
+
715
+ /**
716
+ * @since 4.1.1
717
+ *
718
+ * @param array $plugin_data
719
+ *
720
+ * @throws Exception
721
+ */
722
+ protected function update_package_data() {
723
+
724
+ if ( ! $this->plugin_main_file ) {
725
+ return;
726
+ }
727
+
728
+ $default_headers = [
729
+ 'Version' => 'Version',
730
+ 'FrameworkVersion' => 'Framework Version'
731
+ ];
732
+
733
+ $plugin_data = get_file_data( $this->plugin_main_file, $default_headers, 'plugin' );
734
+
735
+ $this->plugin->premium->update_package_data( [
736
+ 'basename' => $this->plugin_basename,
737
+ 'version' => $plugin_data['Version'],
738
+ 'framework_version' => isset( $plugin_data['FrameworkVersion'] ) ? $plugin_data['FrameworkVersion'] : null,
739
+ ] );
740
+ }
741
+
742
+ /**
743
+ * @since 4.1.1
744
+ *
745
+ * @param string $type
746
+ *
747
+ * @return string|null
748
+ */
749
+ private function get_notice_text( $type ) {
750
+ $upgrade_url = $this->get_action_url( 'install' );
751
+ $activate_plugin_url = $this->get_activate_premium_url();
752
+ $cancel_license_url = $this->get_action_url( 'cancel_license' );
753
+
754
+ $texts = [
755
+ 'need_activate_license' => __( 'License activation required. A license is required to get premium plugin updates, as well as to get additional services.', 'wbcr_factory_420' ),
756
+ 'need_renew_license' => __( 'Your license has expired. You can no longer get premium plugin updates, premium support and your access to Webcraftic services has been suspended.', 'wbcr_factory_420' ),
757
+ 'please_install_premium' => sprintf( __( 'Congratulations, you have activated a premium license! Please install premium add-on to use pro features now.
758
+ <a href="%s">Install</a> premium add-on or <a href="%s">cancel</a> license.', 'wbcr_factory_420' ), $upgrade_url, $cancel_license_url ),
759
+ 'please_activate_premium' => sprintf( __( 'Congratulations, you have activated a premium license! Please activate premium add-on to use pro features now.
760
+ <a href="%s">Activate</a> premium add-on or <a href="%s">cancel</a> license.', 'wbcr_factory_420' ), $activate_plugin_url, $cancel_license_url )
761
+ ];
762
+
763
+ if ( isset( $texts[ $type ] ) ) {
764
+
765
+ /**
766
+ * @since 4.1.1
767
+ *
768
+ * @param string $type
769
+ * @param string $plugin_name
770
+ *
771
+ * @param array $messages
772
+ */
773
+ return apply_filters( 'wbcr/factory/premium/notice_text', $texts[ $type ], $type, $this->plugin->getPluginName() );
774
+ }
775
+
776
+ return null;
777
+ }
778
+ }
libs/factory/core/includes/updates/class-factory-upgrader.php ADDED
@@ -0,0 +1,313 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace WBCR\Factory_420\Updates;
4
+
5
+ use Exception;
6
+ use stdClass;
7
+ use Wbcr_Factory420_Plugin;
8
+
9
+ // Exit if accessed directly
10
+ if ( ! defined( 'ABSPATH' ) ) {
11
+ exit;
12
+ }
13
+
14
+ /**
15
+ * @author Alex Kovalev <alex.kovalevv@gmail.com>, repo: https://github.com/alexkovalevv
16
+ * @author Webcraftic <wordpress.webraftic@gmail.com>, site: https://webcraftic.com
17
+ * @copyright (c) 2018 Webraftic Ltd
18
+ * @version 1.0
19
+ */
20
+ class Upgrader {
21
+
22
+ const CHECK_UPDATES_INTERVAL = "43200";
23
+
24
+ /**
25
+ * Список доступных классов для работы с репозиториями
26
+ *
27
+ * @author Alexander Kovalev <alex.kovalevv@gmail.com>
28
+ * @since 4.1.7
29
+ * @var array хранит имя репозитория и его имя класса
30
+ * [
31
+ * 'wordpress' => 'WBCR\Factory_Freemius_000\Updates\Freemius_Repository',
32
+ * 'freemius' => '\WBCR\Factory_420\Updates\Wordpress_Repository'
33
+ * ]
34
+ */
35
+ public static $repositories = [];
36
+
37
+ /**
38
+ * Тип апгрейдера, может быть default, premium
39
+ *
40
+ * @var string
41
+ */
42
+ protected $type = 'default';
43
+
44
+ /**
45
+ * @var Wbcr_Factory420_Plugin
46
+ */
47
+ protected $plugin;
48
+
49
+ /**
50
+ * @var string
51
+ */
52
+ protected $plugin_basename;
53
+
54
+ /**
55
+ * @var string
56
+ */
57
+ protected $plugin_main_file;
58
+
59
+ /**
60
+ * @var string
61
+ */
62
+ protected $plugin_absolute_path;
63
+
64
+ /**
65
+ * Имя плагина, для которого нужно проверять обновления
66
+ *
67
+ * @var string
68
+ */
69
+ protected $plugin_slug;
70
+
71
+ /**
72
+ * @var Repository
73
+ */
74
+ protected $repository;
75
+
76
+ /**
77
+ * @var array
78
+ */
79
+ protected $rollback = [
80
+ 'prev_stable_version' => null
81
+ ];
82
+
83
+ /**
84
+ * @var bool
85
+ */
86
+ protected $is_debug = false;
87
+
88
+ /**
89
+ * Manager constructor.
90
+ *
91
+ * @since 4.1.1
92
+ *
93
+ * @param Wbcr_Factory420_Plugin $plugin
94
+ * @param $args
95
+ * @param bool $is_premium
96
+ *
97
+ * @throws Exception
98
+ */
99
+ public function __construct( Wbcr_Factory420_Plugin $plugin ) {
100
+
101
+ $this->plugin = $plugin;
102
+
103
+ $this->plugin_basename = $plugin->get_paths()->basename;
104
+ $this->plugin_main_file = $plugin->get_paths()->main_file;
105
+ $this->plugin_absolute_path = $plugin->get_paths()->absolute;
106
+ $this->is_debug = defined( 'FACTORY_UPDATES_DEBUG' ) && FACTORY_UPDATES_DEBUG;
107
+
108
+ # Добавляем Wordpress репозиторий в список доступных репозиториев по умолчанию
109
+ self::$repositories['wordpress'] = '\WBCR\Factory_420\Updates\Wordpress_Repository';
110
+
111
+ $settings = $this->get_settings();
112
+
113
+ $this->plugin_slug = $settings['slug'];
114
+ $this->rollback = $settings['rollback_settings'];
115
+
116
+ if ( empty( $this->plugin_slug ) || ! is_string( $this->plugin_slug ) ) {
117
+ throw new Exception( 'Argument {slug} can not be empty and must be of type string.' );
118
+ }
119
+
120
+ $this->set_repository();
121
+
122
+ if ( $this->repository->need_check_updates() ) {
123
+ $this->init_hooks();
124
+ }
125
+ }
126
+
127
+ /**
128
+ * @throws Exception
129
+ */
130
+ protected function set_repository() {
131
+ $settings = $this->get_settings();
132
+ $this->repository = $this->get_repository( $settings['repository'] );
133
+ $this->repository->init();
134
+ }
135
+
136
+ /**
137
+ * @return array
138
+ */
139
+ protected function get_settings() {
140
+ $settings = $this->plugin->getPluginInfoAttr( 'updates_settings' );
141
+
142
+ return wp_parse_args( $settings, [
143
+ 'repository' => 'wordpress',
144
+ 'slug' => '',
145
+ 'maybe_rollback' => false,
146
+ 'rollback_settings' => [
147
+ 'prev_stable_version' => '0.0.0'
148
+ ]
149
+ ] );
150
+ }
151
+
152
+ /**
153
+ * @since 4.1.1
154
+ * @throws Exception
155
+ */
156
+ protected function init_hooks() {
157
+ add_filter( 'site_transient_update_plugins', [
158
+ $this,
159
+ 'site_transient_update_plugins_hook'
160
+ ] );
161
+
162
+ add_action( 'wp_update_plugins', [ $this, 'reset_check_update_timer' ], 9 ); // WP Cron.
163
+ add_action( 'deleted_site_transient', [ $this, 'reset_check_update_timer' ] );
164
+ add_action( 'setted_site_transient', [ $this, 'reset_check_update_timer' ] );
165
+ }
166
+
167
+
168
+ /**
169
+ * When WP sets the update_plugins site transient, we set our own transient
170
+ *
171
+ * @since 4.1.1
172
+ *
173
+ * @param Object $transient Site transient object.
174
+ *
175
+ * @throws Exception
176
+ */
177
+ public function site_transient_update_plugins_hook( $transient ) {
178
+
179
+ if ( ! $transient || ! is_object( $transient ) ) {
180
+ return $transient;
181
+ }
182
+
183
+ $temp_object = $this->check_updates();
184
+
185
+ if ( ! empty( $temp_object ) && is_object( $temp_object ) && version_compare( $this->get_plugin_version(), $temp_object->new_version, '<' ) ) {
186
+ $transient->response[ $temp_object->plugin ] = $temp_object;
187
+
188
+ return $transient;
189
+ }
190
+
191
+ return $transient;
192
+ }
193
+
194
+ /**
195
+ * When WP deletes the update_plugins site transient or updates the plugins, we delete our own transients to avoid another 12 hours waiting
196
+ *
197
+ * @since 4.1.1
198
+ *
199
+ * @param string $transient Transient name.
200
+ * @param object $value Transient object.
201
+ */
202
+ public function reset_check_update_timer( $transient = 'update_plugins', $value = null ) {
203
+ $options_prefix = $this->type == "default" ? "" : "_" . $this->type;
204
+
205
+ // $value used by setted.
206
+ if ( 'update_plugins' === $transient ) {
207
+ if ( is_null( $value ) || is_object( $value ) && ! isset( $value->response ) ) {
208
+
209
+ $last_check_time = (int) $this->plugin->getPopulateOption( "last_check{$options_prefix}_update_time", 0 );
210
+
211
+ if ( 0 !== $last_check_time && time() > ( $last_check_time + MINUTE_IN_SECONDS ) ) {
212
+ $this->plugin->deletePopulateOption( "last_check{$options_prefix}_update_time" );
213
+ $this->plugin->deletePopulateOption( "last_check{$options_prefix}_update" );
214
+ }
215
+ }
216
+ }
217
+ }
218
+
219
+ /**
220
+ * Проверяет последние обновления для текущего или премиум плагина.
221
+ *
222
+ * @since 4.1.1
223
+ * @return object|null
224
+ * @throws Exception
225
+ */
226
+ protected function check_updates( $force = false ) {
227
+
228
+ $options_prefix = $this->type == "default" ? "" : "_" . $this->type;
229
+ $check_updates_interval = self::CHECK_UPDATES_INTERVAL;
230
+ $last_check_time = (int) $this->plugin->getPopulateOption( "last_check{$options_prefix}_update_time", 0 );
231
+
232
+ if ( $this->is_debug && defined( 'FACTORY_CHECK_UPDATES_INTERVAL' ) ) {
233
+ $check_updates_interval = FACTORY_CHECK_UPDATES_INTERVAL;
234
+ if ( empty( $check_updates_interval ) || ! is_numeric( $check_updates_interval ) ) {
235
+ $check_updates_interval = MINUTE_IN_SECONDS;
236
+ }
237
+ }
238
+
239
+ if ( $force || ( time() > ( $last_check_time + $check_updates_interval ) ) ) {
240
+
241
+ $this->plugin->updatePopulateOption( "last_check{$options_prefix}_update_time", time() );
242
+
243
+ $last_version = $this->repository->get_last_version();
244
+
245
+ if ( ! empty( $last_version ) ) {
246
+ $temp_object = new stdClass();
247
+ $temp_object->slug = $this->plugin_slug;
248
+ $temp_object->plugin = $this->plugin_basename;
249
+ $temp_object->new_version = $last_version;
250
+ $temp_object->package = $this->repository->get_download_url();
251
+
252
+ $this->plugin->updatePopulateOption( "last_check{$options_prefix}_update", $temp_object );
253
+
254
+ return $temp_object;
255
+ }
256
+ }
257
+
258
+ return $this->plugin->getPopulateOption( "last_check{$options_prefix}_update" );
259
+ }
260
+
261
+ /**
262
+ * @since 4.1.1
263
+ *
264
+ * @param $args
265
+ *
266
+ * @return string
267
+ */
268
+ protected function get_admin_url( $args ) {
269
+ $url = admin_url( 'plugins.php', $args );
270
+
271
+ if ( $this->plugin->isNetworkActive() ) {
272
+ $url = network_admin_url( 'plugins.php', $args );
273
+ }
274
+
275
+ return add_query_arg( $args, $url );
276
+ }
277
+
278
+ /**
279
+ * @since 4.1.1
280
+ *
281
+ * @param $repository_name
282
+ *
283
+ * @return Repository
284
+ * @throws Exception
285
+ */
286
+ protected function get_repository( $repository_name ) {
287
+
288
+ if ( isset( self::$repositories[ $repository_name ] ) && class_exists( self::$repositories[ $repository_name ] ) ) {
289
+ if ( self::$repositories[ $repository_name ] instanceof Repository ) {
290
+ throw new Exception( "Repository {$repository_name} must extend the class WBCR\Factory_420\Updates\Repository interface!" );
291
+ }
292
+
293
+ return new self::$repositories[ $repository_name ]( $this->plugin );
294
+ }
295
+
296
+ throw new Exception( "Repository {$repository_name} is not supported!" );
297
+ }
298
+
299
+ /**
300
+ * @since 4.1.1
301
+ * @return string
302
+ */
303
+ protected function get_plugin_version() {
304
+ return $this->plugin->getPluginVersion();
305
+ }
306
+
307
+ /**
308
+ * @since 4.1.1
309
+ */
310
+ protected function rollback() {
311
+
312
+ }
313
+ }
libs/factory/core/includes/updates/index.php ADDED
@@ -0,0 +1,2 @@
 
 
1
+ <?php
2
+ // Silence is golden.
libs/factory/core/includes/updates/repositories/class-factory-repository-abstract.php ADDED
@@ -0,0 +1,62 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace WBCR\Factory_420\Updates;
4
+
5
+ // Exit if accessed directly
6
+ use Wbcr_Factory420_Plugin;
7
+
8
+ if ( ! defined( 'ABSPATH' ) ) {
9
+ exit;
10
+ }
11
+
12
+ /**
13
+ * @author Alex Kovalev <alex.kovalevv@gmail.com>, repo: https://github.com/alexkovalevv
14
+ * @author Webcraftic <wordpress.webraftic@gmail.com>, site: https://webcraftic.com
15
+ * @copyright (c) 2018 Webraftic Ltd
16
+ * @version 1.0
17
+ */
18
+ abstract class Repository {
19
+
20
+ /**
21
+ * @var bool
22
+ */
23
+ protected $initialized = false;
24
+
25
+ /**
26
+ * @var Wbcr_Factory420_Plugin
27
+ */
28
+ protected $plugin;
29
+
30
+ /**
31
+ * Repository constructor.
32
+ *
33
+ * @param Wbcr_Factory420_Plugin $plugin
34
+ * @param bool $is_premium
35
+ */
36
+ abstract public function __construct( Wbcr_Factory420_Plugin $plugin );
37
+
38
+ /**
39
+ * @return void
40
+ */
41
+ abstract public function init();
42
+
43
+ /**
44
+ * @return bool
45
+ */
46
+ abstract public function need_check_updates();
47
+
48
+ /**
49
+ * @return mixed
50
+ */
51
+ abstract public function is_support_premium();
52
+
53
+ /**
54
+ * @return string
55
+ */
56
+ abstract public function get_download_url();
57
+
58
+ /**
59
+ * @return string
60
+ */
61
+ abstract public function get_last_version();
62
+ }
libs/factory/core/includes/updates/repositories/class-factory-wordpress.php ADDED
@@ -0,0 +1,72 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace WBCR\Factory_420\Updates;
4
+
5
+ // Exit if accessed directly
6
+ use Wbcr_Factory420_Plugin;
7
+
8
+ if ( ! defined( 'ABSPATH' ) ) {
9
+ exit;
10
+ }
11
+
12
+ /**
13
+ * @author Alex Kovalev <alex.kovalevv@gmail.com>, repo: https://github.com/alexkovalevv
14
+ * @author Webcraftic <wordpress.webraftic@gmail.com>, site: https://webcraftic.com
15
+ * @copyright (c) 2018 Webraftic Ltd
16
+ * @version 1.0
17
+ */
18
+ class Wordpress_Repository extends Repository {
19
+
20
+ /**
21
+ * Wordpress constructor.
22
+ *
23
+ * @param Wbcr_Factory420_Plugin $plugin
24
+ * @param bool $is_premium
25
+ */
26
+ public function __construct( Wbcr_Factory420_Plugin $plugin ) {
27
+ $this->plugin = $plugin;
28
+ }
29
+
30
+ public function init() {
31
+ // TODO: Implement init() method.
32
+ }
33
+
34
+ /**
35
+ * @return bool
36
+ */
37
+ public function need_check_updates() {
38
+ return false;
39
+ }
40
+
41
+ /**
42
+ * @return bool
43
+ */
44
+ public function is_support_premium() {
45
+ return false;
46
+ }
47
+
48
+ /**
49
+ * @return string
50
+ */
51
+ public function get_download_url() {
52
+ return '';
53
+ }
54
+
55
+ /**
56
+ * @return string
57
+ */
58
+ public function get_last_version() {
59
+ return '0.0.0';
60
+ }
61
+
62
+ public function check_updates() {
63
+
64
+ }
65
+
66
+ /**
67
+ * @return bool
68
+ */
69
+ public function need_update() {
70
+ return false;
71
+ }
72
+ }
{languages → libs/factory/core/includes/updates/repositories}/index.php RENAMED
File without changes
libs/factory/core/index.php ADDED
@@ -0,0 +1,2 @@
 
 
1
+ <?php
2
+ // Silence is golden.
libs/factory/core/langs/index.php ADDED
@@ -0,0 +1,2 @@
 
 
1
+ <?php
2
+ // Silence is golden.
libs/factory/core/langs/wbcr_factory_420-ru_RU.mo ADDED
Binary file
libs/factory/core/langs/wbcr_factory_420-ru_RU.po ADDED
@@ -0,0 +1,128 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ msgid ""
2
+ msgstr ""
3
+ "Project-Id-Version: factory_forms\n"
4
+ "POT-Creation-Date: 2018-10-16 22:44+0300\n"
5
+ "PO-Revision-Date: 2018-10-16 22:45+0300\n"
6
+ "Last-Translator: \n"
7
+ "Language-Team: Alex Kovalev <alex.kovalevv@gmail.com>\n"
8
+ "Language: ru_RU\n"
9
+ "MIME-Version: 1.0\n"
10
+ "Content-Type: text/plain; charset=UTF-8\n"
11
+ "Content-Transfer-Encoding: 8bit\n"
12
+ "X-Generator: Poedit 2.1.1\n"
13
+ "X-Poedit-Basepath: ..\n"
14
+ "Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
15
+ "%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
16
+ "X-Poedit-SourceCharset: UTF-8\n"
17
+ "X-Poedit-KeywordsList: __;_e;_n:1,2;_x:1,2c;_ex:1,2c\n"
18
+ "X-Poedit-SearchPath-0: .\n"
19
+
20
+ #: includes/check-compatibility.php:80
21
+ msgid "warning"
22
+ msgstr "предупреждение"
23
+
24
+ #: includes/check-compatibility.php:82
25
+ #, php-format
26
+ msgid "The %s plugin has stopped."
27
+ msgstr "Работа плагина %s была остановлена."
28
+
29
+ #: includes/check-compatibility.php:83
30
+ msgid "Possible reasons:"
31
+ msgstr "Возможные причины:"
32
+
33
+ #: includes/check-compatibility.php:89
34
+ #, php-format
35
+ msgid "You need to update the PHP version to %s or higher!"
36
+ msgstr "Вам нужно обновить версию PHP до %s или выше!"
37
+
38
+ #: includes/check-compatibility.php:94
39
+ #, php-format
40
+ msgid "You need to update WordPress to %s or higher!"
41
+ msgstr "Вам нужно обновить WordPress до %s или выше!"
42
+
43
+ #: includes/functions.php:132
44
+ #, php-format
45
+ msgid ""
46
+ "%1$s is <strong>deprecated</strong> since version %2$s! Use %3$s instead."
47
+ msgstr ""
48
+ "%1$s является <strong>устаревшим,</strong> начиная с версии %2$s в "
49
+ "Wordpress! Используйте %3$s."
50
+
51
+ #: includes/functions.php:134
52
+ #, php-format
53
+ msgid ""
54
+ "%1$s is <strong>deprecated</strong> since version %2$s with no alternative "
55
+ "available."
56
+ msgstr ""
57
+ "%1$s был вызван с параметром, который является <strong>устаревшими</strong> "
58
+ "начиная с версии %2$s , в настоящее время доступных альтернатив нет."
59
+
60
+ #: includes/plugin.class.php:202 includes/plugin.class.php:237
61
+ msgid ""
62
+ "You are trying to call this earlier than the plugin menu will be registered."
63
+ msgstr ""
64
+ "Вы пытаетесь вызвать это раньше, чем будет зарегистрировано меню плагина."
65
+
66
+ #: includes/plugin.class.php:220
67
+ msgid ""
68
+ "You are trying to get a link to a page that does not have multisite mode. "
69
+ "Clicking this link will lead the user to a non-existent page."
70
+ msgstr ""
71
+ "Вы пытаетесь получить ссылку на страницу, которая не имеет "
72
+ "многопользовательского режима. Щелчок по этой ссылке приведет пользователя "
73
+ "к несуществующей странице."
74
+
75
+ #: includes/plugin.class.php:222
76
+ msgid ""
77
+ "Trying to get a link to an unregistered page. You are trying to call this "
78
+ "earlier than the plugin menu will be registered."
79
+ msgstr ""
80
+ "Попытка получить ссылку на незарегистрированную страницу. Вы пытаетесь "
81
+ "вызвать это раньше, чем будет зарегистрировано меню плагина."
82
+
83
+ #~ msgid "On"
84
+ #~ msgstr "Вкл"
85
+
86
+ #~ msgid "Off"
87
+ #~ msgstr "Выкл"
88
+
89
+ #~ msgid "(use default website font)"
90
+ #~ msgstr "(шрифт сайта по умолчанию)"
91
+
92
+ #~ msgid "Sans Serif:"
93
+ #~ msgstr "Группа Sans Serif:"
94
+
95
+ #~ msgid "Serif:"
96
+ #~ msgstr "Группа Serif:"
97
+
98
+ #~ msgid "Monospaced:"
99
+ #~ msgstr "Группа Monospaced:"
100
+
101
+ #~ msgid "vertical"
102
+ #~ msgstr "вертикальный"
103
+
104
+ #~ msgid "horizontal"
105
+ #~ msgstr "горизонтальный"
106
+
107
+ #~ msgid "hide extra options"
108
+ #~ msgstr "скрыть дополнительные настроки"
109
+
110
+ #~ msgid "Select a side and move the slider to set up:"
111
+ #~ msgstr "Выберите сторону и переместите ползунок:"
112
+
113
+ #~ msgid "Change color"
114
+ #~ msgstr "Выбрать цвет"
115
+
116
+ #~ msgid "re-color"
117
+ #~ msgstr "Перекрасить"
118
+
119
+ #~ msgid "Select color:"
120
+ #~ msgstr "Выберите цвет:"
121
+
122
+ #~ msgid "Changing the color may takes a minute or more. Please be patient."
123
+ #~ msgstr ""
124
+ #~ "В некоторых случаях изменение цвета может занять около минуты. "
125
+ #~ "Пожалуйста, будьте терпеливы."
126
+
127
+ #~ msgid "Upload Pattern"
128
+ #~ msgstr "Добавить шаблон"
libs/factory/forms/boot.php CHANGED
@@ -1,271 +1,273 @@
1
  <?php
2
- /**
3
- * Factory Forms
4
- *
5
- * @author Alex Kovalev <alex.kovalevv@gmail.com>
6
- * @copyright (c) 2018, Webcraftic Ltd
7
- *
8
- * @package factory-forms
9
- * @since 1.0.1
10
- */
11
 
12
- // Exit if accessed directly
13
- if( !defined('ABSPATH') ) {
14
- exit;
15
- }
16
 
17
- // the module provides function for the admin area only
18
 
19
- if( !is_admin() ) {
20
- return;
21
- }
22
 
23
- // checks if the module is already loaded in order to
24
- // prevent loading the same version of the module twice.
25
- if( defined('FACTORY_FORMS_400_LOADED') ) {
26
- return;
27
- }
28
 
29
- define('FACTORY_FORMS_400_LOADED', true);
30
 
31
- // absolute path and URL to the files and resources of the module.
32
- define('FACTORY_FORMS_400_DIR', dirname(__FILE__));
33
- define('FACTORY_FORMS_400_URL', plugins_url(null, __FILE__));
34
 
35
- #comp merge
36
- require_once(FACTORY_FORMS_400_DIR . '/includes/providers/value-provider.interface.php');
37
- require_once(FACTORY_FORMS_400_DIR . '/includes/providers/meta-value-provider.class.php');
38
- require_once(FACTORY_FORMS_400_DIR . '/includes/providers/options-value-provider.class.php');
39
 
40
- require_once(FACTORY_FORMS_400_DIR . '/includes/form.class.php');
41
- #endcomp
 
 
42
 
43
- load_plugin_textdomain('wbcr_factory_forms_400', false, dirname(plugin_basename(__FILE__)) . '/langs');
 
 
 
 
 
 
 
 
 
 
 
 
 
44
 
45
  /**
46
- * We add this code into the hook because all these controls quite heavy. So in order to get better perfomance,
47
- * we load the form controls only on pages where the forms are created.
48
  *
49
- * @see the 'wbcr_factory_forms_400_register_controls' hook
50
- *
51
- * @since 3.0.7
52
  */
53
- if( !function_exists('wbcr_factory_forms_400_register_default_controls') ) {
54
-
55
- /**
56
- * @param Wbcr_Factory400_Plugin $plugin
57
- * @throws Exception
58
- */
59
- function wbcr_factory_forms_400_register_default_controls(Wbcr_Factory400_Plugin $plugin)
60
- {
61
 
62
- if( $plugin && !isset($plugin->forms) ) {
63
- throw new Exception("The module Factory Forms is not loaded for the plugin '{$plugin->getPluginName()}'.");
64
- }
65
 
66
- require_once(FACTORY_FORMS_400_DIR . '/includes/html-builder.class.php');
67
- require_once(FACTORY_FORMS_400_DIR . '/includes/form-element.class.php');
68
- require_once(FACTORY_FORMS_400_DIR . '/includes/control.class.php');
69
- require_once(FACTORY_FORMS_400_DIR . '/includes/complex-control.class.php');
70
- require_once(FACTORY_FORMS_400_DIR . '/includes/holder.class.php');
71
- require_once(FACTORY_FORMS_400_DIR . '/includes/control-holder.class.php');
72
- require_once(FACTORY_FORMS_400_DIR . '/includes/custom-element.class.php');
73
- require_once(FACTORY_FORMS_400_DIR . '/includes/form-layout.class.php');
74
 
75
- // registration of controls
76
- $plugin->forms->registerControls(array(
77
- array(
78
- 'type' => 'checkbox',
79
- 'class' => 'Wbcr_FactoryForms400_CheckboxControl',
80
- 'include' => FACTORY_FORMS_400_DIR . '/controls/checkbox.php'
81
- ),
82
- array(
83
- 'type' => 'list',
84
- 'class' => 'Wbcr_FactoryForms400_ListControl',
85
- 'include' => FACTORY_FORMS_400_DIR . '/controls/list.php'
86
- ),
87
- array(
88
- 'type' => 'dropdown',
89
- 'class' => 'Wbcr_FactoryForms400_DropdownControl',
90
- 'include' => FACTORY_FORMS_400_DIR . '/controls/dropdown.php'
91
- ),
92
- array(
93
- 'type' => 'dropdown-and-colors',
94
- 'class' => 'Wbcr_FactoryForms400_DropdownAndColorsControl',
95
- 'include' => FACTORY_FORMS_400_DIR . '/controls/dropdown-and-colors.php'
96
- ),
97
- array(
98
- 'type' => 'hidden',
99
- 'class' => 'Wbcr_FactoryForms400_HiddenControl',
100
- 'include' => FACTORY_FORMS_400_DIR . '/controls/hidden.php'
101
- ),
102
- array(
103
- 'type' => 'hidden',
104
- 'class' => 'Wbcr_FactoryForms400_HiddenControl',
105
- 'include' => FACTORY_FORMS_400_DIR . '/controls/hidden.php'
106
- ),
107
- array(
108
- 'type' => 'radio',
109
- 'class' => 'Wbcr_FactoryForms400_RadioControl',
110
- 'include' => FACTORY_FORMS_400_DIR . '/controls/radio.php'
111
- ),
112
- array(
113
- 'type' => 'radio-colors',
114
- 'class' => 'Wbcr_FactoryForms400_RadioColorsControl',
115
- 'include' => FACTORY_FORMS_400_DIR . '/controls/radio-colors.php'
116
- ),
117
- array(
118
- 'type' => 'textarea',
119
- 'class' => 'Wbcr_FactoryForms400_TextareaControl',
120
- 'include' => FACTORY_FORMS_400_DIR . '/controls/textarea.php'
121
- ),
122
- array(
123
- 'type' => 'textbox',
124
- 'class' => 'Wbcr_FactoryForms400_TextboxControl',
125
- 'include' => FACTORY_FORMS_400_DIR . '/controls/textbox.php'
126
- ),
127
- array(
128
- 'type' => 'multiple-textbox',
129
- 'class' => 'Wbcr_FactoryForms400_MultipleTextboxControl',
130
- 'include' => FACTORY_FORMS_400_DIR . '/controls/multiple-textbox.php'
131
- ),
132
- array(
133
- 'type' => 'datetimepicker-range',
134
- 'class' => 'Wbcr_FactoryForms400_DatepickerRangeControl',
135
- 'include' => FACTORY_FORMS_400_DIR . '/controls/datepicker-range.php'
136
- ),
137
- array(
138
- 'type' => 'url',
139
- 'class' => 'Wbcr_FactoryForms400_UrlControl',
140
- 'include' => FACTORY_FORMS_400_DIR . '/controls/url.php'
141
- ),
142
- array(
143
- 'type' => 'wp-editor',
144
- 'class' => 'Wbcr_FactoryForms400_WpEditorControl',
145
- 'include' => FACTORY_FORMS_400_DIR . '/controls/wp-editor.php'
146
- ),
147
- array(
148
- 'type' => 'color',
149
- 'class' => 'Wbcr_FactoryForms400_ColorControl',
150
- 'include' => FACTORY_FORMS_400_DIR . '/controls/color.php'
151
- ),
152
- array(
153
- 'type' => 'color-and-opacity',
154
- 'class' => 'Wbcr_FactoryForms400_ColorAndOpacityControl',
155
- 'include' => FACTORY_FORMS_400_DIR . '/controls/color-and-opacity.php'
156
- ),
157
- array(
158
- 'type' => 'gradient',
159
- 'class' => 'Wbcr_FactoryForms400_GradientControl',
160
- 'include' => FACTORY_FORMS_400_DIR . '/controls/gradient.php'
161
- ),
162
- array(
163
- 'type' => 'font',
164
- 'class' => 'Wbcr_FactoryForms400_FontControl',
165
- 'include' => FACTORY_FORMS_400_DIR . '/controls/font.php'
166
- ),
167
- array(
168
- 'type' => 'google-font',
169
- 'class' => 'Wbcr_FactoryForms400_GoogleFontControl',
170
- 'include' => FACTORY_FORMS_400_DIR . '/controls/google-font.php'
171
- ),
172
- array(
173
- 'type' => 'pattern',
174
- 'class' => 'Wbcr_FactoryForms400_PatternControl',
175
- 'include' => FACTORY_FORMS_400_DIR . '/controls/pattern.php'
176
- ),
177
- array(
178
- 'type' => 'integer',
179
- 'class' => 'Wbcr_FactoryForms400_IntegerControl',
180
- 'include' => FACTORY_FORMS_400_DIR . '/controls/integer.php'
181
- ),
182
- array(
183
- 'type' => 'control-group',
184
- 'class' => 'Wbcr_FactoryForms400_ControlGroupHolder',
185
- 'include' => FACTORY_FORMS_400_DIR . '/controls/holders/control-group.php'
186
- ),
187
- array(
188
- 'type' => 'paddings-editor',
189
- 'class' => 'Wbcr_FactoryForms400_PaddingsEditorControl',
190
- 'include' => FACTORY_FORMS_400_DIR . '/controls/paddings-editor.php'
191
- ),
192
- ));
193
 
194
- // registration of control holders
195
- $plugin->forms->registerHolders(array(
196
- array(
197
- 'type' => 'tab',
198
- 'class' => 'Wbcr_FactoryForms400_TabHolder',
199
- 'include' => FACTORY_FORMS_400_DIR . '/controls/holders/tab.php'
200
- ),
201
- array(
202
- 'type' => 'tab-item',
203
- 'class' => 'Wbcr_FactoryForms400_TabItemHolder',
204
- 'include' => FACTORY_FORMS_400_DIR . '/controls/holders/tab-item.php'
205
- ),
206
- array(
207
- 'type' => 'accordion',
208
- 'class' => 'Wbcr_FactoryForms400_AccordionHolder',
209
- 'include' => FACTORY_FORMS_400_DIR . '/controls/holders/accordion.php'
210
- ),
211
- array(
212
- 'type' => 'accordion-item',
213
- 'class' => 'Wbcr_FactoryForms400_AccordionItemHolder',
214
- 'include' => FACTORY_FORMS_400_DIR . '/controls/holders/accordion-item.php'
215
- ),
216
- array(
217
- 'type' => 'control-group',
218
- 'class' => 'Wbcr_FactoryForms400_ControlGroupHolder',
219
- 'include' => FACTORY_FORMS_400_DIR . '/controls/holders/control-group.php'
220
- ),
221
- array(
222
- 'type' => 'control-group-item',
223
- 'class' => 'Wbcr_FactoryForms400_ControlGroupItem',
224
- 'include' => FACTORY_FORMS_400_DIR . '/controls/holders/control-group-item.php'
225
- ),
226
- array(
227
- 'type' => 'form-group',
228
- 'class' => 'Wbcr_FactoryForms400_FormGroupHolder',
229
- 'include' => FACTORY_FORMS_400_DIR . '/controls/holders/form-group.php'
230
- ),
231
- array(
232
- 'type' => 'more-link',
233
- 'class' => 'Wbcr_FactoryForms400_MoreLinkHolder',
234
- 'include' => FACTORY_FORMS_400_DIR . '/controls/holders/more-link.php'
235
- ),
236
- array(
237
- 'type' => 'div',
238
- 'class' => 'Wbcr_FactoryForms400_DivHolder',
239
- 'include' => FACTORY_FORMS_400_DIR . '/controls/holders/div.php'
240
- ),
241
- array(
242
- 'type' => 'columns',
243
- 'class' => 'Wbcr_FactoryForms400_ColumnsHolder',
244
- 'include' => FACTORY_FORMS_400_DIR . '/controls/holders/columns.php'
245
- )
246
- ));
247
 
248
- // registration custom form elements
249
- $plugin->forms->registerCustomElements(array(
250
- array(
251
- 'type' => 'html',
252
- 'class' => 'Wbcr_FactoryForms400_Html',
253
- 'include' => FACTORY_FORMS_400_DIR . '/controls/customs/html.php',
254
- ),
255
- array(
256
- 'type' => 'separator',
257
- 'class' => 'Wbcr_FactoryForms400_Separator',
258
- 'include' => FACTORY_FORMS_400_DIR . '/controls/customs/separator.php',
259
- ),
260
- ));
261
 
262
- // registration of form layouts
263
- $plugin->forms->registerFormLayout(array(
264
- 'name' => 'bootstrap-3',
265
- 'class' => 'Wbcr_FactoryForms400_Bootstrap3FormLayout',
266
- 'include' => FACTORY_FORMS_400_DIR . '/layouts/bootstrap-3/bootstrap-3.php'
267
- ));
268
- }
269
 
270
- add_action('wbcr_factory_forms_400_register_controls', 'wbcr_factory_forms_400_register_default_controls');
271
- }
1
  <?php
2
+ /**
3
+ * Factory Forms
4
+ *
5
+ * @author Alex Kovalev <alex.kovalevv@gmail.com>
6
+ * @since 1.0.1
7
+ * @package factory-forms
8
+ * @copyright (c) 2018, Webcraftic Ltd
9
+ *
10
+ */
11
 
12
+ // Exit if accessed directly
13
+ if ( ! defined( 'ABSPATH' ) ) {
14
+ exit;
15
+ }
16
 
17
+ // the module provides function for the admin area only
18
 
19
+ if ( ! is_admin() ) {
20
+ return;
21
+ }
22
 
23
+ // checks if the module is already loaded in order to
24
+ // prevent loading the same version of the module twice.
25
+ if ( defined( 'FACTORY_FORMS_418_LOADED' ) ) {
26
+ return;
27
+ }
28
 
29
+ define( 'FACTORY_FORMS_418_LOADED', true );
30
 
31
+ define( 'FACTORY_FORMS_418_VERSION', '4.1.8' );
 
 
32
 
33
+ // absolute path and URL to the files and resources of the module.
34
+ define( 'FACTORY_FORMS_418_DIR', dirname( __FILE__ ) );
35
+ define( 'FACTORY_FORMS_418_URL', plugins_url( null, __FILE__ ) );
 
36
 
37
+ #comp merge
38
+ require_once( FACTORY_FORMS_418_DIR . '/includes/providers/value-provider.interface.php' );
39
+ require_once( FACTORY_FORMS_418_DIR . '/includes/providers/meta-value-provider.class.php' );
40
+ require_once( FACTORY_FORMS_418_DIR . '/includes/providers/options-value-provider.class.php' );
41
 
42
+ require_once( FACTORY_FORMS_418_DIR . '/includes/form.class.php' );
43
+ #endcomp
44
+
45
+ load_plugin_textdomain( 'wbcr_factory_forms_418', false, dirname( plugin_basename( __FILE__ ) ) . '/langs' );
46
+
47
+ /**
48
+ * We add this code into the hook because all these controls quite heavy. So in order to get better perfomance,
49
+ * we load the form controls only on pages where the forms are created.
50
+ *
51
+ * @since 3.0.7
52
+ * @see the 'wbcr_factory_forms_418_register_controls' hook
53
+ *
54
+ */
55
+ if ( ! function_exists( 'wbcr_factory_forms_418_register_default_controls' ) ) {
56
 
57
  /**
58
+ * @param Wbcr_Factory420_Plugin $plugin
 
59
  *
60
+ * @throws Exception
 
 
61
  */
62
+ function wbcr_factory_forms_418_register_default_controls( Wbcr_Factory420_Plugin $plugin ) {
 
 
 
 
 
 
 
63
 
64
+ if ( $plugin && ! isset( $plugin->forms ) ) {
65
+ throw new Exception( "The module Factory Forms is not loaded for the plugin '{$plugin->getPluginName()}'." );
66
+ }
67
 
68
+ require_once( FACTORY_FORMS_418_DIR . '/includes/html-builder.class.php' );
69
+ require_once( FACTORY_FORMS_418_DIR . '/includes/form-element.class.php' );
70
+ require_once( FACTORY_FORMS_418_DIR . '/includes/control.class.php' );
71
+ require_once( FACTORY_FORMS_418_DIR . '/includes/complex-control.class.php' );
72
+ require_once( FACTORY_FORMS_418_DIR . '/includes/holder.class.php' );
73
+ require_once( FACTORY_FORMS_418_DIR . '/includes/control-holder.class.php' );
74
+ require_once( FACTORY_FORMS_418_DIR . '/includes/custom-element.class.php' );
75
+ require_once( FACTORY_FORMS_418_DIR . '/includes/form-layout.class.php' );
76
 
77
+ // registration of controls
78
+ $plugin->forms->registerControls( [
79
+ [
80
+ 'type' => 'checkbox',
81
+ 'class' => 'Wbcr_FactoryForms418_CheckboxControl',
82
+ 'include' => FACTORY_FORMS_418_DIR . '/controls/checkbox.php'
83
+ ],
84
+ [
85
+ 'type' => 'list',
86
+ 'class' => 'Wbcr_FactoryForms418_ListControl',
87
+ 'include' => FACTORY_FORMS_418_DIR . '/controls/list.php'
88
+ ],
89
+ [
90
+ 'type' => 'dropdown',
91
+ 'class' => 'Wbcr_FactoryForms418_DropdownControl',
92
+ 'include' => FACTORY_FORMS_418_DIR . '/controls/dropdown.php'
93
+ ],
94
+ [
95
+ 'type' => 'dropdown-and-colors',
96
+ 'class' => 'Wbcr_FactoryForms418_DropdownAndColorsControl',
97
+ 'include' => FACTORY_FORMS_418_DIR . '/controls/dropdown-and-colors.php'
98
+ ],
99
+ [
100
+ 'type' => 'hidden',
101
+ 'class' => 'Wbcr_FactoryForms418_HiddenControl',
102
+ 'include' => FACTORY_FORMS_418_DIR . '/controls/hidden.php'
103
+ ],
104
+ [
105
+ 'type' => 'hidden',
106
+ 'class' => 'Wbcr_FactoryForms418_HiddenControl',
107
+ 'include' => FACTORY_FORMS_418_DIR . '/controls/hidden.php'
108
+ ],
109
+ [
110
+ 'type' => 'radio',
111
+ 'class' => 'Wbcr_FactoryForms418_RadioControl',
112
+ 'include' => FACTORY_FORMS_418_DIR . '/controls/radio.php'
113
+ ],
114
+ [
115
+ 'type' => 'radio-colors',
116
+ 'class' => 'Wbcr_FactoryForms418_RadioColorsControl',
117
+ 'include' => FACTORY_FORMS_418_DIR . '/controls/radio-colors.php'
118
+ ],
119
+ [
120
+ 'type' => 'textarea',
121
+ 'class' => 'Wbcr_FactoryForms418_TextareaControl',
122
+ 'include' => FACTORY_FORMS_418_DIR . '/controls/textarea.php'
123
+ ],
124
+ [
125
+ 'type' => 'textbox',
126
+ 'class' => 'Wbcr_FactoryForms418_TextboxControl',
127
+ 'include' => FACTORY_FORMS_418_DIR . '/controls/textbox.php'
128
+ ],
129
+ [
130
+ 'type' => 'multiple-textbox',
131
+ 'class' => 'Wbcr_FactoryForms418_MultipleTextboxControl',
132
+ 'include' => FACTORY_FORMS_418_DIR . '/controls/multiple-textbox.php'
133
+ ],
134
+ [
135
+ 'type' => 'datetimepicker-range',
136
+ 'class' => 'Wbcr_FactoryForms418_DatepickerRangeControl',
137
+ 'include' => FACTORY_FORMS_418_DIR . '/controls/datepicker-range.php'
138
+ ],
139
+ [
140
+ 'type' => 'url',
141
+ 'class' => 'Wbcr_FactoryForms418_UrlControl',
142
+ 'include' => FACTORY_FORMS_418_DIR . '/controls/url.php'
143
+ ],
144
+ [
145
+ 'type' => 'wp-editor',
146
+ 'class' => 'Wbcr_FactoryForms418_WpEditorControl',
147
+ 'include' => FACTORY_FORMS_418_DIR . '/controls/wp-editor.php'
148
+ ],
149
+ [
150
+ 'type' => 'color',
151
+ 'class' => 'Wbcr_FactoryForms418_ColorControl',
152
+ 'include' => FACTORY_FORMS_418_DIR . '/controls/color.php'
153
+ ],
154
+ [
155
+ 'type' => 'color-and-opacity',
156
+ 'class' => 'Wbcr_FactoryForms418_ColorAndOpacityControl',
157
+ 'include' => FACTORY_FORMS_418_DIR . '/controls/color-and-opacity.php'
158
+ ],
159
+ [
160
+ 'type' => 'gradient',
161
+ 'class' => 'Wbcr_FactoryForms418_GradientControl',
162
+ 'include' => FACTORY_FORMS_418_DIR . '/controls/gradient.php'
163
+ ],
164
+ [
165
+ 'type' => 'font',
166
+ 'class' => 'Wbcr_FactoryForms418_FontControl',
167
+ 'include' => FACTORY_FORMS_418_DIR . '/controls/font.php'
168
+ ],
169
+ [
170
+ 'type' => 'google-font',
171
+ 'class' => 'Wbcr_FactoryForms418_GoogleFontControl',
172
+ 'include' => FACTORY_FORMS_418_DIR . '/controls/google-font.php'
173
+ ],
174
+ [
175
+ 'type' => 'pattern',
176
+ 'class' => 'Wbcr_FactoryForms418_PatternControl',
177
+ 'include' => FACTORY_FORMS_418_DIR . '/controls/pattern.php'
178
+ ],
179
+ [
180
+ 'type' => 'integer',
181
+ 'class' => 'Wbcr_FactoryForms418_IntegerControl',
182
+ 'include' => FACTORY_FORMS_418_DIR . '/controls/integer.php'
183
+ ],
184
+ [
185
+ 'type' => 'control-group',
186
+ 'class' => 'Wbcr_FactoryForms418_ControlGroupHolder',
187
+ 'include' => FACTORY_FORMS_418_DIR . '/controls/holders/control-group.php'
188
+ ],
189
+ [
190
+ 'type' => 'paddings-editor',
191
+ 'class' => 'Wbcr_FactoryForms418_PaddingsEditorControl',
192
+ 'include' => FACTORY_FORMS_418_DIR . '/controls/paddings-editor.php'
193
+ ],
194
+ ] );
195
 
196
+ // registration of control holders
197
+ $plugin->forms->registerHolders( [
198
+ [
199
+ 'type' => 'tab',
200
+ 'class' => 'Wbcr_FactoryForms418_TabHolder',
201
+ 'include' => FACTORY_FORMS_418_DIR . '/controls/holders/tab.php'
202
+ ],
203
+ [
204
+ 'type' => 'tab-item',
205
+ 'class' => 'Wbcr_FactoryForms418_TabItemHolder',
206
+ 'include' => FACTORY_FORMS_418_DIR . '/controls/holders/tab-item.php'
207
+ ],
208
+ [
209
+ 'type' => 'accordion',
210
+ 'class' => 'Wbcr_FactoryForms418_AccordionHolder',
211
+ 'include' => FACTORY_FORMS_418_DIR . '/controls/holders/accordion.php'
212
+ ],
213
+ [
214
+ 'type' => 'accordion-item',
215
+ 'class' => 'Wbcr_FactoryForms418_AccordionItemHolder',
216
+ 'include' => FACTORY_FORMS_418_DIR . '/controls/holders/accordion-item.php'
217
+ ],
218
+ [
219
+ 'type' => 'control-group',
220
+ 'class' => 'Wbcr_FactoryForms418_ControlGroupHolder',
221
+ 'include' => FACTORY_FORMS_418_DIR . '/controls/holders/control-group.php'
222
+ ],
223
+ [
224
+ 'type' => 'control-group-item',
225
+ 'class' => 'Wbcr_FactoryForms418_ControlGroupItem',
226
+ 'include' => FACTORY_FORMS_418_DIR . '/controls/holders/control-group-item.php'
227
+ ],
228
+ [
229
+ 'type' => 'form-group',
230
+ 'class' => 'Wbcr_FactoryForms418_FormGroupHolder',
231
+ 'include' => FACTORY_FORMS_418_DIR . '/controls/holders/form-group.php'
232
+ ],
233
+ [
234
+ 'type' => 'more-link',
235
+ 'class' => 'Wbcr_FactoryForms418_MoreLinkHolder',
236
+ 'include' => FACTORY_FORMS_418_DIR . '/controls/holders/more-link.php'
237
+ ],
238
+ [
239
+ 'type' => 'div',
240
+ 'class' => 'Wbcr_FactoryForms418_DivHolder',
241
+ 'include' => FACTORY_FORMS_418_DIR . '/controls/holders/div.php'
242
+ ],
243
+ [
244
+ 'type' => 'columns',
245
+ 'class' => 'Wbcr_FactoryForms418_ColumnsHolder',
246
+ 'include' => FACTORY_FORMS_418_DIR . '/controls/holders/columns.php'
247
+ ]
248
+ ] );
249
 
250
+ // registration custom form elements
251
+ $plugin->forms->registerCustomElements( [
252
+ [
253
+ 'type' => 'html',
254
+ 'class' => 'Wbcr_FactoryForms418_Html',
255
+ 'include' => FACTORY_FORMS_418_DIR . '/controls/customs/html.php',
256
+ ],
257
+ [
258
+ 'type' => 'separator',
259
+ 'class' => 'Wbcr_FactoryForms418_Separator',
260
+ 'include' => FACTORY_FORMS_418_DIR . '/controls/customs/separator.php',
261
+ ],
262
+ ] );
263
 
264
+ // registration of form layouts
265
+ $plugin->forms->registerFormLayout( [
266
+ 'name' => 'bootstrap-3',
267
+ 'class' => 'Wbcr_FactoryForms418_Bootstrap3FormLayout',
268
+ 'include' => FACTORY_FORMS_418_DIR . '/layouts/bootstrap-3/bootstrap-3.php'
269
+ ] );
270
+ }
271
 
272
+ add_action( 'wbcr_factory_forms_418_register_controls', 'wbcr_factory_forms_418_register_default_controls' );
273
+ }
libs/factory/forms/controls/checkbox.php CHANGED
@@ -20,9 +20,9 @@
20
  exit;
21
  }
22
 
23
- if( !class_exists('Wbcr_FactoryForms400_CheckboxControl') ) {
24
 
25
- class Wbcr_FactoryForms400_CheckboxControl extends Wbcr_FactoryForms400_Control {
26
 
27
  public $type = 'checkbox';
28
 
@@ -130,10 +130,10 @@
130
  <div <?php $this->attrs() ?>>
131
  <button type="button" class="btn btn-default btn-small btn-sm factory-on <?php if( $value ) {
132
  echo 'active';
133
- } ?>"><?php _e('On', 'wbcr_factory_forms_400') ?></button>
134
  <button type="button" class="btn btn-default btn-small btn-sm factory-off <?php if( !$value ) {
135
  echo 'active';
136
- } ?>" data-value="0"><?php _e('Off', 'wbcr_factory_forms_400') ?></button>
137
  <input type="checkbox" style="display: none" id="<?php echo $name_on_form ?>" class="factory-result" name="<?php echo $name_on_form ?>" value="<?= $value ?>" <?php if( $value ) {
138
  echo 'checked="checked"';
139
  } ?>" />
20
  exit;
21
  }
22
 
23
+ if( !class_exists('Wbcr_FactoryForms418_CheckboxControl') ) {
24
 
25
+ class Wbcr_FactoryForms418_CheckboxControl extends Wbcr_FactoryForms418_Control {
26
 
27
  public $type = 'checkbox';
28
 
130
  <div <?php $this->attrs() ?>>
131
  <button type="button" class="btn btn-default btn-small btn-sm factory-on <?php if( $value ) {
132
  echo 'active';
133
+ } ?>"><?php _e('On', 'wbcr_factory_forms_418') ?></button>
134
  <button type="button" class="btn btn-default btn-small btn-sm factory-off <?php if( !$value ) {
135
  echo 'active';
136
+ } ?>" data-value="0"><?php _e('Off', 'wbcr_factory_forms_418') ?></button>
137
  <input type="checkbox" style="display: none" id="<?php echo $name_on_form ?>" class="factory-result" name="<?php echo $name_on_form ?>" value="<?= $value ?>" <?php if( $value ) {
138
  echo 'checked="checked"';
139
  } ?>" />
libs/factory/forms/controls/color-and-opacity.php CHANGED
@@ -20,10 +20,10 @@
20
  exit;
21
  }
22
 
23
- if( !class_exists('Wbcr_FactoryForms400_ColorAndOpacityControl') ) {
24
  }
25
 
26
- class Wbcr_FactoryForms400_ColorAndOpacityControl extends Wbcr_FactoryForms400_ComplexControl {
27
 
28
  public $type = 'color-and-opacity';
29
 
@@ -57,8 +57,8 @@
57
  'way' => 'slider'
58
  ));
59
 
60
- $this->color = new Wbcr_FactoryForms400_ColorControl($options['color'], $form, $provider);
61
- $this->opacity = new Wbcr_FactoryForms400_IntegerControl($options['opacity'], $form, $provider);
62
 
63
  $this->innerControls = array($this->color, $this->opacity);
64
  }
20
  exit;
21
  }
22
 
23
+ if( !class_exists('Wbcr_FactoryForms418_ColorAndOpacityControl') ) {
24
  }
25
 
26
+ class Wbcr_FactoryForms418_ColorAndOpacityControl extends Wbcr_FactoryForms418_ComplexControl {
27
 
28
  public $type = 'color-and-opacity';
29
 
57
  'way' => 'slider'
58
  ));
59
 
60
+ $this->color = new Wbcr_FactoryForms418_ColorControl($options['color'], $form, $provider);
61
+ $this->opacity = new Wbcr_FactoryForms418_IntegerControl($options['opacity'], $form, $provider);
62
 
63
  $this->innerControls = array($this->color, $this->opacity);
64
  }
libs/factory/forms/controls/color.php CHANGED
@@ -20,9 +20,9 @@
20
  exit;
21
  }
22
 
23
- if( !class_exists('Wbcr_FactoryForms400_ColorControl') ) {
24
 
25
- class Wbcr_FactoryForms400_ColorControl extends Wbcr_FactoryForms400_Control {
26
 
27
  public $type = 'color';
28
 
20
  exit;
21
  }
22
 
23
+ if( !class_exists('Wbcr_FactoryForms418_ColorControl') ) {
24
 
25
+ class Wbcr_FactoryForms418_ColorControl extends Wbcr_FactoryForms418_Control {
26
 
27
  public $type = 'color';
28
 
libs/factory/forms/controls/customs/html.php CHANGED
@@ -14,9 +14,9 @@
14
  exit;
15
  }
16
 
17
- if( !class_exists('Wbcr_FactoryForms400_Html') ) {
18
 
19
- class Wbcr_FactoryForms400_Html extends Wbcr_FactoryForms400_CustomElement {
20
 
21
  public $type = 'html';
22
 
14
  exit;
15
  }
16
 
17
+ if( !class_exists('Wbcr_FactoryForms418_Html') ) {
18
 
19
+ class Wbcr_FactoryForms418_Html extends Wbcr_FactoryForms418_CustomElement {
20
 
21
  public $type = 'html';
22
 
libs/factory/forms/controls/customs/index.php ADDED
@@ -0,0 +1,2 @@
 
 
1
+ <?php
2
+ // Silence is golden.
libs/factory/forms/controls/customs/separator.php CHANGED
@@ -14,8 +14,8 @@
14
  exit;
15
  }
16
 
17
- if( !class_exists('Wbcr_FactoryForms400_Separator') ) {
18
- class Wbcr_FactoryForms400_Separator extends Wbcr_FactoryForms400_CustomElement {
19
 
20
  public $type = 'separator';
21
 
14
  exit;
15
  }
16
 
17
+ if( !class_exists('Wbcr_FactoryForms418_Separator') ) {
18
+ class Wbcr_FactoryForms418_Separator extends Wbcr_FactoryForms418_CustomElement {
19
 
20
  public $type = 'separator';
21
 
libs/factory/forms/controls/datepicker-range.php CHANGED
@@ -29,9 +29,9 @@
29
  exit;
30
  }
31
 
32
- if( !class_exists('Wbcr_FactoryForms400_DatepickerRangeControl') ) {
33
 
34
- class Wbcr_FactoryForms400_DatepickerRangeControl extends Wbcr_FactoryForms400_ComplexControl {
35
 
36
  public $type = 'datetimepicker-range';
37
 
@@ -65,8 +65,8 @@
65
  'default' => date('Y/m/d H:i', strtotime("+1 month"))
66
  ), $options['range_2']);
67
 
68
- $this->range_1 = new Wbcr_FactoryForms400_TextboxControl($options['range_1'], $form, $provider);
69
- $this->range_2 = new Wbcr_FactoryForms400_TextboxControl($options['range_2'], $form, $provider);
70
  $this->inner_controls = array($this->range_1, $this->range_2);
71
 
72
  foreach($this->inner_controls as $key => $control) {
29
  exit;
30
  }
31
 
32
+ if( !class_exists('Wbcr_FactoryForms418_DatepickerRangeControl') ) {
33
 
34
+ class Wbcr_FactoryForms418_DatepickerRangeControl extends Wbcr_FactoryForms418_ComplexControl {
35
 
36
  public $type = 'datetimepicker-range';
37
 
65
  'default' => date('Y/m/d H:i', strtotime("+1 month"))
66
  ), $options['range_2']);
67
 
68
+ $this->range_1 = new Wbcr_FactoryForms418_TextboxControl($options['range_1'], $form, $provider);
69
+ $this->range_2 = new Wbcr_FactoryForms418_TextboxControl($options['range_2'], $form, $provider);
70
  $this->inner_controls = array($this->range_1, $this->range_2);
71
 
72
  foreach($this->inner_controls as $key => $control) {
libs/factory/forms/controls/dropdown-and-colors.php CHANGED
@@ -5,14 +5,14 @@
5
  *
6
  * Main options:
7
  * name => a name of the control
8
- * // see FactoryForms400_DropdownControl
9
  * 'dropdown' => array(
10
  * // a callback to return items or an array of items to select
11
  * 'data' => OPanda_ThemeManager::getThemes(OPanda_Items::getCurrentItemName(), 'dropdown'),
12
  * 'default' => 'default',
13
  * 'value' => 'value' // a value to show in the control
14
  * ),
15
- * // see FactoryForms400_RadioColorsControl
16
  * 'colors' => array(
17
  * // a callback to return items or an array of items to select
18
  * 'data' => array(
@@ -37,9 +37,9 @@
37
  exit;
38
  }
39
 
40
- if( !class_exists('Wbcr_FactoryForms400_DropdownAndColorsControl') ) {
41
 
42
- class Wbcr_FactoryForms400_DropdownAndColorsControl extends Wbcr_FactoryForms400_ComplexControl {
43
 
44
  public $type = 'dropdown-and-colors';
45
 
@@ -69,8 +69,8 @@
69
  'name' => $this->options['name'] . '__colors',
70
  ));
71
 
72
- $this->dropdown = new Wbcr_FactoryForms400_DropdownControl($options['dropdown'], $form, $provider);
73
- $this->colors = new Wbcr_FactoryForms400_RadioColorsControl($options['colors'], $form, $provider);
74
  $this->inner_controls = array($this->dropdown, $this->colors);
75
 
76
  $colors = $this->colors->getOption('data');
5
  *
6
  * Main options:
7
  * name => a name of the control
8
+ * // see FactoryForms418_DropdownControl
9
  * 'dropdown' => array(
10
  * // a callback to return items or an array of items to select
11
  * 'data' => OPanda_ThemeManager::getThemes(OPanda_Items::getCurrentItemName(), 'dropdown'),
12
  * 'default' => 'default',
13
  * 'value' => 'value' // a value to show in the control
14
  * ),
15
+ * // see FactoryForms418_RadioColorsControl
16
  * 'colors' => array(
17
  * // a callback to return items or an array of items to select
18
  * 'data' => array(
37
  exit;
38
  }
39
 
40
+ if( !class_exists('Wbcr_FactoryForms418_DropdownAndColorsControl') ) {
41
 
42
+ class Wbcr_FactoryForms418_DropdownAndColorsControl extends Wbcr_FactoryForms418_ComplexControl {
43
 
44
  public $type = 'dropdown-and-colors';
45
 
69
  'name' => $this->options['name'] . '__colors',
70
  ));
71
 
72
+ $this->dropdown = new Wbcr_FactoryForms418_DropdownControl($options['dropdown'], $form, $provider);
73
+ $this->colors = new Wbcr_FactoryForms418_RadioColorsControl($options['colors'], $form, $provider);
74
  $this->inner_controls = array($this->dropdown, $this->colors);
75
 
76
  $colors = $this->colors->getOption('data');
libs/factory/forms/controls/dropdown.php CHANGED
@@ -1,5 +1,5 @@
1
  <?php
2
-
3
  /**
4
  * Dropdown List Control
5
  *
@@ -15,372 +15,377 @@
15
  * @package factory-forms
16
  * @since 1.0.0
17
  */
18
-
19
  // Exit if accessed directly
20
- if( !defined('ABSPATH') ) {
21
  exit;
22
  }
23
-
24
- if( !class_exists('Wbcr_FactoryForms400_DropdownControl') ) {
25
-
26
- class Wbcr_FactoryForms400_DropdownControl extends Wbcr_FactoryForms400_Control {
27
-
28
  public $type = 'dropdown';
29
-
30
  /**
31
  * Returns a set of available items for the list.
32
  *
33
  * @since 1.0.0
34
  * @return mixed[]
35
  */
36
- private function getItems()
37
- {
38
- $data = $this->getOption('data', array());
39
-
40
  // if the data options is a valid callback for an object method
41
- if( (is_array($data) && count($data) == 2 && is_object($data[0])) || is_string($data) ) {
42
-
43
- return call_user_func($data);
44
  }
45
-
46
  // if the data options is an array of values
47
  return $data;
48
  }
49
-
50
  /**
51
  * Returns true, if the data should be loaded via ajax.
52
  *
53
  * @since 1.0.0
54
  * @return bool
55
  */
56
- protected function isAjax()
57
- {
58
-
59
- $data = $this->getOption('data', array());
60
-
61
- return is_array($data) && isset($data['ajax']);
62
  }
63
-
64
  /**
65
  * Shows the html markup of the control.
66
  *
67
  * @since 1.0.0
68
  * @return void
69
  */
70
- public function html()
71
- {
72
-
73
- $way = $this->getOption('way', 'default');
74
- $this->addHtmlData('way', $way);
75
-
76
- $events_data = $this->getOption('events', array());
77
-
78
- if( !empty($events_data) ) {
79
- $events_string_data = json_encode($events_data);
80
- $name_on_form = $this->getNameOnForm();
81
-
82
  $value = $this->getValue();
83
-
84
- if( empty($value) || (is_array($value) && empty($value[0])) ) {
85
  $value = null;
86
  }
87
-
88
- if( !empty($value) && isset($events_data[$value]) && is_array($events_data[$value]) ) {
89
  $print_styles = '';
90
- foreach($events_data[$value] as $eventName => $selectors) {
91
- if( $eventName == 'hide' ) {
92
  $print_styles .= $selectors . '{display:none;}';
93
- } else if( $eventName == 'show' ) {
94
  $print_styles .= $selectors . '{display:block;}';
95
  }
96
  }
97
-
98
  echo '<style>' . $print_styles . '</style>';
99
  }
100
  ?>
101
-
102
- <script>
103
  // Onepress factory dropdown control events
104
  if( void 0 === window.factory_dropdown_control_events_data ) {
105
  window.factory_dropdown_control_events_data = {};
106
  }
107
  window.factory_dropdown_control_events_data['<?php echo $name_on_form ?>'] = <?= $events_string_data ?>;
108
- </script>
109
- <?php
110
  }
111
- if( $this->isAjax() ) {
112
-
113
- $data = $this->getOption('data', array());
114
- $ajax_id = 'factory-dropdown-' . rand(1000000, 9999999);
115
-
116
  $value = $this->getValue();
117
-
118
- if( empty($value) || (is_array($value) && empty($value[0])) ) {
119
  $value = null;
120
  }
121
-
122
  ?>
123
- <div class="factory-ajax-loader <?php echo $ajax_id . '-loader'; ?>"></div>
124
- <script>
125
  window['<?php echo $ajax_id ?>'] = {
126
  'loader': '.<?php echo $ajax_id . '-loader' ?>',
127
  'url': '<?php echo $data['url'] ?>',
128
  'data': <?php echo json_encode( $data['data'] ) ?>,
129
  'selected': '<?php echo $value ?>',
130
- 'emptyList': '<?php echo $this->getOption('empty', __('The list is empty.', 'wbcr_factory_forms_400') ) ?>'
131
  };
132
- </script>
133
  <?php
134
-
135
- $this->addHtmlData('ajax', true);
136
- $this->addHtmlData('ajax-data-id', $ajax_id);
137
- $this->addCssClass('factory-hidden');
138
  }
139
-
140
- if( 'buttons' == $way ) {
141
  $this->buttonsHtml();
142
- } elseif( 'ddslick' == $way ) {
143
  $this->ddslickHtml();
144
  } else {
145
  $this->defaultHtml();
146
  }
147
  }
148
-
149
  /**
150
  * Shows the Buttons Dropdown.
151
  *
152
  * @since 1.0.0
153
  * @return void
154
  */
155
- protected function buttonsHtml()
156
- {
157
  $items = $this->getItems();
158
  $value = $this->getValue();
159
-
160
  $name_on_form = $this->getNameOnForm();
161
-
162
- $this->addCssClass('factory-buttons-way');
163
-
164
  ?>
165
- <div <?php $this->attrs() ?>>
166
- <div class="btn-group factory-buttons-group">
167
- <?php foreach($items as $item) { ?>
168
- <button type="button" class="btn btn-default btn-small factory-<?php echo $item[0] ?> <?php if( $value == $item[0] ) {
169
  echo 'active';
170
  } ?>" data-value="<?php echo $item[0] ?>"><?php echo $item[1] ?></button>
171
  <?php } ?>
172
- <input type="hidden" id="<?php echo $name_on_form ?>" class="factory-result" name="<?php echo $name_on_form ?>" value="<?php echo $value ?>"/>
173
- </div>
174
- <div class="factory-hints">
175
- <?php foreach($items as $item) { ?>
176
- <?php if( isset($item[2]) ) { ?>
177
- <div class="factory-hint factory-hint-<?php echo $item[0] ?>" <?php if( $value !== $item[0] ) {
178
  echo 'style="display: none;"';
179
  } ?>><?php echo $item[2] ?></div>
180
  <?php } ?>
181
  <?php } ?>
182
- </div>
183
- </div>
184
- <?php
185
  }
186
-
187
  /**
188
  * Shows the ddSlick dropbox.
189
  *
190
  * @since 3.2.8
191
  * @return void
192
  */
193
- protected function ddslickHtml()
194
- {
195
  $items = $this->getItems();
196
  $value = $this->getValue();
197
-
198
  $name_on_form = $this->getNameOnForm();
199
-
200
- $this->addCssClass('factory-ddslick-way');
201
- $this->addHtmlData('name', $name_on_form);
202
-
203
- $this->addHtmlData('width', $this->getOption('width', 300));
204
- $this->addHtmlData('align', $this->getOption('imagePosition', 'right'));
205
-
206
  ?>
207
- <div <?php $this->attrs() ?>>
208
- <script>
209
  //Dropdown plugin data
210
  var factory_<?php echo $name_on_form ?>_data = [
211
  <?php foreach ( $items as $item ) { ?>
212
  {
213
  text: "<?php echo $item['title'] ?>",
214
  value: "<?php echo $item['value'] ?>",
215
- selected: <?php if ( $value == $item['value'] ) { echo 'true'; } else { echo 'false'; } ?>,
216
- description: "<?php echo ( isset( $item['hint'] ) ? $item['hint'] : '' ); ?>",
217
- imageSrc: "<?php echo ( isset( $item['image'] ) ? $item['image'] : '' ); ?>",
218
- imageHoverSrc: "<?php echo ( isset( $item['hover'] ) ? $item['hover'] : '' ); ?>"
 
 
 
 
219
  },
220
  <?php } ?>
221
  ];
222
- </script>
223
- <div class="factory-ddslick"></div>
224
- <input type="hidden" class="factory-result" id="<?php echo $name_on_form ?>" name="<?php echo $name_on_form ?>" value="<?php echo $value ?>"/>
225
- </div>
226
- <?php
227
  }
228
-
229
  /**
230
  * Shows the standart dropdown.
231
  *
232
  * @since 1.3.1
233
  * @return void
234
  */
235
- protected function defaultHtml()
236
- {
237
-
238
  $items = $this->getItems();
239
- $value = esc_attr($this->getValue());
240
-
241
  $name_on_form = $this->getNameOnForm();
242
-
243
- $this->addHtmlAttr('id', $name_on_form);
244
- $this->addHtmlAttr('name', $name_on_form);
245
- $this->addCssClass('form-control');
246
-
247
- $hasGroups = $this->getOption('hasGroups', true);
248
- $hasHints = $this->getOption('hasHints', false);
249
-
250
- foreach($items as $item) {
251
- if( !isset($item['hint']) ) {
252
- continue;
253
- }
254
- if( empty($item['hint']) ) {
255
- continue;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
256
  }
257
- $hasHints = true;
258
- break;
259
  }
260
-
261
- $isEmpty = $this->isAjax() || empty($items);
262
- $emptyList = $this->getOption('empty', __('- empty -', 'wbcr_factory_forms_400'));
263
-
264
  ?>
265
-
266
- <select <?php $this->attrs() ?>>
267
- <?php if( $isEmpty ) { ?>
268
-
269
- <option value='' class="factory-empty-option">
270
- <?php echo $emptyList ?>
271
- </option>
272
-
273
  <?php } else { ?>
274
-
275
- <?php $this->printItems($items, $value) ?>
276
-
277
  <?php } ?>
278
- </select>
279
-
280
- <?php if( $hasHints ) { ?>
281
- <div class="factory-hints">
282
- <?php foreach($items as $item) {
283
-
284
- $hint = isset($item[2])
285
- ? $item[2]
286
- : null;
287
- $hint = isset($item['hint'])
288
- ? $item['hint']
289
- : null;
290
- $value = isset($item[0])
291
- ? esc_attr($item[0])
292
- : null;
293
- $value = isset($item['value'])
294
- ? esc_attr($item['value'])
295
- : null;
296
-
297
- if( !empty($hint) ) { ?>
298
- <div style="display: none;" class="factory-hint factory-hint-<?php echo $value ?>" <?php if( $value !== $value ) {
299
- echo 'style="display: none;"';
300
- } ?>><?php echo $hint ?></div>
301
- <?php }
302
- } ?>
303
- </div>
304
- <?php } ?>
305
- <?php
306
  }
307
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
308
  /**
309
  * @param array $items
310
  * @param null $selected
311
  */
312
- protected function printItems($items, $selected = null)
313
- {
314
-
315
- foreach((array)$items as $item) {
316
-
317
  $subitems = array();
318
- $data = null;
319
-
320
  // this item is an associative array
321
- if( isset($item['type']) || isset($item['value']) ) {
322
-
323
- $type = isset($item['type'])
324
- ? $item['type']
325
- : 'option';
326
- if( 'group' === $type ) {
327
- $subitems = isset($item['items'])
328
- ? $item['items']
329
- : array();
330
  }
331
-
332
- $value = isset($item['value'])
333
- ? $item['value']
334
- : '';
335
- $title = isset($item['title'])
336
- ? $item['title']
337
- : __('- empty -', 'wbcr_factory_forms_400');
338
-
339
- $data = isset($item['data'])
340
- ? $item['data']
341
- : null;
342
  } else {
343
-
344
- $type = (count($item) == 3 && $item[0] === 'group')
345
- ? 'group'
346
- : 'option';
347
- if( 'group' === $type ) {
348
  $subitems = $item[2];
349
  }
350
-
351
- $title = esc_html($item[1]);
352
- $value = esc_attr($item[0]);
353
  }
354
-
355
- if( 'group' === $type ) {
356
  ?>
357
-
358
- <optgroup label="<?php echo $item[1] ?>">
359
- <?php $this->printItems($subitems, $selected); ?>
360
- </optgroup>
361
-
362
- <?php
363
  } else {
364
-
365
- $attr = ($selected == $value)
366
- ? 'selected="selected"'
367
- : '';
368
-
369
  $strData = '';
370
- if( !empty($data) ) {
371
-
372
- foreach($data as $key => $values) {
373
- $strData = $strData . ' data-' . $key . '="' . (is_array($values)
374
- ? implode(',', $values)
375
- : $values) . '"';
376
  }
377
  }
378
-
379
  ?>
380
- <option value='<?php echo $value ?>' <?php echo $attr ?> <?php echo $strData ?>>
381
  <?php echo $title ?>
382
- </option>
383
- <?php
384
  }
385
  }
386
  }
1
  <?php
2
+
3
  /**
4
  * Dropdown List Control
5
  *
15
  * @package factory-forms
16
  * @since 1.0.0
17
  */
18
+
19
  // Exit if accessed directly
20
+ if ( ! defined( 'ABSPATH' ) ) {
21
  exit;
22
  }
23
+
24
+ if ( ! class_exists( 'Wbcr_FactoryForms418_DropdownControl' ) ) {
25
+
26
+ class Wbcr_FactoryForms418_DropdownControl extends Wbcr_FactoryForms418_Control {
27
+
28
  public $type = 'dropdown';
29
+
30
  /**
31
  * Returns a set of available items for the list.
32
  *
33
  * @since 1.0.0
34
  * @return mixed[]
35
  */
36
+ private function getItems() {
37
+ $data = $this->getOption( 'data', array() );
38
+
 
39
  // if the data options is a valid callback for an object method
40
+ if ( ( is_array( $data ) && count( $data ) == 2 && is_object( $data[0] ) ) || is_string( $data ) ) {
41
+
42
+ return call_user_func( $data );
43
  }
44
+
45
  // if the data options is an array of values
46
  return $data;
47
  }
48
+
49
  /**
50
  * Returns true, if the data should be loaded via ajax.
51
  *
52
  * @since 1.0.0
53
  * @return bool
54
  */
55
+ protected function isAjax() {
56
+
57
+ $data = $this->getOption( 'data', array() );
58
+
59
+ return is_array( $data ) && isset( $data['ajax'] );
 
60
  }
61
+
62
  /**
63
  * Shows the html markup of the control.
64
  *
65
  * @since 1.0.0
66
  * @return void
67
  */
68
+ public function html() {
69
+
70
+ $way = $this->getOption( 'way', 'default' );
71
+ $this->addHtmlData( 'way', $way );
72
+
73
+ $events_data = $this->getOption( 'events', array() );
74
+
75
+ if ( ! empty( $events_data ) ) {
76
+ $events_string_data = json_encode( $events_data );
77
+ $name_on_form = $this->getNameOnForm();
78
+
 
79
  $value = $this->getValue();
80
+
81
+ if ( empty( $value ) || ( is_array( $value ) && empty( $value[0] ) ) ) {
82
  $value = null;
83
  }
84
+
85
+ if ( ! empty( $value ) && isset( $events_data[ $value ] ) && is_array( $events_data[ $value ] ) ) {
86
  $print_styles = '';
87
+ foreach ( $events_data[ $value ] as $eventName => $selectors ) {
88
+ if ( $eventName == 'hide' ) {
89
  $print_styles .= $selectors . '{display:none;}';
90
+ } else if ( $eventName == 'show' ) {
91
  $print_styles .= $selectors . '{display:block;}';
92
  }
93
  }
94
+
95
  echo '<style>' . $print_styles . '</style>';
96
  }
97
  ?>
98
+ <script>
 
99
  // Onepress factory dropdown control events
100
  if( void 0 === window.factory_dropdown_control_events_data ) {
101
  window.factory_dropdown_control_events_data = {};
102
  }
103
  window.factory_dropdown_control_events_data['<?php echo $name_on_form ?>'] = <?= $events_string_data ?>;
104
+ </script>
105
+ <?php
106
  }
107
+ if ( $this->isAjax() ) {
108
+
109
+ $data = $this->getOption( 'data', array() );
110
+ $ajax_id = 'factory-dropdown-' . rand( 1000000, 9999999 );
111
+
112
  $value = $this->getValue();
113
+
114
+ if ( empty( $value ) || ( is_array( $value ) && empty( $value[0] ) ) ) {
115
  $value = null;
116
  }
117
+
118
  ?>
119
+ <div class="factory-ajax-loader <?php echo $ajax_id . '-loader'; ?>"></div>
120
+ <script>
121
  window['<?php echo $ajax_id ?>'] = {
122
  'loader': '.<?php echo $ajax_id . '-loader' ?>',
123
  'url': '<?php echo $data['url'] ?>',
124
  'data': <?php echo json_encode( $data['data'] ) ?>,
125
  'selected': '<?php echo $value ?>',
126
+ 'empty_list': '<?php echo $this->getOption( 'empty', __( 'The list is empty.', 'wbcr_factory_forms_418' ) ) ?>'
127
  };
128
+ </script>
129
  <?php
130
+
131
+ $this->addHtmlData( 'ajax', true );
132
+ $this->addHtmlData( 'ajax-data-id', $ajax_id );
133
+ $this->addCssClass( 'factory-hidden' );
134
  }
135
+
136
+ if ( 'buttons' == $way ) {
137
  $this->buttonsHtml();
138
+ } elseif ( 'ddslick' == $way ) {
139
  $this->ddslickHtml();
140
  } else {
141
  $this->defaultHtml();
142
  }
143
  }
144
+
145
  /**
146
  * Shows the Buttons Dropdown.
147
  *
148
  * @since 1.0.0
149
  * @return void
150
  */
151
+ protected function buttonsHtml() {
 
152
  $items = $this->getItems();
153
  $value = $this->getValue();
154
+
155
  $name_on_form = $this->getNameOnForm();
156
+
157
+ $this->addCssClass( 'factory-buttons-way' );
158
+
159
  ?>
160
+ <div <?php $this->attrs() ?>>
161
+ <div class="btn-group factory-buttons-group">
162
+ <?php foreach ( $items as $item ) { ?>
163
+ <button type="button" class="btn btn-default btn-small factory-<?php echo $item[0] ?> <?php if ( $value == $item[0] ) {
164
  echo 'active';
165
  } ?>" data-value="<?php echo $item[0] ?>"><?php echo $item[1] ?></button>
166
  <?php } ?>
167
+ <input type="hidden" id="<?php echo $name_on_form ?>" class="factory-result" name="<?php echo $name_on_form ?>" value="<?php echo $value ?>"/>
168
+ </div>
169
+ <div class="factory-hints">
170
+ <?php foreach ( $items as $item ) { ?>
171
+ <?php if ( isset( $item[2] ) ) { ?>
172
+ <div class="factory-hint factory-hint-<?php echo $item[0] ?>" <?php if ( $value !== $item[0] ) {
173
  echo 'style="display: none;"';
174
  } ?>><?php echo $item[2] ?></div>
175
  <?php } ?>
176
  <?php } ?>
177
+ </div>
178
+ </div>
179
+ <?php
180
  }
181
+
182
  /**
183
  * Shows the ddSlick dropbox.
184
  *
185
  * @since 3.2.8
186
  * @return void
187
  */
188
+ protected function ddslickHtml() {
 
189
  $items = $this->getItems();
190
  $value = $this->getValue();
191
+
192
  $name_on_form = $this->getNameOnForm();
193
+
194
+ $this->addCssClass( 'factory-ddslick-way' );
195
+ $this->addHtmlData( 'name', $name_on_form );
196
+
197
+ $this->addHtmlData( 'width', $this->getOption( 'width', 300 ) );
198
+ $this->addHtmlData( 'align', $this->getOption( 'imagePosition', 'right' ) );
199
+
200
  ?>
201
+ <div <?php $this->attrs() ?>>
202
+ <script>
203
  //Dropdown plugin data
204
  var factory_<?php echo $name_on_form ?>_data = [
205
  <?php foreach ( $items as $item ) { ?>
206
  {
207
  text: "<?php echo $item['title'] ?>",
208
  value: "<?php echo $item['value'] ?>",
209
+ selected: <?php if ( $value == $item['value'] ) {
210
+ echo 'true';
211
+ } else {
212
+ echo 'false';
213
+ } ?>,
214
+ description: "<?php echo( isset( $item['hint'] ) ? $item['hint'] : '' ); ?>",
215
+ imageSrc: "<?php echo( isset( $item['image'] ) ? $item['image'] : '' ); ?>",
216
+ imageHoverSrc: "<?php echo( isset( $item['hover'] ) ? $item['hover'] : '' ); ?>"
217
  },
218
  <?php } ?>
219
  ];
220
+ </script>
221
+ <div class="factory-ddslick"></div>
222
+ <input type="hidden" class="factory-result" id="<?php echo $name_on_form ?>" name="<?php echo $name_on_form ?>" value="<?php echo $value ?>"/>
223
+ </div>
224
+ <?php
225
  }
226
+
227
  /**
228
  * Shows the standart dropdown.
229
  *
230
  * @since 1.3.1
231
  * @return void
232
  */
233
+ protected function defaultHtml() {
234
+
 
235
  $items = $this->getItems();
236
+ $value = esc_attr( $this->getValue() );
237
+
238
  $name_on_form = $this->getNameOnForm();
239
+
240
+ $this->addHtmlAttr( 'id', $name_on_form );
241
+ $this->addHtmlAttr( 'name', $name_on_form );
242
+ $this->addCssClass( 'form-control' );
243
+
244
+ $hasGroups = $this->getOption( 'hasGroups', true );
245
+ $has_hints = $this->getOption( 'hasHints', false );
246
+
247
+ foreach ( $items as $item ) {
248
+ if ( isset( $item['type'] ) && $item['type'] == 'group' && ! empty( $item['items'] ) ) {
249
+ foreach ( (array) $item['items'] as $group_item ) {
250
+ $is_hint = ( isset( $group_item['hint'] ) && ! empty( $group_item['hint'] ) ) || ( isset( $group_item[2] ) && ! empty( $group_item[2] ) );
251
+ if ( ! $is_hint ) {
252
+ continue;
253
+ }
254
+ $has_hints = true;
255
+ break;
256
+ }
257
+ if ( $has_hints ) {
258
+ break;
259
+ }
260
+ } else {
261
+ $is_hint = ( isset( $item['hint'] ) && ! empty( $item['hint'] ) ) || ( isset( $item[2] ) && ! $item[2] );
262
+ if ( ! $is_hint ) {
263
+ continue;
264
+ }
265
+ $has_hints = true;
266
+ break;
267
  }
 
 
268
  }
269
+
270
+ $is_empty = $this->isAjax() || empty( $items );
271
+ $empty_list = $this->getOption( 'empty', __( '- empty -', 'wbcr_factory_forms_418' ) );
272
+
273
  ?>
274
+ <select <?php $this->attrs() ?>>
275
+ <?php if ( $is_empty ) { ?>
276
+ <option value='' class="factory-empty-option">
277
+ <?php echo $empty_list ?>
278
+ </option>
 
 
 
279
  <?php } else { ?>
280
+ <?php $this->printItems( $items, $value ) ?>
 
 
281
  <?php } ?>
282
+ </select>
283
+ <?php if ( $has_hints ) { ?>
284
+ <div class="factory-hints">
285
+ <?php foreach ( $items as $item ) {
286
+ if ( isset( $item['type'] ) && $item['type'] == 'group' && ! empty( $item['items'] ) ) {
287
+ foreach ( (array) $item['items'] as $group_item ) {
288
+
289
+ $hint = isset( $group_item[2] ) ? esc_attr( $group_item[2] ) : null;
290
+ $hint = isset( $group_item['hint'] ) ? esc_attr( $group_item['hint'] ) : $hint;
291
+
292
+ $value = isset( $group_item[0] ) ? esc_attr( $group_item[0] ) : null;
293
+ $value = isset( $group_item['value'] ) ? esc_attr( $group_item['value'] ) : $value;
294
+
295
+ $this->printHint( $hint, $value, $value !== $value );
296
+ }
297
+ } else {
298
+ $hint = isset( $item[2] ) ? esc_attr( $item[2] ) : null;
299
+ $hint = isset( $item['hint'] ) ? esc_attr( $item['hint'] ) : $hint;
300
+
301
+ $value = isset( $item[0] ) ? esc_attr( $item[0] ) : null;
302
+ $value = isset( $item['value'] ) ? esc_attr( $item['value'] ) : $value;
303
+
304
+ $this->printHint( $hint, $value, $value !== $value );
305
+ }
306
+ } ?>
307
+ </div>
308
+ <?php } ?>
309
+ <?php
310
  }
311
+
312
+ /**
313
+ * Print single hint markup
314
+ * @since 4.1.0
315
+ *
316
+ * @param string $hint
317
+ *
318
+ * @return void
319
+ */
320
+ protected function printHint( $hint, $name, $is_visible = false ) {
321
+
322
+ if ( ! empty( $hint ) ) {
323
+ $styles = ( $is_visible ) ? 'style="display: none;"' : '';
324
+
325
+ ?>
326
+ <div style="display: none;" class="factory-hint factory-hint-<?= esc_attr( $name ) ?>"<?= $styles ?>><?php echo $hint ?></div>
327
+ <?php
328
+ }
329
+ }
330
+
331
  /**
332
  * @param array $items
333
  * @param null $selected
334
  */
335
+ protected function printItems( $items, $selected = null ) {
336
+
337
+ foreach ( (array) $items as $item ) {
338
+
 
339
  $subitems = array();
340
+ $data = null;
341
+
342
  // this item is an associative array
343
+ if ( isset( $item['type'] ) || isset( $item['value'] ) ) {
344
+
345
+ $type = isset( $item['type'] ) ? $item['type'] : 'option';
346
+
347
+ if ( 'group' === $type ) {
348
+ $subitems = isset( $item['items'] ) ? $item['items'] : array();
 
 
 
349
  }
350
+
351
+ $value = isset( $item['value'] ) ? $item['value'] : '';
352
+ $title = isset( $item['title'] ) ? $item['title'] : __( '- empty -', 'wbcr_factory_forms_418' );
353
+
354
+ $data = isset( $item['data'] ) ? $item['data'] : null;
 
 
 
 
 
 
355
  } else {
356
+
357
+ $type = ( count( $item ) == 3 && $item[0] === 'group' ) ? 'group' : 'option';
358
+ if ( 'group' === $type ) {
 
 
359
  $subitems = $item[2];
360
  }
361
+
362
+ $title = $item[1];
363
+ $value = esc_attr( $item[0] );
364
  }
365
+
366
+ if ( 'group' === $type ) {
367
  ?>
368
+ <optgroup label="<?php echo $title ?>">
369
+ <?php $this->printItems( $subitems, $selected ); ?>
370
+ </optgroup>
371
+ <?php
 
 
372
  } else {
373
+
374
+ $attr = ( $selected == $value ) ? 'selected="selected"' : '';
375
+
 
 
376
  $strData = '';
377
+ if ( ! empty( $data ) ) {
378
+
379
+ foreach ( $data as $key => $values ) {
380
+ $strData = $strData . ' data-' . $key . '="' . ( is_array( $values ) ? implode( ',', $values ) : $values ) . '"';
 
 
381
  }
382
  }
383
+
384
  ?>
385
+ <option value='<?php echo $value ?>' <?php echo $attr ?> <?php echo $strData ?>>
386
  <?php echo $title ?>
387
+ </option>
388
+ <?php
389
  }
390
  }
391
  }
libs/factory/forms/controls/font.php CHANGED
@@ -20,9 +20,9 @@
20
  exit;
21
  }
22
 
23
- if( !class_exists('Wbcr_FactoryForms400_FontControl') ) {
24
 
25
- class Wbcr_FactoryForms400_FontControl extends Wbcr_FactoryForms400_ComplexControl {
26
 
27
  public $type = 'font';
28
 
@@ -54,9 +54,9 @@
54
  'pickerTarget' => '.factory-control-' . $this->options['name'] . ' .factory-picker-target'
55
  );
56
 
57
- $this->size = new Wbcr_FactoryForms400_IntegerControl($option_font_size, $form, $provider);
58
- $this->family = new Wbcr_FactoryForms400_DropdownControl($option_font_family, $form, $provider);
59
- $this->color = new Wbcr_FactoryForms400_ColorControl($optionFontColor, $form, $provider);
60
 
61
  $this->innerControls = array($this->family, $this->size, $this->color);
62
  }
@@ -66,8 +66,8 @@
66
 
67
  $fonts = $this->getDefaultFonts();
68
 
69
- $fonts = apply_filters('wbcr_factory_forms_400_fonts', $fonts);
70
- $fonts = apply_filters('wbcr_factory_forms_400_fonts-' . $this->options['name'], $fonts);
71
 
72
  return $fonts;
73
  }
@@ -77,10 +77,10 @@
77
 
78
  $fonts = array(
79
 
80
- array('inherit', __('(use default website font)', 'wbcr_factory_forms_400')),
81
  array(
82
  'group',
83
- __('Sans Serif:', 'wbcr_factory_forms_400'),
84
  array(
85
  array('Arial, "Helvetica Neue", Helvetica, sans-serif', 'Arial'),
86
  array('"Arial Black", "Arial Bold", Gadget, sans-serif', 'Arial Black'),
@@ -131,7 +131,7 @@
131
  ),
132
  array(
133
  'group',
134
- __('Serif:', 'wbcr_factory_forms_400'),
135
  array(
136
  array(
137
  'Baskerville, "Baskerville Old Face", "Hoefler Text", Garamond, "Times New Roman", serif',
@@ -187,7 +187,7 @@
187
  ),
188
  array(
189
  'group',
190
- __('Monospaced:', 'wbcr_factory_forms_400'),
191
  array(
192
  array('"Andale Mono", AndaleMono, monospace', 'Andale Mono'),
193
  array('Consolas, monaco, monospace', 'Consolas'),
20
  exit;
21
  }
22
 
23
+ if( !class_exists('Wbcr_FactoryForms418_FontControl') ) {
24
 
25
+ class Wbcr_FactoryForms418_FontControl extends Wbcr_FactoryForms418_ComplexControl {
26
 
27
  public $type = 'font';
28
 
54
  'pickerTarget' => '.factory-control-' . $this->options['name'] . ' .factory-picker-target'
55
  );
56
 
57
+ $this->size = new Wbcr_FactoryForms418_IntegerControl($option_font_size, $form, $provider);
58
+ $this->family = new Wbcr_FactoryForms418_DropdownControl($option_font_family, $form, $provider);
59
+ $this->color = new Wbcr_FactoryForms418_ColorControl($optionFontColor, $form, $provider);
60
 
61
  $this->innerControls = array($this->family, $this->size, $this->color);
62
  }
66
 
67
  $fonts = $this->getDefaultFonts();
68
 
69
+ $fonts = apply_filters('wbcr_factory_forms_418_fonts', $fonts);
70
+ $fonts = apply_filters('wbcr_factory_forms_418_fonts-' . $this->options['name'], $fonts);
71
 
72
  return $fonts;
73
  }
77
 
78
  $fonts = array(
79
 
80
+ array('inherit', __('(use default website font)', 'wbcr_factory_forms_418')),
81
  array(
82
  'group',
83
+ __('Sans Serif:', 'wbcr_factory_forms_418'),
84
  array(
85
  array('Arial, "Helvetica Neue", Helvetica, sans-serif', 'Arial'),
86
  array('"Arial Black", "Arial Bold", Gadget, sans-serif', 'Arial Black'),
131
  ),
132
  array(
133
  'group',
134
+ __('Serif:', 'wbcr_factory_forms_418'),
135
  array(
136
  array(
137
  'Baskerville, "Baskerville Old Face", "Hoefler Text", Garamond, "Times New Roman", serif',
187
  ),
188
  array(
189
  'group',
190
+ __('Monospaced:', 'wbcr_factory_forms_418'),
191
  array(
192
  array('"Andale Mono", AndaleMono, monospace', 'Andale Mono'),
193
  array('Consolas, monaco, monospace', 'Consolas'),
libs/factory/forms/controls/google-font.php CHANGED
@@ -15,7 +15,7 @@
15
  * @package core
16
  * @since 1.0.0
17
  */
18
- class Wbcr_FactoryForms400_GoogleFontControl extends Wbcr_FactoryForms400_FontControl {
19
 
20
  public $type = 'google-font';
21
  const APIKEY = 'AIzaSyB-3vazYv7Q-5QZA04bmSKFrWcw_VhC40w';
@@ -30,7 +30,7 @@
30
  'cssClass' => 'factory-google-font-data'
31
  );
32
 
33
- $this->google_font_data = new Wbcr_FactoryForms400_HiddenControl($option_google_font_data, $form, $provider);
34
  $this->inner_controls[] = $this->google_font_data;
35
  }
36
 
@@ -49,12 +49,12 @@
49
  $google_fonts = $this->getGoogleFonts();
50
 
51
  $fonts = array(
52
- array('inherit', __('(use default website font)', 'wbcr_factory_forms_400'))
53
  );
54
 
55
  $fontsCommon = array(
56
  'group',
57
- __('Standard:', 'wbcr_factory_forms_400'),
58
  array(
59
 
60
  array('Arial, "Helvetica Neue", Helvetica, sans-serif', 'Arial'),
@@ -65,7 +65,7 @@
65
  )
66
  );
67
 
68
- $fontsGoogleFonts = array('group', __('Google Fonts:', 'wbcr_factory_forms_400'), array());
69
 
70
  foreach($google_fonts->items as $item) {
71
 
@@ -115,7 +115,7 @@
115
 
116
  if( is_wp_error($response) ) {
117
 
118
- $this->error = __('Unable to retrieve the list of Google Fonts.', 'wbcr_factory_forms_400');
119
  $this->defailed_error = $response->get_error_message();
120
 
121
  return $body;
@@ -123,7 +123,7 @@
123
 
124
  if( !isset($response['body']) ) {
125
 
126
- $this->error = __('Invalide response from the Google Fonts API.', 'wbcr_factory_forms_400');
127
  $this->defailed_error = $response['body'];
128
 
129
  return $body;
@@ -133,7 +133,7 @@
133
 
134
  if( empty($body->items) ) {
135
 
136
- $this->error = __('Unexpected error. The list of Google Fonts are empty.', 'wbcr_factory_forms_400');
137
 
138
  return $body;
139
  }
15
  * @package core
16
  * @since 1.0.0
17
  */
18
+ class Wbcr_FactoryForms418_GoogleFontControl extends Wbcr_FactoryForms418_FontControl {
19
 
20
  public $type = 'google-font';
21
  const APIKEY = 'AIzaSyB-3vazYv7Q-5QZA04bmSKFrWcw_VhC40w';
30
  'cssClass' => 'factory-google-font-data'
31
  );
32
 
33
+ $this->google_font_data = new Wbcr_FactoryForms418_HiddenControl($option_google_font_data, $form, $provider);
34
  $this->inner_controls[] = $this->google_font_data;
35
  }
36
 
49
  $google_fonts = $this->getGoogleFonts();
50
 
51
  $fonts = array(
52
+ array('inherit', __('(use default website font)', 'wbcr_factory_forms_418'))
53
  );
54
 
55
  $fontsCommon = array(
56
  'group',
57
+ __('Standard:', 'wbcr_factory_forms_418'),
58
  array(
59
 
60
  array('Arial, "Helvetica Neue", Helvetica, sans-serif', 'Arial'),
65
  )
66
  );
67
 
68
+ $fontsGoogleFonts = array('group', __('Google Fonts:', 'wbcr_factory_forms_418'), array());
69
 
70
  foreach($google_fonts->items as $item) {
71
 
115
 
116
  if( is_wp_error($response) ) {
117
 
118
+ $this->error = __('Unable to retrieve the list of Google Fonts.', 'wbcr_factory_forms_418');
119
  $this->defailed_error = $response->get_error_message();
120
 
121
  return $body;
123
 
124
  if( !isset($response['body']) ) {
125
 
126
+ $this->error = __('Invalide response from the Google Fonts API.', 'wbcr_factory_forms_418');
127
  $this->defailed_error = $response['body'];
128
 
129
  return $body;
133
 
134
  if( empty($body->items) ) {
135
 
136
+ $this->error = __('Unexpected error. The list of Google Fonts are empty.', 'wbcr_factory_forms_418');
137
 
138
  return $body;
139
  }
libs/factory/forms/controls/gradient.php CHANGED
@@ -25,8 +25,8 @@
25
  exit;
26
  }
27
 
28
- if( !class_exists('Wbcr_FactoryForms400_GradientControl') ) {
29
- class Wbcr_FactoryForms400_GradientControl extends Wbcr_FactoryForms400_Control {
30
 
31
  public $type = 'gradient';
32
 
@@ -66,8 +66,8 @@
66
  if( !window.factory.res ) {
67
  window.factory.res = {};
68
  }
69
- factory.res.resVertical = '<?php _e( 'vertical', 'wbcr_factory_forms_400' ) ?>';
70
- factory.res.resHorizontal = '<?php _e( 'horizontal', 'wbcr_factory_forms_400' ) ?>';
71
  </script>
72
  <div <?php $this->attrs() ?>>
73
  <div class="factory-gradient-picker">
25
  exit;
26
  }
27
 
28
+ if( !class_exists('Wbcr_FactoryForms418_GradientControl') ) {
29
+ class Wbcr_FactoryForms418_GradientControl extends Wbcr_FactoryForms418_Control {
30
 
31
  public $type = 'gradient';
32
 
66
  if( !window.factory.res ) {
67
  window.factory.res = {};
68
  }
69
+ factory.res.resVertical = '<?php _e( 'vertical', 'wbcr_factory_forms_418' ) ?>';
70
+ factory.res.resHorizontal = '<?php _e( 'horizontal', 'wbcr_factory_forms_418' ) ?>';
71
  </script>
72
  <div <?php $this->attrs() ?>>
73
  <div class="factory-gradient-picker">
libs/factory/forms/controls/hidden.php CHANGED
@@ -20,9 +20,9 @@
20
  exit;
21
  }
22
 
23
- if( !class_exists('Wbcr_FactoryForms400_HiddenControl') ) {
24
 
25
- class Wbcr_FactoryForms400_HiddenControl extends Wbcr_FactoryForms400_Control {
26
 
27
  public $type = 'hidden';
28
 
20
  exit;
21
  }
22
 
23
+ if( !class_exists('Wbcr_FactoryForms418_HiddenControl') ) {
24
 
25
+ class Wbcr_FactoryForms418_HiddenControl extends Wbcr_FactoryForms418_Control {
26
 
27
  public $type = 'hidden';
28
 
libs/factory/forms/controls/holders/accordion-item.php CHANGED
@@ -14,14 +14,14 @@
14
  exit;
15
  }
16
 
17
- if( !class_exists('Wbcr_FactoryForms400_AccordionItemHolder') ) {
18
 
19
  /**
20
  * Tab Control Holder
21
  *
22
  * @since 1.0.0
23
  */
24
- class Wbcr_FactoryForms400_AccordionItemHolder extends Wbcr_FactoryForms400_Holder {
25
 
26
  /**
27
  * A holder type.
14
  exit;
15
  }
16
 
17
+ if( !class_exists('Wbcr_FactoryForms418_AccordionItemHolder') ) {
18
 
19
  /**
20
  * Tab Control Holder
21
  *
22
  * @since 1.0.0
23
  */
24
+ class Wbcr_FactoryForms418_AccordionItemHolder extends Wbcr_FactoryForms418_Holder {
25
 
26
  /**
27
  * A holder type.
libs/factory/forms/controls/holders/accordion.php CHANGED
@@ -13,13 +13,13 @@
13
  if( !defined('ABSPATH') ) {
14
  exit;
15
  }
16
- if( !class_exists('Wbcr_FactoryForms400_AccordionHolder') ) {
17
  /**
18
  * Tab Control Holder
19
  *
20
  * @since 1.0.0
21
  */
22
- class Wbcr_FactoryForms400_AccordionHolder extends Wbcr_FactoryForms400_Holder {
23
 
24
  /**
25
  * A holder type.
13
  if( !defined('ABSPATH') ) {
14
  exit;
15
  }
16
+ if( !class_exists('Wbcr_FactoryForms418_AccordionHolder') ) {
17
  /**
18
  * Tab Control Holder
19
  *
20
  * @since 1.0.0
21
  */
22
+ class Wbcr_FactoryForms418_AccordionHolder extends Wbcr_FactoryForms418_Holder {
23
 
24
  /**
25
  * A holder type.
libs/factory/forms/controls/holders/columns.php CHANGED
@@ -14,13 +14,13 @@
14
  exit;
15
  }
16
 
17
- if( !class_exists('Wbcr_FactoryForms400_ColumnsHolder') ) {
18
  /**
19
  * Columns Holder
20
  *
21
  * @since 1.0.0
22
  */
23
- class Wbcr_FactoryForms400_ColumnsHolder extends Wbcr_FactoryForms400_Holder {
24
 
25
  /**
26
  * A holder type.
14
  exit;
15
  }
16
 
17
+ if( !class_exists('Wbcr_FactoryForms418_ColumnsHolder') ) {
18
  /**
19
  * Columns Holder
20
  *
21
  * @since 1.0.0
22
  */
23
+ class Wbcr_FactoryForms418_ColumnsHolder extends Wbcr_FactoryForms418_Holder {
24
 
25
  /**
26
  * A holder type.
libs/factory/forms/controls/holders/control-group-item.php CHANGED
@@ -14,14 +14,14 @@
14
  exit;
15
  }
16
 
17
- if( !class_exists('Wbcr_FactoryForms400_ControlGroupItem') ) {
18
 
19
  /**
20
  * Tab Control Holder
21
  *
22
  * @since 1.0.0
23
  */
24
- class Wbcr_FactoryForms400_ControlGroupItem extends Wbcr_FactoryForms400_Holder {
25
 
26
  /**
27
  * A holder type.
14
  exit;
15
  }
16
 
17
+ if( !class_exists('Wbcr_FactoryForms418_ControlGroupItem') ) {
18
 
19
  /**
20
  * Tab Control Holder
21
  *
22
  * @since 1.0.0
23
  */
24
+ class Wbcr_FactoryForms418_ControlGroupItem extends Wbcr_FactoryForms418_Holder {
25
 
26
  /**
27
  * A holder type.
libs/factory/forms/controls/holders/control-group.php CHANGED
@@ -14,14 +14,14 @@
14
  exit;
15
  }
16
 
17
- if( !class_exists('Wbcr_FactoryForms400_ControlGroupHolder') ) {
18
 
19
  /**
20
  * Tab Control Holder
21
  *
22
  * @since 1.0.0
23
  */
24
- class Wbcr_FactoryForms400_ControlGroupHolder extends Wbcr_FactoryForms400_ControlHolder {
25
 
26
  /**
27
  * A holder type.
@@ -61,7 +61,7 @@
61
  continue;
62
  }
63
 
64
- $builder = new Wbcr_FactoryForms400_HtmlAttributeBuilder();
65
 
66
  $builder->addCssClass('factory-control-group-nav-label');
67
  $builder->addCssClass('factory-control-group-nav-label-' . $element->getOption('name'));
14
  exit;
15
  }
16
 
17
+ if( !class_exists('Wbcr_FactoryForms418_ControlGroupHolder') ) {
18
 
19
  /**
20
  * Tab Control Holder
21
  *
22
  * @since 1.0.0
23
  */
24
+ class Wbcr_FactoryForms418_ControlGroupHolder extends Wbcr_FactoryForms418_ControlHolder {
25
 
26
  /**
27
  * A holder type.
61
  continue;
62
  }
63
 
64
+ $builder = new Wbcr_FactoryForms418_HtmlAttributeBuilder();
65
 
66
  $builder->addCssClass('factory-control-group-nav-label');
67
  $builder->addCssClass('factory-control-group-nav-label-' . $element->getOption('name'));
libs/factory/forms/controls/holders/div.php CHANGED
@@ -14,13 +14,13 @@
14
  exit;
15
  }
16
 
17
- if( !class_exists('Wbcr_FactoryForms400_DivHolder') ) {
18
  /**
19
  * Div Control Holder
20
  *
21
  * @since 1.0.0
22
  */
23
- class Wbcr_FactoryForms400_DivHolder extends Wbcr_FactoryForms400_Holder {
24
 
25
  /**
26
  * A holder type.
14
  exit;
15
  }
16
 
17
+ if( !class_exists('Wbcr_FactoryForms418_DivHolder') ) {
18
  /**
19
  * Div Control Holder
20
  *
21
  * @since 1.0.0
22
  */
23
+ class Wbcr_FactoryForms418_DivHolder extends Wbcr_FactoryForms418_Holder {
24
 
25
  /**
26
  * A holder type.
libs/factory/forms/controls/holders/form-group.php CHANGED
@@ -14,13 +14,13 @@
14
  exit;
15
  }
16
 
17
- if( !class_exists('Wbcr_FactoryForms400_FormGroupHolder') ) {
18
  /**
19
  * Group Holder
20
  *
21
  * @since 1.0.0
22
  */
23
- class Wbcr_FactoryForms400_FormGroupHolder extends Wbcr_FactoryForms400_Holder {
24
 
25
  /**
26
  * A holder type.
14
  exit;
15
  }
16
 
17
+ if( !class_exists('Wbcr_FactoryForms418_FormGroupHolder') ) {
18
  /**
19
  * Group Holder
20
  *
21
  * @since 1.0.0
22
  */
23
+ class Wbcr_FactoryForms418_FormGroupHolder extends Wbcr_FactoryForms418_Holder {
24
 
25
  /**
26
  * A holder type.
libs/factory/forms/controls/holders/index.php ADDED
@@ -0,0 +1,2 @@
 
 
1
+ <?php
2
+ // Silence is golden.
libs/factory/forms/controls/holders/more-link.php CHANGED
@@ -14,14 +14,14 @@
14
  exit;
15
  }
16
 
17
- if( !class_exists('Wbcr_FactoryForms400_MoreLinkHolder') ) {
18
 
19
  /**
20
  * Collapsed Group Holder
21
  *
22
  * @since 1.0.0
23
  */
24
- class Wbcr_FactoryForms400_MoreLinkHolder extends Wbcr_FactoryForms400_Holder {
25
 
26
  /**
27
  * A holder type.
14
  exit;
15
  }
16
 
17
+ if( !class_exists('Wbcr_FactoryForms418_MoreLinkHolder') ) {
18
 
19
  /**
20
  * Collapsed Group Holder
21
  *
22
  * @since 1.0.0
23
  */
24
+ class Wbcr_FactoryForms418_MoreLinkHolder extends Wbcr_FactoryForms418_Holder {
25
 
26
  /**
27
  * A holder type.
libs/factory/forms/controls/holders/tab-item.php CHANGED
@@ -13,13 +13,13 @@
13
  exit;
14
  }
15
 
16
- if( !class_exists('Wbcr_FactoryForms400_TabItemHolder') ) {
17
  /**
18
  * Tab Item Control Holder
19
  *
20
  * @since 1.0.0
21
  */
22
- class Wbcr_FactoryForms400_TabItemHolder extends Wbcr_FactoryForms400_Holder {
23
 
24
  /**
25
  * A holder type.
13
  exit;
14
  }
15
 
16
+ if( !class_exists('Wbcr_FactoryForms418_TabItemHolder') ) {
17
  /**
18
  * Tab Item Control Holder
19
  *
20
  * @since 1.0.0
21
  */
22
+ class Wbcr_FactoryForms418_TabItemHolder extends Wbcr_FactoryForms418_Holder {
23
 
24
  /**
25
  * A holder type.
libs/factory/forms/controls/holders/tab.php CHANGED
@@ -14,14 +14,14 @@
14
  exit;
15
  }
16
 
17
- if( !class_exists('Wbcr_FactoryForms400_TabHolder') ) {
18
 
19
  /**
20
  * Tab Control Holder
21
  *
22
  * @since 1.0.0
23
  */
24
- class Wbcr_FactoryForms400_TabHolder extends Wbcr_FactoryForms400_Holder {
25
 
26
  /**
27
  * A holder type.
@@ -44,7 +44,7 @@
44
  *
45
  * @since 1.0.0
46
  * @param mixed[] $options A holder options.
47
- * @param FactoryForms400_Form $form A parent form.
48
  */
49
  public function __construct($options, $form)
50
  {
@@ -88,7 +88,7 @@
88
  $tab_icon = $element->options['icon'];
89
  }
90
 
91
- $builder = new Wbcr_FactoryForms400_HtmlAttributeBuilder();
92
 
93
  $builder->addCssClass('factory-tab-item-header');
94
  $builder->addCssClass('factory-tab-item-header-' . $element->getName());
14
  exit;
15
  }
16
 
17
+ if( !class_exists('Wbcr_FactoryForms418_TabHolder') ) {
18
 
19
  /**
20
  * Tab Control Holder
21
  *
22
  * @since 1.0.0
23
  */
24
+ class Wbcr_FactoryForms418_TabHolder extends Wbcr_FactoryForms418_Holder {
25
 
26
  /**
27
  * A holder type.
44
  *
45
  * @since 1.0.0
46
  * @param mixed[] $options A holder options.
47
+ * @param FactoryForms418_Form $form A parent form.
48
  */
49
  public function __construct($options, $form)
50
  {
88
  $tab_icon = $element->options['icon'];
89
  }
90
 
91
+ $builder = new Wbcr_FactoryForms418_HtmlAttributeBuilder();
92
 
93
  $builder->addCssClass('factory-tab-item-header');
94
  $builder->addCssClass('factory-tab-item-header-' . $element->getName());
libs/factory/forms/controls/index.php ADDED
@@ -0,0 +1,2 @@
 
 
1
+ <?php
2
+ // Silence is golden.
libs/factory/forms/controls/integer.php CHANGED
@@ -32,9 +32,9 @@
32
  exit;
33
  }
34
 
35
- if( !class_exists('Wbcr_FactoryForms400_IntegerControl') ) {
36
 
37
- class Wbcr_FactoryForms400_IntegerControl extends Wbcr_FactoryForms400_Control {
38
 
39
  public $type = 'integer';
40
 
32
  exit;
33
  }
34
 
35
+ if( !class_exists('Wbcr_FactoryForms418_IntegerControl') ) {
36
 
37
+ class Wbcr_FactoryForms418_IntegerControl extends Wbcr_FactoryForms418_Control {
38
 
39
  public $type = 'integer';
40
 
libs/factory/forms/controls/list.php CHANGED
@@ -21,9 +21,9 @@
21
  exit;
22
  }
23
 
24
- if( !class_exists('Wbcr_FactoryForms400_ListControl') ) {
25
 
26
- class Wbcr_FactoryForms400_ListControl extends Wbcr_FactoryForms400_Control {
27
 
28
  public $type = 'list';
29
 
@@ -93,7 +93,7 @@
93
  'url': '<?php echo $data['url'] ?>',
94
  'data': <?php echo json_encode( $data['data'] ) ?>,
95
  'selected': <?php echo json_encode( $value ) ?>,
96
- 'emptyList': '<?php echo $this->getOption('empty', __('The list is empty.', 'wbcr_factory_forms_400') ) ?>'
97
  };
98
  </script>
99
  <?php
@@ -136,7 +136,7 @@
136
  : array();
137
 
138
  $is_empty = $this->isAjax() || empty($items);
139
- $emptyList = $this->getOption('empty', __('The list is empty.', 'wbcr_factory_forms_400'));
140
 
141
  if( $is_empty ) {
142
  $this->addCssClass('factory-empty');
21
  exit;
22
  }
23
 
24
+ if( !class_exists('Wbcr_FactoryForms418_ListControl') ) {
25
 
26
+ class Wbcr_FactoryForms418_ListControl extends Wbcr_FactoryForms418_Control {
27
 
28
  public $type = 'list';
29
 
93
  'url': '<?php echo $data['url'] ?>',
94
  'data': <?php echo json_encode( $data['data'] ) ?>,
95
  'selected': <?php echo json_encode( $value ) ?>,
96
+ 'emptyList': '<?php echo $this->getOption('empty', __('The list is empty.', 'wbcr_factory_forms_418') ) ?>'
97
  };
98
  </script>
99
  <?php
136
  : array();
137
 
138
  $is_empty = $this->isAjax() || empty($items);
139
+ $emptyList = $this->getOption('empty', __('The list is empty.', 'wbcr_factory_forms_418'));
140
 
141
  if( $is_empty ) {
142
  $this->addCssClass('factory-empty');
libs/factory/forms/controls/multiple-textbox.php CHANGED
@@ -15,9 +15,9 @@
15
  exit;
16
  }
17
 
18
- if( !class_exists('Wbcr_FactoryForms400_MultipleTextboxControl') ) {
19
 
20
- class Wbcr_FactoryForms400_MultipleTextboxControl extends Wbcr_FactoryForms400_Control {
21
 
22
  public $type = 'multiple-textbox';
23
 
@@ -86,7 +86,7 @@
86
  <?php endif; ?>
87
  </div>
88
  <button class="btn btn-default btn-small factory-mtextbox-add-item">
89
- <i class="fa fa-plus" aria-hidden="true"></i> <?php _e('Add new', 'wbcr_factory_forms_400') ?>
90
  </button>
91
  </div>
92
 
15
  exit;
16
  }
17
 
18
+ if( !class_exists('Wbcr_FactoryForms418_MultipleTextboxControl') ) {
19
 
20
+ class Wbcr_FactoryForms418_MultipleTextboxControl extends Wbcr_FactoryForms418_Control {
21
 
22
  public $type = 'multiple-textbox';
23
 
86
  <?php endif; ?>
87
  </div>
88
  <button class="btn btn-default btn-small factory-mtextbox-add-item">
89
+ <i class="fa fa-plus" aria-hidden="true"></i> <?php _e('Add new', 'wbcr_factory_forms_418') ?>
90
  </button>
91
  </div>
92
 
libs/factory/forms/controls/paddings-editor.php CHANGED
@@ -14,9 +14,9 @@
14
  exit;
15
  }
16
 
17
- if( !class_exists('Wbcr_FactoryForms400_PaddingsEditorControl') ) {
18
 
19
- class Wbcr_FactoryForms400_PaddingsEditorControl extends Wbcr_FactoryForms400_Control {
20
 
21
  public $type = 'paddings-editor';
22
 
@@ -67,7 +67,7 @@
67
  </div>
68
  <div class="factory-slider-container">
69
  <label class="factory-title">
70
- <?php _e('Select a side and move the slider to set up:', 'wbcr_factory_forms_400') ?>
71
  </label>
72
 
73
  <div class="factory-slider">
14
  exit;
15
  }
16
 
17
+ if( !class_exists('Wbcr_FactoryForms418_PaddingsEditorControl') ) {
18
 
19
+ class Wbcr_FactoryForms418_PaddingsEditorControl extends Wbcr_FactoryForms418_Control {
20
 
21
  public $type = 'paddings-editor';
22
 
67
  </div>
68
  <div class="factory-slider-container">
69
  <label class="factory-title">
70
+ <?php _e('Select a side and move the slider to set up:', 'wbcr_factory_forms_418') ?>
71
  </label>
72
 
73
  <div class="factory-slider">
libs/factory/forms/controls/pattern.php CHANGED
@@ -15,9 +15,9 @@
15
  exit;
16
  }
17
 
18
- if( !class_exists('Wbcr_FactoryForms400_PatternControl') ) {
19
 
20
- class Wbcr_FactoryForms400_PatternControl extends Wbcr_FactoryForms400_Control {
21
 
22
  public $type = 'pattern';
23
 
@@ -52,12 +52,12 @@
52
  $name = $this->getOption('name');
53
 
54
  // filters to get available patterns for the given background contols
55
- $this->patterns = apply_filters('wbcr_factory_forms_400_patterns', array());
56
- $this->patterns = apply_filters('wbcr_factory_forms_400_patterns-' . $name, $this->patterns);
57
 
58
  $this->custom_patterns = $this->getOption('patterns', array());
59
 
60
- $this->color = new Wbcr_FactoryForms400_ColorControl($options['color'], $form, $provider);
61
  }
62
 
63
  /**
@@ -102,19 +102,19 @@
102
  </div>
103
  <a href="#" class="button button-default factory-button factory-change-color-btn <?php if( $hasColor ) {
104
  echo 'button-active';
105
- } ?>" title="<?php _e('Change color', 'wbcr_factory_forms_400') ?>">
106
  <i class="fa fa-flask"></i>
107
- <span><?php _e('re-color', 'wbcr_factory_forms_400') ?></span>
108
  </a>
109
  <input type="hidden" id="<?php echo $name[0]; ?>" name="<?php echo $name[0]; ?>" value="<?php echo esc_url($values['url']); ?>" class="factory-pattern-result">
110
  <input type="hidden" id="<?php echo $name[1]; ?>" name="<?php echo $name[1]; ?>" value="<?php echo esc_attr($values['color']); ?>" class="factory-color-result">
111
  </div>
112
  <div class="factory-color-panel">
113
  <div class="factory-color-wrap">
114
- <span class="factory-color-label"><?php _e('Select color:', 'wbcr_factory_forms_400') ?></span>
115
  <?php $this->color->html() ?>
116
  <div class="factory-hint">
117
- <i><?php _e('Changing the color may takes a minute or more. Please be patient.', 'wbcr_factory_forms_400') ?></i>
118
  </div>
119
  </div>
120
  <div class="factory-picker-target"></div>
15
  exit;
16
  }
17
 
18
+ if( !class_exists('Wbcr_FactoryForms418_PatternControl') ) {
19
 
20
+ class Wbcr_FactoryForms418_PatternControl extends Wbcr_FactoryForms418_Control {
21
 
22
  public $type = 'pattern';
23
 
52
  $name = $this->getOption('name');
53
 
54
  // filters to get available patterns for the given background contols
55
+ $this->patterns = apply_filters('wbcr_factory_forms_418_patterns', array());
56
+ $this->patterns = apply_filters('wbcr_factory_forms_418_patterns-' . $name, $this->patterns);
57
 
58
  $this->custom_patterns = $this->getOption('patterns', array());
59
 
60
+ $this->color = new Wbcr_FactoryForms418_ColorControl($options['color'], $form, $provider);
61
  }
62
 
63
  /**
102
  </div>
103
  <a href="#" class="button button-default factory-button factory-change-color-btn <?php if( $hasColor ) {
104
  echo 'button-active';
105
+ } ?>" title="<?php _e('Change color', 'wbcr_factory_forms_418') ?>">
106
  <i class="fa fa-flask"></i>
107
+ <span><?php _e('re-color', 'wbcr_factory_forms_418') ?></span>
108
  </a>
109
  <input type="hidden" id="<?php echo $name[0]; ?>" name="<?php echo $name[0]; ?>" value="<?php echo esc_url($values['url']); ?>" class="factory-pattern-result">
110
  <input type="hidden" id="<?php echo $name[1]; ?>" name="<?php echo $name[1]; ?>" value="<?php echo esc_attr($values['color']); ?>" class="factory-color-result">
111
  </div>
112
  <div class="factory-color-panel">
113
  <div class="factory-color-wrap">
114
+ <span class="factory-color-label"><?php _e('Select color:', 'wbcr_factory_forms_418') ?></span>
115
  <?php $this->color->html() ?>
116
  <div class="factory-hint">
117
+ <i><?php _e('Changing the color may takes a minute or more. Please be patient.', 'wbcr_factory_forms_418') ?></i>
118
  </div>
119
  </div>
120
  <div class="factory-picker-target"></div>
libs/factory/forms/controls/radio-colors.php CHANGED
@@ -27,9 +27,9 @@
27
  exit;
28
  }
29
 
30
- if( !class_exists('Wbcr_FactoryForms400_RadioColorsControl') ) {
31
 
32
- class Wbcr_FactoryForms400_RadioColorsControl extends Wbcr_FactoryForms400_Control {
33
 
34
  public $type = 'radio-color';
35
 
27
  exit;
28
  }
29
 
30
+ if( !class_exists('Wbcr_FactoryForms418_RadioColorsControl') ) {
31
 
32
+ class Wbcr_FactoryForms418_RadioColorsControl extends Wbcr_FactoryForms418_Control {
33
 
34
  public $type = 'radio-color';
35
 
libs/factory/forms/controls/radio.php CHANGED
@@ -21,9 +21,9 @@
21
  exit;
22
  }
23
 
24
- if( !class_exists('Wbcr_FactoryForms400_RadioControl') ) {
25
 
26
- class Wbcr_FactoryForms400_RadioControl extends Wbcr_FactoryForms400_Control {
27
 
28
  public $type = 'radio';
29
 
21
  exit;
22
  }
23
 
24
+ if( !class_exists('Wbcr_FactoryForms418_RadioControl') ) {
25
 
26
+ class Wbcr_FactoryForms418_RadioControl extends Wbcr_FactoryForms418_Control {
27
 
28
  public $type = 'radio';
29
 
libs/factory/forms/controls/textarea.php CHANGED
@@ -20,9 +20,9 @@
20
  exit;
21
  }
22
 
23
- if( !class_exists('Wbcr_FactoryForms400_TextareaControl') ) {
24
 
25
- class Wbcr_FactoryForms400_TextareaControl extends Wbcr_FactoryForms400_Control {
26
 
27
  public $type = 'textarea';
28
 
@@ -36,15 +36,20 @@
36
  {
37
  $name_on_form = $this->getNameOnForm($name);
38
 
39
- $value = isset($_POST[$name_on_form])
40
  ? $_POST[$name_on_form]
41
  : null;
42
 
 
 
43
  if( is_array($value) ) {
 
44
  $value = implode(',', $value);
 
 
45
  }
46
 
47
- return sanitize_textarea_field($value);
48
  }
49
 
50
  /**
20
  exit;
21
  }
22
 
23
+ if( !class_exists('Wbcr_FactoryForms418_TextareaControl') ) {
24
 
25
+ class Wbcr_FactoryForms418_TextareaControl extends Wbcr_FactoryForms418_Control {
26
 
27
  public $type = 'textarea';
28
 
36
  {
37
  $name_on_form = $this->getNameOnForm($name);
38
 
39
+ $raw_value = isset($_POST[$name_on_form])
40
  ? $_POST[$name_on_form]
41
  : null;
42
 
43
+ $value = $raw_value;
44
+
45
  if( is_array($value) ) {
46
+ $value = array_map('sanitize_textarea_field', $value);
47
  $value = implode(',', $value);
48
+ } else {
49
+ $value = sanitize_textarea_field($value);
50
  }
51
 
52
+ return $this->filterValue($value, $raw_value);
53
  }
54
 
55
  /**
libs/factory/forms/controls/textbox.php CHANGED
@@ -29,9 +29,9 @@
29
  exit;
30
  }
31
 
32
- if( !class_exists('Wbcr_FactoryForms400_TextboxControl') ) {
33
 
34
- class Wbcr_FactoryForms400_TextboxControl extends Wbcr_FactoryForms400_Control {
35
 
36
  public $type = 'textbox';
37
 
@@ -79,14 +79,5 @@
79
  <?php if( $units ) { ?></div><?php } ?>
80
  <?php
81
  }
82
-
83
- public function getSubmitValue($name, $subName)
84
- {
85
- $name_on_form = $this->getNameOnForm($name);
86
-
87
- return isset($_POST[$name_on_form])
88
- ? sanitize_text_field($_POST[$name_on_form])
89
- : '';
90
- }
91
  }
92
  }
29
  exit;
30
  }
31
 
32
+ if( !class_exists('Wbcr_FactoryForms418_TextboxControl') ) {
33
 
34
+ class Wbcr_FactoryForms418_TextboxControl extends Wbcr_FactoryForms418_Control {
35
 
36
  public $type = 'textbox';
37
 
79
  <?php if( $units ) { ?></div><?php } ?>
80
  <?php
81
  }
 
 
 
 
 
 
 
 
 
82
  }
83
  }
libs/factory/forms/controls/url.php CHANGED
@@ -4,7 +4,7 @@
4
  * Url Control
5
  *
6
  * Main options:
7
- * @see FactoryForms400_TextboxControl
8
  *
9
  * @author Alex Kovalev <alex.kovalevv@gmail.com>
10
  * @copyright (c) 2018, Webcraftic Ltd
@@ -18,9 +18,9 @@
18
  exit;
19
  }
20
 
21
- if( !class_exists('Wbcr_FactoryForms400_UrlControl') ) {
22
 
23
- class Wbcr_FactoryForms400_UrlControl extends Wbcr_FactoryForms400_TextboxControl {
24
 
25
  public $type = 'url';
26
 
4
  * Url Control
5
  *
6
  * Main options:
7
+ * @see FactoryForms418_TextboxControl
8
  *
9
  * @author Alex Kovalev <alex.kovalevv@gmail.com>
10
  * @copyright (c) 2018, Webcraftic Ltd
18
  exit;
19
  }
20
 
21
+ if( !class_exists('Wbcr_FactoryForms418_UrlControl') ) {
22
 
23
+ class Wbcr_FactoryForms418_UrlControl extends Wbcr_FactoryForms418_TextboxControl {
24
 
25
  public $type = 'url';
26
 
libs/factory/forms/controls/wp-editor.php CHANGED
@@ -22,9 +22,9 @@
22
  exit;
23
  }
24
 
25
- if( !class_exists('Wbcr_FactoryForms400_WpEditorControl') ) {
26
 
27
- class Wbcr_FactoryForms400_WpEditorControl extends Wbcr_FactoryForms400_Control {
28
 
29
  public $type = 'wp-editor';
30
 
@@ -42,7 +42,7 @@
42
  }
43
 
44
  if( !isset($this->options['tinymce']['content_css']) ) {
45
- $this->options['tinymce']['content_css'] = FACTORY_FORMS_400_URL . '/assets/css/editor.css';
46
  }
47
  }
48
 
22
  exit;
23
  }
24
 
25
+ if( !class_exists('Wbcr_FactoryForms418_WpEditorControl') ) {
26
 
27
+ class Wbcr_FactoryForms418_WpEditorControl extends Wbcr_FactoryForms418_Control {
28
 
29
  public $type = 'wp-editor';
30
 
42
  }
43
 
44
  if( !isset($this->options['tinymce']['content_css']) ) {
45
+ $this->options['tinymce']['content_css'] = FACTORY_FORMS_418_URL . '/assets/css/editor.css';
46
  }
47
  }
48
 
libs/factory/forms/includes/complex-control.class.php CHANGED
@@ -13,13 +13,13 @@
13
  if( !defined('ABSPATH') ) {
14
  exit;
15
  }
16
- if( !class_exists('Wbcr_FactoryForms400_ComplexControl') ) {
17
  /**
18
  * The base class for all controls.
19
  *
20
  * @since 1.0.0
21
  */
22
- abstract class Wbcr_FactoryForms400_ComplexControl extends Wbcr_FactoryForms400_Control {
23
 
24
  /**
25
  * Is this element a complex control?
@@ -33,7 +33,7 @@
33
  * Contains a set of internal controls.
34
  *
35
  * @since 1.0.0
36
- * @var Wbcr_FactoryForms400_Control[]
37
  */
38
  public $inner_controls = array();
39
 
@@ -41,7 +41,7 @@
41
  * Sets a provider for the control.
42
  *
43
  * @since 1.0.0
44
- * @param Wbcr_IFactoryForms400_ValueProvider $provider
45
  * @return void
46
  */
47
  public function setProvider($provider)
13
  if( !defined('ABSPATH') ) {
14
  exit;
15
  }
16
+ if( !class_exists('Wbcr_FactoryForms418_ComplexControl') ) {
17
  /**
18
  * The base class for all controls.
19
  *
20
  * @since 1.0.0
21
  */
22
+ abstract class Wbcr_FactoryForms418_ComplexControl extends Wbcr_FactoryForms418_Control {
23
 
24
  /**
25
  * Is this element a complex control?
33
  * Contains a set of internal controls.
34
  *
35
  * @since 1.0.0
36
+ * @var Wbcr_FactoryForms418_Control[]
37
  */
38
  public $inner_controls = array();
39
 
41
  * Sets a provider for the control.
42
  *
43
  * @since 1.0.0
44
+ * @param Wbcr_IFactoryForms418_ValueProvider $provider
45
  * @return void
46
  */
47
  public function setProvider($provider)
libs/factory/forms/includes/control-holder.class.php CHANGED
@@ -14,19 +14,19 @@
14
  exit;
15
  }
16
 
17
- if( !class_exists('Wbcr_FactoryForms400_ControlHolder') ) {
18
  /**
19
  * The base class for control holders.
20
  *
21
  * @since 1.0.0
22
  */
23
- abstract class Wbcr_FactoryForms400_ControlHolder extends Wbcr_FactoryForms400_Control {
24
 
25
  /**
26
  * Holder Elements.
27
  *
28
  * @since 1.0.0
29
- * @var Wbcr_FactoryForms400_Control[]
30
  */
31
  protected $elements = array();
32
 
@@ -43,7 +43,7 @@
43
  *
44
  * @since 1.0.0
45
  * @param mixed[] $options A holder options.
46
- * @param Wbcr_FactoryForms400_Form $form A parent form.
47
  */
48
  public function __construct($options, $form)
49
  {
@@ -60,7 +60,7 @@
60
  * Returns holder elements.
61
  *
62
  * @since 1.0.0
63
- * @return Wbcr_FactoryForms400_FormElement[].
64
  */
65
  public function getElements()
66
  {
14
  exit;
15
  }
16
 
17
+ if( !class_exists('Wbcr_FactoryForms418_ControlHolder') ) {
18
  /**
19
  * The base class for control holders.
20
  *
21
  * @since 1.0.0
22
  */
23
+ abstract class Wbcr_FactoryForms418_ControlHolder extends Wbcr_FactoryForms418_Control {
24
 
25
  /**
26
  * Holder Elements.
27
  *
28
  * @since 1.0.0
29
+ * @var Wbcr_FactoryForms418_Control[]
30
  */
31
  protected $elements = array();
32
 
43
  *
44
  * @since 1.0.0
45
  * @param mixed[] $options A holder options.
46
+ * @param Wbcr_FactoryForms418_Form $form A parent form.
47
  */
48
  public function __construct($options, $form)
49
  {
60
  * Returns holder elements.
61
  *
62
  * @since 1.0.0
63
+ * @return Wbcr_FactoryForms418_FormElement[].
64
  */
65
  public function getElements()
66
  {
libs/factory/forms/includes/control.class.php CHANGED
@@ -14,14 +14,14 @@
14
  exit;
15
  }
16
 
17
- if( !class_exists('Wbcr_FactoryForms400_Control') ) {
18
 
19
  /**
20
  * The base class for all controls.
21
  *
22
  * @since 1.0.0
23
  */
24
- abstract class Wbcr_FactoryForms400_Control extends Wbcr_FactoryForms400_FormElement {
25
 
26
  /**
27
  * Is this element a control?
@@ -43,7 +43,7 @@
43
  * A provider that is used to get values.
44
  *
45
  * @since 1.0.0
46
- * @var Wbcr_IFactoryForms400_ValueProvider
47
  */
48
  protected $provider = null;
49
 
@@ -51,7 +51,7 @@
51
  * Create a new instance of the control.
52
  *
53
  * @param mixed[] $options
54
- * @param FactoryForms400_Form $form
55
  * @param null $provider
56
  * @since 1.0.0
57
  * @return void
@@ -66,7 +66,7 @@
66
  * Sets a provider for the control.
67
  *
68
  * @since 1.0.0
69
- * @param IFactoryForms400_ValueProvider $provider
70
  * @return void
71
  */
72
  public function setProvider($provider)
@@ -189,19 +189,42 @@
189
  */
190
  public function getSubmitValue($name, $sub_name)
191
  {
192
- $nameOnForm = $this->getNameOnForm($name);
193
 
194
- $value = isset($_POST[$nameOnForm])
195
- ? $_POST[$nameOnForm]
196
  : null;
197
 
 
 
198
  if( is_array($value) ) {
 
199
  $value = implode(',', $value);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
200
  }
201
 
202
- return sanitize_text_field($value);
203
  }
204
 
 
205
  /**
206
  * Returns an array of value to save received after submission of a form.
207
  *
14
  exit;
15
  }
16
 
17
+ if( !class_exists('Wbcr_FactoryForms418_Control') ) {
18
 
19
  /**
20
  * The base class for all controls.
21
  *
22
  * @since 1.0.0
23
  */
24
+ abstract class Wbcr_FactoryForms418_Control extends Wbcr_FactoryForms418_FormElement {
25
 
26
  /**
27
  * Is this element a control?
43
  * A provider that is used to get values.
44
  *
45
  * @since 1.0.0
46
+ * @var Wbcr_IFactoryForms418_ValueProvider
47
  */
48
  protected $provider = null;
49
 
51
  * Create a new instance of the control.
52
  *
53
  * @param mixed[] $options
54
+ * @param FactoryForms418_Form $form
55
  * @param null $provider
56
  * @since 1.0.0
57
  * @return void
66
  * Sets a provider for the control.
67
  *
68
  * @since 1.0.0
69
+ * @param IFactoryForms418_ValueProvider $provider
70
  * @return void
71
  */
72
  public function setProvider($provider)
189
  */
190
  public function getSubmitValue($name, $sub_name)
191
  {
192
+ $name_on_form = $this->getNameOnForm($name);
193
 
194
+ $raw_value = isset($_POST[$name_on_form])
195
+ ? $_POST[$name_on_form]
196
  : null;
197
 
198
+ $value = $raw_value;
199
+
200
  if( is_array($value) ) {
201
+ $value = array_map('sanitize_text_field', $value);
202
  $value = implode(',', $value);
203
+ } else {
204
+ $value = sanitize_text_field($value);
205
+ }
206
+
207
+ return $this->filterValue($value, $raw_value);
208
+ }
209
+
210
+ /**
211
+ * @param $value
212
+ * @param $raw_value
213
+ * @return mixed
214
+ */
215
+ protected function filterValue($value, $raw_value)
216
+ {
217
+ $sanitize_func = $this->getOption('filter_value');
218
+
219
+ // if the data options is a valid callback for an object method
220
+ if( !empty($sanitize_func) && ((is_array($sanitize_func) && count($sanitize_func) == 2 && gettype($sanitize_func[0]) == 'object') || function_exists($sanitize_func)) ) {
221
+ return call_user_func_array($sanitize_func, array($value, $raw_value));
222
  }
223
 
224
+ return $value;
225
  }
226
 
227
+
228
  /**
229
  * Returns an array of value to save received after submission of a form.
230
  *
libs/factory/forms/includes/custom-element.class.php CHANGED
@@ -14,13 +14,13 @@
14
  exit;
15
  }
16
 
17
- if( !class_exists('Wbcr_FactoryForms400_CustomElement') ) {
18
  /**
19
  * The base class for all controls.
20
  *
21
  * @since 1.0.0
22
  */
23
- abstract class Wbcr_FactoryForms400_CustomElement extends Wbcr_FactoryForms400_FormElement {
24
 
25
  /**
26
  * Is this element a custom form element?
14
  exit;
15
  }
16
 
17
+ if( !class_exists('Wbcr_FactoryForms418_CustomElement') ) {
18
  /**
19
  * The base class for all controls.
20
  *
21
  * @since 1.0.0
22
  */
23
+ abstract class Wbcr_FactoryForms418_CustomElement extends Wbcr_FactoryForms418_FormElement {
24
 
25
  /**
26
  * Is this element a custom form element?
libs/factory/forms/includes/form-element.class.php CHANGED
@@ -14,7 +14,7 @@
14
  exit;
15
  }
16
 
17
- if( !class_exists('Wbcr_FactoryForms400_FormElement') ) {
18
 
19
  /**
20
  * The base class for all form element (controls, holders).
@@ -23,7 +23,7 @@
23
  *
24
  * @since 1.0.0
25
  */
26
- abstract class Wbcr_FactoryForms400_FormElement {
27
 
28
  /**
29
  * A type of an elemnt.
@@ -37,7 +37,7 @@
37
  * An html attribute builder.
38
  *
39
  * @since 1.0.0
40
- * @var Wbcr_FactoryForms400_HtmlAttributeBuilder
41
  */
42
  private $html_builder;
43
 
@@ -53,7 +53,7 @@
53
  * A parent form.
54
  *
55
  * @since 1.0.0
56
- * @var Wbcr_FactoryForms400_Form
57
  */
58
  protected $form;
59
 
@@ -61,7 +61,7 @@
61
  * A form layout.
62
  *
63
  * @since 1.0.0
64
- * @var Wbcr_FactoryForms400_FormLayout
65
  */
66
  protected $layout;
67
 
@@ -94,7 +94,7 @@
94
  *
95
  * @since 1.0.0
96
  * @param mixed[] $options A holder options.
97
- * @param Wbcr_FactoryForms400_Form $form A parent form.
98
  */
99
  public function __construct($options, $form)
100
  {
@@ -102,7 +102,7 @@
102
  $this->form = $form;
103
  $this->layout = $form->layout;
104
 
105
- $this->html_builder = new Wbcr_FactoryForms400_HtmlAttributeBuilder();
106
 
107
  if( isset($this->options['cssClass']) ) {
108
  $this->html_builder->addCssClass($this->options['cssClass']);
14
  exit;
15
  }
16
 
17
+ if( !class_exists('Wbcr_FactoryForms418_FormElement') ) {
18
 
19
  /**
20
  * The base class for all form element (controls, holders).
23
  *
24
  * @since 1.0.0
25
  */
26
+ abstract class Wbcr_FactoryForms418_FormElement {
27
 
28
  /**
29
  * A type of an elemnt.
37
  * An html attribute builder.
38
  *
39
  * @since 1.0.0
40
+ * @var Wbcr_FactoryForms418_HtmlAttributeBuilder
41
  */
42
  private $html_builder;
43
 
53
  * A parent form.
54
  *
55
  * @since 1.0.0
56
+ * @var Wbcr_FactoryForms418_Form
57
  */
58
  protected $form;
59
 
61
  * A form layout.
62
  *
63
  * @since 1.0.0
64
+ * @var Wbcr_FactoryForms418_FormLayout
65
  */
66
  protected $layout;
67
 
94
  *
95
  * @since 1.0.0
96
  * @param mixed[] $options A holder options.
97
+ * @param Wbcr_FactoryForms418_Form $form A parent form.
98
  */
99
  public function __construct($options, $form)
100
  {
102
  $this->form = $form;
103
  $this->layout = $form->layout;
104
 
105
+ $this->html_builder = new Wbcr_FactoryForms418_HtmlAttributeBuilder();
106
 
107
  if( isset($this->options['cssClass']) ) {
108
  $this->html_builder->addCssClass($this->options['cssClass']);
libs/factory/forms/includes/form-layout.class.php CHANGED
@@ -14,12 +14,12 @@
14
  exit;
15
  }
16
 
17
- if( !class_exists('Wbcr_FactoryForms400_FormLayout') ) {
18
 
19
  /**
20
  * The base class for all form layouts.
21
  */
22
- abstract class Wbcr_FactoryForms400_FormLayout extends Wbcr_FactoryForms400_Holder {
23
 
24
  /**
25
  * A form layout name.
@@ -42,7 +42,7 @@
42
  *
43
  * @since 1.0.0
44
  * @param mixed[] $options A holder options.
45
- * @param Wbcr_FactoryForms400_Form $form A parent form.
46
  */
47
  public function __construct($options, $form)
48
  {
@@ -52,8 +52,8 @@
52
 
53
  parent::__construct($options, $form);
54
 
55
- $this->addCssClass('factory-forms-400-' . $this->type);
56
- $this->addCssClass('factory-forms-400-' . $this->name);
57
  }
58
 
59
  /**
14
  exit;
15
  }
16
 
17
+ if( !class_exists('Wbcr_FactoryForms418_FormLayout') ) {
18
 
19
  /**
20
  * The base class for all form layouts.
21
  */
22
+ abstract class Wbcr_FactoryForms418_FormLayout extends Wbcr_FactoryForms418_Holder {
23
 
24
  /**
25
  * A form layout name.
42
  *
43
  * @since 1.0.0
44
  * @param mixed[] $options A holder options.
45
+ * @param Wbcr_FactoryForms418_Form $form A parent form.
46
  */
47
  public function __construct($options, $form)
48
  {
52
 
53
  parent::__construct($options, $form);
54
 
55
+ $this->addCssClass('factory-forms-418-' . $this->type);
56
+ $this->addCssClass('factory-forms-418-' . $this->name);
57
  }
58
 
59
  /**
libs/factory/forms/includes/form.class.php CHANGED
@@ -15,16 +15,16 @@
15
  }
16
 
17
  // creating a license manager for each plugin created via the factory
18
- add_action('wbcr_factory_forms_400_plugin_created', 'wbcr_factory_forms_400_plugin_created');
19
 
20
- function wbcr_factory_forms_400_plugin_created($plugin)
21
  {
22
- $plugin->forms = new Wbcr_FactoryForms400_Manager($plugin);
23
  }
24
 
25
- if( !class_exists('Wbcr_FactoryForms400_Manager') ) {
26
 
27
- class Wbcr_FactoryForms400_Manager {
28
 
29
  // ----------------------------------------------------
30
  // Static fields and methods
@@ -57,7 +57,7 @@
57
  /**
58
  * Registers a set of new controls.
59
  *
60
- * @see FactoryForms400_Form::registerControl()
61
  *
62
  * @since 1.0.0
63
  * @return void
@@ -95,7 +95,7 @@
95
  /**
96
  * Registers a set of new holder controls.
97
  *
98
- * @see FactoryForms400_Form::registerHolder()
99
  *
100
  * @since 1.0.0
101
  * @return void
@@ -129,7 +129,7 @@
129
  /**
130
  * Registers a set of new custom form elements.
131
  *
132
- * @see FactoryForms400_Form::registerCustomElement()
133
  *
134
  * @since 1.0.0
135
  * @return void
@@ -180,11 +180,11 @@
180
  public static $controls_registered = false;
181
  }
182
  }
183
- if( !class_exists('Wbcr_FactoryForms400_Form') ) {
184
  /**
185
  * An abstraction for forms.
186
  */
187
- class Wbcr_FactoryForms400_Form {
188
 
189
  // ----------------------------------------------------
190
  // Object fields and methods
@@ -194,7 +194,7 @@
194
  * A value provider of the form that is used to save and load values.
195
  *
196
  * @since 1.0.0
197
- * @var Wbcr_IFactoryForms400_ValueProvider
198
  */
199
  private $provider;
200
 
@@ -245,11 +245,10 @@
245
  * A current form layout used to render a form.
246
  *
247
  * @since 1.0.0
248
- * @var FactoryForms400_FormLayout
249
  */
250
  public $layout;
251
 
252
-
253
  /**
254
  * Creates a new instance of a form.
255
  *
@@ -262,28 +261,27 @@
262
  *
263
  * @since 1.0.0
264
  * @param array $options
265
- * @param Wbcr_Factory400_Plugin $plugin
266
  */
267
- public function __construct(array $options = array(), Wbcr_Factory400_Plugin $plugin)
268
  {
269
  // register controls once, when the first form is created
270
- if( !Wbcr_FactoryForms400_Manager::$controls_registered ) {
271
 
272
- do_action('wbcr_factory_forms_400_register_controls', $plugin);
273
 
274
  //if( !empty($plugin) ) {
275
- do_action('wbcr_factory_forms_400_register_controls_' . $plugin->getPluginName(), $plugin);
276
  //}
277
 
278
- Wbcr_FactoryForms400_Manager::$controls_registered = true;
279
  }
280
 
281
- $this->scope = isset($options['scope'])
282
- ? $options['scope']
283
- : null;
284
- $this->name = isset($options['name'])
285
- ? $options['name']
286
- : $this->name;
287
 
288
  if( isset($options['formLayout']) ) {
289
  $this->form_layout = $options['formLayout'];
@@ -291,14 +289,14 @@
291
  $this->form_layout = 'bootstrap-3';
292
  }
293
 
294
- Wbcr_FactoryForms400_Manager::$temper = 'flat';
295
  }
296
 
297
  /**
298
  * Sets a provider for the control.
299
  *
300
  * @since 1.0.0
301
- * @param Wbcr_IFactoryForms400_ValueProvider $provider
302
  * @return void
303
  */
304
  public function setProvider($provider)
@@ -334,14 +332,14 @@
334
  */
335
  public function getItems()
336
  {
337
- return apply_filters('wbcr_factory_400_form_items', $this->items, $this->name);
338
  }
339
 
340
  /**
341
  * Returns form controls (control objects).
342
  *
343
  * @since 1.0.0
344
- * @return Wbcr_FactoryForms400_Control[]
345
  */
346
  public function getControls()
347
  {
@@ -357,14 +355,12 @@
357
  * Builds a form items to the control objects ready to use.
358
  *
359
  * @param null $holder
360
- * @return Wbcr_FactoryForms400_Control[]
361
  */
362
 
363
  public function createControls($holder = null)
364
  {
365
- $items = ($holder == null)
366
- ? $this->getItems()
367
- : $holder['items'];
368
 
369
  foreach($items as $item) {
370
 
@@ -399,7 +395,7 @@
399
  *
400
  * @since 1.0.0
401
  * @param array $item Item data.
402
- * @return Wbcr_FactoryForms400_FormElement|null A form element.
403
  */
404
  public function createElement($item)
405
  {
@@ -421,7 +417,7 @@
421
  *
422
  * @since 1.0.0
423
  * @param mixed[] $item Data of items.
424
- * @return Wbcr_FactoryForms400_FormElement[] Created elements.
425
  */
426
  public function createElements($items = array())
427
  {
@@ -437,7 +433,7 @@
437
  *
438
  * @since 1.0.0
439
  * @param array $item Item data.
440
- * @return Wbcr_FactoryForms400_Control A control object.
441
  */
442
  public function createControl($item)
443
  {
@@ -445,7 +441,7 @@
445
 
446
  if( is_array($item) ) {
447
 
448
- $control_data = Wbcr_FactoryForms400_Manager::$registered_controls[$item['type']];
449
 
450
  require_once($control_data['include']);
451
 
@@ -469,7 +465,7 @@
469
  *
470
  * @since 1.0.0
471
  * @param array $item Item data.
472
- * @return Wbcr_FactoryForms400_Holder A control holder object.
473
  */
474
  public function createHolder($item)
475
  {
@@ -477,7 +473,7 @@
477
 
478
  if( is_array($item) ) {
479
 
480
- $holderData = Wbcr_FactoryForms400_Manager::$registered_holders[$item['type']];
481
  require_once($holderData['include']);
482
 
483
  $object = new $holderData['class']($item, $this);
@@ -495,7 +491,7 @@
495
  *
496
  * @since 1.0.0
497
  * @param mixed $item Item data.
498
- * @return FactoryForms400_FormElement A custom form element object.
499
  */
500
  public function createCustomElement($item)
501
  {
@@ -503,7 +499,7 @@
503
 
504
  if( is_array($item) ) {
505
 
506
- $data = Wbcr_FactoryForms400_Manager::$registered_custom_elements[$item['type']];
507
  require_once($data['include']);
508
 
509
  $options = $item;
@@ -527,12 +523,12 @@
527
  public function html($options = array())
528
  {
529
 
530
- if( !isset(Wbcr_FactoryForms400_Manager::$form_layouts[$this->form_layout]) ) {
531
  die(sprintf('[ERROR] The form layout %s was not found.', $this->form_layout));
532
  }
533
 
534
  // include a render code
535
- $layout_data = Wbcr_FactoryForms400_Manager::$form_layouts[$this->form_layout];
536
  require_once($layout_data['include']);
537
 
538
  $this->connectAssets();
@@ -556,7 +552,7 @@
556
  {
557
 
558
  $this->connectAssetsForItems();
559
- $layout_data = Wbcr_FactoryForms400_Manager::$form_layouts[$this->form_layout];
560
 
561
  if( $layout_data['name'] == 'default' ) {
562
  if( isset($layout_data['style']) ) {
@@ -606,9 +602,9 @@
606
 
607
  $haystack = array();
608
  if( self::isControl($type) ) {
609
- $haystack = Wbcr_FactoryForms400_Manager::$registered_controls;
610
  } elseif( self::isControlHolder($type) ) {
611
- $haystack = Wbcr_FactoryForms400_Manager::$registered_holders;
612
  }
613
 
614
  if( isset($haystack[$type]) ) {
@@ -635,7 +631,6 @@
635
  * Saves form data by using a specified value provider.
636
  *
637
  * @since 1.0.0
638
- * @return mixed
639
  */
640
  public function save()
641
  {
@@ -644,11 +639,12 @@
644
  }
645
 
646
  $controls = $this->getControls();
647
- foreach($controls as $control) {
648
 
 
649
  $values = $control->getValuesToSave();
650
- foreach($values as $keyToSave => $valueToSave) {
651
- $this->provider->setValue($keyToSave, $valueToSave);
 
652
  }
653
  }
654
 
@@ -664,7 +660,7 @@
664
  */
665
  public static function isControl($item)
666
  {
667
- return isset(Wbcr_FactoryForms400_Manager::$registered_controls[$item['type']]);
668
  }
669
 
670
  /**
@@ -676,7 +672,7 @@
676
  */
677
  public static function isControlHolder($item)
678
  {
679
- return isset(Wbcr_FactoryForms400_Manager::$registered_holders[$item['type']]);
680
  }
681
 
682
  /**
@@ -688,7 +684,7 @@
688
  */
689
  public static function isCustomElement($item)
690
  {
691
- return isset(Wbcr_FactoryForms400_Manager::$registered_custom_elements[$item['type']]);
692
  }
693
  }
694
  }
15
  }
16
 
17
  // creating a license manager for each plugin created via the factory
18
+ add_action('wbcr_factory_forms_418_plugin_created', 'wbcr_factory_forms_418_plugin_created');
19
 
20
+ function wbcr_factory_forms_418_plugin_created($plugin)
21
  {
22
+ $plugin->forms = new Wbcr_FactoryForms418_Manager($plugin);
23
  }
24
 
25
+ if( !class_exists('Wbcr_FactoryForms418_Manager') ) {
26
 
27
+ class Wbcr_FactoryForms418_Manager {
28
 
29
  // ----------------------------------------------------
30
  // Static fields and methods
57
  /**
58
  * Registers a set of new controls.
59
  *
60
+ * @see FactoryForms418_Form::registerControl()
61
  *
62
  * @since 1.0.0
63
  * @return void
95
  /**
96
  * Registers a set of new holder controls.
97
  *
98
+ * @see FactoryForms418_Form::registerHolder()
99
  *
100
  * @since 1.0.0
101
  * @return void
129
  /**
130
  * Registers a set of new custom form elements.
131
  *
132
+ * @see FactoryForms418_Form::registerCustomElement()
133
  *
134
  * @since 1.0.0
135
  * @return void
180
  public static $controls_registered = false;
181
  }
182
  }
183
+ if( !class_exists('Wbcr_FactoryForms418_Form') ) {
184
  /**
185
  * An abstraction for forms.
186
  */
187
+ class Wbcr_FactoryForms418_Form {
188
 
189
  // ----------------------------------------------------
190
  // Object fields and methods
194
  * A value provider of the form that is used to save and load values.
195
  *
196
  * @since 1.0.0
197
+ * @var Wbcr_IFactoryForms418_ValueProvider
198
  */
199
  private $provider;
200
 
245
  * A current form layout used to render a form.
246
  *
247
  * @since 1.0.0
248
+ * @var Wbcr_FactoryForms418_FormLayout
249
  */
250
  public $layout;
251
 
 
252
  /**
253
  * Creates a new instance of a form.
254
  *
261
  *
262
  * @since 1.0.0
263
  * @param array $options
264
+ * @param Wbcr_Factory420_Plugin $plugin
265
  */
266
+ public function __construct(array $options = array(), Wbcr_Factory420_Plugin $plugin)
267
  {
268
  // register controls once, when the first form is created
269
+ if( !Wbcr_FactoryForms418_Manager::$controls_registered ) {
270
 
271
+ do_action('wbcr_factory_forms_418_register_controls', $plugin);
272
 
273
  //if( !empty($plugin) ) {
274
+ do_action('wbcr_factory_forms_418_register_controls_' . $plugin->getPluginName(), $plugin);
275
  //}
276
 
277
+ Wbcr_FactoryForms418_Manager::$controls_registered = true;
278
  }
279
 
280
+ $this->scope = isset($options['scope']) ? $options['scope'] : null;
281
+ $this->name = isset($options['name']) ? $options['name'] : $this->name;
282
+ /*$this->all_sites = isset($options['all_sites'])
283
+ ? $options['all_sites']
284
+ : false;*/
 
285
 
286
  if( isset($options['formLayout']) ) {
287
  $this->form_layout = $options['formLayout'];
289
  $this->form_layout = 'bootstrap-3';
290
  }
291
 
292
+ Wbcr_FactoryForms418_Manager::$temper = 'flat';
293
  }
294
 
295
  /**
296
  * Sets a provider for the control.
297
  *
298
  * @since 1.0.0
299
+ * @param Wbcr_IFactoryForms418_ValueProvider $provider
300
  * @return void
301
  */
302
  public function setProvider($provider)
332
  */
333
  public function getItems()
334
  {
335
+ return apply_filters('wbcr_factory_420_form_items', $this->items, $this->name);
336
  }
337
 
338
  /**
339
  * Returns form controls (control objects).
340
  *
341
  * @since 1.0.0
342
+ * @return Wbcr_FactoryForms418_Control[]
343
  */
344
  public function getControls()
345
  {
355
  * Builds a form items to the control objects ready to use.
356
  *
357
  * @param null $holder
358
+ * @return Wbcr_FactoryForms418_Control[]
359
  */
360
 
361
  public function createControls($holder = null)
362
  {
363
+ $items = ($holder == null) ? $this->getItems() : $holder['items'];
 
 
364
 
365
  foreach($items as $item) {
366
 
395
  *
396
  * @since 1.0.0
397
  * @param array $item Item data.
398
+ * @return Wbcr_FactoryForms418_FormElement|null A form element.
399
  */
400
  public function createElement($item)
401
  {
417
  *
418
  * @since 1.0.0
419
  * @param mixed[] $item Data of items.
420
+ * @return Wbcr_FactoryForms418_FormElement[] Created elements.
421
  */
422
  public function createElements($items = array())
423
  {
433
  *
434
  * @since 1.0.0
435
  * @param array $item Item data.
436
+ * @return Wbcr_FactoryForms418_Control A control object.
437
  */
438
  public function createControl($item)
439
  {
441
 
442
  if( is_array($item) ) {
443
 
444
+ $control_data = Wbcr_FactoryForms418_Manager::$registered_controls[$item['type']];
445
 
446
  require_once($control_data['include']);
447
 
465
  *
466
  * @since 1.0.0
467
  * @param array $item Item data.
468
+ * @return Wbcr_FactoryForms418_Holder A control holder object.
469
  */
470
  public function createHolder($item)
471
  {
473
 
474
  if( is_array($item) ) {
475
 
476
+ $holderData = Wbcr_FactoryForms418_Manager::$registered_holders[$item['type']];
477
  require_once($holderData['include']);
478
 
479
  $object = new $holderData['class']($item, $this);
491
  *
492
  * @since 1.0.0
493
  * @param mixed $item Item data.
494
+ * @return Wbcr_FactoryForms418_FormElement A custom form element object.
495
  */
496
  public function createCustomElement($item)
497
  {
499
 
500
  if( is_array($item) ) {
501
 
502
+ $data = Wbcr_FactoryForms418_Manager::$registered_custom_elements[$item['type']];
503
  require_once($data['include']);
504
 
505
  $options = $item;
523
  public function html($options = array())
524
  {
525
 
526
+ if( !isset(Wbcr_FactoryForms418_Manager::$form_layouts[$this->form_layout]) ) {
527
  die(sprintf('[ERROR] The form layout %s was not found.', $this->form_layout));
528
  }
529
 
530
  // include a render code
531
+ $layout_data = Wbcr_FactoryForms418_Manager::$form_layouts[$this->form_layout];
532
  require_once($layout_data['include']);
533
 
534
  $this->connectAssets();
552
  {
553
 
554
  $this->connectAssetsForItems();
555
+ $layout_data = Wbcr_FactoryForms418_Manager::$form_layouts[$this->form_layout];
556
 
557
  if( $layout_data['name'] == 'default' ) {
558
  if( isset($layout_data['style']) ) {
602
 
603
  $haystack = array();
604
  if( self::isControl($type) ) {
605
+ $haystack = Wbcr_FactoryForms418_Manager::$registered_controls;
606
  } elseif( self::isControlHolder($type) ) {
607
+ $haystack = Wbcr_FactoryForms418_Manager::$registered_holders;
608
  }
609
 
610
  if( isset($haystack[$type]) ) {
631
  * Saves form data by using a specified value provider.
632
  *
633
  * @since 1.0.0
 
634
  */
635
  public function save()
636
  {
639
  }
640
 
641
  $controls = $this->getControls();
 
642
 
643
+ foreach($controls as $control) {
644
  $values = $control->getValuesToSave();
645
+
646
+ foreach($values as $key_to_save => $value_to_save) {
647
+ $this->provider->setValue($key_to_save, $value_to_save);
648
  }
649
  }
650
 
660
  */
661
  public static function isControl($item)
662
  {
663
+ return isset(Wbcr_FactoryForms418_Manager::$registered_controls[$item['type']]);
664
  }
665
 
666
  /**
672
  */
673
  public static function isControlHolder($item)
674
  {
675
+ return isset(Wbcr_FactoryForms418_Manager::$registered_holders[$item['type']]);
676
  }
677
 
678
  /**
684
  */
685
  public static function isCustomElement($item)
686
  {
687
+ return isset(Wbcr_FactoryForms418_Manager::$registered_custom_elements[$item['type']]);
688
  }
689
  }
690
  }
libs/factory/forms/includes/holder.class.php CHANGED
@@ -14,20 +14,20 @@
14
  exit;
15
  }
16
 
17
- if( !class_exists('Wbcr_FactoryForms400_Holder') ) {
18
 
19
  /**
20
  * The base class for control holders.
21
  *
22
  * @since 1.0.0
23
  */
24
- abstract class Wbcr_FactoryForms400_Holder extends Wbcr_FactoryForms400_FormElement {
25
 
26
  /**
27
  * Holder Elements.
28
  *
29
  * @since 1.0.0
30
- * @var Wbcr_FactoryForms400_Control[]
31
  */
32
  protected $elements = array();
33
 
@@ -44,7 +44,7 @@
44
  *
45
  * @since 1.0.0
46
  * @param mixed[] $options A holder options.
47
- * @param Wbcr_FactoryForms400_Form $form A parent form.
48
  */
49
  public function __construct($options, $form)
50
  {
@@ -56,7 +56,7 @@
56
  * Returns holder elements.
57
  *
58
  * @since 1.0.0
59
- * @return Wbcr_FactoryForms400_Control[].
60
  */
61
  public function getElements()
62
  {
@@ -84,7 +84,7 @@
84
  $is_first_item = false;
85
  }
86
 
87
- do_action('wbcr_factory_400_form_before_element_' . $element->getOption('name'));
88
 
89
  // if a current item is a control holder
90
  if( $element->is_holder ) {
14
  exit;
15
  }
16
 
17
+ if( !class_exists('Wbcr_FactoryForms418_Holder') ) {
18
 
19
  /**
20
  * The base class for control holders.
21
  *
22
  * @since 1.0.0
23
  */
24
+ abstract class Wbcr_FactoryForms418_Holder extends Wbcr_FactoryForms418_FormElement {
25
 
26
  /**
27
  * Holder Elements.
28
  *
29
  * @since 1.0.0
30
+ * @var Wbcr_FactoryForms418_Control[]
31
  */
32
  protected $elements = array();
33
 
44
  *
45
  * @since 1.0.0
46
  * @param mixed[] $options A holder options.
47
+ * @param Wbcr_FactoryForms418_Form $form A parent form.
48
  */
49
  public function __construct($options, $form)
50
  {
56
  * Returns holder elements.
57
  *
58
  * @since 1.0.0
59
+ * @return Wbcr_FactoryForms418_Control[].
60
  */
61
  public function getElements()
62
  {
84
  $is_first_item = false;
85
  }
86
 
87
+ do_action('wbcr_factory_420_form_before_element_' . $element->getOption('name'));
88
 
89
  // if a current item is a control holder
90
  if( $element->is_holder ) {
libs/factory/forms/includes/html-builder.class.php CHANGED
@@ -14,13 +14,13 @@
14
  exit;
15
  }
16
 
17
- if( !class_exists('Wbcr_FactoryForms400_HtmlAttributeBuilder') ) {
18
  /**
19
  * Html Attribute Builder
20
  *
21
  * @since 1.0.0
22
  */
23
- class Wbcr_FactoryForms400_HtmlAttributeBuilder {
24
 
25
  /**
26
  * An array to store css classes.
14
  exit;
15
  }
16
 
17
+ if( !class_exists('Wbcr_FactoryForms418_HtmlAttributeBuilder') ) {
18
  /**
19
  * Html Attribute Builder
20
  *
21
  * @since 1.0.0
22
  */
23
+ class Wbcr_FactoryForms418_HtmlAttributeBuilder {
24
 
25
  /**
26
  * An array to store css classes.
libs/factory/forms/includes/index.php ADDED
@@ -0,0 +1,2 @@
 
 
1
+ <?php
2
+ // Silence is golden.
libs/factory/forms/includes/providers/index.php ADDED
@@ -0,0 +1,2 @@
 
 
1
+ <?php
2
+ // Silence is golden.
libs/factory/forms/includes/providers/meta-value-provider.class.php CHANGED
@@ -14,7 +14,7 @@
14
  exit;
15
  }
16
 
17
- if( !class_exists('Wbcr_FactoryForms400_OptionsValueProvider') ) {
18
 
19
  /**
20
  * Factory Meta Value Provider
@@ -24,7 +24,7 @@
24
  *
25
  * @since 1.0.0
26
  */
27
- class Wbcr_FactoryForms400_MetaValueProvider implements Wbcr_IFactoryForms400_ValueProvider {
28
 
29
 
30
  public $scope;
14
  exit;
15
  }
16
 
17
+ if( !class_exists('Wbcr_FactoryForms418_OptionsValueProvider') ) {
18
 
19
  /**
20
  * Factory Meta Value Provider
24
  *
25
  * @since 1.0.0
26
  */
27
+ class Wbcr_FactoryForms418_MetaValueProvider implements Wbcr_IFactoryForms418_ValueProvider {
28
 
29
 
30
  public $scope;
libs/factory/forms/includes/providers/options-value-provider.class.php CHANGED
@@ -13,7 +13,7 @@
13
  exit;
14
  }
15
 
16
- if( !class_exists('Wbcr_FactoryForms400_OptionsValueProvider') ) {
17
 
18
  /**
19
  * Factory Options Value Provider
@@ -22,28 +22,28 @@
22
  *
23
  * @since 1.0.0
24
  */
25
- class Wbcr_FactoryForms400_OptionsValueProvider implements Wbcr_IFactoryForms400_ValueProvider {
26
 
27
  /**
28
- * Values to save $optionName => $optionValue
29
  *
30
  * @since 1.0.0
31
- * @var mixed[]
32
  */
33
- private $values = array();
34
 
35
  /**
36
- * A prefix that will be added to all option names.
37
  *
38
  * @since 1.0.0
39
- * @var string
40
  */
41
- public $scope;
42
 
43
  /**
44
  * Creates a new instance of an options value provider.
45
  */
46
- public function __construct(Wbcr_Factory400_Plugin $plugin)
47
  {
48
  $this->plugin = $plugin;
49
  }
@@ -61,12 +61,14 @@
61
  */
62
  public function saveChanges()
63
  {
64
- $this->plugin->updateOptions($this->values);
 
 
65
  }
66
 
67
  public function getValue($name, $default = null, $multiple = false)
68
  {
69
- $value = $this->plugin->getOption($name, $default);
70
 
71
  if( $value === 'true' || $value === true ) {
72
  $value = 1;
13
  exit;
14
  }
15
 
16
+ if( !class_exists('Wbcr_FactoryForms418_OptionsValueProvider') ) {
17
 
18
  /**
19
  * Factory Options Value Provider
22
  *
23
  * @since 1.0.0
24
  */
25
+ class Wbcr_FactoryForms418_OptionsValueProvider implements Wbcr_IFactoryForms418_ValueProvider {
26
 
27
  /**
28
+ * A prefix that will be added to all option names.
29
  *
30
  * @since 1.0.0
31
+ * @var string
32
  */
33
+ public $scope;
34
 
35
  /**
36
+ * Values to save $optionName => $optionValue
37
  *
38
  * @since 1.0.0
39
+ * @var mixed[]
40
  */
41
+ private $values = array();
42
 
43
  /**
44
  * Creates a new instance of an options value provider.
45
  */
46
+ public function __construct(Wbcr_Factory420_Plugin $plugin)
47
  {
48
  $this->plugin = $plugin;
49
  }
61
  */
62
  public function saveChanges()
63
  {
64
+ foreach((array)$this->values as $option_name => $option_value) {
65
+ $this->plugin->updatePopulateOption($option_name, $option_value);
66
+ }
67
  }
68
 
69
  public function getValue($name, $default = null, $multiple = false)
70
  {
71
+ $value = $this->plugin->getPopulateOption($name, $default);
72
 
73
  if( $value === 'true' || $value === true ) {
74
  $value = 1;
libs/factory/forms/includes/providers/value-provider.interface.php CHANGED
@@ -14,13 +14,13 @@
14
  if( !defined('ABSPATH') ) {
15
  exit;
16
  }
17
- if( !class_exists('Wbcr_IFactoryForms400_ValueProvider') ) {
18
  /**
19
  * The interface for all value provides.
20
  *
21
  * @since 1.0.0
22
  */
23
- interface Wbcr_IFactoryForms400_ValueProvider {
24
 
25
  /**
26
  * Inits a form a provider to get data from a storage.
14
  if( !defined('ABSPATH') ) {
15
  exit;
16
  }
17
+ if( !class_exists('Wbcr_IFactoryForms418_ValueProvider') ) {
18
  /**
19
  * The interface for all value provides.
20
  *
21
  * @since 1.0.0
22
  */
23
+ interface Wbcr_IFactoryForms418_ValueProvider {
24
 
25
  /**
26
  * Inits a form a provider to get data from a storage.
libs/factory/forms/index.php ADDED
@@ -0,0 +1,2 @@
 
 
1
+ <?php
2
+ // Silence is golden.
libs/factory/forms/langs/wbcr_factory_forms_400-fr-FR.mo DELETED
Binary file
libs/factory/forms/langs/wbcr_factory_forms_400-fr-FR.po DELETED
@@ -1,104 +0,0 @@
1
- msgid ""
2
- msgstr ""
3
- "Project-Id-Version: factory_forms\n"
4
- "POT-Creation-Date: 2017-11-09 10:37+0300\n"
5
- "PO-Revision-Date: 2017-11-09 18:37+0300\n"
6
- "Last-Translator: \n"
7
- "Language-Team: Alex Kovalev <alex.kovalevv@gmail.com>\n"
8
- "Language: fr\n"
9
- "MIME-Version: 1.0\n"
10
- "Content-Type: text/plain; charset=UTF-8\n"
11
- "Content-Transfer-Encoding: 8bit\n"
12
- "X-Generator: Poedit 1.8.8\n"
13
- "X-Poedit-Basepath: ..\n"
14
- "Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
15
- "%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
16
- "X-Poedit-SourceCharset: UTF-8\n"
17
- "X-Poedit-KeywordsList: __;_e;_n:1,2;_x:1,2c;_ex:1,2c\n"
18
- "X-Poedit-SearchPath-0: .\n"
19
-
20
- #: controls/checkbox.php:125
21
- msgid "On"
22
- msgstr "On"
23
-
24
- #: controls/checkbox.php:128
25
- msgid "Off"
26
- msgstr "Off"
27
-
28
- #: controls/dropdown.php:126 controls/list.php:89 controls/list.php:127
29
- msgid "The list is empty."
30
- msgstr "La liste est vide."
31
-
32
- #: controls/dropdown.php:258 controls/dropdown.php:330
33
- msgid "- empty -"
34
- msgstr "- vide -"
35
-
36
- #: controls/font.php:73 controls/google-font.php:41
37
- msgid "(use default website font)"
38
- msgstr "(utiliser la police de site par défaut)"
39
-
40
- #: controls/font.php:76
41
- msgid "Sans Serif:"
42
- msgstr "Sans Serif:"
43
-
44
- #: controls/font.php:127
45
- msgid "Serif:"
46
- msgstr "Serif:"
47
-
48
- #: controls/font.php:177
49
- msgid "Monospaced:"
50
- msgstr "Monospaced:"
51
-
52
- #: controls/google-font.php:44
53
- msgid "Standard:"
54
- msgstr "Standard:"
55
-
56
- #: controls/google-font.php:53
57
- msgid "Google Fonts:"
58
- msgstr "Google Fonts:"
59
-
60
- #: controls/google-font.php:94
61
- msgid "Unable to retrieve the list of Google Fonts."
62
- msgstr "Impossible de récupérer la liste des polices Google."
63
-
64
- #: controls/google-font.php:101
65
- msgid "Invalide response from the Google Fonts API."
66
- msgstr "Réponse invalidée de l'API Google Fonts."
67
-
68
- #: controls/google-font.php:110
69
- msgid "Unexpected error. The list of Google Fonts are empty."
70
- msgstr "Erreur inattendue. La liste des polices Google est vide."
71
-
72
- #: controls/gradient.php:59
73
- msgid "vertical"
74
- msgstr "verticale"
75
-
76
- #: controls/gradient.php:60
77
- msgid "horizontal"
78
- msgstr "horizontale"
79
-
80
- #: controls/holders/more-link.php:47
81
- msgid "hide extra options"
82
- msgstr "masquer les options supplémentaires"
83
-
84
- #: controls/paddings-editor.php:53
85
- msgid "Select a side and move the slider to set up:"
86
- msgstr "Sélectionnez un côté et déplacez le curseur pour configurer:"
87
-
88
- #: controls/pattern.php:90
89
- msgid "Change color"
90
- msgstr "Changer de couleur"
91
-
92
- #: controls/pattern.php:92
93
- msgid "re-color"
94
- msgstr "re-color"
95
-
96
- #: controls/pattern.php:99
97
- msgid "Select color:"
98
- msgstr "Sélectionnez couleur:"
99
-
100
- #: controls/pattern.php:102
101
- msgid "Changing the color may takes a minute or more. Please be patient."
102
- msgstr ""
103
- "Changer la couleur peut prendre une minute ou plus. S'll vous plaît "
104
- "soyez patient."
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
libs/factory/forms/langs/{wbcr_factory_forms_400-ru_RU.mo → wbcr_factory_forms_418-ru_RU.mo} RENAMED
File without changes
libs/factory/forms/langs/{wbcr_factory_forms_400-ru_RU.po → wbcr_factory_forms_418-ru_RU.po} RENAMED
File without changes
libs/factory/forms/layouts/bootstrap-3/bootstrap-3.php CHANGED
@@ -14,11 +14,11 @@
14
  exit;
15
  }
16
 
17
- if( !class_exists('Wbcr_FactoryForms400_Bootstrap3FormLayout') ) {
18
  /**
19
  * A form layout based on Twitter Bootstrap 3
20
  */
21
- class Wbcr_FactoryForms400_Bootstrap3FormLayout extends Wbcr_FactoryForms400_FormLayout {
22
 
23
  public $name = 'default';
24
 
@@ -27,7 +27,7 @@
27
  *
28
  * @since 1.0.0
29
  * @param array $options A holder options.
30
- * @param Wbcr_FactoryForms400_Form $form A parent form.
31
  */
32
  public function __construct($options, $form)
33
  {
@@ -68,7 +68,7 @@
68
  }
69
 
70
  /**
71
- * @param Wbcr_FactoryForms400_Control $control
72
  */
73
  public function beforeControl($control)
74
  {
@@ -116,7 +116,7 @@
116
  }
117
 
118
  /**
119
- * @param Wbcr_FactoryForms400_Control $control
120
  */
121
  public function afterControl($control)
122
  {
@@ -168,7 +168,7 @@
168
  }
169
 
170
  /**
171
- * @param Wbcr_FactoryForms400_Control $control
172
  * @param int $index
173
  * @param int $total
174
  */
@@ -193,7 +193,7 @@
193
  }
194
 
195
  /**
196
- * @param Wbcr_FactoryForms400_Control $control
197
  * @param int $index
198
  * @param int $total
199
  */
14
  exit;
15
  }
16
 
17
+ if( !class_exists('Wbcr_FactoryForms418_Bootstrap3FormLayout') ) {
18
  /**
19
  * A form layout based on Twitter Bootstrap 3
20
  */
21
+ class Wbcr_FactoryForms418_Bootstrap3FormLayout extends Wbcr_FactoryForms418_FormLayout {
22
 
23
  public $name = 'default';
24
 
27
  *
28
  * @since 1.0.0
29
  * @param array $options A holder options.
30
+ * @param Wbcr_FactoryForms418_Form $form A parent form.
31
  */
32
  public function __construct($options, $form)
33
  {
68
  }
69
 
70
  /**
71
+ * @param Wbcr_FactoryForms418_Control $control
72
  */
73
  public function beforeControl($control)
74
  {
116
  }
117
 
118
  /**
119
+ * @param Wbcr_FactoryForms418_Control $control
120
  */
121
  public function afterControl($control)
122
  {
168
  }
169
 
170
  /**
171
+ * @param Wbcr_FactoryForms418_Control $control
172
  * @param int $index
173
  * @param int $total
174
  */
193
  }
194
 
195
  /**
196
+ * @param Wbcr_FactoryForms418_Control $control
197
  * @param int $index
198
  * @param int $total
199
  */
libs/factory/forms/layouts/bootstrap-3/index.php ADDED
@@ -0,0 +1,2 @@
 
 
1
+ <?php
2
+ // Silence is golden.
libs/factory/forms/layouts/index.php ADDED
@@ -0,0 +1,2 @@
 
 
1
+ <?php
2
+ // Silence is golden.
libs/factory/pages/boot.php CHANGED
@@ -1,40 +1,43 @@
1
  <?php
2
- /**
3
- * Factory Pages
4
- *
5
- * @author Alex Kovalev <alex.kovalevv@gmail.com>
6
- * @copyright (c) 2018, Webcraftic Ltd
7
- *
8
- * @package core
9
- * @since 1.0.1
10
- */
11
-
12
- // Exit if accessed directly
13
- if( !defined('ABSPATH') ) {
14
- exit;
15
- }
16
-
17
- // module provides function only for the admin area
18
- if( !is_admin() ) {
19
- return;
20
- }
21
-
22
- if( defined('FACTORY_PAGES_401_LOADED') ) {
23
- return;
24
- }
25
- define('FACTORY_PAGES_401_LOADED', true);
26
-
27
- define('FACTORY_PAGES_401_DIR', dirname(__FILE__));
28
- define('FACTORY_PAGES_401_URL', plugins_url(null, __FILE__));
29
-
30
- if( !defined('FACTORY_FLAT_ADMIN') ) {
31
- define('FACTORY_FLAT_ADMIN', true);
32
- }
33
-
34
- load_plugin_textdomain('wbcr_factory_pages_401', false, dirname(plugin_basename(__FILE__)) . '/langs');
35
-
36
- require(FACTORY_PAGES_401_DIR . '/pages.php');
37
- require(FACTORY_PAGES_401_DIR . '/includes/page.class.php');
38
- require(FACTORY_PAGES_401_DIR . '/includes/admin-page.class.php');
39
- require(FACTORY_PAGES_401_DIR . '/templates/impressive-page.class.php');
 
 
 
40
 
1
  <?php
2
+ /**
3
+ * Factory Pages
4
+ *
5
+ * @author Alex Kovalev <alex.kovalevv@gmail.com>
6
+ * @since 1.0.1
7
+ * @package core
8
+ * @copyright (c) 2018, Webcraftic Ltd
9
+ *
10
+ */
11
+
12
+ // Exit if accessed directly
13
+ if ( ! defined( 'ABSPATH' ) ) {
14
+ exit;
15
+ }
16
+
17
+ // module provides function only for the admin area
18
+ if ( ! is_admin() ) {
19
+ return;
20
+ }
21
+
22
+ if ( defined( 'FACTORY_PAGES_420_LOADED' ) ) {
23
+ return;
24
+ }
25
+
26
+ define( 'FACTORY_PAGES_420_LOADED', true );
27
+
28
+ define( 'FACTORY_PAGES_420_VERSION', '4.2.0' );
29
+
30
+ define( 'FACTORY_PAGES_420_DIR', dirname( __FILE__ ) );
31
+ define( 'FACTORY_PAGES_420_URL', plugins_url( null, __FILE__ ) );
32
+
33
+ if ( ! defined( 'FACTORY_FLAT_ADMIN' ) ) {
34
+ define( 'FACTORY_FLAT_ADMIN', true );
35
+ }
36
+
37
+ load_plugin_textdomain( 'wbcr_factory_pages_420', false, dirname( plugin_basename( __FILE__ ) ) . '/langs' );
38
+
39
+ require( FACTORY_PAGES_420_DIR . '/pages.php' );
40
+ require( FACTORY_PAGES_420_DIR . '/includes/page.class.php' );
41
+ require( FACTORY_PAGES_420_DIR . '/includes/admin-page.class.php' );
42
+ require( FACTORY_PAGES_420_DIR . '/templates/impressive-page.class.php' );
43
 
libs/factory/pages/includes/admin-page.class.php CHANGED
@@ -1,451 +1,563 @@
1
  <?php
2
- /**
3
- * Admin page class
4
- *
5
- * @author Alex Kovalev <alex.kovalevv@gmail.com>
6
- * @copyright (c) 2018, Webcraftic Ltd
7
- *
8
- * @package factory-core
9
- * @since 1.0.0
10
- */
11
-
12
- // Exit if accessed directly
13
- if( !defined('ABSPATH') ) {
14
- exit;
15
- }
16
-
17
- if( !class_exists('Wbcr_FactoryPages401_AdminPage') ) {
18
-
19
- class Wbcr_FactoryPages401_AdminPage extends Wbcr_FactoryPages401_Page {
20
-
21
- /**
22
- * Visible page title.
23
- * For example: 'License Manager'
24
- * @var string
25
- */
26
- public $page_title;
27
-
28
- /**
29
- * Visible title in menu.
30
- * For example: 'License Manager'
31
- * @var string
32
- */
33
- public $menu_title = null;
34
-
35
- /**
36
- * If set, an extra sub menu will be created with another title.
37
- * @var string
38
- */
39
- public $menu_sub_title = null;
40
-
41
- /**
42
- * Menu icon (only if a page is placed as a main menu).
43
- * For example: '~/assets/img/menu-icon.png'
44
- * For example dashicons: '\f321'
45
- * @var string
46
- */
47
- public $menu_icon = null;
48
-
49
- /**
50
- * Menu position (only if a page is placed as a main menu).
51
- * @link http://codex.wordpress.org/Function_Reference/add_menu_page
52
- * @var string
53
- */
54
- public $menu_position = null;
55
-
56
- /**
57
- * Menu type. Set it to add the page to the specified type menu.
58
- * For example: 'post'
59
- * @var string
60
- */
61
- public $menu_post_type = null;
62
-
63
- /**
64
- * if specified the page will be added to the given menu target as a submenu.
65
- * For example: 'edit.php?post_type=custom-post-type'
66
- * @var string
67
- */
68
- public $menu_target = null;
69
-
70
- /**
71
- * if true, then admin.php is used as a base url.
72
- * @var bool
73
- */
74
- public $custom_target = false;
75
-
76
- /**
77
- * Capabilities for roles that have access to work with this page.
78
- * Leave it empty to use inherited capabilities for custom post type menu.
79
- * @link http://codex.wordpress.org/Roles_and_Capabilities
80
- * @var array An array of the capabilities.
81
- */
82
- public $capabilitiy = null;
83
-
84
- /**
85
- * If true, the page will not added to the admin menu.
86
- * @var bool
87
- */
88
- public $internal = false;
89
-
90
- /**
91
- * If true, the page will not be cretaed.
92
- *
93
- * @since 3.0.6
94
- * @var bool
95
- */
96
- public $hidden = false;
97
-
98
- /**
99
- * Link title for plugin action menu
100
- *
101
- * @var string/null
102
- */
103
- public $title_plugin_action_link = null;
104
-
105
- /**
106
- * If true, add settings link in plugins list
107
- * https://codex.wordpress.org/Plugin_API/Filter_Reference/plugin_action_links_(plugin_file_name)
108
- * @var bool
109
- */
110
- public $add_link_to_plugin_actions = false;
111
-
112
- public function __construct(Wbcr_Factory400_Plugin $plugin)
113
- {
114
- parent::__construct($plugin);
115
- $this->configure();
116
-
117
- $this->id = empty($this->id)
118
- ? str_replace('adminpage', '', strtolower(get_class($this)))
119
- : $this->id;
120
-
121
- if( $this->add_link_to_plugin_actions ) {
122
- $plugin_path_info = $this->plugin->getPluginPathInfo();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
123
  // plugin settings link
124
- add_filter("plugin_action_links_" . $plugin_path_info->relative_path, array(
125
  $this,
126
  'addLinkToPluginActions'
127
- ));
 
 
 
 
 
 
128
  }
129
  }
130
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
131
  /**
132
- * May be used to configure the page before uts usage.
133
  */
134
- public function configure()
135
- {
136
- }
137
-
 
 
 
 
 
 
138
  /**
139
- * Includes the Factory Bootstrap assets for a current page.
140
- *
141
- * @param string $hook
142
- * @return void
143
  */
144
- public function actionAdminBootstrapScripts($hook)
145
- {
146
- $this->scripts->connect('bootstrap');
147
- $this->styles->connect('bootstrap');
 
 
 
 
 
 
 
 
 
148
  }
149
-
150
- /**
151
- * Includes the assets for a current page (all assets except Factory Bootstrap assets).
152
- *
153
- * @param string $hook
154
- * @return void
155
- */
156
- public function actionAdminScripts($hook)
157
- {
158
- $this->scripts->connect();
159
- $this->styles->connect();
 
 
 
160
  }
161
-
162
- /**
163
- * @param null $id
164
- * @return mixed|string
165
- */
166
- public function getResultId($id = null)
167
- {
168
- $id = !empty($id)
169
- ? $id
170
- : $this->id;
171
-
172
- if( $this->plugin ) {
173
- return $id . '-' . $this->plugin->getPluginName();
174
- }
175
-
176
- return $id;
177
  }
178
-
179
- /**
180
- * Registers admin page for the admin menu.
181
- */
182
- public function connect()
183
- {
184
- $result_id = $this->getResultId();
185
-
186
- $this->hidden = apply_filters('wbcr_factory_400_page_is_hidden_' . $result_id, $this->hidden);
187
-
188
- if( $this->hidden ) {
189
- return;
190
- }
191
-
192
- $this->internal = apply_filters('wbcr_factory_400_page_is_internal_' . $result_id, $this->internal);
193
 
194
- if( $this->internal ) {
195
- $this->menu_target = null;
196
- $this->menu_post_type = null;
197
- }
198
-
199
- // makes redirect to the page
200
- $controller = $this->request->get('fy_page', null, true);
201
-
202
- if( $controller && $controller == $this->id ) {
203
- $plugin = $this->request->get('fy_plugin', null, true);
204
-
205
- if( $this->plugin->getPluginName() == $plugin ) {
206
-
207
- $action = $this->request->get('fy_action', 'index', true);
208
- $is_ajax = $this->request->get('fy_ajax', false);
209
-
210
- if( $is_ajax ) {
211
- $this->executeByName($action);
212
- exit;
213
- } else {
214
-
215
- $params = (array)$this->request->getAll(true);
216
-
217
- unset($params['fy_page']);
218
- unset($params['fy_plugin']);
219
- unset($params['fy_action']);
220
-
221
- $this->redirectToAction($action, $params);
222
- }
223
  }
224
  }
 
225
 
226
- // calls scripts and styles, adds pages to menu
227
- if( $this->request->get('page', 'none') == $result_id ) {
228
- $this->assets($this->scripts, $this->styles);
229
-
230
- if( !$this->scripts->isEmpty('bootstrap') || !$this->styles->isEmpty('bootstrap') ) {
231
- add_action('wbcr_factory_400_bootstrap_enqueue_scripts_' . $this->plugin->getPluginName(), array(
232
- $this,
233
- 'actionAdminBootstrapScripts'
234
- ));
235
- }
236
-
237
- // includes styles and scripts
238
- if( !$this->scripts->isEmpty() || !$this->styles->isEmpty() ) {
239
- add_action('admin_enqueue_scripts', array($this, 'actionAdminScripts'));
240
- }
241
  }
242
-
243
- // if this page for a custom menu page
244
- if( $this->menu_post_type ) {
245
- $this->menu_target = 'edit.php?post_type=' . $this->menu_post_type;
246
 
247
- if( empty($this->capabilitiy) ) {
248
- $this->capabilitiy = 'edit_' . $this->menu_post_type;
249
- }
250
  }
251
-
252
- // sets default capabilities
253
- if( empty($this->capabilitiy) ) {
254
- $this->capabilitiy = 'manage_options';
 
 
 
 
255
  }
256
-
257
- $this->page_title = !$this->page_title
258
- ? $this->menu_title
259
- : $this->page_title;
260
-
261
- $this->menu_title = !$this->menu_title
262
- ? $this->page_title
263
- : $this->menu_title;
264
-
265
- $this->page_title = apply_filters('wbcr_factory_page_title_' . $result_id, $this->page_title);
266
- $this->menu_title = apply_filters('wbcr_factory_menu_title_' . $result_id, $this->menu_title);
267
-
268
- // submenu
269
- if( $this->menu_target ) {
270
-
271
- add_submenu_page($this->menu_target, $this->page_title, $this->menu_title, $this->capabilitiy, $result_id, array(
272
- $this,
273
- 'show'
274
- ));
275
- // global menu
276
- } else {
277
-
278
- add_menu_page($this->page_title, $this->menu_title, $this->capabilitiy, $result_id, array(
279
  $this,
280
  'show'
281
- ), null, $this->menu_position);
282
-
283
- if( !empty($this->menu_sub_title) ) {
284
-
285
- add_submenu_page($result_id, $this->menu_sub_title, $this->menu_sub_title, $this->capabilitiy, $result_id, array(
286
- $this,
287
- 'show'
288
- ));
289
- }
290
-
291
- add_action('admin_head', array($this, 'actionAdminHead'));
292
  }
293
 
294
- // executes an action
295
- if( $this->current() ) {
296
- ob_start();
297
- $action = $this->request->get('action', 'index', true);
298
- $this->executeByName($action);
299
- $this->result = ob_get_contents();
300
- ob_end_clean();
301
- }
302
  }
303
-
304
- protected function current()
305
- {
306
- $result_id = $this->getResultId();
307
-
308
- if( $result_id == $this->request->get('page', 'none') ) {
309
- return true;
310
- }
311
-
312
- return false;
313
  }
314
-
315
- /**
316
- * @param string $action
317
- * @param array $query_args
318
- */
319
- public function redirectToAction($action, $query_args = array())
320
- {
321
-
322
- wp_safe_redirect($this->getActionUrl($action, $query_args));
323
- exit;
324
  }
325
-
326
- /**
327
- * @param string $action
328
- * @param array $query_args
329
- */
330
- public function actionUrl($action = null, $query_args = array())
331
- {
332
- echo $this->getActionUrl($action, $query_args);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
333
  }
334
-
335
- /**
336
- * @param null $action
337
- * @param array $query_args
338
- * @return string
339
- */
340
- public function getActionUrl($action = null, $query_args = array())
341
- {
342
- $baseUrl = $this->getBaseUrl();
343
-
344
- if( !empty($action) ) {
345
- $query_args['action'] = $action;
346
- }
347
- $url = add_query_arg($query_args, $baseUrl);
348
-
349
- return $url;
 
 
350
  }
351
-
352
- /**
353
- * @return string
354
- */
355
- protected function getBaseUrl()
356
- {
357
- $result_id = $this->getResultId();
358
-
359
- if( $this->menu_target ) {
360
- if( $this->custom_target ) {
361
- return admin_url('admin.php') . '?page=' . $result_id;
362
- }
363
-
364
- return $this->menu_target . '&page=' . $result_id;
365
  } else {
366
- return 'admin.php?&page=' . $result_id;
 
367
  }
368
  }
369
-
370
- public function actionAdminHead()
371
- {
372
- $result_id = $this->getResultId();
373
-
374
- if( !empty($this->menu_icon) ) {
375
-
376
- if( preg_match('/\\\f\d{3}/', $this->menu_icon) ) {
377
- $icon_code = $this->menu_icon;
378
- } else {
379
- $plugin_path_info = $this->plugin->getPluginPathInfo();
380
- $icon_url = str_replace('~/', $plugin_path_info->plugin_url . '/', $this->menu_icon);
381
- }
382
- }
383
-
384
- global $wp_version;
385
-
386
- if( version_compare($wp_version, '3.7.3', '>') ) {
387
- ?>
388
- <style type="text/css" media="screen">
389
- <?php i
1
  <?php
2
+ /**
3
+ * Admin page class
4
+ *
5
+ * @author Alex Kovalev <alex.kovalevv@gmail.com>
6
+ * @since 1.0.0
7
+ * @package factory-core
8
+ * @copyright (c) 2018, Webcraftic Ltd
9
+ *
10
+ */
11
+
12
+ // Exit if accessed directly
13
+ if ( ! defined( 'ABSPATH' ) ) {
14
+ exit;
15
+ }
16
+
17
+ if ( ! class_exists( 'Wbcr_FactoryPages420_AdminPage' ) ) {
18
+
19
+ class Wbcr_FactoryPages420_AdminPage extends Wbcr_FactoryPages420_Page {
20
+
21
+ /**
22
+ * Visible page title.
23
+ * For example: 'License Manager'
24
+ *
25
+ * @var string
26
+ */
27
+ public $page_title;
28
+
29
+ /**
30
+ * Visible title in menu.
31
+ * For example: 'License Manager'
32
+ *
33
+ * @var string
34
+ */
35
+ public $menu_title = null;
36
+
37
+ /**
38
+ * If set, an extra sub menu will be created with another title.
39
+ *
40
+ * @var string
41
+ */
42
+ public $menu_sub_title = null;
43
+
44
+ /**
45
+ * Иконка меню в главном меню админ панели
46
+ *
47
+ * Используется только в том случае, если ссылка на страницу отображается
48
+ * в главном меню админ панели (левый сайдбар) и не является элементом подменю.
49
+ *
50
+ * Пример: '~/assets/img/menu-icon.png', ~/ будет заменен ссылкой на корневую
51
+ * директорию плагина.
52
+ * Можно использовать dashicons: '\f321'
53
+ *
54
+ * @var string
55
+ */
56
+ public $menu_icon = null;
57
+
58
+ /**
59
+ * Позиция в главном меню админ панели
60
+ *
61
+ * Если эта страница была добавлена в главное меню админ панели (левый сайдбар).
62
+ * Вы можете установить позицию меню. Подробнее смотрите в Wordpress кодексе.
63
+ *
64
+ * @link http://codex.wordpress.org/Function_Reference/add_menu_page
65
+ *
66
+ * Позиция может быть установлена от 0 до 100 и чем больше цифра, тем ниже будет
67
+ * расположен пункт меню.
68
+ *
69
+ * Внимание! Если два пункта используют одинаковую цифру-позицию, один из пунктов
70
+ * меню может быть перезаписан и будет показан только один пункт из двух.
71
+ * Чтобы избежать конфликта, можно использовать десятичные значения, вместо целых
72
+ * чисел: 63.3 вместо 63. Используйте кавычки: "63.3".
73
+ *
74
+ * 2 Консоль
75
+ * 4 Разделитель
76
+ * 5 Посты
77
+ * 10 Медиа
78
+ * 15 Ссылки
79
+ * 20 Страницы
80
+ * 25 Комментарии
81
+ * 59 Разделитель
82
+ * 60 Внешний вид
83
+ * 65 Плагины
84
+ * 70 Пользователи
85
+ * 75 Инструменты
86
+ * 80 Настройки
87
+ * 99 Разделитель
88
+ *
89
+ * @var string
90
+ */
91
+ public $menu_position = null;
92
+
93
+ /**
94
+ * Тип записи к меню которой, нужно прикрепить ссылку на страницу
95
+ *
96
+ * К примеру, если вы установите тип записи "post". В меню "Записи" появится
97
+ * ссылка на эту страницу, как элемент подменю.
98
+ *
99
+ * Пример: 'post'
100
+ *
101
+ * @var string
102
+ */
103
+ public $menu_post_type = null;
104
+
105
+ /**
106
+ * Название (slug) элемента главного родительского меню в админ панели, в которое будет
107
+ * добавлен пункт меню этой страницы, как элемент подменю.
108
+ *
109
+ * Примеры:
110
+ * index.php - Консоль (Dashboard). Или спец. функция: add_dashboard_page();
111
+ * edit.php - Посты (Posts). Или спец. функция: add_posts_page();
112
+ * upload.php - Медиафайлы (Media). Или спец. функция: add_media_page();
113
+ * link-manager.php - Ссылки (Links). Или спец. функция: add_links_page();
114
+ * edit.php?post_type=page - Страницы (Pages). Или спец. функция: add_pages_page();
115
+ * edit-comments.php - Комментарии (Comments). Или спец. функция: add_comments_page();
116
+ * edit.php?post_type=your_post_type - Произвольные типы записей.
117
+ * themes.php - Внешний вид (Appearance). Или спец. функция: add_theme_page();
118
+ * plugins.php - Плагины (Plugins). Или спец. функция: add_plugins_page();
119
+ * users.php - Пользователи (Users). Или спец. функция: add_users_page();
120
+ * tools.php - Инструменты (Tools). Или спец. функция: add_management_page();
121
+ * options-general.php - Настройки (Settings). Или спец. функция: add_options_page()
122
+ * settings.php - Настройки (Settings) сети сайтов в MU режиме.
123
+ *
124
+ * @var string
125
+ */
126
+ public $menu_target = null;
127
+
128
+ /**
129
+ * if true, then admin.php is used as a base url.
130
+ *
131
+ * @var bool
132
+ */
133
+ public $custom_target = false;
134
+
135
+ /**
136
+ * Разрешения пользователя, чтобы иметь доступ к странице.
137
+ *
138
+ * Этот параметр отвечает и за доступ к странице этого пункта меню. Подробнее
139
+ * смотрите в кодексе Wordpress:
140
+ *
141
+ * @link http://codex.wordpress.org/Roles_and_Capabilities
142
+ *
143
+ * Указывать массив разрешений, например:
144
+ * ['manage_options', 'manage_network']
145
+ *
146
+ * @var array
147
+ */
148
+ public $capabilitiy = null;
149
+
150
+ /**
151
+ * Скрыть страницу из главного меню админ панели?
152
+ *
153
+ * Если true, то закладка на эту страницу не будет добавлена в главное меню
154
+ * админ панели.
155
+ *
156
+ * @var bool
157
+ */
158
+ public $internal = false;
159
+
160
+ /**
161
+ * If true, the page is for network
162
+ *
163
+ * @var bool
164
+ */
165
+ public $network = false;
166
+
167
+ /**
168
+ * Предотвратить создание страницы?
169
+ *
170
+ * Если true, то страница не будет создана. Может пригодиться в тех случаях,
171
+ * когда страница должна быть создана только при выполнении условий.
172
+ *
173
+ * @since 3.0.6
174
+ * @var bool
175
+ */
176
+ public $hidden = false;
177
+
178
+ /**
179
+ * Сделать доступной страницу в панели управлениям сайтами (панель суперадминистратора)
180
+ *
181
+ * Если установлено true, в панели управления сайтами появится закладка на эту страницу.
182
+ * Также эта страница получить разрешения на просмотр для группы суперадминистраторов.
183
+ *
184
+ * @var bool
185
+ */
186
+ public $available_for_multisite = false;
187
+
188
+ /**
189
+ * Задать текст ссылки на странице плагинов (рядом с активировать/деактивировать)
190
+ *
191
+ * Будет работать только, свойство $add_link_to_plugin_actions=true.
192
+ * По умолчанию, если текст ссылки не задан, используется заголовок элемента меню
193
+ * или заголовок страницы.
194
+ *
195
+ * @var string
196
+ */
197
+ public $title_plugin_action_link;
198
+
199
+ /**
200
+ * Добавлять ссылку на странице плагинов (рядом с активировать/деактивировать)?
201
+ *
202
+ * Если true, будет автоматически добавлена ссылка на эту страницу, внутри страницы
203
+ * wp-admin/plugins.php (рядом с активировать/деактивировать). Чаще всего требуется
204
+ * добавить ссылку на страницу настроек. Если эта страница у вас является главной,
205
+ * то вы можете сделать это свойство активным.
206
+ *
207
+ * @link https://codex.wordpress.org/Plugin_API/Filter_Reference/plugin_action_links_(plugin_file_name)
208
+ * @var bool
209
+ */
210
+ public $add_link_to_plugin_actions = false;
211
+
212
+ public function __construct( Wbcr_Factory420_Plugin $plugin ) {
213
+ parent::__construct( $plugin );
214
+ $this->configure();
215
+
216
+ $this->id = empty( $this->id ) ? str_replace( 'adminpage', '', strtolower( get_class( $this ) ) ) : $this->id;
217
+
218
+ if ( $this->add_link_to_plugin_actions ) {
219
+ if ( $plugin->isNetworkActive() ) {
220
  // plugin settings link
221
+ add_filter( "network_admin_plugin_action_links_" . $this->plugin->get_paths()->basename, [
222
  $this,
223
  'addLinkToPluginActions'
224
+ ] );
225
+ } else {
226
+ // plugin settings link
227
+ add_filter( "plugin_action_links_" . $this->plugin->get_paths()->basename, [
228
+ $this,
229
+ 'addLinkToPluginActions'
230
+ ] );
231
  }
232
  }
233
+ }
234
+
235
+ /**
236
+ * May be used to configure the page before uts usage.
237
+ */
238
+ public function configure() {
239
+ }
240
+
241
+ /**
242
+ * Includes the Factory Bootstrap assets for a current page.
243
+ *
244
+ * @param string $hook
245
+ *
246
+ * @return void
247
+ */
248
+ public function actionAdminBootstrapScripts( $hook ) {
249
+ $this->scripts->connect( 'bootstrap' );
250
+ $this->styles->connect( 'bootstrap' );
251
+ }
252
+
253
+ /**
254
+ * Includes the assets for a current page (all assets except Factory Bootstrap assets).
255
+ *
256
+ * @param string $hook
257
+ *
258
+ * @return void
259
+ */
260
+ public function actionAdminScripts( $hook ) {
261
+ $this->scripts->connect();
262
+ $this->styles->connect();
263
+ }
264
+
265
+ /**
266
+ * @return string
267
+ */
268
+ public function getMenuScope() {
269
+ return $this->plugin->getPluginName();
270
+ }
271
+
272
+
273
+ /**
274
+ * @return string
275
+ */
276
+ public function getMenuTitle() {
277
+ $menu_title = ! $this->menu_title ? $this->page_title : $this->menu_title;
278
+
279
  /**
280
+ * @since 4.0.9 - добавлен
281
  */
282
+ return apply_filters( 'wbcr/factory/pages/impressive/menu_title', $menu_title, $this->plugin->getPluginName(), $this->id );
283
+ }
284
+
285
+ /**
286
+ * @return string
287
+ */
288
+ public function getPageTitle() {
289
+
290
+ $page_title = ! $this->page_title ? $this->getMenuTitle() : $this->page_title;
291
+
292
  /**
293
+ * @since 4.0.9 - добавлен
 
 
 
294
  */
295
+ return apply_filters( 'wbcr/factory/pages/impressive/page_title', $page_title, $this->plugin->getPluginName(), $this->id );
296
+ }
297
+
298
+ /**
299
+ * @param null $id
300
+ *
301
+ * @return mixed|string
302
+ */
303
+ public function getResultId( $id = null ) {
304
+ $id = ! empty( $id ) ? $id : $this->id;
305
+
306
+ if ( $this->plugin ) {
307
+ return $id . '-' . $this->getMenuScope();
308
  }
309
+
310
+ return $id;
311
+ }
312
+
313
+ /**
314
+ * Registers admin page for the admin menu.
315
+ */
316
+ public function connect() {
317
+ $result_id = $this->getResultId();
318
+
319
+ $this->hidden = apply_filters( 'wbcr_factory_420_page_is_hidden_' . $result_id, $this->hidden );
320
+
321
+ if ( $this->hidden ) {
322
+ return;
323
  }
324
+
325
+ $this->internal = apply_filters( 'wbcr_factory_420_page_is_internal_' . $result_id, $this->internal );
326
+
327
+ if ( $this->internal ) {
328
+ $this->menu_target = null;
329
+ $this->menu_post_type = null;
 
 
 
 
 
 
 
 
 
 
330
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
331
 
332
+ // makes redirect to the page
333
+ $controller = $this->request->get( 'fy_page', null, true );
334
+
335
+ if ( $controller && $controller == $this->id ) {
336
+ $plugin = $this->request->get( 'fy_plugin', null, true );
337
+
338
+ if ( $this->plugin->getPluginName() == $plugin ) {
339
+
340
+ $action = $this->request->get( 'fy_action', 'index', true );
341
+ $is_ajax = $this->request->get( 'fy_ajax', false );
342
+
343
+ if ( $is_ajax ) {
344
+ $this->executeByName( $action );
345
+ exit;
346
+ } else {
347
+
348
+ $params = (array) $this->request->getAll( true );
349
+
350
+ unset( $params['fy_page'] );
351
+ unset( $params['fy_plugin'] );
352
+ unset( $params['fy_action'] );
353
+
354
+ $this->redirectToAction( $action, $params );
 
 
 
 
 
 
355
  }
356
  }
357
+ }
358
 
359
+ // calls scripts and styles, adds pages to menu
360
+ if ( $this->request->get( 'page', 'none' ) == $result_id ) {
361
+ $this->assets( $this->scripts, $this->styles );
362
+
363
+ if ( ! $this->scripts->isEmpty( 'bootstrap' ) || ! $this->styles->isEmpty( 'bootstrap' ) ) {
364
+ add_action( 'wbcr_factory_420_bootstrap_enqueue_scripts_' . $this->plugin->getPluginName(), [
365
+ $this,
366
+ 'actionAdminBootstrapScripts'
367
+ ] );
 
 
 
 
 
 
368
  }
 
 
 
 
369
 
370
+ // includes styles and scripts
371
+ if ( ! $this->scripts->isEmpty() || ! $this->styles->isEmpty() ) {
372
+ add_action( 'admin_enqueue_scripts', [ $this, 'actionAdminScripts' ] );
373
  }
374
+ }
375
+
376
+ // if this page for a custom menu page
377
+ if ( $this->menu_post_type ) {
378
+ $this->menu_target = 'edit.php?post_type=' . $this->menu_post_type;
379
+
380
+ if ( empty( $this->capabilitiy ) ) {
381
+ $this->capabilitiy = 'edit_' . $this->menu_post_type;
382
  }
383
+ }
384
+
385
+ // sets default capabilities
386
+ if ( empty( $this->capabilitiy ) ) {
387
+ $this->capabilitiy = 'manage_options';
388
+ }
389
+
390
+ // submenu
391
+ if ( $this->menu_target ) {
392
+ add_submenu_page( $this->menu_target, $this->getPageTitle(), $this->getMenuTitle(), $this->capabilitiy, $result_id, [
393
+ $this,
394
+ 'show'
395
+ ] );
396
+ // global menu
397
+ } else {
398
+ add_menu_page( $this->getPageTitle(), $this->getMenuTitle(), $this->capabilitiy, $result_id, [
399
+ $this,
400
+ 'show'
401
+ ], null, $this->menu_position );
402
+
403
+ if ( ! empty( $this->menu_sub_title ) ) {
404
+
405
+ add_submenu_page( $result_id, $this->menu_sub_title, $this->menu_sub_title, $this->capabilitiy, $result_id, [
406
  $this,
407
  'show'
408
+ ] );
 
 
 
 
 
 
 
 
 
 
409
  }
410
 
411
+ add_action( 'admin_head', [ $this, 'actionAdminHead' ] );
 
 
 
 
 
 
 
412
  }
413
+
414
+ // executes an action
415
+ if ( $this->current() ) {
416
+ ob_start();
417
+ $action = $this->request->get( 'action', 'index', true );
418
+ $this->executeByName( $action );
419
+ $this->result = ob_get_contents();
420
+ ob_end_clean();
 
 
421
  }
422
+ }
423
+
424
+ protected function current() {
425
+ $result_id = $this->getResultId();
426
+
427
+ if ( $result_id == $this->request->get( 'page', 'none' ) ) {
428
+ return true;
 
 
 
429
  }
430
+
431
+ return false;
432
+ }
433
+
434
+ /**
435
+ * @param string $action
436
+ * @param array $query_args
437
+ */
438
+ public function redirectToAction( $action, $query_args = [] ) {
439
+
440
+ wp_safe_redirect( $this->getActionUrl( $action, $query_args ) );
441
+ exit;
442
+ }
443
+
444
+ /**
445
+ * @param string $action
446
+ * @param array $query_args
447
+ */
448
+ public function actionUrl( $action = null, $query_args = [] ) {
449
+ echo $this->getActionUrl( $action, $query_args );
450
+ }
451
+
452
+ /**
453
+ * @param null $action
454
+ * @param array $query_args
455
+ *
456
+ * @return string
457
+ */
458
+ public function getActionUrl( $action = null, $query_args = [] ) {
459
+ $url = $this->getBaseUrl( null, $query_args );
460
+
461
+ if ( ! empty( $action ) ) {
462
+ $url = add_query_arg( 'action', $action, $url );
463
  }
464
+
465
+ return $url;
466
+ }
467
+
468
+ /**
469
+ * @return string
470
+ */
471
+ public function getBaseUrl( $id = null, $query_args = [] ) {
472
+ $result_id = $this->getResultId( $id );
473
+
474
+ if ( $this->menu_target ) {
475
+ $url = $this->network ? network_admin_url( $this->menu_target ) : admin_url( $this->menu_target );
476
+
477
+ return add_query_arg( array_merge( [ 'page' => $result_id ], $query_args ), $url );
478
+ } else {
479
+ $url = $this->network ? network_admin_url( 'admin.php' ) : admin_url( 'admin.php' );
480
+
481
+ return add_query_arg( array_merge( [ 'page' => $result_id, $query_args ] ), $url );
482
  }
483
+ }
484
+
485
+ public function actionAdminHead() {
486
+ $result_id = $this->getResultId();
487
+
488
+ if ( ! empty( $this->menu_icon ) ) {
489
+
490
+ if ( preg_match( '/\\\f\d{3}/', $this->menu_icon ) ) {
491
+ $icon_code = $this->menu_icon;
 
 
 
 
 
492
  } else {
493
+ $plugin_path_info = $this->plugin->getPluginPathInfo();
494
+ $icon_url = str_replace( '~/', $plugin_path_info->plugin_url . '/', $this->menu_icon );
495
  }
496
  }