Elementor Addons & Templates – Sizzify Lite - Version 1.3.0

Version Description

  • 2019-03-08
Download this release

Release Info

Developer themeisle
Plugin Icon wp plugin Elementor Addons & Templates – Sizzify Lite
Version 1.3.0
Comparing to
See all releases

Code changes from version 1.2.9 to 1.3.0

Files changed (73) hide show
  1. CHANGELOG.md +5 -0
  2. admin/partials/main.php +19 -3
  3. admin/partials/upsell.php +0 -72
  4. assets/css/admin.css +7 -0
  5. eaw-class.php +54 -20
  6. elementor-addon-widgets.php +14 -2
  7. readme.md +7 -1
  8. readme.txt +7 -1
  9. themeisle-hash.json +1 -1
  10. vendor/autoload.php +1 -1
  11. vendor/codeinwp/elementor-extra-widgets/README.md +1 -0
  12. vendor/codeinwp/elementor-extra-widgets/phpunit.xml +14 -0
  13. vendor/codeinwp/elementor-extra-widgets/tests/bootstrap.php +50 -0
  14. vendor/codeinwp/elementor-extra-widgets/tests/test-basics.php +71 -0
  15. vendor/codeinwp/full-width-page-templates/README.md +119 -0
  16. vendor/codeinwp/full-width-page-templates/phpunit.xml +14 -0
  17. vendor/codeinwp/full-width-page-templates/tests/bootstrap.php +50 -0
  18. vendor/codeinwp/full-width-page-templates/tests/test-basics.php +35 -0
  19. vendor/codeinwp/templates-directory/README.md +1 -0
  20. vendor/codeinwp/themeisle-content-forms/assets/content-forms.css +9 -2
  21. vendor/codeinwp/themeisle-content-forms/assets/content-forms.js +1 -1
  22. vendor/codeinwp/themeisle-content-forms/assets/gutenberg-esnext/block.build.js +0 -376
  23. vendor/codeinwp/themeisle-content-forms/assets/gutenberg-esnext/block.js +0 -85
  24. vendor/codeinwp/themeisle-content-forms/assets/gutenberg-esnext/components/FormEditor.js +0 -148
  25. vendor/codeinwp/themeisle-content-forms/assets/gutenberg-esnext/index.php +0 -2
  26. vendor/codeinwp/themeisle-content-forms/assets/gutenberg-esnext/package-lock.json +0 -4080
  27. vendor/codeinwp/themeisle-content-forms/assets/gutenberg-esnext/package.json +0 -17
  28. vendor/codeinwp/themeisle-content-forms/assets/gutenberg-esnext/webpack.config.js +0 -62
  29. vendor/codeinwp/themeisle-content-forms/class-themeisle-content-forms-gutenberg.php +0 -286
  30. vendor/codeinwp/themeisle-content-forms/phpunit.xml +14 -0
  31. vendor/codeinwp/themeisle-content-forms/tests/bootstrap.php +50 -0
  32. vendor/codeinwp/themeisle-content-forms/tests/test-basics.php +86 -0
  33. vendor/codeinwp/themeisle-content-forms/tests/test-contact-form.php +113 -0
  34. vendor/codeinwp/themeisle-content-forms/tests/test-newsletter-form.php +73 -0
  35. vendor/codeinwp/themeisle-content-forms/tests/test-registration-form.php +139 -0
  36. vendor/codeinwp/themeisle-content-forms/tests/test-server.php +62 -0
  37. vendor/codeinwp/themeisle-sdk/CHANGELOG.md +42 -0
  38. vendor/codeinwp/themeisle-sdk/class-themeisle-sdk-endpoints.php +0 -312
  39. vendor/codeinwp/themeisle-sdk/class-themeisle-sdk-feedback-deactivate.php +0 -556
  40. vendor/codeinwp/themeisle-sdk/class-themeisle-sdk-feedback-factory.php +0 -50
  41. vendor/codeinwp/themeisle-sdk/class-themeisle-sdk-feedback-review.php +0 -209
  42. vendor/codeinwp/themeisle-sdk/class-themeisle-sdk-feedback-translate.php +0 -983
  43. vendor/codeinwp/themeisle-sdk/class-themeisle-sdk-feedback.php +0 -90
  44. vendor/codeinwp/themeisle-sdk/class-themeisle-sdk-licenser.php +0 -686
  45. vendor/codeinwp/themeisle-sdk/class-themeisle-sdk-loader.php +0 -96
  46. vendor/codeinwp/themeisle-sdk/class-themeisle-sdk-logger.php +0 -227
  47. vendor/codeinwp/themeisle-sdk/class-themeisle-sdk-notification-manager.php +0 -105
  48. vendor/codeinwp/themeisle-sdk/class-themeisle-sdk-product.php +0 -635
  49. vendor/codeinwp/themeisle-sdk/class-themeisle-sdk-rollback.php +0 -223
  50. vendor/codeinwp/themeisle-sdk/class-themeisle-sdk-widget-dashboard-blog.php +0 -412
  51. vendor/codeinwp/themeisle-sdk/class-themeisle-sdk-widget.php +0 -50
  52. vendor/codeinwp/themeisle-sdk/class-themeisle-sdk-widgets-factory.php +0 -37
  53. vendor/codeinwp/themeisle-sdk/composer.json +0 -24
  54. vendor/codeinwp/themeisle-sdk/index.php +2 -4
  55. vendor/codeinwp/themeisle-sdk/load.php +17 -3
  56. vendor/codeinwp/themeisle-sdk/src/Common/Abstract_module.php +66 -0
  57. vendor/codeinwp/themeisle-sdk/src/Common/Module_factory.php +108 -0
  58. vendor/codeinwp/themeisle-sdk/src/Loader.php +126 -0
  59. vendor/codeinwp/themeisle-sdk/src/Modules/Dashboard_widget.php +464 -0
  60. vendor/codeinwp/themeisle-sdk/src/Modules/Endpoint.php +358 -0
  61. vendor/codeinwp/themeisle-sdk/src/Modules/Licenser.php +719 -0
  62. vendor/codeinwp/themeisle-sdk/src/Modules/Logger.php +177 -0
  63. vendor/codeinwp/themeisle-sdk/src/Modules/Notification.php +456 -0
  64. vendor/codeinwp/themeisle-sdk/src/Modules/Recommendation.php +374 -0
  65. vendor/codeinwp/themeisle-sdk/src/Modules/Review.php +117 -0
  66. vendor/codeinwp/themeisle-sdk/src/Modules/Rollback.php +376 -0
  67. vendor/codeinwp/themeisle-sdk/src/Modules/Translate.php +918 -0
  68. vendor/codeinwp/themeisle-sdk/src/Modules/Uninstall_feedback.php +728 -0
  69. vendor/codeinwp/themeisle-sdk/src/Product.php +396 -0
  70. vendor/codeinwp/themeisle-sdk/start.php +32 -21
  71. vendor/composer/autoload_files.php +1 -1
  72. vendor/composer/autoload_real.php +5 -5
  73. vendor/composer/installed.json +46 -46
CHANGELOG.md CHANGED
@@ -1,4 +1,9 @@
1
 
 
 
 
 
 
2
  ### v1.2.9 - 2018-12-12
3
  **Changes:**
4
  * fix templates directory importing
1
 
2
+ ### v1.3.0 - 2019-03-08
3
+ **Changes:**
4
+ * Tested with latest WordPress version, 5.1
5
+ * Remove mention of Pro add-on, discontinue recommendation of the Premium features
6
+
7
  ### v1.2.9 - 2018-12-12
8
  **Changes:**
9
  * fix templates directory importing
admin/partials/main.php CHANGED
@@ -10,7 +10,6 @@
10
  href="https://themeisle.com/">ThemeIsle</a></span>
11
  </div><!-- .pro-features-header -->
12
 
13
-
14
  <div class="pro-features-content">
15
 
16
  <div class="pro-feature">
@@ -22,7 +21,7 @@
22
  </div>
23
  <div class="pro-feature-image">
24
  <img src="<?php echo esc_url( EA_URI . '/assets/img/templates.jpg' ); ?>"
25
- alt="Premium Templates"></div>
26
  </div>
27
 
28
  <?php
@@ -40,5 +39,22 @@
40
  }
41
  ?>
42
 
43
-
44
  </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
10
  href="https://themeisle.com/">ThemeIsle</a></span>
11
  </div><!-- .pro-features-header -->
12
 
 
13
  <div class="pro-features-content">
14
 
15
  <div class="pro-feature">
21
  </div>
22
  <div class="pro-feature-image">
23
  <img src="<?php echo esc_url( EA_URI . '/assets/img/templates.jpg' ); ?>"
24
+ alt="Premium Templates"></div>
25
  </div>
26
 
27
  <?php
39
  }
40
  ?>
41
 
 
42
  </div>
43
+ <div class="clear"></div>
44
+ <h3><span class="dashicons dashicons-welcome-learn-more"></span> Sizzify Recommends</h3>
45
+ <footer id="siz-setting-footer">
46
+ <?php
47
+
48
+ do_action(
49
+ EA_PLUGIN_NAME . '_recommend_products',
50
+ array(
51
+ 'otter-blocks' => 'Otter',
52
+ 'optimole-wp' => 'OptiMole',
53
+ 'visualizer' => 'Visualizer',
54
+ ),
55
+ [],
56
+ array( 'install' => __( 'More details', 'elementor-addon-widgets' ) ),
57
+ array( 'image' => 'icon' )
58
+ );
59
+ ?>
60
+ </footer>
admin/partials/upsell.php DELETED
@@ -1,72 +0,0 @@
1
- <?php
2
- /**
3
- * The upsell page template partial.
4
- */
5
- ?>
6
- <div id="sizzify-page-wrapper">
7
- <div class="pro-features-header">
8
- <p class="logo">Sizzify - Elementor Addons & Templates</p>
9
- <span class="slogan">by <a
10
- href="https://themeisle.com/">ThemeIsle</a></span>
11
- <div class="header-btns">
12
- <a target="_blank" href="<?php echo SIZZIFY_UPSELL_LINK; ?>" class="buy-now">
13
- <span class="dashicons dashicons-cart"></span> View features</a>
14
- </div>
15
- </div><!-- .pro-features-header -->
16
-
17
-
18
- <div class="pro-features-content">
19
-
20
- <div class="pro-feature">
21
- <div class="pro-feature-features">
22
- <h2>Premium Page Templates</h2>
23
- <p>One-click import beautifully designed premium Elementor templates.</p>
24
- </div>
25
- <div class="pro-feature-image">
26
- <img src="<?php echo esc_url( EA_URI . '/assets/img/templates.jpg' ); ?>"
27
- alt="Premium Templates"></div>
28
- </div>
29
-
30
- <div class="pro-feature">
31
- <div class="pro-feature-features">
32
- <h2>Flip Card Elementor Widget</h2>
33
- <p>This awesome widget can flip your information around.</p>
34
- </div>
35
- <div class="pro-feature-image">
36
- <img src="<?php echo esc_url( EA_URI . '/assets/img/flipcard.jpg' ); ?>"
37
- alt="Premium Templates"></div>
38
- </div>
39
-
40
- <div class="pro-feature">
41
- <div class="pro-feature-features">
42
- <h2>Review Box Elementor Widget</h2>
43
- <p>Display product reviews on your website. With rating and everything.</p>
44
- </div>
45
- <div class="pro-feature-image">
46
- <img src="<?php echo esc_url( EA_URI . '/assets/img/reviewbox.jpg' ); ?>"
47
- alt="Premium Templates"></div>
48
- </div>
49
-
50
- <div class="pro-feature">
51
- <div class="pro-feature-features">
52
- <h2>Typed Heading Elementor Widget</h2>
53
- <p>Display dynamic text on your pages with this nifty widget.</p>
54
- </div>
55
- <div class="pro-feature-image">
56
- <img src="<?php echo esc_url( EA_URI . '/assets/img/typed.jpg' ); ?>"
57
- alt="Premium Templates"></div>
58
- </div>
59
-
60
- <div class="pro-feature">
61
- <div class="pro-feature-features">
62
- <h2>Social Sharing Elementor Widget</h2>
63
- <p>Share all your content over multiple social networks.</p>
64
- </div>
65
- <div class="pro-feature-image">
66
- <img src="<?php echo esc_url( EA_URI . '/assets/img/socialsharing.jpg' ); ?>"
67
- alt="Premium Templates"></div>
68
- </div>
69
-
70
- </div><!-- .pro-features-content -->
71
-
72
- </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
assets/css/admin.css CHANGED
@@ -259,3 +259,10 @@
259
  text-align: center;
260
  }
261
  }
 
 
 
 
 
 
 
259
  text-align: center;
260
  }
261
  }
262
+ #siz-setting-footer{
263
+ margin-top:10px;
264
+ }
265
+ #siz-setting-footer .plugin_box{
266
+ width:32%;
267
+
268
+ }
eaw-class.php CHANGED
@@ -29,8 +29,11 @@ class Elementor_Addon_Widgets {
29
  add_filter( 'elementor_extra_widgets_category_args', array( $this, 'filter_category_args' ) );
30
  add_filter( 'content_forms_category_args', array( $this, 'filter_category_args' ) );
31
 
32
- add_filter( 'template_directory_templates_list', array( $this, 'filter_templates_preview' ) );
33
- add_filter( 'eaw_should_load_placeholders', '__return_true' );
 
 
 
34
 
35
  add_filter( 'obfx_template_dir_products', array( $this, 'add_page' ) );
36
  add_filter( 'obfx_template_dir_page_title', array( $this, 'page_title' ) );
@@ -39,6 +42,13 @@ class Elementor_Addon_Widgets {
39
  $this->load_composer_library();
40
  }
41
 
 
 
 
 
 
 
 
42
  /**
43
  * Load the Composer library with the base feature
44
  */
@@ -98,6 +108,48 @@ class Elementor_Addon_Widgets {
98
  </div>';
99
  }
100
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
101
  public function eaw_update_dismissed() {
102
  global $current_user;
103
  $user_id = $current_user->ID;
@@ -148,30 +200,12 @@ class Elementor_Addon_Widgets {
148
  '76'
149
  );
150
  remove_submenu_page( 'sizzify-admin', 'sizzify-admin' );
151
- if ( ! defined( 'EAW_PRO_URL' ) ) {
152
- add_submenu_page(
153
- 'sizzify-admin',
154
- __( 'Sizzify', 'elementor-addon-widgets' ),
155
- __( 'More Features', 'elementor-addon-widgets' ) . '<span class="dashicons
156
- dashicons-star-filled more-features-icon" style="width: 17px;height: 17px; margin-left: 4px; color: #ffca54;font-size: 17px;vertical-align: -3px;"></span>',
157
- 'manage_options',
158
- 'sizzify_more_features',
159
- array(
160
- $this,
161
- 'render_upsell',
162
- )
163
- );
164
- }
165
  }
166
 
167
  public function render_main_page() {
168
  include_once EA_PATH . 'admin/partials/main.php';
169
  }
170
 
171
- public function render_upsell() {
172
- include_once EA_PATH . 'admin/partials/upsell.php';
173
- }
174
-
175
  /**
176
  * Adjust the modules category name
177
  *
29
  add_filter( 'elementor_extra_widgets_category_args', array( $this, 'filter_category_args' ) );
30
  add_filter( 'content_forms_category_args', array( $this, 'filter_category_args' ) );
31
 
32
+ if ( defined( 'EAW_PRO_VERSION' ) ) {
33
+ add_filter( 'template_directory_templates_list', array( $this, 'filter_templates_preview' ) );
34
+ }
35
+
36
+ add_filter( 'eaw_should_load_placeholders', array( $this, 'show_placeholder_widgets' ) );
37
 
38
  add_filter( 'obfx_template_dir_products', array( $this, 'add_page' ) );
39
  add_filter( 'obfx_template_dir_page_title', array( $this, 'page_title' ) );
42
  $this->load_composer_library();
43
  }
44
 
45
+ /**
46
+ * Should we show the placeholder widget? Only when PRO exists!
47
+ */
48
+ function show_placeholder_widgets() {
49
+ return defined( 'EAW_PRO_VERSION' );
50
+ }
51
+
52
  /**
53
  * Load the Composer library with the base feature
54
  */
108
  </div>';
109
  }
110
 
111
+
112
+ /**
113
+ * Shows upsell plugin box.
114
+ */
115
+ public function show_upsell_plugins( $list, $strings, $preferences ) {
116
+
117
+ foreach ( $list as $item ) {
118
+ echo '<div class="pro-feature theme-promote">
119
+ <div class="pro-feature-features">
120
+ <h2>' . $item->custom_name . '</h2>
121
+ <p>' . esc_html( $item->short_description ) . '</p>
122
+ <a class="thickbox open-plugin-details-modal install-now" href="' . esc_url( $item->custom_url ) . '"><span class="dashicons dashicons-admin-appearance"></span>' . esc_html( $strings['install'] ) . '</a>
123
+ </div>
124
+ <div class="pro-feature-image">
125
+ <img src="' . $item->custom_image . '">
126
+ </div>
127
+ </div>';
128
+ }
129
+ }
130
+
131
+ /**
132
+ * Shows upsell theme box.
133
+ */
134
+ public function show_upsell_themes( $list, $strings, $preferences ) {
135
+ // for some reason the array becomes an object, so we have to force it back into an array.
136
+ if ( ! is_array( $list ) ) {
137
+ $list = array( $list );
138
+ }
139
+ foreach ( $list as $item ) {
140
+ echo '<div class="pro-feature theme-promote">
141
+ <div class="pro-feature-features">
142
+ <h2>' . $item->custom_name . '</h2>
143
+ <p>' . esc_html( $item->description ) . '</p>
144
+ <a class="thickbox open-plugin-details-modal install-now" href="' . esc_url( $item->custom_url ) . '"><span class="dashicons dashicons-admin-appearance"></span>' . esc_html( $strings['install'] ) . '</a>
145
+ </div>
146
+ <div class="pro-feature-image">
147
+ <img src="' . $item->screenshot_url . '">
148
+ </div>
149
+ </div>';
150
+ }
151
+ }
152
+
153
  public function eaw_update_dismissed() {
154
  global $current_user;
155
  $user_id = $current_user->ID;
200
  '76'
201
  );
202
  remove_submenu_page( 'sizzify-admin', 'sizzify-admin' );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
203
  }
204
 
205
  public function render_main_page() {
206
  include_once EA_PATH . 'admin/partials/main.php';
207
  }
208
 
 
 
 
 
209
  /**
210
  * Adjust the modules category name
211
  *
elementor-addon-widgets.php CHANGED
@@ -3,7 +3,7 @@
3
  * Plugin Name: Elementor Addons & Templates - Sizzify Lite
4
  * Plugin URI: https://themeisle.com/
5
  * Description: Adds new Addons & Widgets that are specifically designed to be used in conjunction with the Elementor Page Builder.
6
- * Version: 1.2.9
7
  * Author: ThemeIsle
8
  * Author URI: https://themeisle.com/
9
  * Requires at least: 4.4
@@ -23,7 +23,7 @@ Constants
23
  ------------------------------------------ */
24
 
25
  /* Set plugin version constant. */
26
- define( 'EA_VERSION', '1.2.9' );
27
 
28
  /* Set constant path to the plugin directory. */
29
  define( 'EA_PATH', trailingslashit( plugin_dir_path( __FILE__ ) ) );
@@ -31,6 +31,8 @@ define( 'EA_PATH', trailingslashit( plugin_dir_path( __FILE__ ) ) );
31
  /* Set the constant path to the plugin directory URI. */
32
  define( 'EA_URI', trailingslashit( plugin_dir_url( __FILE__ ) ) );
33
 
 
 
34
  define( 'SIZZIFY_UPSELL_LINK', 'https://themeisle.com/plugins/sizzify-elementor-addons-templates' );
35
 
36
 
@@ -77,6 +79,7 @@ function eaw_do_shortcode( $tag, array $atts = array(), $content = null ) {
77
  $vendor_file = plugin_dir_path( __FILE__ ) . 'vendor/autoload.php';
78
  if ( is_readable( $vendor_file ) ) {
79
  require_once $vendor_file;
 
80
  }
81
 
82
  /**
@@ -108,3 +111,12 @@ function elementor_addon_widgets_uninstall() {
108
  }
109
  }
110
  register_uninstall_hook( __FILE__, 'elementor_addon_widgets_uninstall' );
 
 
 
 
 
 
 
 
 
3
  * Plugin Name: Elementor Addons & Templates - Sizzify Lite
4
  * Plugin URI: https://themeisle.com/
5
  * Description: Adds new Addons & Widgets that are specifically designed to be used in conjunction with the Elementor Page Builder.
6
+ * Version: 1.3.0
7
  * Author: ThemeIsle
8
  * Author URI: https://themeisle.com/
9
  * Requires at least: 4.4
23
  ------------------------------------------ */
24
 
25
  /* Set plugin version constant. */
26
+ define( 'EA_VERSION', '1.3.0' );
27
 
28
  /* Set constant path to the plugin directory. */
29
  define( 'EA_PATH', trailingslashit( plugin_dir_path( __FILE__ ) ) );
31
  /* Set the constant path to the plugin directory URI. */
32
  define( 'EA_URI', trailingslashit( plugin_dir_url( __FILE__ ) ) );
33
 
34
+ define( 'EA_PLUGIN_NAME', 'elementor_addon_widgets' );
35
+
36
  define( 'SIZZIFY_UPSELL_LINK', 'https://themeisle.com/plugins/sizzify-elementor-addons-templates' );
37
 
38
 
79
  $vendor_file = plugin_dir_path( __FILE__ ) . 'vendor/autoload.php';
80
  if ( is_readable( $vendor_file ) ) {
81
  require_once $vendor_file;
82
+
83
  }
84
 
85
  /**
111
  }
112
  }
113
  register_uninstall_hook( __FILE__, 'elementor_addon_widgets_uninstall' );
114
+
115
+
116
+ add_filter( EA_PLUGIN_NAME . '_enqueue_recommend', 'elementor_addon_widgets_upsell_plugins', 10, 2 );
117
+ /**
118
+ * Validates the correct screen on which the assets for upsell should be loaded.
119
+ */
120
+ function elementor_addon_widgets_upsell_plugins( $return, $screen_id ) {
121
+ return $screen_id === 'toplevel_page_sizzify-admin';
122
+ }
readme.md CHANGED
@@ -2,7 +2,7 @@
2
  **Contributors:** [themeisle](https://profiles.wordpress.org/themeisle), [codeinwp](https://profiles.wordpress.org/codeinwp)
3
  **Tags:** elementor, elementor addons, page builder template, page builder templates, woocommerce, template builder, builder templates
4
  **Requires at least:** 4.4
5
- **Tested up to:** 5.0
6
  **License:** GPLv3
7
  **License URI:** https://www.gnu.org/licenses/gpl-3.0.html
8
 
@@ -61,6 +61,12 @@ See this [issue #495](https://github.com/pojome/elementor/issues/495) for curren
61
  4. Frontend view posts with custom title.
62
 
63
  ## Changelog ##
 
 
 
 
 
 
64
  ### 1.2.9 - 2018-12-12 ###
65
 
66
  * fix templates directory importing
2
  **Contributors:** [themeisle](https://profiles.wordpress.org/themeisle), [codeinwp](https://profiles.wordpress.org/codeinwp)
3
  **Tags:** elementor, elementor addons, page builder template, page builder templates, woocommerce, template builder, builder templates
4
  **Requires at least:** 4.4
5
+ **Tested up to:** 5.1
6
  **License:** GPLv3
7
  **License URI:** https://www.gnu.org/licenses/gpl-3.0.html
8
 
61
  4. Frontend view posts with custom title.
62
 
63
  ## Changelog ##
64
+ ### 1.3.0 - 2019-03-08 ###
65
+
66
+ * Tested with latest WordPress version, 5.1
67
+ * Remove mention of Pro add-on, discontinue recommendation of the Premium features
68
+
69
+
70
  ### 1.2.9 - 2018-12-12 ###
71
 
72
  * fix templates directory importing
readme.txt CHANGED
@@ -2,7 +2,7 @@
2
  Contributors: themeisle, codeinwp
3
  Tags: elementor, elementor addons, page builder template, page builder templates, woocommerce, template builder, builder templates
4
  Requires at least: 4.4
5
- Tested up to: 5.0
6
  License: GPLv3
7
  License URI: https://www.gnu.org/licenses/gpl-3.0.html
8
 
@@ -61,6 +61,12 @@ See this [issue #495](https://github.com/pojome/elementor/issues/495) for curren
61
  4. Frontend view posts with custom title.
62
 
63
  == Changelog ==
 
 
 
 
 
 
64
  = 1.2.9 - 2018-12-12 =
65
 
66
  * fix templates directory importing
2
  Contributors: themeisle, codeinwp
3
  Tags: elementor, elementor addons, page builder template, page builder templates, woocommerce, template builder, builder templates
4
  Requires at least: 4.4
5
+ Tested up to: 5.1
6
  License: GPLv3
7
  License URI: https://www.gnu.org/licenses/gpl-3.0.html
8
 
61
  4. Frontend view posts with custom title.
62
 
63
  == Changelog ==
64
+ = 1.3.0 - 2019-03-08 =
65
+
66
+ * Tested with latest WordPress version, 5.1
67
+ * Remove mention of Pro add-on, discontinue recommendation of the Premium features
68
+
69
+
70
  = 1.2.9 - 2018-12-12 =
71
 
72
  * fix templates directory importing
themeisle-hash.json CHANGED
@@ -1 +1 @@
1
- {"eaw-class.php":"8cfd2eba7189aa727c9ad5ce1581432f","elementor-addon-widgets.php":"650056d773837eb0491236a577367db8"}
1
+ {"eaw-class.php":"7884bd92ace1bd5e8a5b1151b6dfb4a9","elementor-addon-widgets.php":"f1fa7d8d2443a0c6c2c3eaac68d144e6"}
vendor/autoload.php CHANGED
@@ -4,4 +4,4 @@
4
 
5
  require_once __DIR__ . '/composer' . '/autoload_real.php';
6
 
7
- return ComposerAutoloaderInitd67a8571892509a7a621debcca8600f6::getLoader();
4
 
5
  require_once __DIR__ . '/composer' . '/autoload_real.php';
6
 
7
+ return ComposerAutoloaderInit1949c25865d8e9f266b9f04c54d29d81::getLoader();
vendor/codeinwp/elementor-extra-widgets/README.md ADDED
@@ -0,0 +1 @@
 
1
+ # elementor-extra-widgets
vendor/codeinwp/elementor-extra-widgets/phpunit.xml ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <phpunit
2
+ bootstrap="tests/bootstrap.php"
3
+ backupGlobals="false"
4
+ colors="true"
5
+ convertErrorsToExceptions="true"
6
+ convertNoticesToExceptions="true"
7
+ convertWarningsToExceptions="true"
8
+ >
9
+ <testsuites>
10
+ <testsuite>
11
+ <directory prefix="test-" suffix=".php">./tests/</directory>
12
+ </testsuite>
13
+ </testsuites>
14
+ </phpunit>
vendor/codeinwp/elementor-extra-widgets/tests/bootstrap.php ADDED
@@ -0,0 +1,50 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * PHPUnit bootstrap file
4
+ *
5
+ * @package ThemeIsle\ElementorExtraWidgets
6
+ */
7
+
8
+ /**
9
+ * change PLUGIN_FILE env in phpunit.xml
10
+ */
11
+ define( 'PLUGIN_FILE', getenv( 'PLUGIN_FILE' ) );
12
+ define( 'PLUGIN_FOLDER', basename( dirname( __DIR__ ) ) );
13
+ define( 'PLUGIN_PATH', PLUGIN_FOLDER . '/' . PLUGIN_FILE );
14
+
15
+ // Activates this plugin in WordPress so it can be tested.
16
+ $GLOBALS['wp_tests_options'] = [
17
+ 'active_plugins' => [ PLUGIN_PATH ],
18
+ 'template' => 'twentysixteen',
19
+ 'stylesheet' => 'twentysixteen',
20
+ ];
21
+
22
+ // Determine the tests directory (from a WP dev checkout).
23
+ // Try the WP_TESTS_DIR environment variable first.
24
+ $_tests_dir = getenv( 'WP_TESTS_DIR' );
25
+
26
+ // See if we're installed inside an existing WP dev instance.
27
+ if ( ! $_tests_dir ) {
28
+ $_try_tests_dir = dirname( __FILE__ ) . '/../../../../../tests/phpunit';
29
+ if ( file_exists( $_try_tests_dir . '/includes/functions.php' ) ) {
30
+ $_tests_dir = $_try_tests_dir;
31
+ }
32
+ }
33
+ // Fallback.
34
+ if ( ! $_tests_dir ) {
35
+ $_tests_dir = '/tmp/wordpress-tests-lib';
36
+ }
37
+
38
+ // Give access to tests_add_filter() function.
39
+ require_once $_tests_dir . '/includes/functions.php';
40
+
41
+ /**
42
+ * Manually load the plugin being tested.
43
+ */
44
+ function _manually_load_plugin() {
45
+ require dirname( dirname( __FILE__ ) ) . '/load.php';
46
+ }
47
+ tests_add_filter( 'muplugins_loaded', '_manually_load_plugin' );
48
+
49
+ // Start up the WP testing environment.
50
+ require $_tests_dir . '/includes/bootstrap.php';
vendor/codeinwp/elementor-extra-widgets/tests/test-basics.php ADDED
@@ -0,0 +1,71 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Basic Tests
4
+ *
5
+ * @package ThemeIsle\ElementorExtraWidgets
6
+ */
7
+
8
+ /**
9
+ * Test functions in register.php
10
+ */
11
+ class Plugin_Test extends WP_UnitTestCase {
12
+
13
+ public function setUp() {
14
+ parent::setUp();
15
+ wp_set_current_user( $this->factory->user->create( [ 'role' => 'administrator' ] ) );
16
+
17
+ do_action( 'init' );
18
+ do_action( 'plugins_loaded' );
19
+ }
20
+
21
+ /**
22
+ * Tests test_library_availability().
23
+ *
24
+ * @covers ElementorExtraWidgets::instance();
25
+ */
26
+ function test_library_availability() {
27
+ $this->assertTrue( class_exists( '\ThemeIsle\ElementorExtraWidgets') );
28
+ }
29
+
30
+ /**
31
+ * Test the right type of class instance
32
+ *
33
+ * @covers ElementorExtraWidgets::instance();
34
+ */
35
+ public function test_getInstance() {
36
+ $this->assertInstanceOf( '\Themeisle\ElementorExtraWidgets', \Themeisle\ElementorExtraWidgets::instance() );
37
+ }
38
+
39
+ /**
40
+ * Test if the library version is the same from the composer.json
41
+ *
42
+ * @covers ElementorExtraWidgets::$version
43
+ */
44
+ function test_version() {
45
+ $composer_version = json_decode( file_get_contents( dirname( dirname( __FILE__ ) ) . '/composer.json' ) );
46
+ $this->assertTrue( $composer_version->version === \ThemeIsle\ElementorExtraWidgets::$version );
47
+ }
48
+
49
+ /**
50
+ * Test if the class enqueues the required assets
51
+ * @covers ElementorExtraWidgets::register_assets
52
+ */
53
+ public function test_assets_enqueue() {
54
+ $this->assertFalse( wp_script_is( 'obfx-grid-js', 'registered' ) );
55
+ $this->assertFalse( wp_style_is( 'eaw-elementor', 'registered' ) );
56
+ }
57
+
58
+ /**
59
+ * @expectedIncorrectUsage __clone
60
+ */
61
+ public function test_Clone() {
62
+ $obj_cloned = clone \Themeisle\ElementorExtraWidgets::$instance;
63
+ }
64
+
65
+ /**
66
+ * @expectedIncorrectUsage __wakeup
67
+ */
68
+ public function test_Wakeup() {
69
+ unserialize( serialize( \Themeisle\ElementorExtraWidgets::$instance ) );
70
+ }
71
+ }
vendor/codeinwp/full-width-page-templates/README.md ADDED
@@ -0,0 +1,119 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Full-Width Templates
2
+ -------------
3
+ A composer library which injects, in WordPress Dashboard, a Full-Width option in the Page Template selector.
4
+
5
+ [![Codacy Badge](https://api.codacy.com/project/badge/Grade/ff19f3a4a9724f5c97f88d64fbbc1493)](https://www.codacy.com/app/andrei.lupu/full-width-page-templates?utm_source=github.com&amp;utm_medium=referral&amp;utm_content=Codeinwp/full-width-page-templates&amp;utm_campaign=Badge_Grade)
6
+
7
+ #### Supported Builders:
8
+ * A plain simple WordPress page
9
+ * Elementor
10
+
11
+ ### Compatible themes?
12
+ At this moment this library ensures compatibility with the follwing WordPress themes(and more to come):
13
+ * [Hestia](https://wordpress.org/themes/hestia/) - by ThemeIsle
14
+ * [Hestia Pro](https://themeisle.com/themes/hestia-pro/) - by ThemeIsle
15
+ * [Zerif Lite](https://themeisle.com/themes/zerif-lite) - by ThemeIsle
16
+ * [ShopIsle](https://wordpress.org/themes/shop-isle/) - by ThemeIsle
17
+ * [Orfeo](https://themeisle.com/themes/orfeo) - by ThemeIsle
18
+ * [Edge](https://wordpress.org/themes/edge/) - By themefreesia
19
+ * [Experon](https://wordpress.org/themes/experon/) - ThinkUpThemes
20
+ * [Genesis](http://my.studiopress.com/themes/genesis/) - By StudioPress
21
+ * [GeneratePress](https://wordpress.org/themes/generatepress/) - By Tom Usborne
22
+ * [Storefront](https://wordpress.org/themes/storefront/) - by WooThemes/Automattic
23
+ * [TwentyTwelve](https://wordpress.org/themes/twentytwelve/) - by WordPress.org
24
+ * [TwentyThirteen](https://wordpress.org/themes/twentythirteen/) - by WordPress.org
25
+ * [TwentyFourteen](https://wordpress.org/themes/twentyfourteen/) - by WordPress.org
26
+ * [TwentyFifteen](https://wordpress.org/themes/twentyfifteen/) - by WordPress.org
27
+ * [TwentySixteen](https://wordpress.org/themes/twentysixteen/) - by WordPress.org
28
+ * [TwentySeventeen](https://wordpress.org/themes/twentyseventeen/) - by WordPress.org
29
+ * [Vantage](https://wordpress.org/themes/vantage/) - by Greg Priday
30
+ * [Virtue](https://wordpress.org/themes/virtue/) - by Kadence Themes
31
+ * [Enlightenment](https://wordpress.org/themes/enlightenment/) - by Daniel Tara
32
+ * [Actions](https://wordpress.org/themes/actions/) - by WPDevHQ
33
+ * [ActionsPro](https://wpdevhq.com/themes/actions-pro/) - by WPDevHQ
34
+ * [Kale](https://wordpress.org/themes/kale/) - by lyrathemes
35
+ * [InVogue](https://wordpress.org/themes/invogue) - by Kaira
36
+ * [Universal-Store](https://wordpress.org/themes/universal-store/) - by Themes4WP
37
+ * [Editorial](https://wordpress.org/themes/editorial/) - by Mystery Themes
38
+ * [Renden Business](https://wordpress.org/themes/renden-business/) - by ThinkUpThemes
39
+ * [Spacious](https://wordpress.org/themes/spacious/) - by ThemeGrill
40
+ * [Flash](https://wordpress.org/themes/spacious/) - by ThemeGrill
41
+ * [Writee](https://wordpress.org/themes/writee/) - by Scissor Themes
42
+ * [VT Blogging](https://wordpress.org/themes/vt-blogging/) - by VolThemes
43
+ * [One Page Express](https://wordpress.org/themes/one-page-express/) - by horearadu
44
+ * [Primer](https://wordpress.org/themes/primer/) - by GoDaddy
45
+ * [Vantage](https://wordpress.org/themes/vantage/) - by SiteOrigin
46
+ * [Customizr](https://wordpress.org/themes/customizr/) - by Nicolas Guillaume
47
+ * [Nikko Portfolio](https://wordpress.org/themes/nikko-portfolio/) - by Colormelon
48
+ * [Poseidon](https://wordpress.org/themes/poseidon/) - by ThemeZee
49
+ * [Envo Business](https://wordpress.org/themes/envo-business/) - by EnvoThemes
50
+ * [Hueman](https://wordpress.org/themes/hueman/) - by Nicolas Guillaume
51
+ * [News Portal](https://wordpress.org/themes/news-portal/) - by Mystery Themes
52
+ * [Illdy](https://wordpress.org/themes/illdy/) - by Silkalns
53
+ * [Envy Blog](https://wordpress.org/themes/envy-blog/) - by Precise Themes
54
+ * [Avant](https://wordpress.org/themes/avant/) - by Kaira
55
+ * [OceanWP](https://wordpress.org/themes/oceanwp/) - by oceanwp
56
+ * [Astra](https://wordpress.org/themes/astra/) - by Brainstorm Force
57
+ * [Mesmerize](https://wordpress.org/themes/mesmerize/) - by horearadu
58
+ * [Sydney](https://wordpress.org/themes/sydney/) - by athemes
59
+ * [Ashe](https://wordpress.org/themes/ashe/) - by Royal Flush
60
+ * [Lodestar](https://wordpress.org/themes/lodestar/) - by Automattic
61
+ * [Total](https://wordpress.org/themes/total/) - by Hash Themes
62
+ * [Consulting](https://wordpress.org/themes/consulting/) - by ThinkUpThemes
63
+ * [ColorMag](https://wordpress.org/themes/colormag/) - by ThemeGrill
64
+ * [OnePress](https://wordpress.org/themes/onepress/) - by FameThemes
65
+ * [Shapely](https://wordpress.org/themes/shapely/) - by Silkalns
66
+ * [HitMag](https://wordpress.org/themes/hitmag/) - by ThemezHut
67
+ * [Divi](https://www.elegantthemes.com/gallery/divi) - by Elegant Themes
68
+
69
+ ### How to use it?
70
+ Well, this is a Composer library so you will need to add this it as a dependency on your project( either plugin or a theme ) like this:
71
+ ```
72
+ "require": {
73
+ "codeinwp/full-width-page-templates": "master"
74
+ }
75
+ ```
76
+ And run a via the terminal a `composer install` and hope that you have Composer installed globally.
77
+
78
+ The last step is the initialization. Call this wherever you like:
79
+ ```
80
+ if ( class_exists( '\ThemeIsle\FullWidthTemplates' ) ) {
81
+ \ThemeIsle\FullWidthTemplates::instance();
82
+ }
83
+ ```
84
+
85
+ ### Work with this repository?
86
+ To work directly with this repository, I use and recommend the following way.
87
+
88
+ Clone this repository inside the [mu-plugins](https://codex.wordpress.org/Must_Use_Plugins) WordPress directory. This way, we can be sure that the cloned version of this
89
+ library will have priority before the one loaded from Composer.
90
+ After cloning you need to create a php file, like `load-fwt-lib.php`(I'm so bad at naming) and inside you will need to require the loader like this:
91
+ ```
92
+ <?php
93
+ require_once( dirname( __FILE__ ) . '/full-width-page-templates/load.php' );
94
+ ```
95
+
96
+ ### How to make a theme compatible with the full-width template?
97
+
98
+ To add a new theme to the compatibility list, clone this repository(as we talked above) create a new directory with the
99
+ theme's name in the `themes` directory.
100
+ This theme directory supports two files:
101
+
102
+ * `inline-style.php` - A file loaded at the right moment to add an inline style
103
+ * `functions.php` - An optional file to add actions and filters.
104
+
105
+ Our goal here is to add a CSS snippet which will make sure that the page container width full.
106
+ So make use of the `inline-style.php` and add a snipet like this:
107
+ ```
108
+ <?php
109
+ /* Support for the {Theme Name} theme */
110
+ $style = '.page-template-builder-fullwidth-std .site-content {
111
+ width: 100%;
112
+ padding: 0;
113
+ margin:0;
114
+ }';
115
+ wp_add_inline_style( '{theme-style}', $style );
116
+ ```
117
+ Where `{theme-style}` must be an enqueued style.(For example, Twenty Seventeen has 'twentyseventeen-style')
118
+
119
+ Don't forget to add the new theme to this README.md ;)
vendor/codeinwp/full-width-page-templates/phpunit.xml ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <phpunit
2
+ bootstrap="tests/bootstrap.php"
3
+ backupGlobals="false"
4
+ colors="true"
5
+ convertErrorsToExceptions="true"
6
+ convertNoticesToExceptions="true"
7
+ convertWarningsToExceptions="true"
8
+ >
9
+ <testsuites>
10
+ <testsuite>
11
+ <directory prefix="test-" suffix=".php">./tests/</directory>
12
+ </testsuite>
13
+ </testsuites>
14
+ </phpunit>
vendor/codeinwp/full-width-page-templates/tests/bootstrap.php ADDED
@@ -0,0 +1,50 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * PHPUnit bootstrap file
4
+ *
5
+ * @package ThemeIsle\FullWidthTemplates
6
+ */
7
+
8
+ /**
9
+ * change PLUGIN_FILE env in phpunit.xml
10
+ */
11
+ define( 'PLUGIN_FILE', getenv( 'PLUGIN_FILE' ) );
12
+ define( 'PLUGIN_FOLDER', basename( dirname( __DIR__ ) ) );
13
+ define( 'PLUGIN_PATH', PLUGIN_FOLDER . '/' . PLUGIN_FILE );
14
+
15
+ // Activates this plugin in WordPress so it can be tested.
16
+ $GLOBALS['wp_tests_options'] = [
17
+ 'active_plugins' => [ PLUGIN_PATH ],
18
+ 'template' => 'twentysixteen',
19
+ 'stylesheet' => 'twentysixteen',
20
+ ];
21
+
22
+ // Determine the tests directory (from a WP dev checkout).
23
+ // Try the WP_TESTS_DIR environment variable first.
24
+ $_tests_dir = getenv( 'WP_TESTS_DIR' );
25
+
26
+ // See if we're installed inside an existing WP dev instance.
27
+ if ( ! $_tests_dir ) {
28
+ $_try_tests_dir = dirname( __FILE__ ) . '/../../../../../tests/phpunit';
29
+ if ( file_exists( $_try_tests_dir . '/includes/functions.php' ) ) {
30
+ $_tests_dir = $_try_tests_dir;
31
+ }
32
+ }
33
+ // Fallback.
34
+ if ( ! $_tests_dir ) {
35
+ $_tests_dir = '/tmp/wordpress-tests-lib';
36
+ }
37
+
38
+ // Give access to tests_add_filter() function.
39
+ require_once $_tests_dir . '/includes/functions.php';
40
+
41
+ /**
42
+ * Manually load the plugin being tested.
43
+ */
44
+ function _manually_load_plugin() {
45
+ require dirname( dirname( __FILE__ ) ) . '/load.php';
46
+ }
47
+ tests_add_filter( 'muplugins_loaded', '_manually_load_plugin' );
48
+
49
+ // Start up the WP testing environment.
50
+ require $_tests_dir . '/includes/bootstrap.php';
vendor/codeinwp/full-width-page-templates/tests/test-basics.php ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Basic Tests
4
+ *
5
+ * @package ThemeIsle\ContentForms
6
+ */
7
+
8
+ /**
9
+ * Test functions in register.php
10
+ */
11
+ class Plugin_Test extends WP_UnitTestCase {
12
+
13
+ public function setUp() {
14
+ parent::setUp();
15
+ wp_set_current_user( $this->factory->user->create( [ 'role' => 'administrator' ] ) );
16
+
17
+ do_action( 'init' );
18
+ do_action( 'plugins_loaded' );
19
+ }
20
+
21
+ /**
22
+ * Tests test_library_availability().
23
+ *
24
+ * @covers FullWidthTemplates::instance();
25
+ */
26
+ function test_library_availability() {
27
+ $this->assertTrue( class_exists( '\ThemeIsle\FullWidthTemplates') );
28
+ }
29
+
30
+ function test_version() {
31
+ $composer_version = json_decode( file_get_contents( dirname( dirname( __FILE__ ) ) . '/composer.json' ) );
32
+
33
+ $this->assertTrue( $composer_version->version === \ThemeIsle\FullWidthTemplates::$version );
34
+ }
35
+ }
vendor/codeinwp/templates-directory/README.md ADDED
@@ -0,0 +1 @@
 
1
+ # templates-directory
vendor/codeinwp/themeisle-content-forms/assets/content-forms.css CHANGED
@@ -17,11 +17,18 @@ fieldset {
17
  pointer-events: none;
18
  }
19
  .content-form-notice {
20
- font-size: 21px;
21
  padding: 5px;
22
  }
 
 
 
 
 
 
 
23
  .content-form-success {
24
- color: #53a813;
25
  border: 2px solid #53a813;
26
  }
27
  .content-form-error {
17
  pointer-events: none;
18
  }
19
  .content-form-notice {
20
+ font-size: 18px;
21
  padding: 5px;
22
  }
23
+
24
+ .content-form-notice-wrapper {
25
+ display: flex;
26
+ width: 100%;
27
+ padding-left: 5px;
28
+ }
29
+
30
  .content-form-success {
31
+ color: #53a813;
32
  border: 2px solid #53a813;
33
  }
34
  .content-form-error {
vendor/codeinwp/themeisle-content-forms/assets/content-forms.js CHANGED
@@ -76,7 +76,7 @@ var addContentFormNotice = function ( notice, type, $form ) {
76
  noticeStatus = 'content-form-error';
77
  }
78
 
79
- var noticeEl = "<h3 class='content-form-notice " + noticeStatus + "' >" + notice + "</h3>";
80
 
81
  // if an notice already exist, replace it; otherwise create one
82
  if ( $currentNotice.length > 0 ) {
76
  noticeStatus = 'content-form-error';
77
  }
78
 
79
+ var noticeEl = "<div class='content-form-notice-wrapper'><h3 class='content-form-notice " + noticeStatus + "' >" + notice + "</h3></div>";
80
 
81
  // if an notice already exist, replace it; otherwise create one
82
  if ( $currentNotice.length > 0 ) {
vendor/codeinwp/themeisle-content-forms/assets/gutenberg-esnext/block.build.js DELETED
@@ -1,376 +0,0 @@
1
- /******/ (function(modules) { // webpackBootstrap
2
- /******/ // The module cache
3
- /******/ var installedModules = {};
4
- /******/
5
- /******/ // The require function
6
- /******/ function __webpack_require__(moduleId) {
7
- /******/
8
- /******/ // Check if module is in cache
9
- /******/ if(installedModules[moduleId]) {
10
- /******/ return installedModules[moduleId].exports;
11
- /******/ }
12
- /******/ // Create a new module (and put it into the cache)
13
- /******/ var module = installedModules[moduleId] = {
14
- /******/ i: moduleId,
15
- /******/ l: false,
16
- /******/ exports: {}
17
- /******/ };
18
- /******/
19
- /******/ // Execute the module function
20
- /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
21
- /******/
22
- /******/ // Flag the module as loaded
23
- /******/ module.l = true;
24
- /******/
25
- /******/ // Return the exports of the module
26
- /******/ return module.exports;
27
- /******/ }
28
- /******/
29
- /******/
30
- /******/ // expose the modules object (__webpack_modules__)
31
- /******/ __webpack_require__.m = modules;
32
- /******/
33
- /******/ // expose the module cache
34
- /******/ __webpack_require__.c = installedModules;
35
- /******/
36
- /******/ // define getter function for harmony exports
37
- /******/ __webpack_require__.d = function(exports, name, getter) {
38
- /******/ if(!__webpack_require__.o(exports, name)) {
39
- /******/ Object.defineProperty(exports, name, {
40
- /******/ configurable: false,
41
- /******/ enumerable: true,
42
- /******/ get: getter
43
- /******/ });
44
- /******/ }
45
- /******/ };
46
- /******/
47
- /******/ // getDefaultExport function for compatibility with non-harmony modules
48
- /******/ __webpack_require__.n = function(module) {
49
- /******/ var getter = module && module.__esModule ?
50
- /******/ function getDefault() { return module['default']; } :
51
- /******/ function getModuleExports() { return module; };
52
- /******/ __webpack_require__.d(getter, 'a', getter);
53
- /******/ return getter;
54
- /******/ };
55
- /******/
56
- /******/ // Object.prototype.hasOwnProperty.call
57
- /******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
58
- /******/
59
- /******/ // __webpack_public_path__
60
- /******/ __webpack_require__.p = "";
61
- /******/
62
- /******/ // Load entry module and return exports
63
- /******/ return __webpack_require__(__webpack_require__.s = 0);
64
- /******/ })
65
- /************************************************************************/
66
- /******/ ([
67
- /* 0 */
68
- /***/ (function(module, __webpack_exports__, __webpack_require__) {
69
-
70
- "use strict";
71
- Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
72
- /* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__components_FormEditor_js__ = __webpack_require__(1);
73
- var registerBlockType = wp.blocks.registerBlockType;
74
- var __ = wp.i18n.__;
75
-
76
-
77
-
78
- // @TODO think about a method to magically create this list
79
- var content_forms = ['contact', 'newsletter', 'registration'];
80
-
81
- /**
82
- * Go through each form type and register a blockType from the given config
83
- * @TODO maybe create a custom category for OrbitFox only?
84
- *
85
- */
86
- content_forms.forEach(function (form, index) {
87
- var _this = this;
88
-
89
- var config = window['content_forms_config_for_' + form];
90
-
91
- registerBlockType('content-forms/' + form, {
92
- title: config.title,
93
- icon: 'index-card',
94
- category: 'common',
95
- type: form,
96
- keywords: [__('forms'), __('fields')],
97
- edit: __WEBPACK_IMPORTED_MODULE_0__components_FormEditor_js__["a" /* ContentFormEditor */],
98
- // save: props => {return null}
99
- save: function save(props) {
100
- var component = _this;
101
- var attributes = props.attributes;
102
- var fields = attributes.fields;
103
-
104
- var fieldsEl = [];
105
-
106
- if (typeof attributes.uid === "undefined") {
107
- attributes.uid = props.id;
108
- }
109
-
110
- _.each(fields, function (args, key) {
111
-
112
- fieldsEl.push(wp.element.createElement('p', {
113
- key: key,
114
- className: 'content-form-field-label',
115
- 'data-field_id': args.field_id,
116
- 'data-label': args.label,
117
- 'data-field_type': args.type,
118
- 'data-requirement': args.requirement ? "true" : "false"
119
- }));
120
- });
121
-
122
- return wp.element.createElement(
123
- 'div',
124
- { key: 'content-form-fields', className: "content-form-fields content-form-" + form, 'data-uid': props.id },
125
- fieldsEl
126
- );
127
- }
128
-
129
- // @TODO Maybe return to the old way of saving a plain html
130
- // save: props => {
131
- // const {
132
- // className,
133
- // attributes
134
- // } = props;
135
- //
136
- // let elements = [];
137
- //
138
- // _.each(config.fields, function (args, key) {
139
- // let fieldset_element = <fieldset key={key}>
140
- // <label htmlFor={key}>{attributes[key]}</label>
141
- // <input type="text" name={key} />
142
- // </fieldset>;
143
- // elements.push(fieldset_element)
144
- // });
145
- //
146
- // // Add a submit button; @TODO Make a setting for this;
147
- // elements.push(<button key="submit_btn">Submit</button>);
148
- //
149
- // return (
150
- // <form className={ props.className } method="post" action={submitAction}>
151
- // {elements}
152
- // </form>
153
- // );
154
- // }
155
- });
156
- });
157
-
158
- /***/ }),
159
- /* 1 */
160
- /***/ (function(module, __webpack_exports__, __webpack_require__) {
161
-
162
- "use strict";
163
- /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return ContentFormEditor; });
164
- var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
165
-
166
- var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
167
-
168
- function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
169
-
170
- function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
171
-
172
- function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
173
-
174
- /**
175
- * WordPress dependencies
176
- */
177
- // import { map } from 'lodash';
178
- var Component = wp.element.Component;
179
- var _wp$components = wp.components,
180
- Placeholder = _wp$components.Placeholder,
181
- Spinner = _wp$components.Spinner,
182
- withAPIData = _wp$components.withAPIData,
183
- FormToggle = _wp$components.FormToggle;
184
- var __ = wp.i18n.__;
185
- var _wp$blocks = wp.blocks,
186
- Editable = _wp$blocks.Editable,
187
- BlockEdit = _wp$blocks.BlockEdit,
188
- InspectorControls = _wp$blocks.InspectorControls;
189
-
190
-
191
- var fieldStyle = {
192
- width: '40%',
193
- display: 'inline-block'
194
- };
195
-
196
- var fieldStyleR = {
197
- width: '10%',
198
- display: 'inline-block',
199
- textAlign: 'right'
200
- };
201
-
202
- var FormEditor = function (_Component) {
203
- _inherits(FormEditor, _Component);
204
-
205
- function FormEditor() {
206
- _classCallCheck(this, FormEditor);
207
-
208
- var _this = _possibleConstructorReturn(this, (FormEditor.__proto__ || Object.getPrototypeOf(FormEditor)).apply(this, arguments));
209
-
210
- _this.form_type = _this.props.name.replace('content-forms/', '');
211
- _this.config = window['content_forms_config_for_' + _this.form_type];
212
- return _this;
213
- }
214
-
215
- _createClass(FormEditor, [{
216
- key: 'render',
217
- value: function render() {
218
- var component = this;
219
- var _props = this.props,
220
- attributes = _props.attributes,
221
- setAttributes = _props.setAttributes,
222
- focus = _props.focus;
223
- var fields = attributes.fields;
224
-
225
- var placeholderEl = wp.element.createElement(
226
- Placeholder,
227
- { key: 'form-loader', icon: 'admin-post', label: __('Form') },
228
- wp.element.createElement(Spinner, null)
229
- );
230
- var controlsEl = [];
231
- var fieldsEl = [];
232
-
233
- _.each(component.config.controls, function (args, key) {
234
-
235
- controlsEl.push(wp.element.createElement(
236
- 'div',
237
- { key: key },
238
- wp.element.createElement(BlockEdit, { key: 'block-edit-custom-' + key }),
239
- wp.element.createElement(InspectorControls.TextControl, {
240
- key: key,
241
- label: args.label,
242
- value: attributes[key] || '',
243
- onFocus: function onFocus(f) {
244
- console.log(f);
245
- },
246
- onChange: function onChange(value) {
247
- var newValues = {};
248
- newValues[key] = value;
249
- setAttributes(newValues);
250
- }
251
- })
252
- ));
253
- });
254
-
255
- _.each(fields, function (args, key) {
256
- var val = '';
257
- var field_id = args.field_id;
258
- var field_config = component.config.fields[field_id];
259
- var isRequired = false;
260
-
261
- if (_typeof(args.label) === "object") {
262
- val = args.label[0];
263
- } else if (typeof args.label === "string") {
264
- val = [args.label];
265
- }
266
-
267
- if (typeof args.requirement !== "undefined") {
268
- isRequired = args.requirement;
269
- }
270
-
271
- var focusOn = 'field-' + field_id;
272
-
273
- fieldsEl.push(wp.element.createElement(
274
- 'div',
275
- { key: key, style: { border: '1px solid #333', padding: '5px', margin: '5px', borderRadius: '8px' }, className: 'content-form-field' },
276
- wp.element.createElement(
277
- 'fieldset',
278
- { style: fieldStyle },
279
- wp.element.createElement(Editable, {
280
- value: val,
281
- tagName: 'label',
282
- placeholder: __('Label for ') + field_id,
283
- className: 'content-form-field-label',
284
- onChange: function onChange(value) {
285
- var newValues = attributes.fields;
286
- newValues[key]['label'] = value;
287
- setAttributes({ fields: newValues });
288
- component.forceUpdate();
289
- } })
290
- ),
291
- wp.element.createElement(
292
- 'fieldset',
293
- { style: fieldStyle },
294
- wp.element.createElement(
295
- 'select',
296
- {
297
- name: 'field-type-select',
298
- value: typeof args['type'] !== "undefined" ? args['type'] : 'text',
299
- onChange: function onChange(event) {
300
- var newValues = attributes.fields;
301
- newValues[key]['type'] = event.target.selected;
302
- setAttributes({ fields: newValues });
303
- component.forceUpdate();
304
- } },
305
- wp.element.createElement(
306
- 'option',
307
- { value: 'text', key: 'text' },
308
- 'text'
309
- ),
310
- wp.element.createElement(
311
- 'option',
312
- { value: 'textarea', key: 'textarea' },
313
- 'textarea'
314
- ),
315
- wp.element.createElement(
316
- 'option',
317
- { value: 'password', key: 'password' },
318
- 'password'
319
- ),
320
- wp.element.createElement(
321
- 'option',
322
- { value: 'email', key: 'email' },
323
- 'email'
324
- ),
325
- wp.element.createElement(
326
- 'option',
327
- { value: 'number', key: 'number' },
328
- 'number'
329
- )
330
- )
331
- ),
332
- wp.element.createElement(
333
- 'fieldset',
334
- { style: fieldStyleR },
335
- wp.element.createElement(FormToggle, {
336
- checked: isRequired,
337
- showHint: false,
338
- onChange: function onChange(event) {
339
- var newValues = attributes.fields;
340
- newValues[key]['requirement'] = event.target.checked;
341
- setAttributes({ fields: newValues });
342
- component.forceUpdate();
343
- }
344
- })
345
- )
346
- ));
347
- });
348
-
349
- return [focus && wp.element.createElement(
350
- InspectorControls,
351
- { key: 'inspector' },
352
- wp.element.createElement(
353
- 'h3',
354
- null,
355
- __('Form Settings')
356
- ),
357
- controlsEl
358
- ), wp.element.createElement(
359
- 'div',
360
- { key: 'fields', className: 'fields ' + component.props.className, 'data-uid': attributes.uid },
361
- fieldsEl === [] ? placeholderEl : fieldsEl
362
- )];
363
- }
364
- }]);
365
-
366
- return FormEditor;
367
- }(Component);
368
-
369
- var ContentFormEditor = withAPIData(function () {
370
- return {
371
- ContentForm: '/content-forms/v1/forms'
372
- };
373
- })(FormEditor);
374
-
375
- /***/ })
376
- /******/ ]);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/codeinwp/themeisle-content-forms/assets/gutenberg-esnext/block.js DELETED
@@ -1,85 +0,0 @@
1
- const {
2
- registerBlockType,
3
- } = wp.blocks;
4
- const { __ } = wp.i18n;
5
- import { ContentFormEditor } from './components/FormEditor.js'
6
-
7
- // @TODO think about a method to magically create this list
8
- const content_forms = [
9
- 'contact',
10
- 'newsletter',
11
- 'registration'
12
- ];
13
-
14
- /**
15
- * Go through each form type and register a blockType from the given config
16
- * @TODO maybe create a custom category for OrbitFox only?
17
- *
18
- */
19
- content_forms.forEach(function (form, index) {
20
- let config = window['content_forms_config_for_' + form];
21
-
22
- registerBlockType('content-forms/' + form, {
23
- title: config.title,
24
- icon: 'index-card',
25
- category: 'common',
26
- type: form,
27
- keywords: [ __( 'forms' ), __( 'fields' ) ],
28
- edit: ContentFormEditor,
29
- // save: props => {return null}
30
- save: props => {
31
- const component = this
32
- const {attributes} = props
33
- const {fields} = attributes
34
- let fieldsEl = []
35
-
36
- if ( typeof attributes.uid === "undefined" ) {
37
- attributes.uid = props.id
38
- }
39
-
40
- _.each(fields, function (args, key) {
41
-
42
- fieldsEl.push(<p
43
- key={key}
44
- className="content-form-field-label"
45
- data-field_id={args.field_id}
46
- data-label={args.label}
47
- data-field_type={args.type}
48
- data-requirement={args.requirement ? "true": "false"}
49
- />)
50
- })
51
-
52
- return (<div key="content-form-fields" className={"content-form-fields content-form-" + form} data-uid={props.id}>
53
- {fieldsEl}
54
- </div>)
55
- }
56
-
57
- // @TODO Maybe return to the old way of saving a plain html
58
- // save: props => {
59
- // const {
60
- // className,
61
- // attributes
62
- // } = props;
63
- //
64
- // let elements = [];
65
- //
66
- // _.each(config.fields, function (args, key) {
67
- // let fieldset_element = <fieldset key={key}>
68
- // <label htmlFor={key}>{attributes[key]}</label>
69
- // <input type="text" name={key} />
70
- // </fieldset>;
71
- // elements.push(fieldset_element)
72
- // });
73
- //
74
- // // Add a submit button; @TODO Make a setting for this;
75
- // elements.push(<button key="submit_btn">Submit</button>);
76
- //
77
- // return (
78
- // <form className={ props.className } method="post" action={submitAction}>
79
- // {elements}
80
- // </form>
81
- // );
82
- // }
83
- });
84
- });
85
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/codeinwp/themeisle-content-forms/assets/gutenberg-esnext/components/FormEditor.js DELETED
@@ -1,148 +0,0 @@
1
- /**
2
- * WordPress dependencies
3
- */
4
- // import { map } from 'lodash';
5
- const {Component} = wp.element;
6
- const {Placeholder, Spinner, withAPIData, FormToggle} = wp.components;
7
- const {__} = wp.i18n;
8
- const {
9
- Editable,
10
- BlockEdit,
11
- InspectorControls
12
- } = wp.blocks;
13
-
14
- const fieldStyle = {
15
- width: '40%',
16
- display: 'inline-block'
17
- }
18
-
19
- const fieldStyleR = {
20
- width: '10%',
21
- display: 'inline-block',
22
- textAlign: 'right'
23
- }
24
-
25
- class FormEditor extends Component {
26
- constructor() {
27
- super(...arguments);
28
- this.form_type = this.props.name.replace('content-forms/', '')
29
- this.config = window['content_forms_config_for_' + this.form_type]
30
- }
31
-
32
- render() {
33
- const component = this
34
- const { attributes, setAttributes, focus } = this.props
35
- const {fields} = attributes
36
- const placeholderEl = <Placeholder key="form-loader" icon="admin-post" label={__('Form')}>
37
- <Spinner/>
38
- </Placeholder>
39
- let controlsEl = []
40
- let fieldsEl = []
41
-
42
- _.each(component.config.controls, function (args, key) {
43
-
44
- controlsEl.push(<div key={key}>
45
- <BlockEdit key={'block-edit-custom-' + key}/>
46
- <InspectorControls.TextControl
47
- key={key}
48
- label={args.label}
49
- value={attributes[key] || ''}
50
- onFocus={ f => {
51
- console.log(f)
52
- }}
53
- onChange={value => {
54
- let newValues = {}
55
- newValues[key] = value
56
- setAttributes(newValues)
57
- }}
58
- />
59
- </div>)
60
- })
61
-
62
- _.each(fields, function (args, key) {
63
- let val = ''
64
- let field_id = args.field_id
65
- let field_config = component.config.fields[field_id]
66
- let isRequired = false
67
-
68
- if (typeof args.label === "object") {
69
- val = args.label[0]
70
- } else if (typeof args.label === "string") {
71
- val = [args.label]
72
- }
73
-
74
- if (typeof args.requirement !== "undefined") {
75
- isRequired = args.requirement
76
- }
77
-
78
- const focusOn = 'field-' + field_id
79
-
80
- fieldsEl.push(<div key={key} style={{border: '1px solid #333', padding: '5px', margin: '5px', borderRadius: '8px'}} className="content-form-field">
81
-
82
- <fieldset style={fieldStyle}>
83
- <Editable
84
- value={val}
85
- tagName="label"
86
- placeholder={__('Label for ') + field_id}
87
- className="content-form-field-label"
88
- onChange={(value) => {
89
- let newValues = attributes.fields
90
- newValues[key]['label'] = value
91
- setAttributes({fields: newValues})
92
- component.forceUpdate()
93
- }}/>
94
- </fieldset>
95
-
96
- <fieldset style={fieldStyle}>
97
- <select
98
- name="field-type-select"
99
- value={typeof args['type'] !== "undefined" ? args['type'] : 'text'}
100
- onChange={(event) => {
101
- let newValues = attributes.fields
102
- newValues[key]['type'] = event.target.selected
103
- setAttributes({fields: newValues})
104
- component.forceUpdate()
105
- }}>
106
- <option value="text" key="text">text</option>
107
- <option value="textarea" key="textarea">textarea</option>
108
- <option value="password" key="password">password</option>
109
- <option value="email" key="email">email</option>
110
- <option value="number" key="number">number</option>
111
- </select>
112
- </fieldset>
113
-
114
- <fieldset style={fieldStyleR}>
115
- <FormToggle
116
- checked={isRequired}
117
- showHint={false}
118
- onChange={(event) => {
119
- let newValues = attributes.fields
120
- newValues[key]['requirement'] = event.target.checked
121
- setAttributes({fields: newValues})
122
- component.forceUpdate()
123
- }}
124
- />
125
- </fieldset>
126
-
127
- </div>)
128
- })
129
-
130
- return [
131
- focus && (<InspectorControls key="inspector">
132
- <h3>{__('Form Settings')}</h3>
133
- {controlsEl}
134
- </InspectorControls>),
135
- (<div key="fields" className={'fields ' + component.props.className} data-uid={attributes.uid}>
136
- {(fieldsEl === [])
137
- ? placeholderEl
138
- : fieldsEl}
139
- </div>)
140
- ]
141
- }
142
- }
143
-
144
- export const ContentFormEditor = withAPIData(() => {
145
- return {
146
- ContentForm: '/content-forms/v1/forms',
147
- };
148
- })(FormEditor);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/codeinwp/themeisle-content-forms/assets/gutenberg-esnext/index.php DELETED
@@ -1,2 +0,0 @@
1
- <?php
2
- // not here
 
 
vendor/codeinwp/themeisle-content-forms/assets/gutenberg-esnext/package-lock.json DELETED
@@ -1,4080 +0,0 @@
1
- {
2
- "name": "04-controls-esnext",
3
- "version": "1.0.0",
4
- "lockfileVersion": 1,
5
- "requires": true,
6
- "dependencies": {
7
- "acorn": {
8
- "version": "5.2.1",
9
- "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.2.1.tgz",
10
- "integrity": "sha512-jG0u7c4Ly+3QkkW18V+NRDN+4bWHdln30NL1ZL2AvFZZmQe/BfopYCtghCKKVBUSetZ4QKcyA0pY6/4Gw8Pv8w==",
11
- "dev": true
12
- },
13
- "acorn-dynamic-import": {
14
- "version": "2.0.2",
15
- "resolved": "https://registry.npmjs.org/acorn-dynamic-import/-/acorn-dynamic-import-2.0.2.tgz",
16
- "integrity": "sha1-x1K9IQvvZ5UBtsbLf8hPj0cVjMQ=",
17
- "dev": true,
18
- "requires": {
19
- "acorn": "4.0.13"
20
- },
21
- "dependencies": {
22
- "acorn": {
23
- "version": "4.0.13",
24
- "resolved": "https://registry.npmjs.org/acorn/-/acorn-4.0.13.tgz",
25
- "integrity": "sha1-EFSVrlNh1pe9GVyCUZLhrX8lN4c=",
26
- "dev": true
27
- }
28
- }
29
- },
30
- "ajv": {
31
- "version": "5.5.1",
32
- "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.1.tgz",
33
- "integrity": "sha1-s4u4h22ehr7plJVqBOch6IskjrI=",
34
- "dev": true,
35
- "requires": {
36
- "co": "4.6.0",
37
- "fast-deep-equal": "1.0.0",
38
- "fast-json-stable-stringify": "2.0.0",
39
- "json-schema-traverse": "0.3.1"
40
- }
41
- },
42
- "ajv-keywords": {
43
- "version": "2.1.1",
44
- "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-2.1.1.tgz",
45
- "integrity": "sha1-YXmX/F9gV2iUxDX5QNgZ4TW4B2I=",
46
- "dev": true
47
- },
48
- "align-text": {
49
- "version": "0.1.4",
50
- "resolved": "https://registry.npmjs.org/align-text/-/align-text-0.1.4.tgz",
51
- "integrity": "sha1-DNkKVhCT810KmSVsIrcGlDP60Rc=",
52
- "dev": true,
53
- "requires": {
54
- "kind-of": "3.2.2",
55
- "longest": "1.0.1",
56
- "repeat-string": "1.6.1"
57
- }
58
- },
59
- "ansi-regex": {
60
- "version": "2.1.1",
61
- "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
62
- "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
63
- "dev": true
64
- },
65
- "ansi-styles": {
66
- "version": "2.2.1",
67
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
68
- "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
69
- "dev": true
70
- },
71
- "anymatch": {
72
- "version": "1.3.2",
73
- "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.2.tgz",
74
- "integrity": "sha512-0XNayC8lTHQ2OI8aljNCN3sSx6hsr/1+rlcDAotXJR7C1oZZHCNsfpbKwMjRA3Uqb5tF1Rae2oloTr4xpq+WjA==",
75
- "dev": true,
76
- "requires": {
77
- "micromatch": "2.3.11",
78
- "normalize-path": "2.1.1"
79
- }
80
- },
81
- "arr-diff": {
82
- "version": "2.0.0",
83
- "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz",
84
- "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=",
85
- "dev": true,
86
- "requires": {
87
- "arr-flatten": "1.1.0"
88
- }
89
- },
90
- "arr-flatten": {
91
- "version": "1.1.0",
92
- "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz",
93
- "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==",
94
- "dev": true
95
- },
96
- "array-unique": {
97
- "version": "0.2.1",
98
- "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz",
99
- "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=",
100
- "dev": true
101
- },
102
- "asn1.js": {
103
- "version": "4.9.2",
104
- "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.9.2.tgz",
105
- "integrity": "sha512-b/OsSjvWEo8Pi8H0zsDd2P6Uqo2TK2pH8gNLSJtNLM2Db0v2QaAZ0pBQJXVjAn4gBuugeVDr7s63ZogpUIwWDg==",
106
- "dev": true,
107
- "requires": {
108
- "bn.js": "4.11.8",
109
- "inherits": "2.0.3",
110
- "minimalistic-assert": "1.0.0"
111
- }
112
- },
113
- "assert": {
114
- "version": "1.4.1",
115
- "resolved": "https://registry.npmjs.org/assert/-/assert-1.4.1.tgz",
116
- "integrity": "sha1-mZEtWRg2tab1s0XA8H7vwI/GXZE=",
117
- "dev": true,
118
- "requires": {
119
- "util": "0.10.3"
120
- }
121
- },
122
- "async": {
123
- "version": "2.6.0",
124
- "resolved": "https://registry.npmjs.org/async/-/async-2.6.0.tgz",
125
- "integrity": "sha512-xAfGg1/NTLBBKlHFmnd7PlmUW9KhVQIUuSrYem9xzFUZy13ScvtyGGejaae9iAVRiRq9+Cx7DPFaAAhCpyxyPw==",
126
- "dev": true,
127
- "requires": {
128
- "lodash": "4.17.4"
129
- }
130
- },
131
- "async-each": {
132
- "version": "1.0.1",
133
- "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.1.tgz",
134
- "integrity": "sha1-GdOGodntxufByF04iu28xW0zYC0=",
135
- "dev": true
136
- },
137
- "babel-code-frame": {
138
- "version": "6.26.0",
139
- "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz",
140
- "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=",
141
- "dev": true,
142
- "requires": {
143
- "chalk": "1.1.3",
144
- "esutils": "2.0.2",
145
- "js-tokens": "3.0.2"
146
- }
147
- },
148
- "babel-core": {
149
- "version": "6.26.0",
150
- "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-6.26.0.tgz",
151
- "integrity": "sha1-rzL3izGm/O8RnIew/Y2XU/A6C7g=",
152
- "dev": true,
153
- "requires": {
154
- "babel-code-frame": "6.26.0",
155
- "babel-generator": "6.26.0",
156
- "babel-helpers": "6.24.1",
157
- "babel-messages": "6.23.0",
158
- "babel-register": "6.26.0",
159
- "babel-runtime": "6.26.0",
160
- "babel-template": "6.26.0",
161
- "babel-traverse": "6.26.0",
162
- "babel-types": "6.26.0",
163
- "babylon": "6.18.0",
164
- "convert-source-map": "1.5.1",
165
- "debug": "2.6.9",
166
- "json5": "0.5.1",
167
- "lodash": "4.17.4",
168
- "minimatch": "3.0.4",
169
- "path-is-absolute": "1.0.1",
170
- "private": "0.1.8",
171
- "slash": "1.0.0",
172
- "source-map": "0.5.7"
173
- }
174
- },
175
- "babel-generator": {
176
- "version": "6.26.0",
177
- "resolved": "https://registry.npmjs.org/babel-generator/-/babel-generator-6.26.0.tgz",
178
- "integrity": "sha1-rBriAHC3n248odMmlhMFN3TyDcU=",
179
- "dev": true,
180
- "requires": {
181
- "babel-messages": "6.23.0",
182
- "babel-runtime": "6.26.0",
183
- "babel-types": "6.26.0",
184
- "detect-indent": "4.0.0",
185
- "jsesc": "1.3.0",
186
- "lodash": "4.17.4",
187
- "source-map": "0.5.7",
188
- "trim-right": "1.0.1"
189
- }
190
- },
191
- "babel-helper-builder-binary-assignment-operator-visitor": {
192
- "version": "6.24.1",
193
- "resolved": "https://registry.npmjs.org/babel-helper-builder-binary-assignment-operator-visitor/-/babel-helper-builder-binary-assignment-operator-visitor-6.24.1.tgz",
194
- "integrity": "sha1-zORReto1b0IgvK6KAsKzRvmlZmQ=",
195
- "dev": true,
196
- "requires": {
197
- "babel-helper-explode-assignable-expression": "6.24.1",
198
- "babel-runtime": "6.26.0",
199
- "babel-types": "6.26.0"
200
- }
201
- },
202
- "babel-helper-builder-react-jsx": {
203
- "version": "6.26.0",
204
- "resolved": "https://registry.npmjs.org/babel-helper-builder-react-jsx/-/babel-helper-builder-react-jsx-6.26.0.tgz",
205
- "integrity": "sha1-Of+DE7dci2Xc7/HzHTg+D/KkCKA=",
206
- "dev": true,
207
- "requires": {
208
- "babel-runtime": "6.26.0",
209
- "babel-types": "6.26.0",
210
- "esutils": "2.0.2"
211
- }
212
- },
213
- "babel-helper-call-delegate": {
214
- "version": "6.24.1",
215
- "resolved": "https://registry.npmjs.org/babel-helper-call-delegate/-/babel-helper-call-delegate-6.24.1.tgz",
216
- "integrity": "sha1-7Oaqzdx25Bw0YfiL/Fdb0Nqi340=",
217
- "dev": true,
218
- "requires": {
219
- "babel-helper-hoist-variables": "6.24.1",
220
- "babel-runtime": "6.26.0",
221
- "babel-traverse": "6.26.0",
222
- "babel-types": "6.26.0"
223
- }
224
- },
225
- "babel-helper-define-map": {
226
- "version": "6.26.0",
227
- "resolved": "https://registry.npmjs.org/babel-helper-define-map/-/babel-helper-define-map-6.26.0.tgz",
228
- "integrity": "sha1-pfVtq0GiX5fstJjH66ypgZ+Vvl8=",
229
- "dev": true,
230
- "requires": {
231
- "babel-helper-function-name": "6.24.1",
232
- "babel-runtime": "6.26.0",
233
- "babel-types": "6.26.0",
234
- "lodash": "4.17.4"
235
- }
236
- },
237
- "babel-helper-explode-assignable-expression": {
238
- "version": "6.24.1",
239
- "resolved": "https://registry.npmjs.org/babel-helper-explode-assignable-expression/-/babel-helper-explode-assignable-expression-6.24.1.tgz",
240
- "integrity": "sha1-8luCz33BBDPFX3BZLVdGQArCLKo=",
241
- "dev": true,
242
- "requires": {
243
- "babel-runtime": "6.26.0",
244
- "babel-traverse": "6.26.0",
245
- "babel-types": "6.26.0"
246
- }
247
- },
248
- "babel-helper-function-name": {
249
- "version": "6.24.1",
250
- "resolved": "https://registry.npmjs.org/babel-helper-function-name/-/babel-helper-function-name-6.24.1.tgz",
251
- "integrity": "sha1-00dbjAPtmCQqJbSDUasYOZ01gKk=",
252
- "dev": true,
253
- "requires": {
254
- "babel-helper-get-function-arity": "6.24.1",
255
- "babel-runtime": "6.26.0",
256
- "babel-template": "6.26.0",
257
- "babel-traverse": "6.26.0",
258
- "babel-types": "6.26.0"
259
- }
260
- },
261
- "babel-helper-get-function-arity": {
262
- "version": "6.24.1",
263
- "resolved": "https://registry.npmjs.org/babel-helper-get-function-arity/-/babel-helper-get-function-arity-6.24.1.tgz",
264
- "integrity": "sha1-j3eCqpNAfEHTqlCQj4mwMbG2hT0=",
265
- "dev": true,
266
- "requires": {
267
- "babel-runtime": "6.26.0",
268
- "babel-types": "6.26.0"
269
- }
270
- },
271
- "babel-helper-hoist-variables": {
272
- "version": "6.24.1",
273
- "resolved": "https://registry.npmjs.org/babel-helper-hoist-variables/-/babel-helper-hoist-variables-6.24.1.tgz",
274
- "integrity": "sha1-HssnaJydJVE+rbyZFKc/VAi+enY=",
275
- "dev": true,
276
- "requires": {
277
- "babel-runtime": "6.26.0",
278
- "babel-types": "6.26.0"
279
- }
280
- },
281
- "babel-helper-optimise-call-expression": {
282
- "version": "6.24.1",
283
- "resolved": "https://registry.npmjs.org/babel-helper-optimise-call-expression/-/babel-helper-optimise-call-expression-6.24.1.tgz",
284
- "integrity": "sha1-96E0J7qfc/j0+pk8VKl4gtEkQlc=",
285
- "dev": true,
286
- "requires": {
287
- "babel-runtime": "6.26.0",
288
- "babel-types": "6.26.0"
289
- }
290
- },
291
- "babel-helper-regex": {
292
- "version": "6.26.0",
293
- "resolved": "https://registry.npmjs.org/babel-helper-regex/-/babel-helper-regex-6.26.0.tgz",
294
- "integrity": "sha1-MlxZ+QL4LyS3T6zu0DY5VPZJXnI=",
295
- "dev": true,
296
- "requires": {
297
- "babel-runtime": "6.26.0",
298
- "babel-types": "6.26.0",
299
- "lodash": "4.17.4"
300
- }
301
- },
302
- "babel-helper-remap-async-to-generator": {
303
- "version": "6.24.1",
304
- "resolved": "https://registry.npmjs.org/babel-helper-remap-async-to-generator/-/babel-helper-remap-async-to-generator-6.24.1.tgz",
305
- "integrity": "sha1-XsWBgnrXI/7N04HxySg5BnbkVRs=",
306
- "dev": true,
307
- "requires": {
308
- "babel-helper-function-name": "6.24.1",
309
- "babel-runtime": "6.26.0",
310
- "babel-template": "6.26.0",
311
- "babel-traverse": "6.26.0",
312
- "babel-types": "6.26.0"
313
- }
314
- },
315
- "babel-helper-replace-supers": {
316
- "version": "6.24.1",
317
- "resolved": "https://registry.npmjs.org/babel-helper-replace-supers/-/babel-helper-replace-supers-6.24.1.tgz",
318
- "integrity": "sha1-v22/5Dk40XNpohPKiov3S2qQqxo=",
319
- "dev": true,
320
- "requires": {
321
- "babel-helper-optimise-call-expression": "6.24.1",
322
- "babel-messages": "6.23.0",
323
- "babel-runtime": "6.26.0",
324
- "babel-template": "6.26.0",
325
- "babel-traverse": "6.26.0",
326
- "babel-types": "6.26.0"
327
- }
328
- },
329
- "babel-helpers": {
330
- "version": "6.24.1",
331
- "resolved": "https://registry.npmjs.org/babel-helpers/-/babel-helpers-6.24.1.tgz",
332
- "integrity": "sha1-NHHenK7DiOXIUOWX5Yom3fN2ArI=",
333
- "dev": true,
334
- "requires": {
335
- "babel-runtime": "6.26.0",
336
- "babel-template": "6.26.0"
337
- }
338
- },
339
- "babel-loader": {
340
- "version": "7.1.2",
341
- "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-7.1.2.tgz",
342
- "integrity": "sha512-jRwlFbINAeyDStqK6Dd5YuY0k5YuzQUvlz2ZamuXrXmxav3pNqe9vfJ402+2G+OmlJSXxCOpB6Uz0INM7RQe2A==",
343
- "dev": true,
344
- "requires": {
345
- "find-cache-dir": "1.0.0",
346
- "loader-utils": "1.1.0",
347
- "mkdirp": "0.5.1"
348
- }
349
- },
350
- "babel-messages": {
351
- "version": "6.23.0",
352
- "resolved": "https://registry.npmjs.org/babel-messages/-/babel-messages-6.23.0.tgz",
353
- "integrity": "sha1-8830cDhYA1sqKVHG7F7fbGLyYw4=",
354
- "dev": true,
355
- "requires": {
356
- "babel-runtime": "6.26.0"
357
- }
358
- },
359
- "babel-plugin-check-es2015-constants": {
360
- "version": "6.22.0",
361
- "resolved": "https://registry.npmjs.org/babel-plugin-check-es2015-constants/-/babel-plugin-check-es2015-constants-6.22.0.tgz",
362
- "integrity": "sha1-NRV7EBQm/S/9PaP3XH0ekYNbv4o=",
363
- "dev": true,
364
- "requires": {
365
- "babel-runtime": "6.26.0"
366
- }
367
- },
368
- "babel-plugin-syntax-async-functions": {
369
- "version": "6.13.0",
370
- "resolved": "https://registry.npmjs.org/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz",
371
- "integrity": "sha1-ytnK0RkbWtY0vzCuCHI5HgZHvpU=",
372
- "dev": true
373
- },
374
- "babel-plugin-syntax-exponentiation-operator": {
375
- "version": "6.13.0",
376
- "resolved": "https://registry.npmjs.org/babel-plugin-syntax-exponentiation-operator/-/babel-plugin-syntax-exponentiation-operator-6.13.0.tgz",
377
- "integrity": "sha1-nufoM3KQ2pUoggGmpX9BcDF4MN4=",
378
- "dev": true
379
- },
380
- "babel-plugin-syntax-jsx": {
381
- "version": "6.18.0",
382
- "resolved": "https://registry.npmjs.org/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz",
383
- "integrity": "sha1-CvMqmm4Tyno/1QaeYtew9Y0NiUY=",
384
- "dev": true
385
- },
386
- "babel-plugin-syntax-trailing-function-commas": {
387
- "version": "6.22.0",
388
- "resolved": "https://registry.npmjs.org/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-6.22.0.tgz",
389
- "integrity": "sha1-ugNgk3+NBuQBgKQ/4NVhb/9TLPM=",
390
- "dev": true
391
- },
392
- "babel-plugin-transform-async-to-generator": {
393
- "version": "6.24.1",
394
- "resolved": "https://registry.npmjs.org/babel-plugin-transform-async-to-generator/-/babel-plugin-transform-async-to-generator-6.24.1.tgz",
395
- "integrity": "sha1-ZTbjeK/2yx1VF6wOQOs+n8jQh2E=",
396
- "dev": true,
397
- "requires": {
398
- "babel-helper-remap-async-to-generator": "6.24.1",
399
- "babel-plugin-syntax-async-functions": "6.13.0",
400
- "babel-runtime": "6.26.0"
401
- }
402
- },
403
- "babel-plugin-transform-es2015-arrow-functions": {
404
- "version": "6.22.0",
405
- "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz",
406
- "integrity": "sha1-RSaSy3EdX3ncf4XkQM5BufJE0iE=",
407
- "dev": true,
408
- "requires": {
409
- "babel-runtime": "6.26.0"
410
- }
411
- },
412
- "babel-plugin-transform-es2015-block-scoped-functions": {
413
- "version": "6.22.0",
414
- "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoped-functions/-/babel-plugin-transform-es2015-block-scoped-functions-6.22.0.tgz",
415
- "integrity": "sha1-u8UbSflk1wy42OC5ToICRs46YUE=",
416
- "dev": true,
417
- "requires": {
418
- "babel-runtime": "6.26.0"
419
- }
420
- },
421
- "babel-plugin-transform-es2015-block-scoping": {
422
- "version": "6.26.0",
423
- "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.26.0.tgz",
424
- "integrity": "sha1-1w9SmcEwjQXBL0Y4E7CgnnOxiV8=",
425
- "dev": true,
426
- "requires": {
427
- "babel-runtime": "6.26.0",
428
- "babel-template": "6.26.0",
429
- "babel-traverse": "6.26.0",
430
- "babel-types": "6.26.0",
431
- "lodash": "4.17.4"
432
- }
433
- },
434
- "babel-plugin-transform-es2015-classes": {
435
- "version": "6.24.1",
436
- "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-classes/-/babel-plugin-transform-es2015-classes-6.24.1.tgz",
437
- "integrity": "sha1-WkxYpQyclGHlZLSyo7+ryXolhNs=",
438
- "dev": true,
439
- "requires": {
440
- "babel-helper-define-map": "6.26.0",
441
- "babel-helper-function-name": "6.24.1",
442
- "babel-helper-optimise-call-expression": "6.24.1",
443
- "babel-helper-replace-supers": "6.24.1",
444
- "babel-messages": "6.23.0",
445
- "babel-runtime": "6.26.0",
446
- "babel-template": "6.26.0",
447
- "babel-traverse": "6.26.0",
448
- "babel-types": "6.26.0"
449
- }
450
- },
451
- "babel-plugin-transform-es2015-computed-properties": {
452
- "version": "6.24.1",
453
- "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-computed-properties/-/babel-plugin-transform-es2015-computed-properties-6.24.1.tgz",
454
- "integrity": "sha1-b+Ko0WiV1WNPTNmZttNICjCBWbM=",
455
- "dev": true,
456
- "requires": {
457
- "babel-runtime": "6.26.0",
458
- "babel-template": "6.26.0"
459
- }
460
- },
461
- "babel-plugin-transform-es2015-destructuring": {
462
- "version": "6.23.0",
463
- "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-6.23.0.tgz",
464
- "integrity": "sha1-mXux8auWf2gtKwh2/jWNYOdlxW0=",
465
- "dev": true,
466
- "requires": {
467
- "babel-runtime": "6.26.0"
468
- }
469
- },
470
- "babel-plugin-transform-es2015-duplicate-keys": {
471
- "version": "6.24.1",
472
- "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-duplicate-keys/-/babel-plugin-transform-es2015-duplicate-keys-6.24.1.tgz",
473
- "integrity": "sha1-c+s9MQypaePvnskcU3QabxV2Qj4=",
474
- "dev": true,
475
- "requires": {
476
- "babel-runtime": "6.26.0",
477
- "babel-types": "6.26.0"
478
- }
479
- },
480
- "babel-plugin-transform-es2015-for-of": {
481
- "version": "6.23.0",
482
- "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-for-of/-/babel-plugin-transform-es2015-for-of-6.23.0.tgz",
483
- "integrity": "sha1-9HyVsrYT3x0+zC/bdXNiPHUkhpE=",
484
- "dev": true,
485
- "requires": {
486
- "babel-runtime": "6.26.0"
487
- }
488
- },
489
- "babel-plugin-transform-es2015-function-name": {
490
- "version": "6.24.1",
491
- "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-function-name/-/babel-plugin-transform-es2015-function-name-6.24.1.tgz",
492
- "integrity": "sha1-g0yJhTvDaxrw86TF26qU/Y6sqos=",
493
- "dev": true,
494
- "requires": {
495
- "babel-helper-function-name": "6.24.1",
496
- "babel-runtime": "6.26.0",
497
- "babel-types": "6.26.0"
498
- }
499
- },
500
- "babel-plugin-transform-es2015-literals": {
501
- "version": "6.22.0",
502
- "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-literals/-/babel-plugin-transform-es2015-literals-6.22.0.tgz",
503
- "integrity": "sha1-T1SgLWzWbPkVKAAZox0xklN3yi4=",
504
- "dev": true,
505
- "requires": {
506
- "babel-runtime": "6.26.0"
507
- }
508
- },
509
- "babel-plugin-transform-es2015-modules-amd": {
510
- "version": "6.24.1",
511
- "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-amd/-/babel-plugin-transform-es2015-modules-amd-6.24.1.tgz",
512
- "integrity": "sha1-Oz5UAXI5hC1tGcMBHEvS8AoA0VQ=",
513
- "dev": true,
514
- "requires": {
515
- "babel-plugin-transform-es2015-modules-commonjs": "6.26.0",
516
- "babel-runtime": "6.26.0",
517
- "babel-template": "6.26.0"
518
- }
519
- },
520
- "babel-plugin-transform-es2015-modules-commonjs": {
521
- "version": "6.26.0",
522
- "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.26.0.tgz",
523
- "integrity": "sha1-DYOUApt9xqvhqX7xgeAHWN0uXYo=",
524
- "dev": true,
525
- "requires": {
526
- "babel-plugin-transform-strict-mode": "6.24.1",
527
- "babel-runtime": "6.26.0",
528
- "babel-template": "6.26.0",
529
- "babel-types": "6.26.0"
530
- }
531
- },
532
- "babel-plugin-transform-es2015-modules-systemjs": {
533
- "version": "6.24.1",
534
- "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-systemjs/-/babel-plugin-transform-es2015-modules-systemjs-6.24.1.tgz",
535
- "integrity": "sha1-/4mhQrkRmpBhlfXxBuzzBdlAfSM=",
536
- "dev": true,
537
- "requires": {
538
- "babel-helper-hoist-variables": "6.24.1",
539
- "babel-runtime": "6.26.0",
540
- "babel-template": "6.26.0"
541
- }
542
- },
543
- "babel-plugin-transform-es2015-modules-umd": {
544
- "version": "6.24.1",
545
- "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-umd/-/babel-plugin-transform-es2015-modules-umd-6.24.1.tgz",
546
- "integrity": "sha1-rJl+YoXNGO1hdq22B9YCNErThGg=",
547
- "dev": true,
548
- "requires": {
549
- "babel-plugin-transform-es2015-modules-amd": "6.24.1",
550
- "babel-runtime": "6.26.0",
551
- "babel-template": "6.26.0"
552
- }
553
- },
554
- "babel-plugin-transform-es2015-object-super": {
555
- "version": "6.24.1",
556
- "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-object-super/-/babel-plugin-transform-es2015-object-super-6.24.1.tgz",
557
- "integrity": "sha1-JM72muIcuDp/hgPa0CH1cusnj40=",
558
- "dev": true,
559
- "requires": {
560
- "babel-helper-replace-supers": "6.24.1",
561
- "babel-runtime": "6.26.0"
562
- }
563
- },
564
- "babel-plugin-transform-es2015-parameters": {
565
- "version": "6.24.1",
566
- "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-6.24.1.tgz",
567
- "integrity": "sha1-V6w1GrScrxSpfNE7CfZv3wpiXys=",
568
- "dev": true,
569
- "requires": {
570
- "babel-helper-call-delegate": "6.24.1",
571
- "babel-helper-get-function-arity": "6.24.1",
572
- "babel-runtime": "6.26.0",
573
- "babel-template": "6.26.0",
574
- "babel-traverse": "6.26.0",
575
- "babel-types": "6.26.0"
576
- }
577
- },
578
- "babel-plugin-transform-es2015-shorthand-properties": {
579
- "version": "6.24.1",
580
- "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-shorthand-properties/-/babel-plugin-transform-es2015-shorthand-properties-6.24.1.tgz",
581
- "integrity": "sha1-JPh11nIch2YbvZmkYi5R8U3jiqA=",
582
- "dev": true,
583
- "requires": {
584
- "babel-runtime": "6.26.0",
585
- "babel-types": "6.26.0"
586
- }
587
- },
588
- "babel-plugin-transform-es2015-spread": {
589
- "version": "6.22.0",
590
- "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-spread/-/babel-plugin-transform-es2015-spread-6.22.0.tgz",
591
- "integrity": "sha1-1taKmfia7cRTbIGlQujdnxdG+NE=",
592
- "dev": true,
593
- "requires": {
594
- "babel-runtime": "6.26.0"
595
- }
596
- },
597
- "babel-plugin-transform-es2015-sticky-regex": {
598
- "version": "6.24.1",
599
- "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-sticky-regex/-/babel-plugin-transform-es2015-sticky-regex-6.24.1.tgz",
600
- "integrity": "sha1-AMHNsaynERLN8M9hJsLta0V8zbw=",
601
- "dev": true,
602
- "requires": {
603
- "babel-helper-regex": "6.26.0",
604
- "babel-runtime": "6.26.0",
605
- "babel-types": "6.26.0"
606
- }
607
- },
608
- "babel-plugin-transform-es2015-template-literals": {
609
- "version": "6.22.0",
610
- "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-template-literals/-/babel-plugin-transform-es2015-template-literals-6.22.0.tgz",
611
- "integrity": "sha1-qEs0UPfp+PH2g51taH2oS7EjbY0=",
612
- "dev": true,
613
- "requires": {
614
- "babel-runtime": "6.26.0"
615
- }
616
- },
617
- "babel-plugin-transform-es2015-typeof-symbol": {
618
- "version": "6.23.0",
619
- "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-typeof-symbol/-/babel-plugin-transform-es2015-typeof-symbol-6.23.0.tgz",
620
- "integrity": "sha1-3sCfHN3/lLUqxz1QXITfWdzOs3I=",
621
- "dev": true,
622
- "requires": {
623
- "babel-runtime": "6.26.0"
624
- }
625
- },
626
- "babel-plugin-transform-es2015-unicode-regex": {
627
- "version": "6.24.1",
628
- "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-unicode-regex/-/babel-plugin-transform-es2015-unicode-regex-6.24.1.tgz",
629
- "integrity": "sha1-04sS9C6nMj9yk4fxinxa4frrNek=",
630
- "dev": true,
631
- "requires": {
632
- "babel-helper-regex": "6.26.0",
633
- "babel-runtime": "6.26.0",
634
- "regexpu-core": "2.0.0"
635
- }
636
- },
637
- "babel-plugin-transform-exponentiation-operator": {
638
- "version": "6.24.1",
639
- "resolved": "https://registry.npmjs.org/babel-plugin-transform-exponentiation-operator/-/babel-plugin-transform-exponentiation-operator-6.24.1.tgz",
640
- "integrity": "sha1-KrDJx/MJj6SJB3cruBP+QejeOg4=",
641
- "dev": true,
642
- "requires": {
643
- "babel-helper-builder-binary-assignment-operator-visitor": "6.24.1",
644
- "babel-plugin-syntax-exponentiation-operator": "6.13.0",
645
- "babel-runtime": "6.26.0"
646
- }
647
- },
648
- "babel-plugin-transform-react-jsx": {
649
- "version": "6.24.1",
650
- "resolved": "https://registry.npmjs.org/babel-plugin-transform-react-jsx/-/babel-plugin-transform-react-jsx-6.24.1.tgz",
651
- "integrity": "sha1-hAoCjn30YN/DotKfDA2R9jduZqM=",
652
- "dev": true,
653
- "requires": {
654
- "babel-helper-builder-react-jsx": "6.26.0",
655
- "babel-plugin-syntax-jsx": "6.18.0",
656
- "babel-runtime": "6.26.0"
657
- }
658
- },
659
- "babel-plugin-transform-regenerator": {
660
- "version": "6.26.0",
661
- "resolved": "https://registry.npmjs.org/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.26.0.tgz",
662
- "integrity": "sha1-4HA2lvveJ/Cj78rPi03KL3s6jy8=",
663
- "dev": true,
664
- "requires": {
665
- "regenerator-transform": "0.10.1"
666
- }
667
- },
668
- "babel-plugin-transform-strict-mode": {
669
- "version": "6.24.1",
670
- "resolved": "https://registry.npmjs.org/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.24.1.tgz",
671
- "integrity": "sha1-1fr3qleKZbvlkc9e2uBKDGcCB1g=",
672
- "dev": true,
673
- "requires": {
674
- "babel-runtime": "6.26.0",
675
- "babel-types": "6.26.0"
676
- }
677
- },
678
- "babel-preset-env": {
679
- "version": "1.6.1",
680
- "resolved": "https://registry.npmjs.org/babel-preset-env/-/babel-preset-env-1.6.1.tgz",
681
- "integrity": "sha512-W6VIyA6Ch9ePMI7VptNn2wBM6dbG0eSz25HEiL40nQXCsXGTGZSTZu1Iap+cj3Q0S5a7T9+529l/5Bkvd+afNA==",
682
- "dev": true,
683
- "requires": {
684
- "babel-plugin-check-es2015-constants": "6.22.0",
685
- "babel-plugin-syntax-trailing-function-commas": "6.22.0",
686
- "babel-plugin-transform-async-to-generator": "6.24.1",
687
- "babel-plugin-transform-es2015-arrow-functions": "6.22.0",
688
- "babel-plugin-transform-es2015-block-scoped-functions": "6.22.0",
689
- "babel-plugin-transform-es2015-block-scoping": "6.26.0",
690
- "babel-plugin-transform-es2015-classes": "6.24.1",
691
- "babel-plugin-transform-es2015-computed-properties": "6.24.1",
692
- "babel-plugin-transform-es2015-destructuring": "6.23.0",
693
- "babel-plugin-transform-es2015-duplicate-keys": "6.24.1",
694
- "babel-plugin-transform-es2015-for-of": "6.23.0",
695
- "babel-plugin-transform-es2015-function-name": "6.24.1",
696
- "babel-plugin-transform-es2015-literals": "6.22.0",
697
- "babel-plugin-transform-es2015-modules-amd": "6.24.1",
698
- "babel-plugin-transform-es2015-modules-commonjs": "6.26.0",
699
- "babel-plugin-transform-es2015-modules-systemjs": "6.24.1",
700
- "babel-plugin-transform-es2015-modules-umd": "6.24.1",
701
- "babel-plugin-transform-es2015-object-super": "6.24.1",
702
- "babel-plugin-transform-es2015-parameters": "6.24.1",
703
- "babel-plugin-transform-es2015-shorthand-properties": "6.24.1",
704
- "babel-plugin-transform-es2015-spread": "6.22.0",
705
- "babel-plugin-transform-es2015-sticky-regex": "6.24.1",
706
- "babel-plugin-transform-es2015-template-literals": "6.22.0",
707
- "babel-plugin-transform-es2015-typeof-symbol": "6.23.0",
708
- "babel-plugin-transform-es2015-unicode-regex": "6.24.1",
709
- "babel-plugin-transform-exponentiation-operator": "6.24.1",
710
- "babel-plugin-transform-regenerator": "6.26.0",
711
- "browserslist": "2.10.0",
712
- "invariant": "2.2.2",
713
- "semver": "5.4.1"
714
- }
715
- },
716
- "babel-register": {
717
- "version": "6.26.0",
718
- "resolved": "https://registry.npmjs.org/babel-register/-/babel-register-6.26.0.tgz",
719
- "integrity": "sha1-btAhFz4vy0htestFxgCahW9kcHE=",
720
- "dev": true,
721
- "requires": {
722
- "babel-core": "6.26.0",
723
- "babel-runtime": "6.26.0",
724
- "core-js": "2.5.3",
725
- "home-or-tmp": "2.0.0",
726
- "lodash": "4.17.4",
727
- "mkdirp": "0.5.1",
728
- "source-map-support": "0.4.18"
729
- }
730
- },
731
- "babel-runtime": {
732
- "version": "6.26.0",
733
- "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz",
734
- "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=",
735
- "dev": true,
736
- "requires": {
737
- "core-js": "2.5.3",
738
- "regenerator-runtime": "0.11.1"
739
- }
740
- },
741
- "babel-template": {
742
- "version": "6.26.0",
743
- "resolved": "https://registry.npmjs.org/babel-template/-/babel-template-6.26.0.tgz",
744
- "integrity": "sha1-3gPi0WOWsGn0bdn/+FIfsaDjXgI=",
745
- "dev": true,
746
- "requires": {
747
- "babel-runtime": "6.26.0",
748
- "babel-traverse": "6.26.0",
749
- "babel-types": "6.26.0",
750
- "babylon": "6.18.0",
751
- "lodash": "4.17.4"
752
- }
753
- },
754
- "babel-traverse": {
755
- "version": "6.26.0",
756
- "resolved": "https://registry.npmjs.org/babel-traverse/-/babel-traverse-6.26.0.tgz",
757
- "integrity": "sha1-RqnL1+3MYsjlwGTi0tjQ9ANXZu4=",
758
- "dev": true,
759
- "requires": {
760
- "babel-code-frame": "6.26.0",
761
- "babel-messages": "6.23.0",
762
- "babel-runtime": "6.26.0",
763
- "babel-types": "6.26.0",
764
- "babylon": "6.18.0",
765
- "debug": "2.6.9",
766
- "globals": "9.18.0",
767
- "invariant": "2.2.2",
768
- "lodash": "4.17.4"
769
- }
770
- },
771
- "babel-types": {
772
- "version": "6.26.0",
773
- "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.26.0.tgz",
774
- "integrity": "sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc=",
775
- "dev": true,
776
- "requires": {
777
- "babel-runtime": "6.26.0",
778
- "esutils": "2.0.2",
779
- "lodash": "4.17.4",
780
- "to-fast-properties": "1.0.3"
781
- }
782
- },
783
- "babylon": {
784
- "version": "6.18.0",
785
- "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz",
786
- "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==",
787
- "dev": true
788
- },
789
- "balanced-match": {
790
- "version": "1.0.0",
791
- "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
792
- "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
793
- "dev": true
794
- },
795
- "base64-js": {
796
- "version": "1.2.1",
797
- "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.2.1.tgz",
798
- "integrity": "sha512-dwVUVIXsBZXwTuwnXI9RK8sBmgq09NDHzyR9SAph9eqk76gKK2JSQmZARC2zRC81JC2QTtxD0ARU5qTS25gIGw==",
799
- "dev": true
800
- },
801
- "big.js": {
802
- "version": "3.2.0",
803
- "resolved": "https://registry.npmjs.org/big.js/-/big.js-3.2.0.tgz",
804
- "integrity": "sha512-+hN/Zh2D08Mx65pZ/4g5bsmNiZUuChDiQfTUQ7qJr4/kuopCr88xZsAXv6mBoZEsUI4OuGHlX59qE94K2mMW8Q==",
805
- "dev": true
806
- },
807
- "binary-extensions": {
808
- "version": "1.11.0",
809
- "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.11.0.tgz",
810
- "integrity": "sha1-RqoXUftqL5PuXmibsQh9SxTGwgU=",
811
- "dev": true
812
- },
813
- "bn.js": {
814
- "version": "4.11.8",
815
- "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz",
816
- "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==",
817
- "dev": true
818
- },
819
- "brace-expansion": {
820
- "version": "1.1.8",
821
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz",
822
- "integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=",
823
- "dev": true,
824
- "requires": {
825
- "balanced-match": "1.0.0",
826
- "concat-map": "0.0.1"
827
- }
828
- },
829
- "braces": {
830
- "version": "1.8.5",
831
- "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz",
832
- "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=",
833
- "dev": true,
834
- "requires": {
835
- "expand-range": "1.8.2",
836
- "preserve": "0.2.0",
837
- "repeat-element": "1.1.2"
838
- }
839
- },
840
- "brorand": {
841
- "version": "1.1.0",
842
- "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz",
843
- "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=",
844
- "dev": true
845
- },
846
- "browserify-aes": {
847
- "version": "1.1.1",
848
- "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.1.1.tgz",
849
- "integrity": "sha512-UGnTYAnB2a3YuYKIRy1/4FB2HdM866E0qC46JXvVTYKlBlZlnvfpSfY6OKfXZAkv70eJ2a1SqzpAo5CRhZGDFg==",
850
- "dev": true,
851
- "requires": {
852
- "buffer-xor": "1.0.3",
853
- "cipher-base": "1.0.4",
854
- "create-hash": "1.1.3",
855
- "evp_bytestokey": "1.0.3",
856
- "inherits": "2.0.3",
857
- "safe-buffer": "5.1.1"
858
- }
859
- },
860
- "browserify-cipher": {
861
- "version": "1.0.0",
862
- "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.0.tgz",
863
- "integrity": "sha1-mYgkSHS/XtTijalWZtzWasj8Njo=",
864
- "dev": true,
865
- "requires": {
866
- "browserify-aes": "1.1.1",
867
- "browserify-des": "1.0.0",
868
- "evp_bytestokey": "1.0.3"
869
- }
870
- },
871
- "browserify-des": {
872
- "version": "1.0.0",
873
- "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.0.tgz",
874
- "integrity": "sha1-2qJ3cXRwki7S/hhZQRihdUOXId0=",
875
- "dev": true,
876
- "requires": {
877
- "cipher-base": "1.0.4",
878
- "des.js": "1.0.0",
879
- "inherits": "2.0.3"
880
- }
881
- },
882
- "browserify-rsa": {
883
- "version": "4.0.1",
884
- "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz",
885
- "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=",
886
- "dev": true,
887
- "requires": {
888
- "bn.js": "4.11.8",
889
- "randombytes": "2.0.5"
890
- }
891
- },
892
- "browserify-sign": {
893
- "version": "4.0.4",
894
- "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.0.4.tgz",
895
- "integrity": "sha1-qk62jl17ZYuqa/alfmMMvXqT0pg=",
896
- "dev": true,
897
- "requires": {
898
- "bn.js": "4.11.8",
899
- "browserify-rsa": "4.0.1",
900
- "create-hash": "1.1.3",
901
- "create-hmac": "1.1.6",
902
- "elliptic": "6.4.0",
903
- "inherits": "2.0.3",
904
- "parse-asn1": "5.1.0"
905
- }
906
- },
907
- "browserify-zlib": {
908
- "version": "0.2.0",
909
- "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz",
910
- "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==",
911
- "dev": true,
912
- "requires": {
913
- "pako": "1.0.6"
914
- }
915
- },
916
- "browserslist": {
917
- "version": "2.10.0",
918
- "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-2.10.0.tgz",
919
- "integrity": "sha512-WyvzSLsuAVPOjbljXnyeWl14Ae+ukAT8MUuagKVzIDvwBxl4UAwD1xqtyQs2eWYPGUKMeC3Ol62goqYuKqTTcw==",
920
- "dev": true,
921
- "requires": {
922
- "caniuse-lite": "1.0.30000783",
923
- "electron-to-chromium": "1.3.28"
924
- }
925
- },
926
- "buffer": {
927
- "version": "4.9.1",
928
- "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.1.tgz",
929
- "integrity": "sha1-bRu2AbB6TvztlwlBMgkwJ8lbwpg=",
930
- "dev": true,
931
- "requires": {
932
- "base64-js": "1.2.1",
933
- "ieee754": "1.1.8",
934
- "isarray": "1.0.0"
935
- }
936
- },
937
- "buffer-xor": {
938
- "version": "1.0.3",
939
- "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz",
940
- "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=",
941
- "dev": true
942
- },
943
- "builtin-modules": {
944
- "version": "1.1.1",
945
- "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz",
946
- "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=",
947
- "dev": true
948
- },
949
- "builtin-status-codes": {
950
- "version": "3.0.0",
951
- "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz",
952
- "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=",
953
- "dev": true
954
- },
955
- "camelcase": {
956
- "version": "1.2.1",
957
- "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz",
958
- "integrity": "sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk=",
959
- "dev": true
960
- },
961
- "caniuse-lite": {
962
- "version": "1.0.30000783",
963
- "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000783.tgz",
964
- "integrity": "sha1-m1SZ+xtQPSNF0SqmuGEoUvQnb/0=",
965
- "dev": true
966
- },
967
- "center-align": {
968
- "version": "0.1.3",
969
- "resolved": "https://registry.npmjs.org/center-align/-/center-align-0.1.3.tgz",
970
- "integrity": "sha1-qg0yYptu6XIgBBHL1EYckHvCt60=",
971
- "dev": true,
972
- "requires": {
973
- "align-text": "0.1.4",
974
- "lazy-cache": "1.0.4"
975
- }
976
- },
977
- "chalk": {
978
- "version": "1.1.3",
979
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
980
- "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
981
- "dev": true,
982
- "requires": {
983
- "ansi-styles": "2.2.1",
984
- "escape-string-regexp": "1.0.5",
985
- "has-ansi": "2.0.0",
986
- "strip-ansi": "3.0.1",
987
- "supports-color": "2.0.0"
988
- }
989
- },
990
- "chokidar": {
991
- "version": "1.7.0",
992
- "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-1.7.0.tgz",
993
- "integrity": "sha1-eY5ol3gVHIB2tLNg5e3SjNortGg=",
994
- "dev": true,
995
- "requires": {
996
- "anymatch": "1.3.2",
997
- "async-each": "1.0.1",
998
- "fsevents": "1.1.3",
999
- "glob-parent": "2.0.0",
1000
- "inherits": "2.0.3",
1001
- "is-binary-path": "1.0.1",
1002
- "is-glob": "2.0.1",
1003
- "path-is-absolute": "1.0.1",
1004
- "readdirp": "2.1.0"
1005
- }
1006
- },
1007
- "cipher-base": {
1008
- "version": "1.0.4",
1009
- "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz",
1010
- "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==",
1011
- "dev": true,
1012
- "requires": {
1013
- "inherits": "2.0.3",
1014
- "safe-buffer": "5.1.1"
1015
- }
1016
- },
1017
- "cliui": {
1018
- "version": "2.1.0",
1019
- "resolved": "https://registry.npmjs.org/cliui/-/cliui-2.1.0.tgz",
1020
- "integrity": "sha1-S0dXYP+AJkx2LDoXGQMukcf+oNE=",
1021
- "dev": true,
1022
- "requires": {
1023
- "center-align": "0.1.3",
1024
- "right-align": "0.1.3",
1025
- "wordwrap": "0.0.2"
1026
- }
1027
- },
1028
- "co": {
1029
- "version": "4.6.0",
1030
- "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz",
1031
- "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=",
1032
- "dev": true
1033
- },
1034
- "code-point-at": {
1035
- "version": "1.1.0",
1036
- "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz",
1037
- "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=",
1038
- "dev": true
1039
- },
1040
- "commondir": {
1041
- "version": "1.0.1",
1042
- "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz",
1043
- "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=",
1044
- "dev": true
1045
- },
1046
- "concat-map": {
1047
- "version": "0.0.1",
1048
- "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
1049
- "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
1050
- "dev": true
1051
- },
1052
- "console-browserify": {
1053
- "version": "1.1.0",
1054
- "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.1.0.tgz",
1055
- "integrity": "sha1-8CQcRXMKn8YyOyBtvzjtx0HQuxA=",
1056
- "dev": true,
1057
- "requires": {
1058
- "date-now": "0.1.4"
1059
- }
1060
- },
1061
- "constants-browserify": {
1062
- "version": "1.0.0",
1063
- "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz",
1064
- "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=",
1065
- "dev": true
1066
- },
1067
- "convert-source-map": {
1068
- "version": "1.5.1",
1069
- "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.5.1.tgz",
1070
- "integrity": "sha1-uCeAl7m8IpNl3lxiz1/K7YtVmeU=",
1071
- "dev": true
1072
- },
1073
- "core-js": {
1074
- "version": "2.5.3",
1075
- "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.5.3.tgz",
1076
- "integrity": "sha1-isw4NFgk8W2DZbfJtCWRaOjtYD4=",
1077
- "dev": true
1078
- },
1079
- "core-util-is": {
1080
- "version": "1.0.2",
1081
- "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
1082
- "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=",
1083
- "dev": true
1084
- },
1085
- "create-ecdh": {
1086
- "version": "4.0.0",
1087
- "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.0.tgz",
1088
- "integrity": "sha1-iIxyNZbN92EvZJgjPuvXo1MBc30=",
1089
- "dev": true,
1090
- "requires": {
1091
- "bn.js": "4.11.8",
1092
- "elliptic": "6.4.0"
1093
- }
1094
- },
1095
- "create-hash": {
1096
- "version": "1.1.3",
1097
- "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.1.3.tgz",
1098
- "integrity": "sha1-YGBCrIuSYnUPSDyt2rD1gZFy2P0=",
1099
- "dev": true,
1100
- "requires": {
1101
- "cipher-base": "1.0.4",
1102
- "inherits": "2.0.3",
1103
- "ripemd160": "2.0.1",
1104
- "sha.js": "2.4.9"
1105
- }
1106
- },
1107
- "create-hmac": {
1108
- "version": "1.1.6",
1109
- "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.6.tgz",
1110
- "integrity": "sha1-rLniIaThe9sHbpBlfEK5PjcmzwY=",
1111
- "dev": true,
1112
- "requires": {
1113
- "cipher-base": "1.0.4",
1114
- "create-hash": "1.1.3",
1115
- "inherits": "2.0.3",
1116
- "ripemd160": "2.0.1",
1117
- "safe-buffer": "5.1.1",
1118
- "sha.js": "2.4.9"
1119
- }
1120
- },
1121
- "cross-env": {
1122
- "version": "5.1.1",
1123
- "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-5.1.1.tgz",
1124
- "integrity": "sha512-Wtvr+z0Z06KO1JxjfRRsPC+df7biIOiuV4iZ73cThjFGkH+ULBZq1MkBdywEcJC4cTDbO6c8IjgRjfswx3YTBA==",
1125
- "dev": true,
1126
- "requires": {
1127
- "cross-spawn": "5.1.0",
1128
- "is-windows": "1.0.1"
1129
- }
1130
- },
1131
- "cross-spawn": {
1132
- "version": "5.1.0",
1133
- "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz",
1134
- "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=",
1135
- "dev": true,
1136
- "requires": {
1137
- "lru-cache": "4.1.1",
1138
- "shebang-command": "1.2.0",
1139
- "which": "1.3.0"
1140
- }
1141
- },
1142
- "crypto-browserify": {
1143
- "version": "3.12.0",
1144
- "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz",
1145
- "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==",
1146
- "dev": true,
1147
- "requires": {
1148
- "browserify-cipher": "1.0.0",
1149
- "browserify-sign": "4.0.4",
1150
- "create-ecdh": "4.0.0",
1151
- "create-hash": "1.1.3",
1152
- "create-hmac": "1.1.6",
1153
- "diffie-hellman": "5.0.2",
1154
- "inherits": "2.0.3",
1155
- "pbkdf2": "3.0.14",
1156
- "public-encrypt": "4.0.0",
1157
- "randombytes": "2.0.5",
1158
- "randomfill": "1.0.3"
1159
- }
1160
- },
1161
- "d": {
1162
- "version": "1.0.0",
1163
- "resolved": "https://registry.npmjs.org/d/-/d-1.0.0.tgz",
1164
- "integrity": "sha1-dUu1v+VUUdpppYuU1F9MWwRi1Y8=",
1165
- "dev": true,
1166
- "requires": {
1167
- "es5-ext": "0.10.37"
1168
- }
1169
- },
1170
- "date-now": {
1171
- "version": "0.1.4",
1172
- "resolved": "https://registry.npmjs.org/date-now/-/date-now-0.1.4.tgz",
1173
- "integrity": "sha1-6vQ5/U1ISK105cx9vvIAZyueNFs=",
1174
- "dev": true
1175
- },
1176
- "debug": {
1177
- "version": "2.6.9",
1178
- "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
1179
- "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
1180
- "dev": true,
1181
- "requires": {
1182
- "ms": "2.0.0"
1183
- }
1184
- },
1185
- "decamelize": {
1186
- "version": "1.2.0",
1187
- "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
1188
- "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=",
1189
- "dev": true
1190
- },
1191
- "des.js": {
1192
- "version": "1.0.0",
1193
- "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.0.tgz",
1194
- "integrity": "sha1-wHTS4qpqipoH29YfmhXCzYPsjsw=",
1195
- "dev": true,
1196
- "requires": {
1197
- "inherits": "2.0.3",
1198
- "minimalistic-assert": "1.0.0"
1199
- }
1200
- },
1201
- "detect-indent": {
1202
- "version": "4.0.0",
1203
- "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-4.0.0.tgz",
1204
- "integrity": "sha1-920GQ1LN9Docts5hnE7jqUdd4gg=",
1205
- "dev": true,
1206
- "requires": {
1207
- "repeating": "2.0.1"
1208
- }
1209
- },
1210
- "diffie-hellman": {
1211
- "version": "5.0.2",
1212
- "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.2.tgz",
1213
- "integrity": "sha1-tYNXOScM/ias9jIJn97SoH8gnl4=",
1214
- "dev": true,
1215
- "requires": {
1216
- "bn.js": "4.11.8",
1217
- "miller-rabin": "4.0.1",
1218
- "randombytes": "2.0.5"
1219
- }
1220
- },
1221
- "domain-browser": {
1222
- "version": "1.1.7",
1223
- "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.1.7.tgz",
1224
- "integrity": "sha1-hnqksJP6oF8d4IwG9NeyH9+GmLw=",
1225
- "dev": true
1226
- },
1227
- "electron-to-chromium": {
1228
- "version": "1.3.28",
1229
- "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.28.tgz",
1230
- "integrity": "sha1-jdTmRYCGZE6fnwoc8y4qH53/2e4=",
1231
- "dev": true
1232
- },
1233
- "elliptic": {
1234
- "version": "6.4.0",
1235
- "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.4.0.tgz",
1236
- "integrity": "sha1-ysmvh2LIWDYYcAPI3+GT5eLq5d8=",
1237
- "dev": true,
1238
- "requires": {
1239
- "bn.js": "4.11.8",
1240
- "brorand": "1.1.0",
1241
- "hash.js": "1.1.3",
1242
- "hmac-drbg": "1.0.1",
1243
- "inherits": "2.0.3",
1244
- "minimalistic-assert": "1.0.0",
1245
- "minimalistic-crypto-utils": "1.0.1"
1246
- }
1247
- },
1248
- "emojis-list": {
1249
- "version": "2.1.0",
1250
- "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-2.1.0.tgz",
1251
- "integrity": "sha1-TapNnbAPmBmIDHn6RXrlsJof04k=",
1252
- "dev": true
1253
- },
1254
- "enhanced-resolve": {
1255
- "version": "3.4.1",
1256
- "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-3.4.1.tgz",
1257
- "integrity": "sha1-BCHjOf1xQZs9oT0Smzl5BAIwR24=",
1258
- "dev": true,
1259
- "requires": {
1260
- "graceful-fs": "4.1.11",
1261
- "memory-fs": "0.4.1",
1262
- "object-assign": "4.1.1",
1263
- "tapable": "0.2.8"
1264
- }
1265
- },
1266
- "errno": {
1267
- "version": "0.1.6",
1268
- "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.6.tgz",
1269
- "integrity": "sha512-IsORQDpaaSwcDP4ZZnHxgE85werpo34VYn1Ud3mq+eUsF593faR8oCZNXrROVkpFu2TsbrNhHin0aUrTsQ9vNw==",
1270
- "dev": true,
1271
- "requires": {
1272
- "prr": "1.0.1"
1273
- }
1274
- },
1275
- "error-ex": {
1276
- "version": "1.3.1",
1277
- "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.1.tgz",
1278
- "integrity": "sha1-+FWobOYa3E6GIcPNoh56dhLDqNw=",
1279
- "dev": true,
1280
- "requires": {
1281
- "is-arrayish": "0.2.1"
1282
- }
1283
- },
1284
- "es5-ext": {
1285
- "version": "0.10.37",
1286
- "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.37.tgz",
1287
- "integrity": "sha1-DudB0Ui4AGm6J9AgOTdWryV978M=",
1288
- "dev": true,
1289
- "requires": {
1290
- "es6-iterator": "2.0.3",
1291
- "es6-symbol": "3.1.1"
1292
- }
1293
- },
1294
- "es6-iterator": {
1295
- "version": "2.0.3",
1296
- "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz",
1297
- "integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=",
1298
- "dev": true,
1299
- "requires": {
1300
- "d": "1.0.0",
1301
- "es5-ext": "0.10.37",
1302
- "es6-symbol": "3.1.1"
1303
- }
1304
- },
1305
- "es6-map": {
1306
- "version": "0.1.5",
1307
- "resolved": "https://registry.npmjs.org/es6-map/-/es6-map-0.1.5.tgz",
1308
- "integrity": "sha1-kTbgUD3MBqMBaQ8LsU/042TpSfA=",
1309
- "dev": true,
1310
- "requires": {
1311
- "d": "1.0.0",
1312
- "es5-ext": "0.10.37",
1313
- "es6-iterator": "2.0.3",
1314
- "es6-set": "0.1.5",
1315
- "es6-symbol": "3.1.1",
1316
- "event-emitter": "0.3.5"
1317
- }
1318
- },
1319
- "es6-set": {
1320
- "version": "0.1.5",
1321
- "resolved": "https://registry.npmjs.org/es6-set/-/es6-set-0.1.5.tgz",
1322
- "integrity": "sha1-0rPsXU2ADO2BjbU40ol02wpzzLE=",
1323
- "dev": true,
1324
- "requires": {
1325
- "d": "1.0.0",
1326
- "es5-ext": "0.10.37",
1327
- "es6-iterator": "2.0.3",
1328
- "es6-symbol": "3.1.1",
1329
- "event-emitter": "0.3.5"
1330
- }
1331
- },
1332
- "es6-symbol": {
1333
- "version": "3.1.1",
1334
- "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.1.tgz",
1335
- "integrity": "sha1-vwDvT9q2uhtG7Le2KbTH7VcVzHc=",
1336
- "dev": true,
1337
- "requires": {
1338
- "d": "1.0.0",
1339
- "es5-ext": "0.10.37"
1340
- }
1341
- },
1342
- "es6-weak-map": {
1343
- "version": "2.0.2",
1344
- "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.2.tgz",
1345
- "integrity": "sha1-XjqzIlH/0VOKH45f+hNXdy+S2W8=",
1346
- "dev": true,
1347
- "requires": {
1348
- "d": "1.0.0",
1349
- "es5-ext": "0.10.37",
1350
- "es6-iterator": "2.0.3",
1351
- "es6-symbol": "3.1.1"
1352
- }
1353
- },
1354
- "escape-string-regexp": {
1355
- "version": "1.0.5",
1356
- "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
1357
- "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
1358
- "dev": true
1359
- },
1360
- "escope": {
1361
- "version": "3.6.0",
1362
- "resolved": "https://registry.npmjs.org/escope/-/escope-3.6.0.tgz",
1363
- "integrity": "sha1-4Bl16BJ4GhY6ba392AOY3GTIicM=",
1364
- "dev": true,
1365
- "requires": {
1366
- "es6-map": "0.1.5",
1367
- "es6-weak-map": "2.0.2",
1368
- "esrecurse": "4.2.0",
1369
- "estraverse": "4.2.0"
1370
- }
1371
- },
1372
- "esrecurse": {
1373
- "version": "4.2.0",
1374
- "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.0.tgz",
1375
- "integrity": "sha1-+pVo2Y04I/mkHZHpAtyrnqblsWM=",
1376
- "dev": true,
1377
- "requires": {
1378
- "estraverse": "4.2.0",
1379
- "object-assign": "4.1.1"
1380
- }
1381
- },
1382
- "estraverse": {
1383
- "version": "4.2.0",
1384
- "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz",
1385
- "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=",
1386
- "dev": true
1387
- },
1388
- "esutils": {
1389
- "version": "2.0.2",
1390
- "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz",
1391
- "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=",
1392
- "dev": true
1393
- },
1394
- "event-emitter": {
1395
- "version": "0.3.5",
1396
- "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz",
1397
- "integrity": "sha1-34xp7vFkeSPHFXuc6DhAYQsCzDk=",
1398
- "dev": true,
1399
- "requires": {
1400
- "d": "1.0.0",
1401
- "es5-ext": "0.10.37"
1402
- }
1403
- },
1404
- "events": {
1405
- "version": "1.1.1",
1406
- "resolved": "https://registry.npmjs.org/events/-/events-1.1.1.tgz",
1407
- "integrity": "sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ=",
1408
- "dev": true
1409
- },
1410
- "evp_bytestokey": {
1411
- "version": "1.0.3",
1412
- "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz",
1413
- "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==",
1414
- "dev": true,
1415
- "requires": {
1416
- "md5.js": "1.3.4",
1417
- "safe-buffer": "5.1.1"
1418
- }
1419
- },
1420
- "execa": {
1421
- "version": "0.7.0",
1422
- "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz",
1423
- "integrity": "sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=",
1424
- "dev": true,
1425
- "requires": {
1426
- "cross-spawn": "5.1.0",
1427
- "get-stream": "3.0.0",
1428
- "is-stream": "1.1.0",
1429
- "npm-run-path": "2.0.2",
1430
- "p-finally": "1.0.0",
1431
- "signal-exit": "3.0.2",
1432
- "strip-eof": "1.0.0"
1433
- }
1434
- },
1435
- "expand-brackets": {
1436
- "version": "0.1.5",
1437
- "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz",
1438
- "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=",
1439
- "dev": true,
1440
- "requires": {
1441
- "is-posix-bracket": "0.1.1"
1442
- }
1443
- },
1444
- "expand-range": {
1445
- "version": "1.8.2",
1446
- "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz",
1447
- "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=",
1448
- "dev": true,
1449
- "requires": {
1450
- "fill-range": "2.2.3"
1451
- }
1452
- },
1453
- "extglob": {
1454
- "version": "0.3.2",
1455
- "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz",
1456
- "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=",
1457
- "dev": true,
1458
- "requires": {
1459
- "is-extglob": "1.0.0"
1460
- }
1461
- },
1462
- "fast-deep-equal": {
1463
- "version": "1.0.0",
1464
- "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.0.0.tgz",
1465
- "integrity": "sha1-liVqO8l1WV6zbYLpkp0GDYk0Of8=",
1466
- "dev": true
1467
- },
1468
- "fast-json-stable-stringify": {
1469
- "version": "2.0.0",
1470
- "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz",
1471
- "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=",
1472
- "dev": true
1473
- },
1474
- "filename-regex": {
1475
- "version": "2.0.1",
1476
- "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz",
1477
- "integrity": "sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY=",
1478
- "dev": true
1479
- },
1480
- "fill-range": {
1481
- "version": "2.2.3",
1482
- "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.3.tgz",
1483
- "integrity": "sha1-ULd9/X5Gm8dJJHCWNpn+eoSFpyM=",
1484
- "dev": true,
1485
- "requires": {
1486
- "is-number": "2.1.0",
1487
- "isobject": "2.1.0",
1488
- "randomatic": "1.1.7",
1489
- "repeat-element": "1.1.2",
1490
- "repeat-string": "1.6.1"
1491
- }
1492
- },
1493
- "find-cache-dir": {
1494
- "version": "1.0.0",
1495
- "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-1.0.0.tgz",
1496
- "integrity": "sha1-kojj6ePMN0hxfTnq3hfPcfww7m8=",
1497
- "dev": true,
1498
- "requires": {
1499
- "commondir": "1.0.1",
1500
- "make-dir": "1.1.0",
1501
- "pkg-dir": "2.0.0"
1502
- }
1503
- },
1504
- "find-up": {
1505
- "version": "2.1.0",
1506
- "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz",
1507
- "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=",
1508
- "dev": true,
1509
- "requires": {
1510
- "locate-path": "2.0.0"
1511
- }
1512
- },
1513
- "for-in": {
1514
- "version": "1.0.2",
1515
- "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz",
1516
- "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=",
1517
- "dev": true
1518
- },
1519
- "for-own": {
1520
- "version": "0.1.5",
1521
- "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz",
1522
- "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=",
1523
- "dev": true,
1524
- "requires": {
1525
- "for-in": "1.0.2"
1526
- }
1527
- },
1528
- "fsevents": {
1529
- "version": "1.1.3",
1530
- "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.1.3.tgz",
1531
- "integrity": "sha512-WIr7iDkdmdbxu/Gh6eKEZJL6KPE74/5MEsf2whTOFNxbIoIixogroLdKYqB6FDav4Wavh/lZdzzd3b2KxIXC5Q==",
1532
- "dev": true,
1533
- "optional": true,
1534
- "requires": {
1535
- "nan": "2.8.0",
1536
- "node-pre-gyp": "0.6.39"
1537
- },
1538
- "dependencies": {
1539
- "abbrev": {
1540
- "version": "1.1.0",
1541
- "bundled": true,
1542
- "dev": true,
1543
- "optional": true
1544
- },
1545
- "ajv": {
1546
- "version": "4.11.8",
1547
- "bundled": true,
1548
- "dev": true,
1549
- "optional": true,
1550
- "requires": {
1551
- "co": "4.6.0",
1552
- "json-stable-stringify": "1.0.1"
1553
- }
1554
- },
1555
- "ansi-regex": {
1556
- "version": "2.1.1",
1557
- "bundled": true,
1558
- "dev": true
1559
- },
1560
- "aproba": {
1561
- "version": "1.1.1",
1562
- "bundled": true,
1563
- "dev": true,
1564
- "optional": true
1565
- },
1566
- "are-we-there-yet": {
1567
- "version": "1.1.4",
1568
- "bundled": true,
1569
- "dev": true,
1570
- "optional": true,
1571
- "requires": {
1572
- "delegates": "1.0.0",
1573
- "readable-stream": "2.2.9"
1574
- }
1575
- },
1576
- "asn1": {
1577
- "version": "0.2.3",
1578
- "bundled": true,
1579
- "dev": true,
1580
- "optional": true
1581
- },
1582
- "assert-plus": {
1583
- "version": "0.2.0",
1584
- "bundled": true,
1585
- "dev": true,
1586
- "optional": true
1587
- },
1588
- "asynckit": {
1589
- "version": "0.4.0",
1590
- "bundled": true,
1591
- "dev": true,
1592
- "optional": true
1593
- },
1594
- "aws-sign2": {
1595
- "version": "0.6.0",
1596
- "bundled": true,
1597
- "dev": true,
1598
- "optional": true
1599
- },
1600
- "aws4": {
1601
- "version": "1.6.0",
1602
- "bundled": true,
1603
- "dev": true,
1604
- "optional": true
1605
- },
1606
- "balanced-match": {
1607
- "version": "0.4.2",
1608
- "bundled": true,
1609
- "dev": true
1610
- },
1611
- "bcrypt-pbkdf": {
1612
- "version": "1.0.1",
1613
- "bundled": true,
1614
- "dev": true,
1615
- "optional": true,
1616
- "requires": {
1617
- "tweetnacl": "0.14.5"
1618
- }
1619
- },
1620
- "block-stream": {
1621
- "version": "0.0.9",
1622
- "bundled": true,
1623
- "dev": true,
1624
- "requires": {
1625
- "inherits": "2.0.3"
1626
- }
1627
- },
1628
- "boom": {
1629
- "version": "2.10.1",
1630
- "bundled": true,
1631
- "dev": true,
1632
- "requires": {
1633
- "hoek": "2.16.3"
1634
- }
1635
- },
1636
- "brace-expansion": {
1637
- "version": "1.1.7",
1638
- "bundled": true,
1639
- "dev": true,
1640
- "requires": {
1641
- "balanced-match": "0.4.2",
1642
- "concat-map": "0.0.1"
1643
- }
1644
- },
1645
- "buffer-shims": {
1646
- "version": "1.0.0",
1647
- "bundled": true,
1648
- "dev": true
1649
- },
1650
- "caseless": {
1651
- "version": "0.12.0",
1652
- "bundled": true,
1653
- "dev": true,
1654
- "optional": true
1655
- },
1656
- "co": {
1657
- "version": "4.6.0",
1658
- "bundled": true,
1659
- "dev": true,
1660
- "optional": true
1661
- },
1662
- "code-point-at": {
1663
- "version": "1.1.0",
1664
- "bundled": true,
1665
- "dev": true
1666
- },
1667
- "combined-stream": {
1668
- "version": "1.0.5",
1669
- "bundled": true,
1670
- "dev": true,
1671
- "requires": {
1672
- "delayed-stream": "1.0.0"
1673
- }
1674
- },
1675
- "concat-map": {
1676
- "version": "0.0.1",
1677
- "bundled": true,
1678
- "dev": true
1679
- },
1680
- "console-control-strings": {
1681
- "version": "1.1.0",
1682
- "bundled": true,
1683
- "dev": true
1684
- },
1685
- "core-util-is": {
1686
- "version": "1.0.2",
1687
- "bundled": true,
1688
- "dev": true
1689
- },
1690
- "cryptiles": {
1691
- "version": "2.0.5",
1692
- "bundled": true,
1693
- "dev": true,
1694
- "requires": {
1695
- "boom": "2.10.1"
1696
- }
1697
- },
1698
- "dashdash": {
1699
- "version": "1.14.1",
1700
- "bundled": true,
1701
- "dev": true,
1702
- "optional": true,
1703
- "requires": {
1704
- "assert-plus": "1.0.0"
1705
- },
1706
- "dependencies": {
1707
- "assert-plus": {
1708
- "version": "1.0.0",
1709
- "bundled": true,
1710
- "dev": true,
1711
- "optional": true
1712
- }
1713
- }
1714
- },
1715
- "debug": {
1716
- "version": "2.6.8",
1717
- "bundled": true,
1718
- "dev": true,
1719
- "optional": true,
1720
- "requires": {
1721
- "ms": "2.0.0"
1722
- }
1723
- },
1724
- "deep-extend": {
1725
- "version": "0.4.2",
1726
- "bundled": true,
1727
- "dev": true,
1728
- "optional": true
1729
- },
1730
- "delayed-stream": {
1731
- "version": "1.0.0",
1732
- "bundled": true,
1733
- "dev": true
1734
- },
1735
- "delegates": {
1736
- "version": "1.0.0",
1737
- "bundled": true,
1738
- "dev": true,
1739
- "optional": true
1740
- },
1741
- "detect-libc": {
1742
- "version": "1.0.2",
1743
- "bundled": true,
1744
- "dev": true,
1745
- "optional": true
1746
- },
1747
- "ecc-jsbn": {
1748
- "version": "0.1.1",
1749
- "bundled": true,
1750
- "dev": true,
1751
- "optional": true,
1752
- "requires": {
1753
- "jsbn": "0.1.1"
1754
- }
1755
- },
1756
- "extend": {
1757
- "version": "3.0.1",
1758
- "bundled": true,
1759
- "dev": true,
1760
- "optional": true
1761
- },
1762
- "extsprintf": {
1763
- "version": "1.0.2",
1764
- "bundled": true,
1765
- "dev": true
1766
- },
1767
- "forever-agent": {
1768
- "version": "0.6.1",
1769
- "bundled": true,
1770
- "dev": true,
1771
- "optional": true
1772
- },
1773
- "form-data": {
1774
- "version": "2.1.4",
1775
- "bundled": true,
1776
- "dev": true,
1777
- "optional": true,
1778
- "requires": {
1779
- "asynckit": "0.4.0",
1780
- "combined-stream": "1.0.5",
1781
- "mime-types": "2.1.15"
1782
- }
1783
- },
1784
- "fs.realpath": {
1785
- "version": "1.0.0",
1786
- "bundled": true,
1787
- "dev": true
1788
- },
1789
- "fstream": {
1790
- "version": "1.0.11",
1791
- "bundled": true,
1792
- "dev": true,
1793
- "requires": {
1794
- "graceful-fs": "4.1.11",
1795
- "inherits": "2.0.3",
1796
- "mkdirp": "0.5.1",
1797
- "rimraf": "2.6.1"
1798
- }
1799
- },
1800
- "fstream-ignore": {
1801
- "version": "1.0.5",
1802
- "bundled": true,
1803
- "dev": true,
1804
- "optional": true,
1805
- "requires": {
1806
- "fstream": "1.0.11",
1807
- "inherits": "2.0.3",
1808
- "minimatch": "3.0.4"
1809
- }
1810
- },
1811
- "gauge": {
1812
- "version": "2.7.4",
1813
- "bundled": true,
1814
- "dev": true,
1815
- "optional": true,
1816
- "requires": {
1817
- "aproba": "1.1.1",
1818
- "console-control-strings": "1.1.0",
1819
- "has-unicode": "2.0.1",
1820
- "object-assign": "4.1.1",
1821
- "signal-exit": "3.0.2",
1822
- "string-width": "1.0.2",
1823
- "strip-ansi": "3.0.1",
1824
- "wide-align": "1.1.2"
1825
- }
1826
- },
1827
- "getpass": {
1828
- "version": "0.1.7",
1829
- "bundled": true,
1830
- "dev": true,
1831
- "optional": true,
1832
- "requires": {
1833
- "assert-plus": "1.0.0"
1834
- },
1835
- "dependencies": {
1836
- "assert-plus": {
1837
- "version": "1.0.0",
1838
- "bundled": true,
1839
- "dev": true,
1840
- "optional": true
1841
- }
1842
- }
1843
- },
1844
- "glob": {
1845
- "version": "7.1.2",
1846
- "bundled": true,
1847
- "dev": true,
1848
- "requires": {
1849
- "fs.realpath": "1.0.0",
1850
- "inflight": "1.0.6",
1851
- "inherits": "2.0.3",
1852
- "minimatch": "3.0.4",
1853
- "once": "1.4.0",
1854
- "path-is-absolute": "1.0.1"
1855
- }
1856
- },
1857
- "graceful-fs": {
1858
- "version": "4.1.11",
1859
- "bundled": true,
1860
- "dev": true
1861
- },
1862
- "har-schema": {
1863
- "version": "1.0.5",
1864
- "bundled": true,
1865
- "dev": true,
1866
- "optional": true
1867
- },
1868
- "har-validator": {
1869
- "version": "4.2.1",
1870
- "bundled": true,
1871
- "dev": true,
1872
- "optional": true,
1873
- "requires": {
1874
- "ajv": "4.11.8",
1875
- "har-schema": "1.0.5"
1876
- }
1877
- },
1878
- "has-unicode": {
1879
- "version": "2.0.1",
1880
- "bundled": true,
1881
- "dev": true,
1882
- "optional": true
1883
- },
1884
- "hawk": {
1885
- "version": "3.1.3",
1886
- "bundled": true,
1887
- "dev": true,
1888
- "requires": {
1889
- "boom": "2.10.1",
1890
- "cryptiles": "2.0.5",
1891
- "hoek": "2.16.3",
1892
- "sntp": "1.0.9"
1893
- }
1894
- },
1895
- "hoek": {
1896
- "version": "2.16.3",
1897
- "bundled": true,
1898
- "dev": true
1899
- },
1900
- "http-signature": {
1901
- "version": "1.1.1",
1902
- "bundled": true,
1903
- "dev": true,
1904
- "optional": true,
1905
- "requires": {
1906
- "assert-plus": "0.2.0",
1907
- "jsprim": "1.4.0",
1908
- "sshpk": "1.13.0"
1909
- }
1910
- },
1911
- "inflight": {
1912
- "version": "1.0.6",
1913
- "bundled": true,
1914
- "dev": true,
1915
- "requires": {
1916
- "once": "1.4.0",
1917
- "wrappy": "1.0.2"
1918
- }
1919
- },
1920
- "inherits": {
1921
- "version": "2.0.3",
1922
- "bundled": true,
1923
- "dev": true
1924
- },
1925
- "ini": {
1926
- "version": "1.3.4",
1927
- "bundled": true,
1928
- "dev": true,
1929
- "optional": true
1930
- },
1931
- "is-fullwidth-code-point": {
1932
- "version": "1.0.0",
1933
- "bundled": true,
1934
- "dev": true,
1935
- "requires": {
1936
- "number-is-nan": "1.0.1"
1937
- }
1938
- },
1939
- "is-typedarray": {
1940
- "version": "1.0.0",
1941
- "bundled": true,
1942
- "dev": true,
1943
- "optional": true
1944
- },
1945
- "isarray": {
1946
- "version": "1.0.0",
1947
- "bundled": true,
1948
- "dev": true
1949
- },
1950
- "isstream": {
1951
- "version": "0.1.2",
1952
- "bundled": true,
1953
- "dev": true,
1954
- "optional": true
1955
- },
1956
- "jodid25519": {
1957
- "version": "1.0.2",
1958
- "bundled": true,
1959
- "dev": true,
1960
- "optional": true,
1961
- "requires": {
1962
- "jsbn": "0.1.1"
1963
- }
1964
- },
1965
- "jsbn": {
1966
- "version": "0.1.1",
1967
- "bundled": true,
1968
- "dev": true,
1969
- "optional": true
1970
- },
1971
- "json-schema": {
1972
- "version": "0.2.3",
1973
- "bundled": true,
1974
- "dev": true,
1975
- "optional": true
1976
- },
1977
- "json-stable-stringify": {
1978
- "version": "1.0.1",
1979
- "bundled": true,
1980
- "dev": true,
1981
- "optional": true,
1982
- "requires": {
1983
- "jsonify": "0.0.0"
1984
- }
1985
- },
1986
- "json-stringify-safe": {
1987
- "version": "5.0.1",
1988
- "bundled": true,
1989
- "dev": true,
1990
- "optional": true
1991
- },
1992
- "jsonify": {
1993
- "version": "0.0.0",
1994
- "bundled": true,
1995
- "dev": true,
1996
- "optional": true
1997
- },
1998
- "jsprim": {
1999
- "version": "1.4.0",
2000
- "bundled": true,
2001
- "dev": true,
2002
- "optional": true,
2003
- "requires": {
2004
- "assert-plus": "1.0.0",
2005
- "extsprintf": "1.0.2",
2006
- "json-schema": "0.2.3",
2007
- "verror": "1.3.6"
2008
- },
2009
- "dependencies": {
2010
- "assert-plus": {
2011
- "version": "1.0.0",
2012
- "bundled": true,
2013
- "dev": true,
2014
- "optional": true
2015
- }
2016
- }
2017
- },
2018
- "mime-db": {
2019
- "version": "1.27.0",
2020
- "bundled": true,
2021
- "dev": true
2022
- },
2023
- "mime-types": {
2024
- "version": "2.1.15",
2025
- "bundled": true,
2026
- "dev": true,
2027
- "requires": {
2028
- "mime-db": "1.27.0"
2029
- }
2030
- },
2031
- "minimatch": {
2032
- "version": "3.0.4",
2033
- "bundled": true,
2034
- "dev": true,
2035
- "requires": {
2036
- "brace-expansion": "1.1.7"
2037
- }
2038
- },
2039
- "minimist": {
2040
- "version": "0.0.8",
2041
- "bundled": true,
2042
- "dev": true
2043
- },
2044
- "mkdirp": {
2045
- "version": "0.5.1",
2046
- "bundled": true,
2047
- "dev": true,
2048
- "requires": {
2049
- "minimist": "0.0.8"
2050
- }
2051
- },
2052
- "ms": {
2053
- "version": "2.0.0",
2054
- "bundled": true,
2055
- "dev": true,
2056
- "optional": true
2057
- },
2058
- "node-pre-gyp": {
2059
- "version": "0.6.39",
2060
- "bundled": true,
2061
- "dev": true,
2062
- "optional": true,
2063
- "requires": {
2064
- "detect-libc": "1.0.2",
2065
- "hawk": "3.1.3",
2066
- "mkdirp": "0.5.1",
2067
- "nopt": "4.0.1",
2068
- "npmlog": "4.1.0",
2069
- "rc": "1.2.1",
2070
- "request": "2.81.0",
2071
- "rimraf": "2.6.1",
2072
- "semver": "5.3.0",
2073
- "tar": "2.2.1",
2074
- "tar-pack": "3.4.0"
2075
- }
2076
- },
2077
- "nopt": {
2078
- "version": "4.0.1",
2079
- "bundled": true,
2080
- "dev": true,
2081
- "optional": true,
2082
- "requires": {
2083
- "abbrev": "1.1.0",
2084
- "osenv": "0.1.4"
2085
- }
2086
- },
2087
- "npmlog": {
2088
- "version": "4.1.0",
2089
- "bundled": true,
2090
- "dev": true,
2091
- "optional": true,
2092
- "requires": {
2093
- "are-we-there-yet": "1.1.4",
2094
- "console-control-strings": "1.1.0",
2095
- "gauge": "2.7.4",
2096
- "set-blocking": "2.0.0"
2097
- }
2098
- },
2099
- "number-is-nan": {
2100
- "version": "1.0.1",
2101
- "bundled": true,
2102
- "dev": true
2103
- },
2104
- "oauth-sign": {
2105
- "version": "0.8.2",
2106
- "bundled": true,
2107
- "dev": true,
2108
- "optional": true
2109
- },
2110
- "object-assign": {
2111
- "version": "4.1.1",
2112
- "bundled": true,
2113
- "dev": true,
2114
- "optional": true
2115
- },
2116
- "once": {
2117
- "version": "1.4.0",
2118
- "bundled": true,
2119
- "dev": true,
2120
- "requires": {
2121
- "wrappy": "1.0.2"
2122
- }
2123
- },
2124
- "os-homedir": {
2125
- "version": "1.0.2",
2126
- "bundled": true,
2127
- "dev": true,
2128
- "optional": true
2129
- },
2130
- "os-tmpdir": {
2131
- "version": "1.0.2",
2132
- "bundled": true,
2133
- "dev": true,
2134
- "optional": true
2135
- },
2136
- "osenv": {
2137
- "version": "0.1.4",
2138
- "bundled": true,
2139
- "dev": true,
2140
- "optional": true,
2141
- "requires": {
2142
- "os-homedir": "1.0.2",
2143
- "os-tmpdir": "1.0.2"
2144
- }
2145
- },
2146
- "path-is-absolute": {
2147
- "version": "1.0.1",
2148
- "bundled": true,
2149
- "dev": true
2150
- },
2151
- "performance-now": {
2152
- "version": "0.2.0",
2153
- "bundled": true,
2154
- "dev": true,
2155
- "optional": true
2156
- },
2157
- "process-nextick-args": {
2158
- "version": "1.0.7",
2159
- "bundled": true,
2160
- "dev": true
2161
- },
2162
- "punycode": {
2163
- "version": "1.4.1",
2164
- "bundled": true,
2165
- "dev": true,
2166
- "optional": true
2167
- },
2168
- "qs": {
2169
- "version": "6.4.0",
2170
- "bundled": true,
2171
- "dev": true,
2172
- "optional": true
2173
- },
2174
- "rc": {
2175
- "version": "1.2.1",
2176
- "bundled": true,
2177
- "dev": true,
2178
- "optional": true,
2179
- "requires": {
2180
- "deep-extend": "0.4.2",
2181
- "ini": "1.3.4",
2182
- "minimist": "1.2.0",
2183
- "strip-json-comments": "2.0.1"
2184
- },
2185
- "dependencies": {
2186
- "minimist": {
2187
- "version": "1.2.0",
2188
- "bundled": true,
2189
- "dev": true,
2190
- "optional": true
2191
- }
2192
- }
2193
- },
2194
- "readable-stream": {
2195
- "version": "2.2.9",
2196
- "bundled": true,
2197
- "dev": true,
2198
- "requires": {
2199
- "buffer-shims": "1.0.0",
2200
- "core-util-is": "1.0.2",
2201
- "inherits": "2.0.3",
2202
- "isarray": "1.0.0",
2203
- "process-nextick-args": "1.0.7",
2204
- "string_decoder": "1.0.1",
2205
- "util-deprecate": "1.0.2"
2206
- }
2207
- },
2208
- "request": {
2209
- "version": "2.81.0",
2210
- "bundled": true,
2211
- "dev": true,
2212
- "optional": true,
2213
- "requires": {
2214
- "aws-sign2": "0.6.0",
2215
- "aws4": "1.6.0",
2216
- "caseless": "0.12.0",
2217
- "combined-stream": "1.0.5",
2218
- "extend": "3.0.1",
2219
- "forever-agent": "0.6.1",
2220
- "form-data": "2.1.4",
2221
- "har-validator": "4.2.1",
2222
- "hawk": "3.1.3",
2223
- "http-signature": "1.1.1",
2224
- "is-typedarray": "1.0.0",
2225
- "isstream": "0.1.2",
2226
- "json-stringify-safe": "5.0.1",
2227
- "mime-types": "2.1.15",
2228
- "oauth-sign": "0.8.2",
2229
- "performance-now": "0.2.0",
2230
- "qs": "6.4.0",
2231
- "safe-buffer": "5.0.1",
2232
- "stringstream": "0.0.5",
2233
- "tough-cookie": "2.3.2",
2234
- "tunnel-agent": "0.6.0",
2235
- "uuid": "3.0.1"
2236
- }
2237
- },
2238
- "rimraf": {
2239
- "version": "2.6.1",
2240
- "bundled": true,
2241
- "dev": true,
2242
- "requires": {
2243
- "glob": "7.1.2"
2244
- }
2245
- },
2246
- "safe-buffer": {
2247
- "version": "5.0.1",
2248
- "bundled": true,
2249
- "dev": true
2250
- },
2251
- "semver": {
2252
- "version": "5.3.0",
2253
- "bundled": true,
2254
- "dev": true,
2255
- "optional": true
2256
- },
2257
- "set-blocking": {
2258
- "version": "2.0.0",
2259
- "bundled": true,
2260
- "dev": true,
2261
- "optional": true
2262
- },
2263
- "signal-exit": {
2264
- "version": "3.0.2",
2265
- "bundled": true,
2266
- "dev": true,
2267
- "optional": true
2268
- },
2269
- "sntp": {
2270
- "version": "1.0.9",
2271
- "bundled": true,
2272
- "dev": true,
2273
- "requires": {
2274
- "hoek": "2.16.3"
2275
- }
2276
- },
2277
- "sshpk": {
2278
- "version": "1.13.0",
2279
- "bundled": true,
2280
- "dev": true,
2281
- "optional": true,
2282
- "requires": {
2283
- "asn1": "0.2.3",
2284
- "assert-plus": "1.0.0",
2285
- "bcrypt-pbkdf": "1.0.1",
2286
- "dashdash": "1.14.1",
2287
- "ecc-jsbn": "0.1.1",
2288
- "getpass": "0.1.7",
2289
- "jodid25519": "1.0.2",
2290
- "jsbn": "0.1.1",
2291
- "tweetnacl": "0.14.5"
2292
- },
2293
- "dependencies": {
2294
- "assert-plus": {
2295
- "version": "1.0.0",
2296
- "bundled": true,
2297
- "dev": true,
2298
- "optional": true
2299
- }
2300
- }
2301
- },
2302
- "string-width": {
2303
- "version": "1.0.2",
2304
- "bundled": true,
2305
- "dev": true,
2306
- "requires": {
2307
- "code-point-at": "1.1.0",
2308
- "is-fullwidth-code-point": "1.0.0",
2309
- "strip-ansi": "3.0.1"
2310
- }
2311
- },
2312
- "string_decoder": {
2313
- "version": "1.0.1",
2314
- "bundled": true,
2315
- "dev": true,
2316
- "requires": {
2317
- "safe-buffer": "5.0.1"
2318
- }
2319
- },
2320
- "stringstream": {
2321
- "version": "0.0.5",
2322
- "bundled": true,
2323
- "dev": true,
2324
- "optional": true
2325
- },
2326
- "strip-ansi": {
2327
- "version": "3.0.1",
2328
- "bundled": true,
2329
- "dev": true,
2330
- "requires": {
2331
- "ansi-regex": "2.1.1"
2332
- }
2333
- },
2334
- "strip-json-comments": {
2335
- "version": "2.0.1",
2336
- "bundled": true,
2337
- "dev": true,
2338
- "optional": true
2339
- },
2340
- "tar": {
2341
- "version": "2.2.1",
2342
- "bundled": true,
2343
- "dev": true,
2344
- "requires": {
2345
- "block-stream": "0.0.9",
2346
- "fstream": "1.0.11",
2347
- "inherits": "2.0.3"
2348
- }
2349
- },
2350
- "tar-pack": {
2351
- "version": "3.4.0",
2352
- "bundled": true,
2353
- "dev": true,
2354
- "optional": true,
2355
- "requires": {
2356
- "debug": "2.6.8",
2357
- "fstream": "1.0.11",
2358
- "fstream-ignore": "1.0.5",
2359
- "once": "1.4.0",
2360
- "readable-stream": "2.2.9",
2361
- "rimraf": "2.6.1",
2362
- "tar": "2.2.1",
2363
- "uid-number": "0.0.6"
2364
- }
2365
- },
2366
- "tough-cookie": {
2367
- "version": "2.3.2",
2368
- "bundled": true,
2369
- "dev": true,
2370
- "optional": true,
2371
- "requires": {
2372
- "punycode": "1.4.1"
2373
- }
2374
- },
2375
- "tunnel-agent": {
2376
- "version": "0.6.0",
2377
- "bundled": true,
2378
- "dev": true,
2379
- "optional": true,
2380
- "requires": {
2381
- "safe-buffer": "5.0.1"
2382
- }
2383
- },
2384
- "tweetnacl": {
2385
- "version": "0.14.5",
2386
- "bundled": true,
2387
- "dev": true,
2388
- "optional": true
2389
- },
2390
- "uid-number": {
2391
- "version": "0.0.6",
2392
- "bundled": true,
2393
- "dev": true,
2394
- "optional": true
2395
- },
2396
- "util-deprecate": {
2397
- "version": "1.0.2",
2398
- "bundled": true,
2399
- "dev": true
2400
- },
2401
- "uuid": {
2402
- "version": "3.0.1",
2403
- "bundled": true,
2404
- "dev": true,
2405
- "optional": true
2406
- },
2407
- "verror": {
2408
- "version": "1.3.6",
2409
- "bundled": true,
2410
- "dev": true,
2411
- "optional": true,
2412
- "requires": {
2413
- "extsprintf": "1.0.2"
2414
- }
2415
- },
2416
- "wide-align": {
2417
- "version": "1.1.2",
2418
- "bundled": true,
2419
- "dev": true,
2420
- "optional": true,
2421
- "requires": {
2422
- "string-width": "1.0.2"
2423
- }
2424
- },
2425
- "wrappy": {
2426
- "version": "1.0.2",
2427
- "bundled": true,
2428
- "dev": true
2429
- }
2430
- }
2431
- },
2432
- "get-caller-file": {
2433
- "version": "1.0.2",
2434
- "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.2.tgz",
2435
- "integrity": "sha1-9wLmMSfn4jHBYKgMFVSstw1QR+U=",
2436
- "dev": true
2437
- },
2438
- "get-stream": {
2439
- "version": "3.0.0",
2440
- "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz",
2441
- "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=",
2442
- "dev": true
2443
- },
2444
- "glob-base": {
2445
- "version": "0.3.0",
2446
- "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz",
2447
- "integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=",
2448
- "dev": true,
2449
- "requires": {
2450
- "glob-parent": "2.0.0",
2451
- "is-glob": "2.0.1"
2452
- }
2453
- },
2454
- "glob-parent": {
2455
- "version": "2.0.0",
2456
- "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz",
2457
- "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=",
2458
- "dev": true,
2459
- "requires": {
2460
- "is-glob": "2.0.1"
2461
- }
2462
- },
2463
- "globals": {
2464
- "version": "9.18.0",
2465
- "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz",
2466
- "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==",
2467
- "dev": true
2468
- },
2469
- "graceful-fs": {
2470
- "version": "4.1.11",
2471
- "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz",
2472
- "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=",
2473
- "dev": true
2474
- },
2475
- "has-ansi": {
2476
- "version": "2.0.0",
2477
- "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz",
2478
- "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=",
2479
- "dev": true,
2480
- "requires": {
2481
- "ansi-regex": "2.1.1"
2482
- }
2483
- },
2484
- "has-flag": {
2485
- "version": "2.0.0",
2486
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz",
2487
- "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=",
2488
- "dev": true
2489
- },
2490
- "hash-base": {
2491
- "version": "2.0.2",
2492
- "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-2.0.2.tgz",
2493
- "integrity": "sha1-ZuodhW206KVHDK32/OI65SRO8uE=",
2494
- "dev": true,
2495
- "requires": {
2496
- "inherits": "2.0.3"
2497
- }
2498
- },
2499
- "hash.js": {
2500
- "version": "1.1.3",
2501
- "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.3.tgz",
2502
- "integrity": "sha512-/UETyP0W22QILqS+6HowevwhEFJ3MBJnwTf75Qob9Wz9t0DPuisL8kW8YZMK62dHAKE1c1p+gY1TtOLY+USEHA==",
2503
- "dev": true,
2504
- "requires": {
2505
- "inherits": "2.0.3",
2506
- "minimalistic-assert": "1.0.0"
2507
- }
2508
- },
2509
- "hmac-drbg": {
2510
- "version": "1.0.1",
2511
- "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz",
2512
- "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=",
2513
- "dev": true,
2514
- "requires": {
2515
- "hash.js": "1.1.3",
2516
- "minimalistic-assert": "1.0.0",
2517
- "minimalistic-crypto-utils": "1.0.1"
2518
- }
2519
- },
2520
- "home-or-tmp": {
2521
- "version": "2.0.0",
2522
- "resolved": "https://registry.npmjs.org/home-or-tmp/-/home-or-tmp-2.0.0.tgz",
2523
- "integrity": "sha1-42w/LSyufXRqhX440Y1fMqeILbg=",
2524
- "dev": true,
2525
- "requires": {
2526
- "os-homedir": "1.0.2",
2527
- "os-tmpdir": "1.0.2"
2528
- }
2529
- },
2530
- "hosted-git-info": {
2531
- "version": "2.5.0",
2532
- "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.5.0.tgz",
2533
- "integrity": "sha512-pNgbURSuab90KbTqvRPsseaTxOJCZBD0a7t+haSN33piP9cCM4l0CqdzAif2hUqm716UovKB2ROmiabGAKVXyg==",
2534
- "dev": true
2535
- },
2536
- "https-browserify": {
2537
- "version": "1.0.0",
2538
- "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz",
2539
- "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=",
2540
- "dev": true
2541
- },
2542
- "ieee754": {
2543
- "version": "1.1.8",
2544
- "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.8.tgz",
2545
- "integrity": "sha1-vjPUCsEO8ZJnAfbwii2G+/0a0+Q=",
2546
- "dev": true
2547
- },
2548
- "indexof": {
2549
- "version": "0.0.1",
2550
- "resolved": "https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz",
2551
- "integrity": "sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10=",
2552
- "dev": true
2553
- },
2554
- "inherits": {
2555
- "version": "2.0.3",
2556
- "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
2557
- "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=",
2558
- "dev": true
2559
- },
2560
- "interpret": {
2561
- "version": "1.1.0",
2562
- "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.1.0.tgz",
2563
- "integrity": "sha1-ftGxQQxqDg94z5XTuEQMY/eLhhQ=",
2564
- "dev": true
2565
- },
2566
- "invariant": {
2567
- "version": "2.2.2",
2568
- "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.2.tgz",
2569
- "integrity": "sha1-nh9WrArNtr8wMwbzOL47IErmA2A=",
2570
- "dev": true,
2571
- "requires": {
2572
- "loose-envify": "1.3.1"
2573
- }
2574
- },
2575
- "invert-kv": {
2576
- "version": "1.0.0",
2577
- "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz",
2578
- "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=",
2579
- "dev": true
2580
- },
2581
- "is-arrayish": {
2582
- "version": "0.2.1",
2583
- "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
2584
- "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=",
2585
- "dev": true
2586
- },
2587
- "is-binary-path": {
2588
- "version": "1.0.1",
2589
- "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz",
2590
- "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=",
2591
- "dev": true,
2592
- "requires": {
2593
- "binary-extensions": "1.11.0"
2594
- }
2595
- },
2596
- "is-buffer": {
2597
- "version": "1.1.6",
2598
- "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz",
2599
- "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==",
2600
- "dev": true
2601
- },
2602
- "is-builtin-module": {
2603
- "version": "1.0.0",
2604
- "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz",
2605
- "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=",
2606
- "dev": true,
2607
- "requires": {
2608
- "builtin-modules": "1.1.1"
2609
- }
2610
- },
2611
- "is-dotfile": {
2612
- "version": "1.0.3",
2613
- "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz",
2614
- "integrity": "sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE=",
2615
- "dev": true
2616
- },
2617
- "is-equal-shallow": {
2618
- "version": "0.1.3",
2619
- "resolved": "https://registry.npmjs.org/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz",
2620
- "integrity": "sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ=",
2621
- "dev": true,
2622
- "requires": {
2623
- "is-primitive": "2.0.0"
2624
- }
2625
- },
2626
- "is-extendable": {
2627
- "version": "0.1.1",
2628
- "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz",
2629
- "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=",
2630
- "dev": true
2631
- },
2632
- "is-extglob": {
2633
- "version": "1.0.0",
2634
- "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz",
2635
- "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=",
2636
- "dev": true
2637
- },
2638
- "is-finite": {
2639
- "version": "1.0.2",
2640
- "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.2.tgz",
2641
- "integrity": "sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko=",
2642
- "dev": true,
2643
- "requires": {
2644
- "number-is-nan": "1.0.1"
2645
- }
2646
- },
2647
- "is-fullwidth-code-point": {
2648
- "version": "1.0.0",
2649
- "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
2650
- "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
2651
- "dev": true,
2652
- "requires": {
2653
- "number-is-nan": "1.0.1"
2654
- }
2655
- },
2656
- "is-glob": {
2657
- "version": "2.0.1",
2658
- "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz",
2659
- "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=",
2660
- "dev": true,
2661
- "requires": {
2662
- "is-extglob": "1.0.0"
2663
- }
2664
- },
2665
- "is-number": {
2666
- "version": "2.1.0",
2667
- "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz",
2668
- "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=",
2669
- "dev": true,
2670
- "requires": {
2671
- "kind-of": "3.2.2"
2672
- }
2673
- },
2674
- "is-posix-bracket": {
2675
- "version": "0.1.1",
2676
- "resolved": "https://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz",
2677
- "integrity": "sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q=",
2678
- "dev": true
2679
- },
2680
- "is-primitive": {
2681
- "version": "2.0.0",
2682
- "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz",
2683
- "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=",
2684
- "dev": true
2685
- },
2686
- "is-stream": {
2687
- "version": "1.1.0",
2688
- "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz",
2689
- "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=",
2690
- "dev": true
2691
- },
2692
- "is-windows": {
2693
- "version": "1.0.1",
2694
- "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.1.tgz",
2695
- "integrity": "sha1-MQ23D3QtJZoWo2kgK1GvhCMzENk=",
2696
- "dev": true
2697
- },
2698
- "isarray": {
2699
- "version": "1.0.0",
2700
- "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
2701
- "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
2702
- "dev": true
2703
- },
2704
- "isexe": {
2705
- "version": "2.0.0",
2706
- "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
2707
- "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
2708
- "dev": true
2709
- },
2710
- "isobject": {
2711
- "version": "2.1.0",
2712
- "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz",
2713
- "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=",
2714
- "dev": true,
2715
- "requires": {
2716
- "isarray": "1.0.0"
2717
- }
2718
- },
2719
- "js-tokens": {
2720
- "version": "3.0.2",
2721
- "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz",
2722
- "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=",
2723
- "dev": true
2724
- },
2725
- "jsesc": {
2726
- "version": "1.3.0",
2727
- "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-1.3.0.tgz",
2728
- "integrity": "sha1-RsP+yMGJKxKwgz25vHYiF226s0s=",
2729
- "dev": true
2730
- },
2731
- "json-loader": {
2732
- "version": "0.5.7",
2733
- "resolved": "https://registry.npmjs.org/json-loader/-/json-loader-0.5.7.tgz",
2734
- "integrity": "sha512-QLPs8Dj7lnf3e3QYS1zkCo+4ZwqOiF9d/nZnYozTISxXWCfNs9yuky5rJw4/W34s7POaNlbZmQGaB5NiXCbP4w==",
2735
- "dev": true
2736
- },
2737
- "json-schema-traverse": {
2738
- "version": "0.3.1",
2739
- "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz",
2740
- "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=",
2741
- "dev": true
2742
- },
2743
- "json5": {
2744
- "version": "0.5.1",
2745
- "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz",
2746
- "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=",
2747
- "dev": true
2748
- },
2749
- "kind-of": {
2750
- "version": "3.2.2",
2751
- "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
2752
- "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
2753
- "dev": true,
2754
- "requires": {
2755
- "is-buffer": "1.1.6"
2756
- }
2757
- },
2758
- "lazy-cache": {
2759
- "version": "1.0.4",
2760
- "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz",
2761
- "integrity": "sha1-odePw6UEdMuAhF07O24dpJpEbo4=",
2762
- "dev": true
2763
- },
2764
- "lcid": {
2765
- "version": "1.0.0",
2766
- "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz",
2767
- "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=",
2768
- "dev": true,
2769
- "requires": {
2770
- "invert-kv": "1.0.0"
2771
- }
2772
- },
2773
- "load-json-file": {
2774
- "version": "2.0.0",
2775
- "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz",
2776
- "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=",
2777
- "dev": true,
2778
- "requires": {
2779
- "graceful-fs": "4.1.11",
2780
- "parse-json": "2.2.0",
2781
- "pify": "2.3.0",
2782
- "strip-bom": "3.0.0"
2783
- },
2784
- "dependencies": {
2785
- "pify": {
2786
- "version": "2.3.0",
2787
- "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
2788
- "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
2789
- "dev": true
2790
- }
2791
- }
2792
- },
2793
- "loader-runner": {
2794
- "version": "2.3.0",
2795
- "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-2.3.0.tgz",
2796
- "integrity": "sha1-9IKuqC1UPgeSFwDVpG7yb9rGuKI=",
2797
- "dev": true
2798
- },
2799
- "loader-utils": {
2800
- "version": "1.1.0",
2801
- "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.1.0.tgz",
2802
- "integrity": "sha1-yYrvSIvM7aL/teLeZG1qdUQp9c0=",
2803
- "dev": true,
2804
- "requires": {
2805
- "big.js": "3.2.0",
2806
- "emojis-list": "2.1.0",
2807
- "json5": "0.5.1"
2808
- }
2809
- },
2810
- "locate-path": {
2811
- "version": "2.0.0",
2812
- "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz",
2813
- "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=",
2814
- "dev": true,
2815
- "requires": {
2816
- "p-locate": "2.0.0",
2817
- "path-exists": "3.0.0"
2818
- }
2819
- },
2820
- "lodash": {
2821
- "version": "4.17.4",
2822
- "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz",
2823
- "integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4=",
2824
- "dev": true
2825
- },
2826
- "longest": {
2827
- "version": "1.0.1",
2828
- "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz",
2829
- "integrity": "sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc=",
2830
- "dev": true
2831
- },
2832
- "loose-envify": {
2833
- "version": "1.3.1",
2834
- "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.3.1.tgz",
2835
- "integrity": "sha1-0aitM/qc4OcT1l/dCsi3SNR4yEg=",
2836
- "dev": true,
2837
- "requires": {
2838
- "js-tokens": "3.0.2"
2839
- }
2840
- },
2841
- "lru-cache": {
2842
- "version": "4.1.1",
2843
- "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.1.tgz",
2844
- "integrity": "sha512-q4spe4KTfsAS1SUHLO0wz8Qiyf1+vMIAgpRYioFYDMNqKfHQbg+AVDH3i4fvpl71/P1L0dBl+fQi+P37UYf0ew==",
2845
- "dev": true,
2846
- "requires": {
2847
- "pseudomap": "1.0.2",
2848
- "yallist": "2.1.2"
2849
- }
2850
- },
2851
- "make-dir": {
2852
- "version": "1.1.0",
2853
- "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.1.0.tgz",
2854
- "integrity": "sha512-0Pkui4wLJ7rxvmfUvs87skoEaxmu0hCUApF8nonzpl7q//FWp9zu8W61Scz4sd/kUiqDxvUhtoam2efDyiBzcA==",
2855
- "dev": true,
2856
- "requires": {
2857
- "pify": "3.0.0"
2858
- }
2859
- },
2860
- "md5.js": {
2861
- "version": "1.3.4",
2862
- "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.4.tgz",
2863
- "integrity": "sha1-6b296UogpawYsENA/Fdk1bCdkB0=",
2864
- "dev": true,
2865
- "requires": {
2866
- "hash-base": "3.0.4",
2867
- "inherits": "2.0.3"
2868
- },
2869
- "dependencies": {
2870
- "hash-base": {
2871
- "version": "3.0.4",
2872
- "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz",
2873
- "integrity": "sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=",
2874
- "dev": true,
2875
- "requires": {
2876
- "inherits": "2.0.3",
2877
- "safe-buffer": "5.1.1"
2878
- }
2879
- }
2880
- }
2881
- },
2882
- "mem": {
2883
- "version": "1.1.0",
2884
- "resolved": "https://registry.npmjs.org/mem/-/mem-1.1.0.tgz",
2885
- "integrity": "sha1-Xt1StIXKHZAP5kiVUFOZoN+kX3Y=",
2886
- "dev": true,
2887
- "requires": {
2888
- "mimic-fn": "1.1.0"
2889
- }
2890
- },
2891
- "memory-fs": {
2892
- "version": "0.4.1",
2893
- "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz",
2894
- "integrity": "sha1-OpoguEYlI+RHz7x+i7gO1me/xVI=",
2895
- "dev": true,
2896
- "requires": {
2897
- "errno": "0.1.6",
2898
- "readable-stream": "2.3.3"
2899
- }
2900
- },
2901
- "micromatch": {
2902
- "version": "2.3.11",
2903
- "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz",
2904
- "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=",
2905
- "dev": true,
2906
- "requires": {
2907
- "arr-diff": "2.0.0",
2908
- "array-unique": "0.2.1",
2909
- "braces": "1.8.5",
2910
- "expand-brackets": "0.1.5",
2911
- "extglob": "0.3.2",
2912
- "filename-regex": "2.0.1",
2913
- "is-extglob": "1.0.0",
2914
- "is-glob": "2.0.1",
2915
- "kind-of": "3.2.2",
2916
- "normalize-path": "2.1.1",
2917
- "object.omit": "2.0.1",
2918
- "parse-glob": "3.0.4",
2919
- "regex-cache": "0.4.4"
2920
- }
2921
- },
2922
- "miller-rabin": {
2923
- "version": "4.0.1",
2924
- "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz",
2925
- "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==",
2926
- "dev": true,
2927
- "requires": {
2928
- "bn.js": "4.11.8",
2929
- "brorand": "1.1.0"
2930
- }
2931
- },
2932
- "mimic-fn": {
2933
- "version": "1.1.0",
2934
- "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.1.0.tgz",
2935
- "integrity": "sha1-5md4PZLonb00KBi1IwudYqZyrRg=",
2936
- "dev": true
2937
- },
2938
- "minimalistic-assert": {
2939
- "version": "1.0.0",
2940
- "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.0.tgz",
2941
- "integrity": "sha1-cCvi3aazf0g2vLP121ZkG2Sh09M=",
2942
- "dev": true
2943
- },
2944
- "minimalistic-crypto-utils": {
2945
- "version": "1.0.1",
2946
- "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz",
2947
- "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=",
2948
- "dev": true
2949
- },
2950
- "minimatch": {
2951
- "version": "3.0.4",
2952
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
2953
- "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
2954
- "dev": true,
2955
- "requires": {
2956
- "brace-expansion": "1.1.8"
2957
- }
2958
- },
2959
- "minimist": {
2960
- "version": "0.0.8",
2961
- "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
2962
- "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=",
2963
- "dev": true
2964
- },
2965
- "mkdirp": {
2966
- "version": "0.5.1",
2967
- "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
2968
- "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
2969
- "dev": true,
2970
- "requires": {
2971
- "minimist": "0.0.8"
2972
- }
2973
- },
2974
- "ms": {
2975
- "version": "2.0.0",
2976
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
2977
- "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
2978
- "dev": true
2979
- },
2980
- "nan": {
2981
- "version": "2.8.0",
2982
- "resolved": "https://registry.npmjs.org/nan/-/nan-2.8.0.tgz",
2983
- "integrity": "sha1-7XFfP+neArV6XmJS2QqWZ14fCFo=",
2984
- "dev": true,
2985
- "optional": true
2986
- },
2987
- "node-libs-browser": {
2988
- "version": "2.1.0",
2989
- "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.1.0.tgz",
2990
- "integrity": "sha512-5AzFzdoIMb89hBGMZglEegffzgRg+ZFoUmisQ8HI4j1KDdpx13J0taNp2y9xPbur6W61gepGDDotGBVQ7mfUCg==",
2991
- "dev": true,
2992
- "requires": {
2993
- "assert": "1.4.1",
2994
- "browserify-zlib": "0.2.0",
2995
- "buffer": "4.9.1",
2996
- "console-browserify": "1.1.0",
2997
- "constants-browserify": "1.0.0",
2998
- "crypto-browserify": "3.12.0",
2999
- "domain-browser": "1.1.7",
3000
- "events": "1.1.1",
3001
- "https-browserify": "1.0.0",
3002
- "os-browserify": "0.3.0",
3003
- "path-browserify": "0.0.0",
3004
- "process": "0.11.10",
3005
- "punycode": "1.4.1",
3006
- "querystring-es3": "0.2.1",
3007
- "readable-stream": "2.3.3",
3008
- "stream-browserify": "2.0.1",
3009
- "stream-http": "2.7.2",
3010
- "string_decoder": "1.0.3",
3011
- "timers-browserify": "2.0.4",
3012
- "tty-browserify": "0.0.0",
3013
- "url": "0.11.0",
3014
- "util": "0.10.3",
3015
- "vm-browserify": "0.0.4"
3016
- }
3017
- },
3018
- "normalize-package-data": {
3019
- "version": "2.4.0",
3020
- "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.0.tgz",
3021
- "integrity": "sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw==",
3022
- "dev": true,
3023
- "requires": {
3024
- "hosted-git-info": "2.5.0",
3025
- "is-builtin-module": "1.0.0",
3026
- "semver": "5.4.1",
3027
- "validate-npm-package-license": "3.0.1"
3028
- }
3029
- },
3030
- "normalize-path": {
3031
- "version": "2.1.1",
3032
- "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz",
3033
- "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=",
3034
- "dev": true,
3035
- "requires": {
3036
- "remove-trailing-separator": "1.1.0"
3037
- }
3038
- },
3039
- "npm-run-path": {
3040
- "version": "2.0.2",
3041
- "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz",
3042
- "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=",
3043
- "dev": true,
3044
- "requires": {
3045
- "path-key": "2.0.1"
3046
- }
3047
- },
3048
- "number-is-nan": {
3049
- "version": "1.0.1",
3050
- "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz",
3051
- "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=",
3052
- "dev": true
3053
- },
3054
- "object-assign": {
3055
- "version": "4.1.1",
3056
- "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
3057
- "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=",
3058
- "dev": true
3059
- },
3060
- "object.omit": {
3061
- "version": "2.0.1",
3062
- "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz",
3063
- "integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=",
3064
- "dev": true,
3065
- "requires": {
3066
- "for-own": "0.1.5",
3067
- "is-extendable": "0.1.1"
3068
- }
3069
- },
3070
- "os-browserify": {
3071
- "version": "0.3.0",
3072
- "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz",
3073
- "integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=",
3074
- "dev": true
3075
- },
3076
- "os-homedir": {
3077
- "version": "1.0.2",
3078
- "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz",
3079
- "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=",
3080
- "dev": true
3081
- },
3082
- "os-locale": {
3083
- "version": "2.1.0",
3084
- "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-2.1.0.tgz",
3085
- "integrity": "sha512-3sslG3zJbEYcaC4YVAvDorjGxc7tv6KVATnLPZONiljsUncvihe9BQoVCEs0RZ1kmf4Hk9OBqlZfJZWI4GanKA==",
3086
- "dev": true,
3087
- "requires": {
3088
- "execa": "0.7.0",
3089
- "lcid": "1.0.0",
3090
- "mem": "1.1.0"
3091
- }
3092
- },
3093
- "os-tmpdir": {
3094
- "version": "1.0.2",
3095
- "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
3096
- "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=",
3097
- "dev": true
3098
- },
3099
- "p-finally": {
3100
- "version": "1.0.0",
3101
- "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz",
3102
- "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=",
3103
- "dev": true
3104
- },
3105
- "p-limit": {
3106
- "version": "1.1.0",
3107
- "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.1.0.tgz",
3108
- "integrity": "sha1-sH/y2aXYi+yAYDWJWiurZqJ5iLw=",
3109
- "dev": true
3110
- },
3111
- "p-locate": {
3112
- "version": "2.0.0",
3113
- "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz",
3114
- "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=",
3115
- "dev": true,
3116
- "requires": {
3117
- "p-limit": "1.1.0"
3118
- }
3119
- },
3120
- "pako": {
3121
- "version": "1.0.6",
3122
- "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.6.tgz",
3123
- "integrity": "sha512-lQe48YPsMJAig+yngZ87Lus+NF+3mtu7DVOBu6b/gHO1YpKwIj5AWjZ/TOS7i46HD/UixzWb1zeWDZfGZ3iYcg==",
3124
- "dev": true
3125
- },
3126
- "parse-asn1": {
3127
- "version": "5.1.0",
3128
- "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.0.tgz",
3129
- "integrity": "sha1-N8T5t+06tlx0gXtfJICTf7+XxxI=",
3130
- "dev": true,
3131
- "requires": {
3132
- "asn1.js": "4.9.2",
3133
- "browserify-aes": "1.1.1",
3134
- "create-hash": "1.1.3",
3135
- "evp_bytestokey": "1.0.3",
3136
- "pbkdf2": "3.0.14"
3137
- }
3138
- },
3139
- "parse-glob": {
3140
- "version": "3.0.4",
3141
- "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz",
3142
- "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=",
3143
- "dev": true,
3144
- "requires": {
3145
- "glob-base": "0.3.0",
3146
- "is-dotfile": "1.0.3",
3147
- "is-extglob": "1.0.0",
3148
- "is-glob": "2.0.1"
3149
- }
3150
- },
3151
- "parse-json": {
3152
- "version": "2.2.0",
3153
- "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz",
3154
- "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=",
3155
- "dev": true,
3156
- "requires": {
3157
- "error-ex": "1.3.1"
3158
- }
3159
- },
3160
- "path-browserify": {
3161
- "version": "0.0.0",
3162
- "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.0.tgz",
3163
- "integrity": "sha1-oLhwcpquIUAFt9UDLsLLuw+0RRo=",
3164
- "dev": true
3165
- },
3166
- "path-exists": {
3167
- "version": "3.0.0",
3168
- "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz",
3169
- "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=",
3170
- "dev": true
3171
- },
3172
- "path-is-absolute": {
3173
- "version": "1.0.1",
3174
- "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
3175
- "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
3176
- "dev": true
3177
- },
3178
- "path-key": {
3179
- "version": "2.0.1",
3180
- "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz",
3181
- "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=",
3182
- "dev": true
3183
- },
3184
- "path-type": {
3185
- "version": "2.0.0",
3186
- "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz",
3187
- "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=",
3188
- "dev": true,
3189
- "requires": {
3190
- "pify": "2.3.0"
3191
- },
3192
- "dependencies": {
3193
- "pify": {
3194
- "version": "2.3.0",
3195
- "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
3196
- "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
3197
- "dev": true
3198
- }
3199
- }
3200
- },
3201
- "pbkdf2": {
3202
- "version": "3.0.14",
3203
- "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.14.tgz",
3204
- "integrity": "sha512-gjsZW9O34fm0R7PaLHRJmLLVfSoesxztjPjE9o6R+qtVJij90ltg1joIovN9GKrRW3t1PzhDDG3UMEMFfZ+1wA==",
3205
- "dev": true,
3206
- "requires": {
3207
- "create-hash": "1.1.3",
3208
- "create-hmac": "1.1.6",
3209
- "ripemd160": "2.0.1",
3210
- "safe-buffer": "5.1.1",
3211
- "sha.js": "2.4.9"
3212
- }
3213
- },
3214
- "pify": {
3215
- "version": "3.0.0",
3216
- "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
3217
- "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=",
3218
- "dev": true
3219
- },
3220
- "pkg-dir": {
3221
- "version": "2.0.0",
3222
- "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz",
3223
- "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=",
3224
- "dev": true,
3225
- "requires": {
3226
- "find-up": "2.1.0"
3227
- }
3228
- },
3229
- "preserve": {
3230
- "version": "0.2.0",
3231
- "resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz",
3232
- "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=",
3233
- "dev": true
3234
- },
3235
- "private": {
3236
- "version": "0.1.8",
3237
- "resolved": "https://registry.npmjs.org/private/-/private-0.1.8.tgz",
3238
- "integrity": "sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg==",
3239
- "dev": true
3240
- },
3241
- "process": {
3242
- "version": "0.11.10",
3243
- "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz",
3244
- "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=",
3245
- "dev": true
3246
- },
3247
- "process-nextick-args": {
3248
- "version": "1.0.7",
3249
- "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz",
3250
- "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=",
3251
- "dev": true
3252
- },
3253
- "prr": {
3254
- "version": "1.0.1",
3255
- "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz",
3256
- "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=",
3257
- "dev": true
3258
- },
3259
- "pseudomap": {
3260
- "version": "1.0.2",
3261
- "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz",
3262
- "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=",
3263
- "dev": true
3264
- },
3265
- "public-encrypt": {
3266
- "version": "4.0.0",
3267
- "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.0.tgz",
3268
- "integrity": "sha1-OfaZ86RlYN1eusvKaTyvfGXBjMY=",
3269
- "dev": true,
3270
- "requires": {
3271
- "bn.js": "4.11.8",
3272
- "browserify-rsa": "4.0.1",
3273
- "create-hash": "1.1.3",
3274
- "parse-asn1": "5.1.0",
3275
- "randombytes": "2.0.5"
3276
- }
3277
- },
3278
- "punycode": {
3279
- "version": "1.4.1",
3280
- "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
3281
- "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=",
3282
- "dev": true
3283
- },
3284
- "querystring": {
3285
- "version": "0.2.0",
3286
- "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz",
3287
- "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=",
3288
- "dev": true
3289
- },
3290
- "querystring-es3": {
3291
- "version": "0.2.1",
3292
- "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz",
3293
- "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=",
3294
- "dev": true
3295
- },
3296
- "randomatic": {
3297
- "version": "1.1.7",
3298
- "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-1.1.7.tgz",
3299
- "integrity": "sha512-D5JUjPyJbaJDkuAazpVnSfVkLlpeO3wDlPROTMLGKG1zMFNFRgrciKo1ltz/AzNTkqE0HzDx655QOL51N06how==",
3300
- "dev": true,
3301
- "requires": {
3302
- "is-number": "3.0.0",
3303
- "kind-of": "4.0.0"
3304
- },
3305
- "dependencies": {
3306
- "is-number": {
3307
- "version": "3.0.0",
3308
- "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
3309
- "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=",
3310
- "dev": true,
3311
- "requires": {
3312
- "kind-of": "3.2.2"
3313
- },
3314
- "dependencies": {
3315
- "kind-of": {
3316
- "version": "3.2.2",
3317
- "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
3318
- "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
3319
- "dev": true,
3320
- "requires": {
3321
- "is-buffer": "1.1.6"
3322
- }
3323
- }
3324
- }
3325
- },
3326
- "kind-of": {
3327
- "version": "4.0.0",
3328
- "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz",
3329
- "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=",
3330
- "dev": true,
3331
- "requires": {
3332
- "is-buffer": "1.1.6"
3333
- }
3334
- }
3335
- }
3336
- },
3337
- "randombytes": {
3338
- "version": "2.0.5",
3339
- "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.0.5.tgz",
3340
- "integrity": "sha512-8T7Zn1AhMsQ/HI1SjcCfT/t4ii3eAqco3yOcSzS4mozsOz69lHLsoMXmF9nZgnFanYscnSlUSgs8uZyKzpE6kg==",
3341
- "dev": true,
3342
- "requires": {
3343
- "safe-buffer": "5.1.1"
3344
- }
3345
- },
3346
- "randomfill": {
3347
- "version": "1.0.3",
3348
- "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.3.tgz",
3349
- "integrity": "sha512-YL6GrhrWoic0Eq8rXVbMptH7dAxCs0J+mh5Y0euNekPPYaxEmdVGim6GdoxoRzKW2yJoU8tueifS7mYxvcFDEQ==",
3350
- "dev": true,
3351
- "requires": {
3352
- "randombytes": "2.0.5",
3353
- "safe-buffer": "5.1.1"
3354
- }
3355
- },
3356
- "read-pkg": {
3357
- "version": "2.0.0",
3358
- "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz",
3359
- "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=",
3360
- "dev": true,
3361
- "requires": {
3362
- "load-json-file": "2.0.0",
3363
- "normalize-package-data": "2.4.0",
3364
- "path-type": "2.0.0"
3365
- }
3366
- },
3367
- "read-pkg-up": {
3368
- "version": "2.0.0",
3369
- "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz",
3370
- "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=",
3371
- "dev": true,
3372
- "requires": {
3373
- "find-up": "2.1.0",
3374
- "read-pkg": "2.0.0"
3375
- }
3376
- },
3377
- "readable-stream": {
3378
- "version": "2.3.3",
3379
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz",
3380
- "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==",
3381
- "dev": true,
3382
- "requires": {
3383
- "core-util-is": "1.0.2",
3384
- "inherits": "2.0.3",
3385
- "isarray": "1.0.0",
3386
- "process-nextick-args": "1.0.7",
3387
- "safe-buffer": "5.1.1",
3388
- "string_decoder": "1.0.3",
3389
- "util-deprecate": "1.0.2"
3390
- }
3391
- },
3392
- "readdirp": {
3393
- "version": "2.1.0",
3394
- "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.1.0.tgz",
3395
- "integrity": "sha1-TtCtBg3zBzMAxIRANz9y0cxkLXg=",
3396
- "dev": true,
3397
- "requires": {
3398
- "graceful-fs": "4.1.11",
3399
- "minimatch": "3.0.4",
3400
- "readable-stream": "2.3.3",
3401
- "set-immediate-shim": "1.0.1"
3402
- }
3403
- },
3404
- "regenerate": {
3405
- "version": "1.3.3",
3406
- "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.3.3.tgz",
3407
- "integrity": "sha512-jVpo1GadrDAK59t/0jRx5VxYWQEDkkEKi6+HjE3joFVLfDOh9Xrdh0dF1eSq+BI/SwvTQ44gSscJ8N5zYL61sg==",
3408
- "dev": true
3409
- },
3410
- "regenerator-runtime": {
3411
- "version": "0.11.1",
3412
- "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz",
3413
- "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==",
3414
- "dev": true
3415
- },
3416
- "regenerator-transform": {
3417
- "version": "0.10.1",
3418
- "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.10.1.tgz",
3419
- "integrity": "sha512-PJepbvDbuK1xgIgnau7Y90cwaAmO/LCLMI2mPvaXq2heGMR3aWW5/BQvYrhJ8jgmQjXewXvBjzfqKcVOmhjZ6Q==",
3420
- "dev": true,
3421
- "requires": {
3422
- "babel-runtime": "6.26.0",
3423
- "babel-types": "6.26.0",
3424
- "private": "0.1.8"
3425
- }
3426
- },
3427
- "regex-cache": {
3428
- "version": "0.4.4",
3429
- "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.4.tgz",
3430
- "integrity": "sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ==",
3431
- "dev": true,
3432
- "requires": {
3433
- "is-equal-shallow": "0.1.3"
3434
- }
3435
- },
3436
- "regexpu-core": {
3437
- "version": "2.0.0",
3438
- "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-2.0.0.tgz",
3439
- "integrity": "sha1-SdA4g3uNz4v6W5pCE5k45uoq4kA=",
3440
- "dev": true,
3441
- "requires": {
3442
- "regenerate": "1.3.3",
3443
- "regjsgen": "0.2.0",
3444
- "regjsparser": "0.1.5"
3445
- }
3446
- },
3447
- "regjsgen": {
3448
- "version": "0.2.0",
3449
- "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.2.0.tgz",
3450
- "integrity": "sha1-bAFq3qxVT3WCP+N6wFuS1aTtsfc=",
3451
- "dev": true
3452
- },
3453
- "regjsparser": {
3454
- "version": "0.1.5",
3455
- "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.1.5.tgz",
3456
- "integrity": "sha1-fuj4Tcb6eS0/0K4ijSS9lJ6tIFw=",
3457
- "dev": true,
3458
- "requires": {
3459
- "jsesc": "0.5.0"
3460
- },
3461
- "dependencies": {
3462
- "jsesc": {
3463
- "version": "0.5.0",
3464
- "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz",
3465
- "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=",
3466
- "dev": true
3467
- }
3468
- }
3469
- },
3470
- "remove-trailing-separator": {
3471
- "version": "1.1.0",
3472
- "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz",
3473
- "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=",
3474
- "dev": true
3475
- },
3476
- "repeat-element": {
3477
- "version": "1.1.2",
3478
- "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.2.tgz",
3479
- "integrity": "sha1-7wiaF40Ug7quTZPrmLT55OEdmQo=",
3480
- "dev": true
3481
- },
3482
- "repeat-string": {
3483
- "version": "1.6.1",
3484
- "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz",
3485
- "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=",
3486
- "dev": true
3487
- },
3488
- "repeating": {
3489
- "version": "2.0.1",
3490
- "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz",
3491
- "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=",
3492
- "dev": true,
3493
- "requires": {
3494
- "is-finite": "1.0.2"
3495
- }
3496
- },
3497
- "require-directory": {
3498
- "version": "2.1.1",
3499
- "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
3500
- "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=",
3501
- "dev": true
3502
- },
3503
- "require-main-filename": {
3504
- "version": "1.0.1",
3505
- "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz",
3506
- "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=",
3507
- "dev": true
3508
- },
3509
- "right-align": {
3510
- "version": "0.1.3",
3511
- "resolved": "https://registry.npmjs.org/right-align/-/right-align-0.1.3.tgz",
3512
- "integrity": "sha1-YTObci/mo1FWiSENJOFMlhSGE+8=",
3513
- "dev": true,
3514
- "requires": {
3515
- "align-text": "0.1.4"
3516
- }
3517
- },
3518
- "ripemd160": {
3519
- "version": "2.0.1",
3520
- "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.1.tgz",
3521
- "integrity": "sha1-D0WEKVxTo2KK9+bXmsohzlfRxuc=",
3522
- "dev": true,
3523
- "requires": {
3524
- "hash-base": "2.0.2",
3525
- "inherits": "2.0.3"
3526
- }
3527
- },
3528
- "safe-buffer": {
3529
- "version": "5.1.1",
3530
- "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz",
3531
- "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==",
3532
- "dev": true
3533
- },
3534
- "semver": {
3535
- "version": "5.4.1",
3536
- "resolved": "https://registry.npmjs.org/semver/-/semver-5.4.1.tgz",
3537
- "integrity": "sha512-WfG/X9+oATh81XtllIo/I8gOiY9EXRdv1cQdyykeXK17YcUW3EXUAi2To4pcH6nZtJPr7ZOpM5OMyWJZm+8Rsg==",
3538
- "dev": true
3539
- },
3540
- "set-blocking": {
3541
- "version": "2.0.0",
3542
- "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
3543
- "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=",
3544
- "dev": true
3545
- },
3546
- "set-immediate-shim": {
3547
- "version": "1.0.1",
3548
- "resolved": "https://registry.npmjs.org/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz",
3549
- "integrity": "sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E=",
3550
- "dev": true
3551
- },
3552
- "setimmediate": {
3553
- "version": "1.0.5",
3554
- "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz",
3555
- "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=",
3556
- "dev": true
3557
- },
3558
- "sha.js": {
3559
- "version": "2.4.9",
3560
- "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.9.tgz",
3561
- "integrity": "sha512-G8zektVqbiPHrylgew9Zg1VRB1L/DtXNUVAM6q4QLy8NE3qtHlFXTf8VLL4k1Yl6c7NMjtZUTdXV+X44nFaT6A==",
3562
- "dev": true,
3563
- "requires": {
3564
- "inherits": "2.0.3",
3565
- "safe-buffer": "5.1.1"
3566
- }
3567
- },
3568
- "shebang-command": {
3569
- "version": "1.2.0",
3570
- "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz",
3571
- "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=",
3572
- "dev": true,
3573
- "requires": {
3574
- "shebang-regex": "1.0.0"
3575
- }
3576
- },
3577
- "shebang-regex": {
3578
- "version": "1.0.0",
3579
- "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz",
3580
- "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=",
3581
- "dev": true
3582
- },
3583
- "signal-exit": {
3584
- "version": "3.0.2",
3585
- "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz",
3586
- "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=",
3587
- "dev": true
3588
- },
3589
- "slash": {
3590
- "version": "1.0.0",
3591
- "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz",
3592
- "integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=",
3593
- "dev": true
3594
- },
3595
- "source-list-map": {
3596
- "version": "2.0.0",
3597
- "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.0.tgz",
3598
- "integrity": "sha512-I2UmuJSRr/T8jisiROLU3A3ltr+swpniSmNPI4Ml3ZCX6tVnDsuZzK7F2hl5jTqbZBWCEKlj5HRQiPExXLgE8A==",
3599
- "dev": true
3600
- },
3601
- "source-map": {
3602
- "version": "0.5.7",
3603
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
3604
- "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
3605
- "dev": true
3606
- },
3607
- "source-map-support": {
3608
- "version": "0.4.18",
3609
- "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.18.tgz",
3610
- "integrity": "sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA==",
3611
- "dev": true,
3612
- "requires": {
3613
- "source-map": "0.5.7"
3614
- }
3615
- },
3616
- "spdx-correct": {
3617
- "version": "1.0.2",
3618
- "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-1.0.2.tgz",
3619
- "integrity": "sha1-SzBz2TP/UfORLwOsVRlJikFQ20A=",
3620
- "dev": true,
3621
- "requires": {
3622
- "spdx-license-ids": "1.2.2"
3623
- }
3624
- },
3625
- "spdx-expression-parse": {
3626
- "version": "1.0.4",
3627
- "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-1.0.4.tgz",
3628
- "integrity": "sha1-m98vIOH0DtRH++JzJmGR/O1RYmw=",
3629
- "dev": true
3630
- },
3631
- "spdx-license-ids": {
3632
- "version": "1.2.2",
3633
- "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-1.2.2.tgz",
3634
- "integrity": "sha1-yd96NCRZSt5r0RkA1ZZpbcBrrFc=",
3635
- "dev": true
3636
- },
3637
- "stream-browserify": {
3638
- "version": "2.0.1",
3639
- "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.1.tgz",
3640
- "integrity": "sha1-ZiZu5fm9uZQKTkUUyvtDu3Hlyds=",
3641
- "dev": true,
3642
- "requires": {
3643
- "inherits": "2.0.3",
3644
- "readable-stream": "2.3.3"
3645
- }
3646
- },
3647
- "stream-http": {
3648
- "version": "2.7.2",
3649
- "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.7.2.tgz",
3650
- "integrity": "sha512-c0yTD2rbQzXtSsFSVhtpvY/vS6u066PcXOX9kBB3mSO76RiUQzL340uJkGBWnlBg4/HZzqiUXtaVA7wcRcJgEw==",
3651
- "dev": true,
3652
- "requires": {
3653
- "builtin-status-codes": "3.0.0",
3654
- "inherits": "2.0.3",
3655
- "readable-stream": "2.3.3",
3656
- "to-arraybuffer": "1.0.1",
3657
- "xtend": "4.0.1"
3658
- }
3659
- },
3660
- "string-width": {
3661
- "version": "2.1.1",
3662
- "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
3663
- "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
3664
- "dev": true,
3665
- "requires": {
3666
- "is-fullwidth-code-point": "2.0.0",
3667
- "strip-ansi": "4.0.0"
3668
- },
3669
- "dependencies": {
3670
- "ansi-regex": {
3671
- "version": "3.0.0",
3672
- "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
3673
- "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
3674
- "dev": true
3675
- },
3676
- "is-fullwidth-code-point": {
3677
- "version": "2.0.0",
3678
- "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
3679
- "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
3680
- "dev": true
3681
- },
3682
- "strip-ansi": {
3683
- "version": "4.0.0",
3684
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
3685
- "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
3686
- "dev": true,
3687
- "requires": {
3688
- "ansi-regex": "3.0.0"
3689
- }
3690
- }
3691
- }
3692
- },
3693
- "string_decoder": {
3694
- "version": "1.0.3",
3695
- "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz",
3696
- "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==",
3697
- "dev": true,
3698
- "requires": {
3699
- "safe-buffer": "5.1.1"
3700
- }
3701
- },
3702
- "strip-ansi": {
3703
- "version": "3.0.1",
3704
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
3705
- "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
3706
- "dev": true,
3707
- "requires": {
3708
- "ansi-regex": "2.1.1"
3709
- }
3710
- },
3711
- "strip-bom": {
3712
- "version": "3.0.0",
3713
- "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz",
3714
- "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=",
3715
- "dev": true
3716
- },
3717
- "strip-eof": {
3718
- "version": "1.0.0",
3719
- "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz",
3720
- "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=",
3721
- "dev": true
3722
- },
3723
- "supports-color": {
3724
- "version": "2.0.0",
3725
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
3726
- "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
3727
- "dev": true
3728
- },
3729
- "tapable": {
3730
- "version": "0.2.8",
3731
- "resolved": "https://registry.npmjs.org/tapable/-/tapable-0.2.8.tgz",
3732
- "integrity": "sha1-mTcqXJmb8t8WCvwNdL7U9HlIzSI=",
3733
- "dev": true
3734
- },
3735
- "timers-browserify": {
3736
- "version": "2.0.4",
3737
- "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.4.tgz",
3738
- "integrity": "sha512-uZYhyU3EX8O7HQP+J9fTVYwsq90Vr68xPEFo7yrVImIxYvHgukBEgOB/SgGoorWVTzGM/3Z+wUNnboA4M8jWrg==",
3739
- "dev": true,
3740
- "requires": {
3741
- "setimmediate": "1.0.5"
3742
- }
3743
- },
3744
- "to-arraybuffer": {
3745
- "version": "1.0.1",
3746
- "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz",
3747
- "integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=",
3748
- "dev": true
3749
- },
3750
- "to-fast-properties": {
3751
- "version": "1.0.3",
3752
- "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz",
3753
- "integrity": "sha1-uDVx+k2MJbguIxsG46MFXeTKGkc=",
3754
- "dev": true
3755
- },
3756
- "trim-right": {
3757
- "version": "1.0.1",
3758
- "resolved": "https://registry.npmjs.org/trim-right/-/trim-right-1.0.1.tgz",
3759
- "integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=",
3760
- "dev": true
3761
- },
3762
- "tty-browserify": {
3763
- "version": "0.0.0",
3764
- "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz",
3765
- "integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=",
3766
- "dev": true
3767
- },
3768
- "uglify-js": {
3769
- "version": "2.8.29",
3770
- "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.29.tgz",
3771
- "integrity": "sha1-KcVzMUgFe7Th913zW3qcty5qWd0=",
3772
- "dev": true,
3773
- "requires": {
3774
- "source-map": "0.5.7",
3775
- "uglify-to-browserify": "1.0.2",
3776
- "yargs": "3.10.0"
3777
- },
3778
- "dependencies": {
3779
- "yargs": {
3780
- "version": "3.10.0",
3781
- "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz",
3782
- "integrity": "sha1-9+572FfdfB0tOMDnTvvWgdFDH9E=",
3783
- "dev": true,
3784
- "requires": {
3785
- "camelcase": "1.2.1",
3786
- "cliui": "2.1.0",
3787
- "decamelize": "1.2.0",
3788
- "window-size": "0.1.0"
3789
- }
3790
- }
3791
- }
3792
- },
3793
- "uglify-to-browserify": {
3794
- "version": "1.0.2",
3795
- "resolved": "https://registry.npmjs.org/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz",
3796
- "integrity": "sha1-bgkk1r2mta/jSeOabWMoUKD4grc=",
3797
- "dev": true,
3798
- "optional": true
3799
- },
3800
- "uglifyjs-webpack-plugin": {
3801
- "version": "0.4.6",
3802
- "resolved": "https://registry.npmjs.org/uglifyjs-webpack-plugin/-/uglifyjs-webpack-plugin-0.4.6.tgz",
3803
- "integrity": "sha1-uVH0q7a9YX5m9j64kUmOORdj4wk=",
3804
- "dev": true,
3805
- "requires": {
3806
- "source-map": "0.5.7",
3807
- "uglify-js": "2.8.29",
3808
- "webpack-sources": "1.1.0"
3809
- }
3810
- },
3811
- "url": {
3812
- "version": "0.11.0",
3813
- "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz",
3814
- "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=",
3815
- "dev": true,
3816
- "requires": {
3817
- "punycode": "1.3.2",
3818
- "querystring": "0.2.0"
3819
- },
3820
- "dependencies": {
3821
- "punycode": {
3822
- "version": "1.3.2",
3823
- "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz",
3824
- "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=",
3825
- "dev": true
3826
- }
3827
- }
3828
- },
3829
- "util": {
3830
- "version": "0.10.3",
3831
- "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz",
3832
- "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=",
3833
- "dev": true,
3834
- "requires": {
3835
- "inherits": "2.0.1"
3836
- },
3837
- "dependencies": {
3838
- "inherits": {
3839
- "version": "2.0.1",
3840
- "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz",
3841
- "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=",
3842
- "dev": true
3843
- }
3844
- }
3845
- },
3846
- "util-deprecate": {
3847
- "version": "1.0.2",
3848
- "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
3849
- "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=",
3850
- "dev": true
3851
- },
3852
- "validate-npm-package-license": {
3853
- "version": "3.0.1",
3854
- "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.1.tgz",
3855
- "integrity": "sha1-KAS6vnEq0zeUWaz74kdGqywwP7w=",
3856
- "dev": true,
3857
- "requires": {
3858
- "spdx-correct": "1.0.2",
3859
- "spdx-expression-parse": "1.0.4"
3860
- }
3861
- },
3862
- "vm-browserify": {
3863
- "version": "0.0.4",
3864
- "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-0.0.4.tgz",
3865
- "integrity": "sha1-XX6kW7755Kb/ZflUOOCofDV9WnM=",
3866
- "dev": true,
3867
- "requires": {
3868
- "indexof": "0.0.1"
3869
- }
3870
- },
3871
- "watchpack": {
3872
- "version": "1.4.0",
3873
- "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.4.0.tgz",
3874
- "integrity": "sha1-ShRyvLuVK9Cpu0A2gB+VTfs5+qw=",
3875
- "dev": true,
3876
- "requires": {
3877
- "async": "2.6.0",
3878
- "chokidar": "1.7.0",
3879
- "graceful-fs": "4.1.11"
3880
- }
3881
- },
3882
- "webpack": {
3883
- "version": "3.10.0",
3884
- "resolved": "https://registry.npmjs.org/webpack/-/webpack-3.10.0.tgz",
3885
- "integrity": "sha512-fxxKXoicjdXNUMY7LIdY89tkJJJ0m1Oo8PQutZ5rLgWbV5QVKI15Cn7+/IHnRTd3vfKfiwBx6SBqlorAuNA8LA==",
3886
- "dev": true,
3887
- "requires": {
3888
- "acorn": "5.2.1",
3889
- "acorn-dynamic-import": "2.0.2",
3890
- "ajv": "5.5.1",
3891
- "ajv-keywords": "2.1.1",
3892
- "async": "2.6.0",
3893
- "enhanced-resolve": "3.4.1",
3894
- "escope": "3.6.0",
3895
- "interpret": "1.1.0",
3896
- "json-loader": "0.5.7",
3897
- "json5": "0.5.1",
3898
- "loader-runner": "2.3.0",
3899
- "loader-utils": "1.1.0",
3900
- "memory-fs": "0.4.1",
3901
- "mkdirp": "0.5.1",
3902
- "node-libs-browser": "2.1.0",
3903
- "source-map": "0.5.7",
3904
- "supports-color": "4.5.0",
3905
- "tapable": "0.2.8",
3906
- "uglifyjs-webpack-plugin": "0.4.6",
3907
- "watchpack": "1.4.0",
3908
- "webpack-sources": "1.1.0",
3909
- "yargs": "8.0.2"
3910
- },
3911
- "dependencies": {
3912
- "supports-color": {
3913
- "version": "4.5.0",
3914
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz",
3915
- "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=",
3916
- "dev": true,
3917
- "requires": {
3918
- "has-flag": "2.0.0"
3919
- }
3920
- }
3921
- }
3922
- },
3923
- "webpack-sources": {
3924
- "version": "1.1.0",
3925
- "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.1.0.tgz",
3926
- "integrity": "sha512-aqYp18kPphgoO5c/+NaUvEeACtZjMESmDChuD3NBciVpah3XpMEU9VAAtIaB1BsfJWWTSdv8Vv1m3T0aRk2dUw==",
3927
- "dev": true,
3928
- "requires": {
3929
- "source-list-map": "2.0.0",
3930
- "source-map": "0.6.1"
3931
- },
3932
- "dependencies": {
3933
- "source-map": {
3934
- "version": "0.6.1",
3935
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
3936
- "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
3937
- "dev": true
3938
- }
3939
- }
3940
- },
3941
- "which": {
3942
- "version": "1.3.0",
3943
- "resolved": "https://registry.npmjs.org/which/-/which-1.3.0.tgz",
3944
- "integrity": "sha512-xcJpopdamTuY5duC/KnTTNBraPK54YwpenP4lzxU8H91GudWpFv38u0CKjclE1Wi2EH2EDz5LRcHcKbCIzqGyg==",
3945
- "dev": true,
3946
- "requires": {
3947
- "isexe": "2.0.0"
3948
- }
3949
- },
3950
- "which-module": {
3951
- "version": "2.0.0",
3952
- "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz",
3953
- "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=",
3954
- "dev": true
3955
- },
3956
- "window-size": {
3957
- "version": "0.1.0",
3958
- "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.0.tgz",
3959
- "integrity": "sha1-VDjNLqk7IC76Ohn+iIeu58lPnJ0=",
3960
- "dev": true
3961
- },
3962
- "wordwrap": {
3963
- "version": "0.0.2",
3964
- "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz",
3965
- "integrity": "sha1-t5Zpu0LstAn4PVg8rVLKF+qhZD8=",
3966
- "dev": true
3967
- },
3968
- "wrap-ansi": {
3969
- "version": "2.1.0",
3970
- "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz",
3971
- "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=",
3972
- "dev": true,
3973
- "requires": {
3974
- "string-width": "1.0.2",
3975
- "strip-ansi": "3.0.1"
3976
- },
3977
- "dependencies": {
3978
- "string-width": {
3979
- "version": "1.0.2",
3980
- "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
3981
- "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
3982
- "dev": true,
3983
- "requires": {
3984
- "code-point-at": "1.1.0",
3985
- "is-fullwidth-code-point": "1.0.0",
3986
- "strip-ansi": "3.0.1"
3987
- }
3988
- }
3989
- }
3990
- },
3991
- "xtend": {
3992
- "version": "4.0.1",
3993
- "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz",
3994
- "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=",
3995
- "dev": true
3996
- },
3997
- "y18n": {
3998
- "version": "3.2.1",
3999
- "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz",
4000
- "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=",
4001
- "dev": true
4002
- },
4003
- "yallist": {
4004
- "version": "2.1.2",
4005
- "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz",
4006
- "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=",
4007
- "dev": true
4008
- },
4009
- "yargs": {
4010
- "version": "8.0.2",
4011
- "resolved": "https://registry.npmjs.org/yargs/-/yargs-8.0.2.tgz",
4012
- "integrity": "sha1-YpmpBVsc78lp/355wdkY3Osiw2A=",
4013
- "dev": true,
4014
- "requires": {
4015
- "camelcase": "4.1.0",
4016
- "cliui": "3.2.0",
4017
- "decamelize": "1.2.0",
4018
- "get-caller-file": "1.0.2",
4019
- "os-locale": "2.1.0",
4020
- "read-pkg-up": "2.0.0",
4021
- "require-directory": "2.1.1",
4022
- "require-main-filename": "1.0.1",
4023
- "set-blocking": "2.0.0",
4024
- "string-width": "2.1.1",
4025
- "which-module": "2.0.0",
4026
- "y18n": "3.2.1",
4027
- "yargs-parser": "7.0.0"
4028
- },
4029
- "dependencies": {
4030
- "camelcase": {
4031
- "version": "4.1.0",
4032
- "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz",
4033
- "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=",
4034
- "dev": true
4035
- },
4036
- "cliui": {
4037
- "version": "3.2.0",
4038
- "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz",
4039
- "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=",
4040
- "dev": true,
4041
- "requires": {
4042
- "string-width": "1.0.2",
4043
- "strip-ansi": "3.0.1",
4044
- "wrap-ansi": "2.1.0"
4045
- },
4046
- "dependencies": {
4047
- "string-width": {
4048
- "version": "1.0.2",
4049
- "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
4050
- "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
4051
- "dev": true,
4052
- "requires": {
4053
- "code-point-at": "1.1.0",
4054
- "is-fullwidth-code-point": "1.0.0",
4055
- "strip-ansi": "3.0.1"
4056
- }
4057
- }
4058
- }
4059
- }
4060
- }
4061
- },
4062
- "yargs-parser": {
4063
- "version": "7.0.0",
4064
- "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-7.0.0.tgz",
4065
- "integrity": "sha1-jQrELxbqVd69MyyvTEA4s+P139k=",
4066
- "dev": true,
4067
- "requires": {
4068
- "camelcase": "4.1.0"
4069
- },
4070
- "dependencies": {
4071
- "camelcase": {
4072
- "version": "4.1.0",
4073
- "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz",
4074
- "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=",
4075
- "dev": true
4076
- }
4077
- }
4078
- }
4079
- }
4080
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/codeinwp/themeisle-content-forms/assets/gutenberg-esnext/package.json DELETED
@@ -1,17 +0,0 @@
1
- {
2
- "name": "04-controls-esnext",
3
- "version": "1.0.0",
4
- "main": "block.js",
5
- "devDependencies": {
6
- "babel-core": "^6.25.0",
7
- "babel-loader": "^7.1.1",
8
- "babel-plugin-transform-react-jsx": "^6.24.1",
9
- "babel-preset-env": "^1.6.0",
10
- "cross-env": "^5.0.1",
11
- "webpack": "^3.1.0"
12
- },
13
- "scripts": {
14
- "build": "cross-env BABEL_ENV=default NODE_ENV=production webpack",
15
- "dev": "cross-env BABEL_ENV=default webpack --watch"
16
- }
17
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/codeinwp/themeisle-content-forms/assets/gutenberg-esnext/webpack.config.js DELETED
@@ -1,62 +0,0 @@
1
- var webpack = require( 'webpack' ),
2
- NODE_ENV = process.env.NODE_ENV || 'development';
3
-
4
- const entryPointNames = [
5
- 'blocks',
6
- 'components',
7
- 'date',
8
- 'editor',
9
- 'element',
10
- 'i18n',
11
- 'utils',
12
- 'data',
13
- ];
14
-
15
- const packageNames = [
16
- 'hooks',
17
- ];
18
-
19
- const externals = {
20
- react: 'React',
21
- 'react-dom': 'ReactDOM',
22
- 'react-dom/server': 'ReactDOMServer',
23
- tinymce: 'tinymce',
24
- moment: 'moment',
25
- jquery: 'jQuery',
26
- };
27
-
28
- [ ...entryPointNames, ...packageNames ].forEach( name => {
29
- externals[ `@wordpress/${ name }` ] = {
30
- this: [ 'wp', name ],
31
- };
32
- } );
33
-
34
-
35
- var webpackConfig = {
36
- entry: './block.js',
37
- output: {
38
- path: __dirname,
39
- filename: 'block.build.js',
40
- },
41
- externals,
42
- module: {
43
- loaders: [
44
- {
45
- test: /.js$/,
46
- loader: 'babel-loader',
47
- exclude: /node_modules/,
48
- },
49
- ],
50
- },
51
- plugins: [
52
- new webpack.DefinePlugin( {
53
- 'process.env.NODE_ENV': JSON.stringify( NODE_ENV )
54
- } ),
55
- ]
56
- };
57
-
58
- if ( 'production' === NODE_ENV ) {
59
- webpackConfig.plugins.push( new webpack.optimize.UglifyJsPlugin() );
60
- }
61
-
62
- module.exports = webpackConfig;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/codeinwp/themeisle-content-forms/class-themeisle-content-forms-gutenberg.php DELETED
@@ -1,286 +0,0 @@
1
- <?php
2
-
3
- namespace ThemeIsle\ContentForms;
4
-
5
-
6
- /**
7
- * This class is used to create a Gutenberg block based on a ContentForms config
8
- * Class ContentFormsGutenbergModule
9
- * @TODO This is a work in progress and for now we will start from the basisc example of a Gutenberg block.
10
- */
11
- class GutenbergModule {
12
-
13
- private $name;
14
-
15
- private $form_type;
16
-
17
- private $title;
18
-
19
- private $icon;
20
-
21
- private $forms_config = array();
22
-
23
- public function __construct( $data ) {
24
-
25
- $this->setup_attributes( $data );
26
- $this->gutenberg_register_attributes();
27
- add_action( 'enqueue_block_editor_assets', array( $this, 'gutenberg_enqueue_block_editor_assets' ) );
28
- }
29
-
30
- /**
31
- * This method takes the given attributes and sets them as properties
32
- *
33
- * @param $data array
34
- */
35
- private function setup_attributes( $data ) {
36
- $this->form_type = $data['type'];
37
-
38
- if ( ! empty( $data['content_forms_config'] ) ) {
39
- $this->forms_config = $data['content_forms_config'];
40
- } else {
41
- $this->forms_config = apply_filters( 'content_forms_config_for_' . $this->form_type, $this->forms_config );
42
- }
43
-
44
- if ( ! empty( $data['id'] ) ) {
45
- $this->set_name( $data['id'] );
46
- }
47
-
48
- if ( ! empty( $this->forms_config['title'] ) ) {
49
- $this->set_title( $this->forms_config['title'] );
50
- }
51
-
52
- if ( ! empty( $this->forms_config['icon'] ) ) {
53
- $this->set_icon( $this->forms_config['icon'] );
54
- }
55
- }
56
-
57
- /**
58
- * Load our block generator once but for each type of form we need to localize the config
59
- */
60
- function gutenberg_enqueue_block_editor_assets() {
61
-
62
- if ( ! wp_script_is( 'gutenberg-content-forms' ) ) {
63
-
64
- wp_enqueue_script(
65
- 'gutenberg-content-forms',
66
- plugins_url( './assets/gutenberg-esnext/block.build.js', __FILE__ ),
67
- array( 'wp-blocks', 'wp-i18n', 'wp-element', 'underscore' ),
68
- filemtime( plugin_dir_path( __FILE__ ) . './assets/gutenberg-esnext/block.build.js' )
69
- );
70
- }
71
-
72
- wp_localize_script(
73
- 'gutenberg-content-forms',
74
- 'content_forms_config_for_' . $this->form_type,
75
- $this->forms_config
76
- );
77
- }
78
-
79
- function gutenberg_enqueue_block_assets() {
80
- wp_enqueue_style(
81
- 'gutenberg-examples-05',
82
- plugins_url( 'style.css', __FILE__ ),
83
- array( 'wp-blocks' ),
84
- filemtime( plugin_dir_path( __FILE__ ) . 'style.css' )
85
- );
86
- }
87
-
88
- function render_block( $attributes, $content ) {
89
- $form_content = '';
90
- $uid = $attributes['uid'];
91
- $fields = $attributes['fields'];
92
- wp_enqueue_script( 'content-forms' );
93
-
94
- $form_header = $this->render_form_header( $uid );
95
- $form_footer = $this->render_form_footer();
96
-
97
-
98
- $btn_label = esc_html__( 'Submit', 'elementor-addon-widgets' );
99
- ob_start();
100
- if ( ! empty( $attributes['submit_label'] ) ) {
101
- $btn_label = $attributes['submit_label'];
102
- } ?>
103
- <fieldset>
104
- <button type="submit" name="submit" value="submit-<?php echo $this->getFormType(); ?>-<?php echo $uid; ?>">
105
- <?php echo $btn_label; ?>
106
- </button>
107
- </fieldset>
108
- <?php
109
-
110
- $form_submit = ob_get_clean();
111
-
112
- foreach ( $fields as $key => $field ) {
113
- ob_start(); ?>
114
- <fields>
115
- <label for="<?php echo $key; ?>"><?php echo $field['label']; ?></label>
116
- <input type="text" name="<?php echo $key; ?>">
117
- </fields>
118
- <?php
119
- $form_content .= ob_get_clean();
120
- }
121
-
122
- $block_content = sprintf(
123
- '<div class="content-form-fields" data-uid="%1$s">
124
- <h3>%1$s</h3>
125
- %2$s
126
- %3$s
127
- %4$s
128
- %5$s
129
- </div>',
130
- $uid,
131
- $form_header,
132
- $form_content,
133
- $form_submit,
134
- $form_footer
135
- );
136
-
137
- return $block_content;
138
- }
139
-
140
- public function render_form_header( $id ) {
141
- // create an url for the form's action
142
- $url = admin_url( 'admin-post.php' );
143
-
144
- ob_start();
145
-
146
- echo '<form action="' . esc_url( $url ) . '" method="post" name="content-form-' . $id . '" id="content-form-' . $id . '" class="content-form content-form-' . $this->getFormType() . ' ' . $this->get_name() . '">';
147
-
148
- wp_nonce_field( 'content-form-' . $id, '_wpnonce_' . $this->getFormType() );
149
-
150
- echo '<input type="hidden" name="action" value="content_form_submit" />';
151
- // there could be also the possibility to submit by type
152
- // echo '<input type="hidden" name="action" value="content_form_{type}_submit" />';
153
- echo '<input type="hidden" name="form-type" value="' . $this->getFormType() . '" />';
154
- echo '<input type="hidden" name="form-builder" value="gutenberg" />';
155
- echo '<input type="hidden" name="post-id" value="' . get_the_ID() . '" />';
156
- echo '<input type="hidden" name="form-id" value="' . $id . '" />';
157
-
158
- return ob_get_clean();
159
- }
160
-
161
- public function render_form_footer() {
162
- return '</form>';
163
- }
164
-
165
- function gutenberg_register_attributes() {
166
- $gutenberg_args = array(
167
- 'attributes' => array(
168
- 'uid' => array(
169
- 'type' => 'string',
170
- 'selector' => '.content-form-fields',
171
- 'source' => 'attribute',
172
- 'attribute' => 'data-uid'
173
- ),
174
- 'fields' => array(
175
- 'type' => 'array',
176
- 'source' => 'query',
177
- 'selector' => '.content-form-field-label',
178
- 'query' => array(
179
- 'field_id' => array(
180
- 'type' => 'string',
181
- 'source' => 'attribute',
182
- 'attribute' => 'data-field_id'
183
- ),
184
- 'label' => array(
185
- 'type' => 'string',
186
- 'source' => 'attribute',
187
- 'attribute' => 'data-label'
188
- ),
189
- 'requirement' => array(
190
- 'type' => 'string',
191
- 'source' => 'attribute',
192
- 'attribute' => 'data-requirement'
193
- ),
194
- 'type' => array(
195
- 'type' => 'string',
196
- 'source' => 'attribute',
197
- 'attribute' => 'data-field_type'
198
- ),
199
- ),
200
- 'default' => array(),
201
- ),
202
- ),
203
- 'render_callback' => array( $this, 'render_block' ),
204
- );
205
-
206
- // Create form settings
207
- foreach ( $this->forms_config['controls'] as $name => $control ) {
208
- $gutenberg_args['attributes'][ $name ] = array(
209
- 'type' => 'string',
210
- 'default' => isset( $control['default'] ) ? $control['default'] : '',
211
- );
212
- }
213
-
214
- foreach ( $this->forms_config['fields'] as $name => $field ) {
215
- $gutenberg_args['attributes']['fields']['default'][ $name ] = array(
216
- 'field_id' => $name,
217
- 'label' => $field['label'],
218
- 'type' => $field['type'],
219
- 'requirement' => ( $field['require'] === 'required' ) ? 'true' : 'false',
220
- );
221
- }
222
-
223
- register_block_type( 'content-forms/' . $this->form_type, $gutenberg_args );
224
- }
225
-
226
- /**
227
- * Retrieve the widget name.
228
- *
229
- * @since 1.0.0
230
- * @access public
231
- *
232
- * @return string Widget name.
233
- */
234
- public function get_name() {
235
- return $this->name;
236
- }
237
-
238
- /**
239
- * Set the widget name property
240
- */
241
- private function set_name( $name ) {
242
- $this->name = $name;
243
- }
244
-
245
- /**
246
- * Retrieve the widget title.
247
- *
248
- * @since 1.0.0
249
- * @access public
250
- *
251
- * @return string Widget title.
252
- */
253
- public function get_title() {
254
- return $this->title;
255
- }
256
-
257
- /**
258
- * Set the widget title property
259
- */
260
- private function set_title( $title ) {
261
- $this->title = $title;
262
- }
263
-
264
- /**
265
- * Retrieve content form widget icon.
266
- *
267
- * @since 1.0.0
268
- * @access public
269
- *
270
- * @return string Widget icon.
271
- */
272
- public function get_icon() {
273
- return $this->icon;
274
- }
275
-
276
- /**
277
- * Set the widget title property
278
- */
279
- private function set_icon( $icon ) {
280
- $this->icon = $icon;
281
- }
282
-
283
- private function getFormType() {
284
- return $this->form_type;
285
- }
286
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/codeinwp/themeisle-content-forms/phpunit.xml ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <phpunit
2
+ bootstrap="tests/bootstrap.php"
3
+ backupGlobals="false"
4
+ colors="true"
5
+ convertErrorsToExceptions="true"
6
+ convertNoticesToExceptions="true"
7
+ convertWarningsToExceptions="true"
8
+ >
9
+ <testsuites>
10
+ <testsuite>
11
+ <directory prefix="test-" suffix=".php">./tests/</directory>
12
+ </testsuite>
13
+ </testsuites>
14
+ </phpunit>
vendor/codeinwp/themeisle-content-forms/tests/bootstrap.php ADDED
@@ -0,0 +1,50 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * PHPUnit bootstrap file
4
+ *
5
+ * @package ThemeIsle\ContentForms
6
+ */
7
+
8
+ /**
9
+ * change PLUGIN_FILE env in phpunit.xml
10
+ */
11
+ define( 'PLUGIN_FILE', getenv( 'PLUGIN_FILE' ) );
12
+ define( 'PLUGIN_FOLDER', basename( dirname( __DIR__ ) ) );
13
+ define( 'PLUGIN_PATH', PLUGIN_FOLDER . '/' . PLUGIN_FILE );
14
+
15
+ // Activates this plugin in WordPress so it can be tested.
16
+ $GLOBALS['wp_tests_options'] = [
17
+ 'active_plugins' => [ PLUGIN_PATH ],
18
+ 'template' => 'twentysixteen',
19
+ 'stylesheet' => 'twentysixteen',
20
+ ];
21
+
22
+ // Determine the tests directory (from a WP dev checkout).
23
+ // Try the WP_TESTS_DIR environment variable first.
24
+ $_tests_dir = getenv( 'WP_TESTS_DIR' );
25
+
26
+ // See if we're installed inside an existing WP dev instance.
27
+ if ( ! $_tests_dir ) {
28
+ $_try_tests_dir = dirname( __FILE__ ) . '/../../../../../tests/phpunit';
29
+ if ( file_exists( $_try_tests_dir . '/includes/functions.php' ) ) {
30
+ $_tests_dir = $_try_tests_dir;
31
+ }
32
+ }
33
+ // Fallback.
34
+ if ( ! $_tests_dir ) {
35
+ $_tests_dir = '/tmp/wordpress-tests-lib';
36
+ }
37
+
38
+ // Give access to tests_add_filter() function.
39
+ require_once $_tests_dir . '/includes/functions.php';
40
+
41
+ /**
42
+ * Manually load the plugin being tested.
43
+ */
44
+ function _manually_load_plugin() {
45
+ require dirname( dirname( __FILE__ ) ) . '/load.php';
46
+ }
47
+ tests_add_filter( 'muplugins_loaded', '_manually_load_plugin' );
48
+
49
+ // Start up the WP testing environment.
50
+ require $_tests_dir . '/includes/bootstrap.php';
vendor/codeinwp/themeisle-content-forms/tests/test-basics.php ADDED
@@ -0,0 +1,86 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Basic Tests
4
+ *
5
+ * @package ThemeIsle\ContentForms
6
+ */
7
+
8
+ /**
9
+ * Test functions in register.php
10
+ */
11
+ class Plugin_Test extends WP_UnitTestCase {
12
+
13
+ public function setUp() {
14
+ parent::setUp();
15
+ wp_set_current_user( $this->factory->user->create( [ 'role' => 'administrator' ] ) );
16
+
17
+ do_action( 'init' );
18
+ do_action( 'plugins_loaded' );
19
+ }
20
+
21
+ /**
22
+ * Tests test_library_availability().
23
+ *
24
+ * @covers test_library_availability
25
+ */
26
+ function test_library_availability() {
27
+ $this->assertTrue( class_exists( '\ThemeIsle\ContentForms\ContactForm') );
28
+ $this->assertTrue( class_exists( '\ThemeIsle\ContentForms\NewsletterForm') );
29
+ $this->assertTrue( class_exists( '\ThemeIsle\ContentForms\RegistrationForm') );
30
+ }
31
+
32
+
33
+ /**
34
+ * Tests if the default style can be disalbed.
35
+ *
36
+ * @covers themeisle_content_forms_register_public_assets
37
+ */
38
+ function test_posibility_to_disable_default_style() {
39
+ // the content-forms scripts should not be registered before the below function is called.
40
+ $this->assertFalse( wp_style_is( 'content-forms', 'registered' ) );
41
+
42
+ add_filter( 'themeisle_content_forms_register_default_style', '__return_false' );
43
+
44
+ themeisle_content_forms_register_public_assets();
45
+
46
+ $this->assertFalse( wp_style_is( 'content-forms', 'registered' ) );
47
+ }
48
+
49
+ /**
50
+ * Tests form default styles availability.
51
+ *
52
+ * @covers themeisle_content_forms_register_public_assets
53
+ */
54
+ function test_style_availability() {
55
+ // the content-forms scripts should not be registered before the below function is called
56
+ $this->assertFalse( wp_style_is( 'content-forms', 'registered' ) );
57
+
58
+ themeisle_content_forms_register_public_assets();
59
+
60
+ $this->assertTrue( wp_style_is( 'content-forms', 'registered' ) );
61
+ }
62
+
63
+ /**
64
+ * Tests scripts availability.
65
+ *
66
+ * @covers themeisle_content_forms_register_public_assets
67
+ */
68
+ function test_script_availability() {
69
+
70
+ // check if the function which should load assets exists
71
+ $this->assertTrue( function_exists( 'themeisle_content_forms_register_public_assets' ) );
72
+
73
+ // the content-forms scripts should not be enqueued before the aboce function is called
74
+ $this->assertFalse( wp_script_is( 'content-forms' ) );
75
+
76
+ // by default, front-end scripts are not enqueued globally. but we can do it for the sake of a test
77
+ add_filter( 'themeisle_content_forms_force_js_enqueue', '__return_true' );
78
+
79
+ themeisle_content_forms_register_public_assets();
80
+
81
+ $this->assertTrue( wp_script_is( 'content-forms' ) );
82
+ }
83
+
84
+
85
+
86
+ }
vendor/codeinwp/themeisle-content-forms/tests/test-contact-form.php ADDED
@@ -0,0 +1,113 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Contact Form Tests
4
+ *
5
+ * @package ThemeIsle\ContentForms
6
+ */
7
+
8
+ /**
9
+ * Test functions in register.php
10
+ */
11
+ class ContactFormTest extends WP_UnitTestCase {
12
+
13
+ public $form = null;
14
+
15
+ public function setUp() {
16
+ parent::setUp();
17
+ wp_set_current_user( $this->factory->user->create( [ 'role' => 'administrator' ] ) );
18
+
19
+ $this->form = \ThemeIsle\ContentForms\ContactForm::instance();
20
+ }
21
+
22
+ /**
23
+ * Each form should have defined a type.
24
+ */
25
+ function test_form_type() {
26
+ $this->assertEquals( 'contact', $this->form->get_type() );
27
+ }
28
+
29
+ /**
30
+ * Make sure that the form has a config defined.
31
+ */
32
+ function test_if_config_exists() {
33
+ $this->assertTrue( method_exists( $this->form, 'make_form_config' ) );
34
+ }
35
+
36
+ /**
37
+ * The `rest_submit_form` form is required.
38
+ */
39
+ function test_if_rest_callback_exists() {
40
+ $this->assertTrue( method_exists( $this->form, 'rest_submit_form' ) );
41
+ }
42
+
43
+ /**
44
+ * Every config must have a these keys
45
+ */
46
+ function test_if_config_is_valid() {
47
+ $config = $this->form->get_config();
48
+
49
+ $this->assertArrayHasKey( 'id', $config );
50
+ $this->assertArrayHasKey( 'title', $config );
51
+ $this->assertArrayHasKey( 'icon', $config );
52
+ $this->assertArrayHasKey( 'fields', $config );
53
+ $this->assertArrayHasKey( 'controls', $config );
54
+ }
55
+
56
+
57
+ /**
58
+ * If a request to `rest_submit_form` lacks data the method should warn about email.
59
+ */
60
+ function test_an_empty_submit() {
61
+
62
+ $return = $this->form->rest_submit_form(
63
+ array(),
64
+ array(),
65
+ 1,
66
+ 1,
67
+ 'builder'
68
+ );
69
+
70
+ $this->assertEquals( $return, array(
71
+ 'msg' => 'Invalid email.'
72
+ ) );
73
+ }
74
+
75
+ /**
76
+ * If a request to `rest_submit_form` lacks the name from data should trigger a warning
77
+ */
78
+ function test_name_warning() {
79
+
80
+ $return = $this->form->rest_submit_form(
81
+ array(),
82
+ array( 'email' => 'admin@admin.com' ),
83
+ 1,
84
+ 1,
85
+ 'builder'
86
+ );
87
+
88
+ $this->assertEquals( $return, array(
89
+ 'msg' => 'Missing name.'
90
+ ) );
91
+ }
92
+
93
+ /**
94
+ * If a request to `rest_submit_form` lacks the message from data should trigger a warning.
95
+ */
96
+ function test_message_warning() {
97
+
98
+ $return = $this->form->rest_submit_form(
99
+ array(),
100
+ array(
101
+ 'email' => 'admin@admin.com',
102
+ 'name' => 'My name',
103
+ ),
104
+ 1,
105
+ 1,
106
+ 'builder'
107
+ );
108
+
109
+ $this->assertEquals( $return, array(
110
+ 'msg' => 'Missing message.'
111
+ ) );
112
+ }
113
+ }
vendor/codeinwp/themeisle-content-forms/tests/test-newsletter-form.php ADDED
@@ -0,0 +1,73 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Contact Form Tests
4
+ *
5
+ * @package ThemeIsle\ContentForms
6
+ */
7
+
8
+ /**
9
+ * Test functions in register.php
10
+ */
11
+ class NewsletterFormTest extends WP_UnitTestCase {
12
+
13
+ public $form = null;
14
+
15
+ public function setUp() {
16
+ parent::setUp();
17
+ wp_set_current_user( $this->factory->user->create( [ 'role' => 'administrator' ] ) );
18
+
19
+ $this->form = \ThemeIsle\ContentForms\NewsletterForm::instance();
20
+ }
21
+
22
+ /**
23
+ * Each form should have defined a type.
24
+ */
25
+ function test_form_type() {
26
+ $this->assertEquals( 'newsletter', $this->form->get_type() );
27
+ }
28
+
29
+ /**
30
+ * Make sure that the form has a config defined.
31
+ */
32
+ function test_if_config_exists() {
33
+ $this->assertTrue( method_exists( $this->form, 'make_form_config' ) );
34
+ }
35
+
36
+ /**
37
+ * The `rest_submit_form` form is required.
38
+ */
39
+ function test_if_rest_callback_exists() {
40
+ $this->assertTrue( method_exists( $this->form, 'rest_submit_form' ) );
41
+ }
42
+
43
+ /**
44
+ * Every config must have a these keys
45
+ */
46
+ function test_if_config_is_valid() {
47
+ $config = $this->form->get_config();
48
+
49
+ $this->assertArrayHasKey( 'id', $config );
50
+ $this->assertArrayHasKey( 'title', $config );
51
+ $this->assertArrayHasKey( 'icon', $config );
52
+ $this->assertArrayHasKey( 'fields', $config );
53
+ $this->assertArrayHasKey( 'controls', $config );
54
+ }
55
+
56
+ /**
57
+ * If a request to `rest_submit_form` lacks data the method should warn about email.
58
+ */
59
+ function test_an_empty_submit() {
60
+
61
+ $return = $this->form->rest_submit_form(
62
+ array(),
63
+ array(),
64
+ 1,
65
+ 1,
66
+ 'builder'
67
+ );
68
+
69
+ $this->assertEquals( $return, array(
70
+ 'msg' => 'Invalid email.'
71
+ ) );
72
+ }
73
+ }
vendor/codeinwp/themeisle-content-forms/tests/test-registration-form.php ADDED
@@ -0,0 +1,139 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Contact Form Tests
4
+ *
5
+ * @package ThemeIsle\ContentForms
6
+ */
7
+
8
+ /**
9
+ * Test functions in register.php
10
+ */
11
+ class RegistrationFormTest extends WP_UnitTestCase {
12
+
13
+ public $form = null;
14
+
15
+ public function setUp() {
16
+ parent::setUp();
17
+ wp_set_current_user( $this->factory->user->create( [ 'role' => 'administrator' ] ) );
18
+
19
+ $this->form = \ThemeIsle\ContentForms\RegistrationForm::instance();
20
+ }
21
+
22
+ /**
23
+ * Each form should have defined a type.
24
+ */
25
+ function test_form_type() {
26
+ $this->assertEquals( 'registration', $this->form->get_type() );
27
+ }
28
+
29
+ /**
30
+ * Make sure that the form has a config defined.
31
+ */
32
+ function test_if_config_exists() {
33
+ $this->assertTrue( method_exists( $this->form, 'make_form_config' ) );
34
+ }
35
+
36
+ /**
37
+ * The `rest_submit_form` form is required.
38
+ */
39
+ function test_if_rest_callback_exists() {
40
+ $this->assertTrue( method_exists( $this->form, 'rest_submit_form' ) );
41
+ }
42
+
43
+ /**
44
+ * Every config must have a these keys
45
+ */
46
+ function test_if_config_is_valid() {
47
+ $config = $this->form->get_config();
48
+
49
+ $this->assertArrayHasKey( 'id', $config );
50
+ $this->assertArrayHasKey( 'title', $config );
51
+ $this->assertArrayHasKey( 'icon', $config );
52
+ $this->assertArrayHasKey( 'fields', $config );
53
+ $this->assertArrayHasKey( 'controls', $config );
54
+ }
55
+
56
+ /**
57
+ * If a request to `rest_submit_form` lacks data the method should warn about email.
58
+ */
59
+ function test_an_empty_submit() {
60
+
61
+ $return = $this->form->rest_submit_form(
62
+ array(),
63
+ array(),
64
+ 1,
65
+ 1,
66
+ 'builder'
67
+ );
68
+
69
+ $this->assertEquals( $return, array(
70
+ 'msg' => 'Invalid email.'
71
+ ) );
72
+ }
73
+
74
+ /**
75
+ * Test the case when the username is not present in the request
76
+ */
77
+ function test_username_missing() {
78
+
79
+ update_option( 'users_can_register', 1 );
80
+
81
+ $return = $this->form->rest_submit_form(
82
+ array(),
83
+ array( 'email' => 'admin@admin.com' ),
84
+ 1,
85
+ 1,
86
+ 'builder'
87
+ );
88
+
89
+ // if the username is not serverd, the email should be used instead
90
+ $this->assertEquals( $return, array(
91
+ 'success' => true,
92
+ 'msg' => 'Welcome, admin@admin.com'
93
+ ) );
94
+ }
95
+
96
+ /**
97
+ * If a request to `rest_submit_form` lacks the username from data should trigger a warning
98
+ */
99
+ function test_disabled_user_registration() {
100
+ $return = $this->form->rest_submit_form(
101
+ array(),
102
+ array(
103
+ 'username' => 'admin2',
104
+ 'email' => 'admin@admin.com',
105
+ ),
106
+ 1,
107
+ 1,
108
+ 'builder'
109
+ );
110
+
111
+ $this->assertEquals( $return, array(
112
+ 'msg' => 'This website does not allow registrations at this moment!'
113
+ ) );
114
+ }
115
+
116
+ /**
117
+ * If a request to `rest_submit_form` lacks the username from data should trigger a warning
118
+ */
119
+ function test_user_creation() {
120
+ // by default, this option is false; but we need it to test the registration
121
+ update_option( 'users_can_register', 1 );
122
+
123
+ $return = $this->form->rest_submit_form(
124
+ array(),
125
+ array(
126
+ 'username' => 'admin2',
127
+ 'email' => 'admin@admin.com',
128
+ ),
129
+ 1,
130
+ 1,
131
+ 'builder'
132
+ );
133
+
134
+ $this->assertEquals( $return, array(
135
+ 'success' => true,
136
+ 'msg' => 'Welcome, admin2'
137
+ ) );
138
+ }
139
+ }
vendor/codeinwp/themeisle-content-forms/tests/test-server.php ADDED
@@ -0,0 +1,62 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Basic Tests
4
+ *
5
+ * @package ThemeIsle\ContentForms
6
+ */
7
+
8
+ /**
9
+ * Test functions in register.php
10
+ */
11
+ class RestServerTest extends WP_UnitTestCase {
12
+
13
+ public $server = null;
14
+ private $nonce = null;
15
+
16
+ public function setUp() {
17
+ parent::setUp();
18
+ wp_set_current_user( $this->factory->user->create( [ 'role' => 'administrator' ] ) );
19
+
20
+ $this->server = \Themeisle\ContentForms\RestServer::instance();
21
+
22
+ $this->nonce = wp_create_nonce( 'content-form-1' );
23
+
24
+ do_action( 'rest_api_init' );
25
+ do_action( 'init' );
26
+ do_action( 'plugins_loaded' );
27
+ }
28
+
29
+ public function test_form_submission() {
30
+
31
+ // @TODO try to mock a request
32
+ $request = new WP_REST_Request( 'POST', '/content-forms/v1/check', array(
33
+ 'args' => array( 'nonce' => $this->nonce ),
34
+ 'form_id' => '1',
35
+ 'post_id' => '1'
36
+ ) );
37
+
38
+ $this->assertTrue( method_exists( $this->server, 'submit_form' ) );
39
+ // @TODO try to actually test the method call
40
+ }
41
+
42
+ /**
43
+ * Test the right type of class instance
44
+ */
45
+ public function test_getInstance() {
46
+ $this->assertInstanceOf( '\Themeisle\ContentForms\RestServer', \Themeisle\ContentForms\RestServer::$instance );
47
+ }
48
+
49
+ /**
50
+ * @expectedIncorrectUsage __clone
51
+ */
52
+ public function test_Clone() {
53
+ $obj_cloned = clone \Themeisle\ContentForms\RestServer::$instance;
54
+ }
55
+
56
+ /**
57
+ * @expectedIncorrectUsage __wakeup
58
+ */
59
+ public function test_Wakeup() {
60
+ unserialize( serialize( \Themeisle\ContentForms\RestServer::$instance ) );
61
+ }
62
+ }
vendor/codeinwp/themeisle-sdk/CHANGELOG.md ADDED
@@ -0,0 +1,42 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ## [3.0.5](https://github.com/Codeinwp/themeisle-sdk/compare/v3.0.4...v3.0.5) (2019-03-07)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * dashboard widget issues and recommended module inconsistency fix [#50](https://github.com/Codeinwp/themeisle-sdk/issues/50), [#49](https://github.com/Codeinwp/themeisle-sdk/issues/49), [#47](https://github.com/Codeinwp/themeisle-sdk/issues/47) ([757eb02](https://github.com/Codeinwp/themeisle-sdk/commit/757eb02))
7
+
8
+ ## [3.0.4](https://github.com/Codeinwp/themeisle-sdk/compare/v3.0.3...v3.0.4) (2019-01-28)
9
+
10
+
11
+ ### Bug Fixes
12
+
13
+ * uninstall feedback disclosure issues when one of the feedback fields is open ([4631eef](https://github.com/Codeinwp/themeisle-sdk/commit/4631eef))
14
+
15
+ ## [3.0.3](https://github.com/Codeinwp/themeisle-sdk/compare/v3.0.2...v3.0.3) (2019-01-07)
16
+
17
+
18
+ ### Bug Fixes
19
+
20
+ * **build:** fix exit code when is running outside wordpress context ([d298bb5](https://github.com/Codeinwp/themeisle-sdk/commit/d298bb5))
21
+
22
+ ## [3.0.2](https://github.com/Codeinwp/themeisle-sdk/compare/v3.0.1...v3.0.2) (2018-12-28)
23
+
24
+
25
+ ### Bug Fixes
26
+
27
+ * remove composer/installers from package requirements ([a0ad543](https://github.com/Codeinwp/themeisle-sdk/commit/a0ad543))
28
+
29
+ ## [3.0.1](https://github.com/Codeinwp/themeisle-sdk/compare/v3.0.0...v3.0.1) (2018-12-24)
30
+
31
+
32
+ ### Bug Fixes
33
+
34
+ * notifications setup triggers after all products register their n… ([999a944](https://github.com/Codeinwp/themeisle-sdk/commit/999a944))
35
+ * notifications setup triggers after all products register their notices ([ec3cacc](https://github.com/Codeinwp/themeisle-sdk/commit/ec3cacc))
36
+
37
+ # 1.0.0 (2018-12-21)
38
+
39
+
40
+ ### Features
41
+
42
+ * adds uninstall feedback privacy policy info ([ed17943](https://github.com/Codeinwp/themeisle-sdk/commit/ed17943))
vendor/codeinwp/themeisle-sdk/class-themeisle-sdk-endpoints.php DELETED
@@ -1,312 +0,0 @@
1
- <?php
2
- /**
3
- * The class that exposes endpoints.
4
- *
5
- * @package ThemeIsleSDK
6
- * @subpackage Endpoints
7
- * @copyright Copyright (c) 2017, Marius Cristea
8
- * @license http://opensource.org/licenses/gpl-3.0.php GNU Public License
9
- * @since 1.0.0
10
- */
11
- // Exit if accessed directly.
12
- if ( ! defined( 'ABSPATH' ) ) {
13
- exit;
14
- }
15
- if ( ! class_exists( 'ThemeIsle_SDK_Endpoints' ) ) :
16
- /**
17
- * Expose endpoints for ThemeIsle SDK.
18
- */
19
- final class ThemeIsle_SDK_Endpoints {
20
-
21
- const SDK_ENDPOINT = 'themeisle-sdk';
22
- const SDK_ENDPOINT_VERSION = 1;
23
-
24
- const HASH_FILE = 'themeisle-hash.json';
25
-
26
- // if true, the endpoint will expect a product slug and will return the value only for that.
27
- const PRODUCT_SPECIFIC = false;
28
-
29
- /**
30
- * @var ThemeIsle_SDK_Product $products Array of Themeisle Product.
31
- */
32
- static protected $products = array();
33
-
34
- /**
35
- * ThemeIsle_SDK_Endpoints constructor.
36
- *
37
- * @param ThemeIsle_SDK_Product $product_object Product Object.
38
- */
39
- public function __construct( $product_object ) {
40
- if ( $product_object instanceof ThemeIsle_SDK_Product ) {
41
- self::$products[] = $product_object;
42
- }
43
- $this->setup_endpoints();
44
- }
45
-
46
- /**
47
- * Setup endpoints.
48
- */
49
- private function setup_endpoints() {
50
- global $wp_version;
51
- if ( version_compare( $wp_version, '4.4', '<' ) ) {
52
- // no REST support.
53
- return;
54
- }
55
-
56
- $this->setup_rest();
57
- }
58
-
59
- /**
60
- * Setup REST endpoints.
61
- */
62
- private function setup_rest() {
63
- add_action( 'rest_api_init', array( $this, 'rest_register' ) );
64
- }
65
-
66
- /**
67
- * Registers the endpoints
68
- */
69
- function rest_register() {
70
- register_rest_route(
71
- self::SDK_ENDPOINT . '/v' . self::SDK_ENDPOINT_VERSION,
72
- '/checksum/' . ( self::PRODUCT_SPECIFIC ? '(?P<slug>.*)/' : '' ),
73
- array(
74
- 'methods' => 'GET',
75
- 'callback' => array( $this, 'checksum' ),
76
- )
77
- );
78
- }
79
-
80
- /**
81
- * The checksum endpoint.
82
- *
83
- * @param WP_REST_Request $data the request.
84
- *
85
- * @return WP_REST_Response Response or the error
86
- */
87
- function checksum( WP_REST_Request $data ) {
88
- $products = self::$products;
89
- if ( self::PRODUCT_SPECIFIC ) {
90
- $params = $this->validate_params( $data, array( 'slug' ) );
91
- foreach ( self::$products as $product ) {
92
- if ( $params['slug'] === $product->get_slug() ) {
93
- $products = array( $product );
94
- break;
95
- }
96
- }
97
- }
98
- $response = array();
99
- $custom_css = $this->has_custom_css();
100
- if ( is_bool( $custom_css ) ) {
101
- $response['custom_css'] = $custom_css;
102
- }
103
-
104
- $response['child_theme'] = $this->get_theme_properties();
105
-
106
- foreach ( $products as $product ) {
107
- $files = array();
108
- switch ( $product->get_type() ) {
109
- case 'plugin':
110
- $files = array();
111
- break;
112
- case 'theme':
113
- $files = array( 'style.css', 'functions.php' );
114
- break;
115
- }
116
-
117
- $error = '';
118
-
119
- // if any element in the $files array contains a '/', this would imply recursion is required.
120
- $diff = $this->generate_diff( $product, $files, array_reduce( $files, array( $this, 'is_recursion_required' ), false ) );
121
- if ( is_wp_error( $diff ) ) {
122
- $error = $diff->get_error_message();
123
- $diff = array();
124
- }
125
-
126
- $response['products'][] = array(
127
- 'slug' => $product->get_slug(),
128
- 'version' => $product->get_version(),
129
- 'diffs' => $diff,
130
- 'error' => $error,
131
- );
132
- }
133
-
134
- return new WP_REST_Response( array( 'checksum' => $response ) );
135
- }
136
-
137
- /**
138
- * Get the current theme properties.
139
- *
140
- * @return array Properties of the current theme.
141
- */
142
- function get_theme_properties() {
143
- if ( ! is_child_theme() ) {
144
- return false;
145
- }
146
-
147
- $properties = array();
148
- $theme = wp_get_theme();
149
- // @codingStandardsIgnoreStart
150
- $properties['name'] = $theme->Name;
151
- // @codingStandardsIgnoreEnd
152
-
153
- // get the files in the child theme.
154
- require_once( ABSPATH . 'wp-admin/includes/file.php' );
155
- WP_Filesystem();
156
- global $wp_filesystem;
157
- $path = str_replace( ABSPATH, $wp_filesystem->abspath(), get_stylesheet_directory() );
158
- $list = $wp_filesystem->dirlist( $path, false, false );
159
- if ( $list ) {
160
- $list = array_keys( self::flatten_dirlist( $list ) );
161
- $properties['files'] = $list;
162
- }
163
- return $properties;
164
- }
165
-
166
- /**
167
- * Check if custom css has been added to the theme.
168
- *
169
- * @return bool Whether custom css has been added to the theme.
170
- */
171
- private function has_custom_css() {
172
- $query = new WP_Query(
173
- array(
174
- 'post_type' => 'custom_css',
175
- 'post_status' => 'publish',
176
- 'numberposts' => 1,
177
- 'update_post_meta_cache' => false,
178
- 'update_post_term_cache' => false,
179
- )
180
- );
181
-
182
- if ( $query->have_posts() ) {
183
- $query->the_post();
184
- $content = get_the_content();
185
- // if the content contains a colon, a CSS rule has been added.
186
- return strpos( $content, ':' ) === false ? false : true;
187
- }
188
- return false;
189
- }
190
-
191
- /**
192
- * Check if recursion needs to be enabled on the WP_Filesystem by reducing the array of files to a boolean.
193
- *
194
- * @param string $carry Value of the previous iteration.
195
- * @param string $item Value of the current iteration.
196
- *
197
- * @return bool Whether to recurse or not.
198
- */
199
- function is_recursion_required( $carry, $item ) {
200
- if ( ! $carry ) {
201
- return ( strpos( $item, '/' ) !== false );
202
- }
203
- return $carry;
204
- }
205
-
206
- /**
207
- * Generate the diff of the files.
208
- *
209
- * @param ThemeIsle_SDK_Product $product Themeisle Product.
210
- * @param array $files Array of files.
211
- * @param bool $recurse Whether to recurse or not.
212
- *
213
- * @return string
214
- */
215
- private function generate_diff( $product, $files, $recurse = false ) {
216
- require_once( ABSPATH . 'wp-admin/includes/file.php' );
217
- WP_Filesystem();
218
- global $wp_filesystem;
219
-
220
- $diff = array();
221
- $path = str_replace( ABSPATH, $wp_filesystem->abspath(), plugin_dir_path( $product->get_basefile() ) );
222
- $list = $wp_filesystem->dirlist( $path, false, $recurse );
223
- // nothing found.
224
- if ( ! $list ) {
225
- return $diff;
226
- }
227
- $list = array_keys( self::flatten_dirlist( $list ) );
228
-
229
- // now let's get the valid files that actually exist.
230
- if ( empty( $files ) ) {
231
- $files = $list;
232
- } else {
233
- $files = array_intersect( $files, $list );
234
- }
235
-
236
- // fetch the calculated hashes.
237
- if ( ! $wp_filesystem->is_readable( $path . '/' . self::HASH_FILE ) ) {
238
- return new WP_Error( 'themeisle_sdk_hash_not_found', sprintf( '%s not found', self::HASH_FILE ) );
239
- }
240
-
241
- $hashes = json_decode( $wp_filesystem->get_contents( $path . '/' . self::HASH_FILE ), true );
242
- ksort( $hashes );
243
-
244
- $diff = array();
245
- foreach ( $files as $file ) {
246
- // file does not exist in the hashes.
247
- if ( ! array_key_exists( $file, $hashes ) ) {
248
- continue;
249
- }
250
- $new = md5( $wp_filesystem->get_contents( $path . $file ) );
251
- $old = $hashes[ $file ];
252
-
253
- // same hash, bail.
254
- if ( $new === $old ) {
255
- continue;
256
- }
257
- $diff[] = $file;
258
- }
259
- return $diff;
260
- }
261
-
262
- /**
263
- * Flatten the results of WP_Filesystem::dirlist() for iterating over.
264
- *
265
- * @access private
266
- *
267
- * @param array $nested_files Array of files as returned by WP_Filesystem::dirlist().
268
- * @param string $path Relative path to prepend to child nodes. Optional.
269
- * @return array $files A flattened array of the $nested_files specified.
270
- */
271
- private static function flatten_dirlist( $nested_files, $path = '' ) {
272
- $files = array();
273
- foreach ( $nested_files as $name => $details ) {
274
- $files[ $path . $name ] = $details;
275
- // Append children recursively
276
- if ( ! empty( $details['files'] ) ) {
277
- $children = self::flatten_dirlist( $details['files'], $path . $name . '/' );
278
- // Merge keeping possible numeric keys, which array_merge() will reindex from 0..n
279
- $files = $files + $children;
280
- }
281
- }
282
- return $files;
283
- }
284
-
285
- /**
286
- * Validates the parameters to the API
287
- *
288
- * @param WP_REST_Request $data the request.
289
- * @param array $params the parameters to validate.
290
- *
291
- * @return array of parameter name=>value
292
- */
293
- private function validate_params( WP_REST_Request $data, $params ) {
294
- $collect = array();
295
- foreach ( $params as $param ) {
296
- $value = sanitize_text_field( $data[ $param ] );
297
- if ( empty( $value ) ) {
298
- return new WP_Error(
299
- 'themeisle_' . $param . '_invalid', sprintf( 'Invalid %', $param ), array(
300
- 'status' => 403,
301
- )
302
- );
303
- } else {
304
- $collect[ $param ] = $value;
305
- }
306
- }
307
-
308
- return $collect;
309
- }
310
-
311
- }
312
- endif;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/codeinwp/themeisle-sdk/class-themeisle-sdk-feedback-deactivate.php DELETED
@@ -1,556 +0,0 @@
1
- <?php
2
- /**
3
- * The deactivate feedback model class for ThemeIsle SDK
4
- *
5
- * @package ThemeIsleSDK
6
- * @subpackage Feedback
7
- * @copyright Copyright (c) 2017, Marius Cristea
8
- * @license http://opensource.org/licenses/gpl-3.0.php GNU Public License
9
- * @since 1.0.0
10
- */
11
- // Exit if accessed directly.
12
- if ( ! defined( 'ABSPATH' ) ) {
13
- exit;
14
- }
15
- if ( ! class_exists( 'ThemeIsle_SDK_Feedback_Deactivate' ) ) :
16
- /**
17
- * Deactivate feedback model for ThemeIsle SDK.
18
- */
19
- class ThemeIsle_SDK_Feedback_Deactivate extends ThemeIsle_SDK_Feedback {
20
-
21
- /**
22
- * @var array $options_plugin The main options list for plugins.
23
- */
24
- private $options_plugin = array(
25
- 'I found a better plugin' => array(
26
- 'id' => 3,
27
- 'type' => 'text',
28
- 'placeholder' => 'What\'s the plugin\'s name?',
29
- ),
30
- 'I could not get the plugin to work' => array(
31
- 'id' => 4,
32
- ),
33
- 'I no longer need the plugin' => array(
34
- 'id' => 5,
35
- 'type' => 'textarea',
36
- 'placeholder' => 'If you could improve one thing about our product, what would it be?',
37
- ),
38
- 'It\'s a temporary deactivation. I\'m just debugging an issue.' => array(
39
- 'id' => 6,
40
- ),
41
- );
42
-
43
- /**
44
- * @var array $options_theme The main options list for themes.
45
- */
46
- private $options_theme = array(
47
- 'I don\'t know how to make it look like demo' => array(
48
- 'id' => 7,
49
- ),
50
- 'It lacks options' => array(
51
- 'id' => 8,
52
- ),
53
- 'Is not working with a plugin that I need' => array(
54
- 'id' => 9,
55
- 'type' => 'text',
56
- 'placeholder' => 'What is the name of the plugin',
57
- ),
58
- 'I want to try a new design, I don\'t like {theme} style' => array(
59
- 'id' => 10,
60
- ),
61
- );
62
-
63
- /**
64
- * @var array $other The other option
65
- */
66
- private $other = array(
67
- 'Other' => array(
68
- 'id' => 999,
69
- 'type' => 'textarea',
70
- 'placeholder' => 'cmon cmon tell us',
71
- ),
72
- );
73
-
74
- /**
75
- * @var string $heading_plugin The heading of the modal
76
- */
77
- private $heading_plugin = 'Quick Feedback <span>Because we care about our clients, please leave us a feedback.</span>';
78
-
79
- /**
80
- * @var string $heading_theme The heading of the modal
81
- */
82
- private $heading_theme = 'Looking to change {theme} <span> What does not work for you?</span>';
83
-
84
- /**
85
- * @var string $button_submit_before The text of the deactivate button before an option is chosen
86
- */
87
- private $button_submit_before = 'Skip &amp; Deactivate';
88
-
89
- /**
90
- * @var string $button_submit The text of the deactivate button
91
- */
92
- private $button_submit = 'Submit &amp; Deactivate';
93
-
94
- /**
95
- * @var string $button_cancel The text of the cancel button
96
- */
97
- private $button_cancel = 'Skip &amp; Deactivate';
98
-
99
- /**
100
- * @var int how many seconds before the deactivation window is triggered for themes
101
- */
102
- const AUTO_TRIGGER_DEACTIVATE_WINDOW_SECONDS = 3;
103
-
104
- /**
105
- * @var int how many days before the deactivation window pops up again for the theme
106
- */
107
- const PAUSE_DEACTIVATE_WINDOW_DAYS = 100;
108
-
109
- /**
110
- * ThemeIsle_SDK_Feedback_Deactivate constructor.
111
- *
112
- * @param ThemeIsle_SDK_Product $product_object The product object.
113
- */
114
- public function __construct( $product_object ) {
115
- parent::__construct( $product_object );
116
- }
117
-
118
- /**
119
- * Registers the hooks
120
- */
121
- public function setup_hooks_child() {
122
- global $pagenow;
123
-
124
- if ( ( $this->product->get_type() === 'plugin' && $pagenow === 'plugins.php' ) || ( $this->product->get_type() === 'theme' && $pagenow === 'theme-install.php' ) ) {
125
- add_action( 'admin_head', array( $this, 'load_resources' ) );
126
- }
127
- add_action( 'wp_ajax_' . $this->product->get_key() . __CLASS__, array( $this, 'post_deactivate' ) );
128
- }
129
-
130
- /**
131
- * Loads the additional resources
132
- */
133
- function load_resources() {
134
- add_thickbox();
135
-
136
- $id = $this->product->get_key() . '_deactivate';
137
-
138
- $this->add_css( $this->product->get_type(), $this->product->get_key() );
139
- $this->add_js( $this->product->get_type(), $this->product->get_key(), '#TB_inline?' . apply_filters( $this->product->get_key() . '_feedback_deactivate_attributes', 'width=600&height=550' ) . '&inlineId=' . $id );
140
-
141
- echo '<div id="' . $id . '" style="display:none;" class="themeisle-deactivate-box">' . $this->get_html( $this->product->get_type(), $this->product->get_key() ) . '</div>';
142
- }
143
-
144
- /**
145
- * Loads the css
146
- *
147
- * @param string $type The type of product.
148
- * @param string $key The product key.
149
- */
150
- function add_css( $type, $key ) {
151
- $suffix = 'theme' === $type ? 'theme-install-php' : 'plugins-php';
152
- ?>
153
- <style type="text/css" id="<?php echo $key; ?>ti-deactivate-css">
154
- input[name="ti-deactivate-option"] ~ div {
155
- display: none;
156
- }
157
-
158
- input[name="ti-deactivate-option"]:checked ~ div {
159
- display: block;
160
- }
161
-
162
- body.<?php echo $suffix; ?> .<?php echo $key; ?>-container #TB_window.thickbox-loading:before {
163
- background: none !important;
164
- }
165
-
166
- body.<?php echo $suffix; ?> .<?php echo $key; ?>-container #TB_title {
167
- background: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADwAAAA8CAYAAAA6/NlyAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyFpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNi1jMTQyIDc5LjE2MDkyNCwgMjAxNy8wNy8xMy0wMTowNjozOSAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIChXaW5kb3dzKSIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDpDNkVDM0M4RkYxMzMxMUU3OEMyMkQ0NTIxRTVEQ0ZBRiIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDpDNkVDM0M5MEYxMzMxMUU3OEMyMkQ0NTIxRTVEQ0ZBRiI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOkM2RUMzQzhERjEzMzExRTc4QzIyRDQ1MjFFNURDRkFGIiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOkM2RUMzQzhFRjEzMzExRTc4QzIyRDQ1MjFFNURDRkFGIi8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+KBNOswAAFtFJREFUeNrkWwmUXVWV3W/8Y81zkVAhgUwQg00IAYIRGcRuERDSKqALtVEbxRYcGzWIuhatKCYuUXQtERRtFAccQCDtckCZwpRISEIlIXMqlaGGP///ht7n3vd//YRUUkljN718a53U+++//97d95yzz3BvjDAM8fd02May4YndaZhoDErYeu/laCyN8rN16PuDAPA83mcAjjOxd8jcVypydhrlKspCSidlhPIk5T8p9/+PAP8fTrZJaaQ0UFxKiVKk/CvlU5Rk3b0C+gTKFZRvUa75/wJ4EuVcyimU2RGQdkqCkoOBDExjBoJx3Uwm5OlXt4bFrIPgTXSJK+DY59PEO8a5s0mPiEPyfUrwMieh3ED57qsTsJBhoXAOmps+gd6u85AvGtgxQEOmJcfj+vvxDsvS/hzsB5pkgA9QplJuoux59QD2g1ZUvCXhVe+4pnjxJc5gdx8SxTza1jwDY9ntMDdsBlLJQ4O2CTogRs+vBzydFmLCMm98NWl4OvL5O3Hd+09/9p8/iK/9GOjfRHZKpnHZWy7AlbfPRuK918DYTm3H3PHZWrQbVnHKtUBbh201EvSFvHLX0TLlK3ksRLG4HPPmnL7+0vfiaz8EOkwP+aduwPKbZ+DadyzBnVuPBa4nEQf+/hqW0zKvZcqkJoYmi0DTMXo2+cyltiu8oSi+HQrR3UG5+n9Fw6bFmRYJOVehUf/VAsrPacodOPtM3LcmjmPSwMz4cvzXAJEXt6C89gv49rJTcMk3zkdPL8e9e0iTVNHTTziuGTi9D5jF73oaNVg5RnLAjiywagfwp01ybiJufQOOuYMTdf9hg3s5H83oEQIWhYwOMGySf2KNFTjJchW0EMmPKB1KMx2d2LQFGCKtvPD0A1izbitnitcZbrat+T12Fi8i4C5g6y49kDkk7re/RoNtTmo+DiKmFlPupaZPbAPOp3VceSLwYD/fttrFUPlbSNsL+YgtB48QjGKmje+ceBlKlqsATBywIe82sG9TC5OhONqP2wOnucB0wRY13Cn6qQWPYgEtVNZvf8/J3RhnZAprrtjY81qkxHX3jGrtvn8esHgm0wzek6Vf76Y2Q19ncibBmymeM1Mz+H1IS2ji9XfPAuZzAm5+ajLWDn8JKfvymgprQczHyvbpGEh14f2nX89sLyVsehQmbQewKj5GBxtQzMXQ3DvyWcvxz9rPvFf9Fed+ELjnl8Q07To07FyJ3MATCDouxXmL344pO55nmsFs8avMHE8jmH1/puzmkEsarBo7n2dweCbn06YFxJizWJzFErVW5Kwez8m45VTgM08txqqhu5C0HxyDHNIIDSxedCP6Ozk5Bb6rNHzkpCWQTJqlwQcWcgkUh+NXG2b4sf1uSjDGPvQITh98Bh/5F35s6UXTovvR+eaVuPD6O/DRt8bg/uL7CK+nj75mI7DtD0CefhkUopfYkUZtDdyn75Y2kMz+wvtW6s8yMRmCaCLwG2Za6E5ch4xnoMLPZUo2g3uPPQfr25iNFob3U76BpUMTVK2JBLOmP37hU5hE5yzBvbZz2p6lyXYSiH/AvBVLCI/pRvnmG7Fy8nysYtgVEz+jIYPuu7+NSvIe2OfZMIvh4YuQevIRkxYtx6fxd662hkZOzu9257Fk/esZrlaI2arY+PY70d8yhRNZOWKWPobSS4fPFBx37YaeHkwdGrgCqfDWZGveRHAQI6GWje07EXvfRzB/0XzMn0UfzdBnH/oLwrOogTcfS7BbtSaPxL7kfp+aLayliR+nJytDEz8jnsRpDW/F45kVFTfE0rmXo7+VPOqXjygOn0f5qXgk5QnKc9Ty50MVfozbGjqyVFFwIFWM0XkioXPiB8hct9wGfI15Qmo3gnfSb3MZVW4e1SGmHtL8K1u1G1QYciyCflPqPFRK9ouN0/CJM6+LNBtOKA6Lqy6hfJri1H5jWbFUIX9D75597yM/NSWaiwfG4ZeDlpw4ldLvjXO23zOPeYMPw9/HqY5pRj+qg8/1yebYp0ktzwfNDGdgvnvcKnd6P7yKDmcTzLQE7Oc4SMflty1xA21JEyazng8v/4110uDmrrAphBXzdK47kUNYdS7j94ITEI7uhOkEh56sCefsGQ1cEotkIV3+ePKUm856txCXlKCXqLzgMIDfqEowaqQ1YaCv0URrjJyciGHu9k24+k8PsiB1EW8q6rg40S6GzPbZ3bSnOK1xAJZtHrpwmHDM4HODnDbtcAiPetNnb8x1fBFmebnK+oBHKVeOZ9JMBPEfHKDbTrBdKZMZX4gS3TDvmHjvA79BayGDYSONWKo8ce36BNZGgCd3EmyRRDt8BMw8kaNquhXmLC3vrHhOj2GXqp54POUHUVL0hQM1fBXvOjnlGOgm2Arjrcdn5VwHJ2zZggueXYEc4tSOD8vxxupW4zDAJcuaxBDSmUaQzzKS5HXV87cowWFMgWPElBtSHLPGW1I/L64HzGwB75KTjqShrI3JlBprgbnoPz3xONqZrVRoEKYVQrGzmJSkhgJ6PABGBLiPBBW3SJySXHhjJd8rfhiK/CVtF8X1pk3EdP4iL/x36ZOZtUonxClJ3iQ3lqldscQK70tmczj/mRUoE6z8TqolBboKWDqSVeDjabvZ0n7MxCH0A/ytjqyf5msspTCxTpvDEdCmHtZrKYuqgC8VbTe5ot1QZWjyg6ztYNbmzZi+Y5tkViqlNKhdQ4BVw45Dc3Uj0CIHalvuFfsJyuqrMLReAcI6+DGCHsX+AccZRPSR4JCa40bVtF8no4tJ4a7GxXELWLnRDyUBt7DghReQCop8gHFAmhdGPWd7f007ddqu4hLt+gX6vuTJCX4MXnHvlVRzS2lmrfgQxYVROtDg1sb+D6Zql4Y4PsY6ltasAQfanA3Px4xtWyIXqFZd9EXF0KFuw4h2rQioAu3UmbmpQUtiIKHDFKtoQTlb0t+9YkeFFtmNFUNMJw0ydGjUwErH16VNR6/rkT9zJCSJc8tNnjLnkD5rIp3N44TB7UzHx8KI75mcxGiw5XIENgLp2AdoPLq2Tx6aV1qOt01CcUieUTk8w0848SpjXeFUPDvUQmCBAloFK2IyZzC1jlIy8mnqN2bVlDWPlqnVhlwO7SOj/DymjYCARdRgBbA8yHXHfLhewwJW/GSbaJkaDrKwk0m4bXMwujkLv1JSWaJ6vIyoKvJMSWwM6XuVyXWM374kO8FBJknYKYn1T07hKzxyjPbfsE7qWoEyIsxU8SliNvFdZdJ8sctEIVEq1/xXDCVkdVQpOHAk+ZDYVSCQpubIj0w9SDVoQycnTGIwyAcOcBr7mAp6MSS6ephenonsrrX06wzcRJSLmJoMaYD0FpvjINsZbeQhxvAKx5HfiFR7hWltXV9bUtyB45G6YzPMS0scq1XTcFjT8Jiz26r0k4nlVS9ATUJ+jpVKcFgD1/uwvKY4GkeyI6fnbZQgWlt0fSqrDPJ039DgxfSFmkd5/Uk+9DiadSWrfhZjgRxrWohyIY+glFcmboQmgcdYVzTDdJs4KQ0E18RrBGi5KA3vRqb/e2jsLfKxjp5ctxW4mwnRmgHFlZ7y33BMwxHVBDqSlgVwuxF94YU6u/KV8UtzkjE3Yrux0B4qwGHF4kB4U5GmNkoQba21RoGWqI8soMVzHufnN1CaWc/6jh4N73HTSdJoS9TlqIoVdTwkhPH54u+Bg1hbL7zhhfByD8BtciS7AJa3oXD3Ls73ND7Oh7TpqiYtMELolkBkEFmzuqajTDnyYb/6i4NkRAKYZSdBM5pZUWjas0f/KBar8+U6ApNguJevepD3S1oq5WFYjjqT9GOPbiEpZ00KWgLpcVV0p0OE1uE0dHGiCLSBz3osicqyvchk5V1mzb9rJh2pStrdUSDca0buq8ZbZWgvMt4SycejnRgHKYCkiad8VF5C08fOnWPsXGXsGmh+bqTJ/5Gv+4skeOL/uxWJVTMwMuH+f2vnVcCVKMaWYIiKfsf33pLF8EuuKtsrDv1eIkagDTqo8+OSF1Y1vM6MNF5LOJT/Rg5QJPuWGGfNAzoH8rk4EkdxOKGb8uI8+6i1wUHdxKuxdB14N5J7ONCnKEkBRMuo7NXaRtSDluEoYNXzYIxn42KFW2H8mr/9RoD8YAK5bJqG7yGXSMC3rJqGa2YtU1RbnsJacZS9QlyS45vRzETxB3kOcJQAmlnlAC8v6Ya2NaG7saTSTbUSsX2H1mZ3J99i6BaPYYyJpO5Fyvd8zdxn82Ux+nSZBOinOIBG3cEQkgqicCXEZEvSQlm5De6d62CtcMmPDvYNtCh05GXsaGmlm/Pd5aI230hpokBZoeF8+VXA2yX58ALNxYrMOMNhpYJhFv4bWzswbe+gWp4/0JdL+RiGCbplCrVbbeYx91Ya6u2l9jy9hUHFV1NPgISpMuUXPF8VgZ7O8zSBm6MRUdmatITtZa1pE8H+gdHg90xP88yVYw72bGiHR841VdAMsbp7kn5HqJspSsOGNueK1uJW6cvZ0Yr6BWOa9RnfPSU+zbm/vRMX9P91nGIsxMiuBrXkku6kFXhV0FsYn8mufX3UakL7uBFpu8ri0vXYxGvfpbRR+qQ/ymE2+nqhf4TnWzlhLxLwFko+VGwfsHzd3d+OYjamwIp2C2T21cccq0mwluqHKsUs+DV3FJy7BfCDlE+q7ocCW1Ga0H+BZ6YcC+8xs6b9AwHLRO3a1KxCTLo9r8OQaGcX/ZmlJSZz5pv5vR1qbVc3usgT04a+f4R/VxDg414UNH3USjaJ55KvM8Hw6Q4717eiRP5wIt5leoLdqUb0d3VANe/qxik/r/PfX1cbAOTN8F7RqMkSzvA9DVYYkgnBo32TsT3Vwhf44y4/BjTnLRtbMTSQ1pwvaaGQlmRh617UMjwytvovImvDVUJL8LzBlrKGk0CRxSdh9WaGuTSvxwzkMzG8tJYxl2DdCFKoSj0Pz07qow83wygXUQ1Gmp1R5SQx598qwAZ1bwTBZw2/sgu+NmVEJm0z192VTuGxqceypK1gvCpW6ksh602bmrCV4rGiUhqVBN3k+fAwTZOgX1jDV/PdmYzWpLCqG9XTMgFy7lRragkbJKB8EQMbXWxY08yCy1Wldf3CiVS/D594orIaQ1mo7pULCZfHNsfcSxnU+7Sk7RJiA5/+Sf7gzv1MWkyLL//ZSSfirc8/zzwjPKAuHnt5Ujieyf3OXUkMZ1z09mTR0soUUIBX15IlKxOti7nXJyhG3Sq/76kmurx+eNjFjp2NJPE4Gvn8GIz9Jl2UsLmhDQ/PnKUX2eQdQri81w9q95JR8c0xi4wiMjV9l+GX51C7HzUi4hJN28UAj0yZhGe6e3Dqzu3Iwh23G5siMGmrDBdsrNnYgPSuBDoIurWpzCTMZ4IU+a56pRexeFhXaxsoknn3jiSxZyiGQs5BOrTQRgDmAWCrgH8697UYbOZ00BoNy9HRgn4fmrWGrCwobKgDnNAxTmvu0wQ7jdq9WJk1NW3zb9G1cMcpc3Dab7brimmcJpzyKYLu5PAkaR3OGViXt2EPkNASHhqZbCQI3LGDagRRIMuUfNFGJm+xxONAPQspPqNLadXcr8yrHi45ZWeiEXedOo+2WyJ1cGRq+cZSZaTkBtT0V3jh9v04x3SeQpibxxtGRKPSLriaoNtpWgurmnaLJfxqxhRc8WwfXrd9G0Zgjdt3rA6skeWdLEEXGY4ynLgcZ2AoK9SnSa32+9BQnmhT4jxvJcAUn+9EXYvxmkEpavfW+QuxpZ2ESu2GaoVfp6msukbD0FrCRy57Wa8g9p5f0s+eRzi0AIYnhWmZEc94yPTKi0hkvaJpiw5VJE+v7whx0Ysb4Pr2YZeFor6m0riYZRMhNfJvo3wmoJQ6t9DMJKOV0hY6PLcI+uDmW//cBpTxdFcvPn7hBZxAQ2l3LKMz/0jbvoqgfnawBTvLeRvhpVfDSD3Hp3GWStKkdzJGJfaQEeTONYJyl1FxOePD2HT2UnrALrxx5SSUEE60vVYDL3bhEk6cwJIEFuNfV5X7Ri3OH+6pYsoVMvn7Lv5HvNTWBlfiOlSltJl+chOB/htls+ztODjgxbKKx9fGNsFs+gPM9ntZkrK+tEdGjHz3b81ifD7cHZPDObfAbFmJJ2ZmMXVLA07d2oa8mt8j7i++TCa+ZhgyGnhYsuhM/Oqk6YiXmDeY5mBoWt8kwA9QHmYY9BXYcQDbtWEECf3XGoLR8X2QMSgztgT5rvuQ2ngG0ttglRLw3AAfvfZpdIzE8PrVnRhGpa67ZEZtfh0fxwCadZVW9bpRIz8j+nSo60Jdab7rK/Pm4tvzZiNeLA7CjP2ARHUbtfvShNcmEj9JtEWl0J66TZ6S2b4OZmkx06+FLDSVFdRWP8m07QT8nS/NxzmruzEkoGMBUhcW4E4vo9zvIv/LJIKyLLP6SF2Uh9PnofRXF7n7Eyp0WC28fnEOdpeP4tMMQcvjasKc7gqSb8nDag5QfDSO/J8lswoU2K/PnYUbz16wwTGdH5pm7K7QcjZSFGGFJsWOxIrxL8W0Dgp4drSzzVHNSr3Fty3a0jv+ki9BNzHkfHXpPFzy5CTElg0geWlG0yqDcf7HDdjzuVZ0LtuN+Hl5XWyzasrc3ozh25rQ+d1diJ1WrDWbRm5uRebeNLp/NAB7dinaZ2lg9DOt2Ht3E76+YMajSxfM/QFJ7Sem6exToBTYIwcsfxdR7o7ATsw0JFelVg1iuXXzdFy7uEHFT5BtmQUwQlRQejyO+MKC6lQq77HKCAs+ys/FEDtLth/FdP/KLiEYZhnX7yB2ulyXriSvx3i+r1z6ycfmfehtfed/H+1WOc2iIqiCOgrAJC21sYRFLO6LAM+e6Hq0RQ2ULQ99cwy8OdHNCyIs4o0043ce9hQBm6Tt9PB6g4qehpGFPZlAPH52u/X1MAnDzcCeRAMrs7Jy5DoLkYATksoWEyflbyqY7s7n9/WgUIrBdkNNSgKoKkbd+SFIq/6KOP5llPOjnaq7J7QIz/LOzUlY4ODcTmqL3uB06hXYkpR3BGx31V3nfaVQA3Wi+90u1ZVU99ukEIelnt2uvy+45tSpQ6nvXPgAnrrsDlwxaxUrRwsFz8HRHPYBw1+ktv8CA9FC7oSOuBnuYaLcBrvDqHU7jfU6T5LNKwJA9aaCqKMRRDvsOnV3RJp0og11Pa0nSMrRIK9VUtLLE3M6d+Dui36IM57ehqWr3oD+zGRYTFmtowQcQv9HC9Hy6ye42WCfZeDz81NSxFpfVqZbXVU0qsCk5OvV8xdGSyWmdD9oAW5v1I2sjO3ZkL2V1fv90aoidJzypca2cc3Jf8a7pq/CHS8uwJfXnIvthW7FsbI74Uj3Sz9GOScC/fNqDXmQTRXS87mlFARnzYwnll3U1JZFmR7g7dba9Bjh1F4Ot4IKjSUY0vslKzs0CLle3qZ70GLS5c16c4rBqqL8kloN1PsqX9K9aea7+42gHEfaKeLDJz+MNRd/HjedfB+unPYnloQWg4F52Dh8qO8lHk+Jtv+INWSjpp+MarjAYvvnfVNxSXOrlJWP8pY07BaClRLUl//g8Fma7FJqmfVAU3Q9WMfrzFF9ZkdxQ5GTtGoN40lev4cfblVmbST0xBnmI/xHdhcVDo6A8++UlH0+t28qrlxxPVbnZnBOjYOy9OG2Hm6OZPz9/q6EHNG4eTlHuIQaPY7mzN+Yn1N9JMMq0mQ/icquHmpwLa/LXotHVPEalD5EP23l9VUc+fUc9UoOKQU/9x7OLSndelJfHwesckRqtKyVdnLbOjQ4hUPuATP+3v4r3n8LMAAsR90w+kkNLQAAAABJRU5ErkJggg==') 40px 30px no-repeat;
168
- border: none;
169
- box-sizing: border-box;
170
- color: #373e40;
171
- font-size: 24px;
172
- font-weight: 700;
173
- height: 90px;
174
- padding: 40px 40px 0 120px;
175
- text-transform: uppercase;
176
- width: 100%;
177
- }
178
-
179
- body.<?php echo $suffix; ?> .<?php echo $key; ?>-container div.actions {
180
- box-sizing: border-box;
181
- padding: 30px 40px;
182
- background-color: #eaeaea;
183
- }
184
-
185
- body.<?php echo $suffix; ?> .<?php echo $key; ?>-container input.button {
186
- background: #ec5d60;
187
- border: none;
188
- box-shadow: none;
189
- color: #ffffff;
190
- font-size: 15px;
191
- font-weight: 700;
192
- height: auto;
193
- line-height: 20px;
194
- padding: 10px 15px;
195
- text-transform: uppercase;
196
- -webkit-transition: 0.3s ease;
197
- -moz-transition: 0.3s ease;
198
- -ms-transition: 0.3s ease;
199
- -o-transition: 0.3s ease;
200
- transition: 0.3s ease;
201
- }
202
-
203
- body.<?php echo $suffix; ?> .<?php echo $key; ?>-container input.button.button-primary {
204
- background: transparent;
205
- box-shadow: none;
206
- color: #8d9192;
207
- font-weight: 400;
208
- float: right;
209
- line-height: 40px;
210
- padding: 0;
211
- text-decoration: underline;
212
- text-shadow: none;
213
- text-transform: none;
214
- }
215
-
216
- body.<?php echo $suffix; ?> .<?php echo $key; ?>-container input.button:hover {
217
- background: #e83f42;
218
- }
219
-
220
- body.<?php echo $suffix; ?> .<?php echo $key; ?>-container input.button.button-primary:hover {
221
- background: transparent;
222
- }
223
-
224
- body.<?php echo $suffix; ?> .<?php echo $key; ?>-container input.button:focus {
225
- box-shadow: none;
226
- outline: none;
227
- }
228
-
229
- body.<?php echo $suffix; ?> .<?php echo $key; ?>-container input.button:active {
230
- box-shadow: none;
231
- transform: translateY(0);
232
- }
233
-
234
- body.<?php echo $suffix; ?> .<?php echo $key; ?>-container input.button:disabled {
235
- cursor: not-allowed;
236
- }
237
-
238
- body.<?php echo $suffix; ?> .<?php echo $key; ?>-container input.button.button-primary:hover {
239
- text-decoration: none;
240
- }
241
-
242
- body.<?php echo $suffix; ?> .<?php echo $key; ?>-container div.revive_network-container {
243
- background-color: #ffffff;
244
- }
245
-
246
- body.<?php echo $suffix; ?> .<?php echo $key; ?>-container ul.ti-list {
247
- margin: 0;
248
- }
249
-
250
- body.<?php echo $suffix; ?> .<?php echo $key; ?>-container ul.ti-list li {
251
- color: #373e40;
252
- font-size: 13px;
253
- margin-bottom: 5px;
254
- }
255
-
256
- body.<?php echo $suffix; ?> .<?php echo $key; ?>-container ul.ti-list li label {
257
- margin-left: 10px;
258
- line-height: 28px;
259
- font-size: 15px;
260
- }
261
-
262
- body.<?php echo $suffix; ?> .<?php echo $key; ?>-container ul.ti-list input[type=radio] {
263
- margin-top: 1px;
264
- }
265
-
266
- body.<?php echo $suffix; ?> .<?php echo $key; ?>-container #TB_ajaxContent {
267
- box-sizing: border-box;
268
- height: auto !important;
269
- padding: 20px 40px;
270
- width: 100% !important;
271
- }
272
-
273
- body.<?php echo $suffix; ?> .<?php echo $key; ?>-container li div textarea {
274
- padding: 10px 15px;
275
- width: 100%;
276
- }
277
-
278
- body.<?php echo $suffix; ?> .<?php echo $key; ?>-container ul.ti-list li div {
279
- margin: 10px 30px;
280
- }
281
-
282
- .<?php echo $key; ?>-container #TB_title #TB_ajaxWindowTitle {
283
- box-sizing: border-box;
284
- display: block;
285
- float: none;
286
- font-weight: 700;
287
- line-height: 1;
288
- padding: 0;
289
- text-align: left;
290
- width: 100%;
291
- }
292
-
293
- .<?php echo $key; ?>-container #TB_title #TB_ajaxWindowTitle span {
294
- color: #8d9192;
295
- display: block;
296
- font-size: 15px;
297
- font-weight: 400;
298
- margin-top: 5px;
299
- text-transform: none;
300
- }
301
-
302
- body.<?php echo $suffix; ?> .<?php echo $key; ?>-container .actions {
303
- width: 100%;
304
- display: block;
305
- position: absolute;
306
- left: 0;
307
- bottom: 0;
308
- }
309
-
310
- .theme-install-php .<?php echo $key; ?>-container #TB_closeWindowButton .tb-close-icon:before {
311
- font-size: 32px;
312
- }
313
-
314
- .<?php echo $key; ?>-container #TB_closeWindowButton .tb-close-icon {
315
- color: #eee;
316
- }
317
-
318
- .<?php echo $key; ?>-container #TB_closeWindowButton {
319
- left: auto;
320
- right: -5px;
321
- top: -35px;
322
- color: #eee;
323
- }
324
-
325
- .<?php echo $key; ?>-container #TB_closeWindowButton .tb-close-icon {
326
- text-align: right;
327
- line-height: 25px;
328
- width: 25px;
329
- height: 25px;
330
- }
331
-
332
- .<?php echo $key; ?>-container #TB_closeWindowButton:focus .tb-close-icon {
333
- box-shadow: none;
334
- outline: none;
335
- }
336
-
337
- .<?php echo $key; ?>-container #TB_closeWindowButton .tb-close-icon:before {
338
- font: normal 25px dashicons;
339
- }
340
-
341
- body.<?php echo $suffix; ?> .<?php echo $key; ?>-container {
342
- margin: auto !important;
343
- height: 500px !important;
344
- top: 0 !important;
345
- left: 0 !important;
346
- bottom: 0 !important;
347
- right: 0 !important;
348
- width: 600px !important;
349
- }
350
- </style>
351
- <?php
352
- }
353
-
354
- /**
355
- * Loads the js
356
- *
357
- * @param string $type The type of product.
358
- * @param string $key The product key.
359
- * @param string $src The url that will hijack the deactivate button url.
360
- */
361
- function add_js( $type, $key, $src ) {
362
- $heading = 'plugin' === $type ? $this->heading_plugin : str_replace( '{theme}', $this->product->get_name(), $this->heading_theme );
363
- $heading = apply_filters( $this->product->get_key() . '_feedback_deactivate_heading', $heading );
364
- ?>
365
- <script type="text/javascript" id="ti-deactivate-js">
366
- (function ($) {
367
- $(document).ready(function () {
368
- var auto_trigger = false;
369
- var target_element = 'tr[data-plugin^="<?php echo $this->product->get_slug(); ?>/"] span.deactivate a';
370
- <?php
371
- if ( 'theme' === $type ) {
372
- ?>
373
- auto_trigger = true;
374
- if ($('a.ti-auto-anchor').length == 0) {
375
- $('body').append($('<a class="ti-auto-anchor" href=""></a>'));
376
- }
377
- target_element = 'a.ti-auto-anchor';
378
- <?php
379
- }
380
- ?>
381
-
382
- if (auto_trigger) {
383
- setTimeout(function () {
384
- $('a.ti-auto-anchor').trigger('click');
385
- }, <?php echo self::AUTO_TRIGGER_DEACTIVATE_WINDOW_SECONDS * 1000; ?> );
386
- }
387
- $(document).on('thickbox:removed', function () {
388
- $.ajax({
389
- url: ajaxurl,
390
- method: 'post',
391
- data: {
392
- 'action': '<?php echo $key . __CLASS__; ?>',
393
- 'nonce': '<?php echo wp_create_nonce( (string) __CLASS__ ); ?>',
394
- 'type': '<?php echo $type; ?>',
395
- 'key': '<?php echo $key; ?>'
396
- },
397
- });
398
- });
399
- var href = $(target_element).attr('href');
400
- $('#<?php echo $key; ?>ti-deactivate-no').attr('data-ti-action', href).on('click', function (e) {
401
- e.preventDefault();
402
- e.stopPropagation();
403
-
404
- $('body').unbind('thickbox:removed');
405
- tb_remove();
406
- var redirect = $(this).attr('data-ti-action');
407
- if (redirect != '') {
408
- location.href = redirect;
409
- }
410
- });
411
-
412
- $('#<?php echo $key; ?> ul.ti-list label, #<?php echo $key; ?> ul.ti-list input[name="ti-deactivate-option"]').on('click', function (e) {
413
- $('#<?php echo $key; ?>ti-deactivate-yes').val($('#<?php echo $key; ?>ti-deactivate-yes').attr('data-after-text'));
414
-
415
- var radio = $(this).prop('tagName') === 'LABEL' ? $(this).parent() : $(this);
416
- if (radio.parent().find('textarea').length > 0 && radio.parent().find('textarea').val().length === 0) {
417
- $('#<?php echo $key; ?>ti-deactivate-yes').attr('disabled', 'disabled');
418
- radio.parent().find('textarea').on('keyup', function (ee) {
419
- if ($(this).val().length === 0) {
420
- $('#<?php echo $key; ?>ti-deactivate-yes').attr('disabled', 'disabled');
421
- } else {
422
- $('#<?php echo $key; ?>ti-deactivate-yes').removeAttr('disabled');
423
- }
424
- });
425
- } else {
426
- $('#<?php echo $key; ?>ti-deactivate-yes').removeAttr('disabled');
427
- }
428
- });
429
-
430
- $('#<?php echo $key; ?>ti-deactivate-yes').attr('data-ti-action', href).on('click', function (e) {
431
- e.preventDefault();
432
- e.stopPropagation();
433
- $.ajax({
434
- url: ajaxurl,
435
- method: 'post',
436
- data: {
437
- 'action': '<?php echo $key . __CLASS__; ?>',
438
- 'nonce': '<?php echo wp_create_nonce( (string) __CLASS__ ); ?>',
439
- 'id': $('#<?php echo $key; ?> input[name="ti-deactivate-option"]:checked').parent().attr('ti-option-id'),
440
- 'msg': $('#<?php echo $key; ?> input[name="ti-deactivate-option"]:checked').parent().find('textarea').val(),
441
- 'type': '<?php echo $type; ?>',
442
- 'key': '<?php echo $key; ?>'
443
- },
444
- });
445
- var redirect = $(this).attr('data-ti-action');
446
- if (redirect != '') {
447
- location.href = redirect;
448
- } else {
449
- $('body').unbind('thickbox:removed');
450
- tb_remove();
451
- }
452
- });
453
-
454
- $(target_element).attr('name', '<?php echo wp_kses( $heading, array( 'span' => array() ) ); ?>').attr('href', '<?php echo $src; ?>').addClass('thickbox');
455
- var thicbox_timer;
456
- $(target_element).on('click', function () {
457
- tiBindThickbox();
458
- });
459
-
460
- function tiBindThickbox() {
461
- var thicbox_timer = setTimeout(function () {
462
- if ($("#<?php echo esc_html( $key ); ?>").is(":visible")) {
463
- $("body").trigger('thickbox:iframe:loaded');
464
- $("#TB_window").addClass("<?php echo $key; ?>-container");
465
- clearTimeout(thicbox_timer);
466
- $('body').unbind('thickbox:removed');
467
- } else {
468
- tiBindThickbox();
469
- }
470
- }, 100);
471
- }
472
- });
473
- })(jQuery);
474
- </script>
475
- <?php
476
- }
477
-
478
- /**
479
- * Generates the HTML
480
- *
481
- * @param string $type The type of product.
482
- * @param string $key The product key.
483
- */
484
- function get_html( $type, $key ) {
485
- $options = 'plugin' === $type ? $this->options_plugin : $this->options_theme;
486
- $button_submit_before = 'plugin' === $type ? $this->button_submit_before : 'Submit';
487
- $button_submit = 'plugin' === $type ? $this->button_submit : 'Submit';
488
- $options = $this->randomize_options( apply_filters( $this->product->get_key() . '_feedback_deactivate_options', $options ) );
489
- $button_submit_before = apply_filters( $this->product->get_key() . '_feedback_deactivate_button_submit_before', $button_submit_before );
490
- $button_submit = apply_filters( $this->product->get_key() . '_feedback_deactivate_button_submit', $button_submit );
491
- $button_cancel = apply_filters( $this->product->get_key() . '_feedback_deactivate_button_cancel', $this->button_cancel );
492
-
493
- $options += $this->other;
494
-
495
- $list = '';
496
- foreach ( $options as $title => $attributes ) {
497
- $id = $attributes['id'];
498
- $list .= '<li ti-option-id="' . $id . '"><input type="radio" name="ti-deactivate-option" id="' . $key . $id . '"><label for="' . $key . $id . '">' . str_replace( '{theme}', $this->product->get_name(), $title ) . '</label>';
499
- if ( array_key_exists( 'type', $attributes ) ) {
500
- $list .= '<div>';
501
- $placeholder = array_key_exists( 'placeholder', $attributes ) ? $attributes['placeholder'] : '';
502
- switch ( $attributes['type'] ) {
503
- case 'text':
504
- $list .= '<textarea style="width: 100%" rows="1" name="comments" placeholder="' . $placeholder . '"></textarea>';
505
- break;
506
- case 'textarea':
507
- $list .= '<textarea style="width: 100%" rows="2" name="comments" placeholder="' . $placeholder . '"></textarea>';
508
- break;
509
- }
510
- $list .= '</div>';
511
- }
512
- $list .= '</li>';
513
- }
514
-
515
- return '<div id="' . $this->product->get_key() . '">'
516
- . '<ul class="ti-list">' . $list . '</ul>'
517
- . '<div class="actions">'
518
- . get_submit_button(
519
- $button_submit, 'secondary', $this->product->get_key() . 'ti-deactivate-yes', false, array(
520
- 'data-after-text' => $button_submit,
521
- 'disabled' => true,
522
- )
523
- )
524
- . get_submit_button( $button_cancel, 'primary', $this->product->get_key() . 'ti-deactivate-no', false )
525
- . '</div></div>';
526
- }
527
-
528
- /**
529
- * Called when the deactivate button is clicked
530
- */
531
- function post_deactivate() {
532
- check_ajax_referer( (string) __CLASS__, 'nonce' );
533
-
534
- if ( ! empty( $_POST['id'] ) ) {
535
- $this->call_api(
536
- array(
537
- 'type' => 'deactivate',
538
- 'id' => $_POST['id'],
539
- 'comment' => isset( $_POST['msg'] ) ? $_POST['msg'] : '',
540
- )
541
- );
542
- }
543
-
544
- $this->post_deactivate_or_cancel();
545
- }
546
-
547
- /**
548
- * Called when the deactivate/cancel button is clicked
549
- */
550
- private function post_deactivate_or_cancel() {
551
- if ( isset( $_POST['type'] ) && isset( $_POST['key'] ) && 'theme' === $_POST['type'] ) {
552
- set_transient( 'ti_sdk_pause_' . $_POST['key'], true, PAUSE_DEACTIVATE_WINDOW_DAYS * DAY_IN_SECONDS );
553
- }
554
- }
555
- }
556
- endif;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/codeinwp/themeisle-sdk/class-themeisle-sdk-feedback-factory.php DELETED
@@ -1,50 +0,0 @@
1
- <?php
2
- /**
3
- * The feedback factory class for ThemeIsle SDK
4
- *
5
- * @package ThemeIsleSDK
6
- * @subpackage Feedback
7
- * @copyright Copyright (c) 2017, Marius Cristea
8
- * @license http://opensource.org/licenses/gpl-3.0.php GNU Public License
9
- * @since 1.0.0
10
- */
11
- // Exit if accessed directly.
12
- if ( ! defined( 'ABSPATH' ) ) {
13
- exit;
14
- }
15
- if ( ! class_exists( 'ThemeIsle_SDK_Feedback_Factory' ) ) :
16
- /**
17
- * Feedback model for ThemeIsle SDK.
18
- */
19
- class ThemeIsle_SDK_Feedback_Factory {
20
-
21
- /**
22
- * @var array $instances collection of the instances that are registered with the factory
23
- */
24
- private $_instances = array();
25
-
26
- /**
27
- * ThemeIsle_SDK_Feedback_Factory constructor.
28
- *
29
- * @param ThemeIsle_SDK_Product $product_object Product Object.
30
- * @param array $feedback_types the feedback types.
31
- */
32
- public function __construct( $product_object, $feedback_types ) {
33
- if ( $product_object instanceof ThemeIsle_SDK_Product && $feedback_types && is_array( $feedback_types ) ) {
34
- foreach ( $feedback_types as $type ) {
35
- $class = 'ThemeIsle_SDK_Feedback_' . ucwords( $type );
36
- $instance = new $class( $product_object );
37
- $this->_instances[ $type ] = $instance;
38
- $instance->setup_hooks();
39
- }
40
- }
41
- }
42
-
43
- /**
44
- * Get the registered instances
45
- */
46
- public function get_instances() {
47
- return $this->_instances;
48
- }
49
- }
50
- endif;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/codeinwp/themeisle-sdk/class-themeisle-sdk-feedback-review.php DELETED
@@ -1,209 +0,0 @@
1
- <?php
2
- /**
3
- * The review feedback model class for ThemeIsle SDK
4
- *
5
- * @package ThemeIsleSDK
6
- * @subpackage Feedback
7
- * @copyright Copyright (c) 2017, Marius Cristea
8
- * @license http://opensource.org/licenses/gpl-3.0.php GNU Public License
9
- * @since 1.0.0
10
- */
11
- // Exit if accessed directly.
12
- if ( ! defined( 'ABSPATH' ) ) {
13
- exit;
14
- }
15
- if ( ! class_exists( 'ThemeIsle_SDK_Feedback_Review' ) ) :
16
- /**
17
- * Deactivate feedback model for ThemeIsle SDK.
18
- */
19
- class ThemeIsle_SDK_Feedback_Review extends ThemeIsle_SDK_Feedback {
20
-
21
- /**
22
- * @var string $heading The heading of the modal
23
- */
24
- private $heading = 'Hey, it’s great to see you have <b>{product}</b> active for a few days now. How is everything going? If you can spare a few moments to rate it on WordPress.org it would help us a lot (and boost my motivation). Cheers! <br/> <br/>~ {developer}, developer of {product}';
25
-
26
- /**
27
- * @var string $msg The text of the modal
28
- */
29
- private $msg = '';
30
-
31
- /**
32
- * @var string $button_cancel The text of the cancel button
33
- */
34
- private $button_cancel = 'No, thanks.';
35
- /**
36
- * @var array Developers who work for each type of product for review purpose.
37
- */
38
- private $developers = array(
39
- 'plugin' => array( 'Marius', 'Bogdan' ),
40
- 'theme' => array( 'Rodica', 'Andrei', 'Bogdan', 'Cristi' ),
41
- );
42
- /**
43
- * @var string $button_already The text of the already did it button
44
- */
45
- private $button_do = 'Ok, I will gladly help.';
46
-
47
- /**
48
- * ThemeIsle_SDK_Feedback_Deactivate constructor.
49
- *
50
- * @param ThemeIsle_SDK_Product $product_object The product object.
51
- */
52
- public function __construct( $product_object ) {
53
- parent::__construct( $product_object );
54
- }
55
-
56
- /**
57
- * Registers the hooks
58
- */
59
- public function setup_hooks_child() {
60
- add_action( 'wp_ajax_' . $this->product->get_key() . __CLASS__, array( $this, 'dismiss' ) );
61
- }
62
-
63
- /**
64
- * Either we can notify or not.
65
- *
66
- * @return bool Notification available or not.
67
- */
68
- public function can_notify() {
69
- if ( ! $this->product->is_wordpress_available() ) {
70
- $this->disable();
71
-
72
- return false;
73
- }
74
- $show = get_option( $this->product->get_key() . '_review_flag', 'yes' );
75
- if ( 'no' === $show ) {
76
- return false;
77
- }
78
- $finally_show = apply_filters( $this->product->get_key() . '_feedback_review_trigger', true );
79
- if ( false !== $finally_show ) {
80
- if ( is_array( $finally_show ) && ! empty( $finally_show ) ) {
81
- $this->heading = $finally_show['heading'];
82
- $this->msg = $finally_show['msg'];
83
- }
84
- } else {
85
- return false;
86
- }
87
-
88
- return true;
89
- }
90
-
91
- /**
92
- * Shows the notification
93
- */
94
- function show_notification() {
95
- add_action( 'admin_notices', array( $this, 'admin_notices' ) );
96
- }
97
-
98
- /**
99
- * Shows the admin notice
100
- */
101
- function admin_notices() {
102
- $id = $this->product->get_key() . '_review';
103
-
104
- $this->add_css( $this->product->get_key() );
105
- $this->add_js( $this->product->get_key() );
106
-
107
- echo '<div class="notice notice-success is-dismissible" id="' . $id . '" ><div class="themeisle-review-box">' . $this->get_html( $this->product->get_key() ) . '</div></div>';
108
- }
109
-
110
- /**
111
- * Loads the css
112
- *
113
- * @param string $key The product key.
114
- */
115
- function add_css( $key ) {
116
- ?>
117
- <style type="text/css" id="<?php echo $key; ?>ti-review-css">
118
- #<?php echo $key; ?>-review-notification {
119
- padding-bottom: 5px;
120
- }
121
-
122
- #<?php echo $key; ?>-review-notification .review-dismiss {
123
- margin-left: 5px;
124
- }
125
- </style>
126
- <?php
127
- }
128
-
129
- /**
130
- * Loads the js
131
- *
132
- * @param string $key The product key.
133
- */
134
- function add_js( $key ) {
135
- ?>
136
- <script type="text/javascript" id="<?php echo $key; ?>ti-review-js">
137
- (function ($) {
138
- $(document).ready(function () {
139
- $('#<?php echo $key; ?>_review').on('click', '.notice-dismiss, .review-dismiss', function (e) {
140
-
141
- $.ajax({
142
- url: ajaxurl,
143
- method: "post",
144
- data: {
145
- 'nonce': '<?php echo wp_create_nonce( (string) __CLASS__ ); ?>',
146
- 'action': '<?php echo $this->product->get_key() . __CLASS__; ?>'
147
- },
148
- success: function () {
149
- $('#<?php echo $key; ?>_review').html('<p><b>Thanks for your answer.</b></p>');
150
- }
151
- });
152
- });
153
- });
154
- })(jQuery);
155
- </script>
156
- <?php
157
- }
158
-
159
- /**
160
- * Generates the HTML
161
- *
162
- * @param string $key The product key.
163
- */
164
- function get_html( $key ) {
165
- $link = 'https://wordpress.org/support/' . $this->product->get_type() . '/' . $this->product->get_slug() . '/reviews/#wporg-footer';
166
- $heading = apply_filters( $this->product->get_key() . '_feedback_review_heading', $this->heading );
167
- $heading = str_replace(
168
- array( '{product}' ),
169
- $this->product->get_friendly_name(), $heading
170
- );
171
- $heading = str_replace( '{developer}', $this->developers[ $this->product->get_type() ][ rand( 0, ( count( $this->developers[ $this->product->get_type() ] ) - 1 ) ) ], $heading );
172
-
173
- $button_cancel = apply_filters( $this->product->get_key() . '_feedback_review_button_cancel', $this->button_cancel );
174
- $button_do = apply_filters( $this->product->get_key() . '_feedback_review_button_do', $this->button_do );
175
- $msg = apply_filters( $this->product->get_key() . '_feedback_review_message', $this->msg );
176
-
177
- return '<div id="' . $this->product->get_key() . '-review-notification" class="themeisle-sdk-review-box">'
178
- . '<p>' . $heading . '</p>'
179
- . ( $msg ? '<p>' . $msg . '</p>' : '' )
180
- . '<div class="actions">'
181
- . '<a href="' . $link . '" target="_blank" class="button button-primary review-dismiss"> ' . $button_do . '</a>'
182
- . get_submit_button( $button_cancel, 'review-dismiss ' . $this->product->get_key() . '-ti-review', $this->product->get_key() . 'ti-review-no', false )
183
- . '</div></div>';
184
- }
185
-
186
- /**
187
- * Called when the either button is clicked
188
- */
189
- function dismiss() {
190
- check_ajax_referer( (string) __CLASS__, 'nonce' );
191
-
192
- $this->disable();
193
- }
194
-
195
- /**
196
- * Disables the notification
197
- */
198
- protected function disable() {
199
- update_option( $this->product->get_key() . '_review_flag', 'no' );
200
- }
201
-
202
- /**
203
- * Enables the notification
204
- */
205
- protected function enable() {
206
- update_option( $this->product->get_key() . '_review_flag', 'yes' );
207
- }
208
- }
209
- endif;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/codeinwp/themeisle-sdk/class-themeisle-sdk-feedback-translate.php DELETED
@@ -1,983 +0,0 @@
1
- <?php
2
- /**
3
- * The Translate feedback model class for ThemeIsle SDK
4
- *
5
- * @package ThemeIsleSDK
6
- * @subpackage Feedback
7
- * @copyright Copyright (c) 2017, Marius Cristea
8
- * @license http://opensource.org/licenses/gpl-3.0.php GNU Public License
9
- * @since 1.0.0
10
- */
11
- // Exit if accessed directly.
12
- if ( ! defined( 'ABSPATH' ) ) {
13
- exit;
14
- }
15
- if ( ! class_exists( 'ThemeIsle_SDK_Feedback_Translate' ) ) :
16
- /**
17
- * Translate feedback model for ThemeIsle SDK.
18
- */
19
- class ThemeIsle_SDK_Feedback_Translate extends ThemeIsle_SDK_Feedback {
20
-
21
- /**
22
- * @var string $heading The heading of the modal
23
- */
24
- private $heading = 'Improve {product}';
25
- /**
26
- * @var string The message.
27
- */
28
- private $msg = 'Translating <b>{product}</b> into as many languages as possible is a huge project. We still need help with a lot of them, so if you are good at translating into <b>{language}</b>, it would be greatly appreciated.
29
- The process is easy, and you can join by following the link below!';
30
- /**
31
- * @var string $button_cancel The text of the cancel button
32
- */
33
- private $button_cancel = 'No, thanks.';
34
- /**
35
- * @var string $button_already The text of the already did it button
36
- */
37
- private $button_do = 'Ok, I will gladly help.';
38
- /**
39
- * @var array Array of available locals.
40
- */
41
- private $locales = array(
42
- 'af' => array(
43
- 'slug' => 'af',
44
- 'name' => 'Afrikaans',
45
- ),
46
- 'ak' => array(
47
- 'slug' => 'ak',
48
- 'name' => 'Akan',
49
- ),
50
- 'am' => array(
51
- 'slug' => 'am',
52
- 'name' => 'Amharic',
53
- ),
54
- 'ar' => array(
55
- 'slug' => 'ar',
56
- 'name' => 'Arabic',
57
- ),
58
- 'arq' => array(
59
- 'slug' => 'arq',
60
- 'name' => 'Algerian Arabic',
61
- ),
62
- 'ary' => array(
63
- 'slug' => 'ary',
64
- 'name' => 'Moroccan Arabic',
65
- ),
66
- 'as' => array(
67
- 'slug' => 'as',
68
- 'name' => 'Assamese',
69
- ),
70
- 'ast' => array(
71
- 'slug' => 'ast',
72
- 'name' => 'Asturian',
73
- ),
74
- 'az' => array(
75
- 'slug' => 'az',
76
- 'name' => 'Azerbaijani',
77
- ),
78
- 'azb' => array(
79
- 'slug' => 'azb',
80
- 'name' => 'South Azerbaijani',
81
- ),
82
- 'az_TR' => array(
83
- 'slug' => 'az-tr',
84
- 'name' => 'Azerbaijani (Turkey)',
85
- ),
86
- 'ba' => array(
87
- 'slug' => 'ba',
88
- 'name' => 'Bashkir',
89
- ),
90
- 'bal' => array(
91
- 'slug' => 'bal',
92
- 'name' => 'Catalan (Balear)',
93
- ),
94
- 'bcc' => array(
95
- 'slug' => 'bcc',
96
- 'name' => 'Balochi Southern',
97
- ),
98
- 'bel' => array(
99
- 'slug' => 'bel',
100
- 'name' => 'Belarusian',
101
- ),
102
- 'bg_BG' => array(
103
- 'slug' => 'bg',
104
- 'name' => 'Bulgarian',
105
- ),
106
- 'bn_BD' => array(
107
- 'slug' => 'bn',
108
- 'name' => 'Bengali',
109
- ),
110
- 'bo' => array(
111
- 'slug' => 'bo',
112
- 'name' => 'Tibetan',
113
- ),
114
- 'bre' => array(
115
- 'slug' => 'br',
116
- 'name' => 'Breton',
117
- ),
118
- 'bs_BA' => array(
119
- 'slug' => 'bs',
120
- 'name' => 'Bosnian',
121
- ),
122
- 'ca' => array(
123
- 'slug' => 'ca',
124
- 'name' => 'Catalan',
125
- ),
126
- 'ceb' => array(
127
- 'slug' => 'ceb',
128
- 'name' => 'Cebuano',
129
- ),
130
- 'ckb' => array(
131
- 'slug' => 'ckb',
132
- 'name' => 'Kurdish (Sorani)',
133
- ),
134
- 'co' => array(
135
- 'slug' => 'co',
136
- 'name' => 'Corsican',
137
- ),
138
- 'cs_CZ' => array(
139
- 'slug' => 'cs',
140
- 'name' => 'Czech',
141
- ),
142
- 'cy' => array(
143
- 'slug' => 'cy',
144
- 'name' => 'Welsh',
145
- ),
146
- 'da_DK' => array(
147
- 'slug' => 'da',
148
- 'name' => 'Danish',
149
- ),
150
- 'de_DE' => array(
151
- 'slug' => 'de',
152
- 'name' => 'German',
153
- ),
154
- 'de_CH' => array(
155
- 'slug' => 'de-ch',
156
- 'name' => 'German (Switzerland)',
157
- ),
158
- 'dv' => array(
159
- 'slug' => 'dv',
160
- 'name' => 'Dhivehi',
161
- ),
162
- 'dzo' => array(
163
- 'slug' => 'dzo',
164
- 'name' => 'Dzongkha',
165
- ),
166
- 'el' => array(
167
- 'slug' => 'el',
168
- 'name' => 'Greek',
169
- ),
170
- 'art_xemoji' => array(
171
- 'slug' => 'art-xemoji',
172
- 'name' => 'Emoji',
173
- ),
174
- 'en_US' => array(
175
- 'slug' => 'en',
176
- 'name' => 'English',
177
- ),
178
- 'en_AU' => array(
179
- 'slug' => 'en-au',
180
- 'name' => 'English (Australia)',
181
- ),
182
- 'en_CA' => array(
183
- 'slug' => 'en-ca',
184
- 'name' => 'English (Canada)',
185
- ),
186
- 'en_GB' => array(
187
- 'slug' => 'en-gb',
188
- 'name' => 'English (UK)',
189
- ),
190
- 'en_NZ' => array(
191
- 'slug' => 'en-nz',
192
- 'name' => 'English (New Zealand)',
193
- ),
194
- 'en_ZA' => array(
195
- 'slug' => 'en-za',
196
- 'name' => 'English (South Africa)',
197
- ),
198
- 'eo' => array(
199
- 'slug' => 'eo',
200
- 'name' => 'Esperanto',
201
- ),
202
- 'es_ES' => array(
203
- 'slug' => 'es',
204
- 'name' => 'Spanish (Spain)',
205
- ),
206
- 'es_AR' => array(
207
- 'slug' => 'es-ar',
208
- 'name' => 'Spanish (Argentina)',
209
- ),
210
- 'es_CL' => array(
211
- 'slug' => 'es-cl',
212
- 'name' => 'Spanish (Chile)',
213
- ),
214
- 'es_CO' => array(
215
- 'slug' => 'es-co',
216
- 'name' => 'Spanish (Colombia)',
217
- ),
218
- 'es_CR' => array(
219
- 'slug' => 'es-cr',
220
- 'name' => 'Spanish (Costa Rica)',
221
- ),
222
- 'es_GT' => array(
223
- 'slug' => 'es-gt',
224
- 'name' => 'Spanish (Guatemala)',
225
- ),
226
- 'es_MX' => array(
227
- 'slug' => 'es-mx',
228
- 'name' => 'Spanish (Mexico)',
229
- ),
230
- 'es_PE' => array(
231
- 'slug' => 'es-pe',
232
- 'name' => 'Spanish (Peru)',
233
- ),
234
- 'es_PR' => array(
235
- 'slug' => 'es-pr',
236
- 'name' => 'Spanish (Puerto Rico)',
237
- ),
238
- 'es_VE' => array(
239
- 'slug' => 'es-ve',
240
- 'name' => 'Spanish (Venezuela)',
241
- ),
242
- 'et' => array(
243
- 'slug' => 'et',
244
- 'name' => 'Estonian',
245
- ),
246
- 'eu' => array(
247
- 'slug' => 'eu',
248
- 'name' => 'Basque',
249
- ),
250
- 'fa_IR' => array(
251
- 'slug' => 'fa',
252
- 'name' => 'Persian',
253
- ),
254
- 'fa_AF' => array(
255
- 'slug' => 'fa-af',
256
- 'name' => 'Persian (Afghanistan)',
257
- ),
258
- 'fuc' => array(
259
- 'slug' => 'fuc',
260
- 'name' => 'Fulah',
261
- ),
262
- 'fi' => array(
263
- 'slug' => 'fi',
264
- 'name' => 'Finnish',
265
- ),
266
- 'fo' => array(
267
- 'slug' => 'fo',
268
- 'name' => 'Faroese',
269
- ),
270
- 'fr_FR' => array(
271
- 'slug' => 'fr',
272
- 'name' => 'French (France)',
273
- ),
274
- 'fr_BE' => array(
275
- 'slug' => 'fr-be',
276
- 'name' => 'French (Belgium)',
277
- ),
278
- 'fr_CA' => array(
279
- 'slug' => 'fr-ca',
280
- 'name' => 'French (Canada)',
281
- ),
282
- 'frp' => array(
283
- 'slug' => 'frp',
284
- 'name' => 'Arpitan',
285
- ),
286
- 'fur' => array(
287
- 'slug' => 'fur',
288
- 'name' => 'Friulian',
289
- ),
290
- 'fy' => array(
291
- 'slug' => 'fy',
292
- 'name' => 'Frisian',
293
- ),
294
- 'ga' => array(
295
- 'slug' => 'ga',
296
- 'name' => 'Irish',
297
- ),
298
- 'gd' => array(
299
- 'slug' => 'gd',
300
- 'name' => 'Scottish Gaelic',
301
- ),
302
- 'gl_ES' => array(
303
- 'slug' => 'gl',
304
- 'name' => 'Galician',
305
- ),
306
- 'gn' => array(
307
- 'slug' => 'gn',
308
- 'name' => 'Guaraní',
309
- ),
310
- 'gsw' => array(
311
- 'slug' => 'gsw',
312
- 'name' => 'Swiss German',
313
- ),
314
- 'gu' => array(
315
- 'slug' => 'gu',
316
- 'name' => 'Gujarati',
317
- ),
318
- 'hat' => array(
319
- 'slug' => 'hat',
320
- 'name' => 'Haitian Creole',
321
- ),
322
- 'hau' => array(
323
- 'slug' => 'hau',
324
- 'name' => 'Hausa',
325
- ),
326
- 'haw_US' => array(
327
- 'slug' => 'haw',
328
- 'name' => 'Hawaiian',
329
- ),
330
- 'haz' => array(
331
- 'slug' => 'haz',
332
- 'name' => 'Hazaragi',
333
- ),
334
- 'he_IL' => array(
335
- 'slug' => 'he',
336
- 'name' => 'Hebrew',
337
- ),
338
- 'hi_IN' => array(
339
- 'slug' => 'hi',
340
- 'name' => 'Hindi',
341
- ),
342
- 'hr' => array(
343
- 'slug' => 'hr',
344
- 'name' => 'Croatian',
345
- ),
346
- 'hu_HU' => array(
347
- 'slug' => 'hu',
348
- 'name' => 'Hungarian',
349
- ),
350
- 'hy' => array(
351
- 'slug' => 'hy',
352
- 'name' => 'Armenian',
353
- ),
354
- 'id_ID' => array(
355
- 'slug' => 'id',
356
- 'name' => 'Indonesian',
357
- ),
358
- 'ido' => array(
359
- 'slug' => 'ido',
360
- 'name' => 'Ido',
361
- ),
362
- 'is_IS' => array(
363
- 'slug' => 'is',
364
- 'name' => 'Icelandic',
365
- ),
366
- 'it_IT' => array(
367
- 'slug' => 'it',
368
- 'name' => 'Italian',
369
- ),
370
- 'ja' => array(
371
- 'slug' => 'ja',
372
- 'name' => 'Japanese',
373
- ),
374
- 'jv_ID' => array(
375
- 'slug' => 'jv',
376
- 'name' => 'Javanese',
377
- ),
378
- 'ka_GE' => array(
379
- 'slug' => 'ka',
380
- 'name' => 'Georgian',
381
- ),
382
- 'kab' => array(
383
- 'slug' => 'kab',
384
- 'name' => 'Kabyle',
385
- ),
386
- 'kal' => array(
387
- 'slug' => 'kal',
388
- 'name' => 'Greenlandic',
389
- ),
390
- 'kin' => array(
391
- 'slug' => 'kin',
392
- 'name' => 'Kinyarwanda',
393
- ),
394
- 'kk' => array(
395
- 'slug' => 'kk',
396
- 'name' => 'Kazakh',
397
- ),
398
- 'km' => array(
399
- 'slug' => 'km',
400
- 'name' => 'Khmer',
401
- ),
402
- 'kn' => array(
403
- 'slug' => 'kn',
404
- 'name' => 'Kannada',
405
- ),
406
- 'ko_KR' => array(
407
- 'slug' => 'ko',
408
- 'name' => 'Korean',
409
- ),
410
- 'kir' => array(
411
- 'slug' => 'kir',
412
- 'name' => 'Kyrgyz',
413
- ),
414
- 'lb_LU' => array(
415
- 'slug' => 'lb',
416
- 'name' => 'Luxembourgish',
417
- ),
418
- 'li' => array(
419
- 'slug' => 'li',
420
- 'name' => 'Limburgish',
421
- ),
422
- 'lin' => array(
423
- 'slug' => 'lin',
424
- 'name' => 'Lingala',
425
- ),
426
- 'lo' => array(
427
- 'slug' => 'lo',
428
- 'name' => 'Lao',
429
- ),
430
- 'lt_LT' => array(
431
- 'slug' => 'lt',
432
- 'name' => 'Lithuanian',
433
- ),
434
- 'lv' => array(
435
- 'slug' => 'lv',
436
- 'name' => 'Latvian',
437
- ),
438
- 'me_ME' => array(
439
- 'slug' => 'me',
440
- 'name' => 'Montenegrin',
441
- ),
442
- 'mg_MG' => array(
443
- 'slug' => 'mg',
444
- 'name' => 'Malagasy',
445
- ),
446
- 'mk_MK' => array(
447
- 'slug' => 'mk',
448
- 'name' => 'Macedonian',
449
- ),
450
- 'ml_IN' => array(
451
- 'slug' => 'ml',
452
- 'name' => 'Malayalam',
453
- ),
454
- 'mlt' => array(
455
- 'slug' => 'mlt',
456
- 'name' => 'Maltese',
457
- ),
458
- 'mn' => array(
459
- 'slug' => 'mn',
460
- 'name' => 'Mongolian',
461
- ),
462
- 'mr' => array(
463
- 'slug' => 'mr',
464
- 'name' => 'Marathi',
465
- ),
466
- 'mri' => array(
467
- 'slug' => 'mri',
468
- 'name' => 'Maori',
469
- ),
470
- 'ms_MY' => array(
471
- 'slug' => 'ms',
472
- 'name' => 'Malay',
473
- ),
474
- 'my_MM' => array(
475
- 'slug' => 'mya',
476
- 'name' => 'Myanmar (Burmese)',
477
- ),
478
- 'ne_NP' => array(
479
- 'slug' => 'ne',
480
- 'name' => 'Nepali',
481
- ),
482
- 'nb_NO' => array(
483
- 'slug' => 'nb',
484
- 'name' => 'Norwegian (Bokmål)',
485
- ),
486
- 'nl_NL' => array(
487
- 'slug' => 'nl',
488
- 'name' => 'Dutch',
489
- ),
490
- 'nl_BE' => array(
491
- 'slug' => 'nl-be',
492
- 'name' => 'Dutch (Belgium)',
493
- ),
494
- 'nn_NO' => array(
495
- 'slug' => 'nn',
496
- 'name' => 'Norwegian (Nynorsk)',
497
- ),
498
- 'oci' => array(
499
- 'slug' => 'oci',
500
- 'name' => 'Occitan',
501
- ),
502
- 'ory' => array(
503
- 'slug' => 'ory',
504
- 'name' => 'Oriya',
505
- ),
506
- 'os' => array(
507
- 'slug' => 'os',
508
- 'name' => 'Ossetic',
509
- ),
510
- 'pa_IN' => array(
511
- 'slug' => 'pa',
512
- 'name' => 'Punjabi',
513
- ),
514
- 'pl_PL' => array(
515
- 'slug' => 'pl',
516
- 'name' => 'Polish',
517
- ),
518
- 'pt_BR' => array(
519
- 'slug' => 'pt-br',
520
- 'name' => 'Portuguese (Brazil)',
521
- ),
522
- 'pt_PT' => array(
523
- 'slug' => 'pt',
524
- 'name' => 'Portuguese (Portugal)',
525
- ),
526
- 'ps' => array(
527
- 'slug' => 'ps',
528
- 'name' => 'Pashto',
529
- ),
530
- 'rhg' => array(
531
- 'slug' => 'rhg',
532
- 'name' => 'Rohingya',
533
- ),
534
- 'ro_RO' => array(
535
- 'slug' => 'ro',
536
- 'name' => 'Romanian',
537
- ),
538
- 'roh' => array(
539
- 'slug' => 'roh',
540
- 'name' => 'Romansh',
541
- ),
542
- 'ru_RU' => array(
543
- 'slug' => 'ru',
544
- 'name' => 'Russian',
545
- ),
546
- 'rue' => array(
547
- 'slug' => 'rue',
548
- 'name' => 'Rusyn',
549
- ),
550
- 'rup_MK' => array(
551
- 'slug' => 'rup',
552
- 'name' => 'Aromanian',
553
- ),
554
- 'sah' => array(
555
- 'slug' => 'sah',
556
- 'name' => 'Sakha',
557
- ),
558
- 'sa_IN' => array(
559
- 'slug' => 'sa-in',
560
- 'name' => 'Sanskrit',
561
- ),
562
- 'scn' => array(
563
- 'slug' => 'scn',
564
- 'name' => 'Sicilian',
565
- ),
566
- 'si_LK' => array(
567
- 'slug' => 'si',
568
- 'name' => 'Sinhala',
569
- ),
570
- 'sk_SK' => array(
571
- 'slug' => 'sk',
572
- 'name' => 'Slovak',
573
- ),
574
- 'sl_SI' => array(
575
- 'slug' => 'sl',
576
- 'name' => 'Slovenian',
577
- ),
578
- 'sna' => array(
579
- 'slug' => 'sna',
580
- 'name' => 'Shona',
581
- ),
582
- 'snd' => array(
583
- 'slug' => 'snd',
584
- 'name' => 'Sindhi',
585
- ),
586
- 'so_SO' => array(
587
- 'slug' => 'so',
588
- 'name' => 'Somali',
589
- ),
590
- 'sq' => array(
591
- 'slug' => 'sq',
592
- 'name' => 'Albanian',
593
- ),
594
- 'sq_XK' => array(
595
- 'slug' => 'sq-xk',
596
- 'name' => 'Shqip (Kosovo)',
597
- ),
598
- 'sr_RS' => array(
599
- 'slug' => 'sr',
600
- 'name' => 'Serbian',
601
- ),
602
- 'srd' => array(
603
- 'slug' => 'srd',
604
- 'name' => 'Sardinian',
605
- ),
606
- 'su_ID' => array(
607
- 'slug' => 'su',
608
- 'name' => 'Sundanese',
609
- ),
610
- 'sv_SE' => array(
611
- 'slug' => 'sv',
612
- 'name' => 'Swedish',
613
- ),
614
- 'sw' => array(
615
- 'slug' => 'sw',
616
- 'name' => 'Swahili',
617
- ),
618
- 'syr' => array(
619
- 'slug' => 'syr',
620
- 'name' => 'Syriac',
621
- ),
622
- 'szl' => array(
623
- 'slug' => 'szl',
624
- 'name' => 'Silesian',
625
- ),
626
- 'ta_IN' => array(
627
- 'slug' => 'ta',
628
- 'name' => 'Tamil',
629
- ),
630
- 'ta_LK' => array(
631
- 'slug' => 'ta-lk',
632
- 'name' => 'Tamil (Sri Lanka)',
633
- ),
634
- 'tah' => array(
635
- 'slug' => 'tah',
636
- 'name' => 'Tahitian',
637
- ),
638
- 'te' => array(
639
- 'slug' => 'te',
640
- 'name' => 'Telugu',
641
- ),
642
- 'tg' => array(
643
- 'slug' => 'tg',
644
- 'name' => 'Tajik',
645
- ),
646
- 'th' => array(
647
- 'slug' => 'th',
648
- 'name' => 'Thai',
649
- ),
650
- 'tir' => array(
651
- 'slug' => 'tir',
652
- 'name' => 'Tigrinya',
653
- ),
654
- 'tl' => array(
655
- 'slug' => 'tl',
656
- 'name' => 'Tagalog',
657
- ),
658
- 'tr_TR' => array(
659
- 'slug' => 'tr',
660
- 'name' => 'Turkish',
661
- ),
662
- 'tt_RU' => array(
663
- 'slug' => 'tt',
664
- 'name' => 'Tatar',
665
- ),
666
- 'tuk' => array(
667
- 'slug' => 'tuk',
668
- 'name' => 'Turkmen',
669
- ),
670
- 'twd' => array(
671
- 'slug' => 'twd',
672
- 'name' => 'Tweants',
673
- ),
674
- 'tzm' => array(
675
- 'slug' => 'tzm',
676
- 'name' => 'Tamazight (Central Atlas)',
677
- ),
678
- 'ug_CN' => array(
679
- 'slug' => 'ug',
680
- 'name' => 'Uighur',
681
- ),
682
- 'uk' => array(
683
- 'slug' => 'uk',
684
- 'name' => 'Ukrainian',
685
- ),
686
- 'ur' => array(
687
- 'slug' => 'ur',
688
- 'name' => 'Urdu',
689
- ),
690
- 'uz_UZ' => array(
691
- 'slug' => 'uz',
692
- 'name' => 'Uzbek',
693
- ),
694
- 'vi' => array(
695
- 'slug' => 'vi',
696
- 'name' => 'Vietnamese',
697
- ),
698
- 'wa' => array(
699
- 'slug' => 'wa',
700
- 'name' => 'Walloon',
701
- ),
702
- 'xho' => array(
703
- 'slug' => 'xho',
704
- 'name' => 'Xhosa',
705
- ),
706
- 'xmf' => array(
707
- 'slug' => 'xmf',
708
- 'name' => 'Mingrelian',
709
- ),
710
- 'yor' => array(
711
- 'slug' => 'yor',
712
- 'name' => 'Yoruba',
713
- ),
714
- 'zh_CN' => array(
715
- 'slug' => 'zh-cn',
716
- 'name' => 'Chinese (China)',
717
- ),
718
- 'zh_HK' => array(
719
- 'slug' => 'zh-hk',
720
- 'name' => 'Chinese (Hong Kong)',
721
- ),
722
- 'zh_TW' => array(
723
- 'slug' => 'zh-tw',
724
- 'name' => 'Chinese (Taiwan)',
725
- ),
726
- 'de_DE_formal' => array(
727
- 'slug' => 'de/formal',
728
- 'name' => 'German (Formal)',
729
- ),
730
- 'nl_NL_formal' => array(
731
- 'slug' => 'nl/formal',
732
- 'name' => 'Dutch (Formal)',
733
- ),
734
- 'de_CH_informal' => array(
735
- 'slug' => 'de-ch/informal',
736
- 'name' => 'Chinese (Taiwan)',
737
- ),
738
- 'pt_PT_ao90' => array(
739
- 'slug' => 'pt/ao90',
740
- 'name' => 'Portuguese (Portugal, AO90)',
741
- ),
742
- );
743
-
744
- /**
745
- * ThemeIsle_SDK_Feedback_Translate constructor.
746
- *
747
- * @param ThemeIsle_SDK_Product $product_object The product object.
748
- */
749
- public function __construct( $product_object ) {
750
- parent::__construct( $product_object );
751
- }
752
-
753
- /**
754
- * Return the locale path.
755
- *
756
- * @param string $locale Locale code.
757
- *
758
- * @return string Locale path.
759
- */
760
- private function get_locale_paths( $locale ) {
761
- if ( empty( $locale ) ) {
762
- return '';
763
- }
764
-
765
- $slug = isset( $this->locales[ $locale ] ) ? $this->locales[ $locale ]['slug'] : '';
766
- if ( empty( $slug ) ) {
767
- return '';
768
- }
769
- if ( strpos( $slug, '/' ) === false ) {
770
- $slug .= '/default';
771
- }
772
- $url = 'https://translate.wordpress.org/projects/wp-' . $this->product->get_type() . 's/' . $this->product->get_slug() . '/' . ( $this->product->get_type() === 'plugin' ? 'dev/' : '' ) . $slug . '?filters%5Bstatus%5D=untranslated&sort%5Bby%5D=random';
773
-
774
- return $url;
775
- }
776
-
777
- /**
778
- * Registers the hooks
779
- */
780
- public function setup_hooks_child() {
781
- add_action( 'wp_ajax_' . $this->product->get_key() . __CLASS__, array( $this, 'dismiss' ) );
782
- }
783
-
784
- /**
785
- * Either we should show the notification or not.
786
- *
787
- * @return bool Valid notification.
788
- */
789
- function can_notify() {
790
- if ( ! $this->product->is_wordpress_available() ) {
791
- $this->disable();
792
- return false;
793
- }
794
- $show = get_option( $this->product->get_key() . '_translate_flag', 'yes' );
795
- if ( 'no' === $show ) {
796
- return false;
797
- }
798
- $lang = $this->get_user_locale();
799
- if ( 'en_US' === $lang ) {
800
- return false;
801
- }
802
- $languages = $this->get_translations();
803
- if ( ! is_array( $languages ) ) {
804
- return false;
805
- }
806
- if ( ! isset( $languages['translations'] ) ) {
807
- return false;
808
- }
809
-
810
- $languages = $languages['translations'];
811
- $available = wp_list_pluck( $languages, 'language' );
812
- if ( in_array( $lang, $available ) ) {
813
- return false;
814
- }
815
- if ( ! isset( $this->locales[ $lang ] ) ) {
816
- return false;
817
- }
818
-
819
- return true;
820
- }
821
-
822
- /**
823
- * Get the user's locale.
824
- */
825
- private function get_user_locale() {
826
- global $wp_version;
827
- if ( version_compare( $wp_version, '4.7.0', '>=' ) ) {
828
- return get_user_locale();
829
- }
830
- $user = wp_get_current_user();
831
- if ( $user ) {
832
- $locale = $user->locale;
833
- }
834
- return $locale ? $locale : get_locale();
835
- }
836
-
837
- /**
838
- * Shows the notification
839
- */
840
- function show_notification() {
841
- add_action( 'admin_notices', array( $this, 'admin_notices' ) );
842
- }
843
-
844
- /**
845
- * Shows the admin notice
846
- */
847
- function admin_notices() {
848
- $id = $this->product->get_key() . '_translate';
849
-
850
- $this->add_css( $this->product->get_key() );
851
- $this->add_js( $this->product->get_key() );
852
- $html = $this->get_html( $this->product->get_key() );
853
-
854
- if ( $html ) {
855
- echo '<div class="notice notice-success is-dismissible" id="' . $id . '" ><div class="themeisle-translate-box">' . $html . '</div></div>';
856
- }
857
- }
858
-
859
- /**
860
- * Loads the css
861
- *
862
- * @param string $key The product key.
863
- */
864
- function add_css( $key ) {
865
- ?>
866
- <style type="text/css" id="<?php echo $key; ?>ti-translate-css">
867
- </style>
868
- <?php
869
- }
870
-
871
- /**
872
- * Loads the js
873
- *
874
- * @param string $key The product key.
875
- */
876
- function add_js( $key ) {
877
- ?>
878
- <script type="text/javascript" id="<?php echo $key; ?>ti-translate-js">
879
- (function ($) {
880
- $(document).ready(function () {
881
- $('#<?php echo $key; ?>_translate').on('click', '.translate-dismiss', function (e) {
882
-
883
- $.ajax({
884
- url: ajaxurl,
885
- method: "post",
886
- data: {
887
- 'nonce': '<?php echo wp_create_nonce( (string) __CLASS__ ); ?>',
888
- 'action': '<?php echo $this->product->get_key() . __CLASS__; ?>'
889
- },
890
- success: function () {
891
- $('#<?php echo $key; ?>_translate').html('<p><b>Thanks for your answer.</b></p>');
892
- }
893
- });
894
- });
895
- });
896
- })(jQuery);
897
- </script>
898
- <?php
899
- }
900
-
901
- /**
902
- * Fetch translations from api.
903
- *
904
- * @return mixed Translation array.
905
- */
906
- private function get_translations() {
907
- $cache_key = $this->product->get_key() . '_all_languages';
908
- $translations = get_transient( $cache_key );
909
-
910
- if ( $translations === false ) {
911
- require_once( ABSPATH . 'wp-admin/includes/translation-install.php' );
912
- $translations = translations_api(
913
- $this->product->get_type() . 's',
914
- array(
915
- 'slug' => $this->product->get_slug(),
916
- 'version' => $this->product->get_version(),
917
- )
918
- );
919
- set_transient( $cache_key, $translations, WEEK_IN_SECONDS );
920
- }
921
-
922
- return $translations;
923
-
924
- }
925
-
926
- /**
927
- * Generates the HTML
928
- *
929
- * @param string $key The product key.
930
- *
931
- * @return void|string Html code of the notification.
932
- */
933
- function get_html( $key ) {
934
- $lang = $this->get_user_locale();
935
- $link = $this->get_locale_paths( $lang );
936
- $heading = apply_filters( $this->product->get_key() . '_feedback_translate_heading', $this->heading );
937
- $product = $this->product->get_friendly_name();
938
- $heading = str_replace(
939
- array( '{product}' ),
940
- $product, $heading
941
- );
942
-
943
- $message = apply_filters( $this->product->get_key() . '_feedback_translation', $this->msg );
944
- $language_meta = $this->locales[ $lang ];
945
- $message = str_replace( '{language}', $language_meta['name'], $message );
946
- $message = str_replace( '{product}', $product, $message );
947
- $button_cancel = apply_filters( $this->product->get_key() . '_feedback_translate_button_cancel', $this->button_cancel );
948
- $button_do = apply_filters( $this->product->get_key() . '_feedback_translate_button_do', $this->button_do );
949
-
950
- return '<div id="' . $this->product->get_key() . '-translate-notification" class="themeisle-sdk-translate-box">'
951
- . '<h2>' . $heading . '</h2>'
952
- . '<p>' . $message . '</p>'
953
- . '<div class="actions">'
954
- . '<a href="' . $link . '" target="_blank" class="button button-primary translate-dismiss"> ' . $button_do . '</a>&nbsp;'
955
- . get_submit_button( $button_cancel, 'translate-dismiss ' . $this->product->get_key() . '-ti-translate', $this->product->get_key() . 'ti-translate-no', false )
956
- . '</div></br></div>';
957
- }
958
-
959
- /**
960
- * Called when the either button is clicked
961
- */
962
- function dismiss() {
963
- check_ajax_referer( (string) __CLASS__, 'nonce' );
964
-
965
- $this->disable();
966
- }
967
-
968
- /**
969
- * Disables the notification
970
- */
971
- protected function disable() {
972
-
973
- update_option( $this->product->get_key() . '_translate_flag', 'no' );
974
- }
975
-
976
- /**
977
- * Enables the notification
978
- */
979
- protected function enable() {
980
- update_option( $this->product->get_key() . '_translate_flag', 'yes' );
981
- }
982
- }
983
- endif;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/codeinwp/themeisle-sdk/class-themeisle-sdk-feedback.php DELETED
@@ -1,90 +0,0 @@
1
- <?php
2
- /**
3
- * The feedback model class for ThemeIsle SDK
4
- *
5
- * @package ThemeIsleSDK
6
- * @subpackage Feedback
7
- * @copyright Copyright (c) 2017, Marius Cristea
8
- * @license http://opensource.org/licenses/gpl-3.0.php GNU Public License
9
- * @since 1.0.0
10
- */
11
- // Exit if accessed directly.
12
- if ( ! defined( 'ABSPATH' ) ) {
13
- exit;
14
- }
15
- if ( ! class_exists( 'ThemeIsle_SDK_Feedback' ) ) :
16
- /**
17
- * Feedback model for ThemeIsle SDK.
18
- */
19
- abstract class ThemeIsle_SDK_Feedback {
20
- /**
21
- * @var ThemeIsle_SDK_Product $product Themeisle Product.
22
- */
23
- protected $product;
24
-
25
- /**
26
- * @var string $feedback_url Url where to send the feedback
27
- */
28
- private $feedback_url = 'http://feedback.themeisle.com/wordpress/wp-json/__pirate_feedback_/v1/feedback';
29
-
30
- /**
31
- * ThemeIsle_SDK_Feedback constructor.
32
- *
33
- * @param ThemeIsle_SDK_Product $product_object Product Object.
34
- */
35
- public function __construct( $product_object ) {
36
- if ( $product_object instanceof ThemeIsle_SDK_Product ) {
37
- $this->product = $product_object;
38
- }
39
- $this->setup_hooks();
40
- }
41
-
42
- /**
43
- * Registers the hooks and then delegates to the child
44
- */
45
- public function setup_hooks() {
46
- $this->setup_hooks_child();
47
- }
48
-
49
- /**
50
- * Calls the API
51
- *
52
- * @param string $attributes The attributes of the post body.
53
- */
54
- protected function call_api( $attributes ) {
55
- $slug = $this->product->get_slug();
56
- $version = $this->product->get_version();
57
- $attributes['slug'] = $slug;
58
- $attributes['version'] = $version;
59
-
60
- $response = wp_remote_post(
61
- $this->feedback_url, array(
62
- 'body' => $attributes,
63
- )
64
- );
65
- }
66
-
67
- /**
68
- * Randomizes the options array
69
- *
70
- * @param array $options The options array.
71
- */
72
- function randomize_options( $options ) {
73
- $new = array();
74
- $keys = array_keys( $options );
75
- shuffle( $keys );
76
-
77
- foreach ( $keys as $key ) {
78
- $new[ $key ] = $options[ $key ];
79
- }
80
-
81
- return $new;
82
- }
83
-
84
- /**
85
- * Abstract function for delegating to the child
86
- */
87
- protected abstract function setup_hooks_child();
88
-
89
- }
90
- endif;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/codeinwp/themeisle-sdk/class-themeisle-sdk-licenser.php DELETED
@@ -1,686 +0,0 @@
1
- <?php
2
- /**
3
- * The main loader class for license handling.
4
- *
5
- * @package ThemeIsleSDK
6
- * @subpackage Licenser
7
- * @copyright Copyright (c) 2017, Marius Cristea
8
- * @license http://opensource.org/licenses/gpl-3.0.php GNU Public License
9
- * @since 1.0.0
10
- */
11
- if ( ! class_exists( 'ThemeIsle_SDK_Licenser' ) ) :
12
- /**
13
- * Class ThemeIsle_SDK_Licenser
14
- *
15
- * Used to update the themeisle products
16
- */
17
- class ThemeIsle_SDK_Licenser {
18
-
19
- /**
20
- * @var string $license_key The license key string
21
- */
22
- public $license_key;
23
-
24
- /**
25
- * @var bool $do_check This ensures that the custom API request only runs on the second time that WP fires the update check
26
- */
27
- private $do_check = false;
28
-
29
- /**
30
- * @var bool $failed_checks Number of failed checks to the api endpoint
31
- */
32
- private $failed_checks = 0;
33
- /**
34
- * @var ThemeIsle_SDK_Product $product The ThemeIsle Product.
35
- */
36
- private $product;
37
- /**
38
- * @var string $product_key The product update response key.
39
- */
40
- private $product_key;
41
- /**
42
- * @var int $max_failed Maximum failed checks allowed before show the notice
43
- */
44
- private static $max_failed = 5;
45
-
46
- /**
47
- * ThemeIsle_SDK_Licenser constructor.
48
- *
49
- * @param ThemeIsle_SDK_Product $product The product object.
50
- */
51
- public function __construct( $product ) {
52
- $this->product = $product;
53
-
54
- $this->product_key = $this->product->get_key() . '-update-response';
55
- if ( ! $this->product->requires_license() ) {
56
- $this->license_key = 'free';
57
- } else {
58
- $license_data = get_option( $this->product->get_key() . '_license_data', '' );
59
- $this->failed_checks = intval( get_option( $this->product->get_key() . '_failed_checks', 0 ) );
60
- if ( $license_data !== '' ) {
61
- $this->license_key = isset( $license_data->key ) ? $license_data->key : get_option( $this->product->get_key() . '_license', '' );
62
- } else {
63
- $this->license_key = get_option( $this->product->get_key() . '_license', '' );
64
- }
65
- $this->register_license_hooks();
66
- }
67
- }
68
-
69
- /**
70
- * Register license hooks for the themeisle products
71
- */
72
- public function register_license_hooks() {
73
- add_action( 'admin_init', array( $this, 'register_settings' ) );
74
- add_action( 'admin_init', array( $this, 'activate_license' ) );
75
- add_action( 'admin_init', array( $this, 'product_valid' ), 99999999 );
76
- add_action( 'admin_notices', array( $this, 'show_notice' ) );
77
- add_filter( $this->product->get_key() . '_license_status', array( $this, 'get_license_status' ) );
78
- }
79
-
80
- /**
81
- * @param string $r Update payload.
82
- * @param string $url The api url.
83
- *
84
- * @return mixed List of themes to check for update.
85
- */
86
- function disable_wporg_update( $r, $url ) {
87
-
88
- if ( 0 !== strpos( $url, 'https://api.wordpress.org/themes/update-check/' ) ) {
89
- return $r;
90
- }
91
-
92
- // Decode the JSON response
93
- $themes = json_decode( $r['body']['themes'] );
94
-
95
- unset( $themes->themes->{$this->product->get_slug()} );
96
-
97
- // Encode the updated JSON response
98
- $r['body']['themes'] = json_encode( $themes );
99
-
100
- return $r;
101
- }
102
-
103
- /**
104
- * Register the setting for the license of the product
105
- *
106
- * @return bool
107
- */
108
- public function register_settings() {
109
- if ( ! is_admin() ) {
110
- return false;
111
- }
112
- add_settings_field(
113
- $this->product->get_key() . '_license',
114
- $this->product->get_name() . ' license',
115
- array( $this, 'license_view' ),
116
- 'general'
117
- );
118
- }
119
-
120
- /**
121
- * The license view field
122
- */
123
- public function license_view() {
124
- $status = $this->get_license_status();
125
- $value = $this->license_key;
126
-
127
- $activate_string = apply_filters( $this->product->get_key() . '_lc_activate_string', 'Activate' );
128
- $deactivate_string = apply_filters( $this->product->get_key() . '_lc_deactivate_string', 'Deactivate' );
129
- $valid_string = apply_filters( $this->product->get_key() . '_lc_valid_string', 'Valid' );
130
- $invalid_string = apply_filters( $this->product->get_key() . '_lc_invalid_string', 'Invalid' );
131
- $license_message = apply_filters( $this->product->get_key() . '_lc_license_message', 'Enter your license from %s purchase history in order to get %s updates' );
132
-
133
- echo '<p ><input ' . ( ( $status === 'valid' ) ? ( 'style="border:1px solid #7ad03a; "' ) : '' ) . ' type="text" id="' . $this->product->get_key() . '_license" name="' . $this->product->get_key() . '_license" value="' . $value . '" /><a ' . ( ( $status === 'valid' ) ? ( 'style="color:#fff;background: #7ad03a; display: inline-block;text-decoration: none;font-size: 13px;line-height: 26px;height: 26px; margin-left:5px; padding: 0 10px 1px; -webkit-border-radius: 3px;border-radius: 3px; ">' . $valid_string ) : ( 'style="color:#fff;background: #dd3d36; display: inline-block;text-decoration: none;font-size: 13px;line-height: 26px;height: 26px; margin-left:5px; padding: 0 10px 1px; -webkit-border-radius: 3px;border-radius: 3px; ">' . $invalid_string ) ) . ' </a>&nbsp;&nbsp;&nbsp;<button name="' . $this->product->get_key() . '_btn_trigger" ' . ( ( $status === 'valid' ) ? ( ' class="button button-primary">' . $deactivate_string ) : ( ' class="button button-primary" value="yes" type="submit" >' . $activate_string ) ) . ' </button></p><p class="description">' . sprintf( $license_message, '<a href="' . $this->product->get_store_url() . '">' . $this->product->get_store_name() . '</a> ', $this->product->get_type() ) . '</p>';
134
-
135
- }
136
-
137
- /**
138
- * Return the license status.
139
- *
140
- * @return string The License status.
141
- */
142
- public function get_license_status() {
143
- $license_data = get_option( $this->product->get_key() . '_license_data', '' );
144
- if ( $license_data !== '' ) {
145
- return isset( $license_data->license ) ? $license_data->license : get_option( $this->product->get_key() . '_license_status', 'not_active' );
146
- } else {
147
- return get_option( $this->product->get_key() . '_license_status', 'not_active' );
148
- }
149
-
150
- }
151
-
152
- /**
153
- * Check if the license is active or not
154
- *
155
- * @return bool
156
- */
157
- public function check_activation() {
158
- $license_data = get_option( $this->product->get_key() . '_license_data', '' );
159
- if ( $license_data !== '' ) {
160
- return isset( $license_data->error ) ? ( $license_data->error == 'no_activations_left' ) : false;
161
- }
162
-
163
- return false;
164
- }
165
-
166
- /**
167
- * Check if the license is about to expire in the next month
168
- *
169
- * @return bool
170
- */
171
- function check_expiration() {
172
- $license_data = get_option( $this->product->get_key() . '_license_data', '' );
173
- if ( $license_data !== '' ) {
174
- if ( isset( $license_data->expires ) ) {
175
- if ( strtotime( $license_data->expires ) - time() < 30 * 24 * 3600 ) {
176
- return true;
177
- }
178
- }
179
- }
180
-
181
- return false;
182
- }
183
-
184
- /**
185
- * Return the renew url from the store used
186
- *
187
- * @return string The renew url.
188
- */
189
- function renew_url() {
190
- $license_data = get_option( $this->product->get_key() . '_license_data', '' );
191
- if ( $license_data !== '' ) {
192
- if ( isset( $license_data->download_id ) && isset( $license_data->key ) ) {
193
- return $this->product->get_store_url() . '/checkout/?edd_license_key=' . $license_data->key . '&download_id=' . $license_data->download_id;
194
- }
195
- }
196
-
197
- return $this->product->get_store_url();
198
- }
199
-
200
- /**
201
- * Check if we hide the notificatin nag or not
202
- *
203
- * @param string $hide The notification to hide.
204
- *
205
- * @return bool Either hide them or not.
206
- */
207
- function check_hide( $hide ) {
208
- return true;
209
- }
210
-
211
- /**
212
- * Show the admin notice regarding the license status
213
- *
214
- * @return bool
215
- */
216
- function show_notice() {
217
- if ( ! is_admin() ) {
218
- return false;
219
- }
220
- $status = $this->get_license_status();
221
- $no_activations_string = apply_filters(
222
- $this->product->get_key() . '_lc_no_activations_string', 'No activations left for %s !!!. You need to
223
- upgrade your plan in order to use %s on more
224
- websites. Please ask the %s
225
- Staff for more details.'
226
- );
227
- $no_valid_string = apply_filters(
228
- $this->product->get_key() . '_lc_no_valid_string', 'In order to benefit from updates and support for %s, please add
229
- your license code from your <a href="%s" target="_blank">purchase history</a> and validate it <a
230
- href="%s">here</a>. '
231
- );
232
- $expiration_string = apply_filters(
233
- $this->product->get_key() . '_lc_expiration_string', 'Your license is about to expire
234
- for %s. You can go to %s and renew it '
235
- );
236
- if ( $status != 'valid' ) {
237
- if ( $this->check_activation() ) {
238
- if ( $this->check_hide( 'activation' ) ) {
239
- ?>
240
- <div class="error">
241
- <p><strong>
242
- <?php
243
- echo sprintf(
244
- $no_activations_string, $this->product->get_name(), $this->product->get_name(), '<a href="' . $this->product->get_store_url() . '"
245
- target="_blank">' . $this->product->get_store_name() . '</a>'
246
- );
247
- ?>
248
- </strong>
249
- </p>
250
- </div>
251
- <?php
252
- return false;
253
- }
254
- }
255
- ?>
256
- <?php if ( $this->check_hide( 'valid' ) ) : ?>
257
- <div class="error">
258
- <p>
259
- <strong><?php echo sprintf( $no_valid_string, $this->product->get_name() . ' ' . $this->product->get_type(), $this->product->get_store_url(), admin_url( 'options-general.php' ) . '#' . $this->product->get_key() ); ?> </strong>
260
- </p>
261
- </div>
262
- <?php endif; ?>
263
- <?php
264
- } else {
265
- if ( $this->check_expiration() ) {
266
- if ( $this->check_hide( 'expiration' ) ) {
267
- ?>
268
- <div class="update-nag">
269
- <p>
270
- <strong>
271
- <?php
272
- echo sprintf(
273
- $expiration_string, $this->product->get_name() . ' ' . $this->product->get_type(), '<a
274
- href="' . $this->renew_url() . '"
275
- target="_blank">' . $this->product->get_store_name() . '</a>'
276
- );
277
- ?>
278
- </strong>
279
- </p>
280
- </div>
281
- <?php
282
- }
283
- }
284
- }
285
- }
286
-
287
- /**
288
- * Run the license check call
289
- */
290
- public function product_valid() {
291
- if ( false === ( $license = get_transient( $this->product->get_key() . '_license_data' ) ) ) {
292
- $license = $this->check_license();
293
- set_transient( $this->product->get_key() . '_license_data', $license, 12 * HOUR_IN_SECONDS );
294
- update_option( $this->product->get_key() . '_license_data', $license );
295
- }
296
-
297
- }
298
-
299
- /**
300
- * Increment the failed checks
301
- */
302
- private function increment_failed_checks() {
303
- $this->failed_checks ++;
304
- update_option( $this->product->get_key() . '_failed_checks', $this->failed_checks );
305
- }
306
-
307
- /**
308
- * Reset the failed checks
309
- */
310
- private function reset_failed_checks() {
311
- $this->failed_checks = 1;
312
- update_option( $this->product->get_key() . '_failed_checks', $this->failed_checks );
313
- }
314
-
315
- /**
316
- * Check the license status
317
- *
318
- * @return object The license data.
319
- */
320
- public function check_license() {
321
- $status = $this->get_license_status();
322
- if ( $status == 'not_active' ) {
323
- $license_data = new stdClass();
324
- $license_data->license = 'not_active';
325
-
326
- return $license_data;
327
- }
328
- $license = trim( $this->license_key );
329
- $api_params = array(
330
- 'edd_action' => 'check_license',
331
- 'license' => $license,
332
- 'item_name' => rawurlencode( $this->product->get_name() ),
333
- 'url' => rawurlencode( home_url() ),
334
- );
335
- // Call the custom API.
336
- $response = wp_remote_get(
337
- add_query_arg( $api_params, $this->product->get_store_url() ), array(
338
- 'timeout' => 15,
339
- 'sslverify' => false,
340
- )
341
- );
342
- if ( is_wp_error( $response ) ) {
343
- $license_data = new stdClass();
344
- $license_data->license = 'valid';
345
-
346
- } else {
347
- $license_data = json_decode( wp_remote_retrieve_body( $response ) );
348
- if ( ! is_object( $license_data ) ) {
349
- $license_data = new stdClass();
350
- $license_data->license = 'valid';
351
- }
352
- }
353
- $license_old = get_option( $this->product->get_key() . '_license_data', '' );
354
- if ( $license_old->license == 'valid' && ( $license_data->license != $license_old->license ) ) {
355
- $this->increment_failed_checks();
356
- } else {
357
- $this->reset_failed_checks();
358
- }
359
-
360
- if ( $this->failed_checks <= self::$max_failed ) {
361
- return $license_old;
362
- }
363
-
364
- if ( isset( $license_old->hide_valid ) ) {
365
- $license_data->hide_valid = true;
366
- }
367
-
368
- if ( ! isset( $license_data->key ) ) {
369
- $license_data->key = isset( $license_old->key ) ? $license_old->key : '';
370
- }
371
-
372
- if ( isset( $license_old->hide_expiration ) ) {
373
- $license_data->hide_expiration = true;
374
- }
375
-
376
- if ( isset( $license_old->hide_activation ) ) {
377
- $license_data->hide_activation = true;
378
- }
379
-
380
- return $license_data;
381
-
382
- }
383
-
384
- /**
385
- * Activate the license remotely
386
- */
387
- function activate_license() {
388
- // listen for our activate button to be clicked
389
- if ( isset( $_POST[ $this->product->get_key() . '_btn_trigger' ] ) ) {
390
- $status = $this->get_license_status();
391
- // retrieve the license from the database
392
- $license = $_POST[ $this->product->get_key() . '_license' ];
393
- $api_params = array(
394
- 'license' => $license,
395
- 'item_name' => rawurlencode( $this->product->get_name() ),
396
- 'url' => rawurlencode( home_url() ),
397
- );
398
- if ( $status != 'valid' ) {
399
- // data to send in our API request
400
- $api_params['edd_action'] = 'activate_license';
401
- } else {
402
- $api_params['edd_action'] = 'deactivate_license';
403
- }
404
- // Call the custom API.
405
- $response = wp_remote_get( add_query_arg( $api_params, $this->product->get_store_url() ) );
406
- // make sure the response came back okay
407
- if ( is_wp_error( $response ) ) {
408
- $license_data = new stdClass();
409
- $license_data->license = ( $status != 'valid' ) ? 'valid' : 'invalid';
410
-
411
- } else {
412
- $license_data = json_decode( wp_remote_retrieve_body( $response ) );
413
- if ( ! is_object( $license_data ) ) {
414
- $license_data = new stdClass();
415
- $license_data->license = ( $status != 'valid' ) ? 'valid' : 'invalid';
416
- }
417
- }
418
- if ( ! isset( $license_data->key ) ) {
419
- $license_data->key = $license;
420
- }
421
- if ( $license_data->license == 'valid' ) {
422
- $this->reset_failed_checks();
423
- }
424
-
425
- if ( isset( $license_data->plan ) ) {
426
- update_option( $this->product->get_key() . '_license_plan', $license_data->plan );
427
- }
428
-
429
- update_option( $this->product->get_key() . '_license_data', $license_data );
430
- delete_transient( $this->product->get_key() . '_license_data' );
431
- set_transient( $this->product->get_key() . '_license_data', $license_data, 12 * HOUR_IN_SECONDS );
432
-
433
- }
434
- }
435
-
436
- /**
437
- * Enable the license system
438
- */
439
- public function enable() {
440
- if ( $this->product->get_type() == 'plugin' ) {
441
- add_filter(
442
- 'pre_set_site_transient_update_plugins', array(
443
- $this,
444
- 'pre_set_site_transient_update_plugins_filter',
445
- )
446
- );
447
- add_filter( 'plugins_api', array( $this, 'plugins_api_filter' ), 10, 3 );
448
- add_filter( 'http_request_args', array( $this, 'http_request_args' ), 10, 2 );
449
- }
450
- if ( $this->product->get_type() == 'theme' ) {
451
- add_filter( 'site_transient_update_themes', array( &$this, 'theme_update_transient' ) );
452
- add_filter( 'delete_site_transient_update_themes', array( &$this, 'delete_theme_update_transient' ) );
453
- add_action( 'load-update-core.php', array( &$this, 'delete_theme_update_transient' ) );
454
- add_action( 'load-themes.php', array( &$this, 'delete_theme_update_transient' ) );
455
- add_action( 'load-themes.php', array( &$this, 'load_themes_screen' ) );
456
- add_filter( 'http_request_args', array( $this, 'disable_wporg_update' ), 5, 2 );
457
-
458
- }
459
-
460
- }
461
-
462
- /**
463
- * Load the Themes screen
464
- */
465
- function load_themes_screen() {
466
- add_thickbox();
467
- add_action( 'admin_notices', array( &$this, 'update_nag' ) );
468
- }
469
-
470
- /**
471
- * Alter the nag for themes update
472
- */
473
- function update_nag() {
474
- $theme = wp_get_theme( $this->product->get_slug() );
475
- $api_response = get_transient( $this->product_key );
476
- if ( false === $api_response ) {
477
- return;
478
- }
479
- $update_url = wp_nonce_url( 'update.php?action=upgrade-theme&amp;theme=' . urlencode( $this->product->get_slug() ), 'upgrade-theme_' . $this->product->get_slug() );
480
- $update_message = apply_filters( 'themeisle_sdk_license_update_message', 'Updating this theme will lose any customizations you have made. Cancel to stop, OK to update.' );
481
- $update_onclick = ' onclick="if ( confirm(\'' . esc_js( $update_message ) . '\') ) {return true;}return false;"';
482
- if ( version_compare( $this->product->get_version(), $api_response->new_version, '<' ) ) {
483
- echo '<div id="update-nag">';
484
- printf(
485
- '<strong>%1$s %2$s</strong> is available. <a href="%3$s" class="thickbox" title="%4s">Check out what\'s new</a> or <a href="%5$s"%6$s>update now</a>.',
486
- $theme->get( 'Name' ),
487
- $api_response->new_version,
488
- '#TB_inline?width=640&amp;inlineId=' . $this->product->get_version() . '_changelog',
489
- $theme->get( 'Name' ),
490
- $update_url,
491
- $update_onclick
492
- );
493
- echo '</div>';
494
- echo '<div id="' . $this->product->get_slug() . '_' . 'changelog" style="display:none;">';
495
- echo wpautop( $api_response->sections['changelog'] );
496
- echo '</div>';
497
- }
498
- }
499
-
500
- /**
501
- * @param mixed $value The transient data.
502
- *
503
- * @return mixed
504
- */
505
- function theme_update_transient( $value ) {
506
- $update_data = $this->check_for_update();
507
- if ( $update_data ) {
508
- $value->response[ $this->product->get_slug() ] = $update_data;
509
- }
510
-
511
- return $value;
512
- }
513
-
514
- /**
515
- * Delete the update transient
516
- */
517
- function delete_theme_update_transient() {
518
- delete_transient( $this->product_key );
519
- }
520
-
521
- /**
522
- * Check remote api for latest version.
523
- *
524
- * @return bool|mixed Update api response.
525
- */
526
- private function get_version_data() {
527
- $api_params = array(
528
- 'edd_action' => 'get_version',
529
- 'version' => $this->product->get_version(),
530
- 'license' => $this->license_key,
531
- 'name' => $this->product->get_name(),
532
- 'slug' => $this->product->get_slug(),
533
- 'author' => $this->product->get_store_name(),
534
- 'url' => rawurlencode( home_url() ),
535
- );
536
- $response = wp_remote_post(
537
- $this->product->get_store_url(), array(
538
- 'timeout' => 15,
539
- 'sslverify' => false,
540
- 'body' => $api_params,
541
- )
542
- );
543
- if ( is_wp_error( $response ) || 200 != wp_remote_retrieve_response_code( $response ) ) {
544
- return false;
545
- }
546
- $update_data = json_decode( wp_remote_retrieve_body( $response ) );
547
- if ( ! is_object( $update_data ) ) {
548
- return false;
549
- }
550
-
551
- return $update_data;
552
- }
553
-
554
- /**
555
- * Check for updates
556
- *
557
- * @return array|bool Either the update data or false in case of failure
558
- */
559
- function check_for_update() {
560
- $theme = wp_get_theme( $this->product->get_slug() );
561
- $update_data = get_transient( $this->product_key );
562
-
563
- if ( false === $update_data ) {
564
- $failed = false;
565
-
566
- $update_data = $this->get_version_data();
567
- if ( empty( $update_data ) ) {
568
- $failed = true;
569
- }
570
- // If the response failed, try again in 30 minutes.
571
- if ( $failed ) {
572
- $data = new stdClass;
573
- $data->new_version = $this->product->get_version();
574
- set_transient( $this->product_key, $data, strtotime( '+30 minutes' ) );
575
-
576
- return false;
577
- } else {
578
- $update_data->sections = maybe_unserialize( $update_data->sections );
579
- set_transient( $this->product_key, $update_data, strtotime( '+12 hours' ) );
580
- }
581
- }
582
- if ( ! isset( $update_data->new_version ) ) {
583
- return false;
584
- }
585
- if ( version_compare( $this->product->get_version(), $update_data->new_version, '>=' ) ) {
586
- return false;
587
- }
588
-
589
- return (array) $update_data;
590
- }
591
-
592
- /**
593
- * Check for Updates at the defined API endpoint and modify the update array.
594
- *
595
- * This function dives into the update API just when WordPress creates its update array,
596
- * then adds a custom API call and injects the custom plugin data retrieved from the API.
597
- * It is reassembled from parts of the native WordPress plugin update code.
598
- * See wp-includes/update.php line 121 for the original wp_update_plugins() function.
599
- *
600
- * @uses api_request()
601
- *
602
- * @param array $_transient_data Update array build by WordPress.
603
- *
604
- * @return array Modified update array with custom plugin data.
605
- */
606
- public function pre_set_site_transient_update_plugins_filter( $_transient_data ) {
607
- if ( empty( $_transient_data ) || ! $this->do_check ) {
608
- $this->do_check = true;
609
-
610
- return $_transient_data;
611
- }
612
- $api_response = $this->api_request();
613
- if ( false !== $api_response && is_object( $api_response ) && isset( $api_response->new_version ) ) {
614
- if ( version_compare( $this->product->get_version(), $api_response->new_version, '<' ) ) {
615
- $_transient_data->response[ $this->product->get_slug() . '/' . $this->product->get_file() ] = $api_response;
616
- }
617
- }
618
-
619
- return $_transient_data;
620
- }
621
-
622
- /**
623
- * Calls the API and, if successfull, returns the object delivered by the API.
624
- *
625
- * @uses get_bloginfo()
626
- * @uses wp_remote_post()
627
- * @uses is_wp_error()
628
- *
629
- * @param string $_action The requested action.
630
- * @param array $_data Parameters for the API action.
631
- *
632
- * @return false||object
633
- */
634
- private function api_request( $_action = '', $_data = '' ) {
635
- $update_data = $this->get_version_data();
636
- if ( empty( $update_data ) ) {
637
- return false;
638
- }
639
- if ( $update_data && isset( $update_data->sections ) ) {
640
- $update_data->sections = maybe_unserialize( $update_data->sections );
641
- }
642
- return $update_data;
643
- }
644
-
645
- /**
646
- * Updates information on the "View version x.x details" page with custom data.
647
- *
648
- * @uses api_request()
649
- *
650
- * @param mixed $_data Plugin data.
651
- * @param string $_action Action to send.
652
- * @param object $_args Arguments to use.
653
- *
654
- * @return object $_data
655
- */
656
- public function plugins_api_filter( $_data, $_action = '', $_args = null ) {
657
- if ( ( $_action != 'plugin_information' ) || ! isset( $_args->slug ) || ( $_args->slug != $this->product->get_slug() ) ) {
658
- return $_data;
659
- }
660
- $api_response = $this->api_request();
661
- if ( false !== $api_response ) {
662
- $_data = $api_response;
663
- }
664
-
665
- return $_data;
666
- }
667
-
668
- /**
669
- * Disable SSL verification in order to prevent download update failures
670
- *
671
- * @param array $args Http args.
672
- * @param string $url Url to check.
673
- *
674
- * @return object $array
675
- */
676
- function http_request_args( $args, $url ) {
677
- // If it is an https request and we are performing a package download, disable ssl verification
678
- if ( strpos( $url, 'https://' ) !== false && strpos( $url, 'edd_action=package_download' ) ) {
679
- $args['sslverify'] = false;
680
- }
681
-
682
- return $args;
683
- }
684
-
685
- }
686
- endif;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/codeinwp/themeisle-sdk/class-themeisle-sdk-loader.php DELETED
@@ -1,96 +0,0 @@
1
- <?php
2
- /**
3
- * The main loader class for ThemeIsle SDK
4
- *
5
- * @package ThemeIsleSDK
6
- * @subpackage Loader
7
- * @copyright Copyright (c) 2017, Marius Cristea
8
- * @license http://opensource.org/licenses/gpl-3.0.php GNU Public License
9
- * @since 1.0.0
10
- */
11
- // Exit if accessed directly.
12
- if ( ! defined( 'ABSPATH' ) ) {
13
- exit;
14
- }
15
- if ( ! class_exists( 'ThemeIsle_SDK_Loader' ) ) :
16
- /**
17
- * Singleton loader for ThemeIsle SDK.
18
- */
19
- final class ThemeIsle_SDK_Loader {
20
- /**
21
- * @var ThemeIsle_SDK_Loader instance The singleton instance
22
- */
23
- private static $instance;
24
- /**
25
- * @var string $version The class version.
26
- */
27
- private static $version = '1.0.0';
28
- /**
29
- * @var array The products which use the SDK.
30
- */
31
- private static $products;
32
-
33
- /**
34
- * Register product into SDK.
35
- *
36
- * @param string $basefile The product basefile.
37
- *
38
- * @return ThemeIsle_SDK_Loader The singleton object.
39
- */
40
- public static function init_product( $basefile ) {
41
-
42
- if ( ! isset( self::$instance ) && ! ( self::$instance instanceof ThemeIsle_SDK_Loader ) ) {
43
- self::$instance = new ThemeIsle_SDK_Loader;
44
-
45
- }
46
- $product_object = new ThemeIsle_SDK_Product( $basefile );
47
- self::$products[ $product_object->get_slug() ] = $product_object;
48
-
49
- $notifications = array();
50
- // Based on the WordPress Available file header we enable the logger or not.
51
- if ( ! $product_object->is_wordpress_available() && apply_filters( $product_object->get_key() . '_enable_licenser', true ) === true ) {
52
- $licenser = new ThemeIsle_SDK_Licenser( $product_object );
53
- $licenser->enable();
54
- }
55
-
56
- $logger = new ThemeIsle_SDK_Logger( $product_object );
57
- if ( $product_object->is_logger_active() ) {
58
- $logger->enable();
59
- } else {
60
- $notifications[] = $logger;
61
- }
62
-
63
- $feedback = new ThemeIsle_SDK_Feedback_Factory( $product_object, $product_object->get_feedback_types() );
64
-
65
- $instances = $feedback->get_instances();
66
- if ( array_key_exists( 'review', $instances ) ) {
67
- $notifications[] = $instances['review'];
68
- }
69
- if ( array_key_exists( 'translate', $instances ) ) {
70
- $notifications[] = $instances['translate'];
71
- }
72
- new ThemeIsle_SDK_Notification_Manager( $product_object, $notifications );
73
- if ( ! $product_object->is_external_author() ) {
74
- new ThemeIsle_SDK_Widgets_Factory( $product_object, $product_object->get_widget_types() );
75
- }
76
- if ( ! $product_object->is_external_author() ) {
77
- new ThemeIsle_SDK_Rollback( $product_object );
78
- }
79
-
80
- new ThemeIsle_SDK_Endpoints( $product_object );
81
-
82
- return self::$instance;
83
- }
84
-
85
- /**
86
- * Get all products using the SDK.
87
- *
88
- * @return array Products available.
89
- */
90
- public static function get_products() {
91
- return self::$products;
92
- }
93
-
94
-
95
- }
96
- endif;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/codeinwp/themeisle-sdk/class-themeisle-sdk-logger.php DELETED
@@ -1,227 +0,0 @@
1
- <?php
2
- /**
3
- * The main loader class for ThemeIsle SDK
4
- *
5
- * @package ThemeIsleSDK
6
- * @subpackage Logger
7
- * @copyright Copyright (c) 2017, Marius Cristea
8
- * @license http://opensource.org/licenses/gpl-3.0.php GNU Public License
9
- * @since 1.0.0
10
- */
11
- if ( ! class_exists( 'ThemeIsle_SDK_Logger' ) ) :
12
- /**
13
- * Class ThemeIsle_SDK_Logger
14
- *
15
- * Send the statistics to the Themeisle Endpoint
16
- */
17
- /**
18
- * Class ThemeIsle_SDK_Logger
19
- */
20
- class ThemeIsle_SDK_Logger {
21
-
22
- /**
23
- * @var string $logging_url Url where to send the logs
24
- */
25
- private $logging_url = 'http://log.themeisle.com/wp-json/v1/logs/';
26
-
27
- /**
28
- * @var ThemeIsle_SDK_Product $product Themeisle Product.
29
- */
30
- private $product;
31
-
32
- /**
33
- * @var string $product_cron Cron name handler
34
- */
35
- private $product_cron;
36
-
37
- /**
38
- * @var string $heading The heading of the modal
39
- */
40
- private $heading = 'Do you enjoy <b>{product}</b>? Become a contributor by opting in to our anonymous data tracking. We guarantee no sensitive data is collected.';
41
-
42
- /**
43
- * @var string $button_submit The text of the submit button
44
- */
45
- private $button_submit = 'Sure, I would love to help.';
46
-
47
- /**
48
- * @var string $button_cancel The text of the cancel button
49
- */
50
- private $button_cancel = 'No, thanks.';
51
-
52
- /**
53
- * ThemeIsle_SDK_Logger constructor.
54
- *
55
- * @param ThemeIsle_SDK_Product $product_object Product Object.
56
- */
57
- public function __construct( $product_object ) {
58
- if ( $product_object instanceof ThemeIsle_SDK_Product ) {
59
- $this->product = $product_object;
60
- $this->product_cron = $product_object->get_key() . '_log_activity';
61
- }
62
- add_action( 'wp_ajax_' . $this->product->get_key() . __CLASS__, array( $this, 'dismiss' ) );
63
- }
64
-
65
-
66
- /**
67
- * Start the cron to send the log. It will randomize the interval in order to not send all the logs at the same time.
68
- */
69
- public function enable() {
70
- if ( ! wp_next_scheduled( $this->product_cron ) ) {
71
- wp_schedule_single_event( time() + ( rand( 15, 24 ) * 3600 ), $this->product_cron );
72
- }
73
- add_action( $this->product_cron, array( $this, 'send_log' ) );
74
- }
75
-
76
- /**
77
- * Send the statistics to the api endpoint
78
- */
79
- public function send_log() {
80
- $environment = array();
81
- $theme = wp_get_theme();
82
- $environment['theme'] = array();
83
- $environment['theme']['name'] = $theme->get( 'Name' );
84
- $environment['theme']['author'] = $theme->get( 'Author' );
85
- $environment['plugins'] = get_option( 'active_plugins' );
86
-
87
- wp_remote_post(
88
- $this->logging_url, array(
89
- 'method' => 'POST',
90
- 'timeout' => 3,
91
- 'redirection' => 5,
92
- 'headers' => array(
93
- 'X-ThemeIsle-Event' => 'log_site',
94
- ),
95
- 'body' => array(
96
- 'site' => get_site_url(),
97
- 'slug' => $this->product->get_slug(),
98
- 'version' => $this->product->get_version(),
99
- 'data' => apply_filters( $this->product->get_key() . '_logger_data', array() ),
100
- 'environment' => $environment,
101
- 'license' => apply_filters( $this->product->get_key() . '_license_status', '' ),
102
- ),
103
- )
104
- );
105
- }
106
-
107
- /**
108
- * Dismiss the notification
109
- */
110
- function dismiss() {
111
- check_ajax_referer( (string) __CLASS__, 'nonce' );
112
-
113
- $flag = intval( $_POST['enable'] ) === 1;
114
- update_option( $this->product->logger_option, ( $flag ? 'yes' : 'no' ) );
115
-
116
- if ( true === $flag ) {
117
- $this->enable();
118
- }
119
- }
120
-
121
- /**
122
- * Either we should show the notification or not.
123
- *
124
- * @return bool Valida notification.
125
- */
126
- function can_notify() {
127
- $show = $this->product->is_logger_active();
128
- $checked = get_option( $this->product->logger_option, '' );
129
- if ( ! $show && $checked == '' ) {
130
- return true;
131
- }
132
-
133
- return false;
134
- }
135
-
136
- /**
137
- * Shows the notification
138
- */
139
- function show_notification() {
140
- add_action( 'admin_notices', array( $this, 'admin_notices' ) );
141
- }
142
-
143
- /**
144
- * Shows the admin notice
145
- */
146
- function admin_notices() {
147
- $id = $this->product->get_key() . '_logger';
148
-
149
- $this->add_media( $this->product->get_key() );
150
-
151
- echo '<div class="notice notice-success is-dismissible " id="' . $this->product->get_key() . '-logger-notification" ><div id="' . $id . '" class="themeisle-logger-box">' . $this->get_html( $this->product->get_key() ) . '</div></div>';
152
- }
153
-
154
- /**
155
- * Generates the HTML
156
- *
157
- * @param string $key The product key.
158
- */
159
- function get_html( $key ) {
160
- $heading = apply_filters( $this->product->get_key() . '_logger_heading', $this->heading );
161
- $heading = str_replace(
162
- array( '{product}' ), array(
163
- trim( str_replace( 'Lite', '', $this->product->get_name() ) ),
164
- ),
165
- $heading
166
- );
167
- $button_submit = apply_filters( $this->product->get_key() . '_logger_button_submit', $this->button_submit );
168
- $button_cancel = apply_filters( $this->product->get_key() . '_logger_button_cancel', $this->button_cancel );
169
-
170
- return '<div >'
171
- . '<p>' . $heading . '</p>'
172
- . '<div class="actions">'
173
- . get_submit_button(
174
- $button_submit, 'primary ' . $this->product->get_key() . '-ti-logger', $this->product->get_key() . 'ti-logger-yes', false, array(
175
- 'data-ti-log-enable' => 1,
176
- )
177
- )
178
- . get_submit_button(
179
- $button_cancel, 'secondary ' . $this->product->get_key() . '-ti-logger', $this->product->get_key() . 'ti-logger-no', false, array(
180
- 'data-ti-log-enable' => 0,
181
- )
182
- )
183
- . '</div></div>';
184
- }
185
-
186
- /**
187
- * Loads the js
188
- *
189
- * @param string $key The product key.
190
- */
191
- function add_media( $key ) {
192
- ?>
193
- <style type="text/css">
194
- #<?php echo $key; ?>-logger-notification {
195
- padding-bottom: 5px;
196
- }
197
-
198
- #<?php echo $key; ?>-logger-notification .button {
199
- margin-left: 5px;
200
- }
201
- </style>
202
- <script type="text/javascript" id="<?php echo $key; ?>ti-logger-js">
203
- (function ($) {
204
- $(document).ready(function () {
205
- $('.<?php echo $key; ?>-ti-logger').on('click', function (e) {
206
-
207
- $.ajax({
208
- url: ajaxurl,
209
- method: "post",
210
- data: {
211
- 'nonce': '<?php echo wp_create_nonce( (string) __CLASS__ ); ?>',
212
- 'action': '<?php echo $this->product->get_key() . __CLASS__; ?>',
213
- 'enable': $(this).attr('data-ti-log-enable')
214
- },
215
- success: function () {
216
- $('#<?php echo $key; ?>-logger-notification').hide();
217
- }
218
- });
219
- });
220
- });
221
- })(jQuery);
222
- </script>
223
- <?php
224
- }
225
-
226
- }
227
- endif;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/codeinwp/themeisle-sdk/class-themeisle-sdk-notification-manager.php DELETED
@@ -1,105 +0,0 @@
1
- <?php
2
- /**
3
- * The notification manager class for ThemeIsle SDK
4
- *
5
- * @package ThemeIsleSDK
6
- * @subpackage Notification
7
- * @copyright Copyright (c) 2017, Marius Cristea
8
- * @license http://opensource.org/licenses/gpl-3.0.php GNU Public License
9
- * @since 1.0.0
10
- */
11
- // Exit if accessed directly.
12
- if ( ! defined( 'ABSPATH' ) ) {
13
- exit;
14
- }
15
- if ( ! class_exists( 'ThemeIsle_SDK_Notification_Manager' ) ) :
16
- /**
17
- * Notification manager model for ThemeIsle SDK.
18
- */
19
- class ThemeIsle_SDK_Notification_Manager {
20
- /**
21
- * Time between notifications.
22
- */
23
- const NOTIFICATION_INTERVAL_HOURS = 100;
24
- /**
25
- * @var array Notifications for the current product.
26
- */
27
- static private $notifications = array();
28
- /**
29
- * @var ThemeIsle_SDK_Product Current product.
30
- */
31
- private $product;
32
- /**
33
- * @var array ThemeIsle_SDK_Feedback Feedbacks available.
34
- */
35
- private $callbacks = array();
36
-
37
- /**
38
- * ThemeIsle_SDK_Notification_Manager constructor.
39
- *
40
- * @param ThemeIsle_SDK_Product $product_object Product Object.
41
- * @param array $callbacks the objects that will be called when a notification is due.
42
- */
43
- public function __construct( $product_object, $callbacks ) {
44
- $this->product = $product_object;
45
- $this->callbacks = $callbacks;
46
- $this->setup_hooks();
47
- }
48
-
49
- /**
50
- * Setup the notifications.
51
- */
52
- function setup_notifications() {
53
- if ( ! current_user_can( 'manage_options' ) ) {
54
- return;
55
- }
56
- // Load the notifications only if we have it installed after the required interval.
57
- if ( ( time() - $this->product->get_install_time() ) > self::NOTIFICATION_INTERVAL_HOURS * HOUR_IN_SECONDS ) {
58
- if ( $this->product instanceof ThemeIsle_SDK_Product && $this->callbacks && is_array( $this->callbacks ) ) {
59
- foreach ( $this->callbacks as $instance ) {
60
- self::$notifications[ $this->product->get_key() . get_class( $instance ) ] = $instance;
61
- }
62
- }
63
- }
64
- }
65
-
66
- /**
67
- * Setup the internal hooks
68
- */
69
- private function setup_hooks() {
70
- add_action( 'admin_head', array( $this, 'show_notification' ) );
71
- add_action( 'admin_init', array( $this, 'setup_notifications' ) );
72
- }
73
-
74
- /**
75
- * Shows the notification
76
- */
77
- function show_notification() {
78
- $instances = self::$notifications;
79
- if ( empty( $instances ) ) {
80
- return;
81
- }
82
-
83
- $available = array_keys( $instances );
84
- $active = get_option( 'themeisle_sdk_active_notification', array() );
85
-
86
- foreach ( $available as $key ) {
87
- $instance = $instances[ $key ];
88
- if ( $instance->can_notify() ) {
89
-
90
- // Detect notification switch.
91
- if ( empty( $active['key'] ) || ( $active['key'] != $key ) ) {
92
- $active['key'] = $key;
93
- $active['time'] = time();
94
- update_option( 'themeisle_sdk_active_notification', $active );
95
- }
96
- if ( ( time() - $active['time'] ) > ( self::NOTIFICATION_INTERVAL_HOURS * HOUR_IN_SECONDS ) ) {
97
- $instance->show_notification();
98
- }
99
- break;
100
- }
101
- }
102
-
103
- }
104
- }
105
- endif;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/codeinwp/themeisle-sdk/class-themeisle-sdk-product.php DELETED
@@ -1,635 +0,0 @@
1
- <?php
2
- /**
3
- * The product model class for ThemeIsle SDK
4
- *
5
- * @package ThemeIsleSDK
6
- * @subpackage Product
7
- * @copyright Copyright (c) 2017, Marius Cristea
8
- * @license http://opensource.org/licenses/gpl-3.0.php GNU Public License
9
- * @since 1.0.0
10
- */
11
- // Exit if accessed directly.
12
- if ( ! defined( 'ABSPATH' ) ) {
13
- exit;
14
- }
15
- if ( ! class_exists( 'ThemeIsle_SDK_Product' ) ) :
16
- /**
17
- * Product model for ThemeIsle SDK.
18
- */
19
- class ThemeIsle_SDK_Product {
20
- /**
21
- * @var string $slug THe product slug.
22
- */
23
- private $slug;
24
- /**
25
- * @var string $basefile The file with headers.
26
- */
27
- private $basefile;
28
- /**
29
- * @var string $type The product type ( plugin | theme ).
30
- */
31
- private $type;
32
- /**
33
- * @var string $file The file name.
34
- */
35
- private $file;
36
- /**
37
- * @var string $name The product name.
38
- */
39
- private $name;
40
- /**
41
- * @var string $key The product ready key.
42
- */
43
- private $key;
44
- /**
45
- * @var string $author_url The url of the author.
46
- */
47
- private $author_url;
48
- /**
49
- * @var string $store_url The store url.
50
- */
51
- private $store_url;
52
- /**
53
- * @var int $install The date of install.
54
- */
55
- private $install;
56
- /**
57
- * @var string $store_name The store name.
58
- */
59
- private $store_name;
60
- /**
61
- * @var array $allowed_authors The allowed authors.
62
- */
63
- private $allowed_authors = array(
64
- 'proteusthemes.com',
65
- 'anarieldesign.com',
66
- 'prothemedesign.com',
67
- 'cssigniter.com',
68
- );
69
- /**
70
- * @var array $allowed_external_products The allowed external_products.
71
- */
72
- private $allowed_products = array(
73
- 'zermatt',
74
- 'neto',
75
- 'olsen',
76
- 'benson',
77
- 'romero',
78
- 'carmack',
79
- 'puzzle',
80
- 'broadsheet',
81
- 'girlywp',
82
- 'veggie',
83
- 'zeko',
84
- 'maishawp',
85
- 'didi',
86
- 'liber',
87
- 'medicpress-pt',
88
- 'adrenaline-pt',
89
- 'consultpress-pt',
90
- 'legalpress-pt',
91
- 'gympress-pt',
92
- 'readable-pt',
93
- 'bolts-pt',
94
- );
95
- /**
96
- * @var bool $requires_license Either user needs to activate it with license.
97
- */
98
- private $requires_license;
99
- /**
100
- * @var bool $wordpress_available Either is available on WordPress or not.
101
- */
102
- private $wordpress_available;
103
- /**
104
- * @var string $version The product version.
105
- */
106
- private $version;
107
- /**
108
- * @var string $logger_option Logger option key.
109
- */
110
- public $logger_option;
111
- /**
112
- * @var string $pro_slug Pro slug, if available.
113
- */
114
- public $pro_slug;
115
- /**
116
- * @var string $feedback_types All the feedback types the product supports
117
- */
118
- private $feedback_types = array();
119
-
120
- /**
121
- * @var string $widget_types All the widget types the product supports
122
- */
123
- private $widget_types = array( 'dashboard_blog' );
124
-
125
- /**
126
- * ThemeIsle_SDK_Product constructor.
127
- *
128
- * @param string $basefile Product basefile.
129
- */
130
- public function __construct( $basefile ) {
131
- if ( ! empty( $basefile ) ) {
132
- if ( is_readable( $basefile ) ) {
133
- $this->basefile = $basefile;
134
- $this->setup_from_path();
135
- $this->setup_from_fileheaders();
136
- }
137
- }
138
- $install = get_option( $this->get_key() . '_install', 0 );
139
- if ( $install === 0 ) {
140
- $install = time();
141
- update_option( $this->get_key() . '_install', time() );
142
- }
143
- $this->install = $install;
144
-
145
- $this->logger_option = $this->get_key() . '_logger_flag';
146
-
147
- }
148
-
149
- /**
150
- * Setup props from fileheaders.
151
- */
152
- public function setup_from_fileheaders() {
153
- $file_headers = array(
154
- 'Requires License' => 'Requires License',
155
- 'WordPress Available' => 'WordPress Available',
156
- 'Pro Slug' => 'Pro Slug',
157
- 'Version' => 'Version',
158
- );
159
- if ( $this->type == 'plugin' ) {
160
- $file_headers['Name'] = 'Plugin Name';
161
- $file_headers['AuthorName'] = 'Author';
162
- $file_headers['AuthorURI'] = 'Author URI';
163
- }
164
- if ( $this->type == 'theme' ) {
165
- $file_headers['Name'] = 'Theme Name';
166
- $file_headers['AuthorName'] = 'Author';
167
- $file_headers['AuthorURI'] = 'Author URI';
168
- }
169
- $file_headers = get_file_data( $this->basefile, $file_headers );
170
-
171
- $this->name = $file_headers['Name'];
172
- $this->store_name = $file_headers['AuthorName'];
173
- $this->author_url = $file_headers['AuthorURI'];
174
- $this->store_url = $file_headers['AuthorURI'];
175
- if ( $this->is_external_author() ) {
176
- $this->store_url = 'https://themeisle.com';
177
- $this->store_name = 'ThemeIsle';
178
- }
179
- $this->requires_license = ( $file_headers['Requires License'] == 'yes' ) ? true : false;
180
- $this->wordpress_available = ( $file_headers['WordPress Available'] == 'yes' ) ? true : false;
181
- $this->pro_slug = ! empty( $file_headers['Pro Slug'] ) ? $file_headers['Pro Slug'] : '';
182
- $this->version = $file_headers['Version'];
183
- if ( $this->require_uninstall_feedback() ) {
184
- $this->feedback_types[] = 'deactivate';
185
- }
186
- if ( $this->is_wordpress_available() ) {
187
- $this->feedback_types[] = 'review';
188
- $this->feedback_types[] = 'translate';
189
- }
190
- }
191
-
192
- /**
193
- * Check if the product is by external author or not.
194
- *
195
- * @return bool Either is external author or no.
196
- */
197
- public function is_external_author() {
198
- foreach ( $this->allowed_authors as $author ) {
199
- if ( strpos( $this->author_url, $author ) !== false ) {
200
- return true;
201
- }
202
- if ( in_array( $this->get_slug(), $this->allowed_products ) ) {
203
- return true;
204
- }
205
- }
206
-
207
- return false;
208
- }
209
-
210
- /**
211
- * The magic var_dump info method.
212
- *
213
- * @return array Debug info.
214
- */
215
- public function __debugInfo() {
216
- return array(
217
- 'name' => $this->name,
218
- 'slug' => $this->slug,
219
- 'version' => $this->version,
220
- 'basefile' => $this->basefile,
221
- 'key' => $this->key,
222
- 'type' => $this->type,
223
- 'store_name' => $this->store_name,
224
- 'store_url' => $this->store_url,
225
- 'wordpress_available' => $this->wordpress_available,
226
- 'requires_license' => $this->requires_license,
227
- );
228
-
229
- }
230
-
231
- /**
232
- * Setup props from path.
233
- */
234
- public function setup_from_path() {
235
- $this->file = basename( $this->basefile );
236
- $dir = dirname( $this->basefile );
237
- $this->slug = basename( $dir );
238
- $exts = explode( '.', $this->basefile );
239
- $ext = $exts[ count( $exts ) - 1 ];
240
- if ( $ext == 'css' ) {
241
- $this->type = 'theme';
242
- }
243
- if ( $ext == 'php' ) {
244
- $this->type = 'plugin';
245
- }
246
- $this->key = self::key_ready_name( $this->slug );
247
- }
248
-
249
- /**
250
- * @param string $string the String to be normalized for cron handler.
251
- *
252
- * @return string $name The normalized string.
253
- */
254
- static function key_ready_name( $string ) {
255
- return str_replace( '-', '_', strtolower( trim( $string ) ) );
256
- }
257
-
258
- /**
259
- * Getter for product name.
260
- *
261
- * @return string The product name.
262
- */
263
- public function get_name() {
264
- return $this->name;
265
- }
266
-
267
- /**
268
- * Getter for product version.
269
- *
270
- * @return string The product version.
271
- */
272
- public function get_version() {
273
- return $this->version;
274
- }
275
-
276
- /**
277
- * If product is available on wordpress.org or not.
278
- *
279
- * @return bool Either is wp available or not.
280
- */
281
- public function is_wordpress_available() {
282
- return $this->wordpress_available;
283
- }
284
-
285
- /**
286
- * @return array Array of available versions.
287
- */
288
- private function get_plugin_versions() {
289
-
290
- $url = sprintf( 'https://api.wordpress.org/plugins/info/1.0/%s', $this->get_slug() );
291
- $response = wp_remote_get( $url );
292
- if ( is_wp_error( $response ) ) {
293
- return array();
294
- }
295
- $response = wp_remote_retrieve_body( $response );
296
- $response = maybe_unserialize( $response );
297
-
298
- if ( ! is_object( $response ) ) {
299
- return array();
300
- }
301
- if ( ! isset( $response->versions ) ) {
302
- return array();
303
- }
304
- $versions = array();
305
- foreach ( $response->versions as $version => $zip ) {
306
- $versions[] = array(
307
- 'version' => $version,
308
- 'url' => $zip,
309
- );
310
- }
311
-
312
- return $versions;
313
- }
314
-
315
- /**
316
- * @return string Return license key, if available.
317
- */
318
- private function get_license() {
319
- $license_data = get_option( $this->get_key() . '_license_data', '' );
320
-
321
- if ( empty( $license_data ) ) {
322
- return '';
323
- }
324
- if ( ! isset( $license_data->key ) ) {
325
- return '';
326
- }
327
-
328
- return $license_data->key;
329
- }
330
-
331
- /**
332
- * @return array Array of available versions.
333
- */
334
- private function get_pro_versions() {
335
- $license = $this->get_license();
336
- $store_url = trailingslashit( $this->store_url );
337
- $url = sprintf( '%s?edd_action=get_versions&name=%s&url=%s&license=%s', $store_url, urlencode( $this->get_name() ), urlencode( get_site_url() ), $license );
338
- $response = wp_remote_get( $url );
339
- if ( is_wp_error( $response ) ) {
340
- return array();
341
- }
342
- $response = wp_remote_retrieve_body( $response );
343
- $response = json_decode( $response );
344
- if ( ! is_object( $response ) ) {
345
- return array();
346
- }
347
- if ( ! isset( $response->versions ) ) {
348
- return array();
349
- }
350
- $versions = array();
351
- foreach ( $response->versions as $key => $version ) {
352
- $versions[] = array(
353
- 'version' => $version->version,
354
- 'url' => $version->file,
355
- );
356
- }
357
-
358
- return $versions;
359
- }
360
-
361
- /**
362
- * Return theme versions.
363
- *
364
- * @return array Theme versions array.
365
- */
366
- public function get_theme_versions() {
367
- $url = sprintf( 'https://api.wordpress.org/themes/info/1.1/?action=theme_information&request[slug]=%s&request[fields][versions]=true', $this->get_slug() );
368
- $response = wp_remote_get( $url );
369
- if ( is_wp_error( $response ) ) {
370
- return array();
371
- }
372
- $response = wp_remote_retrieve_body( $response );
373
- $response = json_decode( $response );
374
-
375
- if ( ! is_object( $response ) ) {
376
- return array();
377
- }
378
- if ( ! isset( $response->versions ) ) {
379
- return array();
380
- }
381
- $versions = array();
382
- foreach ( $response->versions as $version => $zip ) {
383
- $versions[] = array(
384
- 'version' => $version,
385
- 'url' => $zip,
386
- );
387
- }
388
-
389
- return $versions;
390
- }
391
-
392
- /**
393
- * Get versions array from wp.org
394
- *
395
- * @return array Array of versions.
396
- */
397
- private function get_api_versions() {
398
-
399
- $cache_key = $this->get_key() . '_' . preg_replace( '/[^0-9a-zA-Z ]/m', '', $this->version ) . 'versions';
400
- $cache_versions = get_transient( $cache_key );
401
- if ( false === $cache_versions ) {
402
- $versions = array();
403
- if ( ! $this->is_wordpress_available() ) {
404
- $versions = $this->get_pro_versions();
405
- } else {
406
- if ( $this->get_type() === 'plugin' ) {
407
- $versions = $this->get_plugin_versions();
408
- }
409
- if ( $this->get_type() === 'theme' ) {
410
- $versions = $this->get_theme_versions();
411
- }
412
- }
413
- set_transient( $cache_key, $versions, 5 * DAY_IN_SECONDS );
414
- } else {
415
- $versions = is_array( $cache_versions ) ? $cache_versions : array();
416
- }
417
-
418
- return $versions;
419
- }
420
-
421
- /**
422
- * Get the last rollback for this product.
423
- *
424
- * @return array The rollback version.
425
- */
426
- public function get_rollback() {
427
- $rollback = array();
428
- $versions = $this->get_api_versions();
429
- $versions = apply_filters( $this->get_key() . '_rollbacks', $versions );
430
-
431
- if ( $versions ) {
432
- usort( $versions, array( $this, 'sort_rollback_array' ) );
433
- foreach ( $versions as $version ) {
434
- if ( isset( $version['version'] ) && isset( $version['url'] ) && version_compare( $this->version, $version['version'], '>' ) ) {
435
- $rollback = $version;
436
- break;
437
- }
438
- }
439
- }
440
-
441
- return $rollback;
442
- }
443
-
444
- /**
445
- * Sort the rollbacks array in descending order.
446
- */
447
- public function sort_rollback_array( $a, $b ) {
448
- return version_compare( $a['version'], $b['version'], '<' ) > 0;
449
- }
450
-
451
- /**
452
- * If product can be rolled back.
453
- *
454
- * @return bool Can the product be rolled back or not.
455
- */
456
- public function can_rollback() {
457
- if ( $this->get_type() === 'theme' ) {
458
- if ( ! current_user_can( 'switch_themes' ) ) {
459
- return false;
460
- }
461
- }
462
- if ( $this->get_type() === 'plugin' ) {
463
- if ( ! current_user_can( 'install_plugins' ) ) {
464
- return false;
465
- }
466
- }
467
- $rollback = $this->get_rollback();
468
-
469
- return ! empty( $rollback );
470
- }
471
-
472
- /**
473
- * Return the product key.
474
- *
475
- * @return string The product key.
476
- */
477
- public function get_key() {
478
- return $this->key;
479
- }
480
-
481
- /**
482
- * Return friendly name.
483
- *
484
- * @return string Friendly name.
485
- */
486
- public function get_friendly_name() {
487
- $name = apply_filters( $this->get_key() . '_friendly_name', trim( str_replace( 'Lite', '', $this->get_name() ) ) );
488
- $name = rtrim( $name, '- ' );
489
-
490
- return $name;
491
- }
492
-
493
- /**
494
- * Either the product requires license or not.
495
- *
496
- * @return bool Either requires license or not.
497
- */
498
- public function requires_license() {
499
- return $this->requires_license;
500
- }
501
-
502
- /**
503
- * Check if the product is either theme or plugin.
504
- *
505
- * @return string Product type.
506
- */
507
- public function get_type() {
508
- return $this->type;
509
- }
510
-
511
- /**
512
- * Returns the Store name.
513
- *
514
- * @return string Store name.
515
- */
516
- public function get_store_name() {
517
- return $this->store_name;
518
- }
519
-
520
- /**
521
- * Returns the store url.
522
- *
523
- * @return string The store url.
524
- */
525
- public function get_store_url() {
526
- return $this->store_url;
527
- }
528
-
529
- /**
530
- * Returns the product slug.
531
- *
532
- * @return string The product slug.
533
- */
534
- public function get_slug() {
535
- return $this->slug;
536
- }
537
-
538
- /**
539
- * Returns product basefile, which holds the metaheaders.
540
- *
541
- * @return string The product basefile.
542
- */
543
- public function get_basefile() {
544
- return $this->basefile;
545
- }
546
-
547
- /**
548
- * Returns product filename.
549
- *
550
- * @return string The product filename.
551
- */
552
- public function get_file() {
553
- return $this->file;
554
- }
555
-
556
- /**
557
- * Returns feedback types
558
- *
559
- * @return array The feedback types.
560
- */
561
- public function get_feedback_types() {
562
- return apply_filters( $this->get_key() . '_feedback_types', $this->feedback_types );
563
- }
564
-
565
- /**
566
- * Returns widget types
567
- *
568
- * @return array The widget types.
569
- */
570
- public function get_widget_types() {
571
- return apply_filters( $this->get_key() . '_widget_types', $this->widget_types );
572
- }
573
-
574
- /**
575
- * We log the user website and product version.
576
- *
577
- * @return bool Either we log the data or not.
578
- */
579
- public function is_logger_active() {
580
- // If is not available on WordPress log this automatically.
581
- if ( ! $this->is_wordpress_available() ) {
582
- return true;
583
- } else {
584
- $pro_slug = $this->get_pro_slug();
585
- if ( ! empty( $pro_slug ) ) {
586
-
587
- $all_products = ThemeIsle_SDK_Loader::get_products();
588
- if ( isset( $all_products[ $pro_slug ] ) ) {
589
- return true;
590
- }
591
- }
592
-
593
- return ( get_option( $this->get_key() . '_logger_flag', 'no' ) === 'yes' );
594
-
595
- }
596
- }
597
-
598
- /**
599
- * Returns the pro slug, if available.
600
- *
601
- * @return string The pro slug.
602
- */
603
- public function get_pro_slug() {
604
- return $this->pro_slug;
605
- }
606
-
607
- /**
608
- * Return the install timestamp.
609
- *
610
- * @return int The install timestamp.
611
- */
612
- public function get_install_time() {
613
- return $this->install;
614
- }
615
-
616
- /**
617
- * We require feedback on uninstall.
618
- *
619
- * @return bool Either we should require feedback on uninstall or not.
620
- */
621
- public function require_uninstall_feedback() {
622
- if ( $this->get_type() == 'theme' && ! $this->is_external_author() ) {
623
- return ! get_transient( 'ti_sdk_pause_' . $this->get_key(), false );
624
- }
625
-
626
- if ( $this->get_type() == 'plugin' ) {
627
-
628
- return true;
629
- }
630
-
631
- return false;
632
- }
633
-
634
- }
635
- endif;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/codeinwp/themeisle-sdk/class-themeisle-sdk-rollback.php DELETED
@@ -1,223 +0,0 @@
1
- <?php
2
- /**
3
- * The rollback class for ThemeIsle SDK
4
- *
5
- * @package ThemeIsleSDK
6
- * @subpackage Rollback
7
- * @copyright Copyright (c) 2017, Marius Cristea
8
- * @license http://opensource.org/licenses/gpl-3.0.php GNU Public License
9
- * @since 1.0.0
10
- */
11
- // Exit if accessed directly.
12
- if ( ! defined( 'ABSPATH' ) ) {
13
- exit;
14
- }
15
- if ( ! class_exists( 'ThemeIsle_SDK_Rollback' ) ) :
16
- /**
17
- * Rollback for ThemeIsle SDK.
18
- */
19
- class ThemeIsle_SDK_Rollback {
20
-
21
- /**
22
- * @var ThemeIsle_SDK_Product $product Themeisle Product.
23
- */
24
- protected $product;
25
-
26
-
27
- /**
28
- * ThemeIsle_SDK_Rollback constructor.
29
- *
30
- * @param ThemeIsle_SDK_Product $product_object Product Object.
31
- */
32
- public function __construct( $product_object ) {
33
- if ( $product_object instanceof ThemeIsle_SDK_Product ) {
34
- $this->product = $product_object;
35
- }
36
- if ( $this->product->can_rollback() ) {
37
- $this->show_link();
38
- $this->add_hooks();
39
-
40
- }
41
- }
42
-
43
- /**
44
- * Add js scripts for themes rollback.
45
- */
46
- public function add_footer() {
47
- $screen = get_current_screen();
48
- if ( ! isset( $screen->parent_file ) ) {
49
- return;
50
- }
51
- if ( $screen->parent_file !== 'themes.php' ) {
52
- return;
53
- }
54
- if ( $this->product->get_type() === 'plugin' ) {
55
- return;
56
- }
57
-
58
- $version = $this->product->get_rollback();
59
- ?>
60
- <script type="text/javascript">
61
- jQuery(document).ready(function ($) {
62
- setInterval(checkTheme, 500);
63
-
64
- function checkTheme() {
65
- var theme = '<?php echo esc_attr( $this->product->get_slug() ); ?>-action';
66
-
67
- if (jQuery('#' + theme).length > 0) {
68
- if (jQuery('.theme-overlay.active').is(':visible')) {
69
- if (jQuery('#' + theme + '-rollback').length === 0) {
70
- jQuery('.theme-actions .active-theme').prepend('<a class="button" style="float:left" id="' + theme + '-rollback" href="<?php echo esc_url( wp_nonce_url( admin_url( 'admin-post.php?action=' . $this->product->get_key() . '_rollback' ), $this->product->get_key() . '_rollback' ) ); ?>">Rollback to v<?php echo esc_attr( $version['version'] ); ?></a>')
71
- }
72
- }
73
-
74
- }
75
- }
76
- })
77
-
78
- </script>
79
- <?php
80
-
81
- }
82
-
83
- /**
84
- * Set the rollback hook. Strangely, this does not work if placed in the ThemeIsle_SDK_Rollback class, so it is being called from there instead.
85
- */
86
- public function add_hooks() {
87
- add_action( 'admin_post_' . $this->product->get_key() . '_rollback', array( $this, 'start_rollback' ) );
88
- add_action( 'admin_footer', array( $this, 'add_footer' ) );
89
- }
90
-
91
- /**
92
- * If product can be rolled back, show the link to rollback.
93
- */
94
- private function show_link() {
95
- add_filter(
96
- 'plugin_action_links_' . plugin_basename( $this->product->get_basefile() ), array(
97
- $this,
98
- 'add_rollback_link',
99
- )
100
- );
101
- }
102
-
103
- /**
104
- * Show the rollback links in the plugin page.
105
- *
106
- * @return array The links.
107
- */
108
- public function add_rollback_link( $links ) {
109
- $version = $this->product->get_rollback();
110
- $links[] = '<a href="' . wp_nonce_url( admin_url( 'admin-post.php?action=' . $this->product->get_key() . '_rollback' ), $this->product->get_key() . '_rollback' ) . '">' . sprintf( apply_filters( $this->product->get_key() . '_rollback_label', 'Rollback to v%s' ), $version['version'] ) . '</a>';
111
-
112
- return $links;
113
- }
114
-
115
- /**
116
- * Start the rollback operation.
117
- */
118
- public function start_rollback() {
119
- if ( ! isset( $_GET['_wpnonce'] ) || ! wp_verify_nonce( $_GET['_wpnonce'], $this->product->get_key() . '_rollback' ) ) {
120
- wp_nonce_ays( '' );
121
- }
122
-
123
- if ( $this->product->get_type() === 'plugin' ) {
124
- $this->start_rollback_plugin();
125
- } elseif ( $this->product->get_type() === 'theme' ) {
126
- $this->start_rollback_theme();
127
- }
128
- }
129
-
130
- /**
131
- * Alter links and remove duplicate customize message.
132
- *
133
- * @param array $links Array of old links.
134
- *
135
- * @return mixed Array of links.
136
- */
137
- public function alter_links_theme_upgrade( $links ) {
138
- if ( isset( $links['preview'] ) ) {
139
- $links['preview'] = str_replace( '<span aria-hidden="true">Customize</span>', '', $links['preview'] );
140
- }
141
-
142
- return $links;
143
- }
144
-
145
- /**
146
- * Start the rollback operation for the theme.
147
- */
148
- private function start_rollback_theme() {
149
- add_filter( 'update_theme_complete_actions', array( $this, 'alter_links_theme_upgrade' ) );
150
- $rollback = $this->product->get_rollback();
151
- $transient = get_site_transient( 'update_themes' );
152
- $folder = $this->product->get_slug();
153
- $version = $rollback['version'];
154
- $temp_array = array(
155
- 'new_version' => $version,
156
- 'package' => $rollback['url'],
157
- );
158
-
159
- $transient->response[ $folder . '/style.css' ] = $temp_array;
160
- set_site_transient( 'update_themes', $transient );
161
-
162
- $transient = get_transient( $this->product->get_key() . '_warning_rollback' );
163
-
164
- if ( false === $transient ) {
165
- set_transient( $this->product->get_key() . '_warning_rollback', 'in progress', 30 );
166
- require_once( ABSPATH . 'wp-admin/includes/class-wp-upgrader.php' );
167
- $title = sprintf( apply_filters( $this->product->get_key() . '_rollback_message', 'Rolling back %s to v%s' ), $this->product->get_name(), $version );
168
- $theme = $folder . '/style.css';
169
- $nonce = 'upgrade-theme_' . $theme;
170
- $url = 'update.php?action=upgrade-theme&theme=' . urlencode( $theme );
171
-
172
- $upgrader = new Theme_Upgrader( new Theme_Upgrader_Skin( compact( 'title', 'nonce', 'url', 'theme' ) ) );
173
- $upgrader->upgrade( $theme );
174
- delete_transient( $this->product->get_key() . '_warning_rollback' );
175
- wp_die(
176
- '', $title, array(
177
- 'response' => 200,
178
- )
179
- );
180
- }
181
- }
182
-
183
- /**
184
- * Start the rollback operation for the plugin.
185
- */
186
- private function start_rollback_plugin() {
187
- $rollback = $this->product->get_rollback();
188
- $plugin_transient = get_site_transient( 'update_plugins' );
189
- $plugin_folder = $this->product->get_slug();
190
- $plugin_file = $this->product->get_file();
191
- $version = $rollback['version'];
192
- $temp_array = array(
193
- 'slug' => $plugin_folder,
194
- 'new_version' => $version,
195
- 'package' => $rollback['url'],
196
- );
197
-
198
- $temp_object = (object) $temp_array;
199
- $plugin_transient->response[ $plugin_folder . '/' . $plugin_file ] = $temp_object;
200
- set_site_transient( 'update_plugins', $plugin_transient );
201
-
202
- $transient = get_transient( $this->product->get_key() . '_warning_rollback' );
203
-
204
- if ( false === $transient ) {
205
- set_transient( $this->product->get_key() . '_warning_rollback', 'in progress', 30 );
206
- require_once( ABSPATH . 'wp-admin/includes/class-wp-upgrader.php' );
207
- $title = sprintf( apply_filters( $this->product->get_key() . '_rollback_message', 'Rolling back %s to v%s' ), $this->product->get_name(), $version );
208
- $plugin = $plugin_folder . '/' . $plugin_file;
209
- $nonce = 'upgrade-plugin_' . $plugin;
210
- $url = 'update.php?action=upgrade-plugin&plugin=' . urlencode( $plugin );
211
- $upgrader_skin = new Plugin_Upgrader_Skin( compact( 'title', 'nonce', 'url', 'plugin' ) );
212
- $upgrader = new Plugin_Upgrader( $upgrader_skin );
213
- $upgrader->upgrade( $plugin );
214
- delete_transient( $this->product->get_key() . '_warning_rollback' );
215
- wp_die(
216
- '', $title, array(
217
- 'response' => 200,
218
- )
219
- );
220
- }
221
- }
222
- }
223
- endif;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/codeinwp/themeisle-sdk/class-themeisle-sdk-widget-dashboard-blog.php DELETED
@@ -1,412 +0,0 @@
1
- <?php
2
- /**
3
- * The blog dashboard model class for ThemeIsle SDK
4
- *
5
- * @package ThemeIsleSDK
6
- * @subpackage Widgets
7
- * @copyright Copyright (c) 2017, Marius Cristea
8
- * @license http://opensource.org/licenses/gpl-3.0.php GNU Public License
9
- * @since 1.0.0
10
- */
11
- // Exit if accessed directly.
12
- if ( ! defined( 'ABSPATH' ) ) {
13
- exit;
14
- }
15
- if ( ! class_exists( 'ThemeIsle_SDK_Widget_Dashboard_Blog' ) ) :
16
- /**
17
- * Blog dashboard widget model for ThemeIsle SDK.
18
- */
19
- class ThemeIsle_SDK_Widget_Dashboard_Blog extends ThemeIsle_SDK_Widget {
20
-
21
- /**
22
- * @var array instance The instances.
23
- */
24
- protected $product;
25
- /**
26
- * @var array Feed items.
27
- */
28
- private $items = array();
29
-
30
- /**
31
- * ThemeIsle_SDK_Widget_Dashboard_Blog constructor.
32
- *
33
- * @param ThemeIsle_SDK_Product $product_object The product object.
34
- */
35
- public function __construct( $product_object ) {
36
- $this->product = $product_object;
37
- parent::__construct( $product_object );
38
- }
39
-
40
- /**
41
- * Registers the hooks
42
- */
43
- public function setup_hooks_child() {
44
- $this->setup_vars();
45
- add_action( 'wp_dashboard_setup', array( &$this, 'add_widget' ) );
46
- add_action( 'wp_network_dashboard_setup', array( &$this, 'add_widget' ) );
47
- add_filter( 'themeisle_sdk_recommend_plugin_or_theme', array( &$this, 'recommend_plugin_or_theme' ) );
48
- }
49
-
50
- /**
51
- * Setup class variables
52
- */
53
- function setup_vars() {
54
- $this->dashboard_name = apply_filters( 'themeisle_sdk_dashboard_widget_name', 'WordPress Guides/Tutorials' );
55
- $this->feeds = apply_filters(
56
- 'themeisle_sdk_dashboard_widget_feeds', array(
57
- 'https://themeisle.com/blog/feed',
58
- )
59
- );
60
- }
61
-
62
- /**
63
- * Add widget to the dashboard
64
- *
65
- * @return string|void
66
- */
67
- function add_widget() {
68
- global $wp_meta_boxes;
69
- if ( isset( $wp_meta_boxes['dashboard']['normal']['core']['themeisle'] ) ) {
70
- return;
71
- }
72
- wp_add_dashboard_widget(
73
- 'themeisle', $this->dashboard_name, array(
74
- &$this,
75
- 'render_dashboard_widget',
76
- )
77
- );
78
- }
79
-
80
- /**
81
- * Setup feed items.
82
- */
83
- private function setup_feeds() {
84
- $items_normalized = array();
85
- if ( false === ( $items_normalized = get_transient( 'themeisle_sdk_feed_items' ) ) ) {
86
- // Load SimplePie Instance
87
- $feed = fetch_feed( $this->feeds );
88
- // TODO report error when is an error loading the feed
89
- if ( is_wp_error( $feed ) ) {
90
- return;
91
- }
92
-
93
- $items = $feed->get_items( 0, 5 );
94
- foreach ( (array) $items as $item ) {
95
- $items_normalized[] = array(
96
- 'title' => $item->get_title(),
97
- 'date' => $item->get_date( 'U' ),
98
- 'link' => $item->get_permalink(),
99
- );
100
- }
101
- set_transient( 'themeisle_sdk_feed_items', $items_normalized, 48 * HOUR_IN_SECONDS );
102
- }
103
- $this->items = $items_normalized;
104
- }
105
-
106
- /**
107
- * Render widget content
108
- */
109
- function render_dashboard_widget() {
110
- $this->setup_feeds();
111
- if ( empty( $this->items ) || ! is_array( $this->items ) ) {
112
- return;
113
- }
114
- ?>
115
- <style type="text/css">
116
- #themeisle ul li.ti-dw-recommend-item {
117
- padding-left: 7px;
118
- border-top: 1px solid #eee;
119
- margin-bottom: 0px;
120
- padding-top: 6px;
121
- }
122
-
123
- #themeisle h2.hndle {
124
- background-image: url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA3Ny4xMiA3Ny4xMiI+PHRpdGxlPkFzc2V0IDM8L3RpdGxlPjxwYXRoIGQ9Ik03NS43Niw0Ny42cS0xLjUsNi40Ni00LjA3LDkuMjZBMzYuMjIsMzYuMjIsMCwwLDEsNjMuMjYsNjNhNTEsNTEsMCwwLDEtOS43OSw0LjZoLS4xNXY0LjgyQTQuNjYsNC42NiwwLDAsMSw1Miw3NS43Niw0LjA3LDQuMDcsMCwwLDEsNDksNzcuMTJhNCw0LDAsMCwxLTIuMTgtLjYxQTQuOTQsNC45NCwwLDAsMSw0NS4xOSw3NWE0LjQyLDQuNDIsMCwwLDEtNy41NCwwLDQuOTQsNC45NCwwLDAsMS0xLjU4LDEuNSwzLjc1LDMuNzUsMCwwLDEtMiwuNjFBNC4yNyw0LjI3LDAsMCwxLDMwLjI3LDc1YTQuOTQsNC45NCwwLDAsMS0xLjU4LDEuNSw0LDQsMCwwLDEtMi4xOC42MSwzLjkzLDMuOTMsMCwwLDEtMy4xNi0xLjQzLDUuMyw1LjMsMCwwLDEtMS4yMS0zLjU0LDEzLjgxLDEzLjgxLDAsMCwxLTguNTgsMywxMy4yMywxMy4yMywwLDAsMS05LTMuNDdBMTguMjEsMTguMjEsMCwwLDAsOSw3MC43OWExNC4yNiwxNC4yNiwwLDAsMS03LjgzLTUuNDIsMTYuMTIsMTYuMTIsMCwwLDAsNS4xOS4wNywxMi44OSwxMi44OSwwLDAsMCw0LjktMS43M1EzLjE1LDU1LjQzLDEuMDUsNTAuNDZhMTgsMTgsMCwwLDEtMS02LjkzQTQwLDQwLDAsMCwxLDEuMjEsMzQsMjYuNTksMjYuNTksMCwwLDEsNS4yNywyNC4xUTguNDQsMTkuNDMsMTMsMTkuNDNhMy40MSwzLjQxLDAsMCwxLDMuNDcsMi4yNmMuNi0uOCwxLjItMS41NiwxLjgxLTIuMjZsLjQ1LS40NS43NS0uNzUsMS4wNS0xLjgxYTM1LjIsMzUuMiwwLDAsMSwyLjExLTMuMzIsMjguNTcsMjguNTcsMCwwLDEsOS4xMi03LjY4QTIzLjQsMjMuNCwwLDAsMSw0Mi45MywyLjU2YTIyLjIyLDIyLjIyLDAsMCwxLDIuNzEuMTVBOC4xNiw4LjE2LDAsMCwxLDUxLjgxLDAsOC42OSw4LjY5LDAsMCwxLDU4LDIuNDFhMS41MSwxLjUxLDAsMCwxLC4xNS42OGMwLC4yNS0uNTUuOTMtMS42NiwybC0uMy4zYTkuNjksOS42OSwwLDAsMSwxLjU4LjgzYy41NS4zNS44My42NS44My45YTEuNjIsMS42MiwwLDAsMS0uNiwxbC0uMTUuMTVxNi43OCw2LDguNTgsMTYuMjdBMy4zLDMuMywwLDAsMSw2OSwyMy4zNWE2LjQ4LDYuNDgsMCwwLDEsNC4yMiwyLjFxMy45MiwzLjMyLDMuOTIsMTEuOUE0Mi4wNSw0Mi4wNSwwLDAsMSw3NS43Niw0Ny42Wk01My42Miw1NC4wN2EyNCwyNCwwLDAsMS0xNCw0LjUyQTIxLjQxLDIxLjQxLDAsMCwxLDI3LDU0LjY3LDI0LjI4LDI0LjI4LDAsMCwxLDE4LjUzLDQ1YTI5LDI5LDAsMCwxLTMtMTMsMzEuNzgsMzEuNzgsMCwwLDEsLjkxLTcuNTNBMzIuMTcsMzIuMTcsMCwwLDAsMTEuOSw0MS4yN2EzMy41LDMzLjUsMCwwLDAsMi43OSwxMy40LDI5LjEsMjkuMSwwLDAsMCw3LjksMTAuODUsNC42OCw0LjY4LDAsMCwxLDEuNjYtMS44OCw0LjE3LDQuMTcsMCwwLDEsNC40NC0uMDgsNC41LDQuNSwwLDAsMSwxLjU4LDEuNjZBNC4yLDQuMiwwLDAsMSwzNCw2M2EzLjgzLDMuODMsMCwwLDEsMiwuNiw0LjUsNC41LDAsMCwxLDEuNTgsMS42Niw0LjI3LDQuMjcsMCwwLDEsNy41NCwwLDQuNSw0LjUsMCwwLDEsMS41OC0xLjY2LDQuMTcsNC4xNywwLDAsMSw0LjQ0LjA4LDMuODYsMy44NiwwLDAsMSwxLjUxLDEuNzMsMzAuMTcsMzAuMTcsMCwwLDAsNy42OC05Ljk0LDMxLjE4LDMxLjE4LDAsMCwwLDMuMTYtMTIuMzVBMjguMzksMjguMzksMCwwLDEsNTMuNjIsNTQuMDdaTTI4Ljc3LDY1LjM3YTMuMSwzLjEsMCwwLDAtNC4zNywwLDMuMDYsMy4wNiwwLDAsMC0uOSwyLjI2djQuODJhMy4zMiwzLjMyLDAsMCwwLC45LDIuMzMsMi45MywyLjkzLDAsMCwwLDQuMzcsMCwzLjMyLDMuMzIsMCwwLDAsLjktMi4zM1Y2Ny42M0EzLjA2LDMuMDYsMCwwLDAsMjguNzcsNjUuMzdabS45LTQ4YTQuMjQsNC4yNCwwLDAsMCwzLjQ3LDEuNzMsNC40NSw0LjQ1LDAsMCwwLDMuNTQtMS43Myw2LDYsMCwwLDAsMS40My0zLjkyLDUuNyw1LjcsMCwwLDAtMS40My0zLjg0QTQuNTMsNC41MywwLDAsMCwzMy4xNCw4YTQuMzEsNC4zMSwwLDAsMC0zLjQ3LDEuNjYsNS43OSw1Ljc5LDAsMCwwLTEuMzUsMy43N0E2LjMzLDYuMzMsMCwwLDAsMjkuNjcsMTcuNFptNi40OCw0OGEzLjEsMy4xLDAsMCwwLTQuMzcsMCwzLjA2LDMuMDYsMCwwLDAtLjksMi4yNnY0LjgyYTMuMzIsMy4zMiwwLDAsMCwuOSwyLjMzLDIuOTMsMi45MywwLDAsMCw0LjM3LDAsMy4zMiwzLjMyLDAsMCwwLC45LTIuMzNWNjcuNjNBMy4wNiwzLjA2LDAsMCwwLDM2LjE1LDY1LjM3Wm0tNC4wNy01NC4zYTIuMzcsMi4zNywwLDAsMSwyLTEsMi4xNywyLjE3LDAsMCwxLDEuODgsMSw0LjEsNC4xLDAsMCwxLDAsNC41MiwyLjE3LDIuMTcsMCwwLDEtMS44OCwxLDIuMzcsMi4zNywwLDAsMS0yLTEsMy43MiwzLjcyLDAsMCwxLS43NS0yLjM0QTMuNDksMy40OSwwLDAsMSwzMi4wOCwxMS4wN1ptNSw5LjQxYTIwLjYxLDIwLjYxLDAsMCwwLTMuNTQsMTIuMjgsMTcuMTUsMTcuMTUsMCwwLDAsNC4wNywxMSwxMi40MywxMi40MywwLDAsMCw5Ljg3LDQuNDUsMTUuMywxNS4zLDAsMCwwLDktMywxMywxMywwLDAsMCwuNi0zLjMycTAtMy4zMi0zLjE2LTMuMzFhOC41OCw4LjU4LDAsMCwwLTIsLjNxLTcuODMsMS41LTExLjU5LS4zLTQuNTMtMi4xMi00LjUyLTkuMzRBMzcuOTIsMzcuOTIsMCwwLDEsMzcuMDUsMjAuNDhaTTYxLjQ1LDE3QTEyLjg0LDEyLjg0LDAsMCwwLDUxLjIxLDEyLjJhMTUuMTEsMTUuMTEsMCwwLDAtNi40LDEuNDMsMTcuODMsMTcuODMsMCwwLDAtNS41LDRxLTYuMTgsMjAuNjQsNi4xOCwyMC42NEEyNC43NSwyNC43NSwwLDAsMCw0OSwzNy44MWEzOC45MiwzOC45MiwwLDAsMSw0LjgyLS40NmMxLjgxLDAsMy4wNi40NiwzLjc3LDEuMzZxMS4zNSwxLjUuNzUsNS4xMmEyMS43MiwyMS43MiwwLDAsMCw1LTcuMTVBMjEuMzgsMjEuMzgsMCwwLDAsNjUuMDcsMjgsMTcuNDQsMTcuNDQsMCwwLDAsNjEuNDUsMTdaTTQzLjYsNjUuMzdhMi43MiwyLjcyLDAsMCwwLTIuMS0uOSwzLDMsMCwwLDAtMi4xOS45LDMuMDYsMy4wNiwwLDAsMC0uOSwyLjI2djQuODJhMy4zMiwzLjMyLDAsMCwwLC45LDIuMzMsMi44NCwyLjg0LDAsMCwwLDIuMTksMSwyLjYxLDIuNjEsMCwwLDAsMi4xLTEsMy40NSwzLjQ1LDAsMCwwLC44My0yLjMzVjY3LjYzQTMuMTcsMy4xNywwLDAsMCw0My42LDY1LjM3Wm03LjQ2LDBhMywzLDAsMCwwLTIuMTgtLjksMi43MywyLjczLDAsMCwwLTIuMTEuOSwzLjE3LDMuMTcsMCwwLDAtLjgzLDIuMjZ2NC44MmEzLjQ1LDMuNDUsMCwwLDAsLjgzLDIuMzMsMi42MSwyLjYxLDAsMCwwLDIuMTEsMSwyLjgzLDIuODMsMCwwLDAsMi4xOC0xLDMuMzIsMy4zMiwwLDAsMCwuOS0yLjMzVjY3LjYzQTMuMDYsMy4wNiwwLDAsMCw1MS4wNiw2NS4zN1oiLz48L3N2Zz4=');
125
- background-repeat: no-repeat;
126
- background-position: 92% 50%;
127
- background-size: 30px;
128
- }
129
-
130
- #themeisle .inside {
131
- padding: 0;
132
- }
133
-
134
- .ti-feed-list {
135
- padding: 0 12px 5px;
136
- margin-bottom: 10px;
137
- border-bottom: 1px solid #eee;
138
- }
139
-
140
- .ti-dw-feed-item a {
141
- display: flex;
142
- align-items: center;
143
- margin-bottom: 5px;
144
- padding: 5px;
145
- transition: .2s ease;
146
- border-radius: 3px;
147
- }
148
-
149
- .ti-dw-feed-item a:hover {
150
- background-color: #f8f8f8;
151
- }
152
-
153
- .ti-dw-feed-item a:hover .ti-dw-date-container {
154
- opacity: .9;
155
- }
156
-
157
- .ti-dw-feed-item .ti-dw-month-container {
158
- margin-top: -5px;
159
- text-transform: uppercase;
160
- font-size: 10px;
161
- letter-spacing: 1px;
162
- font-weight: 700;
163
- }
164
-
165
- .ti-dw-feed-item .ti-dw-date-container {
166
- border-radius: 3px;
167
- transition: .2s ease;
168
- min-height: 35px;
169
- margin-right: 5px;
170
- min-width: 35px;
171
- text-align: center;
172
- border: 1px solid #2a6f97;
173
- color: #fff;
174
- background: #2ea2cc;
175
- display: flex;
176
- flex-direction: column;
177
- justify-content: center;
178
- }
179
-
180
- .ti-dw-footer {
181
- padding: 0 12px 5px;
182
- text-align: center;
183
- }
184
-
185
- .ti-dw-recommend-item {
186
- display: block;
187
- }
188
-
189
- .ti-dw-recommend-item span {
190
- color: #72777c;
191
- }
192
-
193
- .ti-dw-powered-by {
194
- font-size: 11px;
195
- margin-top: 3px;
196
- display: block;
197
- color: #72777c;
198
- }
199
-
200
- .ti-dw-powered-by span {
201
- font-weight: 600;
202
- }
203
-
204
- </style>
205
- <ul class="ti-feed-list">
206
- <?php
207
- foreach ( $this->items as $item ) {
208
- ?>
209
- <li class="ti-dw-feed-item">
210
- <a href="
211
- <?php
212
- echo add_query_arg(
213
- array(
214
- 'utm_campaign' => 'feed',
215
- 'utm_medium' => 'dashboard_widget',
216
- ), $item['link']
217
- );
218
- ?>
219
- " target="_blank">
220
- <span class="ti-dw-date-container"><span
221
- class="ti-dw-day-container"><?php echo date( 'd', $item['date'] ); ?></span> <span
222
- class="ti-dw-month-container"><?php echo substr( date( 'M', $item['date'] ), 0, 3 ); ?></span></span><?php echo $item['title']; ?>
223
- </a>
224
- </li>
225
- <?php
226
- }
227
- ?>
228
- </ul>
229
- <?php
230
- $recommend = apply_filters( 'themeisle_sdk_recommend_plugin_or_theme', array() );
231
- if ( is_array( $recommend ) && ! empty( $recommend ) ) {
232
-
233
- $type = $recommend['type'];
234
- if ( ( $type == 'theme' && current_user_can( 'install_themes' ) ) || ( $type == 'plugin' && current_user_can( 'install_plugins' ) ) ) {
235
- add_thickbox();
236
- $url = add_query_arg(
237
- array(
238
- 'theme' => $recommend['slug'],
239
- ), network_admin_url( 'theme-install.php' )
240
- );
241
-
242
- if ( 'plugin' === $type ) {
243
-
244
- $url = add_query_arg(
245
- array(
246
- 'tab' => 'plugin-information',
247
- 'plugin' => $recommend['slug'],
248
- ), network_admin_url( 'plugin-install.php' )
249
- );
250
- }
251
- ?>
252
- <div class="ti-dw-footer">
253
- <span class="ti-dw-recommend-item ">
254
- <span class="ti-dw-recommend"><?php echo apply_filters( 'themeisle_sdk_dashboard_popular_label', sprintf( 'Popular %s', ucwords( $type ) ) ); ?>
255
- : </span>
256
- <?php
257
- echo trim(
258
- str_replace(
259
- array(
260
- 'lite',
261
- 'Lite',
262
- ), '', $recommend['name']
263
- )
264
- );
265
- ?>
266
- (<a class="thickbox open-plugin-details-modal"
267
- href="<?php echo $url . '&TB_iframe=true&width=600&height=500'; ?>"><?php echo apply_filters( 'themeisle_sdk_dashboard_install_label', 'Install' ); ?></a>)
268
- </span>
269
- <span class="ti-dw-powered-by">
270
- Powered by <span><?php echo esc_attr( $this->product->get_friendly_name() ); ?></span>
271
- </span>
272
- </div>
273
-
274
- <?php
275
- }
276
- }
277
- ?>
278
-
279
- <?php
280
-
281
- }
282
-
283
- /**
284
- * Either the current product is installed or not.
285
- *
286
- * @param array $val The current recommended product.
287
- *
288
- * @return bool Either we should exclude the plugin or not.
289
- */
290
- public function remove_current_products( $val ) {
291
- if ( $val['type'] === 'theme' ) {
292
- $exist = wp_get_theme( $val['slug'] );
293
-
294
- return ! $exist->exists();
295
- } else {
296
- $all_plugins = array_keys( get_plugins() );
297
- foreach ( $all_plugins as $slug ) {
298
- if ( strpos( $slug, $val['slug'] ) !== false ) {
299
- return false;
300
- }
301
- }
302
-
303
- return true;
304
- }
305
- }
306
-
307
- /**
308
- * Fetch themes from wporg api.
309
- *
310
- * @param string $author The author name.
311
- *
312
- * @return array The list of themes.
313
- */
314
- function get_themes_from_wporg( $author ) {
315
- $products = wp_remote_get(
316
- 'https://api.wordpress.org/themes/info/1.1/?action=query_themes&request[author]=' . $author . '&request[per_page]=30&request[fields][active_installs]=true'
317
- );
318
- $products = json_decode( wp_remote_retrieve_body( $products ) );
319
- if ( is_object( $products ) ) {
320
- $products = isset( $products->themes ) ? $products->themes : array();
321
- } else {
322
- $products = array();
323
- }
324
-
325
- return $products;
326
- }
327
-
328
- /**
329
- * Fetch plugin from wporg api.
330
- *
331
- * @param string $author The author slug.
332
- *
333
- * @return array The list of plugins for the selected author.
334
- */
335
- function get_plugins_from_wporg( $author ) {
336
- $products = wp_remote_get(
337
- 'https://api.wordpress.org/plugins/info/1.1/?action=query_plugins&request[author]=' . $author . '&request[author]=codeinwp&request[per_page]=20&request[fields][active_installs]=true'
338
- );
339
- $products = json_decode( wp_remote_retrieve_body( $products ) );
340
- if ( is_object( $products ) ) {
341
- $products = isset( $products->plugins ) ? $products->plugins : array();
342
- } else {
343
- $products = array();
344
- }
345
-
346
- return $products;
347
- }
348
-
349
- /**
350
- * Fetch products from the recomended section.
351
- *
352
- * @return array|mixed The list of products to use in recomended section.
353
- */
354
- function get_product_from_api() {
355
- if ( false === ( $products = get_transient( 'themeisle_sdk_products' ) ) ) {
356
- $products = array();
357
- $themeisle_themes = $this->get_themes_from_wporg( 'themeisle' );
358
- $codeinwp_themes = $this->get_themes_from_wporg( 'codeinwp' );
359
-
360
- $themeisle_plugins = $this->get_plugins_from_wporg( 'themeisle' );
361
- $codeinwp_plugins = $this->get_plugins_from_wporg( 'codeinwp' );
362
-
363
- $all_themes = array_merge( $themeisle_themes, $codeinwp_themes );
364
- foreach ( $all_themes as $theme ) {
365
- if ( $theme->active_installs < 4999 ) {
366
- continue;
367
- }
368
- $products[] = array(
369
- 'name' => $theme->name,
370
- 'type' => 'theme',
371
- 'slug' => $theme->slug,
372
- 'installs' => $theme->active_installs,
373
- );
374
- }
375
- $all_plugins = array_merge( $themeisle_plugins, $codeinwp_plugins );
376
- foreach ( $all_plugins as $plugin ) {
377
- if ( $plugin->active_installs < 5999 ) {
378
- continue;
379
- }
380
- $products[] = array(
381
- 'name' => $plugin->name,
382
- 'type' => 'plugin',
383
- 'slug' => $plugin->slug,
384
- 'installs' => $plugin->active_installs,
385
- );
386
- }
387
- set_transient( 'themeisle_sdk_products', $products, 6 * HOUR_IN_SECONDS );
388
- }
389
-
390
- return $products;
391
- }
392
-
393
- /**
394
- * Contact the API and fetch the recommended plugins/themes
395
- */
396
- function recommend_plugin_or_theme() {
397
- $products = $this->get_product_from_api();
398
- if ( ! is_array( $products ) ) {
399
- $products = array();
400
- }
401
- $products = array_filter( $products, array( $this, 'remove_current_products' ) );
402
- $products = array_merge( $products );
403
- if ( count( $products ) > 1 ) {
404
- shuffle( $products );
405
- $products = array_slice( $products, 0, 1 );
406
- }
407
- $to_recommend = isset( $products[0] ) ? $products[0] : $products;
408
-
409
- return $to_recommend;
410
- }
411
- }
412
- endif;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/codeinwp/themeisle-sdk/class-themeisle-sdk-widget.php DELETED
@@ -1,50 +0,0 @@
1
- <?php
2
- /**
3
- * The widget model class for ThemeIsle SDK
4
- *
5
- * @package ThemeIsleSDK
6
- * @subpackage Widgets
7
- * @copyright Copyright (c) 2017, Marius Cristea
8
- * @license http://opensource.org/licenses/gpl-3.0.php GNU Public License
9
- * @since 1.0.0
10
- */
11
- // Exit if accessed directly.
12
- if ( ! defined( 'ABSPATH' ) ) {
13
- exit;
14
- }
15
- if ( ! class_exists( 'ThemeIsle_SDK_Widget' ) ) :
16
- /**
17
- * Widget model for ThemeIsle SDK.
18
- */
19
- abstract class ThemeIsle_SDK_Widget {
20
- /**
21
- * @var ThemeIsle_SDK_Product $product Themeisle Product.
22
- */
23
- protected $product;
24
-
25
- /**
26
- * ThemeIsle_SDK_Widget constructor.
27
- *
28
- * @param ThemeIsle_SDK_Product $product_object Product Object.
29
- */
30
- public function __construct( $product_object ) {
31
- if ( $product_object instanceof ThemeIsle_SDK_Product ) {
32
- $this->product = $product_object;
33
- }
34
- $this->setup_hooks();
35
- }
36
-
37
- /**
38
- * Registers the hooks and then delegates to the child
39
- */
40
- public function setup_hooks() {
41
- $this->setup_hooks_child();
42
- }
43
-
44
- /**
45
- * Abstract function for delegating to the child
46
- */
47
- protected abstract function setup_hooks_child();
48
-
49
- }
50
- endif;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/codeinwp/themeisle-sdk/class-themeisle-sdk-widgets-factory.php DELETED
@@ -1,37 +0,0 @@
1
- <?php
2
- /**
3
- * The widgets factory class for ThemeIsle SDK
4
- *
5
- * @package ThemeIsleSDK
6
- * @subpackage Widgets
7
- * @copyright Copyright (c) 2017, Marius Cristea
8
- * @license http://opensource.org/licenses/gpl-3.0.php GNU Public License
9
- * @since 1.0.0
10
- */
11
- // Exit if accessed directly.
12
- if ( ! defined( 'ABSPATH' ) ) {
13
- exit;
14
- }
15
- if ( ! class_exists( 'ThemeIsle_SDK_Widgets_Factory' ) ) :
16
- /**
17
- * Widgets factory model for ThemeIsle SDK.
18
- */
19
- class ThemeIsle_SDK_Widgets_Factory {
20
-
21
- /**
22
- * ThemeIsle_SDK_Widgets_Factory constructor.
23
- *
24
- * @param ThemeIsle_SDK_Product $product_object Product Object.
25
- * @param array $widgets the widgets.
26
- */
27
- public function __construct( $product_object, $widgets ) {
28
- if ( $product_object instanceof ThemeIsle_SDK_Product && $widgets && is_array( $widgets ) ) {
29
- foreach ( $widgets as $widget ) {
30
- $class = 'ThemeIsle_SDK_Widget_' . str_replace( ' ', '_', ucwords( str_replace( '_', ' ', $widget ) ) );
31
- $instance = new $class( $product_object );
32
- $instance->setup_hooks();
33
- }
34
- }
35
- }
36
- }
37
- endif;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/codeinwp/themeisle-sdk/composer.json DELETED
@@ -1,24 +0,0 @@
1
- {
2
- "name": "codeinwp/themeisle-sdk",
3
- "description": "ThemeIsle SDK ",
4
- "keywords": [
5
- "wordpress"
6
- ],
7
- "homepage": "https://github.com/Codeinwp/themeisle-sdk",
8
- "license": "GPL-2.0+",
9
- "authors": [
10
- {
11
- "name": "ThemeIsle team",
12
- "email": "friends@themeisle.com",
13
- "homepage": "https://themeisle.com"
14
- }
15
- ],
16
- "autoload": {
17
- "files": [
18
- "load.php"
19
- ]
20
- },
21
- "support": {
22
- "issues": "https://github.com/Codeinwp/themeisle-sdk/issues"
23
- }
24
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/codeinwp/themeisle-sdk/index.php CHANGED
@@ -1,5 +1,3 @@
1
  <?php
2
- /**
3
- * @package ThemeIsleSDK
4
- * Ignore this.
5
- */
1
  <?php
2
+ // phpcs:ignoreFile
3
+ // Nothing here.
 
 
vendor/codeinwp/themeisle-sdk/load.php CHANGED
@@ -10,24 +10,38 @@
10
  * @since 1.1.0
11
  */
12
 
 
 
 
13
  // Current SDK version and path.
14
- $themeisle_sdk_version = '2.2.8';
15
  $themeisle_sdk_path = dirname( __FILE__ );
16
 
17
  global $themeisle_sdk_max_version;
18
  global $themeisle_sdk_max_path;
19
 
20
- if ( version_compare( $themeisle_sdk_version, $themeisle_sdk_max_version ) >= 0 ) {
 
 
 
 
 
21
  $themeisle_sdk_max_version = $themeisle_sdk_version;
22
  $themeisle_sdk_max_path = $themeisle_sdk_path;
23
  }
24
 
25
- // load the latest sdk version from the active Themeisle products
26
  if ( ! function_exists( 'themeisle_sdk_load_latest' ) ) :
27
  /**
28
  * Always load the latest sdk version.
29
  */
30
  function themeisle_sdk_load_latest() {
 
 
 
 
 
 
31
  global $themeisle_sdk_max_path;
32
  require_once $themeisle_sdk_max_path . '/start.php';
33
  }
10
  * @since 1.1.0
11
  */
12
 
13
+ if ( ! defined( 'ABSPATH' ) ) {
14
+ return;
15
+ }
16
  // Current SDK version and path.
17
+ $themeisle_sdk_version = '3.0.5';
18
  $themeisle_sdk_path = dirname( __FILE__ );
19
 
20
  global $themeisle_sdk_max_version;
21
  global $themeisle_sdk_max_path;
22
 
23
+ if ( version_compare( $themeisle_sdk_version, $themeisle_sdk_max_path ) == 0 &&
24
+ apply_filters( 'themeisle_sdk_should_overwrite_path', false, $themeisle_sdk_path, $themeisle_sdk_max_path ) ) {
25
+ $themeisle_sdk_max_path = $themeisle_sdk_path;
26
+ }
27
+
28
+ if ( version_compare( $themeisle_sdk_version, $themeisle_sdk_max_version ) > 0 ) {
29
  $themeisle_sdk_max_version = $themeisle_sdk_version;
30
  $themeisle_sdk_max_path = $themeisle_sdk_path;
31
  }
32
 
33
+ // load the latest sdk version from the active Themeisle products.
34
  if ( ! function_exists( 'themeisle_sdk_load_latest' ) ) :
35
  /**
36
  * Always load the latest sdk version.
37
  */
38
  function themeisle_sdk_load_latest() {
39
+ /**
40
+ * Don't load the library if we are on < 5.4.
41
+ */
42
+ if ( version_compare( PHP_VERSION, '5.4.32', '<' ) ) {
43
+ return;
44
+ }
45
  global $themeisle_sdk_max_path;
46
  require_once $themeisle_sdk_max_path . '/start.php';
47
  }
vendor/codeinwp/themeisle-sdk/src/Common/Abstract_module.php ADDED
@@ -0,0 +1,66 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The abstract class for module definition.
4
+ *
5
+ * @package ThemeIsleSDK
6
+ * @subpackage Loader
7
+ * @copyright Copyright (c) 2017, Marius Cristea
8
+ * @license http://opensource.org/licenses/gpl-3.0.php GNU Public License
9
+ * @since 3.0.0
10
+ */
11
+
12
+ namespace ThemeisleSDK\Common;
13
+
14
+ use ThemeisleSDK\Product;
15
+
16
+ if ( ! defined( 'ABSPATH' ) ) {
17
+ exit;
18
+ }
19
+
20
+ /**
21
+ * Class Abstract_Module.
22
+ *
23
+ * @package ThemeisleSDK\Common
24
+ */
25
+ abstract class Abstract_Module {
26
+ /**
27
+ * Product which use the module.
28
+ *
29
+ * @var Product $product Product object.
30
+ */
31
+ protected $product = null;
32
+
33
+ /**
34
+ * Can load the module for the selected product.
35
+ *
36
+ * @param Product $product Product data.
37
+ *
38
+ * @return bool Should load module?
39
+ */
40
+ public abstract function can_load( $product );
41
+
42
+ /**
43
+ * Bootstrap the module.
44
+ *
45
+ * @param Product $product Product object.
46
+ */
47
+ public abstract function load( $product );
48
+
49
+ /**
50
+ * Check if the product is from partner.
51
+ *
52
+ * @param Product $product Product data.
53
+ *
54
+ * @return bool Is product from partner.
55
+ */
56
+ public function is_from_partner( $product ) {
57
+
58
+ foreach ( Module_Factory::$domains as $partner_domain ) {
59
+ if ( strpos( $product->get_store_url(), $partner_domain ) !== false ) {
60
+ return true;
61
+ }
62
+ }
63
+
64
+ return array_key_exists( $product->get_slug(), Module_Factory::$slugs );
65
+ }
66
+ }
vendor/codeinwp/themeisle-sdk/src/Common/Module_factory.php ADDED
@@ -0,0 +1,108 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The module factory class.
4
+ *
5
+ * @package ThemeIsleSDK
6
+ * @subpackage Loader
7
+ * @copyright Copyright (c) 2017, Marius Cristea
8
+ * @license http://opensource.org/licenses/gpl-3.0.php GNU Public License
9
+ * @since 3.0.0
10
+ */
11
+
12
+ namespace ThemeisleSDK\Common;
13
+
14
+ use ThemeisleSDK\Product;
15
+
16
+ if ( ! defined( 'ABSPATH' ) ) {
17
+ exit;
18
+ }
19
+
20
+ /**
21
+ * Class Job_Factory
22
+ *
23
+ * @package ThemeisleSDK\Common
24
+ */
25
+ class Module_Factory {
26
+ /**
27
+ * Partners slugs.
28
+ *
29
+ * @var array $SLUGS Partners product slugs.
30
+ */
31
+ public static $slugs = [
32
+ 'zermatt' => true,
33
+ 'neto' => true,
34
+ 'olsen' => true,
35
+ 'benson' => true,
36
+ 'romero' => true,
37
+ 'carmack' => true,
38
+ 'puzzle' => true,
39
+ 'broadsheet' => true,
40
+ 'girlywp' => true,
41
+ 'veggie' => true,
42
+ 'zeko' => true,
43
+ 'maishawp' => true,
44
+ 'didi' => true,
45
+ 'liber' => true,
46
+ 'medicpress-pt' => true,
47
+ 'adrenaline-pt' => true,
48
+ 'consultpress-pt' => true,
49
+ 'legalpress-pt' => true,
50
+ 'gympress-pt' => true,
51
+ 'readable-pt' => true,
52
+ 'bolts-pt' => true,
53
+ ];
54
+ /**
55
+ * Partners domains.
56
+ *
57
+ * @var array $DOMAINS Partners domains.
58
+ */
59
+ public static $domains = [
60
+ 'proteusthemes.com',
61
+ 'anarieldesign.com',
62
+ 'prothemedesign.com',
63
+ 'cssigniter.com',
64
+ ];
65
+ /**
66
+ * Map which contains all the modules loaded for each product.
67
+ *
68
+ * @var array Mapping array.
69
+ */
70
+ private static $modules_attached = [];
71
+
72
+ /**
73
+ * Load availabe modules for the selected product.
74
+ *
75
+ * @param Product $product Loaded product.
76
+ * @param array $modules List of modules.
77
+ */
78
+ public static function attach( $product, $modules ) {
79
+
80
+ if ( ! isset( self::$modules_attached[ $product->get_slug() ] ) ) {
81
+ self::$modules_attached[ $product->get_slug() ] = [];
82
+ }
83
+
84
+ foreach ( $modules as $module ) {
85
+ $class = 'ThemeisleSDK\\Modules\\' . ucwords( $module, '_' );
86
+ /**
87
+ * Module object.
88
+ *
89
+ * @var Abstract_Module $module_object Module instance.
90
+ */
91
+ $module_object = new $class( $product );
92
+
93
+ if ( ! $module_object->can_load( $product ) ) {
94
+ continue;
95
+ }
96
+ self::$modules_attached[ $product->get_slug() ][ $module ] = $module_object->load( $product );
97
+ }
98
+ }
99
+
100
+ /**
101
+ * Products/Modules loaded map.
102
+ *
103
+ * @return array Modules map.
104
+ */
105
+ public static function get_modules_map() {
106
+ return self::$modules_attached;
107
+ }
108
+ }
vendor/codeinwp/themeisle-sdk/src/Loader.php ADDED
@@ -0,0 +1,126 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The main loader class for ThemeIsle SDK
4
+ *
5
+ * @package ThemeIsleSDK
6
+ * @subpackage Loader
7
+ * @copyright Copyright (c) 2017, Marius Cristea
8
+ * @license http://opensource.org/licenses/gpl-3.0.php GNU Public License
9
+ * @since 1.0.0
10
+ */
11
+
12
+ namespace ThemeisleSDK;
13
+
14
+ use ThemeisleSDK\Common\Module_Factory;
15
+
16
+ if ( ! defined( 'ABSPATH' ) ) {
17
+ exit;
18
+ }
19
+
20
+
21
+ /**
22
+ * Singleton loader for ThemeIsle SDK.
23
+ */
24
+ final class Loader {
25
+ /**
26
+ * Singleton instance.
27
+ *
28
+ * @var Loader instance The singleton instance
29
+ */
30
+ private static $instance;
31
+ /**
32
+ * Current loader version.
33
+ *
34
+ * @var string $version The class version.
35
+ */
36
+ private static $version = '2.0.0';
37
+ /**
38
+ * Holds registered products.
39
+ *
40
+ * @var array The products which use the SDK.
41
+ */
42
+ private static $products = [];
43
+ /**
44
+ * Holds available modules to load.
45
+ *
46
+ * @var array The modules which SDK will be using.
47
+ */
48
+ private static $available_modules = [
49
+ 'dashboard_widget',
50
+ 'rollback',
51
+ 'uninstall_feedback',
52
+ 'licenser',
53
+ 'endpoint',
54
+ 'notification',
55
+ 'logger',
56
+ 'translate',
57
+ 'review',
58
+ 'recommendation',
59
+
60
+ ];
61
+
62
+ /**
63
+ * Initialize the sdk logic.
64
+ */
65
+ public static function init() {
66
+ if ( ! isset( self::$instance ) && ! ( self::$instance instanceof Loader ) ) {
67
+ self::$instance = new Loader();
68
+ $modules = array_merge( self::$available_modules, apply_filters( 'themeisle_sdk_modules', [] ) );
69
+ foreach ( $modules as $key => $module ) {
70
+ if ( ! class_exists( 'ThemeisleSDK\\Modules\\' . ucwords( $module, '_' ) ) ) {
71
+ unset( $modules[ $key ] );
72
+ }
73
+ }
74
+ self::$available_modules = $modules;
75
+ }
76
+ }
77
+
78
+ /**
79
+ * Register product into SDK.
80
+ *
81
+ * @param string $base_file The product base file.
82
+ *
83
+ * @return Loader The singleton object.
84
+ */
85
+ public static function add_product( $base_file ) {
86
+
87
+ if ( ! is_readable( $base_file ) ) {
88
+ return self::$instance;
89
+ }
90
+ $product = new Product( $base_file );
91
+
92
+ Module_Factory::attach( $product, self::get_modules() );
93
+
94
+ self::$products[ $product->get_slug() ] = $product;
95
+
96
+ return self::$instance;
97
+ }
98
+
99
+ /**
100
+ * Get all registered modules by the SDK.
101
+ *
102
+ * @return array Modules available.
103
+ */
104
+ public static function get_modules() {
105
+ return self::$available_modules;
106
+ }
107
+
108
+ /**
109
+ * Get all products using the SDK.
110
+ *
111
+ * @return array Products available.
112
+ */
113
+ public static function get_products() {
114
+ return self::$products;
115
+ }
116
+
117
+ /**
118
+ * Get the version of the SDK.
119
+ *
120
+ * @return string The version.
121
+ */
122
+ public static function get_version() {
123
+ return self::$version;
124
+ }
125
+
126
+ }
vendor/codeinwp/themeisle-sdk/src/Modules/Dashboard_widget.php ADDED
@@ -0,0 +1,464 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The blog dashboard model class for ThemeIsle SDK
4
+ *
5
+ * @package ThemeIsleSDK
6
+ * @subpackage Modules
7
+ * @copyright Copyright (c) 2017, Marius Cristea
8
+ * @license http://opensource.org/licenses/gpl-3.0.php GNU Public License
9
+ * @since 1.0.0
10
+ */
11
+
12
+ namespace ThemeisleSDK\Modules;
13
+
14
+ use ThemeisleSDK\Common\Abstract_Module;
15
+ use ThemeisleSDK\Product;
16
+
17
+ // Exit if accessed directly.
18
+ if ( ! defined( 'ABSPATH' ) ) {
19
+ exit;
20
+ }
21
+
22
+ /**
23
+ * Blog dashboard widget module for ThemeIsle SDK.
24
+ */
25
+ class Dashboard_Widget extends Abstract_Module {
26
+
27
+ /**
28
+ * Fetched feeds items.
29
+ *
30
+ * @var array Feed items.
31
+ */
32
+ private $items = array();
33
+
34
+ /**
35
+ * Dashboard widget title.
36
+ *
37
+ * @var string $dashboard_name Dashboard name.
38
+ */
39
+ private $dashboard_name = '';
40
+
41
+ /**
42
+ * Dashboard widget feed sources.
43
+ *
44
+ * @var array $feeds Feed url.
45
+ */
46
+ private $feeds = [];
47
+
48
+ /**
49
+ * Should we load this module.
50
+ *
51
+ * @param Product $product Product object.
52
+ *
53
+ * @return bool
54
+ */
55
+ public function can_load( $product ) {
56
+ if ( $this->is_from_partner( $product ) ) {
57
+ return false;
58
+ }
59
+
60
+ if ( ! apply_filters( $product->get_slug() . '_load_dashboard_widget', true ) ) {
61
+ return false;
62
+ }
63
+
64
+ return true;
65
+ }
66
+
67
+ /**
68
+ * Registers the hooks.
69
+ *
70
+ * @param Product $product Product to load.
71
+ *
72
+ * @return Dashboard_Widget Module instance.
73
+ */
74
+ public function load( $product ) {
75
+
76
+ $this->product = $product;
77
+ $this->dashboard_name = apply_filters( 'themeisle_sdk_dashboard_widget_name', 'WordPress Guides/Tutorials' );
78
+ $this->feeds = apply_filters(
79
+ 'themeisle_sdk_dashboard_widget_feeds',
80
+ [
81
+ 'https://themeisle.com/blog/feed',
82
+ ]
83
+ );
84
+ add_action( 'wp_dashboard_setup', array( &$this, 'add_widget' ) );
85
+ add_action( 'wp_network_dashboard_setup', array( &$this, 'add_widget' ) );
86
+ add_filter( 'themeisle_sdk_recommend_plugin_or_theme', array( &$this, 'recommend_plugin_or_theme' ) );
87
+
88
+ return $this;
89
+ }
90
+
91
+
92
+ /**
93
+ * Add widget to the dashboard
94
+ *
95
+ * @return string|void
96
+ */
97
+ function add_widget() {
98
+ global $wp_meta_boxes;
99
+ if ( isset( $wp_meta_boxes['dashboard']['normal']['core']['themeisle'] ) ) {
100
+ return;
101
+ }
102
+ wp_add_dashboard_widget(
103
+ 'themeisle',
104
+ $this->dashboard_name,
105
+ [
106
+ $this,
107
+ 'render_dashboard_widget',
108
+ ]
109
+ );
110
+ }
111
+
112
+ /**
113
+ * Render widget content
114
+ */
115
+ function render_dashboard_widget() {
116
+ $this->setup_feeds();
117
+ if ( empty( $this->items ) || ! is_array( $this->items ) ) {
118
+ return;
119
+ }
120
+ ?>
121
+ <style type="text/css">
122
+ #themeisle ul li.ti-dw-recommend-item {
123
+ padding-left: 7px;
124
+ border-top: 1px solid #eee;
125
+ margin-bottom: 0px;
126
+ padding-top: 6px;
127
+ }
128
+
129
+ #themeisle h2.hndle {
130
+ background-image: url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA3Ny4xMiA3Ny4xMiI+PHRpdGxlPkFzc2V0IDM8L3RpdGxlPjxwYXRoIGQ9Ik03NS43Niw0Ny42cS0xLjUsNi40Ni00LjA3LDkuMjZBMzYuMjIsMzYuMjIsMCwwLDEsNjMuMjYsNjNhNTEsNTEsMCwwLDEtOS43OSw0LjZoLS4xNXY0LjgyQTQuNjYsNC42NiwwLDAsMSw1Miw3NS43Niw0LjA3LDQuMDcsMCwwLDEsNDksNzcuMTJhNCw0LDAsMCwxLTIuMTgtLjYxQTQuOTQsNC45NCwwLDAsMSw0NS4xOSw3NWE0LjQyLDQuNDIsMCwwLDEtNy41NCwwLDQuOTQsNC45NCwwLDAsMS0xLjU4LDEuNSwzLjc1LDMuNzUsMCwwLDEtMiwuNjFBNC4yNyw0LjI3LDAsMCwxLDMwLjI3LDc1YTQuOTQsNC45NCwwLDAsMS0xLjU4LDEuNSw0LDQsMCwwLDEtMi4xOC42MSwzLjkzLDMuOTMsMCwwLDEtMy4xNi0xLjQzLDUuMyw1LjMsMCwwLDEtMS4yMS0zLjU0LDEzLjgxLDEzLjgxLDAsMCwxLTguNTgsMywxMy4yMywxMy4yMywwLDAsMS05LTMuNDdBMTguMjEsMTguMjEsMCwwLDAsOSw3MC43OWExNC4yNiwxNC4yNiwwLDAsMS03LjgzLTUuNDIsMTYuMTIsMTYuMTIsMCwwLDAsNS4xOS4wNywxMi44OSwxMi44OSwwLDAsMCw0LjktMS43M1EzLjE1LDU1LjQzLDEuMDUsNTAuNDZhMTgsMTgsMCwwLDEtMS02LjkzQTQwLDQwLDAsMCwxLDEuMjEsMzQsMjYuNTksMjYuNTksMCwwLDEsNS4yNywyNC4xUTguNDQsMTkuNDMsMTMsMTkuNDNhMy40MSwzLjQxLDAsMCwxLDMuNDcsMi4yNmMuNi0uOCwxLjItMS41NiwxLjgxLTIuMjZsLjQ1LS40NS43NS0uNzUsMS4wNS0xLjgxYTM1LjIsMzUuMiwwLDAsMSwyLjExLTMuMzIsMjguNTcsMjguNTcsMCwwLDEsOS4xMi03LjY4QTIzLjQsMjMuNCwwLDAsMSw0Mi45MywyLjU2YTIyLjIyLDIyLjIyLDAsMCwxLDIuNzEuMTVBOC4xNiw4LjE2LDAsMCwxLDUxLjgxLDAsOC42OSw4LjY5LDAsMCwxLDU4LDIuNDFhMS41MSwxLjUxLDAsMCwxLC4xNS42OGMwLC4yNS0uNTUuOTMtMS42NiwybC0uMy4zYTkuNjksOS42OSwwLDAsMSwxLjU4LjgzYy41NS4zNS44My42NS44My45YTEuNjIsMS42MiwwLDAsMS0uNiwxbC0uMTUuMTVxNi43OCw2LDguNTgsMTYuMjdBMy4zLDMuMywwLDAsMSw2OSwyMy4zNWE2LjQ4LDYuNDgsMCwwLDEsNC4yMiwyLjFxMy45MiwzLjMyLDMuOTIsMTEuOUE0Mi4wNSw0Mi4wNSwwLDAsMSw3NS43Niw0Ny42Wk01My42Miw1NC4wN2EyNCwyNCwwLDAsMS0xNCw0LjUyQTIxLjQxLDIxLjQxLDAsMCwxLDI3LDU0LjY3LDI0LjI4LDI0LjI4LDAsMCwxLDE4LjUzLDQ1YTI5LDI5LDAsMCwxLTMtMTMsMzEuNzgsMzEuNzgsMCwwLDEsLjkxLTcuNTNBMzIuMTcsMzIuMTcsMCwwLDAsMTEuOSw0MS4yN2EzMy41LDMzLjUsMCwwLDAsMi43OSwxMy40LDI5LjEsMjkuMSwwLDAsMCw3LjksMTAuODUsNC42OCw0LjY4LDAsMCwxLDEuNjYtMS44OCw0LjE3LDQuMTcsMCwwLDEsNC40NC0uMDgsNC41LDQuNSwwLDAsMSwxLjU4LDEuNjZBNC4yLDQuMiwwLDAsMSwzNCw2M2EzLjgzLDMuODMsMCwwLDEsMiwuNiw0LjUsNC41LDAsMCwxLDEuNTgsMS42Niw0LjI3LDQuMjcsMCwwLDEsNy41NCwwLDQuNSw0LjUsMCwwLDEsMS41OC0xLjY2LDQuMTcsNC4xNywwLDAsMSw0LjQ0LjA4LDMuODYsMy44NiwwLDAsMSwxLjUxLDEuNzMsMzAuMTcsMzAuMTcsMCwwLDAsNy42OC05Ljk0LDMxLjE4LDMxLjE4LDAsMCwwLDMuMTYtMTIuMzVBMjguMzksMjguMzksMCwwLDEsNTMuNjIsNTQuMDdaTTI4Ljc3LDY1LjM3YTMuMSwzLjEsMCwwLDAtNC4zNywwLDMuMDYsMy4wNiwwLDAsMC0uOSwyLjI2djQuODJhMy4zMiwzLjMyLDAsMCwwLC45LDIuMzMsMi45MywyLjkzLDAsMCwwLDQuMzcsMCwzLjMyLDMuMzIsMCwwLDAsLjktMi4zM1Y2Ny42M0EzLjA2LDMuMDYsMCwwLDAsMjguNzcsNjUuMzdabS45LTQ4YTQuMjQsNC4yNCwwLDAsMCwzLjQ3LDEuNzMsNC40NSw0LjQ1LDAsMCwwLDMuNTQtMS43Myw2LDYsMCwwLDAsMS40My0zLjkyLDUuNyw1LjcsMCwwLDAtMS40My0zLjg0QTQuNTMsNC41MywwLDAsMCwzMy4xNCw4YTQuMzEsNC4zMSwwLDAsMC0zLjQ3LDEuNjYsNS43OSw1Ljc5LDAsMCwwLTEuMzUsMy43N0E2LjMzLDYuMzMsMCwwLDAsMjkuNjcsMTcuNFptNi40OCw0OGEzLjEsMy4xLDAsMCwwLTQuMzcsMCwzLjA2LDMuMDYsMCwwLDAtLjksMi4yNnY0LjgyYTMuMzIsMy4zMiwwLDAsMCwuOSwyLjMzLDIuOTMsMi45MywwLDAsMCw0LjM3LDAsMy4zMiwzLjMyLDAsMCwwLC45LTIuMzNWNjcuNjNBMy4wNiwzLjA2LDAsMCwwLDM2LjE1LDY1LjM3Wm0tNC4wNy01NC4zYTIuMzcsMi4zNywwLDAsMSwyLTEsMi4xNywyLjE3LDAsMCwxLDEuODgsMSw0LjEsNC4xLDAsMCwxLDAsNC41MiwyLjE3LDIuMTcsMCwwLDEtMS44OCwxLDIuMzcsMi4zNywwLDAsMS0yLTEsMy43MiwzLjcyLDAsMCwxLS43NS0yLjM0QTMuNDksMy40OSwwLDAsMSwzMi4wOCwxMS4wN1ptNSw5LjQxYTIwLjYxLDIwLjYxLDAsMCwwLTMuNTQsMTIuMjgsMTcuMTUsMTcuMTUsMCwwLDAsNC4wNywxMSwxMi40MywxMi40MywwLDAsMCw5Ljg3LDQuNDUsMTUuMywxNS4zLDAsMCwwLDktMywxMywxMywwLDAsMCwuNi0zLjMycTAtMy4zMi0zLjE2LTMuMzFhOC41OCw4LjU4LDAsMCwwLTIsLjNxLTcuODMsMS41LTExLjU5LS4zLTQuNTMtMi4xMi00LjUyLTkuMzRBMzcuOTIsMzcuOTIsMCwwLDEsMzcuMDUsMjAuNDhaTTYxLjQ1LDE3QTEyLjg0LDEyLjg0LDAsMCwwLDUxLjIxLDEyLjJhMTUuMTEsMTUuMTEsMCwwLDAtNi40LDEuNDMsMTcuODMsMTcuODMsMCwwLDAtNS41LDRxLTYuMTgsMjAuNjQsNi4xOCwyMC42NEEyNC43NSwyNC43NSwwLDAsMCw0OSwzNy44MWEzOC45MiwzOC45MiwwLDAsMSw0LjgyLS40NmMxLjgxLDAsMy4wNi40NiwzLjc3LDEuMzZxMS4zNSwxLjUuNzUsNS4xMmEyMS43MiwyMS43MiwwLDAsMCw1LTcuMTVBMjEuMzgsMjEuMzgsMCwwLDAsNjUuMDcsMjgsMTcuNDQsMTcuNDQsMCwwLDAsNjEuNDUsMTdaTTQzLjYsNjUuMzdhMi43MiwyLjcyLDAsMCwwLTIuMS0uOSwzLDMsMCwwLDAtMi4xOS45LDMuMDYsMy4wNiwwLDAsMC0uOSwyLjI2djQuODJhMy4zMiwzLjMyLDAsMCwwLC45LDIuMzMsMi44NCwyLjg0LDAsMCwwLDIuMTksMSwyLjYxLDIuNjEsMCwwLDAsMi4xLTEsMy40NSwzLjQ1LDAsMCwwLC44My0yLjMzVjY3LjYzQTMuMTcsMy4xNywwLDAsMCw0My42LDY1LjM3Wm03LjQ2LDBhMywzLDAsMCwwLTIuMTgtLjksMi43MywyLjczLDAsMCwwLTIuMTEuOSwzLjE3LDMuMTcsMCwwLDAtLjgzLDIuMjZ2NC44MmEzLjQ1LDMuNDUsMCwwLDAsLjgzLDIuMzMsMi42MSwyLjYxLDAsMCwwLDIuMTEsMSwyLjgzLDIuODMsMCwwLDAsMi4xOC0xLDMuMzIsMy4zMiwwLDAsMCwuOS0yLjMzVjY3LjYzQTMuMDYsMy4wNiwwLDAsMCw1MS4wNiw2NS4zN1oiLz48L3N2Zz4=');
131
+ background-repeat: no-repeat;
132
+ background-position: 92% 50%;
133
+ background-size: 30px;
134
+ }
135
+
136
+ #themeisle .inside {
137
+ padding: 0;
138
+ }
139
+
140
+ .ti-feed-list {
141
+ padding: 0 12px 5px;
142
+ margin-bottom: 10px;
143
+ border-bottom: 1px solid #eee;
144
+ }
145
+
146
+ .ti-dw-feed-item a {
147
+ display: flex;
148
+ align-items: center;
149
+ margin-bottom: 5px;
150
+ padding: 5px;
151
+ transition: .2s ease;
152
+ border-radius: 3px;
153
+ }
154
+
155
+ .ti-dw-feed-item a:hover {
156
+ background-color: #f8f8f8;
157
+ }
158
+
159
+ .ti-dw-feed-item a:hover .ti-dw-date-container {
160
+ opacity: .9;
161
+ }
162
+
163
+ .ti-dw-feed-item .ti-dw-month-container {
164
+ margin-top: -5px;
165
+ text-transform: uppercase;
166
+ font-size: 10px;
167
+ letter-spacing: 1px;
168
+ font-weight: 700;
169
+ }
170
+
171
+ .ti-dw-feed-item .ti-dw-date-container {
172
+ border-radius: 3px;
173
+ transition: .2s ease;
174
+ min-height: 35px;
175
+ margin-right: 5px;
176
+ min-width: 35px;
177
+ text-align: center;
178
+ border: 1px solid #2a6f97;
179
+ color: #fff;
180
+ background: #2ea2cc;
181
+ display: flex;
182
+ flex-direction: column;
183
+ justify-content: center;
184
+ }
185
+
186
+ .ti-dw-footer {
187
+ padding: 0 12px 5px;
188
+ text-align: center;
189
+ }
190
+
191
+ .ti-dw-recommend-item {
192
+ display: block;
193
+ }
194
+
195
+ .ti-dw-recommend-item span {
196
+ color: #72777c;
197
+ }
198
+
199
+ .ti-dw-powered-by {
200
+ font-size: 11px;
201
+ margin-top: 3px;
202
+ display: block;
203
+ color: #72777c;
204
+ }
205
+
206
+ .ti-dw-powered-by span {
207
+ font-weight: 600;
208
+ }
209
+
210
+ </style>
211
+ <?php do_action( 'themeisle_sdk_dashboard_widget_before', $this->product ); ?>
212
+
213
+ <ul class="ti-feed-list">
214
+ <?php
215
+
216
+ foreach ( $this->items as $item ) {
217
+ ?>
218
+ <li class="ti-dw-feed-item">
219
+ <a href="
220
+ <?php
221
+ echo add_query_arg(
222
+ array(
223
+ 'utm_source' => 'wpadmin',
224
+ 'utm_campaign' => 'feed',
225
+ 'utm_medium' => 'dashboard_widget',
226
+ ),
227
+ $item['link']
228
+ );
229
+ ?>
230
+ " target="_blank">
231
+ <span class="ti-dw-date-container"><span
232
+ class="ti-dw-day-container"><?php echo date( 'd', $item['date'] ); ?></span> <span
233
+ class="ti-dw-month-container"><?php echo substr( date( 'M', $item['date'] ), 0, 3 ); ?></span></span><?php echo $item['title']; ?>
234
+ </a>
235
+ </li>
236
+ <?php
237
+ }
238
+ ?>
239
+ </ul>
240
+ <?php
241
+ $recommend = apply_filters( 'themeisle_sdk_recommend_plugin_or_theme', array() );
242
+ if ( ! is_array( $recommend ) || empty( $recommend ) ) {
243
+ return;
244
+ }
245
+
246
+ $type = $recommend['type'];
247
+
248
+ if ( ( 'theme' === $type && ! current_user_can( 'install_themes' ) ) ) {
249
+ return;
250
+ }
251
+ if ( ( 'plugin' === $type && ! current_user_can( 'install_plugins' ) ) ) {
252
+ return;
253
+ }
254
+
255
+ add_thickbox();
256
+ $url = add_query_arg(
257
+ [
258
+ 'theme' => $recommend['slug'],
259
+ ],
260
+ network_admin_url( 'theme-install.php' )
261
+ );
262
+
263
+ if ( 'plugin' === $type ) {
264
+
265
+ $url = add_query_arg(
266
+ array(
267
+ 'tab' => 'plugin-information',
268
+ 'plugin' => $recommend['slug'],
269
+ ),
270
+ network_admin_url( 'plugin-install.php' )
271
+ );
272
+ }
273
+ ?>
274
+ <div class="ti-dw-footer">
275
+ <span class="ti-dw-recommend-item ">
276
+ <span class="ti-dw-recommend"><?php echo apply_filters( 'themeisle_sdk_dashboard_popular_label', sprintf( 'Popular %s', ucwords( $type ) ) ); ?>
277
+ : </span>
278
+ <?php
279
+ echo trim(
280
+ str_replace(
281
+ array(
282
+ 'lite',
283
+ 'Lite',
284
+ '(Lite)',
285
+ '(lite)',
286
+ ),
287
+ '',
288
+ $recommend['name']
289
+ )
290
+ );
291
+ ?>
292
+ (<a class="thickbox open-plugin-details-modal"
293
+ href="<?php echo $url . '&TB_iframe=true&width=600&height=500'; ?>"><?php echo apply_filters( 'themeisle_sdk_dashboard_install_label', 'Install' ); ?></a>)
294
+ </span>
295
+ <span class="ti-dw-powered-by"><span><?php echo apply_filters( 'themeisle_sdk_dashboard_widget_powered_by', esc_attr( sprintf( 'Powered by %s', $this->product->get_friendly_name() ) ) ); ?></span></span>
296
+ </div>
297
+
298
+ <?php
299
+
300
+ }
301
+
302
+ /**
303
+ * Setup feed items.
304
+ */
305
+ private function setup_feeds() {
306
+ if ( false === ( $items_normalized = get_transient( 'themeisle_sdk_feed_items' ) ) ) {
307
+ // Load SimplePie Instance.
308
+ $feed = fetch_feed( $this->feeds );
309
+ // TODO report error when is an error loading the feed.
310
+ if ( is_wp_error( $feed ) ) {
311
+ return;
312
+ }
313
+
314
+ $items = $feed->get_items( 0, 5 );
315
+ foreach ( (array) $items as $item ) {
316
+ $items_normalized[] = array(
317
+ 'title' => $item->get_title(),
318
+ 'date' => $item->get_date( 'U' ),
319
+ 'link' => $item->get_permalink(),
320
+ );
321
+ }
322
+ set_transient( 'themeisle_sdk_feed_items', $items_normalized, 48 * HOUR_IN_SECONDS );
323
+ }
324
+ $this->items = $items_normalized;
325
+ }
326
+
327
+ /**
328
+ * Either the current product is installed or not.
329
+ *
330
+ * @param array $val The current recommended product.
331
+ *
332
+ * @return bool Either we should exclude the plugin or not.
333
+ */
334
+ public function remove_current_products( $val ) {
335
+ if ( 'theme' === $val['type'] ) {
336
+ $exist = wp_get_theme( $val['slug'] );
337
+
338
+ return ! $exist->exists();
339
+ } else {
340
+ $all_plugins = array_keys( get_plugins() );
341
+ foreach ( $all_plugins as $slug ) {
342
+ if ( strpos( $slug, $val['slug'] ) !== false ) {
343
+ return false;
344
+ }
345
+ }
346
+
347
+ return true;
348
+ }
349
+ }
350
+
351
+ /**
352
+ * Contact the API and fetch the recommended plugins/themes
353
+ */
354
+ function recommend_plugin_or_theme() {
355
+ $products = $this->get_product_from_api();
356
+ if ( ! is_array( $products ) ) {
357
+ $products = array();
358
+ }
359
+ $products = array_filter( $products, array( $this, 'remove_current_products' ) );
360
+ $products = array_merge( $products );
361
+ if ( count( $products ) > 1 ) {
362
+ shuffle( $products );
363
+ $products = array_slice( $products, 0, 1 );
364
+ }
365
+ $to_recommend = isset( $products[0] ) ? $products[0] : $products;
366
+
367
+ return $to_recommend;
368
+ }
369
+
370
+ /**
371
+ * Fetch products from the recomended section.
372
+ *
373
+ * @return array|mixed The list of products to use in recomended section.
374
+ */
375
+ function get_product_from_api() {
376
+ if ( false === ( $products = get_transient( 'themeisle_sdk_products' ) ) ) {
377
+ $products = array();
378
+ $all_themes = $this->get_themes_from_wporg( 'themeisle' );
379
+ $all_plugins = $this->get_plugins_from_wporg( 'themeisle' );
380
+ static $allowed_products = [
381
+ 'hestia' => true,
382
+ 'neve' => true,
383
+ 'visualizer' => true,
384
+ 'feedzy-rss-feeds' => true,
385
+ 'wp-product-review' => true,
386
+ 'otter-blocks' => true,
387
+ 'themeisle-companion' => true,
388
+ ];
389
+ foreach ( $all_themes as $theme ) {
390
+ if ( $theme->active_installs < 4999 ) {
391
+ continue;
392
+ }
393
+ if ( ! isset( $allowed_products[ $theme->slug ] ) ) {
394
+ continue;
395
+ }
396
+ $products[] = array(
397
+ 'name' => $theme->name,
398
+ 'type' => 'theme',
399
+ 'slug' => $theme->slug,
400
+ 'installs' => $theme->active_installs,
401
+ );
402
+ }
403
+ foreach ( $all_plugins as $plugin ) {
404
+ if ( $plugin->active_installs < 4999 ) {
405
+ continue;
406
+ }
407
+ if ( ! isset( $allowed_products[ $plugin->slug ] ) ) {
408
+ continue;
409
+ }
410
+ $products[] = array(
411
+ 'name' => $plugin->name,
412
+ 'type' => 'plugin',
413
+ 'slug' => $plugin->slug,
414
+ 'installs' => $plugin->active_installs,
415
+ );
416
+ }
417
+ set_transient( 'themeisle_sdk_products', $products, 6 * HOUR_IN_SECONDS );
418
+ }
419
+
420
+ return $products;
421
+ }
422
+
423
+ /**
424
+ * Fetch themes from wporg api.
425
+ *
426
+ * @param string $author The author name.
427
+ *
428
+ * @return array The list of themes.
429
+ */
430
+ function get_themes_from_wporg( $author ) {
431
+ $products = wp_remote_get(
432
+ 'https://api.wordpress.org/themes/info/1.1/?action=query_themes&request[author]=' . $author . '&request[per_page]=30&request[fields][active_installs]=true'
433
+ );
434
+ $products = json_decode( wp_remote_retrieve_body( $products ) );
435
+ if ( is_object( $products ) ) {
436
+ $products = isset( $products->themes ) ? $products->themes : array();
437
+ } else {
438
+ $products = array();
439
+ }
440
+
441
+ return (array) $products;
442
+ }
443
+
444
+ /**
445
+ * Fetch plugin from wporg api.
446
+ *
447
+ * @param string $author The author slug.
448
+ *
449
+ * @return array The list of plugins for the selected author.
450
+ */
451
+ function get_plugins_from_wporg( $author ) {
452
+ $products = wp_remote_get(
453
+ 'https://api.wordpress.org/plugins/info/1.1/?action=query_plugins&request[author]=' . $author . '&request[per_page]=40&request[fields][active_installs]=true'
454
+ );
455
+ $products = json_decode( wp_remote_retrieve_body( $products ) );
456
+ if ( is_object( $products ) ) {
457
+ $products = isset( $products->plugins ) ? $products->plugins : array();
458
+ } else {
459
+ $products = array();
460
+ }
461
+
462
+ return (array) $products;
463
+ }
464
+ }
vendor/codeinwp/themeisle-sdk/src/Modules/Endpoint.php ADDED
@@ -0,0 +1,358 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The class that exposes endpoints.
4
+ *
5
+ * @package ThemeIsleSDK
6
+ * @subpackage Rollback
7
+ * @copyright Copyright (c) 2017, Marius Cristea
8
+ * @license http://opensource.org/licenses/gpl-3.0.php GNU Public License
9
+ * @since 1.0.0
10
+ */
11
+
12
+ namespace ThemeisleSDK\Modules;
13
+
14
+ // Exit if accessed directly.
15
+ use ThemeisleSDK\Common\Abstract_Module;
16
+ use ThemeisleSDK\Loader;
17
+ use ThemeisleSDK\Product;
18
+
19
+ if ( ! defined( 'ABSPATH' ) ) {
20
+ exit;
21
+ }
22
+
23
+ /**
24
+ * Expose endpoints for ThemeIsle SDK.
25
+ */
26
+ class Endpoint extends Abstract_Module {
27
+ /**
28
+ * Endpoint slug.
29
+ */
30
+ const SDK_ENDPOINT = 'themeisle-sdk';
31
+ /**
32
+ * Endpoint version.
33
+ */
34
+ const SDK_ENDPOINT_VERSION = 1;
35
+ /**
36
+ * Hash file which contains the checksum.
37
+ */
38
+ const HASH_FILE = 'themeisle-hash.json';
39
+
40
+ /*
41
+ * If true, the endpoint will expect a product slug and will return the value only for that.
42
+ */
43
+ const PRODUCT_SPECIFIC = false;
44
+
45
+ /**
46
+ * Registers the endpoints.
47
+ */
48
+ function rest_register() {
49
+ register_rest_route(
50
+ self::SDK_ENDPOINT . '/v' . self::SDK_ENDPOINT_VERSION,
51
+ '/checksum/' . ( self::PRODUCT_SPECIFIC ? '(?P<slug>.*)/' : '' ),
52
+ array(
53
+ 'methods' => 'GET',
54
+ 'callback' => array( $this, 'checksum' ),
55
+ )
56
+ );
57
+ }
58
+
59
+ /**
60
+ * The checksum endpoint.
61
+ *
62
+ * @param \WP_REST_Request $data the request.
63
+ *
64
+ * @return \WP_REST_Response Response or the error
65
+ */
66
+ function checksum( \WP_REST_Request $data ) {
67
+ $products = Loader::get_products();
68
+ if ( self::PRODUCT_SPECIFIC ) {
69
+ $params = $this->validate_params( $data, array( 'slug' ) );
70
+ foreach ( $products as $product ) {
71
+ if ( $params['slug'] === $product->get_slug() ) {
72
+ $products = array( $product );
73
+ break;
74
+ }
75
+ }
76
+ }
77
+ $response = array();
78
+ $custom_css = $this->has_custom_css();
79
+ if ( is_bool( $custom_css ) ) {
80
+ $response['custom_css'] = $custom_css;
81
+ }
82
+
83
+ $response['child_theme'] = $this->get_theme_properties();
84
+
85
+ foreach ( $products as $product ) {
86
+ $files = array();
87
+ switch ( $product->get_type() ) {
88
+ case 'plugin':
89
+ $files = array();
90
+ break;
91
+ case 'theme':
92
+ $files = array( 'style.css', 'functions.php' );
93
+ break;
94
+ }
95
+
96
+ $error = '';
97
+
98
+ // if any element in the $files array contains a '/', this would imply recursion is required.
99
+ $diff = $this->generate_diff(
100
+ $product,
101
+ $files,
102
+ array_reduce(
103
+ $files,
104
+ array(
105
+ $this,
106
+ 'is_recursion_required',
107
+ ),
108
+ false
109
+ )
110
+ );
111
+ if ( is_wp_error( $diff ) ) {
112
+ /**
113
+ * Error returner by the diff checker method.
114
+ *
115
+ * @var \WP_Error $diff Error returned.
116
+ */
117
+ $error = $diff->get_error_message();
118
+ $diff = array();
119
+ }
120
+
121
+ $response['products'][] = array(
122
+ 'slug' => $product->get_slug(),
123
+ 'version' => $product->get_version(),
124
+ 'diffs' => $diff,
125
+ 'error' => $error,
126
+ );
127
+ }
128
+
129
+ return new \WP_REST_Response( array( 'checksum' => $response ) );
130
+ }
131
+
132
+ /**
133
+ * Validates the parameters to the API
134
+ *
135
+ * @param \WP_REST_Request $data the request.
136
+ * @param array $params the parameters to validate.
137
+ *
138
+ * @return array of parameter name=>value
139
+ */
140
+ private function validate_params( \WP_REST_Request $data, $params ) {
141
+ $collect = array();
142
+ foreach ( $params as $param ) {
143
+ $value = sanitize_text_field( $data[ $param ] );
144
+ if ( empty( $value ) ) {
145
+ return rest_ensure_response(
146
+ new \WP_Error(
147
+ 'themeisle_' . $param . '_invalid',
148
+ sprintf( 'Invalid %', $param ),
149
+ array(
150
+ 'status' => 403,
151
+ )
152
+ )
153
+ );
154
+ } else {
155
+ $collect[ $param ] = $value;
156
+ }
157
+ }
158
+
159
+ return $collect;
160
+ }
161
+
162
+ /**
163
+ * Check if custom css has been added to the theme.
164
+ *
165
+ * @return bool Whether custom css has been added to the theme.
166
+ */
167
+ private function has_custom_css() {
168
+ $query = new \WP_Query(
169
+ array(
170
+ 'post_type' => 'custom_css',
171
+ 'post_status' => 'publish',
172
+ 'numberposts' => 1,
173
+ 'update_post_meta_cache' => false,
174
+ 'update_post_term_cache' => false,
175
+ )
176
+ );
177
+
178
+ if ( $query->have_posts() ) {
179
+ $query->the_post();
180
+ $content = get_the_content();
181
+
182
+ // if the content contains a colon, a CSS rule has been added.
183
+ return strpos( $content, ':' ) === false ? false : true;
184
+ }
185
+
186
+ return false;
187
+ }
188
+
189
+ /**
190
+ * Get the current theme properties.
191
+ *
192
+ * @return mixed Properties of the current theme.
193
+ */
194
+ function get_theme_properties() {
195
+ if ( ! is_child_theme() ) {
196
+ return false;
197
+ }
198
+
199
+ $properties = array();
200
+ $theme = wp_get_theme();
201
+ // @codingStandardsIgnoreStart
202
+ $properties['name'] = $theme->Name;
203
+ // @codingStandardsIgnoreEnd
204
+
205
+ // get the files in the child theme.
206
+ require_once( ABSPATH . 'wp-admin/includes/file.php' );
207
+ WP_Filesystem();
208
+ global $wp_filesystem;
209
+ $path = str_replace( ABSPATH, $wp_filesystem->abspath(), get_stylesheet_directory() );
210
+ $list = $wp_filesystem->dirlist( $path, false, false );
211
+ if ( $list ) {
212
+ $list = array_keys( self::flatten_dirlist( $list ) );
213
+ $properties['files'] = $list;
214
+ }
215
+
216
+ return $properties;
217
+ }
218
+
219
+ /**
220
+ * Flatten the results of WP_Filesystem::dirlist() for iterating over.
221
+ *
222
+ * @access private
223
+ *
224
+ * @param array $nested_files Array of files as returned by WP_Filesystem::dirlist().
225
+ * @param string $path Relative path to prepend to child nodes. Optional.
226
+ *
227
+ * @return array $files A flattened array of the $nested_files specified.
228
+ */
229
+ private static function flatten_dirlist( $nested_files, $path = '' ) {
230
+ $files = array();
231
+ foreach ( $nested_files as $name => $details ) {
232
+ $files[ $path . $name ] = $details;
233
+ // Append children recursively.
234
+ if ( ! empty( $details['files'] ) ) {
235
+ $children = self::flatten_dirlist( $details['files'], $path . $name . '/' );
236
+ // Merge keeping possible numeric keys, which array_merge() will reindex from 0..n.
237
+ $files = $files + $children;
238
+ }
239
+ }
240
+
241
+ return $files;
242
+ }
243
+
244
+ /**
245
+ * Generate the diff of the files.
246
+ *
247
+ * @param Product $product Themeisle Product.
248
+ * @param array $files Array of files.
249
+ * @param bool $recurse Whether to recurse or not.
250
+ *
251
+ * @return mixed Diff data.
252
+ */
253
+ private function generate_diff( $product, $files, $recurse = false ) {
254
+ require_once( ABSPATH . 'wp-admin/includes/file.php' );
255
+ WP_Filesystem();
256
+ global $wp_filesystem;
257
+
258
+ $diff = array();
259
+ $path = str_replace( ABSPATH, $wp_filesystem->abspath(), plugin_dir_path( $product->get_basefile() ) );
260
+ $list = $wp_filesystem->dirlist( $path, false, $recurse );
261
+ // nothing found.
262
+ if ( ! $list ) {
263
+ return $diff;
264
+ }
265
+ $list = array_keys( self::flatten_dirlist( $list ) );
266
+
267
+ // now let's get the valid files that actually exist.
268
+ if ( empty( $files ) ) {
269
+ $files = $list;
270
+ } else {
271
+ $files = array_intersect( $files, $list );
272
+ }
273
+
274
+ // fetch the calculated hashes.
275
+ if ( ! $wp_filesystem->is_readable( $path . '/' . self::HASH_FILE ) ) {
276
+ return new WP_Error( 'themeisle_sdk_hash_not_found', sprintf( '%s not found', self::HASH_FILE ) );
277
+ }
278
+
279
+ $hashes = json_decode( $wp_filesystem->get_contents( $path . '/' . self::HASH_FILE ), true );
280
+ ksort( $hashes );
281
+
282
+ $diff = array();
283
+ foreach ( $files as $file ) {
284
+ // file does not exist in the hashes.
285
+ if ( ! array_key_exists( $file, $hashes ) ) {
286
+ continue;
287
+ }
288
+ $new = md5( $wp_filesystem->get_contents( $path . $file ) );
289
+ $old = $hashes[ $file ];
290
+
291
+ // same hash, bail.
292
+ if ( $new === $old ) {
293
+ continue;
294
+ }
295
+ $diff[] = $file;
296
+ }
297
+
298
+ return $diff;
299
+ }
300
+
301
+ /**
302
+ * Check if recursion needs to be enabled on the WP_Filesystem by reducing the array of files to a boolean.
303
+ *
304
+ * @param string $carry Value of the previous iteration.
305
+ * @param string $item Value of the current iteration.
306
+ *
307
+ * @return bool Whether to recurse or not.
308
+ */
309
+ function is_recursion_required( $carry, $item ) {
310
+ if ( ! $carry ) {
311
+ return ( strpos( $item, '/' ) !== false );
312
+ }
313
+
314
+ return $carry;
315
+ }
316
+
317
+ /**
318
+ * Load module for this product.
319
+ *
320
+ * @param Product $product Product to check.
321
+ *
322
+ * @return bool Should we load this?
323
+ */
324
+ public function can_load( $product ) {
325
+ return true;
326
+ }
327
+
328
+ /**
329
+ * Load module logic.
330
+ *
331
+ * @param Product $product Product to load.
332
+ */
333
+ public function load( $product ) {
334
+ $this->setup_endpoints();
335
+
336
+ return $this;
337
+ }
338
+
339
+ /**
340
+ * Setup endpoints.
341
+ */
342
+ private function setup_endpoints() {
343
+ global $wp_version;
344
+ if ( version_compare( $wp_version, '4.4', '<' ) ) {
345
+ // no REST support.
346
+ return;
347
+ }
348
+
349
+ $this->setup_rest();
350
+ }
351
+
352
+ /**
353
+ * Setup REST endpoints.
354
+ */
355
+ private function setup_rest() {
356
+ add_action( 'rest_api_init', array( $this, 'rest_register' ) );
357
+ }
358
+ }
vendor/codeinwp/themeisle-sdk/src/Modules/Licenser.php ADDED
@@ -0,0 +1,719 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The main loader class for license handling.
4
+ *
5
+ * @package ThemeIsleSDK
6
+ * @subpackage Modules
7
+ * @copyright Copyright (c) 2017, Marius Cristea
8
+ * @license http://opensource.org/licenses/gpl-3.0.php GNU Public License
9
+ * @since 1.0.0
10
+ */
11
+
12
+ namespace ThemeisleSDK\Modules;
13
+
14
+ // Exit if accessed directly.
15
+ use ThemeisleSDK\Common\Abstract_Module;
16
+ use ThemeisleSDK\Product;
17
+
18
+ if ( ! defined( 'ABSPATH' ) ) {
19
+ exit;
20
+ }
21
+
22
+ /**
23
+ * Licenser module for ThemeIsle SDK.
24
+ */
25
+ class Licenser extends Abstract_Module {
26
+
27
+ /**
28
+ * Number of max failed checks before showing the license message.
29
+ *
30
+ * @var int $max_failed Maximum failed checks allowed before show the notice
31
+ */
32
+ private static $max_failed = 5;
33
+ /**
34
+ * License key string.
35
+ *
36
+ * @var string $license_key The license key string
37
+ */
38
+ public $license_key;
39
+ /**
40
+ * This ensures that the custom API request only runs on the second time that WP fires the update check.
41
+ *
42
+ * @var bool $do_check Flag for request.
43
+ */
44
+ private $do_check = false;
45
+ /**
46
+ * Number of failed checks to the api endpoint.
47
+ *
48
+ * @var bool $failed_checks
49
+ */
50
+ private $failed_checks = 0;
51
+ /**
52
+ * The product update response key.
53
+ *
54
+ * @var string $product_key Product key.
55
+ */
56
+ private $product_key;
57
+
58
+ /**
59
+ * Disable wporg updates for premium products.
60
+ *
61
+ * @param string $r Update payload.
62
+ * @param string $url The api url.
63
+ *
64
+ * @return mixed List of themes to check for update.
65
+ */
66
+ function disable_wporg_update( $r, $url ) {
67
+
68
+ if ( 0 !== strpos( $url, 'https://api.wordpress.org/themes/update-check/' ) ) {
69
+ return $r;
70
+ }
71
+
72
+ // Decode the JSON response.
73
+ $themes = json_decode( $r['body']['themes'] );
74
+
75
+ unset( $themes->themes->{$this->product->get_slug()} );
76
+
77
+ // Encode the updated JSON response.
78
+ $r['body']['themes'] = json_encode( $themes );
79
+
80
+ return $r;
81
+ }
82
+
83
+ /**
84
+ * Register the setting for the license of the product.
85
+ *
86
+ * @return bool
87
+ */
88
+ public function register_settings() {
89
+ if ( ! is_admin() ) {
90
+ return false;
91
+ }
92
+ add_settings_field(
93
+ $this->product->get_key() . '_license',
94
+ $this->product->get_name() . ' license',
95
+ array( $this, 'license_view' ),
96
+ 'general'
97
+ );
98
+ }
99
+
100
+ /**
101
+ * The license view field.
102
+ */
103
+ public function license_view() {
104
+ $status = $this->get_license_status();
105
+ $value = $this->license_key;
106
+
107
+ $activate_string = apply_filters( $this->product->get_key() . '_lc_activate_string', 'Activate' );
108
+ $deactivate_string = apply_filters( $this->product->get_key() . '_lc_deactivate_string', 'Deactivate' );
109
+ $valid_string = apply_filters( $this->product->get_key() . '_lc_valid_string', 'Valid' );
110
+ $invalid_string = apply_filters( $this->product->get_key() . '_lc_invalid_string', 'Invalid' );
111
+ $license_message = apply_filters( $this->product->get_key() . '_lc_license_message', 'Enter your license from %s purchase history in order to get %s updates' );
112
+
113
+ echo '<p ><input ' . ( ( 'valid' === $status ) ? ( 'style="border:1px solid #7ad03a; "' ) : '' ) . ' type="text" id="' . $this->product->get_key() . '_license" name="' . $this->product->get_key() . '_license" value="' . $value . '" /><a ' . ( ( 'valid' === $status ) ? ( 'style="color:#fff;background: #7ad03a; display: inline-block;text-decoration: none;font-size: 13px;line-height: 26px;height: 26px; margin-left:5px; padding: 0 10px 1px; -webkit-border-radius: 3px;border-radius: 3px; ">' . $valid_string ) : ( 'style="color:#fff;background: #dd3d36; display: inline-block;text-decoration: none;font-size: 13px;line-height: 26px;height: 26px; margin-left:5px; padding: 0 10px 1px; -webkit-border-radius: 3px;border-radius: 3px; ">' . $invalid_string ) ) . ' </a>&nbsp;&nbsp;&nbsp;<button name="' . $this->product->get_key() . '_btn_trigger" ' . ( ( 'valid' === $status ) ? ( ' class="button button-primary">' . $deactivate_string ) : ( ' class="button button-primary" value="yes" type="submit" >' . $activate_string ) ) . ' </button></p><p class="description">' . sprintf( $license_message, '<a href="' . $this->get_api_url() . '">' . $this->get_distributor_name() . '</a> ', $this->product->get_type() ) . '</p>';
114
+
115
+ }
116
+
117
+ /**
118
+ * Return the license status.
119
+ *
120
+ * @return string The License status.
121
+ */
122
+ public function get_license_status() {
123
+
124
+ $license_data = get_option( $this->product->get_key() . '_license_data', '' );
125
+
126
+ if ( '' === $license_data ) {
127
+ return get_option( $this->product->get_key() . '_license_status', 'not_active' );
128
+ }
129
+
130
+ return isset( $license_data->license ) ? $license_data->license : get_option( $this->product->get_key() . '_license_status', 'not_active' );
131
+
132
+ }
133
+
134
+ /**
135
+ * Get remote api url.
136
+ *
137
+ * @return string Remote api url.
138
+ */
139
+ public function get_api_url() {
140
+ if ( $this->is_from_partner( $this->product ) ) {
141
+ return 'https://themeisle.com';
142
+ }
143
+
144
+ return $this->product->get_store_url();
145
+ }
146
+
147
+ /**
148
+ * Get remote api url.
149
+ *
150
+ * @return string Remote api url.
151
+ */
152
+ public function get_distributor_name() {
153
+ if ( $this->is_from_partner( $this->product ) ) {
154
+ return 'ThemeIsle';
155
+ }
156
+
157
+ return $this->product->get_store_name();
158
+ }
159
+
160
+ /**
161
+ * Show the admin notice regarding the license status.
162
+ *
163
+ * @return bool Should we show the notice ?
164
+ */
165
+ function show_notice() {
166
+ if ( ! is_admin() ) {
167
+ return false;
168
+ }
169
+ $status = $this->get_license_status();
170
+ $no_activations_string = apply_filters( $this->product->get_key() . '_lc_no_activations_string', 'No activations left for %s !!!. You need to upgrade your plan in order to use %s on more websites. Please ask the %s Staff for more details.' );
171
+ $no_valid_string = apply_filters( $this->product->get_key() . '_lc_no_valid_string', 'In order to benefit from updates and support for %s, please add your license code from your <a href="%s" target="_blank">purchase history</a> and validate it <a href="%s">here</a>. ' );
172
+ $expiration_string = apply_filters( $this->product->get_key() . '_lc_expiration_string', 'Your license is about to expire for %s. You can go to %s and renew it ' );
173
+
174
+ // No activations left for this license.
175
+ if ( 'valid' != $status && $this->check_activation() ) {
176
+ ?>
177
+ <div class="error">
178
+ <p><strong>
179
+ <?php
180
+ echo sprintf(
181
+ $no_activations_string,
182
+ $this->product->get_name(),
183
+ $this->product->get_name(),
184
+ '<a href="' . $this->get_api_url() . '" target="_blank">' . $this->get_distributor_name() . '</a>'
185
+ );
186
+ ?>
187
+ </strong>
188
+ </p>
189
+ </div>
190
+ <?php
191
+ return false;
192
+ }
193
+ // Invalid license key.
194
+ if ( 'valid' != $status ) {
195
+ ?>
196
+ <div class="error">
197
+ <p>
198
+ <strong><?php echo sprintf( $no_valid_string, $this->product->get_name() . ' ' . $this->product->get_type(), $this->get_api_url(), admin_url( 'options-general.php' ) . '#' . $this->product->get_key() ); ?> </strong>
199
+ </p>
200
+ </div>
201
+ <?php
202
+
203
+ return false;
204
+ }
205
+
206
+ // Expired and soon to expire license.
207
+ if ( 'valid' == $status && $this->check_expiration() ) {
208
+ ?>
209
+ <div class="update-nag">
210
+ <p>
211
+ <strong>
212
+ <?php
213
+ echo sprintf(
214
+ $expiration_string,
215
+ $this->product->get_name() . ' ' . $this->product->get_type(),
216
+ '<a href="' . $this->renew_url() . '" target="_blank">' . $this->get_distributor_name() . '</a>'
217
+ );
218
+ ?>
219
+ </strong>
220
+ </p>
221
+ </div>
222
+ <?php
223
+ return false;
224
+ }
225
+
226
+ return true;
227
+ }
228
+
229
+ /**
230
+ * Check if the license is active or not.
231
+ *
232
+ * @return bool
233
+ */
234
+ public function check_activation() {
235
+ $license_data = get_option( $this->product->get_key() . '_license_data', '' );
236
+ if ( '' === $license_data ) {
237
+ return false;
238
+ }
239
+
240
+ return isset( $license_data->error ) ? ( 'no_activations_left' == $license_data->error ) : false;
241
+
242
+ }
243
+
244
+ /**
245
+ * Check if the license is about to expire in the next month.
246
+ *
247
+ * @return bool
248
+ */
249
+ function check_expiration() {
250
+ $license_data = get_option( $this->product->get_key() . '_license_data', '' );
251
+ if ( '' === $license_data ) {
252
+ return false;
253
+ }
254
+ if ( ! isset( $license_data->expires ) ) {
255
+ return false;
256
+ }
257
+ if ( strtotime( $license_data->expires ) - time() > 30 * 24 * 3600 ) {
258
+ return false;
259
+ }
260
+
261
+ return true;
262
+ }
263
+
264
+ /**
265
+ * Return the renew url from the store used.
266
+ *
267
+ * @return string The renew url.
268
+ */
269
+ function renew_url() {
270
+ $license_data = get_option( $this->product->get_key() . '_license_data', '' );
271
+ if ( '' === $license_data ) {
272
+ return $this->get_api_url();
273
+ }
274
+ if ( ! isset( $license_data->download_id ) || ! isset( $license_data->key ) ) {
275
+ return $this->get_api_url();
276
+ }
277
+
278
+ return $this->get_api_url() . '/checkout/?edd_license_key=' . $license_data->key . '&download_id=' . $license_data->download_id;
279
+ }
280
+
281
+ /**
282
+ * Run the license check call.
283
+ */
284
+ public function product_valid() {
285
+ if ( false !== ( $license = get_transient( $this->product->get_key() . '_license_data' ) ) ) {
286
+ return;
287
+ }
288
+ $license = $this->check_license();
289
+ set_transient( $this->product->get_key() . '_license_data', $license, 12 * HOUR_IN_SECONDS );
290
+ update_option( $this->product->get_key() . '_license_data', $license );
291
+ }
292
+
293
+ /**
294
+ * Check the license status.
295
+ *
296
+ * @return object The license data.
297
+ */
298
+ public function check_license() {
299
+ $status = $this->get_license_status();
300
+ if ( 'not_active' == $status ) {
301
+ $license_data = new \stdClass();
302
+ $license_data->license = 'not_active';
303
+
304
+ return $license_data;
305
+ }
306
+ $license = trim( $this->license_key );
307
+ $api_params = array(
308
+ 'edd_action' => 'check_license',
309
+ 'license' => $license,
310
+ 'item_name' => rawurlencode( $this->product->get_name() ),
311
+ 'url' => rawurlencode( home_url() ),
312
+ );
313
+ // Call the custom API.
314
+ $response = wp_remote_get(
315
+ add_query_arg( $api_params, $this->get_api_url() ),
316
+ array(
317
+ 'timeout' => 15,
318
+ 'sslverify' => false,
319
+ )
320
+ );
321
+ if ( is_wp_error( $response ) ) {
322
+ $license_data = new \stdClass();
323
+ $license_data->license = 'valid';
324
+
325
+ } else {
326
+ $license_data = json_decode( wp_remote_retrieve_body( $response ) );
327
+ if ( ! is_object( $license_data ) ) {
328
+ $license_data = new \stdClass();
329
+ $license_data->license = 'valid';
330
+ }
331
+ }
332
+ $license_old = get_option( $this->product->get_key() . '_license_data', '' );
333
+ if ( 'valid' == $license_old->license && ( $license_data->license != $license_old->license ) ) {
334
+ $this->increment_failed_checks();
335
+ } else {
336
+ $this->reset_failed_checks();
337
+ }
338
+
339
+ if ( $this->failed_checks <= self::$max_failed ) {
340
+ return $license_old;
341
+ }
342
+
343
+ if ( isset( $license_old->hide_valid ) ) {
344
+ $license_data->hide_valid = true;
345
+ }
346
+
347
+ if ( ! isset( $license_data->key ) ) {
348
+ $license_data->key = isset( $license_old->key ) ? $license_old->key : '';
349
+ }
350
+
351
+ if ( isset( $license_old->hide_expiration ) ) {
352
+ $license_data->hide_expiration = true;
353
+ }
354
+
355
+ if ( isset( $license_old->hide_activation ) ) {
356
+ $license_data->hide_activation = true;
357
+ }
358
+
359
+ return $license_data;
360
+
361
+ }
362
+
363
+ /**
364
+ * Increment the failed checks.
365
+ */
366
+ private function increment_failed_checks() {
367
+ $this->failed_checks ++;
368
+ update_option( $this->product->get_key() . '_failed_checks', $this->failed_checks );
369
+ }
370
+
371
+ /**
372
+ * Reset the failed checks
373
+ */
374
+ private function reset_failed_checks() {
375
+ $this->failed_checks = 1;
376
+ update_option( $this->product->get_key() . '_failed_checks', $this->failed_checks );
377
+ }
378
+
379
+ /**
380
+ * Activate the license remotely.
381
+ */
382
+ function activate_license() {
383
+ // listen for our activate button to be clicked.
384
+ if ( ! isset( $_POST[ $this->product->get_key() . '_btn_trigger' ] ) ) {
385
+ return;
386
+ }
387
+ $status = $this->get_license_status();
388
+ // retrieve the license from the database.
389
+ $license = $_POST[ $this->product->get_key() . '_license' ];
390
+ $api_params = array(
391
+ 'license' => $license,
392
+ 'item_name' => rawurlencode( $this->product->get_name() ),
393
+ 'url' => rawurlencode( home_url() ),
394
+ );
395
+ if ( 'valid' != $status ) {
396
+ // data to send in our API request.
397
+ $api_params['edd_action'] = 'activate_license';
398
+ } else {
399
+ $api_params['edd_action'] = 'deactivate_license';
400
+ }
401
+ // Call the custom API.
402
+ $response = wp_remote_get( add_query_arg( $api_params, $this->get_api_url() ) );
403
+ // make sure the response came back okay.
404
+ if ( is_wp_error( $response ) ) {
405
+ $license_data = new \stdClass();
406
+ $license_data->license = ( 'valid' != $status ) ? 'valid' : 'invalid';
407
+
408
+ } else {
409
+ $license_data = json_decode( wp_remote_retrieve_body( $response ) );
410
+ if ( ! is_object( $license_data ) ) {
411
+ $license_data = new \stdClass();
412
+ $license_data->license = ( 'valid' != $status ) ? 'valid' : 'invalid';
413
+ }
414
+ if ( ! isset( $license_data->license ) ) {
415
+ $license_data->license = 'invalid';
416
+ }
417
+ }
418
+ if ( ! isset( $license_data->key ) ) {
419
+ $license_data->key = $license;
420
+ }
421
+ if ( 'valid' == $license_data->license ) {
422
+ $this->reset_failed_checks();
423
+ }
424
+
425
+ if ( isset( $license_data->plan ) ) {
426
+ update_option( $this->product->get_key() . '_license_plan', $license_data->plan );
427
+ }
428
+
429
+ update_option( $this->product->get_key() . '_license_data', $license_data );
430
+ set_transient( $this->product->get_key() . '_license_data', $license_data, 12 * HOUR_IN_SECONDS );
431
+
432
+ }
433
+
434
+ /**
435
+ * Load the Themes screen.
436
+ */
437
+ function load_themes_screen() {
438
+ add_thickbox();
439
+ add_action( 'admin_notices', array( &$this, 'update_nag' ) );
440
+ }
441
+
442
+ /**
443
+ * Alter the nag for themes update.
444
+ */
445
+ function update_nag() {
446
+ $theme = wp_get_theme( $this->product->get_slug() );
447
+ $api_response = get_transient( $this->product_key );
448
+ if ( false === $api_response ) {
449
+ return;
450
+ }
451
+ $update_url = wp_nonce_url( 'update.php?action=upgrade-theme&amp;theme=' . urlencode( $this->product->get_slug() ), 'upgrade-theme_' . $this->product->get_slug() );
452
+ $update_message = apply_filters( 'themeisle_sdk_license_update_message', 'Updating this theme will lose any customizations you have made. Cancel to stop, OK to update.' );
453
+ $update_onclick = ' onclick="if ( confirm(\'' . esc_js( $update_message ) . '\') ) {return true;}return false;"';
454
+ if ( version_compare( $this->product->get_version(), $api_response->new_version, '<' ) ) {
455
+ echo '<div id="update-nag">';
456
+ printf(
457
+ '<strong>%1$s %2$s</strong> is available. <a href="%3$s" class="thickbox" title="%4s">Check out what\'s new</a> or <a href="%5$s"%6$s>update now</a>.',
458
+ $theme->get( 'Name' ),
459
+ $api_response->new_version,
460
+ '#TB_inline?width=640&amp;inlineId=' . $this->product->get_version() . '_changelog',
461
+ $theme->get( 'Name' ),
462
+ $update_url,
463
+ $update_onclick
464
+ );
465
+ echo '</div>';
466
+ echo '<div id="' . $this->product->get_slug() . '_' . 'changelog" style="display:none;">';
467
+ echo wpautop( $api_response->sections['changelog'] );
468
+ echo '</div>';
469
+ }
470
+ }
471
+
472
+ /**
473
+ * Alter update transient.
474
+ *
475
+ * @param mixed $value The transient data.
476
+ *
477
+ * @return mixed
478
+ */
479
+ function theme_update_transient( $value ) {
480
+ $update_data = $this->check_for_update();
481
+ if ( $update_data ) {
482
+ $value->response[ $this->product->get_slug() ] = $update_data;
483
+ }
484
+
485
+ return $value;
486
+ }
487
+
488
+ /**
489
+ * Check for updates
490
+ *
491
+ * @return array|bool Either the update data or false in case of failure.
492
+ */
493
+ function check_for_update() {
494
+ $update_data = get_transient( $this->product_key );
495
+
496
+ if ( false === $update_data ) {
497
+ $failed = false;
498
+ $update_data = $this->get_version_data();
499
+ if ( empty( $update_data ) ) {
500
+ $failed = true;
501
+ }
502
+ // If the response failed, try again in 30 minutes.
503
+ if ( $failed ) {
504
+ $data = new \stdClass();
505
+ $data->new_version = $this->product->get_version();
506
+ set_transient( $this->product_key, $data, 30 * MINUTE_IN_SECONDS );
507
+
508
+ return false;
509
+ }
510
+ $update_data->sections = maybe_unserialize( $update_data->sections );
511
+
512
+ set_transient( $this->product_key, $update_data, 12 * HOUR_IN_SECONDS );
513
+ }
514
+ if ( ! isset( $update_data->new_version ) ) {
515
+ return false;
516
+ }
517
+ if ( version_compare( $this->product->get_version(), $update_data->new_version, '>=' ) ) {
518
+ return false;
519
+ }
520
+
521
+ return (array) $update_data;
522
+ }
523
+
524
+ /**
525
+ * Check remote api for latest version.
526
+ *
527
+ * @return bool|mixed Update api response.
528
+ */
529
+ private function get_version_data() {
530
+ $api_params = array(
531
+ 'edd_action' => 'get_version',
532
+ 'version' => $this->product->get_version(),
533
+ 'license' => $this->license_key,
534
+ 'name' => $this->product->get_name(),
535
+ 'slug' => $this->product->get_slug(),
536
+ 'author' => $this->get_distributor_name(),
537
+ 'url' => rawurlencode( home_url() ),
538
+ );
539
+ $response = wp_remote_get(
540
+ $this->get_api_url(),
541
+ array(
542
+ 'timeout' => 15,
543
+ 'sslverify' => false,
544
+ 'body' => $api_params,
545
+ )
546
+ );
547
+ if ( is_wp_error( $response ) || 200 != wp_remote_retrieve_response_code( $response ) ) {
548
+ return false;
549
+ }
550
+ $update_data = json_decode( wp_remote_retrieve_body( $response ) );
551
+ if ( ! is_object( $update_data ) ) {
552
+ return false;
553
+ }
554
+
555
+ return $update_data;
556
+ }
557
+
558
+ /**
559
+ * Delete the update transient
560
+ */
561
+ function delete_theme_update_transient() {
562
+ delete_transient( $this->product_key );
563
+ }
564
+
565
+ /**
566
+ * Check for Updates at the defined API endpoint and modify the update array.
567
+ *
568
+ * @param array $_transient_data Update array build by WordPress.
569
+ *
570
+ * @return mixed Modified update array with custom plugin data.
571
+ */
572
+ public function pre_set_site_transient_update_plugins_filter( $_transient_data ) {
573
+ if ( empty( $_transient_data ) || ! $this->do_check ) {
574
+ $this->do_check = true;
575
+
576
+ return $_transient_data;
577
+ }
578
+ $api_response = $this->api_request();
579
+ if ( false !== $api_response && is_object( $api_response ) && isset( $api_response->new_version ) ) {
580
+ if ( version_compare( $this->product->get_version(), $api_response->new_version, '<' ) ) {
581
+ $_transient_data->response[ $this->product->get_slug() . '/' . $this->product->get_file() ] = $api_response;
582
+ }
583
+ }
584
+
585
+ return $_transient_data;
586
+ }
587
+
588
+ /**
589
+ * Calls the API and, if successfull, returns the object delivered by the API.
590
+ *
591
+ * @param string $_action The requested action.
592
+ * @param array $_data Parameters for the API action.
593
+ *
594
+ * @return false||object
595
+ */
596
+ private function api_request( $_action = '', $_data = '' ) {
597
+ $update_data = $this->get_version_data();
598
+ if ( empty( $update_data ) ) {
599
+ return false;
600
+ }
601
+ if ( $update_data && isset( $update_data->sections ) ) {
602
+ $update_data->sections = maybe_unserialize( $update_data->sections );
603
+ }
604
+
605
+ return $update_data;
606
+ }
607
+
608
+ /**
609
+ * Updates information on the "View version x.x details" page with custom data.
610
+ *
611
+ * @param mixed $_data Plugin data.
612
+ * @param string $_action Action to send.
613
+ * @param object $_args Arguments to use.
614
+ *
615
+ * @return object $_data
616
+ */
617
+ public function plugins_api_filter( $_data, $_action = '', $_args = null ) {
618
+ if ( ( 'plugin_information' != $_action ) || ! isset( $_args->slug ) || ( $_args->slug != $this->product->get_slug() ) ) {
619
+ return $_data;
620
+ }
621
+ $api_response = $this->api_request();
622
+ if ( false !== $api_response ) {
623
+ $_data = $api_response;
624
+ }
625
+
626
+ return $_data;
627
+ }
628
+
629
+ /**
630
+ * Disable SSL verification in order to prevent download update failures.
631
+ *
632
+ * @param array $args Http args.
633
+ * @param string $url Url to check.
634
+ *
635
+ * @return array $array
636
+ */
637
+ function http_request_args( $args, $url ) {
638
+ // If it is an https request and we are performing a package download, disable ssl verification.
639
+ if ( strpos( $url, 'https://' ) !== false && strpos( $url, 'edd_action=package_download' ) ) {
640
+ $args['sslverify'] = false;
641
+ }
642
+
643
+ return $args;
644
+ }
645
+
646
+ /**
647
+ * Check if we should load the module for this product.
648
+ *
649
+ * @param Product $product Product data.
650
+ *
651
+ * @return bool Should we load the module?
652
+ */
653
+ public function can_load( $product ) {
654
+
655
+ if ( $product->is_wordpress_available() ) {
656
+ return false;
657
+ }
658
+
659
+ return ( apply_filters( $product->get_key() . '_enable_licenser', true ) === true );
660
+
661
+ }
662
+
663
+ /**
664
+ * Load module logic.
665
+ *
666
+ * @param Product $product Product to load the module for.
667
+ *
668
+ * @return Licenser Module object.
669
+ */
670
+ public function load( $product ) {
671
+ $this->product = $product;
672
+
673
+ $this->product_key = $this->product->get_key() . '-update-response';
674
+
675
+ $this->license_key = $this->product->get_license();
676
+ if ( $this->product->requires_license() ) {
677
+ $this->failed_checks = intval( get_option( $this->product->get_key() . '_failed_checks', 0 ) );
678
+ $this->register_license_hooks();
679
+ }
680
+
681
+ if ( $this->product->is_plugin() ) {
682
+ add_filter(
683
+ 'pre_set_site_transient_update_plugins',
684
+ [
685
+ $this,
686
+ 'pre_set_site_transient_update_plugins_filter',
687
+ ]
688
+ );
689
+ add_filter( 'plugins_api', array( $this, 'plugins_api_filter' ), 10, 3 );
690
+ add_filter( 'http_request_args', array( $this, 'http_request_args' ), 10, 2 );
691
+
692
+ return $this;
693
+ }
694
+ if ( $this->product->is_theme() ) {
695
+ add_filter( 'site_transient_update_themes', array( &$this, 'theme_update_transient' ) );
696
+ add_filter( 'delete_site_transient_update_themes', array( &$this, 'delete_theme_update_transient' ) );
697
+ add_action( 'load-update-core.php', array( &$this, 'delete_theme_update_transient' ) );
698
+ add_action( 'load-themes.php', array( &$this, 'delete_theme_update_transient' ) );
699
+ add_action( 'load-themes.php', array( &$this, 'load_themes_screen' ) );
700
+ add_filter( 'http_request_args', array( $this, 'disable_wporg_update' ), 5, 2 );
701
+
702
+ return $this;
703
+
704
+ }
705
+
706
+ return $this;
707
+ }
708
+
709
+ /**
710
+ * Register license fields for the products.
711
+ */
712
+ public function register_license_hooks() {
713
+ add_action( 'admin_init', array( $this, 'register_settings' ) );
714
+ add_action( 'admin_init', array( $this, 'activate_license' ) );
715
+ add_action( 'admin_init', array( $this, 'product_valid' ), 99999999 );
716
+ add_action( 'admin_notices', array( $this, 'show_notice' ) );
717
+ add_filter( $this->product->get_key() . '_license_status', array( $this, 'get_license_status' ) );
718
+ }
719
+ }
vendor/codeinwp/themeisle-sdk/src/Modules/Logger.php ADDED
@@ -0,0 +1,177 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The logger model class for ThemeIsle SDK
4
+ *
5
+ * @package ThemeIsleSDK
6
+ * @subpackage Modules
7
+ * @copyright Copyright (c) 2017, Marius Cristea
8
+ * @license http://opensource.org/licenses/gpl-3.0.php GNU Public License
9
+ * @since 1.0.0
10
+ */
11
+
12
+ namespace ThemeisleSDK\Modules;
13
+
14
+ use ThemeisleSDK\Common\Abstract_Module;
15
+ use ThemeisleSDK\Loader;
16
+ use ThemeisleSDK\Product;
17
+
18
+ // Exit if accessed directly.
19
+ if ( ! defined( 'ABSPATH' ) ) {
20
+ exit;
21
+ }
22
+
23
+ /**
24
+ * Logger module for ThemeIsle SDK.
25
+ */
26
+ class Logger extends Abstract_Module {
27
+ /**
28
+ * Endpoint where to collect logs.
29
+ */
30
+ const TRACKING_ENDPOINT = 'http://log.themeisle.com/wp-json/v1/logs/';
31
+
32
+
33
+ /**
34
+ * Check if we should load the module for this product.
35
+ *
36
+ * @param Product $product Product to load the module for.
37
+ *
38
+ * @return bool Should we load ?
39
+ */
40
+ public function can_load( $product ) {
41
+
42
+ return apply_filters( $product->get_slug() . '_sdk_enable_logger', true );
43
+ }
44
+
45
+ /**
46
+ * Load module logic.
47
+ *
48
+ * @param Product $product Product to load.
49
+ *
50
+ * @return Logger Module object.
51
+ */
52
+ public function load( $product ) {
53
+ $this->product = $product;
54
+ $this->setup_notification();
55
+ $this->setup_actions();
56
+
57
+ return $this;
58
+ }
59
+
60
+ /**
61
+ * Setup notification on admin.
62
+ */
63
+ public function setup_notification() {
64
+ if ( ! $this->product->is_wordpress_available() ) {
65
+ return;
66
+ }
67
+
68
+ add_filter( 'themeisle_sdk_registered_notifications', [ $this, 'add_notification' ] );
69
+
70
+ }
71
+
72
+ /**
73
+ * Setup tracking actions.
74
+ */
75
+ public function setup_actions() {
76
+ if ( ! $this->is_logger_active() ) {
77
+ return;
78
+ }
79
+ $action_key = $this->product->get_key() . '_log_activity';
80
+ if ( ! wp_next_scheduled( $action_key ) ) {
81
+ wp_schedule_single_event( time() + ( rand( 1, 24 ) * 3600 ), $action_key );
82
+ }
83
+ add_action( $action_key, array( $this, 'send_log' ) );
84
+
85
+ }
86
+
87
+ /**
88
+ * Check if the logger is active.
89
+ *
90
+ * @return bool Is logger active?
91
+ */
92
+ private function is_logger_active() {
93
+ if ( ! $this->product->is_wordpress_available() ) {
94
+ return true;
95
+ }
96
+ $pro_slug = $this->product->get_pro_slug();
97
+
98
+ if ( ! empty( $pro_slug ) ) {
99
+ $all_products = Loader::get_products();
100
+ if ( isset( $all_products[ $pro_slug ] ) ) {
101
+ return true;
102
+ }
103
+ }
104
+
105
+ return ( get_option( $this->product->get_key() . '_logger_flag', 'no' ) === 'yes' );
106
+ }
107
+
108
+ /**
109
+ * Add notification to queue.
110
+ *
111
+ * @param array $all_notifications Previous notification.
112
+ *
113
+ * @return array All notifications.
114
+ */
115
+ public function add_notification( $all_notifications ) {
116
+
117
+ $message = apply_filters( $this->product->get_key() . '_logger_heading', 'Do you enjoy <b>{product}</b>? Become a contributor by opting in to our anonymous data tracking. We guarantee no sensitive data is collected.' );
118
+
119
+ $message = str_replace(
120
+ array( '{product}' ),
121
+ $this->product->get_friendly_name(),
122
+ $message
123
+ );
124
+ $button_submit = apply_filters( $this->product->get_key() . '_logger_button_submit', 'Sure, I would love to help.' );
125
+ $button_cancel = apply_filters( $this->product->get_key() . '_logger_button_cancel', 'No, thanks.' );
126
+
127
+ $all_notifications[] = [
128
+ 'id' => $this->product->get_key() . '_logger_flag',
129
+ 'message' => $message,
130
+ 'ctas' => [
131
+ 'confirm' => [
132
+ 'link' => '#',
133
+ 'text' => $button_submit,
134
+ ],
135
+ 'cancel' => [
136
+ 'link' => '#',
137
+ 'text' => $button_cancel,
138
+ ],
139
+ ],
140
+ ];
141
+
142
+ return $all_notifications;
143
+ }
144
+
145
+ /**
146
+ * Send the statistics to the api endpoint.
147
+ */
148
+ public function send_log() {
149
+ $environment = array();
150
+ $theme = wp_get_theme();
151
+ $environment['theme'] = array();
152
+ $environment['theme']['name'] = $theme->get( 'Name' );
153
+ $environment['theme']['author'] = $theme->get( 'Author' );
154
+ $environment['plugins'] = get_option( 'active_plugins' );
155
+ global $wp_version;
156
+ wp_remote_post(
157
+ self::TRACKING_ENDPOINT,
158
+ array(
159
+ 'method' => 'POST',
160
+ 'timeout' => 3,
161
+ 'redirection' => 5,
162
+ 'headers' => array(
163
+ 'X-ThemeIsle-Event' => 'log_site',
164
+ ),
165
+ 'body' => array(
166
+ 'site' => get_site_url(),
167
+ 'slug' => $this->product->get_slug(),
168
+ 'version' => $this->product->get_version(),
169
+ 'wp_version' => $wp_version,
170
+ 'data' => apply_filters( $this->product->get_key() . '_logger_data', array() ),
171
+ 'environment' => $environment,
172
+ 'license' => apply_filters( $this->product->get_key() . '_license_status', '' ),
173
+ ),
174
+ )
175
+ );
176
+ }
177
+ }
vendor/codeinwp/themeisle-sdk/src/Modules/Notification.php ADDED
@@ -0,0 +1,456 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The notification model class for ThemeIsle SDK
4
+ *
5
+ * @package ThemeIsleSDK
6
+ * @subpackage Modules
7
+ * @copyright Copyright (c) 2017, Marius Cristea
8
+ * @license http://opensource.org/licenses/gpl-3.0.php GNU Public License
9
+ * @since 1.0.0
10
+ */
11
+
12
+ namespace ThemeisleSDK\Modules;
13
+
14
+ use ThemeisleSDK\Common\Abstract_Module;
15
+ use ThemeisleSDK\Product;
16
+
17
+ // Exit if accessed directly.
18
+ if ( ! defined( 'ABSPATH' ) ) {
19
+ exit;
20
+ }
21
+
22
+ /**
23
+ * Notification module for ThemeIsle SDK.
24
+ */
25
+ class Notification extends Abstract_Module {
26
+ /**
27
+ * Show notifications only after the user has the product installed after this amount of time, in hours.
28
+ */
29
+ const MIN_INSTALL_TIME = 100;
30
+ /**
31
+ * How much time should we show the notification, in days.
32
+ */
33
+ const MAX_TIME_TO_LIVE = 7;
34
+
35
+ /**
36
+ * Number of days between notifications.
37
+ */
38
+ const TIME_BETWEEN_NOTIFICATIONS = 5;
39
+
40
+ /**
41
+ * Holds a possible notification list.
42
+ *
43
+ * @var array Notifications list.
44
+ */
45
+ private static $notifications = [];
46
+
47
+ /**
48
+ * Show notification data.
49
+ */
50
+ public static function show_notification() {
51
+
52
+ $current_notification = self::get_last_notification();
53
+
54
+ $notification_details = [];
55
+ // Check if the saved notification is still present among the possible ones.
56
+ if ( ! empty( $current_notification ) ) {
57
+ $notification_details = self::get_notification_details( $current_notification );
58
+ if ( empty( $notification_details ) ) {
59
+ $current_notification = [];
60
+ }
61
+ }
62
+ // Check if the notificatin is expired.
63
+ if ( ! empty( $current_notification ) && self::is_notification_expired( $current_notification ) ) {
64
+ update_option( $current_notification['id'], 'no' );
65
+ self::set_last_active_notification_timestamp();
66
+ $current_notification = [];
67
+ }
68
+ // If we don't have any saved notification, get a new one.
69
+ if ( empty( $current_notification ) ) {
70
+ $notification_details = self::get_random_notification();
71
+ if ( empty( $notification_details ) ) {
72
+ return;
73
+ }
74
+ self::set_active_notification(
75
+ [
76
+ 'id' => $notification_details['id'],
77
+ 'display_at' => time(),
78
+ ]
79
+ );
80
+ }
81
+ if ( empty( $notification_details ) ) {
82
+ return;
83
+ }
84
+ $notification_html = self::get_notification_html( $notification_details );
85
+ do_action( $notification_details['id'] . '_before_render' );
86
+
87
+ echo $notification_html;
88
+
89
+ do_action( $notification_details['id'] . '_after_render' );
90
+ self::render_snippets();
91
+ }
92
+
93
+ /**
94
+ * Get last notification details.
95
+ *
96
+ * @return array Last notification details.
97
+ */
98
+ private static function get_last_notification() {
99
+ $notification = self::get_notifications_metadata();
100
+
101
+ return isset( $notification['last_notification'] ) ? $notification['last_notification'] : [];
102
+ }
103
+
104
+ /**
105
+ * Get notification center details.
106
+ *
107
+ * @return array Notification center details.
108
+ */
109
+ private static function get_notifications_metadata() {
110
+
111
+ $data = get_option(
112
+ 'themeisle_sdk_notifications',
113
+ [
114
+ 'last_notification' => [],
115
+ 'last_notification_active' => 0,
116
+ ]
117
+ );
118
+
119
+ return $data;
120
+
121
+ }
122
+
123
+ /**
124
+ * Check if the notification is still possible.
125
+ *
126
+ * @param array $notification Notification to check.
127
+ *
128
+ * @return array Either is still active or not.
129
+ */
130
+ private static function get_notification_details( $notification ) {
131
+ $notifications = array_filter(
132
+ self::$notifications,
133
+ function ( $value ) use ( $notification ) {
134
+ if ( isset( $value['id'] ) && isset( $notification['id'] ) && $value['id'] === $notification['id'] ) {
135
+ return true;
136
+ }
137
+
138
+ return false;
139
+ }
140
+ );
141
+
142
+ return ! empty( $notifications ) ? reset( $notifications ) : [];
143
+ }
144
+
145
+ /**
146
+ * Check if the notification is expired.
147
+ *
148
+ * @param array $notification Notification to check.
149
+ *
150
+ * @return bool Either the notification is due.
151
+ */
152
+ private static function is_notification_expired( $notification ) {
153
+ if ( ! isset( $notification['display_at'] ) ) {
154
+ return true;
155
+ }
156
+
157
+ $notifications = array_filter(
158
+ self::$notifications,
159
+ function ( $value ) use ( $notification ) {
160
+ if ( isset( $value['id'] ) && isset( $notification['id'] ) && $value['id'] === $notification['id'] ) {
161
+ return true;
162
+ }
163
+
164
+ return false;
165
+ }
166
+ );
167
+
168
+ if ( empty( $notifications ) ) {
169
+ return true;
170
+ }
171
+ $notification_definition = reset( $notifications );
172
+
173
+ $when_to_expire = isset( $notification_definition['expires_at'] )
174
+ ? $notification_definition['expires_at'] :
175
+ ( isset( $notification_definition['expires'] )
176
+ ? ( $notification['display_at'] + $notification_definition['expires'] ) :
177
+ ( $notification['display_at'] + self::MAX_TIME_TO_LIVE * DAY_IN_SECONDS )
178
+ );
179
+
180
+ return ( $when_to_expire - time() ) < 0;
181
+ }
182
+
183
+ /**
184
+ * Set last notification details.
185
+ */
186
+ private static function set_last_active_notification_timestamp() {
187
+ $metadata = self::get_notifications_metadata();
188
+ $metadata['last_notification_active'] = time();
189
+ update_option( 'themeisle_sdk_notifications', $metadata );
190
+ }
191
+
192
+ /**
193
+ * Return notification to show.
194
+ *
195
+ * @return array Notification data.
196
+ */
197
+ public static function get_random_notification() {
198
+ if ( ( time() - self::get_last_active_notification_timestamp() ) < self::TIME_BETWEEN_NOTIFICATIONS * DAY_IN_SECONDS ) {
199
+ return [];
200
+ }
201
+
202
+ $notifications = self::$notifications;
203
+ $notifications = array_filter(
204
+ $notifications,
205
+ function ( $value ) {
206
+ if ( isset( $value['sticky'] ) && true === $value['sticky'] ) {
207
+ return true;
208
+ }
209
+
210
+ return false;
211
+ }
212
+ );
213
+ // No priority notifications, use all.
214
+ if ( empty( $notifications ) ) {
215
+ $notifications = self::$notifications;
216
+ }
217
+ if ( empty( $notifications ) ) {
218
+ return [];
219
+ }
220
+ $notifications = array_values( $notifications );
221
+
222
+ return $notifications[ array_rand( $notifications, 1 ) ];
223
+
224
+ }
225
+
226
+ /**
227
+ * Get last notification details.
228
+ *
229
+ * @return array Last notification details.
230
+ */
231
+ private static function get_last_active_notification_timestamp() {
232
+ $notification = self::get_notifications_metadata();
233
+
234
+ return isset( $notification['last_notification_active'] ) ? $notification['last_notification_active'] : 0;
235
+ }
236
+
237
+ /**
238
+ * Get last notification details.
239
+ *
240
+ * @param array $notification Notification data.
241
+ */
242
+ private static function set_active_notification( $notification ) {
243
+ $metadata = self::get_notifications_metadata();
244
+ $metadata['last_notification'] = $notification;
245
+ update_option( 'themeisle_sdk_notifications', $metadata );
246
+ }
247
+
248
+ /**
249
+ * Get notification html.
250
+ *
251
+ * @param array $notification_details Notification details.
252
+ *
253
+ * @return string Html for notice.
254
+ */
255
+ public static function get_notification_html( $notification_details ) {
256
+ $default = [
257
+ 'id' => '',
258
+ 'heading' => '',
259
+ 'message' => '',
260
+ 'ctas' => [
261
+ 'confirm' => [
262
+ 'link' => '#',
263
+ 'text' => '',
264
+ ],
265
+ 'cancel' => [
266
+ 'link' => '#',
267
+ 'text' => '',
268
+ ],
269
+ ],
270
+ ];
271
+ $notification_details = wp_parse_args( $notification_details, $default );
272
+
273
+ $notification_html = '<div class="notice notice-success is-dismissible themeisle-sdk-notice" data-notification-id="' . esc_attr( $notification_details['id'] ) . '" id="' . esc_attr( $notification_details['id'] ) . '-notification"> <div class="themeisle-sdk-notification-box">';
274
+
275
+ if ( ! empty( $notification_details['heading'] ) ) {
276
+ $notification_html .= sprintf( '<h4>%s</h4>', wp_kses_post( $notification_details['heading'] ) );
277
+ }
278
+ if ( ! empty( $notification_details['message'] ) ) {
279
+ $notification_html .= wp_kses_post( $notification_details['message'] );
280
+ }
281
+ $notification_html .= '<div class="actions">';
282
+
283
+ if ( ! empty( $notification_details['ctas']['confirm']['text'] ) ) {
284
+ $notification_html .= sprintf(
285
+ '<a href="%s" target="_blank" class=" button button-primary %s" data-confirm="yes" >%s</a>',
286
+ esc_url( $notification_details['ctas']['confirm']['link'] ),
287
+ esc_attr( $notification_details['id'] . '_confirm' ),
288
+ wp_kses_post( $notification_details['ctas']['confirm']['text'] )
289
+ );
290
+ }
291
+
292
+ if ( ! empty( $notification_details['ctas']['cancel']['text'] ) ) {
293
+ $notification_html .= sprintf(
294
+ '<a href="%s" class=" button %s" data-confirm="no">%s</a>',
295
+ esc_url( $notification_details['ctas']['cancel']['link'] ),
296
+ esc_attr( $notification_details['id'] ) . '_cancel',
297
+ wp_kses_post( $notification_details['ctas']['cancel']['text'] )
298
+ );
299
+ }
300
+
301
+ $notification_html .= '</div>';
302
+ $notification_html .= ' </div>';
303
+ $notification_html .= ' </div>';
304
+
305
+ return $notification_html;
306
+ }
307
+
308
+ /**
309
+ * Adds js snippet for hiding the notice.
310
+ */
311
+ public static function render_snippets() {
312
+
313
+ ?>
314
+ <style type="text/css">
315
+ .themeisle-sdk-notification-box {
316
+ padding: 3px;
317
+ }
318
+
319
+ .themeisle-sdk-notification-box .actions {
320
+ margin-top: 6px;
321
+ margin-bottom: 4px;
322
+ }
323
+
324
+ .themeisle-sdk-notification-box .button {
325
+ margin-right: 5px;
326
+ }
327
+ </style>
328
+ <script type="text/javascript">
329
+ (function ($) {
330
+ $(document).ready(function () {
331
+ $('#wpbody-content').on('click', ".themeisle-sdk-notice a.button, .themeisle-sdk-notice .notice-dismiss", function (e) {
332
+
333
+ var container = $('.themeisle-sdk-notice');
334
+ var link = $(this);
335
+ var notification_id = container.attr('data-notification-id');
336
+ var confirm = link.attr('data-confirm');
337
+ if (typeof confirm === "undefined") {
338
+ confirm = 'no';
339
+ }
340
+ $.post(
341
+ ajaxurl,
342
+ {
343
+ 'nonce': '<?php echo wp_create_nonce( (string) __CLASS__ ); ?>',
344
+ 'action': 'themeisle_sdk_dismiss_notice',
345
+ 'id': notification_id,
346
+ 'confirm': confirm
347
+ }
348
+ );
349
+ if (confirm === 'yes') {
350
+ $(this).trigger('themeisle-sdk:confirmed');
351
+ } else {
352
+ $(this).trigger('themeisle-sdk:canceled');
353
+ }
354
+ container.hide();
355
+ if (link.attr('href') === '#') {
356
+ return false;
357
+ }
358
+ });
359
+ });
360
+ })(jQuery);
361
+ </script>
362
+ <?php
363
+ }
364
+
365
+ /**
366
+ * Dismiss the notification.
367
+ */
368
+ static function dismiss() {
369
+ check_ajax_referer( (string) __CLASS__, 'nonce' );
370
+
371
+ $id = isset( $_POST['id'] ) ? sanitize_text_field( $_POST['id'] ) : '';
372
+ $confirm = isset( $_POST['confirm'] ) ? sanitize_text_field( $_POST['confirm'] ) : 'no';
373
+
374
+ if ( empty( $id ) ) {
375
+ wp_send_json( [] );
376
+ }
377
+ self::set_last_active_notification_timestamp();
378
+ update_option( $id, $confirm );
379
+ do_action( $id . '_process_confirm', $confirm );
380
+ wp_send_json( [] );
381
+ }
382
+
383
+ /**
384
+ * Check if we should load the notification module.
385
+ *
386
+ * @param Product $product Product to check.
387
+ *
388
+ * @return bool Should we load this?
389
+ */
390
+ public function can_load( $product ) {
391
+
392
+ if ( $this->is_from_partner( $product ) ) {
393
+ return false;
394
+ }
395
+ if ( ! current_user_can( 'manage_options' ) ) {
396
+ return false;
397
+ }
398
+ if ( ( time() - $product->get_install_time() ) < ( self::MIN_INSTALL_TIME * HOUR_IN_SECONDS ) ) {
399
+ return false;
400
+ }
401
+
402
+ return true;
403
+ }
404
+
405
+ /**
406
+ * Setup notifications queue.
407
+ */
408
+ public static function setup_notifications() {
409
+ $notifications = apply_filters( 'themeisle_sdk_registered_notifications', [] );
410
+ $notifications = array_filter(
411
+ $notifications,
412
+ function ( $value ) {
413
+ if ( ! isset( $value['id'] ) ) {
414
+ return false;
415
+ }
416
+ if ( get_option( $value['id'], '' ) !== '' ) {
417
+ return false;
418
+ }
419
+
420
+ return apply_filters( $value['id'] . '_should_show', true );
421
+ }
422
+ );
423
+ self::$notifications = $notifications;
424
+ }
425
+ /**
426
+ * Load the module logic.
427
+ *
428
+ * @param Product $product Product to load the module for.
429
+ *
430
+ * @return Notification Module instance.
431
+ */
432
+ public function load( $product ) {
433
+ $this->product = $product;
434
+
435
+ $notifications = apply_filters( 'themeisle_sdk_registered_notifications', [] );
436
+ $notifications = array_filter(
437
+ $notifications,
438
+ function ( $value ) {
439
+ if ( ! isset( $value['id'] ) ) {
440
+ return false;
441
+ }
442
+ if ( get_option( $value['id'], '' ) !== '' ) {
443
+ return false;
444
+ }
445
+
446
+ return apply_filters( $value['id'] . '_should_show', true );
447
+ }
448
+ );
449
+ self::$notifications = $notifications;
450
+ add_action( 'admin_notices', array( __CLASS__, 'show_notification' ) );
451
+ add_action( 'wp_ajax_themeisle_sdk_dismiss_notice', array( __CLASS__, 'dismiss' ) );
452
+ add_action( 'admin_head', array( __CLASS__, 'setup_notifications' ) );
453
+
454
+ return $this;
455
+ }
456
+ }
vendor/codeinwp/themeisle-sdk/src/Modules/Recommendation.php ADDED
@@ -0,0 +1,374 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The class that exposes hooks for recommend.
4
+ *
5
+ * @package ThemeIsleSDK
6
+ * @subpackage Rollback
7
+ * @copyright Copyright (c) 2017, Marius Cristea
8
+ * @license http://opensource.org/licenses/gpl-3.0.php GNU Public License
9
+ * @since 1.0.0
10
+ */
11
+
12
+ namespace ThemeisleSDK\Modules;
13
+
14
+ // Exit if accessed directly.
15
+ use ThemeisleSDK\Common\Abstract_Module;
16
+ use ThemeisleSDK\Product;
17
+
18
+ if ( ! defined( 'ABSPATH' ) ) {
19
+ exit;
20
+ }
21
+
22
+ /**
23
+ * Expose endpoints for ThemeIsle SDK.
24
+ */
25
+ class Recommendation extends Abstract_Module {
26
+
27
+
28
+ /**
29
+ * Load module logic.
30
+ *
31
+ * @param Product $product Product to load.
32
+ */
33
+ public function load( $product ) {
34
+ $this->product = $product;
35
+ $this->setup_hooks();
36
+
37
+ return $this;
38
+ }
39
+
40
+ /**
41
+ * Setup endpoints.
42
+ */
43
+ private function setup_hooks() {
44
+ add_action( $this->product->get_key() . '_recommend_products', array( $this, 'render_products_box' ), 10, 4 );
45
+ add_action( 'admin_head', array( $this, 'enqueue' ) );
46
+ }
47
+
48
+ /**
49
+ * Check if we should load the module for this product.
50
+ *
51
+ * @param Product $product Product data.
52
+ *
53
+ * @return bool Should we load the module?
54
+ */
55
+ public function can_load( $product ) {
56
+ return true;
57
+ }
58
+
59
+ /**
60
+ * Render products box content.
61
+ *
62
+ * @param array $plugins_list - list of useful plugins (in slug => nicename format).
63
+ * @param array $themes_list - list of useful themes (in slug => nicename format).
64
+ * @param array $strings - list of translated strings.
65
+ * @param array $preferences - list of preferences.
66
+ */
67
+ function render_products_box( $plugins_list, $themes_list, $strings, $preferences = array() ) {
68
+
69
+ if ( empty( $plugins_list ) && empty( $themes_list ) ) {
70
+ return;
71
+ }
72
+
73
+ if ( ! empty( $plugins_list ) && ! current_user_can( 'install_plugins' ) ) {
74
+ return;
75
+ }
76
+
77
+ if ( ! empty( $themes_list ) && ! current_user_can( 'install_themes' ) ) {
78
+ return;
79
+ }
80
+
81
+ add_thickbox();
82
+
83
+ if ( ! empty( $themes_list ) ) {
84
+ $list = $this->get_themes( $themes_list, $preferences );
85
+
86
+ if ( has_action( $this->product->get_key() . '_recommend_products_theme_template' ) ) {
87
+ do_action( $this->product->get_key() . '_recommend_products_theme_template', $list, $strings, $preferences );
88
+ } else {
89
+ echo '<div class="recommend-product">';
90
+
91
+ foreach ( $list as $theme ) {
92
+ echo '<div class="plugin_box">';
93
+ echo ' <img class="theme-banner" src="' . $theme->screenshot_url . '">';
94
+ echo ' <div class="title-action-wrapper">';
95
+ echo ' <span class="plugin-name">' . esc_html( $theme->custom_name ) . '</span>';
96
+ if ( ! isset( $preferences['description'] ) || ( isset( $preferences['description'] ) && $preferences['description'] ) ) {
97
+ echo '<span class="plugin-desc">' . esc_html( substr( $theme->description, 0, strpos( $theme->description, '.' ) ) ) . '.</span>';
98
+ }
99
+ echo ' </div>';
100
+ echo '<div class="plugin-box-footer">';
101
+ echo ' <div class="button-wrap">';
102
+ echo ' <a class="button button-primary " href="' . esc_url( $theme->custom_url ) . '"><span class="dashicons dashicons-external"></span>' . esc_html( $strings['install'] ) . '</a>';
103
+ echo ' </div>';
104
+ echo ' </div>';
105
+ echo '</div>';
106
+ }
107
+
108
+ echo '</div>';
109
+ }
110
+ }
111
+ if ( ! empty( $plugins_list ) ) {
112
+ $list = $this->get_plugins( $plugins_list, $preferences );
113
+
114
+ if ( has_action( $this->product->get_key() . '_recommend_products_plugin_template' ) ) {
115
+ do_action( $this->product->get_key() . '_recommend_products_plugin_template', $list, $strings, $preferences );
116
+ } else {
117
+ echo '<div class="recommend-product">';
118
+
119
+ foreach ( $list as $current_plugin ) {
120
+ echo '<div class="plugin_box">';
121
+ echo ' <img class="plugin-banner" src="' . $current_plugin->custom_image . '">';
122
+ echo ' <div class="title-action-wrapper">';
123
+ echo ' <span class="plugin-name">' . esc_html( $current_plugin->custom_name ) . '</span>';
124
+ if ( ! isset( $preferences['description'] ) || ( isset( $preferences['description'] ) && $preferences['description'] ) ) {
125
+ echo '<span class="plugin-desc">' . esc_html( substr( $current_plugin->short_description, 0, strpos( $current_plugin->short_description, '.' ) ) ) . '. </span>';
126
+ }
127
+ echo ' </div>';
128
+ echo ' <div class="plugin-box-footer">';
129
+ echo ' <a class="button button-primary thickbox open-plugin-details-modal" href="' . esc_url( $current_plugin->custom_url ) . '"><span class="dashicons dashicons-external"></span>' . esc_html( $strings['install'] ) . '</a>';
130
+ echo ' </div>';
131
+ echo '</div>';
132
+ }
133
+
134
+ echo '</div>';
135
+ }
136
+ }
137
+
138
+ }
139
+
140
+ /**
141
+ * Collect all the information for the themes list.
142
+ *
143
+ * @param array $themes_list - list of useful themes (in slug => nicename format).
144
+ * @param array $preferences - list of preferences.
145
+ *
146
+ * @return array
147
+ */
148
+ private function get_themes( $themes_list, $preferences ) {
149
+ $list = array();
150
+ foreach ( $themes_list as $slug => $nicename ) {
151
+ $theme = $this->call_theme_api( $slug );
152
+ if ( ! $theme ) {
153
+ continue;
154
+ }
155
+
156
+ $url = add_query_arg(
157
+ array(
158
+ 'theme' => $theme->slug,
159
+ ),
160
+ network_admin_url( 'theme-install.php' )
161
+ );
162
+
163
+ $name = empty( $nicename ) ? $theme->name : $nicename;
164
+
165
+ $theme->custom_url = $url;
166
+ $theme->custom_name = $name;
167
+
168
+ $list[] = $theme;
169
+ }
170
+
171
+ return $list;
172
+ }
173
+
174
+ /**
175
+ * Call theme api
176
+ *
177
+ * @param string $slug theme slug.
178
+ *
179
+ * @return array|mixed|object
180
+ */
181
+ private function call_theme_api( $slug ) {
182
+ $theme = get_transient( 'ti_theme_info_' . $slug );
183
+
184
+ if ( false !== $theme ) {
185
+ return $theme;
186
+ }
187
+
188
+ $products = wp_remote_get(
189
+ 'https://api.wordpress.org/themes/info/1.1/?action=query_themes&request[theme]=' . $slug . '&request[per_page]=1'
190
+ );
191
+ $products = json_decode( wp_remote_retrieve_body( $products ) );
192
+ if ( is_object( $products ) ) {
193
+ $theme = $products->themes[0];
194
+ set_transient( 'ti_theme_info_' . $slug, $theme, 6 * HOUR_IN_SECONDS );
195
+ }
196
+
197
+ return $theme;
198
+ }
199
+
200
+ /**
201
+ * Collect all the information for the plugins list.
202
+ *
203
+ * @param array $plugins_list - list of useful plugins (in slug => nicename format).
204
+ * @param array $preferences - list of preferences.
205
+ *
206
+ * @return array
207
+ */
208
+ private function get_plugins( $plugins_list, $preferences ) {
209
+ $list = array();
210
+ foreach ( $plugins_list as $plugin => $nicename ) {
211
+ $current_plugin = $this->call_plugin_api( $plugin );
212
+
213
+ $name = empty( $nicename ) ? $current_plugin->name : $nicename;
214
+
215
+ $image = $current_plugin->banners['low'];
216
+ if ( isset( $preferences['image'] ) && 'icon' === $preferences['image'] ) {
217
+ $image = $current_plugin->icons['1x'];
218
+ }
219
+
220
+ $url = add_query_arg(
221
+ array(
222
+ 'tab' => 'plugin-information',
223
+ 'plugin' => $current_plugin->slug,
224
+ 'TB_iframe' => true,
225
+ 'width' => 800,
226
+ 'height' => 800,
227
+ ),
228
+ network_admin_url( 'plugin-install.php' )
229
+ );
230
+
231
+ $current_plugin->custom_url = $url;
232
+ $current_plugin->custom_name = $name;
233
+ $current_plugin->custom_image = $image;
234
+
235
+ $list[] = $current_plugin;
236
+ }
237
+
238
+ return $list;
239
+ }
240
+
241
+ /**
242
+ * Call plugin api
243
+ *
244
+ * @param string $slug plugin slug.
245
+ *
246
+ * @return array|mixed|object
247
+ */
248
+ private function call_plugin_api( $slug ) {
249
+ include_once( ABSPATH . 'wp-admin/includes/plugin-install.php' );
250
+
251
+ $call_api = get_transient( 'ti_plugin_info_' . $slug );
252
+
253
+ if ( false === $call_api ) {
254
+ $call_api = plugins_api(
255
+ 'plugin_information',
256
+ array(
257
+ 'slug' => $slug,
258
+ 'fields' => array(
259
+ 'downloaded' => false,
260
+ 'rating' => false,
261
+ 'description' => false,
262
+ 'short_description' => true,
263
+ 'donate_link' => false,
264
+ 'tags' => false,
265
+ 'sections' => true,
266
+ 'homepage' => true,
267
+ 'added' => false,
268
+ 'last_updated' => false,
269
+ 'compatibility' => false,
270
+ 'tested' => false,
271
+ 'requires' => false,
272
+ 'downloadlink' => false,
273
+ 'icons' => true,
274
+ 'banners' => true,
275
+ ),
276
+ )
277
+ );
278
+ set_transient( 'ti_plugin_info_' . $slug, $call_api, 30 * MINUTE_IN_SECONDS );
279
+ }
280
+
281
+ return $call_api;
282
+ }
283
+
284
+ /**
285
+ * Load css and scripts for the plugin recommend page.
286
+ */
287
+ public function enqueue() {
288
+ $screen = get_current_screen();
289
+
290
+ if ( ! isset( $screen->id ) ) {
291
+ return;
292
+ }
293
+ if ( false === apply_filters( $this->product->get_key() . '_enqueue_recommend', false, $screen->id ) ) {
294
+ return;
295
+ }
296
+
297
+ ?>
298
+ <style type="text/css">
299
+ .recommend-product {
300
+ display: flex;
301
+ justify-content: space-between;
302
+ flex-wrap: wrap;
303
+ }
304
+
305
+ .recommend-product .theme-banner {
306
+ width:200px;
307
+ margin: auto;
308
+ }
309
+ .recommend-product .plugin-banner {
310
+ width: 100px;
311
+ margin: auto;
312
+ }
313
+
314
+ .recommend-product .plugin_box .button span{
315
+
316
+ margin-top: 2px;
317
+ margin-right: 7px;
318
+ }
319
+ .recommend-product .plugin_box .button{
320
+ margin-bottom:10px;
321
+ }
322
+ .recommend-product .plugin_box {
323
+ margin-bottom: 20px;
324
+ padding-top: 5px;
325
+ display: flex;
326
+ box-shadow: 0px 0px 10px -5px rgba(0,0,0,0.55);
327
+ background: #fff;
328
+ border-radius: 5px;
329
+ flex-direction: column;
330
+ justify-content: flex-start;
331
+ width: 95%;
332
+ }
333
+
334
+ .recommend-product .title-action-wrapper {
335
+ padding: 15px 20px 5px 20px;
336
+ }
337
+
338
+ .recommend-product .plugin-name {
339
+ font-size: 18px;
340
+ display: block;
341
+ white-space: nowrap;
342
+ text-overflow: ellipsis;
343
+ margin-bottom: 10px;
344
+ overflow: hidden;
345
+ line-height: normal;
346
+ }
347
+
348
+
349
+ .recommend-product .plugin-desc {
350
+ display: block;
351
+ margin-bottom: 10px;
352
+ font-size: 13px;
353
+ color: #777;
354
+ line-height: 1.6;
355
+ }
356
+
357
+ .recommend-product .button-wrap > div {
358
+ padding: 0;
359
+ margin: 0;
360
+ }
361
+
362
+ .plugin-box-footer {
363
+ display: flex;
364
+ justify-content: space-around;
365
+ vertical-align: middle;
366
+ align-items: center;
367
+ padding: 0px 10px 5px;
368
+ flex: 1;
369
+ margin-top: auto;
370
+ }
371
+ </style>
372
+ <?php
373
+ }
374
+ }
vendor/codeinwp/themeisle-sdk/src/Modules/Review.php ADDED
@@ -0,0 +1,117 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The Review model class for ThemeIsle SDK
4
+ *
5
+ * @package ThemeIsleSDK
6
+ * @subpackage Modules
7
+ * @copyright Copyright (c) 2017, Marius Cristea
8
+ * @license http://opensource.org/licenses/gpl-3.0.php GNU Public License
9
+ * @since 1.0.0
10
+ */
11
+
12
+ namespace ThemeisleSDK\Modules;
13
+
14
+ use ThemeisleSDK\Common\Abstract_Module;
15
+ use ThemeisleSDK\Product;
16
+
17
+ // Exit if accessed directly.
18
+ if ( ! defined( 'ABSPATH' ) ) {
19
+ exit;
20
+ }
21
+
22
+ /**
23
+ * Review module for ThemeIsle SDK.
24
+ */
25
+ class Review extends Abstract_Module {
26
+
27
+ /**
28
+ * Check if we should load module for this.
29
+ *
30
+ * @param Product $product Product to check.
31
+ *
32
+ * @return bool Should load ?
33
+ */
34
+ public function can_load( $product ) {
35
+ if ( $this->is_from_partner( $product ) ) {
36
+ return false;
37
+ }
38
+ if ( ! $product->is_wordpress_available() ) {
39
+ return false;
40
+ }
41
+
42
+ return apply_filters( $product->get_slug() . '_sdk_should_review', true );
43
+ }
44
+
45
+
46
+ /**
47
+ * Add notification to queue.
48
+ *
49
+ * @param array $all_notifications Previous notification.
50
+ *
51
+ * @return array All notifications.
52
+ */
53
+ public function add_notification( $all_notifications ) {
54
+
55
+ $developers = [
56
+ 'Bogdan',
57
+ 'Marius',
58
+ 'Hardeep',
59
+ 'Rodica',
60
+ 'Stefan',
61
+ 'Uriahs',
62
+ 'Madalin',
63
+ 'Radu',
64
+ 'Silviu',
65
+ 'Andrei',
66
+ ];
67
+
68
+ $link = 'https://wordpress.org/support/' . $this->product->get_type() . '/' . $this->product->get_slug() . '/reviews/#wporg-footer';
69
+
70
+ $message = apply_filters( $this->product->get_key() . '_feedback_review_message', '<p>Hey, it’s great to see you have <b>{product}</b> active for a few days now. How is everything going? If you can spare a few moments to rate it on WordPress.org it would help us a lot (and boost my motivation). Cheers! <br/> <br/>~ {developer}, developer of {product}</p>' );
71
+
72
+ $button_submit = apply_filters( $this->product->get_key() . '_feedback_review_button_do', 'Ok, I will gladly help.' );
73
+ $button_cancel = apply_filters( $this->product->get_key() . '_feedback_review_button_cancel', 'No, thanks.' );
74
+ $message = str_replace(
75
+ [ '{product}', '{developer}' ],
76
+ [
77
+ $this->product->get_friendly_name(),
78
+ $developers[ strlen( get_site_url() ) % 10 ],
79
+ ],
80
+ $message
81
+ );
82
+
83
+ $all_notifications[] = [
84
+ 'id' => $this->product->get_key() . '_review_flag',
85
+ 'message' => $message,
86
+ 'ctas' => [
87
+ 'confirm' => [
88
+ 'link' => $link,
89
+ 'text' => $button_submit,
90
+ ],
91
+ 'cancel' => [
92
+ 'link' => '#',
93
+ 'text' => $button_cancel,
94
+ ],
95
+ ],
96
+ ];
97
+
98
+ return $all_notifications;
99
+ }
100
+
101
+
102
+ /**
103
+ * Load module logic.
104
+ *
105
+ * @param Product $product Product to load.
106
+ *
107
+ * @return Review Module instance.
108
+ */
109
+ public function load( $product ) {
110
+
111
+ $this->product = $product;
112
+
113
+ add_filter( 'themeisle_sdk_registered_notifications', [ $this, 'add_notification' ] );
114
+
115
+ return $this;
116
+ }
117
+ }
vendor/codeinwp/themeisle-sdk/src/Modules/Rollback.php ADDED
@@ -0,0 +1,376 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The rollback class for ThemeIsle SDK.
4
+ *
5
+ * @package ThemeIsleSDK
6
+ * @subpackage Rollback
7
+ * @copyright Copyright (c) 2017, Marius Cristea
8
+ * @license http://opensource.org/licenses/gpl-3.0.php GNU Public License
9
+ * @since 1.0.0
10
+ */
11
+
12
+ namespace ThemeisleSDK\Modules;
13
+
14
+ // Exit if accessed directly.
15
+ use ThemeisleSDK\Common\Abstract_Module;
16
+ use ThemeisleSDK\Product;
17
+
18
+ if ( ! defined( 'ABSPATH' ) ) {
19
+ exit;
20
+ }
21
+
22
+ /**
23
+ * Rollback for ThemeIsle SDK.
24
+ */
25
+ class Rollback extends Abstract_Module {
26
+
27
+ /**
28
+ * Add js scripts for themes rollback.
29
+ */
30
+ public function add_footer() {
31
+ $screen = get_current_screen();
32
+ if ( ! isset( $screen->parent_file ) ) {
33
+ return;
34
+ }
35
+ if ( 'themes.php' !== $screen->parent_file ) {
36
+ return;
37
+ }
38
+ if ( ! $this->product->is_theme() ) {
39
+ return;
40
+ }
41
+ $version = $this->get_rollback();
42
+ if ( empty( $version ) ) {
43
+ return;
44
+ }
45
+ ?>
46
+ <script type="text/javascript">
47
+ jQuery(document).ready(function ($) {
48
+ setInterval(checkTheme, 500);
49
+
50
+ function checkTheme() {
51
+ var theme = '<?php echo esc_attr( $this->product->get_slug() ); ?>-action';
52
+
53
+ if (jQuery('#' + theme).length > 0) {
54
+ if (jQuery('.theme-overlay.active').is(':visible')) {
55
+ if (jQuery('#' + theme + '-rollback').length === 0) {
56
+ jQuery('.theme-actions .active-theme').prepend('<a class="button" style="float:left" id="' + theme + '-rollback" href="<?php echo esc_url( wp_nonce_url( admin_url( 'admin-post.php?action=' . $this->product->get_key() . '_rollback' ), $this->product->get_key() . '_rollback' ) ); ?>">Rollback to v<?php echo esc_attr( $version['version'] ); ?></a>')
57
+ }
58
+ }
59
+
60
+ }
61
+ }
62
+ })
63
+
64
+ </script>
65
+ <?php
66
+
67
+ }
68
+
69
+ /**
70
+ * Get the last rollback for this product.
71
+ *
72
+ * @return array The rollback version.
73
+ */
74
+ public function get_rollback() {
75
+ $rollback = array();
76
+ $versions = $this->get_api_versions();
77
+ $versions = apply_filters( $this->product->get_key() . '_rollbacks', $versions );
78
+ if ( empty( $versions ) ) {
79
+ return $rollback;
80
+ }
81
+ if ( $versions ) {
82
+ usort( $versions, array( $this, 'sort_rollback_array' ) );
83
+ foreach ( $versions as $version ) {
84
+ if ( isset( $version['version'] ) && isset( $version['url'] ) && version_compare( $this->product->get_version(), $version['version'], '>' ) ) {
85
+ $rollback = $version;
86
+ break;
87
+ }
88
+ }
89
+ }
90
+
91
+ return $rollback;
92
+ }
93
+
94
+ /**
95
+ * Get versions array from wp.org
96
+ *
97
+ * @return array Array of versions.
98
+ */
99
+ private function get_api_versions() {
100
+
101
+ $cache_key = $this->product->get_key() . '_' . preg_replace( '/[^0-9a-zA-Z ]/m', '', $this->product->get_version() ) . 'versions';
102
+ $cache_versions = get_transient( $cache_key );
103
+ if ( false === $cache_versions ) {
104
+ $versions = $this->get_remote_versions();
105
+ set_transient( $cache_key, $versions, 5 * DAY_IN_SECONDS );
106
+ } else {
107
+ $versions = is_array( $cache_versions ) ? $cache_versions : array();
108
+ }
109
+
110
+ return $versions;
111
+ }
112
+
113
+ /**
114
+ * Get remote versions zips.
115
+ *
116
+ * @return array Array of available versions.
117
+ */
118
+ private function get_remote_versions() {
119
+ $url = $this->get_versions_api_url();
120
+ if ( empty( $url ) ) {
121
+ return [];
122
+ }
123
+ $response = wp_remote_get( $url );
124
+ if ( is_wp_error( $response ) ) {
125
+ return array();
126
+ }
127
+ $response = wp_remote_retrieve_body( $response );
128
+
129
+ if ( is_serialized( $response ) ) {
130
+ $response = maybe_unserialize( $response );
131
+ } else {
132
+ $response = json_decode( $response );
133
+ }
134
+
135
+ if ( ! is_object( $response ) ) {
136
+ return array();
137
+ }
138
+ if ( ! isset( $response->versions ) ) {
139
+ return array();
140
+ }
141
+
142
+ $versions = array();
143
+ foreach ( $response->versions as $key => $value ) {
144
+ $versions[] = array(
145
+ 'version' => is_object( $value ) ? $value->version : $key,
146
+ 'url' => is_object( $value ) ? $value->file : $value,
147
+ );
148
+ }
149
+
150
+ return $versions;
151
+ }
152
+
153
+ /**
154
+ * Return url where to check for versions.
155
+ *
156
+ * @return string Url where to check for versions.
157
+ */
158
+ private function get_versions_api_url() {
159
+ if ( $this->product->is_wordpress_available() && $this->product->is_plugin() ) {
160
+ return sprintf( 'https://api.wordpress.org/plugins/info/1.0/%s', $this->product->get_slug() );
161
+ }
162
+ if ( $this->product->is_wordpress_available() && $this->product->is_theme() ) {
163
+ return sprintf( 'https://api.wordpress.org/themes/info/1.1/?action=theme_information&request[slug]=%s&request[fields][versions]=true', $this->product->get_slug() );
164
+ }
165
+ $license = $this->product->get_license();
166
+ if ( $this->product->requires_license() && strlen( $license ) < 10 ) {
167
+ return '';
168
+ }
169
+
170
+ return sprintf( '%s?edd_action=get_versions&name=%s&url=%s&license=%s', $this->product->get_store_url(), urlencode( $this->product->get_name() ), urlencode( get_site_url() ), $license );
171
+ }
172
+
173
+ /**
174
+ * Show the rollback links in the plugin page.
175
+ *
176
+ * @param array $links Plugin links.
177
+ *
178
+ * @return array $links Altered links.
179
+ */
180
+ public function add_rollback_link( $links ) {
181
+ $version = $this->get_rollback();
182
+ if ( empty( $version ) ) {
183
+ return $links;
184
+ }
185
+ $links[] = '<a href="' . wp_nonce_url( admin_url( 'admin-post.php?action=' . $this->product->get_key() . '_rollback' ), $this->product->get_key() . '_rollback' ) . '">' . sprintf( apply_filters( $this->product->get_key() . '_rollback_label', 'Rollback to v%s' ), $version['version'] ) . '</a>';
186
+
187
+ return $links;
188
+ }
189
+
190
+ /**
191
+ * Start the rollback operation.
192
+ */
193
+ public function start_rollback() {
194
+ if ( ! isset( $_GET['_wpnonce'] ) || ! wp_verify_nonce( $_GET['_wpnonce'], $this->product->get_key() . '_rollback' ) ) {
195
+ wp_nonce_ays( '' );
196
+ }
197
+
198
+ if ( $this->product->is_plugin() ) {
199
+ $this->start_rollback_plugin();
200
+
201
+ return;
202
+ }
203
+ if ( $this->product->is_theme() ) {
204
+ $this->start_rollback_theme();
205
+
206
+ return;
207
+ }
208
+ }
209
+
210
+ /**
211
+ * Start the rollback operation for the plugin.
212
+ */
213
+ private function start_rollback_plugin() {
214
+ $rollback = $this->get_rollback();
215
+ $plugin_transient = get_site_transient( 'update_plugins' );
216
+ $plugin_folder = $this->product->get_slug();
217
+ $plugin_file = $this->product->get_file();
218
+ $version = $rollback['version'];
219
+ $temp_array = array(
220
+ 'slug' => $plugin_folder,
221
+ 'new_version' => $version,
222
+ 'package' => $rollback['url'],
223
+ );
224
+
225
+ $temp_object = (object) $temp_array;
226
+ $plugin_transient->response[ $plugin_folder . '/' . $plugin_file ] = $temp_object;
227
+ set_site_transient( 'update_plugins', $plugin_transient );
228
+
229
+ $transient = get_transient( $this->product->get_key() . '_warning_rollback' );
230
+
231
+ if ( false === $transient ) {
232
+ set_transient( $this->product->get_key() . '_warning_rollback', 'in progress', 30 );
233
+ require_once( ABSPATH . 'wp-admin/includes/class-wp-upgrader.php' );
234
+ $title = sprintf( apply_filters( $this->product->get_key() . '_rollback_message', 'Rolling back %s to v%s' ), $this->product->get_name(), $version );
235
+ $plugin = $plugin_folder . '/' . $plugin_file;
236
+ $nonce = 'upgrade-plugin_' . $plugin;
237
+ $url = 'update.php?action=upgrade-plugin&plugin=' . urlencode( $plugin );
238
+ $upgrader_skin = new \Plugin_Upgrader_Skin( compact( 'title', 'nonce', 'url', 'plugin' ) );
239
+ $upgrader = new \Plugin_Upgrader( $upgrader_skin );
240
+ $upgrader->upgrade( $plugin );
241
+ delete_transient( $this->product->get_key() . '_warning_rollback' );
242
+ wp_die(
243
+ '',
244
+ $title,
245
+ array(
246
+ 'response' => 200,
247
+ )
248
+ );
249
+ }
250
+ }
251
+
252
+ /**
253
+ * Start the rollback operation for the theme.
254
+ */
255
+ private function start_rollback_theme() {
256
+ add_filter( 'update_theme_complete_actions', array( $this, 'alter_links_theme_upgrade' ) );
257
+ $rollback = $this->get_rollback();
258
+ $transient = get_site_transient( 'update_themes' );
259
+ $folder = $this->product->get_slug();
260
+ $version = $rollback['version'];
261
+ $temp_array = array(
262
+ 'new_version' => $version,
263
+ 'package' => $rollback['url'],
264
+ );
265
+
266
+ $transient->response[ $folder . '/style.css' ] = $temp_array;
267
+ set_site_transient( 'update_themes', $transient );
268
+
269
+ $transient = get_transient( $this->product->get_key() . '_warning_rollback' );
270
+
271
+ if ( false === $transient ) {
272
+ set_transient( $this->product->get_key() . '_warning_rollback', 'in progress', 30 );
273
+ require_once( ABSPATH . 'wp-admin/includes/class-wp-upgrader.php' );
274
+ $title = sprintf( apply_filters( $this->product->get_key() . '_rollback_message', 'Rolling back %s to v%s' ), $this->product->get_name(), $version );
275
+ $theme = $folder . '/style.css';
276
+ $nonce = 'upgrade-theme_' . $theme;
277
+ $url = 'update.php?action=upgrade-theme&theme=' . urlencode( $theme );
278
+
279
+ $upgrader = new \Theme_Upgrader( new \Theme_Upgrader_Skin( compact( 'title', 'nonce', 'url', 'theme' ) ) );
280
+ $upgrader->upgrade( $theme );
281
+ delete_transient( $this->product->get_key() . '_warning_rollback' );
282
+ wp_die(
283
+ '',
284
+ $title,
285
+ array(
286
+ 'response' => 200,
287
+ )
288
+ );
289
+ }
290
+ }
291
+
292
+ /**
293
+ * Alter links and remove duplicate customize message.
294
+ *
295
+ * @param array $links Array of old links.
296
+ *
297
+ * @return mixed Array of links.
298
+ */
299
+ public function alter_links_theme_upgrade( $links ) {
300
+ if ( isset( $links['preview'] ) ) {
301
+ $links['preview'] = str_replace( '<span aria-hidden="true">Customize</span>', '', $links['preview'] );
302
+ }
303
+
304
+ return $links;
305
+ }
306
+
307
+ /**
308
+ * Loads product object.
309
+ *
310
+ * @param Product $product Product object.
311
+ *
312
+ * @return bool Should we load the module?
313
+ */
314
+ public function can_load( $product ) {
315
+ if ( $this->is_from_partner( $product ) ) {
316
+ return false;
317
+ }
318
+ if ( $product->is_theme() && ! current_user_can( 'switch_themes' ) ) {
319
+ return false;
320
+ }
321
+
322
+ if ( $product->is_plugin() && ! current_user_can( 'install_plugins' ) ) {
323
+ return false;
324
+ }
325
+
326
+ return true;
327
+ }
328
+
329
+ /**
330
+ * Sort the rollbacks array in descending order.
331
+ *
332
+ * @param mixed $a First version to compare.
333
+ * @param mixed $b Second version to compare.
334
+ *
335
+ * @return bool Which version is greater?
336
+ */
337
+ public function sort_rollback_array( $a, $b ) {
338
+ return version_compare( $a['version'], $b['version'], '<' ) > 0;
339
+ }
340
+
341
+ /**
342
+ * Load module logic.
343
+ *
344
+ * @param Product $product Product object.
345
+ *
346
+ * @return $this Module object.
347
+ */
348
+ public function load( $product ) {
349
+ $this->product = $product;
350
+ $this->show_link();
351
+ $this->add_hooks();
352
+
353
+ return $this;
354
+ }
355
+
356
+ /**
357
+ * If product can be rolled back, show the link to rollback.
358
+ */
359
+ private function show_link() {
360
+ add_filter(
361
+ 'plugin_action_links_' . plugin_basename( $this->product->get_basefile() ),
362
+ array(
363
+ $this,
364
+ 'add_rollback_link',
365
+ )
366
+ );
367
+ }
368
+
369
+ /**
370
+ * Set the rollback hook. Strangely, this does not work if placed in the ThemeIsle_SDK_Rollback class, so it is being called from there instead.
371
+ */
372
+ public function add_hooks() {
373
+ add_action( 'admin_post_' . $this->product->get_key() . '_rollback', array( $this, 'start_rollback' ) );
374
+ add_action( 'admin_footer', array( $this, 'add_footer' ) );
375
+ }
376
+ }
vendor/codeinwp/themeisle-sdk/src/Modules/Translate.php ADDED
@@ -0,0 +1,918 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The translate model class for ThemeIsle SDK
4
+ *
5
+ * @package ThemeIsleSDK
6
+ * @subpackage Modules
7
+ * @copyright Copyright (c) 2017, Marius Cristea
8
+ * @license http://opensource.org/licenses/gpl-3.0.php GNU Public License
9
+ * @since 1.0.0
10
+ */
11
+
12
+ namespace ThemeisleSDK\Modules;
13
+
14
+ use ThemeisleSDK\Common\Abstract_Module;
15
+ use ThemeisleSDK\Product;
16
+
17
+ // Exit if accessed directly.
18
+ if ( ! defined( 'ABSPATH' ) ) {
19
+ exit;
20
+ }
21
+
22
+ /**
23
+ * Translate module for ThemeIsle SDK.
24
+ */
25
+ class Translate extends Abstract_Module {
26
+ /**
27
+ * List of available locales.
28
+ *
29
+ * @var array Array of available locals.
30
+ */
31
+ private static $locales = array(
32
+ 'af' => array(
33
+ 'slug' => 'af',
34
+ 'name' => 'Afrikaans',
35
+ ),
36
+ 'ak' => array(
37
+ 'slug' => 'ak',
38
+ 'name' => 'Akan',
39
+ ),
40
+ 'am' => array(
41
+ 'slug' => 'am',
42
+ 'name' => 'Amharic',
43
+ ),
44
+ 'ar' => array(
45
+ 'slug' => 'ar',
46
+ 'name' => 'Arabic',
47
+ ),
48
+ 'arq' => array(
49
+ 'slug' => 'arq',
50
+ 'name' => 'Algerian Arabic',
51
+ ),
52
+ 'ary' => array(
53
+ 'slug' => 'ary',
54
+ 'name' => 'Moroccan Arabic',
55
+ ),
56
+ 'as' => array(
57
+ 'slug' => 'as',
58
+ 'name' => 'Assamese',
59
+ ),
60
+ 'ast' => array(
61
+ 'slug' => 'ast',
62
+ 'name' => 'Asturian',
63
+ ),
64
+ 'az' => array(
65
+ 'slug' => 'az',
66
+ 'name' => 'Azerbaijani',
67
+ ),
68
+ 'azb' => array(
69
+ 'slug' => 'azb',
70
+ 'name' => 'South Azerbaijani',
71
+ ),
72
+ 'az_TR' => array(
73
+ 'slug' => 'az-tr',
74
+ 'name' => 'Azerbaijani (Turkey)',
75
+ ),
76
+ 'ba' => array(
77
+ 'slug' => 'ba',
78
+ 'name' => 'Bashkir',
79
+ ),
80
+ 'bal' => array(
81
+ 'slug' => 'bal',
82
+ 'name' => 'Catalan (Balear)',
83
+ ),
84
+ 'bcc' => array(
85
+ 'slug' => 'bcc',
86
+ 'name' => 'Balochi Southern',
87
+ ),
88
+ 'bel' => array(
89
+ 'slug' => 'bel',
90
+ 'name' => 'Belarusian',
91
+ ),
92
+ 'bg_BG' => array(
93
+ 'slug' => 'bg',
94
+ 'name' => 'Bulgarian',
95
+ ),
96
+ 'bn_BD' => array(
97
+ 'slug' => 'bn',
98
+ 'name' => 'Bengali',
99
+ ),
100
+ 'bo' => array(
101
+ 'slug' => 'bo',
102
+ 'name' => 'Tibetan',
103
+ ),
104
+ 'bre' => array(
105
+ 'slug' => 'br',
106
+ 'name' => 'Breton',
107
+ ),
108
+ 'bs_BA' => array(
109
+ 'slug' => 'bs',
110
+ 'name' => 'Bosnian',
111
+ ),
112
+ 'ca' => array(
113
+ 'slug' => 'ca',
114
+ 'name' => 'Catalan',
115
+ ),
116
+ 'ceb' => array(
117
+ 'slug' => 'ceb',
118
+ 'name' => 'Cebuano',
119
+ ),
120
+ 'ckb' => array(
121
+ 'slug' => 'ckb',
122
+ 'name' => 'Kurdish (Sorani)',
123
+ ),
124
+ 'co' => array(
125
+ 'slug' => 'co',
126
+ 'name' => 'Corsican',
127
+ ),
128
+ 'cs_CZ' => array(
129
+ 'slug' => 'cs',
130
+ 'name' => 'Czech',
131
+ ),
132
+ 'cy' => array(
133
+ 'slug' => 'cy',
134
+ 'name' => 'Welsh',
135
+ ),
136
+ 'da_DK' => array(
137
+ 'slug' => 'da',
138
+ 'name' => 'Danish',
139
+ ),
140
+ 'de_DE' => array(
141
+ 'slug' => 'de',
142
+ 'name' => 'German',
143
+ ),
144
+ 'de_CH' => array(
145
+ 'slug' => 'de-ch',
146
+ 'name' => 'German (Switzerland)',
147
+ ),
148
+ 'dv' => array(
149
+ 'slug' => 'dv',
150
+ 'name' => 'Dhivehi',
151
+ ),
152
+ 'dzo' => array(
153
+ 'slug' => 'dzo',
154
+ 'name' => 'Dzongkha',
155
+ ),
156
+ 'el' => array(
157
+ 'slug' => 'el',
158
+ 'name' => 'Greek',
159
+ ),
160
+ 'art_xemoji' => array(
161
+ 'slug' => 'art-xemoji',
162
+ 'name' => 'Emoji',
163
+ ),
164
+ 'en_US' => array(
165
+ 'slug' => 'en',
166
+ 'name' => 'English',
167
+ ),
168
+ 'en_AU' => array(
169
+ 'slug' => 'en-au',
170
+ 'name' => 'English (Australia)',
171
+ ),
172
+ 'en_CA' => array(
173
+ 'slug' => 'en-ca',
174
+ 'name' => 'English (Canada)',
175
+ ),
176
+ 'en_GB' => array(
177
+ 'slug' => 'en-gb',
178
+ 'name' => 'English (UK)',
179
+ ),
180
+ 'en_NZ' => array(
181
+ 'slug' => 'en-nz',
182
+ 'name' => 'English (New Zealand)',
183
+ ),
184
+ 'en_ZA' => array(
185
+ 'slug' => 'en-za',
186
+ 'name' => 'English (South Africa)',
187
+ ),
188
+ 'eo' => array(
189
+ 'slug' => 'eo',
190
+ 'name' => 'Esperanto',
191
+ ),
192
+ 'es_ES' => array(
193
+ 'slug' => 'es',
194
+ 'name' => 'Spanish (Spain)',
195
+ ),
196
+ 'es_AR' => array(
197
+ 'slug' => 'es-ar',
198
+ 'name' => 'Spanish (Argentina)',
199
+ ),
200
+ 'es_CL' => array(
201
+ 'slug' => 'es-cl',
202
+ 'name' => 'Spanish (Chile)',
203
+ ),
204
+ 'es_CO' => array(
205
+ 'slug' => 'es-co',
206
+ 'name' => 'Spanish (Colombia)',
207
+ ),
208
+ 'es_CR' => array(
209
+ 'slug' => 'es-cr',
210
+ 'name' => 'Spanish (Costa Rica)',
211
+ ),
212
+ 'es_GT' => array(
213
+ 'slug' => 'es-gt',
214
+ 'name' => 'Spanish (Guatemala)',
215
+ ),
216
+ 'es_MX' => array(
217
+ 'slug' => 'es-mx',
218
+ 'name' => 'Spanish (Mexico)',
219
+ ),
220
+ 'es_PE' => array(
221
+ 'slug' => 'es-pe',
222
+ 'name' => 'Spanish (Peru)',
223
+ ),
224
+ 'es_PR' => array(
225
+ 'slug' => 'es-pr',
226
+ 'name' => 'Spanish (Puerto Rico)',
227
+ ),
228
+ 'es_VE' => array(
229
+ 'slug' => 'es-ve',
230
+ 'name' => 'Spanish (Venezuela)',
231
+ ),
232
+ 'et' => array(
233
+ 'slug' => 'et',
234
+ 'name' => 'Estonian',
235
+ ),
236
+ 'eu' => array(
237
+ 'slug' => 'eu',
238
+ 'name' => 'Basque',
239
+ ),
240
+ 'fa_IR' => array(
241
+ 'slug' => 'fa',
242
+ 'name' => 'Persian',
243
+ ),
244
+ 'fa_AF' => array(
245
+ 'slug' => 'fa-af',
246
+ 'name' => 'Persian (Afghanistan)',
247
+ ),
248
+ 'fuc' => array(
249
+ 'slug' => 'fuc',
250
+ 'name' => 'Fulah',
251
+ ),
252
+ 'fi' => array(
253
+ 'slug' => 'fi',
254
+ 'name' => 'Finnish',
255
+ ),
256
+ 'fo' => array(
257
+ 'slug' => 'fo',
258
+ 'name' => 'Faroese',
259
+ ),
260
+ 'fr_FR' => array(
261
+ 'slug' => 'fr',
262
+ 'name' => 'French (France)',
263
+ ),
264
+ 'fr_BE' => array(
265
+ 'slug' => 'fr-be',
266
+ 'name' => 'French (Belgium)',
267
+ ),
268
+ 'fr_CA' => array(
269
+ 'slug' => 'fr-ca',
270
+ 'name' => 'French (Canada)',
271
+ ),
272
+ 'frp' => array(
273
+ 'slug' => 'frp',
274
+ 'name' => 'Arpitan',
275
+ ),
276
+ 'fur' => array(
277
+ 'slug' => 'fur',
278
+ 'name' => 'Friulian',
279
+ ),
280
+ 'fy' => array(
281
+ 'slug' => 'fy',
282
+ 'name' => 'Frisian',
283
+ ),
284
+ 'ga' => array(
285
+ 'slug' => 'ga',
286
+ 'name' => 'Irish',
287
+ ),
288
+ 'gd' => array(
289
+ 'slug' => 'gd',
290
+ 'name' => 'Scottish Gaelic',
291
+ ),
292
+ 'gl_ES' => array(
293
+ 'slug' => 'gl',
294
+ 'name' => 'Galician',
295
+ ),
296
+ 'gn' => array(
297
+ 'slug' => 'gn',
298
+ 'name' => 'Guaraní',
299
+ ),
300
+ 'gsw' => array(
301
+ 'slug' => 'gsw',
302
+ 'name' => 'Swiss German',
303
+ ),
304
+ 'gu' => array(
305
+ 'slug' => 'gu',
306
+ 'name' => 'Gujarati',
307
+ ),
308
+ 'hat' => array(
309
+ 'slug' => 'hat',
310
+ 'name' => 'Haitian Creole',
311
+ ),
312
+ 'hau' => array(
313
+ 'slug' => 'hau',
314
+ 'name' => 'Hausa',
315
+ ),
316
+ 'haw_US' => array(
317
+ 'slug' => 'haw',
318
+ 'name' => 'Hawaiian',
319
+ ),
320
+ 'haz' => array(
321
+ 'slug' => 'haz',
322
+ 'name' => 'Hazaragi',
323
+ ),
324
+ 'he_IL' => array(
325
+ 'slug' => 'he',
326
+ 'name' => 'Hebrew',
327
+ ),
328
+ 'hi_IN' => array(
329
+ 'slug' => 'hi',
330
+ 'name' => 'Hindi',
331
+ ),
332
+ 'hr' => array(
333
+ 'slug' => 'hr',
334
+ 'name' => 'Croatian',
335
+ ),
336
+ 'hu_HU' => array(
337
+ 'slug' => 'hu',
338
+ 'name' => 'Hungarian',
339
+ ),
340
+ 'hy' => array(
341
+ 'slug' => 'hy',
342
+ 'name' => 'Armenian',
343
+ ),
344
+ 'id_ID' => array(
345
+ 'slug' => 'id',
346
+ 'name' => 'Indonesian',
347
+ ),
348
+ 'ido' => array(
349
+ 'slug' => 'ido',
350
+ 'name' => 'Ido',
351
+ ),
352
+ 'is_IS' => array(
353
+ 'slug' => 'is',
354
+ 'name' => 'Icelandic',
355
+ ),
356
+ 'it_IT' => array(
357
+ 'slug' => 'it',
358
+ 'name' => 'Italian',
359
+ ),
360
+ 'ja' => array(
361
+ 'slug' => 'ja',
362
+ 'name' => 'Japanese',
363
+ ),
364
+ 'jv_ID' => array(
365
+ 'slug' => 'jv',
366
+ 'name' => 'Javanese',
367
+ ),
368
+ 'ka_GE' => array(
369
+ 'slug' => 'ka',
370
+ 'name' => 'Georgian',
371
+ ),
372
+ 'kab' => array(
373
+ 'slug' => 'kab',
374
+ 'name' => 'Kabyle',
375
+ ),
376
+ 'kal' => array(
377
+ 'slug' => 'kal',
378
+ 'name' => 'Greenlandic',
379
+ ),
380
+ 'kin' => array(
381
+ 'slug' => 'kin',
382
+ 'name' => 'Kinyarwanda',
383
+ ),
384
+ 'kk' => array(
385
+ 'slug' => 'kk',
386
+ 'name' => 'Kazakh',
387
+ ),
388
+ 'km' => array(
389
+ 'slug' => 'km',
390
+ 'name' => 'Khmer',
391
+ ),
392
+ 'kn' => array(
393
+ 'slug' => 'kn',
394
+ 'name' => 'Kannada',
395
+ ),
396
+ 'ko_KR' => array(
397
+ 'slug' => 'ko',
398
+ 'name' => 'Korean',
399
+ ),
400
+ 'kir' => array(
401
+ 'slug' => 'kir',
402
+ 'name' => 'Kyrgyz',
403
+ ),
404
+ 'lb_LU' => array(
405
+ 'slug' => 'lb',
406
+ 'name' => 'Luxembourgish',
407
+ ),
408
+ 'li' => array(
409
+ 'slug' => 'li',
410
+ 'name' => 'Limburgish',
411
+ ),
412
+ 'lin' => array(
413
+ 'slug' => 'lin',
414
+ 'name' => 'Lingala',
415
+ ),
416
+ 'lo' => array(
417
+ 'slug' => 'lo',
418
+ 'name' => 'Lao',
419
+ ),
420
+ 'lt_LT' => array(
421
+ 'slug' => 'lt',
422
+ 'name' => 'Lithuanian',
423
+ ),
424
+ 'lv' => array(
425
+ 'slug' => 'lv',
426
+ 'name' => 'Latvian',
427
+ ),
428
+ 'me_ME' => array(
429
+ 'slug' => 'me',
430
+ 'name' => 'Montenegrin',
431
+ ),
432
+ 'mg_MG' => array(
433
+ 'slug' => 'mg',
434
+ 'name' => 'Malagasy',
435
+ ),
436
+ 'mk_MK' => array(
437
+ 'slug' => 'mk',
438
+ 'name' => 'Macedonian',
439
+ ),
440
+ 'ml_IN' => array(
441
+ 'slug' => 'ml',
442
+ 'name' => 'Malayalam',
443
+ ),
444
+ 'mlt' => array(
445
+ 'slug' => 'mlt',
446
+ 'name' => 'Maltese',
447
+ ),
448
+ 'mn' => array(
449
+ 'slug' => 'mn',
450
+ 'name' => 'Mongolian',
451
+ ),
452
+ 'mr' => array(
453
+ 'slug' => 'mr',
454
+ 'name' => 'Marathi',
455
+ ),
456
+ 'mri' => array(
457
+ 'slug' => 'mri',
458
+ 'name' => 'Maori',
459
+ ),
460
+ 'ms_MY' => array(
461
+ 'slug' => 'ms',
462
+ 'name' => 'Malay',
463
+ ),
464
+ 'my_MM' => array(
465
+ 'slug' => 'mya',
466
+ 'name' => 'Myanmar (Burmese)',
467
+ ),
468
+ 'ne_NP' => array(
469
+ 'slug' => 'ne',
470
+ 'name' => 'Nepali',
471
+ ),
472
+ 'nb_NO' => array(
473
+ 'slug' => 'nb',
474
+ 'name' => 'Norwegian (Bokmål)',
475
+ ),
476
+ 'nl_NL' => array(
477
+ 'slug' => 'nl',
478
+ 'name' => 'Dutch',
479
+ ),
480
+ 'nl_BE' => array(
481
+ 'slug' => 'nl-be',
482
+ 'name' => 'Dutch (Belgium)',
483
+ ),
484
+ 'nn_NO' => array(
485
+ 'slug' => 'nn',
486
+ 'name' => 'Norwegian (Nynorsk)',
487
+ ),
488
+ 'oci' => array(
489
+ 'slug' => 'oci',
490
+ 'name' => 'Occitan',
491
+ ),
492
+ 'ory' => array(
493
+ 'slug' => 'ory',
494
+ 'name' => 'Oriya',
495
+ ),
496
+ 'os' => array(
497
+ 'slug' => 'os',
498
+ 'name' => 'Ossetic',
499
+ ),
500
+ 'pa_IN' => array(
501
+ 'slug' => 'pa',
502
+ 'name' => 'Punjabi',
503
+ ),
504
+ 'pl_PL' => array(
505
+ 'slug' => 'pl',
506
+ 'name' => 'Polish',
507
+ ),
508
+ 'pt_BR' => array(
509
+ 'slug' => 'pt-br',
510
+ 'name' => 'Portuguese (Brazil)',
511
+ ),
512
+ 'pt_PT' => array(
513
+ 'slug' => 'pt',
514
+ 'name' => 'Portuguese (Portugal)',
515
+ ),
516
+ 'ps' => array(
517
+ 'slug' => 'ps',
518
+ 'name' => 'Pashto',
519
+ ),
520
+ 'rhg' => array(
521
+ 'slug' => 'rhg',
522
+ 'name' => 'Rohingya',
523
+ ),
524
+ 'ro_RO' => array(
525
+ 'slug' => 'ro',
526
+ 'name' => 'Romanian',
527
+ ),
528
+ 'roh' => array(
529
+ 'slug' => 'roh',
530
+ 'name' => 'Romansh',
531
+ ),
532
+ 'ru_RU' => array(
533
+ 'slug' => 'ru',
534
+ 'name' => 'Russian',
535
+ ),
536
+ 'rue' => array(
537
+ 'slug' => 'rue',
538
+ 'name' => 'Rusyn',
539
+ ),
540
+ 'rup_MK' => array(
541
+ 'slug' => 'rup',
542
+ 'name' => 'Aromanian',
543
+ ),
544
+ 'sah' => array(
545
+ 'slug' => 'sah',
546
+ 'name' => 'Sakha',
547
+ ),
548
+ 'sa_IN' => array(
549
+ 'slug' => 'sa-in',
550
+ 'name' => 'Sanskrit',
551
+ ),
552
+ 'scn' => array(
553
+ 'slug' => 'scn',
554
+ 'name' => 'Sicilian',
555
+ ),
556
+ 'si_LK' => array(
557
+ 'slug' => 'si',
558
+ 'name' => 'Sinhala',
559
+ ),
560
+ 'sk_SK' => array(
561
+ 'slug' => 'sk',
562
+ 'name' => 'Slovak',
563
+ ),
564
+ 'sl_SI' => array(
565
+ 'slug' => 'sl',
566
+ 'name' => 'Slovenian',
567
+ ),
568
+ 'sna' => array(
569
+ 'slug' => 'sna',
570
+ 'name' => 'Shona',
571
+ ),
572
+ 'snd' => array(
573
+ 'slug' => 'snd',
574
+ 'name' => 'Sindhi',
575
+ ),
576
+ 'so_SO' => array(
577
+ 'slug' => 'so',
578
+ 'name' => 'Somali',
579
+ ),
580
+ 'sq' => array(
581
+ 'slug' => 'sq',
582
+ 'name' => 'Albanian',
583
+ ),
584
+ 'sq_XK' => array(
585
+ 'slug' => 'sq-xk',
586
+ 'name' => 'Shqip (Kosovo)',
587
+ ),
588
+ 'sr_RS' => array(
589
+ 'slug' => 'sr',
590
+ 'name' => 'Serbian',
591
+ ),
592
+ 'srd' => array(
593
+ 'slug' => 'srd',
594
+ 'name' => 'Sardinian',
595
+ ),
596
+ 'su_ID' => array(
597
+ 'slug' => 'su',
598
+ 'name' => 'Sundanese',
599
+ ),
600
+ 'sv_SE' => array(
601
+ 'slug' => 'sv',
602
+ 'name' => 'Swedish',
603
+ ),
604
+ 'sw' => array(
605
+ 'slug' => 'sw',
606
+ 'name' => 'Swahili',
607
+ ),
608
+ 'syr' => array(
609
+ 'slug' => 'syr',
610
+ 'name' => 'Syriac',
611
+ ),
612
+ 'szl' => array(
613
+ 'slug' => 'szl',
614
+ 'name' => 'Silesian',
615
+ ),
616
+ 'ta_IN' => array(
617
+ 'slug' => 'ta',
618
+ 'name' => 'Tamil',
619
+ ),
620
+ 'ta_LK' => array(
621
+ 'slug' => 'ta-lk',
622
+ 'name' => 'Tamil (Sri Lanka)',
623
+ ),
624
+ 'tah' => array(
625
+ 'slug' => 'tah',
626
+ 'name' => 'Tahitian',
627
+ ),
628
+ 'te' => array(
629
+ 'slug' => 'te',
630
+ 'name' => 'Telugu',
631
+ ),
632
+ 'tg' => array(
633
+ 'slug' => 'tg',
634
+ 'name' => 'Tajik',
635
+ ),
636
+ 'th' => array(
637
+ 'slug' => 'th',
638
+ 'name' => 'Thai',
639
+ ),
640
+ 'tir' => array(
641
+ 'slug' => 'tir',
642
+ 'name' => 'Tigrinya',
643
+ ),
644
+ 'tl' => array(
645
+ 'slug' => 'tl',
646
+ 'name' => 'Tagalog',
647
+ ),
648
+ 'tr_TR' => array(
649
+ 'slug' => 'tr',
650
+ 'name' => 'Turkish',
651
+ ),
652
+ 'tt_RU' => array(
653
+ 'slug' => 'tt',
654
+ 'name' => 'Tatar',
655
+ ),
656
+ 'tuk' => array(
657
+ 'slug' => 'tuk',
658
+ 'name' => 'Turkmen',
659
+ ),
660
+ 'twd' => array(
661
+ 'slug' => 'twd',
662
+ 'name' => 'Tweants',
663
+ ),
664
+ 'tzm' => array(
665
+ 'slug' => 'tzm',
666
+ 'name' => 'Tamazight (Central Atlas)',
667
+ ),
668
+ 'ug_CN' => array(
669
+ 'slug' => 'ug',
670
+ 'name' => 'Uighur',
671
+ ),
672
+ 'uk' => array(
673
+ 'slug' => 'uk',
674
+ 'name' => 'Ukrainian',
675
+ ),
676
+ 'ur' => array(
677
+ 'slug' => 'ur',
678
+ 'name' => 'Urdu',
679
+ ),
680
+ 'uz_UZ' => array(
681
+ 'slug' => 'uz',
682
+ 'name' => 'Uzbek',
683
+ ),
684
+ 'vi' => array(
685
+ 'slug' => 'vi',
686
+ 'name' => 'Vietnamese',
687
+ ),
688
+ 'wa' => array(
689
+ 'slug' => 'wa',
690
+ 'name' => 'Walloon',
691
+ ),
692
+ 'xho' => array(
693
+ 'slug' => 'xho',
694
+ 'name' => 'Xhosa',
695
+ ),
696
+ 'xmf' => array(
697
+ 'slug' => 'xmf',
698
+ 'name' => 'Mingrelian',
699
+ ),
700
+ 'yor' => array(
701
+ 'slug' => 'yor',
702
+ 'name' => 'Yoruba',
703
+ ),
704
+ 'zh_CN' => array(
705
+ 'slug' => 'zh-cn',
706
+ 'name' => 'Chinese (China)',
707
+ ),
708
+ 'zh_HK' => array(
709
+ 'slug' => 'zh-hk',
710
+ 'name' => 'Chinese (Hong Kong)',
711
+ ),
712
+ 'zh_TW' => array(
713
+ 'slug' => 'zh-tw',
714
+ 'name' => 'Chinese (Taiwan)',
715
+ ),
716
+ 'de_DE_formal' => array(
717
+ 'slug' => 'de/formal',
718
+ 'name' => 'German (Formal)',
719
+ ),
720
+ 'nl_NL_formal' => array(
721
+ 'slug' => 'nl/formal',
722
+ 'name' => 'Dutch (Formal)',
723
+ ),
724
+ 'de_CH_informal' => array(
725
+ 'slug' => 'de-ch/informal',
726
+ 'name' => 'Chinese (Taiwan)',
727
+ ),
728
+ 'pt_PT_ao90' => array(
729
+ 'slug' => 'pt/ao90',
730
+ 'name' => 'Portuguese (Portugal, AO90)',
731
+ ),
732
+ );
733
+
734
+ /**
735
+ * Check if we should load module for this.
736
+ *
737
+ * @param Product $product Product to check.
738
+ *
739
+ * @return bool Should load ?
740
+ */
741
+ public function can_load( $product ) {
742
+ if ( $this->is_from_partner( $product ) ) {
743
+ return false;
744
+ }
745
+ if ( ! $product->is_wordpress_available() ) {
746
+ return false;
747
+ }
748
+
749
+ $lang = $this->get_user_locale();
750
+
751
+ if ( 'en_US' === $lang ) {
752
+ return false;
753
+ }
754
+
755
+ $languages = $this->get_translations( $product );
756
+
757
+ if ( ! is_array( $languages ) ) {
758
+ return false;
759
+ }
760
+
761
+ if ( ! isset( $languages['translations'] ) ) {
762
+ return false;
763
+ }
764
+
765
+ $languages = $languages['translations'];
766
+
767
+ $available = wp_list_pluck( $languages, 'language' );
768
+
769
+ if ( in_array( $lang, $available ) ) {
770
+ return false;
771
+ }
772
+
773
+ if ( ! isset( self::$locales[ $lang ] ) ) {
774
+ return false;
775
+ }
776
+
777
+ return apply_filters( $product->get_slug() . '_sdk_enable_translate', true );
778
+ }
779
+
780
+ /**
781
+ * Get the user's locale.
782
+ */
783
+ private function get_user_locale() {
784
+ global $wp_version;
785
+ if ( version_compare( $wp_version, '4.7.0', '>=' ) ) {
786
+ return get_user_locale();
787
+ }
788
+ $user = wp_get_current_user();
789
+ if ( $user ) {
790
+ $locale = $user->locale;
791
+ }
792
+
793
+ return $locale ? $locale : get_locale();
794
+ }
795
+
796
+ /**
797
+ * Fetch translations from api.
798
+ *
799
+ * @param Product $product Product to check.
800
+ *
801
+ * @return mixed Translation array.
802
+ */
803
+ private function get_translations( $product ) {
804
+ $cache_key = $product->get_key() . '_all_languages';
805
+ $translations = get_transient( $cache_key );
806
+
807
+ if ( false === $translations ) {
808
+ require_once( ABSPATH . 'wp-admin/includes/translation-install.php' );
809
+ $translations = translations_api(
810
+ $product->get_type() . 's',
811
+ array(
812
+ 'slug' => $product->get_slug(),
813
+ 'version' => $product->get_version(),
814
+ )
815
+ );
816
+ set_transient( $cache_key, $translations, WEEK_IN_SECONDS );
817
+ }
818
+
819
+ return $translations;
820
+
821
+ }
822
+
823
+ /**
824
+ * Add notification to queue.
825
+ *
826
+ * @param array $all_notifications Previous notification.
827
+ *
828
+ * @return array All notifications.
829
+ */
830
+ public function add_notification( $all_notifications ) {
831
+
832
+ $lang = $this->get_user_locale();
833
+ $link = $this->get_locale_paths( $lang );
834
+ $language_meta = self::$locales[ $lang ];
835
+
836
+ $heading = apply_filters( $this->product->get_key() . '_feedback_translate_heading', 'Improve {product}' );
837
+ $heading = str_replace(
838
+ array( '{product}' ),
839
+ $this->product->get_friendly_name(),
840
+ $heading
841
+ );
842
+ $message = apply_filters(
843
+ $this->product->get_key() . '_feedback_translation',
844
+ 'Translating <b>{product}</b> into as many languages as possible is a huge project. We still need help with a lot of them, so if you are good at translating into <b>{language}</b>, it would be greatly appreciated.
845
+ The process is easy, and you can join by following the link below!'
846
+ );
847
+
848
+ $message = str_replace(
849
+ [ '{product}', '{language}' ],
850
+ [
851
+ $this->product->get_friendly_name(),
852
+ $language_meta['name'],
853
+ ],
854
+ $message
855
+ );
856
+
857
+ $button_submit = apply_filters( $this->product->get_key() . '_feedback_translate_button_do', 'Ok, I will gladly help.' );
858
+ $button_cancel = apply_filters( $this->product->get_key() . '_feedback_translate_button_cancel', 'No, thanks.' );
859
+
860
+ $all_notifications[] = [
861
+ 'id' => $this->product->get_key() . '_translate_flag',
862
+ 'heading' => $heading,
863
+ 'message' => $message,
864
+ 'ctas' => [
865
+ 'confirm' => [
866
+ 'link' => $link,
867
+ 'text' => $button_submit,
868
+ ],
869
+ 'cancel' => [
870
+ 'link' => '#',
871
+ 'text' => $button_cancel,
872
+ ],
873
+ ],
874
+ ];
875
+
876
+ return $all_notifications;
877
+ }
878
+
879
+ /**
880
+ * Return the locale path.
881
+ *
882
+ * @param string $locale Locale code.
883
+ *
884
+ * @return string Locale path.
885
+ */
886
+ private function get_locale_paths( $locale ) {
887
+ if ( empty( $locale ) ) {
888
+ return '';
889
+ }
890
+
891
+ $slug = isset( self::$locales[ $locale ] ) ? self::$locales[ $locale ]['slug'] : '';
892
+ if ( empty( $slug ) ) {
893
+ return '';
894
+ }
895
+ if ( strpos( $slug, '/' ) === false ) {
896
+ $slug .= '/default';
897
+ }
898
+ $url = 'https://translate.wordpress.org/projects/wp-' . $this->product->get_type() . 's/' . $this->product->get_slug() . '/' . ( $this->product->get_type() === 'plugin' ? 'dev/' : '' ) . $slug . '?filters%5Bstatus%5D=untranslated&sort%5Bby%5D=random';
899
+
900
+ return $url;
901
+ }
902
+
903
+ /**
904
+ * Load module logic.
905
+ *
906
+ * @param Product $product Product to load.
907
+ *
908
+ * @return Translate Module instance.
909
+ */
910
+ public function load( $product ) {
911
+
912
+ $this->product = $product;
913
+
914
+ add_filter( 'themeisle_sdk_registered_notifications', [ $this, 'add_notification' ] );
915
+
916
+ return $this;
917
+ }
918
+ }
vendor/codeinwp/themeisle-sdk/src/Modules/Uninstall_feedback.php ADDED
@@ -0,0 +1,728 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The deactivate feedback model class for ThemeIsle SDK
4
+ *
5
+ * @package ThemeIsleSDK
6
+ * @subpackage Feedback
7
+ * @copyright Copyright (c) 2017, Marius Cristea
8
+ * @license http://opensource.org/licenses/gpl-3.0.php GNU Public License
9
+ * @since 1.0.0
10
+ */
11
+
12
+ namespace ThemeisleSDK\Modules;
13
+
14
+ use ThemeisleSDK\Common\Abstract_Module;
15
+ use ThemeisleSDK\Product;
16
+
17
+ // Exit if accessed directly.
18
+ if ( ! defined( 'ABSPATH' ) ) {
19
+ exit;
20
+ }
21
+
22
+ /**
23
+ * Uninstall feedback module for ThemeIsle SDK.
24
+ */
25
+ class Uninstall_Feedback extends Abstract_Module {
26
+ /**
27
+ * How many seconds before the deactivation window is triggered for themes?
28
+ *
29
+ * @var int Number of days.
30
+ */
31
+ const AUTO_TRIGGER_DEACTIVATE_WINDOW_SECONDS = 3;
32
+ /**
33
+ * How many days before the deactivation window pops up again for the theme?
34
+ *
35
+ * @var int Number of days.
36
+ */
37
+ const PAUSE_DEACTIVATE_WINDOW_DAYS = 100;
38
+ /**
39
+ * Where to send the data.
40
+ *
41
+ * @var string Endpoint url.
42
+ */
43
+ const FEEDBACK_ENDPOINT = 'http://feedback.themeisle.com/wordpress/wp-json/__pirate_feedback_/v1/feedback';
44
+
45
+ /**
46
+ * Default options for plugins.
47
+ *
48
+ * @var array $options_plugin The main options list for plugins.
49
+ */
50
+ private $options_plugin = array(
51
+ 'I found a better plugin' => array(
52
+ 'id' => 3,
53
+ 'type' => 'text',
54
+ 'placeholder' => 'What\'s the plugin\'s name?',
55
+ ),
56
+ 'I could not get the plugin to work' => array(
57
+ 'id' => 4,
58
+ ),
59
+ 'I no longer need the plugin' => array(
60
+ 'id' => 5,
61
+ 'type' => 'textarea',
62
+ 'placeholder' => 'If you could improve one thing about our product, what would it be?',
63
+ ),
64
+ 'It\'s a temporary deactivation. I\'m just debugging an issue.' => array(
65
+ 'id' => 6,
66
+ ),
67
+ );
68
+ /**
69
+ * Default options for theme.
70
+ *
71
+ * @var array $options_theme The main options list for themes.
72
+ */
73
+ private $options_theme = array(
74
+ 'I don\'t know how to make it look like demo' => array(
75
+ 'id' => 7,
76
+ ),
77
+ 'It lacks options' => array(
78
+ 'id' => 8,
79
+ ),
80
+ 'Is not working with a plugin that I need' => array(
81
+ 'id' => 9,
82
+ 'type' => 'text',
83
+ 'placeholder' => 'What is the name of the plugin',
84
+ ),
85
+ 'I want to try a new design, I don\'t like {theme} style' => array(
86
+ 'id' => 10,
87
+ ),
88
+ );
89
+ /**
90
+ * Default other option.
91
+ *
92
+ * @var array $other The other option
93
+ */
94
+ private $other = array(
95
+ 'Other' => array(
96
+ 'id' => 999,
97
+ 'type' => 'textarea',
98
+ 'placeholder' => 'cmon cmon tell us',
99
+ ),
100
+ );
101
+ /**
102
+ * Default heading for plugin.
103
+ *
104
+ * @var string $heading_plugin The heading of the modal
105
+ */
106
+ private $heading_plugin = 'Quick Feedback <span>Because we care about our clients, please leave us feedback.</span>';
107
+ /**
108
+ * Default heading for theme.
109
+ *
110
+ * @var string $heading_theme The heading of the modal
111
+ */
112
+ private $heading_theme = 'Looking to change {theme}? <span> What does not work for you?</span>';
113
+ /**
114
+ * Default submit button action text.
115
+ *
116
+ * @var string $button_submit The text of the deactivate button
117
+ */
118
+ private $button_submit = 'Submit &amp; Deactivate';
119
+ /**
120
+ * Default cancel button.
121
+ *
122
+ * @var string $button_cancel The text of the cancel button
123
+ */
124
+ private $button_cancel = 'Skip &amp; Deactivate';
125
+
126
+ /**
127
+ * Loads the additional resources
128
+ */
129
+ function load_resources() {
130
+ add_thickbox();
131
+
132
+ $id = $this->product->get_key() . '_deactivate';
133
+
134
+ $this->add_css( $this->product->get_type(), $this->product->get_key() );
135
+ $this->add_js( $this->product->get_type(), $this->product->get_key(), '#TB_inline?' . apply_filters( $this->product->get_key() . '_feedback_deactivate_attributes', 'width=600&height=550' ) . '&inlineId=' . $id );
136
+
137
+ echo '<div id="' . $id . '" style="display:none;" class="themeisle-deactivate-box">' . $this->get_html( $this->product->get_type(), $this->product->get_key() ) . '</div>';
138
+ }
139
+
140
+ /**
141
+ * Loads the css
142
+ *
143
+ * @param string $type The type of product.
144
+ * @param string $key The product key.
145
+ */
146
+ function add_css( $type, $key ) {
147
+ $key = esc_attr( $key );
148
+ $suffix = Product::THEME_TYPE === $type ? 'theme-install-php' : 'plugins-php';
149
+ $icon = esc_attr( apply_filters( $this->product->get_slug() . '_uninstall_feedback_icon', '' ) );
150
+ if ( empty( $icon ) ) {
151
+ $icon = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADwAAAA8CAYAAAA6/NlyAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyFpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNi1jMTQyIDc5LjE2MDkyNCwgMjAxNy8wNy8xMy0wMTowNjozOSAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIChXaW5kb3dzKSIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDpDNkVDM0M4RkYxMzMxMUU3OEMyMkQ0NTIxRTVEQ0ZBRiIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDpDNkVDM0M5MEYxMzMxMUU3OEMyMkQ0NTIxRTVEQ0ZBRiI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOkM2RUMzQzhERjEzMzExRTc4QzIyRDQ1MjFFNURDRkFGIiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOkM2RUMzQzhFRjEzMzExRTc4QzIyRDQ1MjFFNURDRkFGIi8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+KBNOswAAFtFJREFUeNrkWwmUXVWV3W/8Y81zkVAhgUwQg00IAYIRGcRuERDSKqALtVEbxRYcGzWIuhatKCYuUXQtERRtFAccQCDtckCZwpRISEIlIXMqlaGGP///ht7n3vd//YRUUkljN718a53U+++//97d95yzz3BvjDAM8fd02May4YndaZhoDErYeu/laCyN8rN16PuDAPA83mcAjjOxd8jcVypydhrlKspCSidlhPIk5T8p9/+PAP8fTrZJaaQ0UFxKiVKk/CvlU5Rk3b0C+gTKFZRvUa75/wJ4EuVcyimU2RGQdkqCkoOBDExjBoJx3Uwm5OlXt4bFrIPgTXSJK+DY59PEO8a5s0mPiEPyfUrwMieh3ED57qsTsJBhoXAOmps+gd6u85AvGtgxQEOmJcfj+vvxDsvS/hzsB5pkgA9QplJuoux59QD2g1ZUvCXhVe+4pnjxJc5gdx8SxTza1jwDY9ntMDdsBlLJQ4O2CTogRs+vBzydFmLCMm98NWl4OvL5O3Hd+09/9p8/iK/9GOjfRHZKpnHZWy7AlbfPRuK918DYTm3H3PHZWrQbVnHKtUBbh201EvSFvHLX0TLlK3ksRLG4HPPmnL7+0vfiaz8EOkwP+aduwPKbZ+DadyzBnVuPBa4nEQf+/hqW0zKvZcqkJoYmi0DTMXo2+cyltiu8oSi+HQrR3UG5+n9Fw6bFmRYJOVehUf/VAsrPacodOPtM3LcmjmPSwMz4cvzXAJEXt6C89gv49rJTcMk3zkdPL8e9e0iTVNHTTziuGTi9D5jF73oaNVg5RnLAjiywagfwp01ybiJufQOOuYMTdf9hg3s5H83oEQIWhYwOMGySf2KNFTjJchW0EMmPKB1KMx2d2LQFGCKtvPD0A1izbitnitcZbrat+T12Fi8i4C5g6y49kDkk7re/RoNtTmo+DiKmFlPupaZPbAPOp3VceSLwYD/fttrFUPlbSNsL+YgtB48QjGKmje+ceBlKlqsATBywIe82sG9TC5OhONqP2wOnucB0wRY13Cn6qQWPYgEtVNZvf8/J3RhnZAprrtjY81qkxHX3jGrtvn8esHgm0wzek6Vf76Y2Q19ncibBmymeM1Mz+H1IS2ji9XfPAuZzAm5+ajLWDn8JKfvymgprQczHyvbpGEh14f2nX89sLyVsehQmbQewKj5GBxtQzMXQ3DvyWcvxz9rPvFf9Fed+ELjnl8Q07To07FyJ3MATCDouxXmL344pO55nmsFs8avMHE8jmH1/puzmkEsarBo7n2dweCbn06YFxJizWJzFErVW5Kwez8m45VTgM08txqqhu5C0HxyDHNIIDSxedCP6Ozk5Bb6rNHzkpCWQTJqlwQcWcgkUh+NXG2b4sf1uSjDGPvQITh98Bh/5F35s6UXTovvR+eaVuPD6O/DRt8bg/uL7CK+nj75mI7DtD0CefhkUopfYkUZtDdyn75Y2kMz+wvtW6s8yMRmCaCLwG2Za6E5ch4xnoMLPZUo2g3uPPQfr25iNFob3U76BpUMTVK2JBLOmP37hU5hE5yzBvbZz2p6lyXYSiH/AvBVLCI/pRvnmG7Fy8nysYtgVEz+jIYPuu7+NSvIe2OfZMIvh4YuQevIRkxYtx6fxd662hkZOzu9257Fk/esZrlaI2arY+PY70d8yhRNZOWKWPobSS4fPFBx37YaeHkwdGrgCqfDWZGveRHAQI6GWje07EXvfRzB/0XzMn0UfzdBnH/oLwrOogTcfS7BbtSaPxL7kfp+aLayliR+nJytDEz8jnsRpDW/F45kVFTfE0rmXo7+VPOqXjygOn0f5qXgk5QnKc9Ty50MVfozbGjqyVFFwIFWM0XkioXPiB8hct9wGfI15Qmo3gnfSb3MZVW4e1SGmHtL8K1u1G1QYciyCflPqPFRK9ouN0/CJM6+LNBtOKA6Lqy6hfJri1H5jWbFUIX9D75597yM/NSWaiwfG4ZeDlpw4ldLvjXO23zOPeYMPw9/HqY5pRj+qg8/1yebYp0ktzwfNDGdgvnvcKnd6P7yKDmcTzLQE7Oc4SMflty1xA21JEyazng8v/4110uDmrrAphBXzdK47kUNYdS7j94ITEI7uhOkEh56sCefsGQ1cEotkIV3+ePKUm856txCXlKCXqLzgMIDfqEowaqQ1YaCv0URrjJyciGHu9k24+k8PsiB1EW8q6rg40S6GzPbZ3bSnOK1xAJZtHrpwmHDM4HODnDbtcAiPetNnb8x1fBFmebnK+oBHKVeOZ9JMBPEfHKDbTrBdKZMZX4gS3TDvmHjvA79BayGDYSONWKo8ce36BNZGgCd3EmyRRDt8BMw8kaNquhXmLC3vrHhOj2GXqp54POUHUVL0hQM1fBXvOjnlGOgm2Arjrcdn5VwHJ2zZggueXYEc4tSOD8vxxupW4zDAJcuaxBDSmUaQzzKS5HXV87cowWFMgWPElBtSHLPGW1I/L64HzGwB75KTjqShrI3JlBprgbnoPz3xONqZrVRoEKYVQrGzmJSkhgJ6PABGBLiPBBW3SJySXHhjJd8rfhiK/CVtF8X1pk3EdP4iL/x36ZOZtUonxClJ3iQ3lqldscQK70tmczj/mRUoE6z8TqolBboKWDqSVeDjabvZ0n7MxCH0A/ytjqyf5msspTCxTpvDEdCmHtZrKYuqgC8VbTe5ot1QZWjyg6ztYNbmzZi+Y5tkViqlNKhdQ4BVw45Dc3Uj0CIHalvuFfsJyuqrMLReAcI6+DGCHsX+AccZRPSR4JCa40bVtF8no4tJ4a7GxXELWLnRDyUBt7DghReQCop8gHFAmhdGPWd7f007ddqu4hLt+gX6vuTJCX4MXnHvlVRzS2lmrfgQxYVROtDg1sb+D6Zql4Y4PsY6ltasAQfanA3Px4xtWyIXqFZd9EXF0KFuw4h2rQioAu3UmbmpQUtiIKHDFKtoQTlb0t+9YkeFFtmNFUNMJw0ydGjUwErH16VNR6/rkT9zJCSJc8tNnjLnkD5rIp3N44TB7UzHx8KI75mcxGiw5XIENgLp2AdoPLq2Tx6aV1qOt01CcUieUTk8w0848SpjXeFUPDvUQmCBAloFK2IyZzC1jlIy8mnqN2bVlDWPlqnVhlwO7SOj/DymjYCARdRgBbA8yHXHfLhewwJW/GSbaJkaDrKwk0m4bXMwujkLv1JSWaJ6vIyoKvJMSWwM6XuVyXWM374kO8FBJknYKYn1T07hKzxyjPbfsE7qWoEyIsxU8SliNvFdZdJ8sctEIVEq1/xXDCVkdVQpOHAk+ZDYVSCQpubIj0w9SDVoQycnTGIwyAcOcBr7mAp6MSS6ephenonsrrX06wzcRJSLmJoMaYD0FpvjINsZbeQhxvAKx5HfiFR7hWltXV9bUtyB45G6YzPMS0scq1XTcFjT8Jiz26r0k4nlVS9ATUJ+jpVKcFgD1/uwvKY4GkeyI6fnbZQgWlt0fSqrDPJ039DgxfSFmkd5/Uk+9DiadSWrfhZjgRxrWohyIY+glFcmboQmgcdYVzTDdJs4KQ0E18RrBGi5KA3vRqb/e2jsLfKxjp5ctxW4mwnRmgHFlZ7y33BMwxHVBDqSlgVwuxF94YU6u/KV8UtzkjE3Yrux0B4qwGHF4kB4U5GmNkoQba21RoGWqI8soMVzHufnN1CaWc/6jh4N73HTSdJoS9TlqIoVdTwkhPH54u+Bg1hbL7zhhfByD8BtciS7AJa3oXD3Ls73ND7Oh7TpqiYtMELolkBkEFmzuqajTDnyYb/6i4NkRAKYZSdBM5pZUWjas0f/KBar8+U6ApNguJevepD3S1oq5WFYjjqT9GOPbiEpZ00KWgLpcVV0p0OE1uE0dHGiCLSBz3osicqyvchk5V1mzb9rJh2pStrdUSDca0buq8ZbZWgvMt4SycejnRgHKYCkiad8VF5C08fOnWPsXGXsGmh+bqTJ/5Gv+4skeOL/uxWJVTMwMuH+f2vnVcCVKMaWYIiKfsf33pLF8EuuKtsrDv1eIkagDTqo8+OSF1Y1vM6MNF5LOJT/Rg5QJPuWGGfNAzoH8rk4EkdxOKGb8uI8+6i1wUHdxKuxdB14N5J7ONCnKEkBRMuo7NXaRtSDluEoYNXzYIxn42KFW2H8mr/9RoD8YAK5bJqG7yGXSMC3rJqGa2YtU1RbnsJacZS9QlyS45vRzETxB3kOcJQAmlnlAC8v6Ya2NaG7saTSTbUSsX2H1mZ3J99i6BaPYYyJpO5Fyvd8zdxn82Ux+nSZBOinOIBG3cEQkgqicCXEZEvSQlm5De6d62CtcMmPDvYNtCh05GXsaGmlm/Pd5aI230hpokBZoeF8+VXA2yX58ALNxYrMOMNhpYJhFv4bWzswbe+gWp4/0JdL+RiGCbplCrVbbeYx91Ya6u2l9jy9hUHFV1NPgISpMuUXPF8VgZ7O8zSBm6MRUdmatITtZa1pE8H+gdHg90xP88yVYw72bGiHR841VdAMsbp7kn5HqJspSsOGNueK1uJW6cvZ0Yr6BWOa9RnfPSU+zbm/vRMX9P91nGIsxMiuBrXkku6kFXhV0FsYn8mufX3UakL7uBFpu8ri0vXYxGvfpbRR+qQ/ymE2+nqhf4TnWzlhLxLwFko+VGwfsHzd3d+OYjamwIp2C2T21cccq0mwluqHKsUs+DV3FJy7BfCDlE+q7ocCW1Ga0H+BZ6YcC+8xs6b9AwHLRO3a1KxCTLo9r8OQaGcX/ZmlJSZz5pv5vR1qbVc3usgT04a+f4R/VxDg414UNH3USjaJ55KvM8Hw6Q4717eiRP5wIt5leoLdqUb0d3VANe/qxik/r/PfX1cbAOTN8F7RqMkSzvA9DVYYkgnBo32TsT3Vwhf44y4/BjTnLRtbMTSQ1pwvaaGQlmRh617UMjwytvovImvDVUJL8LzBlrKGk0CRxSdh9WaGuTSvxwzkMzG8tJYxl2DdCFKoSj0Pz07qow83wygXUQ1Gmp1R5SQx598qwAZ1bwTBZw2/sgu+NmVEJm0z192VTuGxqceypK1gvCpW6ksh602bmrCV4rGiUhqVBN3k+fAwTZOgX1jDV/PdmYzWpLCqG9XTMgFy7lRragkbJKB8EQMbXWxY08yCy1Wldf3CiVS/D594orIaQ1mo7pULCZfHNsfcSxnU+7Sk7RJiA5/+Sf7gzv1MWkyLL//ZSSfirc8/zzwjPKAuHnt5Ujieyf3OXUkMZ1z09mTR0soUUIBX15IlKxOti7nXJyhG3Sq/76kmurx+eNjFjp2NJPE4Gvn8GIz9Jl2UsLmhDQ/PnKUX2eQdQri81w9q95JR8c0xi4wiMjV9l+GX51C7HzUi4hJN28UAj0yZhGe6e3Dqzu3Iwh23G5siMGmrDBdsrNnYgPSuBDoIurWpzCTMZ4IU+a56pRexeFhXaxsoknn3jiSxZyiGQs5BOrTQRgDmAWCrgH8697UYbOZ00BoNy9HRgn4fmrWGrCwobKgDnNAxTmvu0wQ7jdq9WJk1NW3zb9G1cMcpc3Dab7brimmcJpzyKYLu5PAkaR3OGViXt2EPkNASHhqZbCQI3LGDagRRIMuUfNFGJm+xxONAPQspPqNLadXcr8yrHi45ZWeiEXedOo+2WyJ1cGRq+cZSZaTkBtT0V3jh9v04x3SeQpibxxtGRKPSLriaoNtpWgurmnaLJfxqxhRc8WwfXrd9G0Zgjdt3rA6skeWdLEEXGY4ynLgcZ2AoK9SnSa32+9BQnmhT4jxvJcAUn+9EXYvxmkEpavfW+QuxpZ2ESu2GaoVfp6msukbD0FrCRy57Wa8g9p5f0s+eRzi0AIYnhWmZEc94yPTKi0hkvaJpiw5VJE+v7whx0Ysb4Pr2YZeFor6m0riYZRMhNfJvo3wmoJQ6t9DMJKOV0hY6PLcI+uDmW//cBpTxdFcvPn7hBZxAQ2l3LKMz/0jbvoqgfnawBTvLeRvhpVfDSD3Hp3GWStKkdzJGJfaQEeTONYJyl1FxOePD2HT2UnrALrxx5SSUEE60vVYDL3bhEk6cwJIEFuNfV5X7Ri3OH+6pYsoVMvn7Lv5HvNTWBlfiOlSltJl+chOB/htls+ztODjgxbKKx9fGNsFs+gPM9ntZkrK+tEdGjHz3b81ifD7cHZPDObfAbFmJJ2ZmMXVLA07d2oa8mt8j7i++TCa+ZhgyGnhYsuhM/Oqk6YiXmDeY5mBoWt8kwA9QHmYY9BXYcQDbtWEECf3XGoLR8X2QMSgztgT5rvuQ2ngG0ttglRLw3AAfvfZpdIzE8PrVnRhGpa67ZEZtfh0fxwCadZVW9bpRIz8j+nSo60Jdab7rK/Pm4tvzZiNeLA7CjP2ARHUbtfvShNcmEj9JtEWl0J66TZ6S2b4OZmkx06+FLDSVFdRWP8m07QT8nS/NxzmruzEkoGMBUhcW4E4vo9zvIv/LJIKyLLP6SF2Uh9PnofRXF7n7Eyp0WC28fnEOdpeP4tMMQcvjasKc7gqSb8nDag5QfDSO/J8lswoU2K/PnYUbz16wwTGdH5pm7K7QcjZSFGGFJsWOxIrxL8W0Dgp4drSzzVHNSr3Fty3a0jv+ki9BNzHkfHXpPFzy5CTElg0geWlG0yqDcf7HDdjzuVZ0LtuN+Hl5XWyzasrc3ozh25rQ+d1diJ1WrDWbRm5uRebeNLp/NAB7dinaZ2lg9DOt2Ht3E76+YMajSxfM/QFJ7Sem6exToBTYIwcsfxdR7o7ATsw0JFelVg1iuXXzdFy7uEHFT5BtmQUwQlRQejyO+MKC6lQq77HKCAs+ys/FEDtLth/FdP/KLiEYZhnX7yB2ulyXriSvx3i+r1z6ycfmfehtfed/H+1WOc2iIqiCOgrAJC21sYRFLO6LAM+e6Hq0RQ2ULQ99cwy8OdHNCyIs4o0043ce9hQBm6Tt9PB6g4qehpGFPZlAPH52u/X1MAnDzcCeRAMrs7Jy5DoLkYATksoWEyflbyqY7s7n9/WgUIrBdkNNSgKoKkbd+SFIq/6KOP5llPOjnaq7J7QIz/LOzUlY4ODcTmqL3uB06hXYkpR3BGx31V3nfaVQA3Wi+90u1ZVU99ukEIelnt2uvy+45tSpQ6nvXPgAnrrsDlwxaxUrRwsFz8HRHPYBw1+ktv8CA9FC7oSOuBnuYaLcBrvDqHU7jfU6T5LNKwJA9aaCqKMRRDvsOnV3RJp0og11Pa0nSMrRIK9VUtLLE3M6d+Dui36IM57ehqWr3oD+zGRYTFmtowQcQv9HC9Hy6ye42WCfZeDz81NSxFpfVqZbXVU0qsCk5OvV8xdGSyWmdD9oAW5v1I2sjO3ZkL2V1fv90aoidJzypca2cc3Jf8a7pq/CHS8uwJfXnIvthW7FsbI74Uj3Sz9GOScC/fNqDXmQTRXS87mlFARnzYwnll3U1JZFmR7g7dba9Bjh1F4Ot4IKjSUY0vslKzs0CLle3qZ70GLS5c16c4rBqqL8kloN1PsqX9K9aea7+42gHEfaKeLDJz+MNRd/HjedfB+unPYnloQWg4F52Dh8qO8lHk+Jtv+INWSjpp+MarjAYvvnfVNxSXOrlJWP8pY07BaClRLUl//g8Fma7FJqmfVAU3Q9WMfrzFF9ZkdxQ5GTtGoN40lev4cfblVmbST0xBnmI/xHdhcVDo6A8++UlH0+t28qrlxxPVbnZnBOjYOy9OG2Hm6OZPz9/q6EHNG4eTlHuIQaPY7mzN+Yn1N9JMMq0mQ/icquHmpwLa/LXotHVPEalD5EP23l9VUc+fUc9UoOKQU/9x7OLSndelJfHwesckRqtKyVdnLbOjQ4hUPuATP+3v4r3n8LMAAsR90w+kkNLQAAAABJRU5ErkJggg==';
152
+ }
153
+ ?>
154
+ <style type="text/css" id="<?php echo $key; ?>ti-deactivate-css">
155
+ input[name="ti-deactivate-option"] ~ div {
156
+ display: none;
157
+ }
158
+
159
+ input[name="ti-deactivate-option"]:checked ~ div {
160
+ display: block;
161
+ }
162
+
163
+ body.<?php echo $suffix; ?> .<?php echo $key; ?>-container #TB_window.thickbox-loading:before {
164
+ background: none !important;
165
+ }
166
+
167
+ body.<?php echo $suffix; ?> .<?php echo $key; ?>-container #TB_title {
168
+ background: url('<?php echo $icon; ?>') 40px 30px no-repeat;
169
+ border: none;
170
+ box-sizing: border-box;
171
+ color: #373e40;
172
+ font-size: 24px;
173
+ font-weight: 700;
174
+ height: 90px;
175
+ padding: 40px 40px 0 120px;
176
+ text-transform: uppercase;
177
+ width: 100%;
178
+ }
179
+
180
+ body.<?php echo $suffix; ?> .<?php echo $key; ?>-container #<?php echo $key; ?>-info-disclosure-content ul i {
181
+ padding-left: 5px;
182
+ margin: 0 1px;
183
+ }
184
+
185
+ body.<?php echo $suffix; ?> .<?php echo $key; ?>-container #<?php echo $key; ?>-info-disclosure-content ul strong {
186
+ width: 125px;
187
+ display: block;
188
+ margin: 0;
189
+ float: left;
190
+ }
191
+
192
+ body.<?php echo $suffix; ?> .<?php echo $key; ?>-container #<?php echo $key; ?>-info-disclosure-content ul {
193
+ margin-left: 39px;
194
+ margin-top: 2px;
195
+ padding-top: 0px;
196
+ }
197
+
198
+ body.<?php echo $suffix; ?> .<?php echo $key; ?>-container #<?php echo $key; ?>-info-disclosure-content p {
199
+ font-style: italic;
200
+ margin-bottom: 0px;
201
+ }
202
+
203
+ body.<?php echo $suffix; ?> .<?php echo $key; ?>-container #<?php echo $key; ?>-info-disclosure-content {
204
+ display: none;
205
+ }
206
+ body.<?php echo $suffix; ?> .<?php echo $key; ?>-container.<?php echo $key; ?>-container-disc-open #<?php echo $key; ?>-info-disclosure-content {
207
+ display: block;
208
+ position:absolute;
209
+ bottom: 100px;
210
+ }
211
+
212
+ body.<?php echo $suffix; ?> .<?php echo $key; ?>-container.<?php echo $key; ?>-container-disc-open #<?php echo $key; ?>-info-disclosure {
213
+ top: -130px;
214
+ }
215
+
216
+ body.<?php echo $suffix; ?> .<?php echo $key; ?>-container.<?php echo $key; ?>-container-disc-open {
217
+ height: 590px !important;
218
+ }
219
+ body.<?php echo $suffix; ?> .<?php echo $key; ?>-container #<?php echo $key; ?>-info-disclosure {
220
+ position: absolute;
221
+ top: -50px;
222
+ font-size: 13px;
223
+ color: #8d9192;
224
+ font-weight: 400;
225
+ right: 40px;
226
+ }
227
+
228
+ body.<?php echo $suffix; ?> .<?php echo $key; ?>-container div.actions {
229
+ box-sizing: border-box;
230
+ padding: 30px 40px;
231
+ background-color: #eaeaea;
232
+ }
233
+
234
+ body.<?php echo $suffix; ?> .<?php echo $key; ?>-container input.button {
235
+ background: #ec5d60;
236
+ border: none;
237
+ box-shadow: none;
238
+ color: #ffffff;
239
+ font-size: 15px;
240
+ font-weight: 700;
241
+ height: auto;
242
+ line-height: 20px;
243
+ padding: 10px 15px;
244
+ text-transform: uppercase;
245
+ -webkit-transition: 0.3s ease;
246
+ -moz-transition: 0.3s ease;
247
+ -ms-transition: 0.3s ease;
248
+ -o-transition: 0.3s ease;
249
+ transition: 0.3s ease;
250
+ }
251
+
252
+ body.<?php echo $suffix; ?> .<?php echo $key; ?>-container input.button.button-primary {
253
+ background: transparent;
254
+ box-shadow: none;
255
+ color: #8d9192;
256
+ font-weight: 400;
257
+ float: right;
258
+ line-height: 40px;
259
+ padding: 0;
260
+ text-decoration: underline;
261
+ text-shadow: none;
262
+ text-transform: none;
263
+ }
264
+
265
+ body.<?php echo $suffix; ?> .<?php echo $key; ?>-container input.button:hover {
266
+ background: #e83f42;
267
+ }
268
+
269
+ body.<?php echo $suffix; ?> .<?php echo $key; ?>-container input.button.button-primary:hover {
270
+ background: transparent;
271
+ }
272
+
273
+ body.<?php echo $suffix; ?> .<?php echo $key; ?>-container input.button:focus {
274
+ box-shadow: none;
275
+ outline: none;
276
+ }
277
+
278
+ body.<?php echo $suffix; ?> .<?php echo $key; ?>-container input.button:active {
279
+ box-shadow: none;
280
+ transform: translateY(0);
281
+ }
282
+
283
+ body.<?php echo $suffix; ?> .<?php echo $key; ?>-container input.button:disabled {
284
+ cursor: not-allowed;
285
+ }
286
+
287
+ body.<?php echo $suffix; ?> .<?php echo $key; ?>-container input.button.button-primary:hover {
288
+ text-decoration: none;
289
+ }
290
+
291
+ body.<?php echo $suffix; ?> .<?php echo $key; ?>-container div.revive_network-container {
292
+ background-color: #ffffff;
293
+ }
294
+
295
+ body.<?php echo $suffix; ?> .<?php echo $key; ?>-container ul.ti-list {
296
+ margin: 0;
297
+ }
298
+
299
+ body.<?php echo $suffix; ?> .<?php echo $key; ?>-container ul.ti-list li {
300
+ color: #373e40;
301
+ font-size: 13px;
302
+ margin-bottom: 5px;
303
+ }
304
+
305
+ body.<?php echo $suffix; ?> .<?php echo $key; ?>-container ul.ti-list li label {
306
+ margin-left: 10px;
307
+ line-height: 28px;
308
+ font-size: 15px;
309
+ }
310
+
311
+ body.<?php echo $suffix; ?> .<?php echo $key; ?>-container ul.ti-list input[type=radio] {
312
+ margin-top: 1px;
313
+ }
314
+
315
+ body.<?php echo $suffix; ?> .<?php echo $key; ?>-container #TB_ajaxContent {
316
+ box-sizing: border-box;
317
+ height: auto !important;
318
+ padding: 20px 40px;
319
+ width: 100% !important;
320
+ }
321
+
322
+ body.<?php echo $suffix; ?> .<?php echo $key; ?>-container li div textarea {
323
+ padding: 10px 15px;
324
+ width: 100%;
325
+ }
326
+
327
+ body.<?php echo $suffix; ?> .<?php echo $key; ?>-container ul.ti-list li div {
328
+ margin: 10px 30px;
329
+ }
330
+
331
+ .<?php echo $key; ?>-container #TB_title #TB_ajaxWindowTitle {
332
+ box-sizing: border-box;
333
+ display: block;
334
+ float: none;
335
+ font-weight: 700;
336
+ line-height: 1;
337
+ padding: 0;
338
+ text-align: left;
339
+ width: 100%;
340
+ }
341
+
342
+ .<?php echo $key; ?>-container #TB_title #TB_ajaxWindowTitle span {
343
+ color: #8d9192;
344
+ display: block;
345
+ font-size: 15px;
346
+ font-weight: 400;
347
+ margin-top: 5px;
348
+ text-transform: none;
349
+ }
350
+
351
+ body.<?php echo $suffix; ?> .<?php echo $key; ?>-container .actions {
352
+ width: 100%;
353
+ display: block;
354
+ position: absolute;
355
+ left: 0;
356
+ bottom: 0;
357
+ }
358
+
359
+ .theme-install-php .<?php echo $key; ?>-container #TB_closeWindowButton .tb-close-icon:before {
360
+ font-size: 32px;
361
+ }
362
+
363
+ .<?php echo $key; ?>-container #TB_closeWindowButton .tb-close-icon {
364
+ color: #eee;
365
+ }
366
+
367
+ .<?php echo $key; ?>-container #TB_closeWindowButton {
368
+ left: auto;
369
+ right: -5px;
370
+ top: -35px;
371
+ color: #eee;
372
+ }
373
+
374
+ .<?php echo $key; ?>-container #TB_closeWindowButton .tb-close-icon {
375
+ text-align: right;
376
+ line-height: 25px;
377
+ width: 25px;
378
+ height: 25px;
379
+ }
380
+
381
+ .<?php echo $key; ?>-container #TB_closeWindowButton:focus .tb-close-icon {
382
+ box-shadow: none;
383
+ outline: none;
384
+ }
385
+
386
+ .<?php echo $key; ?>-container #TB_closeWindowButton .tb-close-icon:before {
387
+ font: normal 25px dashicons;
388
+ }
389
+
390
+ body.<?php echo $suffix; ?> .<?php echo $key; ?>-container {
391
+ margin: auto !important;
392
+ height: 500px !important;
393
+ top: 0 !important;
394
+ left: 0 !important;
395
+ bottom: 0 !important;
396
+ right: 0 !important;
397
+ width: 600px !important;
398
+ }
399
+ </style>
400
+ <?php
401
+ do_action( $this->product->get_key() . '_uninstall_feedback_after_css' );
402
+ }
403
+
404
+ /**
405
+ * Loads the js.
406
+ *
407
+ * @param string $type The type of product.
408
+ * @param string $key The product key.
409
+ * @param string $src The url that will hijack the deactivate button url.
410
+ */
411
+ function add_js( $type, $key, $src ) {
412
+ $heading = Product::PLUGIN_TYPE === $type ? $this->heading_plugin : str_replace( '{theme}', $this->product->get_name(), $this->heading_theme );
413
+ $key = esc_attr( $key );
414
+ $heading = apply_filters( $this->product->get_key() . '_feedback_deactivate_heading', $heading );
415
+ ?>
416
+ <script type="text/javascript" id="ti-deactivate-js">
417
+ (function ($) {
418
+ $(document).ready(function () {
419
+ var auto_trigger = false;
420
+ var target_element = 'tr[data-plugin^="<?php echo $this->product->get_slug(); ?>/"] span.deactivate a';
421
+ <?php
422
+ if ( 'theme' === $type ) {
423
+ ?>
424
+ auto_trigger = true;
425
+ if ($('a.ti-auto-anchor').length == 0) {
426
+ $('body').append($('<a class="ti-auto-anchor" href=""></a>'));
427
+ }
428
+ target_element = 'a.ti-auto-anchor';
429
+ <?php
430
+ }
431
+ ?>
432
+
433
+ if (auto_trigger) {
434
+ setTimeout(function () {
435
+ $('a.ti-auto-anchor').trigger('click');
436
+ }, <?php echo self::AUTO_TRIGGER_DEACTIVATE_WINDOW_SECONDS * 1000; ?> );
437
+ }
438
+ $(document).on('thickbox:removed', function () {
439
+ $.post(ajaxurl, {
440
+ 'action': '<?php echo $key . '_uninstall_feedback'; ?>',
441
+ 'nonce': '<?php echo wp_create_nonce( (string) __CLASS__ ); ?>',
442
+ 'type': '<?php echo $type; ?>',
443
+ 'key': '<?php echo $key; ?>'
444
+ });
445
+ });
446
+ var href = $(target_element).attr('href');
447
+ $('#<?php echo $key; ?>ti-deactivate-no').attr('data-ti-action', href).on('click', function (e) {
448
+ e.preventDefault();
449
+ e.stopPropagation();
450
+
451
+ $('body').unbind('thickbox:removed');
452
+ tb_remove();
453
+ var redirect = $(this).attr('data-ti-action');
454
+ if (redirect !== '') {
455
+ location.href = redirect;
456
+ }
457
+ });
458
+
459
+ $('#<?php echo $key; ?> ul.ti-list label, #<?php echo $key; ?> ul.ti-list input[name="ti-deactivate-option"]').on('click', function (e) {
460
+ $('#<?php echo $key; ?>ti-deactivate-yes').val($('#<?php echo $key; ?>ti-deactivate-yes').attr('data-after-text'));
461
+
462
+ var radio = $(this).prop('tagName') === 'LABEL' ? $(this).parent() : $(this);
463
+ if (radio.parent().find('textarea').length > 0 && radio.parent().find('textarea').val().length === 0) {
464
+ $('#<?php echo $key; ?>ti-deactivate-yes').attr('disabled', 'disabled');
465
+ radio.parent().find('textarea').on('keyup', function (ee) {
466
+ if ($(this).val().length === 0) {
467
+ $('#<?php echo $key; ?>ti-deactivate-yes').attr('disabled', 'disabled');
468
+ } else {
469
+ $('#<?php echo $key; ?>ti-deactivate-yes').removeAttr('disabled');
470
+ }
471
+ });
472
+ } else {
473
+ $('#<?php echo $key; ?>ti-deactivate-yes').removeAttr('disabled');
474
+ }
475
+ });
476
+ $("#<?php echo $key; ?>-info-disclosure").on('click', function () {
477
+ $("#TB_window").toggleClass("<?php echo $key; ?>-container-disc-open");
478
+ return false;
479
+ });
480
+ $('#<?php echo $key; ?>ti-deactivate-yes').attr('data-ti-action', href).on('click', function (e) {
481
+ e.preventDefault();
482
+ e.stopPropagation();
483
+ $.post(ajaxurl, {
484
+ 'action': '<?php echo $key . '_uninstall_feedback'; ?>',
485
+ 'nonce': '<?php echo wp_create_nonce( (string) __CLASS__ ); ?>',
486
+ 'id': $('#<?php echo $key; ?> input[name="ti-deactivate-option"]:checked').parent().attr('ti-option-id'),
487
+ 'msg': $('#<?php echo $key; ?> input[name="ti-deactivate-option"]:checked').parent().find('textarea').val(),
488
+ 'type': '<?php echo $type; ?>',
489
+ });
490
+ var redirect = $(this).attr('data-ti-action');
491
+ if (redirect != '') {
492
+ location.href = redirect;
493
+ } else {
494
+ $('body').unbind('thickbox:removed');
495
+ tb_remove();
496
+ }
497
+ });
498
+
499
+ $(target_element).attr('name', '<?php echo wp_kses( $heading, array( 'span' => array() ) ); ?>').attr('href', '<?php echo $src; ?>').addClass('thickbox');
500
+ var thicbox_timer;
501
+ $(target_element).on('click', function () {
502
+ tiBindThickbox();
503
+ });
504
+
505
+ function tiBindThickbox() {
506
+ var thicbox_timer = setTimeout(function () {
507
+ if ($("#<?php echo esc_html( $key ); ?>").is(":visible")) {
508
+ $("body").trigger('thickbox:iframe:loaded');
509
+ $("#TB_window").addClass("<?php echo $key; ?>-container");
510
+ clearTimeout(thicbox_timer);
511
+ $('body').unbind('thickbox:removed');
512
+ } else {
513
+ tiBindThickbox();
514
+ }
515
+ }, 100);
516
+ }
517
+ });
518
+ })(jQuery);
519
+ </script>
520
+ <?php
521
+
522
+ do_action( $this->product->get_key() . '_uninstall_feedback_after_js' );
523
+ }
524
+
525
+ /**
526
+ * Generates the HTML.
527
+ *
528
+ * @param string $type The type of product.
529
+ * @param string $key The product key.
530
+ */
531
+ function get_html( $type, $key ) {
532
+ $options = Product::PLUGIN_TYPE === $type ? $this->options_plugin : $this->options_theme;
533
+ $button_cancel = Product::PLUGIN_TYPE === $type ? $this->button_cancel : 'Skip';
534
+ $button_submit = Product::PLUGIN_TYPE === $type ? $this->button_submit : 'Submit';
535
+ $options = $this->randomize_options( apply_filters( $this->product->get_key() . '_feedback_deactivate_options', $options ) );
536
+ $button_submit = apply_filters( $this->product->get_key() . '_feedback_deactivate_button_submit', $button_submit );
537
+ $button_cancel = apply_filters( $this->product->get_key() . '_feedback_deactivate_button_cancel', $button_cancel );
538
+
539
+ $options += $this->other;
540
+
541
+ $list = '';
542
+ foreach ( $options as $title => $attributes ) {
543
+ $id = $attributes['id'];
544
+ $list .= '<li ti-option-id="' . $id . '"><input type="radio" name="ti-deactivate-option" id="' . $key . $id . '"><label for="' . $key . $id . '">' . str_replace( '{theme}', $this->product->get_name(), $title ) . '</label>';
545
+ if ( array_key_exists( 'type', $attributes ) ) {
546
+ $list .= '<div>';
547
+ $placeholder = array_key_exists( 'placeholder', $attributes ) ? $attributes['placeholder'] : '';
548
+ switch ( $attributes['type'] ) {
549
+ case 'text':
550
+ $list .= '<textarea style="width: 100%" rows="1" name="comments" placeholder="' . $placeholder . '"></textarea>';
551
+ break;
552
+ case 'textarea':
553
+ $list .= '<textarea style="width: 100%" rows="2" name="comments" placeholder="' . $placeholder . '"></textarea>';
554
+ break;
555
+ }
556
+ $list .= '</div>';
557
+ }
558
+ $list .= '</li>';
559
+ }
560
+
561
+ $disclosure_new_labels = apply_filters( $this->product->get_slug() . '_themeisle_sdk_disclosure_content_labels', [], $this->product );
562
+ $disclosure_labels = array_merge(
563
+ [
564
+ 'title' => 'Below is a detailed view of all data that ThemeIsle will receive if you fill in this survey. No domain name, email address or IP addresses are transmited after you submit the survey.',
565
+ 'items' => [
566
+ sprintf( '%s %s version %s %s %s %s', '<strong>', ucwords( $this->product->get_type() ), '</strong>', '<code>', $this->product->get_version(), '</code>' ),
567
+ sprintf( '%s Uninstall reason %s %s Selected reson from the above survey %s ', '<strong>', '</strong>', '<i>', '</i>' ),
568
+ ],
569
+ ],
570
+ $disclosure_new_labels
571
+ );
572
+
573
+ $info_disclosure_link = '<a href="#" id="' . $this->product->get_key() . '-info-disclosure">' . apply_filters( $this->product->get_slug() . '_themeisle_sdk_info_collect_cta', 'What info do we collect?' ) . '</a>';
574
+ $info_disclosure_content = '<div id="' . $this->product->get_key() . '-info-disclosure-content"><p>' . wp_kses_post( $disclosure_labels['title'] ) . '</p><ul>';
575
+ foreach ( $disclosure_labels['items'] as $disclosure_item ) {
576
+ $info_disclosure_content .= sprintf( '<li>%s</li>', wp_kses_post( $disclosure_item ) );
577
+ }
578
+ $info_disclosure_content .= '</ul></div>';
579
+
580
+ return
581
+ '<div id="' . $this->product->get_key() . '"><ul class="ti-list">' . $list . '</ul>'
582
+ . $info_disclosure_content
583
+ . '<div class="actions">'
584
+ . get_submit_button(
585
+ $button_submit,
586
+ 'secondary',
587
+ $this->product->get_key() . 'ti-deactivate-yes',
588
+ false,
589
+ array(
590
+ 'data-after-text' => $button_submit,
591
+ 'disabled' => true,
592
+ )
593
+ )
594
+ . wp_kses_post( $info_disclosure_link )
595
+ . get_submit_button( $button_cancel, 'primary', $this->product->get_key() . 'ti-deactivate-no', false )
596
+ . '</div></div>';
597
+ }
598
+
599
+ /**
600
+ * Randomizes the options array.
601
+ *
602
+ * @param array $options The options array.
603
+ */
604
+ function randomize_options( $options ) {
605
+ $new = array();
606
+ $keys = array_keys( $options );
607
+ shuffle( $keys );
608
+
609
+ foreach ( $keys as $key ) {
610
+ $new[ $key ] = $options[ $key ];
611
+ }
612
+
613
+ return $new;
614
+ }
615
+
616
+ /**
617
+ * Called when the deactivate button is clicked.
618
+ */
619
+ function post_deactivate() {
620
+ check_ajax_referer( (string) __CLASS__, 'nonce' );
621
+
622
+ $this->post_deactivate_or_cancel();
623
+
624
+ if ( empty( $_POST['id'] ) ) {
625
+
626
+ wp_send_json( [] );
627
+
628
+ return;
629
+ }
630
+ $this->call_api(
631
+ array(
632
+ 'type' => 'deactivate',
633
+ 'id' => $_POST['id'],
634
+ 'comment' => isset( $_POST['msg'] ) ? $_POST['msg'] : '',
635
+ )
636
+ );
637
+ wp_send_json( [] );
638
+
639
+ }
640
+
641
+ /**
642
+ * Called when the deactivate/cancel button is clicked.
643
+ */
644
+ private function post_deactivate_or_cancel() {
645
+ if ( ! isset( $_POST['type'] ) || ! isset( $_POST['key'] ) ) {
646
+ return;
647
+ }
648
+ if ( 'theme' !== $_POST['type'] ) {
649
+ return;
650
+ }
651
+
652
+ set_transient( 'ti_sdk_pause_' . $_POST['key'], true, self::PAUSE_DEACTIVATE_WINDOW_DAYS * DAY_IN_SECONDS );
653
+
654
+ }
655
+
656
+ /**
657
+ * Calls the API
658
+ *
659
+ * @param array $attributes The attributes of the post body.
660
+ *
661
+ * @return bool Is the request succesfull?
662
+ */
663
+ protected function call_api( $attributes ) {
664
+ $slug = $this->product->get_slug();
665
+ $version = $this->product->get_version();
666
+ $attributes['slug'] = $slug;
667
+ $attributes['version'] = $version;
668
+
669
+ $response = wp_remote_post(
670
+ self::FEEDBACK_ENDPOINT,
671
+ array(
672
+ 'body' => $attributes,
673
+ )
674
+ );
675
+
676
+ return is_wp_error( $response );
677
+ }
678
+
679
+ /**
680
+ * Should we load this object?.
681
+ *
682
+ * @param Product $product Product object.
683
+ *
684
+ * @return bool Should we load the module?
685
+ */
686
+ public function can_load( $product ) {
687
+ if ( $this->is_from_partner( $product ) ) {
688
+ return false;
689
+ }
690
+ if ( $product->is_theme() && ( false !== get_transient( 'ti_sdk_pause_' . $product->get_key(), false ) ) ) {
691
+ return false;
692
+ }
693
+
694
+ if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) {
695
+ return true;
696
+ }
697
+ global $pagenow;
698
+
699
+ if ( ! isset( $pagenow ) || empty( $pagenow ) ) {
700
+ return false;
701
+ }
702
+
703
+ if ( $product->is_plugin() && 'plugins.php' !== $pagenow ) {
704
+ return false;
705
+
706
+ }
707
+ if ( $product->is_theme() && 'theme-install.php' !== $pagenow ) {
708
+ return false;
709
+ }
710
+
711
+ return true;
712
+ }
713
+
714
+ /**
715
+ * Loads module hooks.
716
+ *
717
+ * @param Product $product Product details.
718
+ *
719
+ * @return Uninstall_Feedback Current module instance.
720
+ */
721
+ public function load( $product ) {
722
+ $this->product = $product;
723
+ add_action( 'admin_head', array( $this, 'load_resources' ) );
724
+ add_action( 'wp_ajax_' . $this->product->get_key() . '_uninstall_feedback', array( $this, 'post_deactivate' ) );
725
+
726
+ return $this;
727
+ }
728
+ }
vendor/codeinwp/themeisle-sdk/src/Product.php ADDED
@@ -0,0 +1,396 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The product model class for ThemeIsle SDK
4
+ *
5
+ * @package ThemeIsleSDK
6
+ * @subpackage Product
7
+ * @copyright Copyright (c) 2017, Marius Cristea
8
+ * @license http://opensource.org/licenses/gpl-3.0.php GNU Public License
9
+ * @since 1.0.0
10
+ */
11
+
12
+ namespace ThemeisleSDK;
13
+
14
+ // Exit if accessed directly.
15
+ if ( ! defined( 'ABSPATH' ) ) {
16
+ exit;
17
+ }
18
+
19
+ /**
20
+ * Product model for ThemeIsle SDK.
21
+ */
22
+ class Product {
23
+ /**
24
+ * Define plugin type string.
25
+ */
26
+ const PLUGIN_TYPE = 'plugin';
27
+ /**
28
+ * Define theme type string.
29
+ */
30
+ const THEME_TYPE = 'theme';
31
+ /**
32
+ * If the product has a pro version, contains the pro slug.
33
+ *
34
+ * @var string $pro_slug Pro slug, if available.
35
+ */
36
+ public $pro_slug;
37
+ /**
38
+ * Current product slug.
39
+ *
40
+ * @var string $slug THe product slug.
41
+ */
42
+ private $slug;
43
+ /**
44
+ * Product basefile, with the proper metadata.
45
+ *
46
+ * @var string $basefile The file with headers.
47
+ */
48
+ private $basefile;
49
+ /**
50
+ * Type of the product.
51
+ *
52
+ * @var string $type The product type ( plugin | theme ).
53
+ */
54
+ private $type;
55
+ /**
56
+ * The file name.
57
+ *
58
+ * @var string $file The file name.
59
+ */
60
+ private $file;
61
+ /**
62
+ * Product name, fetched from the file headers.
63
+ *
64
+ * @var string $name The product name.
65
+ */
66
+ private $name;
67
+ /**
68
+ * Product normalized key.
69
+ *
70
+ * @var string $key The product ready key.
71
+ */
72
+ private $key;
73
+ /**
74
+ * Product store url.
75
+ *
76
+ * @var string $store_url The store url.
77
+ */
78
+ private $store_url;
79
+ /**
80
+ * Product install timestamp.
81
+ *
82
+ * @var int $install The date of install.
83
+ */
84
+ private $install;
85
+ /**
86
+ * Product store/author name.
87
+ *
88
+ * @var string $store_name The store name.
89
+ */
90
+ private $store_name;
91
+ /**
92
+ * Does the product requires license.
93
+ *
94
+ * @var bool $requires_license Either user needs to activate it with license.
95
+ */
96
+ private $requires_license;
97
+ /**
98
+ * Is the product available on wordpress.org
99
+ *
100
+ * @var bool $wordpress_available Either is available on WordPress or not.
101
+ */
102
+ private $wordpress_available;
103
+ /**
104
+ * Current version of the product.
105
+ *
106
+ * @var string $version The product version.
107
+ */
108
+ private $version;
109
+
110
+ /**
111
+ * ThemeIsle_SDK_Product constructor.
112
+ *
113
+ * @param string $basefile Product basefile.
114
+ */
115
+ public function __construct( $basefile ) {
116
+ if ( ! empty( $basefile ) ) {
117
+ if ( is_readable( $basefile ) ) {
118
+ $this->basefile = $basefile;
119
+ $this->setup_from_path();
120
+ $this->setup_from_fileheaders();
121
+ }
122
+ }
123
+ $install = get_option( $this->get_key() . '_install', 0 );
124
+ if ( 0 === $install ) {
125
+ $install = time();
126
+ update_option( $this->get_key() . '_install', time() );
127
+ }
128
+ $this->install = $install;
129
+
130
+ }
131
+
132
+ /**
133
+ * Setup props from path.
134
+ */
135
+ public function setup_from_path() {
136
+ $this->file = basename( $this->basefile );
137
+ $dir = dirname( $this->basefile );
138
+ $this->slug = basename( $dir );
139
+ $exts = explode( '.', $this->basefile );
140
+ $ext = $exts[ count( $exts ) - 1 ];
141
+ if ( 'css' === $ext ) {
142
+ $this->type = 'theme';
143
+ }
144
+ if ( 'php' === $ext ) {
145
+ $this->type = 'plugin';
146
+ }
147
+ $this->key = self::key_ready_name( $this->slug );
148
+ }
149
+
150
+ /**
151
+ * Normalize string.
152
+ *
153
+ * @param string $string the String to be normalized for cron handler.
154
+ *
155
+ * @return string $name The normalized string.
156
+ */
157
+ static function key_ready_name( $string ) {
158
+ return str_replace( '-', '_', strtolower( trim( $string ) ) );
159
+ }
160
+
161
+ /**
162
+ * Setup props from fileheaders.
163
+ */
164
+ public function setup_from_fileheaders() {
165
+ $file_headers = array(
166
+ 'Requires License' => 'Requires License',
167
+ 'WordPress Available' => 'WordPress Available',
168
+ 'Pro Slug' => 'Pro Slug',
169
+ 'Version' => 'Version',
170
+ );
171
+ if ( 'plugin' === $this->type ) {
172
+ $file_headers['Name'] = 'Plugin Name';
173
+ $file_headers['AuthorName'] = 'Author';
174
+ $file_headers['AuthorURI'] = 'Author URI';
175
+ }
176
+ if ( 'theme' === $this->type ) {
177
+ $file_headers['Name'] = 'Theme Name';
178
+ $file_headers['AuthorName'] = 'Author';
179
+ $file_headers['AuthorURI'] = 'Author URI';
180
+ }
181
+ $file_headers = get_file_data( $this->basefile, $file_headers );
182
+
183
+ $this->name = $file_headers['Name'];
184
+ $this->store_name = $file_headers['AuthorName'];
185
+ $this->author_url = $file_headers['AuthorURI'];
186
+ $this->store_url = $file_headers['AuthorURI'];
187
+
188
+ $this->requires_license = ( 'yes' === $file_headers['Requires License'] ) ? true : false;
189
+ $this->wordpress_available = ( 'yes' === $file_headers['WordPress Available'] ) ? true : false;
190
+ $this->pro_slug = ! empty( $file_headers['Pro Slug'] ) ? $file_headers['Pro Slug'] : '';
191
+ $this->version = $file_headers['Version'];
192
+
193
+ }
194
+
195
+ /**
196
+ * Return the product key.
197
+ *
198
+ * @return string The product key.
199
+ */
200
+ public function get_key() {
201
+ return $this->key;
202
+ }
203
+ /**
204
+ * Check if the product is either theme or plugin.
205
+ *
206
+ * @return string Product type.
207
+ */
208
+ public function get_type() {
209
+ return $this->type;
210
+ }
211
+
212
+ /**
213
+ * Return if the product is used as a plugin.
214
+ *
215
+ * @return bool Is plugin?
216
+ */
217
+ public function is_plugin() {
218
+ return self::PLUGIN_TYPE === $this->type;
219
+ }
220
+
221
+ /**
222
+ * Return if the product is used as a theme.
223
+ *
224
+ * @return bool Is theme ?
225
+ */
226
+ public function is_theme() {
227
+ return self::THEME_TYPE === $this->type;
228
+ }
229
+
230
+ /**
231
+ * Returns the product slug.
232
+ *
233
+ * @return string The product slug.
234
+ */
235
+ public function get_slug() {
236
+ return $this->slug;
237
+ }
238
+
239
+ /**
240
+ * The magic var_dump info method.
241
+ *
242
+ * @return array Debug info.
243
+ */
244
+ public function __debugInfo() {
245
+ return array(
246
+ 'name' => $this->name,
247
+ 'slug' => $this->slug,
248
+ 'version' => $this->version,
249
+ 'basefile' => $this->basefile,
250
+ 'key' => $this->key,
251
+ 'type' => $this->type,
252
+ 'store_name' => $this->store_name,
253
+ 'store_url' => $this->store_url,
254
+ 'wordpress_available' => $this->wordpress_available,
255
+ 'requires_license' => $this->requires_license,
256
+ );
257
+
258
+ }
259
+
260
+ /**
261
+ * Getter for product version.
262
+ *
263
+ * @return string The product version.
264
+ */
265
+ public function get_version() {
266
+ return $this->version;
267
+ }
268
+
269
+ /**
270
+ * Returns current product license, if available.
271
+ *
272
+ * @return string Return license key, if available.
273
+ */
274
+ public function get_license() {
275
+
276
+ if ( ! $this->requires_license() && ! $this->is_wordpress_available() ) {
277
+ return 'free';
278
+ }
279
+ $license_data = get_option( $this->get_key() . '_license_data', '' );
280
+
281
+ if ( empty( $license_data ) ) {
282
+ return get_option( $this->get_key() . '_license', '' );
283
+ }
284
+ if ( ! isset( $license_data->key ) ) {
285
+ return get_option( $this->get_key() . '_license', '' );
286
+ }
287
+
288
+ return $license_data->key;
289
+ }
290
+
291
+ /**
292
+ * Either the product requires license or not.
293
+ *
294
+ * @return bool Either requires license or not.
295
+ */
296
+ public function requires_license() {
297
+ return $this->requires_license;
298
+ }
299
+
300
+ /**
301
+ * If product is available on wordpress.org or not.
302
+ *
303
+ * @return bool Either is wp available or not.
304
+ */
305
+ public function is_wordpress_available() {
306
+ return $this->wordpress_available;
307
+ }
308
+
309
+ /**
310
+ * Return friendly name.
311
+ *
312
+ * @return string Friendly name.
313
+ */
314
+ public function get_friendly_name() {
315
+ $name = apply_filters( $this->get_key() . '_friendly_name', trim( str_replace( 'Lite', '', $this->get_name() ) ) );
316
+ $name = rtrim( $name, '- ()' );
317
+
318
+ return $name;
319
+ }
320
+
321
+ /**
322
+ * Getter for product name.
323
+ *
324
+ * @return string The product name.
325
+ */
326
+ public function get_name() {
327
+ return $this->name;
328
+ }
329
+
330
+ /**
331
+ * Returns the Store name.
332
+ *
333
+ * @return string Store name.
334
+ */
335
+ public function get_store_name() {
336
+ return $this->store_name;
337
+ }
338
+
339
+ /**
340
+ * Returns the store url.
341
+ *
342
+ * @return string The store url.
343
+ */
344
+ public function get_store_url() {
345
+ return $this->store_url;
346
+ }
347
+
348
+ /**
349
+ * Returns product basefile, which holds the metaheaders.
350
+ *
351
+ * @return string The product basefile.
352
+ */
353
+ public function get_basefile() {
354
+ return $this->basefile;
355
+ }
356
+
357
+ /**
358
+ * Returns product filename.
359
+ *
360
+ * @return string The product filename.
361
+ */
362
+ public function get_file() {
363
+ return $this->file;
364
+ }
365
+ /**
366
+ * Returns the pro slug, if available.
367
+ *
368
+ * @return string The pro slug.
369
+ */
370
+ public function get_pro_slug() {
371
+ return $this->pro_slug;
372
+ }
373
+
374
+ /**
375
+ * Return the install timestamp.
376
+ *
377
+ * @return int The install timestamp.
378
+ */
379
+ public function get_install_time() {
380
+ return $this->install;
381
+ }
382
+
383
+ /**
384
+ * Returns the URL of the product base file.
385
+ *
386
+ * @param string $path The path to the file.
387
+ *
388
+ * @return string The URL of the product base file.
389
+ */
390
+ public function get_base_url( $path = '/' ) {
391
+ if ( $this->type ) {
392
+ return plugins_url( $path, $this->basefile );
393
+ }
394
+ }
395
+
396
+ }
vendor/codeinwp/themeisle-sdk/start.php CHANGED
@@ -7,32 +7,43 @@
7
  * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
8
  * @since 1.1.0
9
  */
 
 
 
 
 
 
10
  $products = apply_filters( 'themeisle_sdk_products', array() );
11
  $path = dirname( __FILE__ );
12
- $files_to_load = array(
13
- 'class-themeisle-sdk-loader.php',
14
- 'class-themeisle-sdk-product.php',
15
- 'class-themeisle-sdk-logger.php',
16
- 'class-themeisle-sdk-licenser.php',
17
- 'class-themeisle-sdk-rollback.php',
18
- 'class-themeisle-sdk-feedback-factory.php',
19
- 'class-themeisle-sdk-feedback.php',
20
- 'class-themeisle-sdk-feedback-deactivate.php',
21
- 'class-themeisle-sdk-feedback-review.php',
22
- 'class-themeisle-sdk-feedback-translate.php',
23
- 'class-themeisle-sdk-notification-manager.php',
24
- 'class-themeisle-sdk-widget.php',
25
- 'class-themeisle-sdk-widget-dashboard-blog.php',
26
- 'class-themeisle-sdk-widgets-factory.php',
27
- 'class-themeisle-sdk-endpoints.php',
28
- );
 
 
 
29
 
30
  foreach ( $files_to_load as $file ) {
31
- $file_path = $path . '/' . $file;
32
- if ( is_readable( $file_path ) ) {
33
- require_once $file_path;
34
  }
35
  }
 
 
 
36
  foreach ( $products as $product ) {
37
- ThemeIsle_SDK_Loader::init_product( $product );
38
  }
7
  * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
8
  * @since 1.1.0
9
  */
10
+
11
+ namespace ThemeisleSDK;
12
+
13
+ if ( ! defined( 'ABSPATH' ) ) {
14
+ exit;
15
+ }
16
  $products = apply_filters( 'themeisle_sdk_products', array() );
17
  $path = dirname( __FILE__ );
18
+ $files_to_load = [
19
+ $path . '/src/' . 'Loader.php',
20
+ $path . '/src/' . 'Product.php',
21
+
22
+ $path . '/src/' . 'Common/Abstract_module.php',
23
+ $path . '/src/' . 'Common/Module_factory.php',
24
+
25
+ $path . '/src/' . 'Modules/Dashboard_widget.php',
26
+ $path . '/src/' . 'Modules/Rollback.php',
27
+ $path . '/src/' . 'Modules/Uninstall_feedback.php',
28
+ $path . '/src/' . 'Modules/Licenser.php',
29
+ $path . '/src/' . 'Modules/Endpoint.php',
30
+ $path . '/src/' . 'Modules/Notification.php',
31
+ $path . '/src/' . 'Modules/Logger.php',
32
+ $path . '/src/' . 'Modules/Translate.php',
33
+ $path . '/src/' . 'Modules/Review.php',
34
+ $path . '/src/' . 'Modules/Recommendation.php',
35
+ ];
36
+
37
+ $files_to_load = array_merge( $files_to_load, apply_filters( 'themeisle_sdk_required_files', [] ) );
38
 
39
  foreach ( $files_to_load as $file ) {
40
+ if ( is_readable( $file ) ) {
41
+ require_once $file;
 
42
  }
43
  }
44
+
45
+ Loader::init();
46
+
47
  foreach ( $products as $product ) {
48
+ Loader::add_product( $product );
49
  }
vendor/composer/autoload_files.php CHANGED
@@ -9,6 +9,6 @@ return array(
9
  '62bc7c35996f19a64625f7ff3ba2fb5e' => $vendorDir . '/codeinwp/full-width-page-templates/load.php',
10
  '2e85745cdd367ff6e5579a8598f422b9' => $vendorDir . '/codeinwp/elementor-extra-widgets/load.php',
11
  '7b1f4385ddfc86d120fe4380e8cb0fa6' => $vendorDir . '/codeinwp/themeisle-content-forms/load.php',
12
- '957c51f8f334b5ea3be310bfb8b3492c' => $vendorDir . '/codeinwp/themeisle-sdk/load.php',
13
  'b4f42ddc6ece5b15b772913931d8824c' => $vendorDir . '/codeinwp/templates-directory/load.php',
 
14
  );
9
  '62bc7c35996f19a64625f7ff3ba2fb5e' => $vendorDir . '/codeinwp/full-width-page-templates/load.php',
10
  '2e85745cdd367ff6e5579a8598f422b9' => $vendorDir . '/codeinwp/elementor-extra-widgets/load.php',
11
  '7b1f4385ddfc86d120fe4380e8cb0fa6' => $vendorDir . '/codeinwp/themeisle-content-forms/load.php',
 
12
  'b4f42ddc6ece5b15b772913931d8824c' => $vendorDir . '/codeinwp/templates-directory/load.php',
13
+ '7dc03c238a420defc3b017ad92d2d53a' => $vendorDir . '/codeinwp/themeisle-sdk/load.php',
14
  );
vendor/composer/autoload_real.php CHANGED
@@ -2,7 +2,7 @@
2
 
3
  // autoload_real.php @generated by Composer
4
 
5
- class ComposerAutoloaderInitd67a8571892509a7a621debcca8600f6
6
  {
7
  private static $loader;
8
 
@@ -19,9 +19,9 @@ class ComposerAutoloaderInitd67a8571892509a7a621debcca8600f6
19
  return self::$loader;
20
  }
21
 
22
- spl_autoload_register(array('ComposerAutoloaderInitd67a8571892509a7a621debcca8600f6', 'loadClassLoader'), true, true);
23
  self::$loader = $loader = new \Composer\Autoload\ClassLoader();
24
- spl_autoload_unregister(array('ComposerAutoloaderInitd67a8571892509a7a621debcca8600f6', 'loadClassLoader'));
25
 
26
  $map = require __DIR__ . '/autoload_namespaces.php';
27
  foreach ($map as $namespace => $path) {
@@ -42,14 +42,14 @@ class ComposerAutoloaderInitd67a8571892509a7a621debcca8600f6
42
 
43
  $includeFiles = require __DIR__ . '/autoload_files.php';
44
  foreach ($includeFiles as $fileIdentifier => $file) {
45
- composerRequired67a8571892509a7a621debcca8600f6($fileIdentifier, $file);
46
  }
47
 
48
  return $loader;
49
  }
50
  }
51
 
52
- function composerRequired67a8571892509a7a621debcca8600f6($fileIdentifier, $file)
53
  {
54
  if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
55
  require $file;
2
 
3
  // autoload_real.php @generated by Composer
4
 
5
+ class ComposerAutoloaderInit1949c25865d8e9f266b9f04c54d29d81
6
  {
7
  private static $loader;
8
 
19
  return self::$loader;
20
  }
21
 
22
+ spl_autoload_register(array('ComposerAutoloaderInit1949c25865d8e9f266b9f04c54d29d81', 'loadClassLoader'), true, true);
23
  self::$loader = $loader = new \Composer\Autoload\ClassLoader();
24
+ spl_autoload_unregister(array('ComposerAutoloaderInit1949c25865d8e9f266b9f04c54d29d81', 'loadClassLoader'));
25
 
26
  $map = require __DIR__ . '/autoload_namespaces.php';
27
  foreach ($map as $namespace => $path) {
42
 
43
  $includeFiles = require __DIR__ . '/autoload_files.php';
44
  foreach ($includeFiles as $fileIdentifier => $file) {
45
+ composerRequire1949c25865d8e9f266b9f04c54d29d81($fileIdentifier, $file);
46
  }
47
 
48
  return $loader;
49
  }
50
  }
51
 
52
+ function composerRequire1949c25865d8e9f266b9f04c54d29d81($fileIdentifier, $file)
53
  {
54
  if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
55
  require $file;
vendor/composer/installed.json CHANGED
@@ -16,7 +16,7 @@
16
  },
17
  "time": "2018-07-27 13:45:55",
18
  "type": "library",
19
- "installation-source": "dist",
20
  "autoload": {
21
  "files": [
22
  "load.php"
@@ -42,17 +42,17 @@
42
  "source": {
43
  "type": "git",
44
  "url": "https://github.com/Codeinwp/themeisle-content-forms.git",
45
- "reference": "60f64fa4bb1d6941937bf45da2420d427cc6183f"
46
  },
47
  "dist": {
48
  "type": "zip",
49
- "url": "https://api.github.com/repos/Codeinwp/themeisle-content-forms/zipball/60f64fa4bb1d6941937bf45da2420d427cc6183f",
50
- "reference": "60f64fa4bb1d6941937bf45da2420d427cc6183f",
51
  "shasum": ""
52
  },
53
- "time": "2018-11-12 09:34:09",
54
  "type": "library",
55
- "installation-source": "dist",
56
  "autoload": {
57
  "files": [
58
  "load.php"
@@ -76,23 +76,23 @@
76
  ]
77
  },
78
  {
79
- "name": "codeinwp/themeisle-sdk",
80
  "version": "dev-master",
81
  "version_normalized": "9999999-dev",
82
  "source": {
83
  "type": "git",
84
- "url": "https://github.com/Codeinwp/themeisle-sdk.git",
85
- "reference": "951cde6e799e00d46a52416b62221fd771ddc326"
86
  },
87
  "dist": {
88
  "type": "zip",
89
- "url": "https://api.github.com/repos/Codeinwp/themeisle-sdk/zipball/951cde6e799e00d46a52416b62221fd771ddc326",
90
- "reference": "951cde6e799e00d46a52416b62221fd771ddc326",
91
  "shasum": ""
92
  },
93
- "time": "2018-11-26 14:24:47",
94
  "type": "library",
95
- "installation-source": "dist",
96
  "autoload": {
97
  "files": [
98
  "load.php"
@@ -100,7 +100,7 @@
100
  },
101
  "notification-url": "https://packagist.org/downloads/",
102
  "license": [
103
- "GPL-2.0+"
104
  ],
105
  "authors": [
106
  {
@@ -109,30 +109,30 @@
109
  "homepage": "https://themeisle.com"
110
  }
111
  ],
112
- "description": "ThemeIsle SDK ",
113
- "homepage": "https://github.com/Codeinwp/themeisle-sdk",
114
- "keywords": [
115
- "wordpress"
116
- ]
117
  },
118
  {
119
- "name": "codeinwp/full-width-page-templates",
120
  "version": "dev-master",
121
  "version_normalized": "9999999-dev",
122
  "source": {
123
  "type": "git",
124
- "url": "https://github.com/Codeinwp/full-width-page-templates.git",
125
- "reference": "770990cf96bd9cb6b8c846b1c9bff16450e2dff9"
126
  },
127
  "dist": {
128
  "type": "zip",
129
- "url": "https://api.github.com/repos/Codeinwp/full-width-page-templates/zipball/770990cf96bd9cb6b8c846b1c9bff16450e2dff9",
130
- "reference": "770990cf96bd9cb6b8c846b1c9bff16450e2dff9",
131
  "shasum": ""
132
  },
133
- "time": "2018-03-02 08:33:03",
 
 
 
134
  "type": "library",
135
- "installation-source": "dist",
136
  "autoload": {
137
  "files": [
138
  "load.php"
@@ -149,38 +149,35 @@
149
  "homepage": "https://themeisle.com"
150
  }
151
  ],
152
- "description": "A WordPress library to create full width page templates.",
153
- "homepage": "https://github.com/Codeinwp/full-width-page-templates"
154
  },
155
  {
156
- "name": "codeinwp/templates-directory",
157
- "version": "dev-master",
158
- "version_normalized": "9999999-dev",
159
  "source": {
160
  "type": "git",
161
- "url": "https://github.com/Codeinwp/templates-directory.git",
162
- "reference": "18e8b64784457e3851bc79203e1306b6057d4d69"
163
  },
164
  "dist": {
165
  "type": "zip",
166
- "url": "https://api.github.com/repos/Codeinwp/templates-directory/zipball/18e8b64784457e3851bc79203e1306b6057d4d69",
167
- "reference": "18e8b64784457e3851bc79203e1306b6057d4d69",
168
  "shasum": ""
169
  },
170
- "require": {
171
- "codeinwp/full-width-page-templates": "master"
 
 
172
  },
173
- "time": "2018-12-12 21:50:20",
174
  "type": "library",
175
  "installation-source": "dist",
176
- "autoload": {
177
- "files": [
178
- "load.php"
179
- ]
180
- },
181
  "notification-url": "https://packagist.org/downloads/",
182
  "license": [
183
- "GPL-2.0-or-later"
184
  ],
185
  "authors": [
186
  {
@@ -189,7 +186,10 @@
189
  "homepage": "https://themeisle.com"
190
  }
191
  ],
192
- "description": "A WordPress library to manage page templates.",
193
- "homepage": "https://github.com/Codeinwp/templates-directory"
 
 
 
194
  }
195
  ]
16
  },
17
  "time": "2018-07-27 13:45:55",
18
  "type": "library",
19
+ "installation-source": "source",
20
  "autoload": {
21
  "files": [
22
  "load.php"
42
  "source": {
43
  "type": "git",
44
  "url": "https://github.com/Codeinwp/themeisle-content-forms.git",
45
+ "reference": "6cf6eb081bc89e99441075b994ed345dbc8670b4"
46
  },
47
  "dist": {
48
  "type": "zip",
49
+ "url": "https://api.github.com/repos/Codeinwp/themeisle-content-forms/zipball/6cf6eb081bc89e99441075b994ed345dbc8670b4",
50
+ "reference": "6cf6eb081bc89e99441075b994ed345dbc8670b4",
51
  "shasum": ""
52
  },
53
+ "time": "2019-01-10 13:04:46",
54
  "type": "library",
55
+ "installation-source": "source",
56
  "autoload": {
57
  "files": [
58
  "load.php"
76
  ]
77
  },
78
  {
79
+ "name": "codeinwp/full-width-page-templates",
80
  "version": "dev-master",
81
  "version_normalized": "9999999-dev",
82
  "source": {
83
  "type": "git",
84
+ "url": "https://github.com/Codeinwp/full-width-page-templates.git",
85
+ "reference": "770990cf96bd9cb6b8c846b1c9bff16450e2dff9"
86
  },
87
  "dist": {
88
  "type": "zip",
89
+ "url": "https://api.github.com/repos/Codeinwp/full-width-page-templates/zipball/770990cf96bd9cb6b8c846b1c9bff16450e2dff9",
90
+ "reference": "770990cf96bd9cb6b8c846b1c9bff16450e2dff9",
91
  "shasum": ""
92
  },
93
+ "time": "2018-03-02 08:33:03",
94
  "type": "library",
95
+ "installation-source": "source",
96
  "autoload": {
97
  "files": [
98
  "load.php"
100
  },
101
  "notification-url": "https://packagist.org/downloads/",
102
  "license": [
103
+ "GPL-2.0-or-later"
104
  ],
105
  "authors": [
106
  {
109
  "homepage": "https://themeisle.com"
110
  }
111
  ],
112
+ "description": "A WordPress library to create full width page templates.",
113
+ "homepage": "https://github.com/Codeinwp/full-width-page-templates"
 
 
 
114
  },
115
  {
116
+ "name": "codeinwp/templates-directory",
117
  "version": "dev-master",
118
  "version_normalized": "9999999-dev",
119
  "source": {
120
  "type": "git",
121
+ "url": "https://github.com/Codeinwp/templates-directory.git",
122
+ "reference": "18e8b64784457e3851bc79203e1306b6057d4d69"
123
  },
124
  "dist": {
125
  "type": "zip",
126
+ "url": "https://api.github.com/repos/Codeinwp/templates-directory/zipball/18e8b64784457e3851bc79203e1306b6057d4d69",
127
+ "reference": "18e8b64784457e3851bc79203e1306b6057d4d69",
128
  "shasum": ""
129
  },
130
+ "require": {
131
+ "codeinwp/full-width-page-templates": "master"
132
+ },
133
+ "time": "2018-12-12 21:50:20",
134
  "type": "library",
135
+ "installation-source": "source",
136
  "autoload": {
137
  "files": [
138
  "load.php"
149
  "homepage": "https://themeisle.com"
150
  }
151
  ],
152
+ "description": "A WordPress library to manage page templates.",
153
+ "homepage": "https://github.com/Codeinwp/templates-directory"
154
  },
155
  {
156
+ "name": "codeinwp/themeisle-sdk",
157
+ "version": "3.0.5",
158
+ "version_normalized": "3.0.5.0",
159
  "source": {
160
  "type": "git",
161
+ "url": "https://github.com/Codeinwp/themeisle-sdk.git",
162
+ "reference": "7ead6c057d783ea6c827d5b5de52a25c0e72de58"
163
  },
164
  "dist": {
165
  "type": "zip",
166
+ "url": "https://api.github.com/repos/Codeinwp/themeisle-sdk/zipball/7ead6c057d783ea6c827d5b5de52a25c0e72de58",
167
+ "reference": "7ead6c057d783ea6c827d5b5de52a25c0e72de58",
168
  "shasum": ""
169
  },
170
+ "require-dev": {
171
+ "dealerdirect/phpcodesniffer-composer-installer": "^0.4.4",
172
+ "squizlabs/php_codesniffer": "^3.1",
173
+ "wp-coding-standards/wpcs": "^1.0.0"
174
  },
175
+ "time": "2019-03-07 15:42:52",
176
  "type": "library",
177
  "installation-source": "dist",
 
 
 
 
 
178
  "notification-url": "https://packagist.org/downloads/",
179
  "license": [
180
+ "GPL-2.0+"
181
  ],
182
  "authors": [
183
  {
186
  "homepage": "https://themeisle.com"
187
  }
188
  ],
189
+ "description": "ThemeIsle SDK.",
190
+ "homepage": "https://github.com/Codeinwp/themeisle-sdk",
191
+ "keywords": [
192
+ "wordpress"
193
+ ]
194
  }
195
  ]