WordPress Page Builder – Beaver Builder - Version 1.5.5

Version Description

Download this release

Release Info

Developer justinbusa
Plugin Icon 128x128 WordPress Page Builder – Beaver Builder
Version 1.5.5
Comparing to
See all releases

Code changes from version 1.5.3 to 1.5.5

Files changed (85) hide show
  1. changelog.txt +23 -0
  2. classes/class-fl-builder-admin-posts.php +51 -29
  3. classes/class-fl-builder-admin-settings.php +203 -123
  4. classes/class-fl-builder-loop.php +40 -7
  5. classes/class-fl-builder-model.php +47 -21
  6. classes/class-fl-builder-photo.php +26 -17
  7. classes/class-fl-builder-service-aweber.php +255 -0
  8. classes/class-fl-builder-service-campaign-monitor.php +259 -0
  9. classes/class-fl-builder-service-constant-contact.php +286 -0
  10. classes/class-fl-builder-service-getresponse.php +210 -0
  11. classes/class-fl-builder-service-icontact.php +286 -0
  12. classes/class-fl-builder-service-madmimi.php +248 -0
  13. classes/class-fl-builder-service-mailchimp.php +227 -0
  14. classes/class-fl-builder-service-mailpoet.php +155 -0
  15. classes/class-fl-builder-service.php +68 -0
  16. classes/class-fl-builder-services.php +338 -0
  17. classes/class-fl-builder.php +27 -11
  18. css/fl-builder-layout-auto-spacing.css +26 -0
  19. css/fl-builder-layout-responsive.css +0 -17
  20. css/fl-builder-layout.css +21 -0
  21. css/fl-builder.css +35 -1
  22. fl-builder.php +10 -6
  23. img/templates/coming-soon.jpg +0 -0
  24. img/templates/pricing.jpg +0 -0
  25. img/templates/signup.jpg +0 -0
  26. img/templates/subscribe.jpg +0 -0
  27. includes/column-css.php +7 -1
  28. includes/field-button.php +1 -0
  29. includes/field.php +12 -6
  30. includes/global-settings.php +11 -1
  31. includes/js-config.php +6 -0
  32. includes/loop-settings.php +10 -0
  33. includes/row-css.php +8 -4
  34. includes/service-settings.php +41 -0
  35. includes/updater-config.php +1 -1
  36. includes/vendor/aweber/aweber.php +292 -0
  37. includes/vendor/aweber/aweber_api.php +8 -0
  38. includes/vendor/aweber/aweber_collection.php +268 -0
  39. includes/vendor/aweber/aweber_entry.php +343 -0
  40. includes/vendor/aweber/aweber_entry_data_array.php +68 -0
  41. includes/vendor/aweber/aweber_response.php +73 -0
  42. includes/vendor/aweber/curl_object.php +103 -0
  43. includes/vendor/aweber/curl_response.php +51 -0
  44. includes/vendor/aweber/exceptions.php +130 -0
  45. includes/vendor/aweber/oauth_adapter.php +11 -0
  46. includes/vendor/aweber/oauth_application.php +682 -0
  47. includes/vendor/campaign-monitor/class/base_classes.php +287 -0
  48. includes/vendor/campaign-monitor/class/cacert.pem +3849 -0
  49. includes/vendor/campaign-monitor/class/log.php +19 -0
  50. includes/vendor/campaign-monitor/class/serialisation.php +129 -0
  51. includes/vendor/campaign-monitor/class/services_json.php +782 -0
  52. includes/vendor/campaign-monitor/class/transport.php +335 -0
  53. includes/vendor/campaign-monitor/csrest_administrators.php +108 -0
  54. includes/vendor/campaign-monitor/csrest_campaigns.php +439 -0
  55. includes/vendor/campaign-monitor/csrest_clients.php +450 -0
  56. includes/vendor/campaign-monitor/csrest_general.php +212 -0
  57. includes/vendor/campaign-monitor/csrest_lists.php +587 -0
  58. includes/vendor/campaign-monitor/csrest_people.php +125 -0
  59. includes/vendor/campaign-monitor/csrest_segments.php +206 -0
  60. includes/vendor/campaign-monitor/csrest_subscribers.php +231 -0
  61. includes/vendor/campaign-monitor/csrest_templates.php +118 -0
  62. includes/vendor/getresponse/getresponse.php +576 -0
  63. includes/vendor/icontact/iContactApi.php +1109 -0
  64. includes/vendor/madmimi/MadMimi.class.php +246 -0
  65. includes/vendor/madmimi/Spyc.class.php +1024 -0
  66. includes/vendor/mailchimp/Mailchimp/Campaigns.php +378 -0
  67. includes/vendor/mailchimp/Mailchimp/Conversations.php +80 -0
  68. includes/vendor/mailchimp/Mailchimp/Ecomm.php +86 -0
  69. includes/vendor/mailchimp/Mailchimp/Exceptions.php +471 -0
  70. includes/vendor/mailchimp/Mailchimp/Folders.php +62 -0
  71. includes/vendor/mailchimp/Mailchimp/Gallery.php +106 -0
  72. includes/vendor/mailchimp/Mailchimp/Goal.php +49 -0
  73. includes/vendor/mailchimp/Mailchimp/Helper.php +237 -0
  74. includes/vendor/mailchimp/Mailchimp/Lists.php +904 -0
  75. includes/vendor/mailchimp/Mailchimp/Mobile.php +10 -0
  76. includes/vendor/mailchimp/Mailchimp/Neapolitan.php +10 -0
  77. includes/vendor/mailchimp/Mailchimp/Reports.php +459 -0
  78. includes/vendor/mailchimp/Mailchimp/Templates.php +114 -0
  79. includes/vendor/mailchimp/Mailchimp/Users.php +105 -0
  80. includes/vendor/mailchimp/Mailchimp/Vip.php +111 -0
  81. includes/vendor/mailchimp/mailchimp.php +261 -0
  82. js/fl-builder-layout.js +103 -29
  83. js/fl-builder-preview.js +18 -4
  84. js/fl-builder-services.js +368 -0
  85. js/fl-builder.js +70 -40
changelog.txt CHANGED
@@ -1,3 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  <h4>1.5.3 - 03/31/2015</h4>
2
  <p><strong>Enhancements</strong></p>
3
  <ul>
1
+ <h4>1.5.5 - 04/12/2015</h4>
2
+ <p><strong>Enhancements</strong></p>
3
+ <ul>
4
+ <li>The Subscribe Form module is here! Please see <a href="https://www.wpbeaverbuilder.com/build-your-email-lists-with-beaver-builders-new-subscribe-form-module/">the blog post</a> for complete details.</li>
5
+ <li>Added four new templates.</li>
6
+ </ul>
7
+
8
+ <h4>1.5.4 - 04/08/2015</h4>
9
+ <p><strong>Enhancements</strong></p>
10
+ <ul>
11
+ <li>Added offset setting to the Posts module.</li>
12
+ <li>Added getting started video to the help button.</li>
13
+ <li>Added auto spacing setting to the global settings for turning off auto spacing on responsive layouts.</li>
14
+ <li>Added SVG support to the photo field for sites that have SVG enabled as an mime type.</li>
15
+ </ul>
16
+ <p><strong>Bug Fixes</strong></p>
17
+ <ul>
18
+ <li>Fixed a bug with switching back to the WordPress editor.</li>
19
+ <li>Fixed a bug with textarea text color being overridden by row text color.</li>
20
+ <li>Fixed an issue with varnish by removing the question mark from the URL when publishing.</li>
21
+ <li>Removed FLBuilderModel::delete_asset_cache_domain_change as it's causing issues and we now have the clear cache button.</li>
22
+ </ul>
23
+
24
  <h4>1.5.3 - 03/31/2015</h4>
25
  <p><strong>Enhancements</strong></p>
26
  <ul>
classes/class-fl-builder-admin-posts.php CHANGED
@@ -1,66 +1,77 @@
1
  <?php
2
 
3
  /**
4
- * Post admin class.
5
  *
6
- * @class FLBuilderAdminPosts
7
  */
8
  final class FLBuilderAdminPosts {
9
 
10
  /**
11
- * @method init
 
 
 
 
12
  */
13
  static public function init()
14
  {
15
  global $pagenow;
16
 
17
- if(in_array($pagenow, array('post.php', 'post-new.php'))) {
18
 
19
  $post_types = FLBuilderModel::get_post_types();
20
  $screen = get_current_screen();
21
 
22
- if(in_array($screen->post_type, $post_types)) {
23
- add_filter('admin_body_class', 'FLBuilderAdminPosts::body_class');
24
- add_action('admin_enqueue_scripts', 'FLBuilderAdminPosts::styles_scripts');
25
- add_action('edit_form_after_title', 'FLBuilderAdminPosts::render');
26
  }
27
  }
28
  }
29
 
30
  /**
31
- * @method styles_scripts
 
 
 
32
  */
33
  static public function styles_scripts()
34
  {
35
  global $wp_version;
36
 
37
  // Styles
38
- wp_enqueue_style('fl-builder-admin-posts', FL_BUILDER_URL . 'css/fl-builder-admin-posts.css', array(), FL_BUILDER_VERSION);
39
 
40
  // Legacy WP Styles (3.7 and below)
41
- if(version_compare($wp_version, '3.7', '<=')) {
42
- wp_enqueue_style('fl-builder-admin-posts-legacy', FL_BUILDER_URL . 'css/fl-builder-admin-posts-legacy.css', array(), FL_BUILDER_VERSION);
43
  }
44
 
45
  // Scripts
46
- wp_enqueue_script('json2');
47
- wp_enqueue_script('fl-builder-admin-posts', FL_BUILDER_URL . 'js/fl-builder-admin-posts.js', array(), FL_BUILDER_VERSION);
48
  }
49
-
50
  /**
51
- * @method body_class
 
 
 
 
52
  */
53
- static public function body_class($classes)
54
  {
55
  global $wp_version;
56
 
57
  // Builder body class
58
- if(FLBuilderModel::is_builder_enabled()) {
59
  $classes .= ' fl-builder-enabled';
60
  }
61
 
62
  // Pre WP 3.8 body class
63
- if(version_compare($wp_version, '3.8', '<')) {
64
  $classes .= ' fl-pre-wp-3-8';
65
  }
66
 
@@ -68,7 +79,10 @@ final class FLBuilderAdminPosts {
68
  }
69
 
70
  /**
71
- * @method render
 
 
 
72
  */
73
  static public function render()
74
  {
@@ -78,32 +92,40 @@ final class FLBuilderAdminPosts {
78
 
79
  include FL_BUILDER_DIR . 'includes/admin-posts.php';
80
  }
81
-
82
  /**
83
- * @method render_row_actions_link
 
 
 
 
84
  */
85
- static public function render_row_actions_link($actions)
86
  {
87
  global $post;
88
 
89
- if(current_user_can('edit_post', $post->ID) && wp_check_post_lock($post->ID) === false) {
90
 
91
  $post_types = FLBuilderModel::get_post_types();
92
 
93
- if(in_array($post->post_type, $post_types)) {
94
  $actions['fl-builder'] = '<a href="' . FLBuilderModel::get_edit_url() . '">' . FLBuilderModel::get_branding() . '</a>';
95
  }
96
  }
97
 
98
  return $actions;
99
  }
100
-
101
  /**
102
- * @method redirect_post_location
 
 
 
 
103
  */
104
- static public function redirect_post_location($location)
105
  {
106
- if(isset($_POST['fl-builder-redirect'])) {
107
  $location = $_POST['fl-builder-redirect'];
108
  }
109
 
1
  <?php
2
 
3
  /**
4
+ * Handles logic for the post edit screen.
5
  *
6
+ * @since 1.5.0
7
  */
8
  final class FLBuilderAdminPosts {
9
 
10
  /**
11
+ * Sets the body class, loads assets and renders the UI
12
+ * if we are on a post type that supports the builder.
13
+ *
14
+ * @since 1.5.0
15
+ * @return void
16
  */
17
  static public function init()
18
  {
19
  global $pagenow;
20
 
21
+ if ( in_array( $pagenow, array( 'post.php', 'post-new.php') ) ) {
22
 
23
  $post_types = FLBuilderModel::get_post_types();
24
  $screen = get_current_screen();
25
 
26
+ if ( in_array( $screen->post_type, $post_types ) ) {
27
+ add_filter( 'admin_body_class', 'FLBuilderAdminPosts::body_class' );
28
+ add_action( 'admin_enqueue_scripts', 'FLBuilderAdminPosts::styles_scripts' );
29
+ add_action( 'edit_form_after_title', 'FLBuilderAdminPosts::render' );
30
  }
31
  }
32
  }
33
 
34
  /**
35
+ * Enqueues the CSS/JS for the post edit screen.
36
+ *
37
+ * @since 1.5.0
38
+ * @return void
39
  */
40
  static public function styles_scripts()
41
  {
42
  global $wp_version;
43
 
44
  // Styles
45
+ wp_enqueue_style( 'fl-builder-admin-posts', FL_BUILDER_URL . 'css/fl-builder-admin-posts.css', array(), FL_BUILDER_VERSION );
46
 
47
  // Legacy WP Styles (3.7 and below)
48
+ if ( version_compare( $wp_version, '3.7', '<=' ) ) {
49
+ wp_enqueue_style( 'fl-builder-admin-posts-legacy', FL_BUILDER_URL . 'css/fl-builder-admin-posts-legacy.css', array(), FL_BUILDER_VERSION );
50
  }
51
 
52
  // Scripts
53
+ wp_enqueue_script( 'json2' );
54
+ wp_enqueue_script( 'fl-builder-admin-posts', FL_BUILDER_URL . 'js/fl-builder-admin-posts.js', array(), FL_BUILDER_VERSION );
55
  }
56
+
57
  /**
58
+ * Adds classes to the post edit screen body class.
59
+ *
60
+ * @since 1.5.0
61
+ * @param string $classes The existing body classes.
62
+ * @return string The body classes.
63
  */
64
+ static public function body_class( $classes = '' )
65
  {
66
  global $wp_version;
67
 
68
  // Builder body class
69
+ if ( FLBuilderModel::is_builder_enabled() ) {
70
  $classes .= ' fl-builder-enabled';
71
  }
72
 
73
  // Pre WP 3.8 body class
74
+ if ( version_compare( $wp_version, '3.8', '<' ) ) {
75
  $classes .= ' fl-pre-wp-3-8';
76
  }
77
 
79
  }
80
 
81
  /**
82
+ * Renders the HTML for the post edit screen.
83
+ *
84
+ * @since 1.5.0
85
+ * @return void
86
  */
87
  static public function render()
88
  {
92
 
93
  include FL_BUILDER_DIR . 'includes/admin-posts.php';
94
  }
95
+
96
  /**
97
+ * Renders the action link for post listing pages.
98
+ *
99
+ * @since 1.5.0
100
+ * @param array $actions
101
+ * @return array The array of action data.
102
  */
103
+ static public function render_row_actions_link( $actions = array() )
104
  {
105
  global $post;
106
 
107
+ if ( current_user_can( 'edit_post', $post->ID ) && wp_check_post_lock( $post->ID ) === false ) {
108
 
109
  $post_types = FLBuilderModel::get_post_types();
110
 
111
+ if ( in_array( $post->post_type, $post_types ) ) {
112
  $actions['fl-builder'] = '<a href="' . FLBuilderModel::get_edit_url() . '">' . FLBuilderModel::get_branding() . '</a>';
113
  }
114
  }
115
 
116
  return $actions;
117
  }
118
+
119
  /**
120
+ * Where to redirect this post on save.
121
+ *
122
+ * @since 1.5.0
123
+ * @param string $location
124
+ * @return string The location to redirect this post on save.
125
  */
126
+ static public function redirect_post_location( $location )
127
  {
128
+ if ( isset( $_POST['fl-builder-redirect'] ) ) {
129
  $location = $_POST['fl-builder-redirect'];
130
  }
131
 
classes/class-fl-builder-admin-settings.php CHANGED
@@ -1,73 +1,93 @@
1
  <?php
2
 
3
  /**
4
- * Settings admin class.
5
  *
6
- * @class FLBuilderAdminSettings
7
  */
8
  final class FLBuilderAdminSettings {
9
 
10
  /**
11
- * @property $errors
 
 
 
 
12
  */
13
  static public $errors = array();
14
 
15
  /**
16
- * @method init
 
 
 
 
17
  */
18
  static public function init()
19
  {
20
- add_action('admin_menu', 'FLBuilderAdminSettings::menu');
21
 
22
- if(isset($_REQUEST['page']) && $_REQUEST['page'] == 'fl-builder-settings') {
23
- add_action('admin_enqueue_scripts', 'FLBuilderAdminSettings::styles_scripts');
24
  self::save();
25
  }
26
  }
27
-
28
- /**
29
- * @method styles_scripts
30
- */
 
 
 
31
  static public function styles_scripts()
32
  {
33
  // Styles
34
- wp_enqueue_style('fl-builder-admin-settings', FL_BUILDER_URL . 'css/fl-builder-admin-settings.css', array(), FL_BUILDER_VERSION);
35
 
36
  // Scripts
37
- wp_enqueue_script('fl-builder-admin-settings', FL_BUILDER_URL . 'js/fl-builder-admin-settings.js', array(), FL_BUILDER_VERSION);
38
 
39
  // Media Uploader
40
  wp_enqueue_media();
41
  }
42
-
43
- /**
44
- * @method menu
 
 
 
45
  */
46
  static public function menu()
47
  {
48
- if(current_user_can('delete_plugins')) {
49
 
50
  $title = FLBuilderModel::get_branding();
51
  $cap = 'delete_plugins';
52
  $slug = 'fl-builder-settings';
53
  $func = 'FLBuilderAdminSettings::render';
54
 
55
- add_submenu_page('options-general.php', $title, $title, $cap, $slug, $func);
56
  }
57
  }
58
-
59
- /**
60
- * @method render
61
- */
 
 
 
62
  static public function render()
63
  {
64
  include FL_BUILDER_DIR . 'includes/admin-settings-js-config.php';
65
  include FL_BUILDER_DIR . 'includes/admin-settings.php';
66
  }
67
-
68
- /**
69
- * @method render_page_class
70
- */
 
 
 
71
  static public function render_page_class()
72
  {
73
  if ( self::multisite_support() ) {
@@ -77,10 +97,13 @@ final class FLBuilderAdminSettings {
77
  echo 'fl-settings-single-install';
78
  }
79
  }
80
-
81
- /**
82
- * @method render_page_heading
83
- */
 
 
 
84
  static public function render_page_heading()
85
  {
86
  $icon = FLBuilderModel::get_branding_icon();
@@ -92,9 +115,12 @@ final class FLBuilderAdminSettings {
92
 
93
  echo '<span>' . sprintf( _x( '%s Settings', '%s stands for custom branded "Page Builder" name.', 'fl-builder' ), FLBuilderModel::get_branding() ) . '</span>';
94
  }
95
-
96
- /**
97
- * @method render_update_message
 
 
 
98
  */
99
  static public function render_update_message()
100
  {
@@ -107,10 +133,13 @@ final class FLBuilderAdminSettings {
107
  echo '<div class="updated"><p>' . __( 'Settings updated!', 'fl-builder' ) . '</p></div>';
108
  }
109
  }
110
-
111
- /**
112
- * @method render_nav_items
113
- */
 
 
 
114
  static public function render_nav_items()
115
  {
116
  $item_data = array(
@@ -166,10 +195,13 @@ final class FLBuilderAdminSettings {
166
  }
167
  }
168
  }
169
-
170
- /**
171
- * @method render_forms
172
- */
 
 
 
173
  static public function render_forms()
174
  {
175
  // License
@@ -209,20 +241,28 @@ final class FLBuilderAdminSettings {
209
  // Uninstall
210
  self::render_form( 'uninstall' );
211
  }
212
-
213
- /**
214
- * @method render_form
215
- */
 
 
 
 
216
  static public function render_form( $type )
217
  {
218
  if ( self::has_support( $type ) ) {
219
  include FL_BUILDER_DIR . 'includes/admin-settings-' . $type . '.php';
220
  }
221
  }
222
-
223
- /**
224
- * @method render_form_action
225
- */
 
 
 
 
226
  static public function render_form_action( $type = '' )
227
  {
228
  if ( is_network_admin() ) {
@@ -232,9 +272,13 @@ final class FLBuilderAdminSettings {
232
  echo admin_url( '/options-general.php?page=fl-builder-settings#' . $type );
233
  }
234
  }
235
-
236
- /**
237
- * @method get_form_action
 
 
 
 
238
  */
239
  static public function get_form_action( $type = '' )
240
  {
@@ -245,34 +289,48 @@ final class FLBuilderAdminSettings {
245
  return admin_url( '/options-general.php?page=fl-builder-settings#' . $type );
246
  }
247
  }
248
-
249
- /**
250
- * @method supports
251
- */
 
 
 
 
252
  static public function has_support( $type )
253
  {
254
  return file_exists( FL_BUILDER_DIR . 'includes/admin-settings-' . $type . '.php' );
255
  }
256
-
257
- /**
258
- * @method multisite_support
259
- */
 
 
 
260
  static public function multisite_support()
261
  {
262
  return is_multisite() && class_exists( 'FLBuilderMultisiteSettings' );
263
  }
264
-
265
- /**
266
- * @method add_error
267
- */
 
 
 
 
268
  static public function add_error( $message )
269
  {
270
  self::$errors[] = $message;
271
  }
272
-
273
- /**
274
- * @method save
275
- */
 
 
 
276
  static public function save()
277
  {
278
  // Only admins can save settings.
@@ -290,11 +348,13 @@ final class FLBuilderAdminSettings {
290
  self::clear_cache();
291
  self::uninstall();
292
  }
293
-
294
- /**
295
- * @method save_enabled_modules
296
- * @private
297
- */
 
 
298
  static private function save_enabled_modules()
299
  {
300
  if ( isset( $_POST['fl-modules-nonce'] ) && wp_verify_nonce( $_POST['fl-modules-nonce'], 'modules' ) ) {
@@ -316,11 +376,13 @@ final class FLBuilderAdminSettings {
316
  }
317
  }
318
  }
319
-
320
- /**
321
- * @method save_enabled_templates
322
- * @private
323
- */
 
 
324
  static private function save_enabled_templates()
325
  {
326
  if ( isset( $_POST['fl-templates-nonce'] ) && wp_verify_nonce( $_POST['fl-templates-nonce'], 'templates' ) ) {
@@ -338,11 +400,13 @@ final class FLBuilderAdminSettings {
338
  }
339
  }
340
  }
341
-
342
- /**
343
- * @method save_enabled_post_types
344
- * @private
345
- */
 
 
346
  static private function save_enabled_post_types()
347
  {
348
  if ( isset( $_POST['fl-post-types-nonce'] ) && wp_verify_nonce( $_POST['fl-post-types-nonce'], 'post-types' ) ) {
@@ -370,11 +434,13 @@ final class FLBuilderAdminSettings {
370
  }
371
  }
372
  }
373
-
374
- /**
375
- * @method save_enabled_icons
376
- * @private
377
- */
 
 
378
  static private function save_enabled_icons()
379
  {
380
  if ( isset( $_POST['fl-icons-nonce'] ) && wp_verify_nonce( $_POST['fl-icons-nonce'], 'icons' ) ) {
@@ -472,11 +538,13 @@ final class FLBuilderAdminSettings {
472
  self::update_enabled_icons( $enabled_icons );
473
  }
474
  }
475
-
476
- /**
477
- * @method update_enabled_icons
478
- * @private
479
- */
 
 
480
  static private function update_enabled_icons( $enabled_icons = array() )
481
  {
482
  if ( is_network_admin() ) {
@@ -490,11 +558,13 @@ final class FLBuilderAdminSettings {
490
  update_option( '_fl_builder_enabled_icons', $enabled_icons );
491
  }
492
  }
493
-
494
- /**
495
- * @method save_editing_capability
496
- * @private
497
- */
 
 
498
  static private function save_editing_capability()
499
  {
500
  if ( isset( $_POST['fl-editing-nonce'] ) && wp_verify_nonce( $_POST['fl-editing-nonce'], 'editing' ) ) {
@@ -512,11 +582,13 @@ final class FLBuilderAdminSettings {
512
  }
513
  }
514
  }
515
-
516
- /**
517
- * @method save_branding
518
- * @private
519
- */
 
 
520
  static private function save_branding()
521
  {
522
  if ( isset( $_POST['fl-branding-nonce'] ) && wp_verify_nonce( $_POST['fl-branding-nonce'], 'branding' ) ) {
@@ -534,11 +606,13 @@ final class FLBuilderAdminSettings {
534
  }
535
  }
536
  }
537
-
538
- /**
539
- * @method save_help_button
540
- * @private
541
- */
 
 
542
  static private function save_help_button()
543
  {
544
  if ( isset( $_POST['fl-help-button-nonce'] ) && wp_verify_nonce( $_POST['fl-help-button-nonce'], 'help-button' ) ) {
@@ -602,11 +676,13 @@ final class FLBuilderAdminSettings {
602
  }
603
  }
604
  }
605
-
606
- /**
607
- * @method clear_cache
608
- * @private
609
- */
 
 
610
  static private function clear_cache()
611
  {
612
  if ( ! current_user_can( 'delete_plugins' ) ) {
@@ -621,11 +697,13 @@ final class FLBuilderAdminSettings {
621
  }
622
  }
623
  }
624
-
625
- /**
626
- * @method clear_cache_for_all_sites
627
- * @private
628
- */
 
 
629
  static private function clear_cache_for_all_sites()
630
  {
631
  global $blog_id;
@@ -646,11 +724,13 @@ final class FLBuilderAdminSettings {
646
  // Revert to the original blog.
647
  switch_to_blog( $original_blog_id );
648
  }
649
-
650
- /**
651
- * @method uninstall
652
- * @private
653
- */
 
 
654
  static private function uninstall()
655
  {
656
  if ( ! current_user_can( 'delete_plugins' ) ) {
1
  <?php
2
 
3
  /**
4
+ * Handles logic for the admin settings page.
5
  *
6
+ * @since 1.5.0
7
  */
8
  final class FLBuilderAdminSettings {
9
 
10
  /**
11
+ * Holds any errors that may arise from
12
+ * saving admin settings.
13
+ *
14
+ * @since 1.5.0
15
+ * @var array $errors
16
  */
17
  static public $errors = array();
18
 
19
  /**
20
+ * Adds the admin menu and enqueues CSS/JS if we are on
21
+ * the builder admin settings page.
22
+ *
23
+ * @since 1.5.0
24
+ * @return void
25
  */
26
  static public function init()
27
  {
28
+ add_action( 'admin_menu', 'FLBuilderAdminSettings::menu' );
29
 
30
+ if ( isset( $_REQUEST['page'] ) && 'fl-builder-settings' == $_REQUEST['page'] ) {
31
+ add_action( 'admin_enqueue_scripts', 'FLBuilderAdminSettings::styles_scripts' );
32
  self::save();
33
  }
34
  }
35
+
36
+ /**
37
+ * Enqueues the needed CSS/JS for the builder's admin settings page.
38
+ *
39
+ * @since 1.5.0
40
+ * @return void
41
+ */
42
  static public function styles_scripts()
43
  {
44
  // Styles
45
+ wp_enqueue_style( 'fl-builder-admin-settings', FL_BUILDER_URL . 'css/fl-builder-admin-settings.css', array(), FL_BUILDER_VERSION );
46
 
47
  // Scripts
48
+ wp_enqueue_script( 'fl-builder-admin-settings', FL_BUILDER_URL . 'js/fl-builder-admin-settings.js', array(), FL_BUILDER_VERSION );
49
 
50
  // Media Uploader
51
  wp_enqueue_media();
52
  }
53
+
54
+ /**
55
+ * Renders the admin settings menu.
56
+ *
57
+ * @since 1.5.0
58
+ * @return void
59
  */
60
  static public function menu()
61
  {
62
+ if ( current_user_can( 'delete_plugins' ) ) {
63
 
64
  $title = FLBuilderModel::get_branding();
65
  $cap = 'delete_plugins';
66
  $slug = 'fl-builder-settings';
67
  $func = 'FLBuilderAdminSettings::render';
68
 
69
+ add_submenu_page( 'options-general.php', $title, $title, $cap, $slug, $func );
70
  }
71
  }
72
+
73
+ /**
74
+ * Renders the admin settings.
75
+ *
76
+ * @since 1.5.0
77
+ * @return void
78
+ */
79
  static public function render()
80
  {
81
  include FL_BUILDER_DIR . 'includes/admin-settings-js-config.php';
82
  include FL_BUILDER_DIR . 'includes/admin-settings.php';
83
  }
84
+
85
+ /**
86
+ * Renders the page class for network installs and single site installs.
87
+ *
88
+ * @since 1.5.0
89
+ * @return void
90
+ */
91
  static public function render_page_class()
92
  {
93
  if ( self::multisite_support() ) {
97
  echo 'fl-settings-single-install';
98
  }
99
  }
100
+
101
+ /**
102
+ * Renders the admin settings page heading.
103
+ *
104
+ * @since 1.5.0
105
+ * @return void
106
+ */
107
  static public function render_page_heading()
108
  {
109
  $icon = FLBuilderModel::get_branding_icon();
115
 
116
  echo '<span>' . sprintf( _x( '%s Settings', '%s stands for custom branded "Page Builder" name.', 'fl-builder' ), FLBuilderModel::get_branding() ) . '</span>';
117
  }
118
+
119
+ /**
120
+ * Renders the update message.
121
+ *
122
+ * @since 1.5.0
123
+ * @return void
124
  */
125
  static public function render_update_message()
126
  {
133
  echo '<div class="updated"><p>' . __( 'Settings updated!', 'fl-builder' ) . '</p></div>';
134
  }
135
  }
136
+
137
+ /**
138
+ * Renders the nav items for the admin settings menu.
139
+ *
140
+ * @since 1.5.0
141
+ * @return void
142
+ */
143
  static public function render_nav_items()
144
  {
145
  $item_data = array(
195
  }
196
  }
197
  }
198
+
199
+ /**
200
+ * Renders the admin settings forms.
201
+ *
202
+ * @since 1.5.0
203
+ * @return void
204
+ */
205
  static public function render_forms()
206
  {
207
  // License
241
  // Uninstall
242
  self::render_form( 'uninstall' );
243
  }
244
+
245
+ /**
246
+ * Renders an admin settings form based on the type specified.
247
+ *
248
+ * @since 1.5.0
249
+ * @param string $type The type of form to render.
250
+ * @return void
251
+ */
252
  static public function render_form( $type )
253
  {
254
  if ( self::has_support( $type ) ) {
255
  include FL_BUILDER_DIR . 'includes/admin-settings-' . $type . '.php';
256
  }
257
  }
258
+
259
+ /**
260
+ * Renders the action for a form.
261
+ *
262
+ * @since 1.5.0
263
+ * @param string $type The type of form being rendered.
264
+ * @return void
265
+ */
266
  static public function render_form_action( $type = '' )
267
  {
268
  if ( is_network_admin() ) {
272
  echo admin_url( '/options-general.php?page=fl-builder-settings#' . $type );
273
  }
274
  }
275
+
276
+ /**
277
+ * Returns the action for a form.
278
+ *
279
+ * @since 1.5.0
280
+ * @param string $type The type of form being rendered.
281
+ * @return string The URL for the form action.
282
  */
283
  static public function get_form_action( $type = '' )
284
  {
289
  return admin_url( '/options-general.php?page=fl-builder-settings#' . $type );
290
  }
291
  }
292
+
293
+ /**
294
+ * Checks to see if a settings form is supported.
295
+ *
296
+ * @since 1.5.0
297
+ * @param string $type The type of form to check.
298
+ * @return bool
299
+ */
300
  static public function has_support( $type )
301
  {
302
  return file_exists( FL_BUILDER_DIR . 'includes/admin-settings-' . $type . '.php' );
303
  }
304
+
305
+ /**
306
+ * Checks to see if multisite is supported.
307
+ *
308
+ * @since 1.5.0
309
+ * @return bool
310
+ */
311
  static public function multisite_support()
312
  {
313
  return is_multisite() && class_exists( 'FLBuilderMultisiteSettings' );
314
  }
315
+
316
+ /**
317
+ * Adds an error message to be rendered.
318
+ *
319
+ * @since 1.5.0
320
+ * @param string $message The error message to add.
321
+ * @return void
322
+ */
323
  static public function add_error( $message )
324
  {
325
  self::$errors[] = $message;
326
  }
327
+
328
+ /**
329
+ * Saves the admin settings.
330
+ *
331
+ * @since 1.5.0
332
+ * @return void
333
+ */
334
  static public function save()
335
  {
336
  // Only admins can save settings.
348
  self::clear_cache();
349
  self::uninstall();
350
  }
351
+
352
+ /**
353
+ * Saves the enabled modules.
354
+ *
355
+ * @since 1.5.0
356
+ * @return void
357
+ */
358
  static private function save_enabled_modules()
359
  {
360
  if ( isset( $_POST['fl-modules-nonce'] ) && wp_verify_nonce( $_POST['fl-modules-nonce'], 'modules' ) ) {
376
  }
377
  }
378
  }
379
+
380
+ /**
381
+ * Saves the enabled templates.
382
+ *
383
+ * @since 1.5.0
384
+ * @return void
385
+ */
386
  static private function save_enabled_templates()
387
  {
388
  if ( isset( $_POST['fl-templates-nonce'] ) && wp_verify_nonce( $_POST['fl-templates-nonce'], 'templates' ) ) {
400
  }
401
  }
402
  }
403
+
404
+ /**
405
+ * Saves the enabled post types.
406
+ *
407
+ * @since 1.5.0
408
+ * @return void
409
+ */
410
  static private function save_enabled_post_types()
411
  {
412
  if ( isset( $_POST['fl-post-types-nonce'] ) && wp_verify_nonce( $_POST['fl-post-types-nonce'], 'post-types' ) ) {
434
  }
435
  }
436
  }
437
+
438
+ /**
439
+ * Saves the enabled icons.
440
+ *
441
+ * @since 1.5.0
442
+ * @return void
443
+ */
444
  static private function save_enabled_icons()
445
  {
446
  if ( isset( $_POST['fl-icons-nonce'] ) && wp_verify_nonce( $_POST['fl-icons-nonce'], 'icons' ) ) {
538
  self::update_enabled_icons( $enabled_icons );
539
  }
540
  }
541
+
542
+ /**
543
+ * Updates the enabled icons in the database.
544
+ *
545
+ * @since 1.5.0
546
+ * @return void
547
+ */
548
  static private function update_enabled_icons( $enabled_icons = array() )
549
  {
550
  if ( is_network_admin() ) {
558
  update_option( '_fl_builder_enabled_icons', $enabled_icons );
559
  }
560
  }
561
+
562
+ /**
563
+ * Saves the editing capability.
564
+ *
565
+ * @since 1.5.0
566
+ * @return void
567
+ */
568
  static private function save_editing_capability()
569
  {
570
  if ( isset( $_POST['fl-editing-nonce'] ) && wp_verify_nonce( $_POST['fl-editing-nonce'], 'editing' ) ) {
582
  }
583
  }
584
  }
585
+
586
+ /**
587
+ * Saves the branding settings.
588
+ *
589
+ * @since 1.5.0
590
+ * @return void
591
+ */
592
  static private function save_branding()
593
  {
594
  if ( isset( $_POST['fl-branding-nonce'] ) && wp_verify_nonce( $_POST['fl-branding-nonce'], 'branding' ) ) {
606
  }
607
  }
608
  }
609
+
610
+ /**
611
+ * Saves the help button settings.
612
+ *
613
+ * @since 1.5.0
614
+ * @return void
615
+ */
616
  static private function save_help_button()
617
  {
618
  if ( isset( $_POST['fl-help-button-nonce'] ) && wp_verify_nonce( $_POST['fl-help-button-nonce'], 'help-button' ) ) {
676
  }
677
  }
678
  }
679
+
680
+ /**
681
+ * Clears the builder cache.
682
+ *
683
+ * @since 1.5.3
684
+ * @return void
685
+ */
686
  static private function clear_cache()
687
  {
688
  if ( ! current_user_can( 'delete_plugins' ) ) {
697
  }
698
  }
699
  }
700
+
701
+ /**
702
+ * Clears the builder cache for all sites on a network.
703
+ *
704
+ * @since 1.5.3
705
+ * @return void
706
+ */
707
  static private function clear_cache_for_all_sites()
708
  {
709
  global $blog_id;
724
  // Revert to the original blog.
725
  switch_to_blog( $original_blog_id );
726
  }
727
+
728
+ /**
729
+ * Uninstalls the builder and all of its data.
730
+ *
731
+ * @since 1.5.0
732
+ * @return void
733
+ */
734
  static private function uninstall()
735
  {
736
  if ( ! current_user_can( 'delete_plugins' ) ) {
classes/class-fl-builder-loop.php CHANGED
@@ -13,21 +13,42 @@ final class FLBuilderLoop {
13
  */
14
  static public function query($settings)
15
  {
16
- $posts_per_page = empty($settings->posts_per_page) ? 10 : $settings->posts_per_page;
17
- $post_type = empty($settings->post_type) ? 'post' : $settings->post_type;
18
- $order_by = empty($settings->order_by) ? 'date' : $settings->order_by;
19
- $order = empty($settings->order) ? 'DESC' : $settings->order;
20
- $users = empty($settings->users) ? '' : $settings->users;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
21
 
 
22
  $args = array(
23
- 'paged' => is_front_page() ? get_query_var('page') : get_query_var('paged'),
24
  'posts_per_page' => $posts_per_page,
25
  'post_type' => $post_type,
26
  'orderby' => $order_by,
27
  'order' => $order,
28
  'author' => $users,
29
  'tax_query' => array('relation' => 'AND'),
30
- 'ignore_sticky_posts' => true
 
 
 
31
  );
32
 
33
  // Build the taxonomy query.
@@ -72,6 +93,18 @@ final class FLBuilderLoop {
72
  // Return the query.
73
  return $query;
74
  }
 
 
 
 
 
 
 
 
 
 
 
 
75
 
76
  /**
77
  * @method pagination
13
  */
14
  static public function query($settings)
15
  {
16
+ $posts_per_page = empty($settings->posts_per_page) ? 10 : $settings->posts_per_page;
17
+ $post_type = empty($settings->post_type) ? 'post' : $settings->post_type;
18
+ $order_by = empty($settings->order_by) ? 'date' : $settings->order_by;
19
+ $order = empty($settings->order) ? 'DESC' : $settings->order;
20
+ $users = empty($settings->users) ? '' : $settings->users;
21
+ $paged = is_front_page() ? get_query_var('page') : get_query_var('paged');
22
+
23
+ // Get the offset.
24
+ if ( ! isset( $settings->offset ) || ! is_int( ( int )$settings->offset ) ) {
25
+ $offset = 0;
26
+ }
27
+ else {
28
+ $offset = $settings->offset;
29
+ }
30
+
31
+ // Get the paged offset.
32
+ if ( $paged < 2 ) {
33
+ $paged_offset = $offset;
34
+ }
35
+ else {
36
+ $paged_offset = $offset + ( ( $paged - 1 ) * $posts_per_page );
37
+ }
38
 
39
+ // Build the query args.
40
  $args = array(
41
+ 'paged' => $paged,
42
  'posts_per_page' => $posts_per_page,
43
  'post_type' => $post_type,
44
  'orderby' => $order_by,
45
  'order' => $order,
46
  'author' => $users,
47
  'tax_query' => array('relation' => 'AND'),
48
+ 'ignore_sticky_posts' => true,
49
+ 'offset' => $paged_offset,
50
+ 'fl_original_offset' => $offset,
51
+ 'fl_builder_loop' => true
52
  );
53
 
54
  // Build the taxonomy query.
93
  // Return the query.
94
  return $query;
95
  }
96
+
97
+ /**
98
+ * @method found_posts
99
+ */
100
+ static public function found_posts( $found_posts, $query )
101
+ {
102
+ if ( isset( $query->query ) && isset( $query->query['fl_builder_loop'] ) ) {
103
+ return $found_posts - $query->query['fl_original_offset'];
104
+ }
105
+
106
+ return $found_posts;
107
+ }
108
 
109
  /**
110
  * @method pagination
classes/class-fl-builder-model.php CHANGED
@@ -624,25 +624,6 @@ final class FLBuilderModel {
624
  }
625
  }
626
 
627
- /**
628
- * Delete the asset cache if the domain has changed.
629
- *
630
- * @method delete_asset_cache_domain_change
631
- */
632
- static public function delete_asset_cache_domain_change()
633
- {
634
- $home_url = home_url();
635
- $saved_url = get_option( '_fl_builder_home_url' );
636
-
637
- if ( ! $saved_url ) {
638
- update_option( '_fl_builder_home_url', $home_url );
639
- }
640
- else if ( $home_url != $saved_url ) {
641
- self::delete_all_asset_cache();
642
- update_option( '_fl_builder_home_url', $home_url );
643
- }
644
- }
645
-
646
  /**
647
  * @method generate_node_id
648
  */
@@ -2478,6 +2459,9 @@ final class FLBuilderModel {
2478
 
2479
  // Get the templates array.
2480
  $templates = self::get_templates();
 
 
 
2481
 
2482
  // Get new ids for the nodes.
2483
  $settings->nodes = self::generate_new_node_ids($data);
@@ -2729,8 +2713,8 @@ final class FLBuilderModel {
2729
  $defaults = array(
2730
  'enabled' => true,
2731
  'tour' => true,
2732
- 'video' => false,
2733
- 'video_embed' => '<iframe width="420" height="315" src="https://www.youtube.com/embed/CNJbH2gaACo" frameborder="0" allowfullscreen></iframe>',
2734
  'knowledge_base' => true,
2735
  'knowledge_base_url' => 'https://www.wpbeaverbuilder.com/knowledge-base/?utm_source=external&utm_medium=builder&utm_campaign=docs-button',
2736
  'forums' => true,
@@ -2765,6 +2749,48 @@ final class FLBuilderModel {
2765
  }
2766
  }
2767
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2768
  /**
2769
  * @method plugin_basename
2770
  */
624
  }
625
  }
626
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
627
  /**
628
  * @method generate_node_id
629
  */
2459
 
2460
  // Get the templates array.
2461
  $templates = self::get_templates();
2462
+
2463
+ // Make sure we have an object.
2464
+ $settings = ( object )$settings;
2465
 
2466
  // Get new ids for the nodes.
2467
  $settings->nodes = self::generate_new_node_ids($data);
2713
  $defaults = array(
2714
  'enabled' => true,
2715
  'tour' => true,
2716
+ 'video' => true,
2717
+ 'video_embed' => '<iframe src="https://player.vimeo.com/video/124230072?autoplay=1" width="420" height="315" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>',
2718
  'knowledge_base' => true,
2719
  'knowledge_base_url' => 'https://www.wpbeaverbuilder.com/knowledge-base/?utm_source=external&utm_medium=builder&utm_campaign=docs-button',
2720
  'forums' => true,
2749
  }
2750
  }
2751
 
2752
+ /**
2753
+ * @method get_services
2754
+ */
2755
+ static public function get_services()
2756
+ {
2757
+ return get_option( '_fl_builder_services', array() );
2758
+ }
2759
+
2760
+ /**
2761
+ * @method update_services
2762
+ */
2763
+ static public function update_services( $service, $account, $data )
2764
+ {
2765
+ $services = self::get_services();
2766
+ $account = sanitize_text_field( $account );
2767
+
2768
+ if ( ! isset( $services[ $service ] ) ) {
2769
+ $services[ $service ] = array();
2770
+ }
2771
+
2772
+ $services[ $service ][ $account ] = $data;
2773
+
2774
+ update_option( '_fl_builder_services', $services );
2775
+ }
2776
+
2777
+ /**
2778
+ * @method delete_service_account
2779
+ */
2780
+ static public function delete_service_account( $service, $account )
2781
+ {
2782
+ $services = self::get_services();
2783
+
2784
+ if ( isset( $services[ $service ][ $account ] ) ) {
2785
+ unset( $services[ $service ][ $account ] );
2786
+ }
2787
+ if ( 0 === count( $services[ $service ] ) ) {
2788
+ unset( $services[ $service ] );
2789
+ }
2790
+
2791
+ update_option( '_fl_builder_services', $services );
2792
+ }
2793
+
2794
  /**
2795
  * @method plugin_basename
2796
  */
classes/class-fl-builder-photo.php CHANGED
@@ -55,10 +55,13 @@ final class FLBuilderPhoto {
55
  */
56
  static public function get_thumb($photo)
57
  {
58
- if(empty($photo)) {
59
  echo FL_BUILDER_URL . 'img/spacer.png';
60
  }
61
- else if(!empty($photo->sizes->thumbnail)) {
 
 
 
62
  echo $photo->sizes->thumbnail->url;
63
  }
64
  else {
@@ -71,20 +74,26 @@ final class FLBuilderPhoto {
71
  */
72
  static public function get_src_options($selected, $photo)
73
  {
74
- $titles = array(
75
- 'full' => _x( 'Full Size', 'Image size.', 'fl-builder' ),
76
- 'large' => _x( 'Large', 'Image size.', 'fl-builder' ),
77
- 'medium' => _x( 'Medium', 'Image size.', 'fl-builder' ),
78
- 'thumbnail' => _x( 'Thumbnail', 'Image size.', 'fl-builder' )
79
- );
80
-
81
- foreach($photo->sizes as $key => $val) {
82
-
83
- if(!isset($titles[$key])) {
84
- $titles[$key] = ucwords(str_replace(array('_', '-'), ' ', $key));
85
- }
86
-
87
- echo '<option value="' . $val->url . '" ' . selected($selected, $val->url) . '>' . $titles[$key] . ' - ' . $val->width . ' x ' . $val->height . '</option>';
88
- }
 
 
 
 
 
 
89
  }
90
  }
55
  */
56
  static public function get_thumb($photo)
57
  {
58
+ if ( empty( $photo ) ) {
59
  echo FL_BUILDER_URL . 'img/spacer.png';
60
  }
61
+ else if ( ! isset( $photo->sizes ) ) {
62
+ echo $photo->url;
63
+ }
64
+ else if ( ! empty( $photo->sizes->thumbnail ) ) {
65
  echo $photo->sizes->thumbnail->url;
66
  }
67
  else {
74
  */
75
  static public function get_src_options($selected, $photo)
76
  {
77
+ if ( ! isset( $photo->sizes ) ) {
78
+ echo '<option value="' . $photo->url . '" selected="selected">' . _x( 'Full Size', 'Image size.', 'fl-builder' ) . '</option>';
79
+ }
80
+ else {
81
+
82
+ $titles = array(
83
+ 'full' => _x( 'Full Size', 'Image size.', 'fl-builder' ),
84
+ 'large' => _x( 'Large', 'Image size.', 'fl-builder' ),
85
+ 'medium' => _x( 'Medium', 'Image size.', 'fl-builder' ),
86
+ 'thumbnail' => _x( 'Thumbnail', 'Image size.', 'fl-builder' )
87
+ );
88
+
89
+ foreach($photo->sizes as $key => $val) {
90
+
91
+ if(!isset($titles[$key])) {
92
+ $titles[$key] = ucwords(str_replace(array('_', '-'), ' ', $key));
93
+ }
94
+
95
+ echo '<option value="' . $val->url . '" ' . selected($selected, $val->url) . '>' . $titles[$key] . ' - ' . $val->width . ' x ' . $val->height . '</option>';
96
+ }
97
+ }
98
  }
99
  }
classes/class-fl-builder-service-aweber.php ADDED
@@ -0,0 +1,255 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Helper class for the AWeber API.
5
+ *
6
+ * @since 1.5.4
7
+ */
8
+ final class FLBuilderServiceAWeber extends FLBuilderService {
9
+
10
+ /**
11
+ * The ID for this service.
12
+ *
13
+ * @since 1.5.4
14
+ * @var string $id
15
+ */
16
+ public $id = 'aweber';
17
+
18
+ /**
19
+ * @since 1.5.4
20
+ * @var object $api_instance
21
+ * @access private
22
+ */
23
+ private $api_instance = null;
24
+
25
+ /**
26
+ * Get an instance of the API.
27
+ *
28
+ * @since 1.5.4
29
+ * @param string $auth_code A valid authorization code.
30
+ * @return object The API instance.
31
+ */
32
+ public function get_api( $auth_code )
33
+ {
34
+ if ( $this->api_instance ) {
35
+ return $this->api_instance;
36
+ }
37
+ if ( ! class_exists( 'AWeberAPI' ) ) {
38
+ require_once FL_BUILDER_DIR . 'includes/vendor/aweber/aweber_api.php';
39
+ }
40
+
41
+ list( $auth_key, $auth_token, $req_key, $req_token, $oauth ) = explode( '|', $auth_code );
42
+
43
+ $this->api_instance = new AWeberAPI( $auth_key, $auth_token );
44
+ $this->api_instance->user->requestToken = $req_key;
45
+ $this->api_instance->user->tokenSecret = $req_token;
46
+ $this->api_instance->user->verifier = $oauth;
47
+
48
+ return $this->api_instance;
49
+ }
50
+
51
+ /**
52
+ * Test the API connection.
53
+ *
54
+ * @since 1.5.4
55
+ * @param array $fields {
56
+ * @type string $auth_code A valid authorization code.
57
+ * }
58
+ * @return array{
59
+ * @type bool|string $error The error message or false if no error.
60
+ * @type array $data An array of data used to make the connection.
61
+ * }
62
+ */
63
+ public function connect( $fields = array() )
64
+ {
65
+ $response = array(
66
+ 'error' => false,
67
+ 'data' => array()
68
+ );
69
+
70
+ // Make sure we have an authorization code.
71
+ if ( ! isset( $fields['auth_code'] ) || empty( $fields['auth_code'] ) ) {
72
+ $response['error'] = __( 'Error: You must provide an Authorization Code.', 'fl-builder' );
73
+ }
74
+ // Make sure we have a valid authorization code.
75
+ else if ( 6 != count( explode( '|', $fields['auth_code'] ) ) ) {
76
+ $response['error'] = __( 'Error: Please enter a valid Authorization Code.', 'fl-builder' );
77
+ }
78
+ // Try to connect and store the connection data.
79
+ else {
80
+
81
+ $api = $this->get_api( $fields['auth_code'] );
82
+
83
+ // Get an access token from the API.
84
+ try {
85
+ list( $access_token, $access_token_secret ) = $api->getAccessToken();
86
+ }
87
+ catch ( AWeberException $e ) {
88
+ $response['error'] = $e->getMessage();
89
+ }
90
+
91
+ // Make sure we can get the account.
92
+ try {
93
+ $account = $api->getAccount();
94
+ }
95
+ catch ( AWeberException $e ) {
96
+ $response['error'] = $e->getMessage();
97
+ }
98
+
99
+ // Build the response data.
100
+ if ( ! $response['error'] ) {
101
+
102
+ $response['data'] = array(
103
+ 'auth_code' => $fields['auth_code'],
104
+ 'access_token' => $access_token,
105
+ 'access_secret' => $access_token_secret
106
+ );
107
+ }
108
+ }
109
+
110
+ return $response;
111
+ }
112
+
113
+ /**
114
+ * Renders the markup for the connection settings.
115
+ *
116
+ * @since 1.5.4
117
+ * @return string The connection settings markup.
118
+ */
119
+ public function render_connect_settings()
120
+ {
121
+ ob_start();
122
+
123
+ FLBuilder::render_settings_field( 'auth_code', array(
124
+ 'row_class' => 'fl-builder-service-connect-row',
125
+ 'class' => 'fl-builder-service-connect-input',
126
+ 'type' => 'text',
127
+ 'label' => __( 'Authorization Code', 'fl-builder' ),
128
+ 'description' => sprintf( __( 'Please register this website with AWeber to get your Authorization Code. <a%s>Register Now</a>', 'fl-builder' ), ' href="https://auth.aweber.com/1.0/oauth/authorize_app/baa1f131" target="_blank"' ),
129
+ 'preview' => array(
130
+ 'type' => 'none'
131
+ )
132
+ ));
133
+
134
+ return ob_get_clean();
135
+ }
136
+
137
+ /**
138
+ * Render the markup for service specific fields.
139
+ *
140
+ * @since 1.5.4
141
+ * @param string $account The name of the saved account.
142
+ * @param object $settings Saved module settings.
143
+ * @return array {
144
+ * @type bool|string $error The error message or false if no error.
145
+ * @type string $html The field markup.
146
+ * }
147
+ */
148
+ public function render_fields( $account, $settings )
149
+ {
150
+ $account_data = $this->get_account_data( $account );
151
+ $api = $this->get_api( $account_data['auth_code'] );
152
+ $response = array(
153
+ 'error' => false,
154
+ 'html' => ''
155
+ );
156
+
157
+ try {
158
+ $account = $api->getAccount( $account_data['access_token'], $account_data['access_secret'] );
159
+ $lists = $account->loadFromUrl( '/accounts/' . $account->id . '/lists' );
160
+ $response['html'] = $this->render_list_field( $lists, $settings );
161
+ }
162
+ catch ( AWeberException $e ) {
163
+ $response['error'] = $e->getMessage();
164
+ }
165
+
166
+ return $response;
167
+ }
168
+
169
+ /**
170
+ * Render markup for the list field.
171
+ *
172
+ * @since 1.5.4
173
+ * @param array $lists List data from the API.
174
+ * @param object $settings Saved module settings.
175
+ * @return string The markup for the list field.
176
+ * @access private
177
+ */
178
+ private function render_list_field( $lists, $settings )
179
+ {
180
+ ob_start();
181
+
182
+ $options = array( '' => __( 'Choose...', 'fl-builder' ) );
183
+
184
+ foreach ( $lists->data['entries'] as $list ) {
185
+ $options[ $list['id'] ] = $list['name'];
186
+ }
187
+
188
+ FLBuilder::render_settings_field( 'list_id', array(
189
+ 'row_class' => 'fl-builder-service-field-row',
190
+ 'class' => 'fl-builder-service-list-select',
191
+ 'type' => 'select',
192
+ 'label' => __( 'List', 'fl-builder' ),
193
+ 'options' => $options,
194
+ 'preview' => array(
195
+ 'type' => 'none'
196
+ )
197
+ ), $settings);
198
+
199
+ return ob_get_clean();
200
+ }
201
+
202
+ /**
203
+ * Subscribe an email address to AWeber.
204
+ *
205
+ * @since 1.5.4
206
+ * @param object $settings A module settings object.
207
+ * @param string $email The email to subscribe.
208
+ * @param string $name Optional. The full name of the person subscribing.
209
+ * @return array {
210
+ * @type bool|string $error The error message or false if no error.
211
+ * }
212
+ */
213
+ public function subscribe( $settings, $email, $name = false )
214
+ {
215
+ $account_data = $this->get_account_data( $settings->service_account );
216
+ $response = array( 'error' => false );
217
+
218
+ if ( ! $account_data ) {
219
+ $response['error'] = __( 'There was an error subscribing to AWeber. The account is no longer connected.', 'fl-builder' );
220
+ }
221
+ else {
222
+
223
+ $api = $this->get_api( $account_data['auth_code'] );
224
+ $data = array(
225
+ 'ws.op' => 'create',
226
+ 'email' => $email
227
+ );
228
+
229
+ if ( $name ) {
230
+ $data['name'] = $name;
231
+ }
232
+
233
+ try {
234
+ $account = $api->getAccount( $account_data['access_token'], $account_data['access_secret'] );
235
+ $url = '/accounts/' . $account->id . '/lists/' . $settings->list_id . '/subscribers';
236
+ $result = $api->adapter->request( 'POST', $url, $data, array( 'return' => 'headers' ) );
237
+
238
+ if ( is_array( $result ) && isset( $result['Status-Code'] ) && 201 == $result['Status-Code'] ) {
239
+ return $response;
240
+ }
241
+ else {
242
+ $response['error'] = __( 'There was an error connecting to AWeber. Please try again.', 'fl-builder' );
243
+ }
244
+ }
245
+ catch ( AWeberAPIException $e ) {
246
+ $response['error'] = sprintf(
247
+ __( 'There was an error subscribing to AWeber. %s', 'fl-builder' ),
248
+ $e->getMessage()
249
+ );
250
+ }
251
+ }
252
+
253
+ return $response;
254
+ }
255
+ }
classes/class-fl-builder-service-campaign-monitor.php ADDED
@@ -0,0 +1,259 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Helper class for the Campaign Monitor API.
5
+ *
6
+ * @since 1.5.4
7
+ */
8
+ final class FLBuilderServiceCampaignMonitor extends FLBuilderService {
9
+
10
+ /**
11
+ * The ID for this service.
12
+ *
13
+ * @since 1.5.4
14
+ * @var string $id
15
+ */
16
+ public $id = 'campaign-monitor';
17
+
18
+ /**
19
+ * Constructor function.
20
+ *
21
+ * @since 1.5.4
22
+ * @return void
23
+ */
24
+ public function __construct()
25
+ {
26
+ if ( ! class_exists( 'CS_REST_General' ) ) {
27
+ require_once FL_BUILDER_DIR . 'includes/vendor/campaign-monitor/csrest_general.php';
28
+ require_once FL_BUILDER_DIR . 'includes/vendor/campaign-monitor/csrest_clients.php';
29
+ require_once FL_BUILDER_DIR . 'includes/vendor/campaign-monitor/csrest_lists.php';
30
+ require_once FL_BUILDER_DIR . 'includes/vendor/campaign-monitor/csrest_subscribers.php';
31
+ }
32
+ }
33
+
34
+ /**
35
+ * Test the API connection.
36
+ *
37
+ * @since 1.5.4
38
+ * @param array $fields {
39
+ * @type string $api_key A valid API key.
40
+ * }
41
+ * @return array{
42
+ * @type bool|string $error The error message or false if no error.
43
+ * @type array $data An array of data used to make the connection.
44
+ * }
45
+ */
46
+ public function connect( $fields = array() )
47
+ {
48
+ $response = array(
49
+ 'error' => false,
50
+ 'data' => array()
51
+ );
52
+
53
+ // Make sure we have an API key.
54
+ if ( ! isset( $fields['api_key'] ) || empty( $fields['api_key'] ) ) {
55
+ $response['error'] = __( 'Error: You must provide an API key.', 'fl-builder' );
56
+ }
57
+ // Try to connect and store the connection data.
58
+ else {
59
+
60
+ $api = new CS_REST_General( array( 'api_key' => $fields['api_key'] ) );
61
+ $result = $api->get_clients();
62
+
63
+ if ( $result->was_successful() ) {
64
+ $response['data'] = array( 'api_key' => $fields['api_key'] );
65
+ }
66
+ else {
67
+ $response['error'] = __( 'Error: Please check your API key.', 'fl-builder' );
68
+ }
69
+ }
70
+
71
+ return $response;
72
+ }
73
+
74
+ /**
75
+ * Renders the markup for the connection settings.
76
+ *
77
+ * @since 1.5.4
78
+ * @return string The connection settings markup.
79
+ */
80
+ public function render_connect_settings()
81
+ {
82
+ ob_start();
83
+
84
+ FLBuilder::render_settings_field( 'api_key', array(
85
+ 'row_class' => 'fl-builder-service-connect-row',
86
+ 'class' => 'fl-builder-service-connect-input',
87
+ 'type' => 'text',
88
+ 'label' => __( 'API Key', 'fl-builder' ),
89
+ 'help' => __( 'Your API key can be found in your Campaign Monitor account under Account Settings > API Key.', 'fl-builder' ),
90
+ 'preview' => array(
91
+ 'type' => 'none'
92
+ )
93
+ ));
94
+
95
+ return ob_get_clean();
96
+ }
97
+
98
+ /**
99
+ * Render the markup for service specific fields.
100
+ *
101
+ * @since 1.5.4
102
+ * @param string $account The name of the saved account.
103
+ * @param object $settings Saved module settings.
104
+ * @return array {
105
+ * @type bool|string $error The error message or false if no error.
106
+ * @type string $html The field markup.
107
+ * }
108
+ */
109
+ public function render_fields( $account, $settings )
110
+ {
111
+ $post_data = FLBuilderModel::get_post_data();
112
+ $account_data = $this->get_account_data( $account );
113
+ $api = new CS_REST_General( $account_data );
114
+ $result = $api->get_clients();
115
+ $response = array(
116
+ 'error' => false,
117
+ 'html' => ''
118
+ );
119
+
120
+ if ( $result->was_successful() ) {
121
+
122
+ if ( ! isset( $post_data['client'] ) ) {
123
+ $response['html'] .= $this->render_client_field( $result, $settings );
124
+ }
125
+
126
+ $response['html'] .= $this->render_list_field( $account_data, $settings );
127
+ }
128
+ else {
129
+ $response['error'] = __( 'Error: Please check your API key.', 'fl-builder' );
130
+ }
131
+
132
+ return $response;
133
+ }
134
+
135
+ /**
136
+ * Render markup for the client field.
137
+ *
138
+ * @since 1.5.4
139
+ * @param array $clients Client data from the API.
140
+ * @param object $settings Saved module settings.
141
+ * @return string The markup for the list field.
142
+ * @access private
143
+ */
144
+ private function render_client_field( $clients, $settings )
145
+ {
146
+ ob_start();
147
+
148
+ $options = array( '' => __( 'Choose...', 'fl-builder' ) );
149
+
150
+ foreach ( $clients->response as $client ) {
151
+ $options[ $client->ClientID ] = $client->Name;
152
+ }
153
+
154
+ FLBuilder::render_settings_field( 'client_id', array(
155
+ 'row_class' => 'fl-builder-service-field-row',
156
+ 'class' => 'fl-builder-campaign-monitor-client-select',
157
+ 'type' => 'select',
158
+ 'label' => __( 'Client', 'fl-builder' ),
159
+ 'options' => $options,
160
+ 'preview' => array(
161
+ 'type' => 'none'
162
+ )
163
+ ), $settings);
164
+
165
+ return ob_get_clean();
166
+ }
167
+
168
+ /**
169
+ * Render markup for the list field.
170
+ *
171
+ * @since 1.5.4
172
+ * @param array $account_data Saved account data.
173
+ * @param object $settings Saved module settings.
174
+ * @return string The markup for the list field.
175
+ * @access private
176
+ */
177
+ private function render_list_field( $account_data, $settings )
178
+ {
179
+ $post_data = FLBuilderModel::get_post_data();
180
+
181
+ // Get the client ID. Return an empty string if we don't have one yet.
182
+ if ( isset( $post_data['client'] ) ) {
183
+ $client_id = $post_data['client'];
184
+ }
185
+ else if ( isset( $settings->client_id ) ) {
186
+ $client_id = $settings->client_id;
187
+ }
188
+ else {
189
+ return '';
190
+ }
191
+
192
+ // Get the list data.
193
+ $api = new CS_REST_Clients( $client_id, $account_data );
194
+ $lists = $api->get_lists();
195
+
196
+ // Render the list field.
197
+ ob_start();
198
+
199
+ $options = array( '' => __( 'Choose...', 'fl-builder' ) );
200
+
201
+ foreach ( $lists->response as $list ) {
202
+ $options[ $list->ListID ] = $list->Name;
203
+ }
204
+
205
+ FLBuilder::render_settings_field( 'list_id', array(
206
+ 'row_class' => 'fl-builder-service-field-row',
207
+ 'class' => 'fl-builder-service-list-select',
208
+ 'type' => 'select',
209
+ 'label' => __( 'List', 'fl-builder' ),
210
+ 'options' => $options,
211
+ 'preview' => array(
212
+ 'type' => 'none'
213
+ )
214
+ ), $settings);
215
+
216
+ return ob_get_clean();
217
+ }
218
+
219
+ /**
220
+ * Subscribe an email address to Campaign Monitor.
221
+ *
222
+ * @since 1.5.4
223
+ * @param object $settings A module settings object.
224
+ * @param string $email The email to subscribe.
225
+ * @param string $name Optional. The full name of the person subscribing.
226
+ * @return array {
227
+ * @type bool|string $error The error message or false if no error.
228
+ * }
229
+ */
230
+ public function subscribe( $settings, $email, $name = false )
231
+ {
232
+ $account_data = $this->get_account_data( $settings->service_account );
233
+ $response = array( 'error' => false );
234
+
235
+ if ( ! $account_data ) {
236
+ $response['error'] = __( 'There was an error subscribing to Campaign Monitor. The account is no longer connected.', 'fl-builder' );
237
+ }
238
+ else {
239
+
240
+ $api = new CS_Rest_Subscribers( $settings->list_id, $account_data );
241
+ $data = array(
242
+ 'EmailAddress' => $email,
243
+ 'Resubscribe' => true
244
+ );
245
+
246
+ if ( $name ) {
247
+ $data['Name'] = $name;
248
+ }
249
+
250
+ $result = $api->add( $data );
251
+
252
+ if ( ! $result->was_successful() ) {
253
+ $response['error'] = __( 'There was an error subscribing to Campaign Monitor.', 'fl-builder' );
254
+ }
255
+ }
256
+
257
+ return $response;
258
+ }
259
+ }
classes/class-fl-builder-service-constant-contact.php ADDED
@@ -0,0 +1,286 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Helper class for the Constant Contact API.
5
+ *
6
+ * @since 1.5.4
7
+ */
8
+ final class FLBuilderServiceConstantContact extends FLBuilderService {
9
+
10
+ /**
11
+ * The ID for this service.
12
+ *
13
+ * @since 1.5.4
14
+ * @var string $id
15
+ */
16
+ public $id = 'constant-contact';
17
+
18
+ /**
19
+ * The api url for this service.
20
+ *
21
+ * @since 1.5.4
22
+ * @var string $api_url
23
+ */
24
+ public $api_url = 'https://api.constantcontact.com/v2/';
25
+
26
+ /**
27
+ * Test the API connection.
28
+ *
29
+ * @since 1.5.4
30
+ * @param array $fields {
31
+ * @type string $api_key A valid API key.
32
+ * @type string $access_token A valid access token.
33
+ * }
34
+ * @return array{
35
+ * @type bool|string $error The error message or false if no error.
36
+ * @type array $data An array of data used to make the connection.
37
+ * }
38
+ */
39
+ public function connect( $fields = array() )
40
+ {
41
+ $response = array(
42
+ 'error' => false,
43
+ 'data' => array()
44
+ );
45
+
46
+ // Make sure we have an API key.
47
+ if ( ! isset( $fields['api_key'] ) || empty( $fields['api_key'] ) ) {
48
+ $response['error'] = __( 'Error: You must provide an API key.', 'fl-builder' );
49
+ }
50
+ // Make sure we have an access token.
51
+ else if ( ! isset( $fields['access_token'] ) || empty( $fields['access_token'] ) ) {
52
+ $response['error'] = __( 'Error: You must provide an access token.', 'fl-builder' );
53
+ }
54
+ // Try to connect and store the connection data.
55
+ else {
56
+
57
+ $url = $this->api_url . 'lists?api_key=' . $fields['api_key'] . '&access_token=' . $fields['access_token'];
58
+ $request = json_decode( wp_remote_retrieve_body( wp_remote_get( $url ) ) );
59
+
60
+ if ( ! is_array( $request ) || ( isset( $request[0] ) && isset( $request[0]->error_message ) ) ) {
61
+ $response['error'] = sprintf( __( 'Error: Could not connect to Constant Contact. %s', 'fl-builder' ), $request[0]->error_message );
62
+ }
63
+ else {
64
+ $response['data'] = array(
65
+ 'api_key' => $fields['api_key'],
66
+ 'access_token' => $fields['access_token']
67
+ );
68
+ }
69
+ }
70
+
71
+ return $response;
72
+ }
73
+
74
+ /**
75
+ * Renders the markup for the connection settings.
76
+ *
77
+ * @since 1.5.4
78
+ * @return string The connection settings markup.
79
+ */
80
+ public function render_connect_settings()
81
+ {
82
+ ob_start();
83
+
84
+ FLBuilder::render_settings_field( 'api_key', array(
85
+ 'row_class' => 'fl-builder-service-connect-row',
86
+ 'class' => 'fl-builder-service-connect-input',
87
+ 'type' => 'text',
88
+ 'label' => __( 'API Key', 'fl-builder' ),
89
+ 'help' => __( 'Your Constant Contact API key.', 'fl-builder' ),
90
+ 'preview' => array(
91
+ 'type' => 'none'
92
+ )
93
+ ));
94
+
95
+ FLBuilder::render_settings_field( 'access_token', array(
96
+ 'row_class' => 'fl-builder-service-connect-row',
97
+ 'class' => 'fl-builder-service-connect-input',
98
+ 'type' => 'text',
99
+ 'label' => __( 'Access Token', 'fl-builder' ),
100
+ 'help' => __( 'Your Constant Contact access token.', 'fl-builder' ),
101
+ 'description' => sprintf( __( 'You must register a <a%s>Developer Account</a> with Constant Contact to obtain an API key and access token. Please see <a%s>Getting an API key</a> for complete instructions.', 'fl-builder' ), ' href="https://constantcontact.mashery.com/member/register" target="_blank"', ' href="https://developer.constantcontact.com/home/api-keys.html" target="_blank"' ),
102
+ 'preview' => array(
103
+ 'type' => 'none'
104
+ )
105
+ ));
106
+
107
+ return ob_get_clean();
108
+ }
109
+
110
+ /**
111
+ * Render the markup for service specific fields.
112
+ *
113
+ * @since 1.5.4
114
+ * @param string $account The name of the saved account.
115
+ * @param object $settings Saved module settings.
116
+ * @return array {
117
+ * @type bool|string $error The error message or false if no error.
118
+ * @type string $html The field markup.
119
+ * }
120
+ */
121
+ public function render_fields( $account, $settings )
122
+ {
123
+ $account_data = $this->get_account_data( $account );
124
+ $api_key = $account_data['api_key'];
125
+ $access_token = $account_data['access_token'];
126
+ $url = $this->api_url . 'lists?api_key=' . $api_key . '&access_token=' . $access_token;
127
+ $request = json_decode( wp_remote_retrieve_body( wp_remote_get( $url ) ) );
128
+ $response = array(
129
+ 'error' => false,
130
+ 'html' => ''
131
+ );
132
+
133
+ if ( ! is_array( $request ) || ( isset( $request[0] ) && isset( $request[0]->error_message ) ) ) {
134
+ $response['error'] = sprintf( __( 'Error: Could not connect to Constant Contact. %s', 'fl-builder' ), $request[0]->error_message );
135
+ }
136
+ else {
137
+ $response['html'] = $this->render_list_field( $request, $settings );
138
+ }
139
+
140
+ return $response;
141
+ }
142
+
143
+ /**
144
+ * Render markup for the list field.
145
+ *
146
+ * @since 1.5.4
147
+ * @param array $lists List data from the API.
148
+ * @param object $settings Saved module settings.
149
+ * @return string The markup for the list field.
150
+ * @access private
151
+ */
152
+ private function render_list_field( $lists, $settings )
153
+ {
154
+ ob_start();
155
+
156
+ $options = array( '' => __( 'Choose...', 'fl-builder' ) );
157
+
158
+ foreach ( $lists as $list ) {
159
+ $options[ $list->id ] = $list->name;
160
+ }
161
+
162
+ FLBuilder::render_settings_field( 'list_id', array(
163
+ 'row_class' => 'fl-builder-service-field-row',
164
+ 'class' => 'fl-builder-service-list-select',
165
+ 'type' => 'select',
166
+ 'label' => __( 'List', 'fl-builder' ),
167
+ 'options' => $options,
168
+ 'preview' => array(
169
+ 'type' => 'none'
170
+ )
171
+ ), $settings);
172
+
173
+ return ob_get_clean();
174
+ }
175
+
176
+ /**
177
+ * Subscribe an email address to Constant Contact.
178
+ *
179
+ * @since 1.5.4
180
+ * @param object $settings A module settings object.
181
+ * @param string $email The email to subscribe.
182
+ * @param string $name Optional. The full name of the person subscribing.
183
+ * @return array {
184
+ * @type bool|string $error The error message or false if no error.
185
+ * }
186
+ */
187
+ public function subscribe( $settings, $email, $name = false )
188
+ {
189
+ $account_data = $this->get_account_data( $settings->service_account );
190
+ $response = array( 'error' => false );
191
+
192
+ if ( ! $account_data ) {
193
+ $response['error'] = __( 'There was an error subscribing to Constant Contact. The account is no longer connected.', 'fl-builder' );
194
+ }
195
+ else {
196
+
197
+ $api_key = $account_data['api_key'];
198
+ $access_token = $account_data['access_token'];
199
+ $url = $this->api_url . 'contacts?api_key=' . $api_key . '&access_token=' . $access_token . '&email=' . $email;
200
+ $request = wp_remote_get( $url );
201
+ $contact = json_decode( wp_remote_retrieve_body( $request ) );
202
+ $list_id = $settings->list_id;
203
+
204
+ // This contact exists.
205
+ if ( ! empty( $contact->results ) ) {
206
+
207
+ $args = array();
208
+ $data = $contact->results[0];
209
+
210
+ // Check if already subscribed to this list.
211
+ if ( ! empty( $data->lists ) ) {
212
+
213
+ // Return early if already added.
214
+ foreach ( $data->lists as $key => $list ) {
215
+ if ( isset( $list->id ) && $list_id == $list->id ) {
216
+ return $response;
217
+ }
218
+ }
219
+
220
+ // Add an existing contact to the list.
221
+ $new_list = new stdClass;
222
+ $new_list->id = $list_id;
223
+ $new_list->status = 'ACTIVE';
224
+ $data->lists[ count( $data->lists ) ] = $new_list;
225
+ }
226
+ else {
227
+
228
+ // Add an existing contact that has no list.
229
+ $data->lists = array();
230
+ $new_list = new stdClass;
231
+ $new_list->id = $list_id;
232
+ $new_list->status = 'ACTIVE';
233
+ $data->lists[0] = $new_list;
234
+ }
235
+
236
+ $args['body'] = json_encode( $data );
237
+ $args['method'] = 'PUT';
238
+ $args['headers']['Content-Type'] = 'application/json';
239
+ $args['headers']['Content-Length'] = strlen( $args['body'] );
240
+ $url = $this->api_url . 'contacts/' . $contact->results[0]->id . '?api_key=' . $api_key . '&access_token=' . $access_token . '&action_by=ACTION_BY_VISITOR';
241
+ $update = wp_remote_request( $url, $args );
242
+ $res = json_decode( wp_remote_retrieve_body( $update ) );
243
+
244
+ if ( isset( $res->error_key ) ) {
245
+ $response['error'] = sprintf( __( 'There was an error subscribing to Constant Contact. %s', 'fl-builder' ), $res->error_key );
246
+ }
247
+ }
248
+ // Add a new contact.
249
+ else {
250
+
251
+ $args = $data = array();
252
+ $data['email_addresses'] = array();
253
+ $data['email_addresses'][0]['id'] = $list_id;
254
+ $data['email_addresses'][0]['status'] = 'ACTIVE';
255
+ $data['email_addresses'][0]['confirm_status'] = 'CONFIRMED';
256
+ $data['email_addresses'][0]['email_address'] = $email;
257
+ $data['lists'] = array();
258
+ $data['lists'][0]['id'] = $list_id;
259
+
260
+ if ( $name ) {
261
+
262
+ $names = explode( ' ', $name );
263
+
264
+ if ( isset( $names[0] ) ) {
265
+ $data['first_name'] = $names[0];
266
+ }
267
+ if ( isset( $names[1] ) ) {
268
+ $data['last_name'] = $names[1];
269
+ }
270
+ }
271
+
272
+ $args['body'] = json_encode( $data );
273
+ $args['headers']['Content-Type'] = 'application/json';
274
+ $args['headers']['Content-Length'] = strlen( json_encode( $data ) );
275
+ $url = $this->api_url . 'contacts?api_key=' . $api_key . '&access_token=' . $access_token . '&action_by=ACTION_BY_VISITOR';
276
+ $create = wp_remote_post( $url, $args );
277
+
278
+ if ( isset( $create->error_key ) ) {
279
+ $response['error'] = sprintf( __( 'There was an error subscribing to Constant Contact. %s', 'fl-builder' ), $create->error_key );
280
+ }
281
+ }
282
+ }
283
+
284
+ return $response;
285
+ }
286
+ }
classes/class-fl-builder-service-getresponse.php ADDED
@@ -0,0 +1,210 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Helper class for the GetResponse API.
5
+ *
6
+ * @since 1.5.4
7
+ */
8
+ final class FLBuilderServiceGetResponse extends FLBuilderService {
9
+
10
+ /**
11
+ * The ID for this service.
12
+ *
13
+ * @since 1.5.4
14
+ * @var string $id
15
+ */
16
+ public $id = 'getresponse';
17
+
18
+ /**
19
+ * @since 1.5.4
20
+ * @var object $api_instance
21
+ * @access private
22
+ */
23
+ private $api_instance = null;
24
+
25
+ /**
26
+ * Get an instance of the API.
27
+ *
28
+ * @since 1.5.4
29
+ * @param string $api_key A valid API key.
30
+ * @return object The API instance.
31
+ */
32
+ public function get_api( $api_key )
33
+ {
34
+ if ( $this->api_instance ) {
35
+ return $this->api_instance;
36
+ }
37
+ if ( ! class_exists( 'GetResponse' ) ) {
38
+ require_once FL_BUILDER_DIR . 'includes/vendor/getresponse/getresponse.php';
39
+ }
40
+
41
+ $this->api_instance = new GetResponse( $api_key );
42
+
43
+ return $this->api_instance;
44
+ }
45
+
46
+ /**
47
+ * Test the API connection.
48
+ *
49
+ * @since 1.5.4
50
+ * @param array $fields {
51
+ * @type string $api_key A valid API key.
52
+ * }
53
+ * @return array{
54
+ * @type bool|string $error The error message or false if no error.
55
+ * @type array $data An array of data used to make the connection.
56
+ * }
57
+ */
58
+ public function connect( $fields = array() )
59
+ {
60
+ $response = array(
61
+ 'error' => false,
62
+ 'data' => array()
63
+ );
64
+
65
+ // Make sure we have an API key.
66
+ if ( ! isset( $fields['api_key'] ) || empty( $fields['api_key'] ) ) {
67
+ $response['error'] = __( 'Error: You must provide an API key.', 'fl-builder' );
68
+ }
69
+ // Try to connect and store the connection data.
70
+ else {
71
+
72
+ $api = $this->get_api( $fields['api_key'] );
73
+ $ping = $api->ping();
74
+
75
+ if ( ! $ping ) {
76
+ $response['error'] = __( 'Error: Please check your API key.', 'fl-builder' );
77
+ }
78
+ else {
79
+ $response['data'] = array( 'api_key' => $fields['api_key'] );
80
+ }
81
+ }
82
+
83
+ return $response;
84
+ }
85
+
86
+ /**
87
+ * Renders the markup for the connection settings.
88
+ *
89
+ * @since 1.5.4
90
+ * @return string The connection settings markup.
91
+ */
92
+ public function render_connect_settings()
93
+ {
94
+ ob_start();
95
+
96
+ FLBuilder::render_settings_field( 'api_key', array(
97
+ 'row_class' => 'fl-builder-service-connect-row',
98
+ 'class' => 'fl-builder-service-connect-input',
99
+ 'type' => 'text',
100
+ 'label' => __( 'API Key', 'fl-builder' ),
101
+ 'help' => __( 'Your API key can be found in your GetResponse account under My Account > GetResponse API.', 'fl-builder' ),
102
+ 'preview' => array(
103
+ 'type' => 'none'
104
+ )
105
+ ));
106
+
107
+ return ob_get_clean();
108
+ }
109
+
110
+ /**
111
+ * Render the markup for service specific fields.
112
+ *
113
+ * @since 1.5.4
114
+ * @param string $account The name of the saved account.
115
+ * @param object $settings Saved module settings.
116
+ * @return array {
117
+ * @type bool|string $error The error message or false if no error.
118
+ * @type string $html The field markup.
119
+ * }
120
+ */
121
+ public function render_fields( $account, $settings )
122
+ {
123
+ $account_data = $this->get_account_data( $account );
124
+ $api = $this->get_api( $account_data['api_key'] );
125
+ $lists = $api->getCampaigns();
126
+ $response = array(
127
+ 'error' => false,
128
+ 'html' => ''
129
+ );
130
+
131
+ if ( ! $lists ) {
132
+ $response['error'] = __( 'Error: Please check your API key.', 'fl-builder' );
133
+ }
134
+ else {
135
+ $response['html'] = $this->render_list_field( $lists, $settings );
136
+ }
137
+
138
+ return $response;
139
+ }
140
+
141
+ /**
142
+ * Render markup for the list field.
143
+ *
144
+ * @since 1.5.4
145
+ * @param array $lists List data from the API.
146
+ * @param object $settings Saved module settings.
147
+ * @return string The markup for the list field.
148
+ * @access private
149
+ */
150
+ private function render_list_field( $lists, $settings )
151
+ {
152
+ ob_start();
153
+
154
+ $options = array( '' => __( 'Choose...', 'fl-builder' ) );
155
+
156
+ foreach ( $lists as $id => $data ) {
157
+ $options[ $id ] = $data->name;
158
+ }
159
+
160
+ FLBuilder::render_settings_field( 'list_id', array(
161
+ 'row_class' => 'fl-builder-service-field-row',
162
+ 'class' => 'fl-builder-service-list-select',
163
+ 'type' => 'select',
164
+ 'label' => __( 'List', 'fl-builder' ),
165
+ 'options' => $options,
166
+ 'preview' => array(
167
+ 'type' => 'none'
168
+ )
169
+ ), $settings);
170
+
171
+ return ob_get_clean();
172
+ }
173
+
174
+ /**
175
+ * Subscribe an email address to GetResponse.
176
+ *
177
+ * @since 1.5.4
178
+ * @param object $settings A module settings object.
179
+ * @param string $email The email to subscribe.
180
+ * @param string $name Optional. The full name of the person subscribing.
181
+ * @return array {
182
+ * @type bool|string $error The error message or false if no error.
183
+ * }
184
+ */
185
+ public function subscribe( $settings, $email, $name = '' )
186
+ {
187
+ $account_data = $this->get_account_data( $settings->service_account );
188
+ $response = array( 'error' => false );
189
+
190
+ if ( ! $account_data ) {
191
+ $response['error'] = __( 'There was an error subscribing to GetResponse. The account is no longer connected.', 'fl-builder' );
192
+ }
193
+ else {
194
+
195
+ $api = $this->get_api( $account_data['api_key'] );
196
+
197
+ try {
198
+ $result = $api->addContact( $settings->list_id, $name, $email );
199
+ }
200
+ catch ( Exception $e ) {
201
+ $response['error'] = sprintf(
202
+ __( 'There was an error subscribing to GetResponse. %s', 'fl-builder' ),
203
+ $e->getMessage()
204
+ );
205
+ }
206
+ }
207
+
208
+ return $response;
209
+ }
210
+ }
classes/class-fl-builder-service-icontact.php ADDED
@@ -0,0 +1,286 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Helper class for the iContact API.
5
+ *
6
+ * @since 1.5.4
7
+ */
8
+ final class FLBuilderServiceIContact extends FLBuilderService {
9
+
10
+ /**
11
+ * The ID for this service.
12
+ *
13
+ * @since 1.5.4
14
+ * @var string $id
15
+ */
16
+ public $id = 'icontact';
17
+
18
+ /**
19
+ * @since 1.5.4
20
+ * @var object $api_instance
21
+ * @access private
22
+ */
23
+ private $api_instance = null;
24
+
25
+ /**
26
+ * Get an instance of the API.
27
+ *
28
+ * @since 1.5.4
29
+ * @param array $data {
30
+ * @type string $username A valid username.
31
+ * @type string $app_id A valid app ID.
32
+ * @type string $app_password A valid app password.
33
+ * }
34
+ * @return object The API instance.
35
+ */
36
+ public function get_api( $data )
37
+ {
38
+ if ( $this->api_instance ) {
39
+ return $this->api_instance;
40
+ }
41
+ if ( ! class_exists( 'iContactApi' ) ) {
42
+ require_once FL_BUILDER_DIR . 'includes/vendor/icontact/iContactApi.php';
43
+ }
44
+
45
+ iContactApi::getInstance()->setConfig( $data );
46
+
47
+ $this->api_instance = iContactApi::getInstance();
48
+
49
+ return $this->api_instance;
50
+ }
51
+
52
+ /**
53
+ * Test the API connection.
54
+ *
55
+ * @since 1.5.4
56
+ * @param array $fields {
57
+ * @type string $username A valid username.
58
+ * @type string $app_id A valid app ID.
59
+ * @type string $app_password A valid app password.
60
+ * }
61
+ * @return array{
62
+ * @type bool|string $error The error message or false if no error.
63
+ * @type array $data An array of data used to make the connection.
64
+ * }
65
+ */
66
+ public function connect( $fields = array() )
67
+ {
68
+ $response = array(
69
+ 'error' => false,
70
+ 'data' => array()
71
+ );
72
+
73
+ // Make sure we have a username.
74
+ if ( ! isset( $fields['username'] ) || empty( $fields['username'] ) ) {
75
+ $response['error'] = __( 'Error: You must provide a username.', 'fl-builder' );
76
+ }
77
+ // Make sure we have an app ID.
78
+ else if ( ! isset( $fields['app_id'] ) || empty( $fields['app_id'] ) ) {
79
+ $response['error'] = __( 'Error: You must provide a app ID.', 'fl-builder' );
80
+ }
81
+ // Make sure we have an app password.
82
+ else if ( ! isset( $fields['app_password'] ) || empty( $fields['app_password'] ) ) {
83
+ $response['error'] = __( 'Error: You must provide a app password.', 'fl-builder' );
84
+ }
85
+ // Try to connect and store the connection data.
86
+ else {
87
+
88
+ $api = $this->get_api( array(
89
+ 'apiUsername' => $fields['username'],
90
+ 'appId' => $fields['app_id'],
91
+ 'apiPassword' => $fields['app_password'],
92
+ ));
93
+
94
+ try {
95
+ $api->getLists();
96
+ $response['data'] = array(
97
+ 'username' => $fields['username'],
98
+ 'app_id' => $fields['app_id'],
99
+ 'app_password' => $fields['app_password'],
100
+ );
101
+ }
102
+ catch ( Exception $e ) {
103
+ $errors = $api->getErrors();
104
+ $response['error'] = sprintf( __( 'Error: Could not connect to iContact. %s', 'fl-builder' ), $errors[0] );
105
+ }
106
+ }
107
+
108
+ return $response;
109
+ }
110
+
111
+ /**
112
+ * Renders the markup for the connection settings.
113
+ *
114
+ * @since 1.5.4
115
+ * @return string The connection settings markup.
116
+ */
117
+ public function render_connect_settings()
118
+ {
119
+ ob_start();
120
+
121
+ FLBuilder::render_settings_field( 'username', array(
122
+ 'row_class' => 'fl-builder-service-connect-row',
123
+ 'class' => 'fl-builder-service-connect-input',
124
+ 'type' => 'text',
125
+ 'label' => __( 'Username', 'fl-builder' ),
126
+ 'help' => __( 'Your iContact username.', 'fl-builder' ),
127
+ 'preview' => array(
128
+ 'type' => 'none'
129
+ )
130
+ ));
131
+
132
+ FLBuilder::render_settings_field( 'app_id', array(
133
+ 'row_class' => 'fl-builder-service-connect-row',
134
+ 'class' => 'fl-builder-service-connect-input',
135
+ 'type' => 'text',
136
+ 'label' => __( 'App ID', 'fl-builder' ),
137
+ 'help' => __( 'Your iContact app ID.', 'fl-builder' ),
138
+ 'preview' => array(
139
+ 'type' => 'none'
140
+ )
141
+ ));
142
+
143
+ FLBuilder::render_settings_field( 'app_password', array(
144
+ 'row_class' => 'fl-builder-service-connect-row',
145
+ 'class' => 'fl-builder-service-connect-input',
146
+ 'type' => 'text',
147
+ 'label' => __( 'App Password', 'fl-builder' ),
148
+ 'help' => __( 'Your iContact app password.', 'fl-builder' ),
149
+ 'description' => sprintf( __( 'You must <a%s>create an app</a> in iContact to obtain an app ID and password. Please see <a%s>the iContact docs</a> for complete instructions.', 'fl-builder' ), ' href="https://app.icontact.com/icp/core/registerapp/" target="_blank"', ' href="http://www.icontact.com/developerportal/api-documentation/vocus-register-your-app/" target="_blank"' ),
150
+ 'preview' => array(
151
+ 'type' => 'none'
152
+ )
153
+ ));
154
+
155
+ return ob_get_clean();
156
+ }
157
+
158
+ /**
159
+ * Render the markup for service specific fields.
160
+ *
161
+ * @since 1.5.4
162
+ * @param string $account The name of the saved account.
163
+ * @param object $settings Saved module settings.
164
+ * @return array {
165
+ * @type bool|string $error The error message or false if no error.
166
+ * @type string $html The field markup.
167
+ * }
168
+ */
169
+ public function render_fields( $account, $settings )
170
+ {
171
+ $account_data = $this->get_account_data( $account );
172
+ $api = $this->get_api( array(
173
+ 'apiUsername' => $account_data['username'],
174
+ 'appId' => $account_data['app_id'],
175
+ 'apiPassword' => $account_data['app_password'],
176
+ ));
177
+ $response = array(
178
+ 'error' => false,
179
+ 'html' => ''
180
+ );
181
+
182
+ try {
183
+ $lists = $api->getLists();
184
+ $response['html'] = $this->render_list_field( $lists, $settings );
185
+ }
186
+ catch ( Exception $e ) {
187
+ $errors = $api->getErrors();
188
+ $response['error'] = sprintf( __( 'Error: Could not connect to iContact. %s', 'fl-builder' ), $errors[0] );
189
+ }
190
+
191
+ return $response;
192
+ }
193
+
194
+ /**
195
+ * Render markup for the list field.
196
+ *
197
+ * @since 1.5.4
198
+ * @param array $lists List data from the API.
199
+ * @param object $settings Saved module settings.
200
+ * @return string The markup for the list field.
201
+ * @access private
202
+ */
203
+ private function render_list_field( $lists, $settings )
204
+ {
205
+ ob_start();
206
+
207
+ $options = array( '' => __( 'Choose...', 'fl-builder' ) );
208
+
209
+ foreach ( $lists as $id => $list ) {
210
+ $options[ $list->listId ] = $list->name;
211
+ }
212
+
213
+ FLBuilder::render_settings_field( 'list_id', array(
214
+ 'row_class' => 'fl-builder-service-field-row',
215
+ 'class' => 'fl-builder-service-list-select',
216
+ 'type' => 'select',
217
+ 'label' => __( 'List', 'fl-builder' ),
218
+ 'options' => $options,
219
+ 'preview' => array(
220
+ 'type' => 'none'
221
+ )
222
+ ), $settings);
223
+
224
+ return ob_get_clean();
225
+ }
226
+
227
+ /**
228
+ * Subscribe an email address to iContact.
229
+ *
230
+ * @since 1.5.4
231
+ * @param object $settings A module settings object.
232
+ * @param string $email The email to subscribe.
233
+ * @param string $name Optional. The full name of the person subscribing.
234
+ * @return array {
235
+ * @type bool|string $error The error message or false if no error.
236
+ * }
237
+ */
238
+ public function subscribe( $settings, $email, $name = false )
239
+ {
240
+ $account_data = $this->get_account_data( $settings->service_account );
241
+ $response = array( 'error' => false );
242
+
243
+ if ( ! $account_data ) {
244
+ $response['error'] = __( 'There was an error subscribing to iContact. The account is no longer connected.', 'fl-builder' );
245
+ }
246
+ else {
247
+
248
+ $data = array( 'email' => $email );
249
+ $api = $this->get_api( array(
250
+ 'apiUsername' => $account_data['username'],
251
+ 'appId' => $account_data['app_id'],
252
+ 'apiPassword' => $account_data['app_password'],
253
+ ));
254
+
255
+ try {
256
+
257
+ if ( $name ) {
258
+
259
+ $names = explode( ' ', $name );
260
+ $data['first_name'] = null;
261
+ $data['last_name'] = null;
262
+
263
+ if ( isset( $names[0] ) ) {
264
+ $data['first_name'] = $names[0];
265
+ }
266
+ if ( isset( $names[1] ) ) {
267
+ $data['last_name'] = $names[1];
268
+ }
269
+
270
+ $result = $api->addContact( $data['email'], 'normal', null, $data['first_name'], $data['last_name'] );
271
+ }
272
+ else {
273
+ $result = $api->addContact( $data['email'] );
274
+ }
275
+
276
+ $api->subscribeContactToList( $result->contactId, $settings->list_id );
277
+ }
278
+ catch ( Exception $e ) {
279
+ $errors = $api->getErrors();
280
+ $response['error'] = sprintf( __( 'There was an error subscribing to iContact. %s', 'fl-builder' ), $errors[0] );
281
+ }
282
+ }
283
+
284
+ return $response;
285
+ }
286
+ }
classes/class-fl-builder-service-madmimi.php ADDED
@@ -0,0 +1,248 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Helper class for the Mad Mimi API.
5
+ *
6
+ * @since 1.5.2
7
+ */
8
+ final class FLBuilderServiceMadMimi extends FLBuilderService {
9
+
10
+ /**
11
+ * The ID for this service.
12
+ *
13
+ * @since 1.5.2
14
+ * @var string $id
15
+ */
16
+ public $id = 'madmimi';
17
+
18
+ /**
19
+ * @since 1.5.2
20
+ * @var object $api_instance
21
+ * @access private
22
+ */
23
+ private $api_instance = null;
24
+
25
+ /**
26
+ * Get an instance of the API.
27
+ *
28
+ * @since 1.5.2
29
+ * @param string $api_email The email address associated with the API key.
30
+ * @param string $api_key A valid API key.
31
+ * @return object The API instance.
32
+ */
33
+ public function get_api( $api_email, $api_key )
34
+ {
35
+ if ( $this->api_instance ) {
36
+ return $this->api_instance;
37
+ }
38
+ if ( ! class_exists( 'MadMimi' ) ) {
39
+ require_once FL_BUILDER_DIR . 'includes/vendor/madmimi/MadMimi.class.php';
40
+ }
41
+
42
+ $this->api_instance = new MadMimi( $api_email, $api_key );
43
+
44
+ return $this->api_instance;
45
+ }
46
+
47
+ /**
48
+ * Test the API connection.
49
+ *
50
+ * @since 1.5.2
51
+ * @param array $fields {
52
+ * @type string $api_email A valid email address.
53
+ * @type string $api_key A valid API key.
54
+ * }
55
+ * @return array{
56
+ * @type bool|string $error The error message or false if no error.
57
+ * @type array $data An array of data used to make the connection.
58
+ * }
59
+ */
60
+ public function connect( $fields = array() )
61
+ {
62
+ $response = array(
63
+ 'error' => false,
64
+ 'data' => array()
65
+ );
66
+
67
+ // Make sure we have an email address.
68
+ if ( ! isset( $fields['api_email'] ) || empty( $fields['api_email'] ) ) {
69
+ $response['error'] = __( 'Error: You must provide an email address.', 'fl-builder' );
70
+ }
71
+ // Make sure we have an API key.
72
+ else if ( ! isset( $fields['api_key'] ) || empty( $fields['api_key'] ) ) {
73
+ $response['error'] = __( 'Error: You must provide an API key.', 'fl-builder' );
74
+ }
75
+ // Try to connect and store the connection data.
76
+ else {
77
+
78
+ $api = $this->get_api( $fields['api_email'], $fields['api_key'] );
79
+
80
+ libxml_use_internal_errors( true );
81
+
82
+ if ( ! simplexml_load_string( $api->Lists() ) ) {
83
+ $response['error'] = __( 'Unable to connect to Mad Mimi. Please check your credentials.', 'fl-builder' );
84
+ }
85
+ else {
86
+ $response['data'] = array(
87
+ 'api_email' => $fields['api_email'],
88
+ 'api_key' => $fields['api_key']
89
+ );
90
+ }
91
+ }
92
+
93
+ return $response;
94
+ }
95
+
96
+ /**
97
+ * Renders the markup for the connection settings.
98
+ *
99
+ * @since 1.5.2
100
+ * @return string The connection settings markup.
101
+ */
102
+ public function render_connect_settings()
103
+ {
104
+ ob_start();
105
+
106
+ FLBuilder::render_settings_field( 'api_email', array(
107
+ 'row_class' => 'fl-builder-service-connect-row',
108
+ 'class' => 'fl-builder-service-connect-input',
109
+ 'type' => 'text',
110
+ 'label' => __( 'Email Address', 'fl-builder' ),
111
+ 'help' => __( 'The email address associated with your Mad Mimi account.', 'fl-builder' ),
112
+ 'preview' => array(
113
+ 'type' => 'none'
114
+ )
115
+ ));
116
+
117
+ FLBuilder::render_settings_field( 'api_key', array(
118
+ 'row_class' => 'fl-builder-service-connect-row',
119
+ 'class' => 'fl-builder-service-connect-input',
120
+ 'type' => 'text',
121
+ 'label' => __( 'API Key', 'fl-builder' ),
122
+ 'help' => __( 'Your API key can be found in your Mad Mimi account under Account > Settings &amp; Billing > API.', 'fl-builder' ),
123
+ 'preview' => array(
124
+ 'type' => 'none'
125
+ )
126
+ ));
127
+
128
+ return ob_get_clean();
129
+ }
130
+
131
+ /**
132
+ * Render the markup for service specific fields.
133
+ *
134
+ * @since 1.5.2
135
+ * @param string $account The name of the saved account.
136
+ * @param object $settings Saved module settings.
137
+ * @return array {
138
+ * @type bool|string $error The error message or false if no error.
139
+ * @type string $html The field markup.
140
+ * }
141
+ */
142
+ public function render_fields( $account, $settings )
143
+ {
144
+ $account_data = $this->get_account_data( $account );
145
+ $api = $this->get_api( $account_data['api_email'], $account_data['api_key'] );
146
+ $response = array(
147
+ 'error' => false,
148
+ 'html' => ''
149
+ );
150
+
151
+ libxml_use_internal_errors( true );
152
+
153
+ $result = simplexml_load_string( $api->Lists() );
154
+
155
+ if ( ! $result ) {
156
+ $response['error'] = __( 'There was a problem retrieving your lists. Please check your API credentials.', 'fl-builder' );
157
+ }
158
+ else {
159
+ $response['html'] = $this->render_list_field( $result, $settings );
160
+ }
161
+
162
+ return $response;
163
+ }
164
+
165
+ /**
166
+ * Render markup for the list field.
167
+ *
168
+ * @since 1.5.2
169
+ * @param array $lists List data from the API.
170
+ * @param object $settings Saved module settings.
171
+ * @return string The markup for the list field.
172
+ * @access private
173
+ */
174
+ private function render_list_field( $lists, $settings )
175
+ {
176
+ ob_start();
177
+
178
+ $options = array( '' => __( 'Choose...', 'fl-builder' ) );
179
+
180
+ foreach ( $lists->list as $list ) {
181
+ $options[ ( string ) $list['id'] ] = $list['name'];
182
+ }
183
+
184
+ FLBuilder::render_settings_field( 'list_id', array(
185
+ 'row_class' => 'fl-builder-service-field-row',
186
+ 'class' => 'fl-builder-service-list-select',
187
+ 'type' => 'select',
188
+ 'label' => __( 'List', 'fl-builder' ),
189
+ 'options' => $options,
190
+ 'preview' => array(
191
+ 'type' => 'none'
192
+ )
193
+ ), $settings);
194
+
195
+ return ob_get_clean();
196
+ }
197
+
198
+ /**
199
+ * Subscribe an email address to Mad Mimi.
200
+ *
201
+ * @since 1.5.2
202
+ * @param object $settings A module settings object.
203
+ * @param string $email The email to subscribe.
204
+ * @param string $name Optional. The full name of the person subscribing.
205
+ * @return array {
206
+ * @type bool|string $error The error message or false if no error.
207
+ * }
208
+ */
209
+ public function subscribe( $settings, $email, $name = false )
210
+ {
211
+ $account_data = $this->get_account_data( $settings->service_account );
212
+ $response = array( 'error' => false );
213
+
214
+ if ( ! $account_data ) {
215
+ $response['error'] = __( 'There was an error subscribing to Mad Mimi. The account is no longer connected.', 'fl-builder' );
216
+ }
217
+ else {
218
+
219
+ $api = $this->get_api( $account_data['api_email'], $account_data['api_key'] );
220
+ $data = array(
221
+ 'email' => $email,
222
+ 'add_list' => $settings->list_id
223
+ );
224
+
225
+ if ( $name ) {
226
+
227
+ $names = explode( ' ', $name );
228
+
229
+ if ( isset( $names[0] ) ) {
230
+ $data['firstName'] = $names[0];
231
+ }
232
+ if ( isset( $names[1] ) ) {
233
+ $data['lastName'] = $names[1];
234
+ }
235
+ }
236
+
237
+ ob_start();
238
+ $api->AddUser( $data, true );
239
+ $request = ob_get_clean();
240
+
241
+ if ( stristr( $request, 'Unable to authenticate' ) ) {
242
+ $response['error'] = __( 'There was an error subscribing to Mad Mimi. The account is no longer connected.', 'fl-builder' );
243
+ }
244
+ }
245
+
246
+ return $response;
247
+ }
248
+ }
classes/class-fl-builder-service-mailchimp.php ADDED
@@ -0,0 +1,227 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Helper class for the MailChimp API.
5
+ *
6
+ * @since 1.5.4
7
+ */
8
+ final class FLBuilderServiceMailChimp extends FLBuilderService {
9
+
10
+ /**
11
+ * The ID for this service.
12
+ *
13
+ * @since 1.5.4
14
+ * @var string $id
15
+ */
16
+ public $id = 'mailchimp';
17
+
18
+ /**
19
+ * @since 1.5.4
20
+ * @var object $api_instance
21
+ * @access private
22
+ */
23
+ private $api_instance = null;
24
+
25
+ /**
26
+ * Get an instance of the API.
27
+ *
28
+ * @since 1.5.4
29
+ * @param string $api_key A valid API key.
30
+ * @return object The API instance.
31
+ */
32
+ public function get_api( $api_key )
33
+ {
34
+ if ( $this->api_instance ) {
35
+ return $this->api_instance;
36
+ }
37
+ if ( ! class_exists( 'Mailchimp' ) ) {
38
+ require_once FL_BUILDER_DIR . 'includes/vendor/mailchimp/mailchimp.php';
39
+ }
40
+
41
+ $this->api_instance = new Mailchimp( $api_key );
42
+
43
+ return $this->api_instance;
44
+ }
45
+
46
+ /**
47
+ * Test the API connection.
48
+ *
49
+ * @since 1.5.4
50
+ * @param array $fields {
51
+ * @type string $api_key A valid API key.
52
+ * }
53
+ * @return array{
54
+ * @type bool|string $error The error message or false if no error.
55
+ * @type array $data An array of data used to make the connection.
56
+ * }
57
+ */
58
+ public function connect( $fields = array() )
59
+ {
60
+ $response = array(
61
+ 'error' => false,
62
+ 'data' => array()
63
+ );
64
+
65
+ // Make sure we have an API key.
66
+ if ( ! isset( $fields['api_key'] ) || empty( $fields['api_key'] ) ) {
67
+ $response['error'] = __( 'Error: You must provide an API key.', 'fl-builder' );
68
+ }
69
+ // Try to connect and store the connection data.
70
+ else {
71
+
72
+ $api = $this->get_api( $fields['api_key'] );
73
+
74
+ try {
75
+ $api->helper->ping();
76
+ $response['data'] = array( 'api_key' => $fields['api_key'] );
77
+ }
78
+ catch ( Mailchimp_Invalid_ApiKey $e ) {
79
+ $response['error'] = $e->getMessage();
80
+ }
81
+ }
82
+
83
+ return $response;
84
+ }
85
+
86
+ /**
87
+ * Renders the markup for the connection settings.
88
+ *
89
+ * @since 1.5.4
90
+ * @return string The connection settings markup.
91
+ */
92
+ public function render_connect_settings()
93
+ {
94
+ ob_start();
95
+
96
+ FLBuilder::render_settings_field( 'api_key', array(
97
+ 'row_class' => 'fl-builder-service-connect-row',
98
+ 'class' => 'fl-builder-service-connect-input',
99
+ 'type' => 'text',
100
+ 'label' => __( 'API Key', 'fl-builder' ),
101
+ 'help' => __( 'Your API key can be found in your MailChimp account under Account > Extras > API Keys.', 'fl-builder' ),
102
+ 'preview' => array(
103
+ 'type' => 'none'
104
+ )
105
+ ));
106
+
107
+ return ob_get_clean();
108
+ }
109
+
110
+ /**
111
+ * Render the markup for service specific fields.
112
+ *
113
+ * @since 1.5.4
114
+ * @param string $account The name of the saved account.
115
+ * @param object $settings Saved module settings.
116
+ * @return array {
117
+ * @type bool|string $error The error message or false if no error.
118
+ * @type string $html The field markup.
119
+ * }
120
+ */
121
+ public function render_fields( $account, $settings )
122
+ {
123
+ $account_data = $this->get_account_data( $account );
124
+ $api = $this->get_api( $account_data['api_key'] );
125
+ $response = array(
126
+ 'error' => false,
127
+ 'html' => ''
128
+ );
129
+
130
+ try {
131
+ $lists = $api->lists->getList();
132
+ $response['html'] = $this->render_list_field( $lists, $settings );
133
+ }
134
+ catch ( Mailchimp_Error $e ) {
135
+ $response['error'] = $e->getMessage();
136
+ }
137
+
138
+ return $response;
139
+ }
140
+
141
+ /**
142
+ * Render markup for the list field.
143
+ *
144
+ * @since 1.5.4
145
+ * @param array $lists List data from the API.
146
+ * @param object $settings Saved module settings.
147
+ * @return string The markup for the list field.
148
+ * @access private
149
+ */
150
+ private function render_list_field( $lists, $settings )
151
+ {
152
+ ob_start();
153
+
154
+ $options = array( '' => __( 'Choose...', 'fl-builder' ) );
155
+
156
+ foreach ( $lists['data'] as $list ) {
157
+ $options[ $list['id'] ] = $list['name'];
158
+ }
159
+
160
+ FLBuilder::render_settings_field( 'list_id', array(
161
+ 'row_class' => 'fl-builder-service-field-row',
162
+ 'class' => 'fl-builder-service-list-select',
163
+ 'type' => 'select',
164
+ 'label' => __( 'List', 'fl-builder' ),
165
+ 'options' => $options,
166
+ 'preview' => array(
167
+ 'type' => 'none'
168
+ )
169
+ ), $settings);
170
+
171
+ return ob_get_clean();
172
+ }
173
+
174
+ /**
175
+ * Subscribe an email address to MailChimp.
176
+ *
177
+ * @since 1.5.4
178
+ * @param object $settings A module settings object.
179
+ * @param string $email The email to subscribe.
180
+ * @param string $name Optional. The full name of the person subscribing.
181
+ * @return array {
182
+ * @type bool|string $error The error message or false if no error.
183
+ * }
184
+ */
185
+ public function subscribe( $settings, $email, $name = false )
186
+ {
187
+ $account_data = $this->get_account_data( $settings->service_account );
188
+ $response = array( 'error' => false );
189
+
190
+ if ( ! $account_data ) {
191
+ $response['error'] = __( 'There was an error subscribing to MailChimp. The account is no longer connected.', 'fl-builder' );
192
+ }
193
+ else {
194
+
195
+ $api = $this->get_api( $account_data['api_key'] );
196
+ $email = array( 'email' => $email );
197
+ $data = array();
198
+
199
+ if ( $name ) {
200
+
201
+ $names = explode( ' ', $name );
202
+
203
+ if ( isset( $names[0] ) ) {
204
+ $data['FNAME'] = $names[0];
205
+ }
206
+ if ( isset( $names[1] ) ) {
207
+ $data['LNAME'] = $names[1];
208
+ }
209
+ }
210
+
211
+ try {
212
+ $api->lists->subscribe( $settings->list_id, $email, $data, 'html', true, true, false, true );
213
+ }
214
+ catch( Mailchimp_List_AlreadySubscribed $e ) {
215
+ return $response;
216
+ }
217
+ catch ( Mailchimp_Error $e ) {
218
+ $response['error'] = sprintf(
219
+ __( 'There was an error subscribing to MailChimp. %s', 'fl-builder' ),
220
+ $e->getMessage()
221
+ );
222
+ }
223
+ }
224
+
225
+ return $response;
226
+ }
227
+ }
classes/class-fl-builder-service-mailpoet.php ADDED
@@ -0,0 +1,155 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Helper class for MailPoet.
5
+ *
6
+ * @since 1.5.4
7
+ */
8
+ final class FLBuilderServiceMailPoet extends FLBuilderService {
9
+
10
+ /**
11
+ * The ID for this service.
12
+ *
13
+ * @since 1.5.4
14
+ * @var string $id
15
+ */
16
+ public $id = 'mailpoet';
17
+
18
+ /**
19
+ * Test the API connection.
20
+ *
21
+ * @since 1.5.4
22
+ * @param array $fields
23
+ * @return array{
24
+ * @type bool|string $error The error message or false if no error.
25
+ * @type array $data An array of data used to make the connection.
26
+ * }
27
+ */
28
+ public function connect( $fields = array() )
29
+ {
30
+ $response = array(
31
+ 'error' => false,
32
+ 'data' => array()
33
+ );
34
+
35
+ return $response;
36
+ }
37
+
38
+ /**
39
+ * Renders the markup for the connection settings.
40
+ *
41
+ * @since 1.5.4
42
+ * @return string The connection settings markup.
43
+ */
44
+ public function render_connect_settings()
45
+ {
46
+ return '';
47
+ }
48
+
49
+ /**
50
+ * Render the markup for service specific fields.
51
+ *
52
+ * @since 1.5.4
53
+ * @param string $account The name of the saved account.
54
+ * @param object $settings Saved module settings.
55
+ * @return array {
56
+ * @type bool|string $error The error message or false if no error.
57
+ * @type string $html The field markup.
58
+ * }
59
+ */
60
+ public function render_fields( $account, $settings )
61
+ {
62
+ $response = array(
63
+ 'error' => false,
64
+ 'html' => ''
65
+ );
66
+
67
+ try {
68
+ $list_model = WYSIJA::get( 'list', 'model' );
69
+ $lists = $list_model->get( array( 'name', 'list_id' ), array( 'is_enabled' => 1 ) );
70
+ $response['html'] = self::render_list_field( $lists, $settings );
71
+ }
72
+ catch ( Exception $e ) {
73
+ $response['error'] = __( 'There was an error retrieveing your lists.', 'fl-builder' );
74
+ }
75
+
76
+ return $response;
77
+ }
78
+
79
+ /**
80
+ * Render markup for the list field.
81
+ *
82
+ * @since 1.5.4
83
+ * @param array $lists List data from the API.
84
+ * @param object $settings Saved module settings.
85
+ * @return string The markup for the list field.
86
+ * @access private
87
+ */
88
+ private function render_list_field( $lists, $settings )
89
+ {
90
+ ob_start();
91
+
92
+ $options = array( '' => __( 'Choose...', 'fl-builder' ) );
93
+
94
+ foreach ( $lists as $list ) {
95
+ $options[ $list['list_id'] ] = $list['name'];
96
+ }
97
+
98
+ FLBuilder::render_settings_field( 'list_id', array(
99
+ 'row_class' => 'fl-builder-service-field-row',
100
+ 'class' => 'fl-builder-service-list-select',
101
+ 'type' => 'select',
102
+ 'label' => __( 'List', 'fl-builder' ),
103
+ 'options' => $options,
104
+ 'preview' => array(
105
+ 'type' => 'none'
106
+ )
107
+ ), $settings);
108
+
109
+ return ob_get_clean();
110
+ }
111
+
112
+ /**
113
+ * Subscribe an email address to MailPoet.
114
+ *
115
+ * @since 1.5.4
116
+ * @param object $settings A module settings object.
117
+ * @param string $email The email to subscribe.
118
+ * @param string $name Optional. The full name of the person subscribing.
119
+ * @return array {
120
+ * @type bool|string $error The error message or false if no error.
121
+ * }
122
+ */
123
+ public function subscribe( $settings, $email, $name = false )
124
+ {
125
+ $response = array( 'error' => false );
126
+ $user = array( 'email' => $email );
127
+
128
+ if ( ! class_exists( 'WYSIJA' ) ) {
129
+ $response['error'] = __( 'There was an error subscribing. MailPoet is not installed.', 'fl-builder' );
130
+ }
131
+ else {
132
+
133
+ $helper = WYSIJA::get( 'user', 'helper' );
134
+
135
+ if ( $name ) {
136
+
137
+ $names = explode( ' ', $name );
138
+
139
+ if ( isset( $names[0] ) ) {
140
+ $user['firstname'] = $names[0];
141
+ }
142
+ if ( isset( $names[1] ) ) {
143
+ $user['lastname'] = $names[1];
144
+ }
145
+ }
146
+
147
+ $helper->addSubscriber( array(
148
+ 'user' => $user,
149
+ 'user_list' => array( 'list_ids' => array( $settings->list_id ) ),
150
+ ));
151
+ }
152
+
153
+ return $response;
154
+ }
155
+ }
classes/class-fl-builder-service.php ADDED
@@ -0,0 +1,68 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Base class for third party services.
5
+ *
6
+ * @since 1.5.4
7
+ */
8
+ abstract class FLBuilderService {
9
+
10
+ /**
11
+ * The ID for this service such as aweber or mailchimp.
12
+ *
13
+ * @since 1.5.4
14
+ * @var string $id
15
+ */
16
+ public $id = '';
17
+
18
+ /**
19
+ * Test the API connection.
20
+ *
21
+ * @since 1.5.4
22
+ * @param array $fields
23
+ * @return array{
24
+ * @type bool|string $error The error message or false if no error.
25
+ * @type array $data An array of data used to make the connection.
26
+ * }
27
+ */
28
+ abstract public function connect( $fields = array() );
29
+
30
+ /**
31
+ * Renders the markup for the connection settings.
32
+ *
33
+ * @since 1.5.4
34
+ * @return string The connection settings markup.
35
+ */
36
+ abstract public function render_connect_settings();
37
+
38
+ /**
39
+ * Render the markup for service specific fields.
40
+ *
41
+ * @since 1.5.4
42
+ * @param string $account The name of the saved account.
43
+ * @param object $settings Saved module settings.
44
+ * @return array {
45
+ * @type bool|string $error The error message or false if no error.
46
+ * @type string $html The field markup.
47
+ * }
48
+ */
49
+ abstract public function render_fields( $account, $settings );
50
+
51
+ /**
52
+ * Get the saved data for a specific account.
53
+ *
54
+ * @since 1.5.4
55
+ * @param string $account The account name.
56
+ * @return array|bool The account data or false if it doesn't exist.
57
+ */
58
+ public function get_account_data( $account )
59
+ {
60
+ $saved_services = FLBuilderModel::get_services();
61
+
62
+ if ( isset( $saved_services[ $this->id ] ) && isset( $saved_services[ $this->id ][ $account ] ) ) {
63
+ return $saved_services[ $this->id ][ $account ];
64
+ }
65
+
66
+ return false;
67
+ }
68
+ }
classes/class-fl-builder-services.php ADDED
@@ -0,0 +1,338 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Helper class for connecting to third party services.
5
+ *
6
+ * @since 1.5.4
7
+ */
8
+ final class FLBuilderServices {
9
+
10
+ /**
11
+ * Data for working with each supported third party service.
12
+ *
13
+ * @since 1.5.4
14
+ * @var array $services_data
15
+ * @access private
16
+ */
17
+ static private $services_data = array(
18
+ 'aweber' => array(
19
+ 'type' => 'autoresponder',
20
+ 'name' => 'AWeber',
21
+ 'class' => 'FLBuilderServiceAWeber'
22
+ ),
23
+ 'campaign-monitor' => array(
24
+ 'type' => 'autoresponder',
25
+ 'name' => 'Campaign Monitor',
26
+ 'class' => 'FLBuilderServiceCampaignMonitor'
27
+ ),
28
+ 'constant-contact' => array(
29
+ 'type' => 'autoresponder',
30
+ 'name' => 'Constant Contact',
31
+ 'class' => 'FLBuilderServiceConstantContact'
32
+ ),
33
+ 'getresponse' => array(
34
+ 'type' => 'autoresponder',
35
+ 'name' => 'GetResponse',
36
+ 'class' => 'FLBuilderServiceGetResponse'
37
+ ),
38
+ 'icontact' => array(
39
+ 'type' => 'autoresponder',
40
+ 'name' => 'iContact',
41
+ 'class' => 'FLBuilderServiceIContact'
42
+ ),
43
+ 'madmimi' => array(
44
+ 'type' => 'autoresponder',
45
+ 'name' => 'Mad Mimi',
46
+ 'class' => 'FLBuilderServiceMadMimi'
47
+ ),
48
+ 'mailchimp' => array(
49
+ 'type' => 'autoresponder',
50
+ 'name' => 'MailChimp',
51
+ 'class' => 'FLBuilderServiceMailChimp'
52
+ ),
53
+ 'mailpoet' => array(
54
+ 'type' => 'autoresponder',
55
+ 'name' => 'MailPoet',
56
+ 'class' => 'FLBuilderServiceMailPoet'
57
+ )
58
+ );
59
+
60
+ /**
61
+ * Get an array of services data of a certain type such as "autoresponder".
62
+ * If no type is specified, all services will be returned.
63
+ *
64
+ * @since 1.5.4
65
+ * @param string $type The type of service data to return.
66
+ * @return array An array of services and related data.
67
+ */
68
+ static public function get_services_data( $type = null )
69
+ {
70
+ $services = array();
71
+
72
+ // Return all services.
73
+ if ( ! $type ) {
74
+ $services = self::$services_data;
75
+ }
76
+ // Return services of a specific type.
77
+ else {
78
+
79
+ foreach ( self::$services_data as $key => $service ) {
80
+ if ( $service['type'] == $type ) {
81
+ $services[ $key ] = $service;
82
+ }
83
+ }
84
+ }
85
+
86
+ return $services;
87
+ }
88
+
89
+ /**
90
+ * Get an instance of a service helper class.
91
+ *
92
+ * @since 1.5.4
93
+ * @param string $type The type of service.
94
+ * @return object
95
+ */
96
+ static public function get_service_instance( $service )
97
+ {
98
+ $services = self::get_services_data();
99
+ $data = $services[ $service ];
100
+
101
+ // Make sure the base class is loaded.
102
+ if ( ! class_exists( 'FLBuilderService' ) ) {
103
+ require_once FL_BUILDER_DIR . 'classes/class-fl-builder-service.php';
104
+ }
105
+
106
+ // Make sure the service class is loaded.
107
+ if ( ! class_exists( $data['class'] ) ) {
108
+ require_once FL_BUILDER_DIR . 'classes/class-fl-builder-service-' . $service . '.php';
109
+ }
110
+
111
+ return new $data['class']();
112
+ }
113
+
114
+ /**
115
+ * Save the API connection of a service and retrieve account settings markup.
116
+ *
117
+ * Called via the fl_ajax_fl_builder_connect_service action.
118
+ *
119
+ * @since 1.5.4
120
+ * @return string The JSON encoded response.
121
+ */
122
+ static public function connect_service()
123
+ {
124
+ $saved_services = FLBuilderModel::get_services();
125
+ $post_data = FLBuilderModel::get_post_data();
126
+ $response = array(
127
+ 'error' => false,
128
+ 'html' => ''
129
+ );
130
+
131
+ // Validate the service data.
132
+ if ( ! isset( $post_data['service'] ) || empty( $post_data['service'] ) ) {
133
+ $response['error'] = _x( 'Error: Missing service type.', 'Third party service such as MailChimp.', 'fl-builder' );
134
+ }
135
+ else if ( ! isset( $post_data['fields'] ) || 0 === count( $post_data['fields'] ) ) {
136
+ $response['error'] = _x( 'Error: Missing service data.', 'Connection data such as an API key.', 'fl-builder' );
137
+ }
138
+ else if ( ! isset( $post_data['fields']['service_account'] ) || empty( $post_data['fields']['service_account'] ) ) {
139
+ $response['error'] = _x( 'Error: Missing account name.', 'Account name for a third party service such as MailChimp.', 'fl-builder' );
140
+ }
141
+
142
+ // Get the service data.
143
+ $service = $post_data['service'];
144
+ $service_account = $post_data['fields']['service_account'];
145
+
146
+ // Does this account already exist?
147
+ if ( isset( $saved_services[ $service ][ $service_account ] ) ) {
148
+ $response['error'] = _x( 'Error: An account with that name already exists.', 'Account name for a third party service such as MailChimp.', 'fl-builder' );
149
+ }
150
+
151
+ // Try to connect to the service.
152
+ if ( ! $response['error'] ) {
153
+
154
+ $instance = self::get_service_instance( $service );
155
+ $connection = $instance->connect( $post_data['fields'] );
156
+
157
+ if ( $connection['error'] ) {
158
+ $response['error'] = $connection['error'];
159
+ }
160
+ else {
161
+
162
+ FLBuilderModel::update_services(
163
+ $service,
164
+ $service_account,
165
+ $connection['data']
166
+ );
167
+
168
+ $response['html'] = self::render_account_settings( $service, $service_account );
169
+ }
170
+ }
171
+
172
+ // Return the response.
173
+ echo json_encode( $response );
174
+
175
+ die();
176
+ }
177
+
178
+ /**
179
+ * Render the connection settings or account settings for a service.
180
+ *
181
+ * Called via the fl_ajax_fl_builder_render_service_settings action.
182
+ *
183
+ * @since 1.5.4
184
+ * @return string The JSON encoded response.
185
+ */
186
+ static public function render_settings()
187
+ {
188
+ $post_data = FLBuilderModel::get_post_data();
189
+ $saved_services = FLBuilderModel::get_services();
190
+ $module = FLBuilderModel::get_module( $post_data['node_id'] );
191
+ $settings = $module->settings;
192
+ $service = $post_data['service'];
193
+ $response = array(
194
+ 'error' => false,
195
+ 'html' => ''
196
+ );
197
+
198
+ // Render the settings to connect a new account.
199
+ if ( isset( $post_data['add_new'] ) || ! isset( $saved_services[ $service ] ) ) {
200
+ $response['html'] = self::render_connect_settings( $service );
201
+ }
202
+ // Render the settings to select a connected account.
203
+ else {
204
+ $account = isset( $settings->service_account ) ? $settings->service_account : '';
205
+ $response['html'] = self::render_account_settings( $service, $account );
206
+ }
207
+
208
+ // Return the response.
209
+ echo json_encode( $response );
210
+
211
+ die();
212
+ }
213
+
214
+ /**
215
+ * Render the settings to connect to a new account.
216
+ *
217
+ * @since 1.5.4
218
+ * @return string The settings markup.
219
+ */
220
+ static public function render_connect_settings( $service )
221
+ {
222
+ ob_start();
223
+
224
+ FLBuilder::render_settings_field( 'service_account', array(
225
+ 'row_class' => 'fl-builder-service-connect-row',
226
+ 'class' => 'fl-builder-service-connect-input',
227
+ 'type' => 'text',
228
+ 'label' => __( 'Account Name', 'fl-builder' ),
229
+ 'help' => __( 'Used to identify this connection within the accounts list and can be anything you like.', 'fl-builder' ),
230
+ 'preview' => array(
231
+ 'type' => 'none'
232
+ )
233
+ ));
234
+
235
+ $instance = self::get_service_instance( $service );
236
+ echo $instance->render_connect_settings();
237
+
238
+ FLBuilder::render_settings_field( 'service_connect_button', array(
239
+ 'row_class' => 'fl-builder-service-connect-row',
240
+ 'class' => 'fl-builder-service-connect-button',
241
+ 'type' => 'button',
242
+ 'label' => __( 'Connect', 'fl-builder' )
243
+ ));
244
+
245
+ return ob_get_clean();
246
+ }
247
+
248
+ /**
249
+ * Render the account settings for a saved connection.
250
+ *
251
+ * @since 1.5.4
252
+ * @param string $service The service id such as "mailchimp".
253
+ * @param string $active The name of the active account, if any.
254
+ * @return string The account settings markup.
255
+ */
256
+ static public function render_account_settings( $service, $active = '' )
257
+ {
258
+ ob_start();
259
+
260
+ $saved_services = FLBuilderModel::get_services();
261
+ $settings = new stdClass();
262
+ $settings->service_account = $active;
263
+ $options = array( '' => __( 'Choose...', 'fl-builder' ) );
264
+
265
+ // Build the account select options.
266
+ foreach ( $saved_services[ $service ] as $account => $data ) {
267
+ $options[ $account ] = $account;
268
+ }
269
+
270
+ $options['add_new_account'] = __( 'Add Account...', 'fl-builder' );
271
+
272
+ // Render the account select.
273
+ FLBuilder::render_settings_field( 'service_account', array(
274
+ 'row_class' => 'fl-builder-service-account-row',
275
+ 'class' => 'fl-builder-service-account-select',
276
+ 'type' => 'select',
277
+ 'label' => __( 'Account', 'fl-builder' ),
278
+ 'options' => $options,
279
+ 'preview' => array(
280
+ 'type' => 'none'
281
+ )
282
+ ), $settings);
283
+
284
+ // Render additional service fields if we have a saved account.
285
+ if ( ! empty( $active ) && isset( $saved_services[ $service ][ $active ] ) ) {
286
+
287
+ $post_data = FLBuilderModel::get_post_data();
288
+ $module = FLBuilderModel::get_module( $post_data['node_id'] );
289
+ $instance = self::get_service_instance( $service );
290
+ $response = $instance->render_fields( $active, $module->settings );
291
+
292
+ if ( ! $response['error'] ) {
293
+ echo $response['html'];
294
+ }
295
+ }
296
+
297
+ return ob_get_clean();
298
+ }
299
+
300
+ /**
301
+ * Render the markup for service specific fields.
302
+ *
303
+ * Called via the fl_ajax_fl_builder_render_service_fields action.
304
+ *
305
+ * @since 1.5.4
306
+ * @return string The JSON encoded response.
307
+ */
308
+ static public function render_fields()
309
+ {
310
+ $post_data = FLBuilderModel::get_post_data();
311
+ $module = FLBuilderModel::get_module( $post_data['node_id'] );
312
+ $instance = self::get_service_instance( $post_data['service'] );
313
+ $response = $instance->render_fields( $post_data['account'], $module->settings );
314
+
315
+ echo json_encode( $response );
316
+
317
+ die();
318
+ }
319
+
320
+ /**
321
+ * Delete a saved account from the database.
322
+ *
323
+ * Called via the fl_ajax_fl_builder_delete_service_account action.
324
+ *
325
+ * @since 1.5.4
326
+ * @return void
327
+ */
328
+ static public function delete_account()
329
+ {
330
+ $post_data = FLBuilderModel::get_post_data();
331
+
332
+ if ( ! isset( $post_data['service'] ) || ! isset( $post_data['account'] ) ) {
333
+ return;
334
+ }
335
+
336
+ FLBuilderModel::delete_service_account( $post_data['service'], $post_data['account'] );
337
+ }
338
+ }
classes/class-fl-builder.php CHANGED
@@ -222,9 +222,10 @@ final class FLBuilder {
222
  global $wp_query;
223
  global $post;
224
 
225
- $ver = FL_BUILDER_VERSION;
226
- $css_url = FL_BUILDER_URL . 'css/';
227
- $js_url = FL_BUILDER_URL . 'js/';
 
228
 
229
  // Register additional CSS
230
  wp_register_style('font-awesome', $css_url . 'font-awesome.min.css', array(), $ver);
@@ -272,8 +273,8 @@ final class FLBuilder {
272
  }
273
  }
274
 
275
- // Reset the main query.
276
- wp_reset_query();
277
  }
278
 
279
  /**
@@ -390,6 +391,7 @@ final class FLBuilder {
390
  wp_enqueue_script('fl-stylesheet', $js_url . 'fl-stylesheet.js', array(), $ver, true);
391
  wp_enqueue_script('fl-builder', $js_url . 'fl-builder.js', array(), $ver, true);
392
  wp_enqueue_script('fl-builder-preview', $js_url . 'fl-builder-preview.js', array(), $ver, true);
 
393
  wp_enqueue_script('fl-builder-tour', $js_url . 'fl-builder-tour.js', array(), $ver, true);
394
 
395
  /* Core template settings */
@@ -573,7 +575,7 @@ final class FLBuilder {
573
 
574
  // Render the content.
575
  ob_start();
576
- echo '<div class="fl-builder-content fl-builder-content-' . $post_id . '">';
577
  self::render_rows();
578
  echo '</div>';
579
  $content = do_shortcode(ob_get_clean());
@@ -669,13 +671,15 @@ final class FLBuilder {
669
  /**
670
  * @method render_settings_field
671
  */
672
- static public function render_settings_field($name, $field, $settings)
673
  {
674
  $i = null;
675
  $is_multiple = isset($field['multiple']) && $field['multiple'] === true;
676
- $supports_multiple = $field['type'] != 'editor' && $field['type'] != 'photo';
 
677
  $value = isset($settings->$name) ? $settings->$name : '';
678
  $preview = isset($field['preview']) ? json_encode($field['preview']) : json_encode(array('type' => 'refresh'));
 
679
 
680
  if($is_multiple && $supports_multiple) {
681
 
@@ -712,7 +716,7 @@ final class FLBuilder {
712
  echo '</tbody>';
713
  }
714
  else {
715
- echo '<tr id="fl-field-'. $name .'" class="fl-field" data-type="' . $field['type'] . '" data-preview=\'' . $preview . '\'>';
716
  include FL_BUILDER_DIR . 'includes/field.php';
717
  echo '</tr>';
718
  }
@@ -1259,11 +1263,17 @@ final class FLBuilder {
1259
 
1260
  // Responsive css
1261
  if($global_settings->responsive_enabled) {
 
1262
  $css .= '@media (max-width: '. $global_settings->medium_breakpoint .'px) { ';
1263
  $css .= file_get_contents(FL_BUILDER_DIR . '/css/fl-builder-layout-medium.css');
1264
  $css .= ' }';
1265
  $css .= '@media (max-width: '. $global_settings->responsive_breakpoint .'px) { ';
1266
  $css .= file_get_contents(FL_BUILDER_DIR . '/css/fl-builder-layout-responsive.css');
 
 
 
 
 
1267
  $css .= ' }';
1268
  }
1269
 
@@ -1295,7 +1305,10 @@ final class FLBuilder {
1295
 
1296
  // Instance row bg positions
1297
  $css .= self::render_row_bg_positions($row);
1298
- $css .= self::render_responsive_row_bg_positions($row);
 
 
 
1299
  }
1300
 
1301
  // Column instances
@@ -1355,7 +1368,10 @@ final class FLBuilder {
1355
 
1356
  // Instance module margins
1357
  $css .= self::render_module_margins($module);
1358
- $css .= self::render_responsive_module_margins($module);
 
 
 
1359
  }
1360
 
1361
  // Default page heading
222
  global $wp_query;
223
  global $post;
224
 
225
+ $original_post = $post;
226
+ $ver = FL_BUILDER_VERSION;
227
+ $css_url = FL_BUILDER_URL . 'css/';
228
+ $js_url = FL_BUILDER_URL . 'js/';
229
 
230
  // Register additional CSS
231
  wp_register_style('font-awesome', $css_url . 'font-awesome.min.css', array(), $ver);
273
  }
274
  }
275
 
276
+ // Reset the global post variable.
277
+ $post = $original_post;
278
  }
279
 
280
  /**
391
  wp_enqueue_script('fl-stylesheet', $js_url . 'fl-stylesheet.js', array(), $ver, true);
392
  wp_enqueue_script('fl-builder', $js_url . 'fl-builder.js', array(), $ver, true);
393
  wp_enqueue_script('fl-builder-preview', $js_url . 'fl-builder-preview.js', array(), $ver, true);
394
+ wp_enqueue_script('fl-builder-services', $js_url . 'fl-builder-services.js', array(), $ver, true);
395
  wp_enqueue_script('fl-builder-tour', $js_url . 'fl-builder-tour.js', array(), $ver, true);
396
 
397
  /* Core template settings */
575
 
576
  // Render the content.
577
  ob_start();
578
+ echo '<div class="fl-builder-content fl-builder-content-' . $post_id . '" data-post-id="' . $post_id . '">';
579
  self::render_rows();
580
  echo '</div>';
581
  $content = do_shortcode(ob_get_clean());
671
  /**
672
  * @method render_settings_field
673
  */
674
+ static public function render_settings_field($name, $field, $settings = null)
675
  {
676
  $i = null;
677
  $is_multiple = isset($field['multiple']) && $field['multiple'] === true;
678
+ $supports_multiple = $field['type'] != 'editor' && $field['type'] != 'photo' && $field['type'] != 'service';
679
+ $settings = ! $settings ? new stdClass() : $settings;
680
  $value = isset($settings->$name) ? $settings->$name : '';
681
  $preview = isset($field['preview']) ? json_encode($field['preview']) : json_encode(array('type' => 'refresh'));
682
+ $row_class = isset($field['row_class']) ? ' ' . $field['row_class'] : '';
683
 
684
  if($is_multiple && $supports_multiple) {
685
 
716
  echo '</tbody>';
717
  }
718
  else {
719
+ echo '<tr id="fl-field-'. $name .'" class="fl-field' . $row_class . '" data-type="' . $field['type'] . '" data-preview=\'' . $preview . '\'>';
720
  include FL_BUILDER_DIR . 'includes/field.php';
721
  echo '</tr>';
722
  }
1263
 
1264
  // Responsive css
1265
  if($global_settings->responsive_enabled) {
1266
+
1267
  $css .= '@media (max-width: '. $global_settings->medium_breakpoint .'px) { ';
1268
  $css .= file_get_contents(FL_BUILDER_DIR . '/css/fl-builder-layout-medium.css');
1269
  $css .= ' }';
1270
  $css .= '@media (max-width: '. $global_settings->responsive_breakpoint .'px) { ';
1271
  $css .= file_get_contents(FL_BUILDER_DIR . '/css/fl-builder-layout-responsive.css');
1272
+
1273
+ if ( ! isset( $global_settings->auto_spacing ) || $global_settings->auto_spacing ) {
1274
+ $css .= file_get_contents(FL_BUILDER_DIR . '/css/fl-builder-layout-auto-spacing.css');
1275
+ }
1276
+
1277
  $css .= ' }';
1278
  }
1279
 
1305
 
1306
  // Instance row bg positions
1307
  $css .= self::render_row_bg_positions($row);
1308
+
1309
+ if ( ! isset( $global_settings->auto_spacing ) || $global_settings->auto_spacing ) {
1310
+ $css .= self::render_responsive_row_bg_positions($row);
1311
+ }
1312
  }
1313
 
1314
  // Column instances
1368
 
1369
  // Instance module margins
1370
  $css .= self::render_module_margins($module);
1371
+
1372
+ if ( ! isset( $global_settings->auto_spacing ) || $global_settings->auto_spacing ) {
1373
+ $css .= self::render_responsive_module_margins($module);
1374
+ }
1375
  }
1376
 
1377
  // Default page heading
css/fl-builder-layout-auto-spacing.css ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* Rows
2
+ ------------------------------------------------------ */
3
+
4
+ .fl-row-content-wrap {
5
+ border-left: none !important;
6
+ border-right: none !important;
7
+ margin: 0 !important;
8
+ padding-left: 0 !important;
9
+ padding-right: 0 !important;
10
+ }
11
+ .fl-row .fl-bg-video,
12
+ .fl-row .fl-bg-slideshow {
13
+ left: 0 !important;
14
+ right: 0 !important;
15
+ }
16
+
17
+ /* Columns
18
+ ------------------------------------------------------ */
19
+
20
+ .fl-col-content {
21
+ border-left: none !important;
22
+ border-right: none !important;
23
+ margin: 0 !important;
24
+ padding-left: 0 !important;
25
+ padding-right: 0 !important;
26
+ }
css/fl-builder-layout-responsive.css CHANGED
@@ -16,21 +16,11 @@
16
 
17
  .fl-row-content-wrap {
18
  background-attachment: scroll !important;
19
- border-left: none !important;
20
- border-right: none !important;
21
- margin: 0 !important;
22
- padding-left: 0 !important;
23
- padding-right: 0 !important;
24
  }
25
  .fl-row-bg-parallax .fl-row-content-wrap {
26
  background-attachment: scroll !important;
27
  background-position: center center !important;
28
  }
29
- .fl-row .fl-bg-video,
30
- .fl-row .fl-bg-slideshow {
31
- left: 0 !important;
32
- right: 0 !important;
33
- }
34
 
35
  /* Columns
36
  ------------------------------------------------------ */
@@ -44,11 +34,4 @@
44
  }
45
  .fl-col-small {
46
  max-width: 400px;
47
- }
48
- .fl-col-content {
49
- border-left: none !important;
50
- border-right: none !important;
51
- margin: 0 !important;
52
- padding-left: 0 !important;
53
- padding-right: 0 !important;
54
  }
16
 
17
  .fl-row-content-wrap {
18
  background-attachment: scroll !important;
 
 
 
 
 
19
  }
20
  .fl-row-bg-parallax .fl-row-content-wrap {
21
  background-attachment: scroll !important;
22
  background-position: center center !important;
23
  }
 
 
 
 
 
24
 
25
  /* Columns
26
  ------------------------------------------------------ */
34
  }
35
  .fl-col-small {
36
  max-width: 400px;
 
 
 
 
 
 
 
37
  }
css/fl-builder-layout.css CHANGED
@@ -407,6 +407,27 @@ img.mfp-img {
407
  display: none;
408
  }
409
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
410
  /* Animations
411
  ------------------------------------------------------ */
412
 
407
  display: none;
408
  }
409
 
410
+ /* Form Fields
411
+ ------------------------------------------------------ */
412
+
413
+ .fl-form-field {
414
+ margin-bottom: 15px;
415
+ }
416
+ .fl-form-field input.fl-form-error {
417
+ border-color: #DD6420;
418
+ }
419
+ .fl-form-error-message {
420
+ clear: both;
421
+ color: #DD6420;
422
+ display: none;
423
+ padding-top: 8px;
424
+ font-size: 12px;
425
+ font-weight: lighter;
426
+ }
427
+ .fl-form-button-disabled {
428
+ opacity: 0.5;
429
+ }
430
+
431
  /* Animations
432
  ------------------------------------------------------ */
433
 
css/fl-builder.css CHANGED
@@ -27,6 +27,11 @@ html.fl-builder-edit {
27
  top: 0;
28
  z-index: 200000;
29
  }
 
 
 
 
 
30
  #tiptip_holder {
31
  z-index: 200000;
32
  }
@@ -551,6 +556,7 @@ html.fl-builder-edit {
551
  color: #333 !important;
552
  font-family: Helvetica, Verdana, sans-serif !important;
553
  font-size: 16px !important;
 
554
  padding: 30px;
555
  }
556
 
@@ -615,7 +621,7 @@ html.fl-builder-edit {
615
  border: 1px solid #d9d9d9;
616
  cursor: pointer;
617
  margin-bottom: 12px;
618
- height: 168px;
619
  overflow: hidden;
620
  }
621
  .fl-template-image:hover {
@@ -1209,6 +1215,7 @@ form.fl-builder-settings {
1209
  .fl-builder-settings p.error {
1210
  color: #d03436;
1211
  display: block;
 
1212
  }
1213
  .fl-builder-settings .fl-form-table .fl-field-description {
1214
  color: #999;
@@ -1317,6 +1324,33 @@ li.as-result-item em {
1317
  display: none;
1318
  }
1319
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1320
  /* Getting Started Video
1321
  ------------------------------------------------------ */
1322
 
27
  top: 0;
28
  z-index: 200000;
29
  }
30
+ .fl-builder-settings .fl-builder-loading {
31
+ background: rgba(255, 255, 255, 0.8) url(../img/ajax-loader.gif) center center no-repeat;
32
+ display: block;
33
+ position: absolute;
34
+ }
35
  #tiptip_holder {
36
  z-index: 200000;
37
  }
556
  color: #333 !important;
557
  font-family: Helvetica, Verdana, sans-serif !important;
558
  font-size: 16px !important;
559
+ line-height: 24px;
560
  padding: 30px;
561
  }
562
 
621
  border: 1px solid #d9d9d9;
622
  cursor: pointer;
623
  margin-bottom: 12px;
624
+ height: 164px;
625
  overflow: hidden;
626
  }
627
  .fl-template-image:hover {
1215
  .fl-builder-settings p.error {
1216
  color: #d03436;
1217
  display: block;
1218
+ margin-top: 5px;
1219
  }
1220
  .fl-builder-settings .fl-form-table .fl-field-description {
1221
  color: #999;
1324
  display: none;
1325
  }
1326
 
1327
+ /* Service Fields */
1328
+ .fl-builder-service-settings {
1329
+ position: relative;
1330
+ }
1331
+ .fl-builder-service-error {
1332
+ color: #ff0000 !important;
1333
+ padding: 15px 0 0 0;
1334
+ }
1335
+ .fl-builder-service-account-delete {
1336
+ color: #ff0000 !important;
1337
+ margin-left: 10px;
1338
+ position: relative;
1339
+ top: 2px;
1340
+ }
1341
+ .fl-builder-service-connect-row .fl-field-description {
1342
+ background: #f0f0f0;
1343
+ color: #333 !important;
1344
+ display: block;
1345
+ float: none;
1346
+ margin: 10px 0 0 0;
1347
+ padding: 10px;
1348
+ }
1349
+ .fl-builder-service-connect-row .fl-field-description a {
1350
+ color: #21759b !important;
1351
+ text-decoration: underline !important;
1352
+ }
1353
+
1354
  /* Getting Started Video
1355
  ------------------------------------------------------ */
1356
 
fl-builder.php CHANGED
@@ -3,7 +3,7 @@
3
  * Plugin Name: Beaver Builder Plugin (Lite Version)
4
  * Plugin URI: https://www.wpbeaverbuilder.com/?utm_source=external&utm_medium=builder&utm_campaign=plugins-page
5
  * Description: A drag and drop frontend WordPress page builder plugin that works with almost any theme!
6
- * Version: 1.5.3
7
  * Author: The Beaver Builder Team
8
  * Author URI: https://www.wpbeaverbuilder.com/?utm_source=external&utm_medium=builder&utm_campaign=plugins-page
9
  * Copyright: (c) 2014 Beaver Builder
@@ -11,7 +11,7 @@
11
  * License URI: http://www.gnu.org/licenses/gpl-2.0.html
12
  * Text Domain: fl-builder
13
  */
14
- define('FL_BUILDER_VERSION', '1.5.3');
15
  define('FL_BUILDER_DIR', plugin_dir_path(__FILE__));
16
  define('FL_BUILDER_URL', plugins_url('/', __FILE__));
17
  define('FL_BUILDER_LITE', true);
@@ -32,6 +32,7 @@ require_once 'classes/class-fl-builder-loop.php';
32
  require_once 'classes/class-fl-builder-model.php';
33
  require_once 'classes/class-fl-builder-module.php';
34
  require_once 'classes/class-fl-builder-photo.php';
 
35
  require_once 'classes/class-fl-builder-update.php';
36
  require_once 'classes/class-fl-builder-utils.php';
37
 
@@ -52,17 +53,16 @@ add_action('init', 'FLBuilderUpdate:
52
  add_action('init', 'FLBuilderModel::load_settings', 1);
53
  add_action('init', 'FLBuilderModel::load_modules', 2);
54
 
55
- /* Admin AJAX Filters */
56
- add_filter('heartbeat_received', 'FLBuilderModel::lock_post', 10, 2);
57
-
58
  /* Admin Actions */
59
  add_action('init', 'FLBuilderAdmin::init');
60
  add_action('current_screen', 'FLBuilderAdminPosts::init');
 
61
  add_action('before_delete_post', 'FLBuilderModel::delete_post');
62
  add_action('save_post', 'FLBuilderModel::save_revision');
63
  add_action('wp_restore_post_revision', 'FLBuilderModel::restore_revision', 10, 2);
64
 
65
  /* Admin Filters */
 
66
  add_filter('redirect_post_location', 'FLBuilderAdminPosts::redirect_post_location');
67
  add_filter('page_row_actions', 'FLBuilderAdminPosts::render_row_actions_link');
68
  add_filter('post_row_actions', 'FLBuilderAdminPosts::render_row_actions_link');
@@ -72,6 +72,10 @@ add_filter('all_plugins', 'FLBuilderAdmin::
72
  /* AJAX Actions */
73
  add_action('fl_ajax_fl_builder_save', 'FLBuilderModel::update');
74
  add_action('fl_ajax_fl_builder_autosuggest', 'FLBuilderAutoSuggest::init');
 
 
 
 
75
  add_action('fl_ajax_fl_builder_render_layout', 'FLBuilder::render_layout');
76
  add_action('fl_ajax_fl_builder_render_preview', 'FLBuilder::render_preview');
77
  add_action('fl_ajax_fl_builder_render_settings_form', 'FLBuilder::render_settings_form');
@@ -87,7 +91,6 @@ add_action('fl_ajax_fl_builder_render_new_module_settings', 'FLBuilder::rende
87
  add_action('fl_ajax_fl_builder_render_module_settings', 'FLBuilder::render_module_settings');
88
 
89
  /* Actions */
90
- add_action('init', 'FLBuilderModel::delete_asset_cache_domain_change');
91
  add_action('init', 'FLBuilder::register_templates_post_type');
92
  add_action('send_headers', 'FLBuilder::no_cache_headers');
93
  add_action('wp', 'FLBuilder::ajax');
@@ -100,6 +103,7 @@ add_action('wp_footer', 'FLBuilder::inclu
100
  add_action('wp_footer', 'FLBuilder::render_ui');
101
 
102
  /* Filters */
 
103
  add_filter('body_class', 'FLBuilder::body_class');
104
  add_filter('wp_default_editor', 'FLBuilder::default_editor');
105
  add_filter('mce_css', 'FLBuilder::add_editor_css');
3
  * Plugin Name: Beaver Builder Plugin (Lite Version)
4
  * Plugin URI: https://www.wpbeaverbuilder.com/?utm_source=external&utm_medium=builder&utm_campaign=plugins-page
5
  * Description: A drag and drop frontend WordPress page builder plugin that works with almost any theme!
6
+ * Version: 1.5.5
7
  * Author: The Beaver Builder Team
8
  * Author URI: https://www.wpbeaverbuilder.com/?utm_source=external&utm_medium=builder&utm_campaign=plugins-page
9
  * Copyright: (c) 2014 Beaver Builder
11
  * License URI: http://www.gnu.org/licenses/gpl-2.0.html
12
  * Text Domain: fl-builder
13
  */
14
+ define('FL_BUILDER_VERSION', '1.5.5');
15
  define('FL_BUILDER_DIR', plugin_dir_path(__FILE__));
16
  define('FL_BUILDER_URL', plugins_url('/', __FILE__));
17
  define('FL_BUILDER_LITE', true);
32
  require_once 'classes/class-fl-builder-model.php';
33
  require_once 'classes/class-fl-builder-module.php';
34
  require_once 'classes/class-fl-builder-photo.php';
35
+ require_once 'classes/class-fl-builder-services.php';
36
  require_once 'classes/class-fl-builder-update.php';
37
  require_once 'classes/class-fl-builder-utils.php';
38
 
53
  add_action('init', 'FLBuilderModel::load_settings', 1);
54
  add_action('init', 'FLBuilderModel::load_modules', 2);
55
 
 
 
 
56
  /* Admin Actions */
57
  add_action('init', 'FLBuilderAdmin::init');
58
  add_action('current_screen', 'FLBuilderAdminPosts::init');
59
+ add_action('wp_ajax_fl_builder_save', 'FLBuilderModel::update');
60
  add_action('before_delete_post', 'FLBuilderModel::delete_post');
61
  add_action('save_post', 'FLBuilderModel::save_revision');
62
  add_action('wp_restore_post_revision', 'FLBuilderModel::restore_revision', 10, 2);
63
 
64
  /* Admin Filters */
65
+ add_filter('heartbeat_received', 'FLBuilderModel::lock_post', 10, 2);
66
  add_filter('redirect_post_location', 'FLBuilderAdminPosts::redirect_post_location');
67
  add_filter('page_row_actions', 'FLBuilderAdminPosts::render_row_actions_link');
68
  add_filter('post_row_actions', 'FLBuilderAdminPosts::render_row_actions_link');
72
  /* AJAX Actions */
73
  add_action('fl_ajax_fl_builder_save', 'FLBuilderModel::update');
74
  add_action('fl_ajax_fl_builder_autosuggest', 'FLBuilderAutoSuggest::init');
75
+ add_action('fl_ajax_fl_builder_render_service_settings', 'FLBuilderServices::render_settings');
76
+ add_action('fl_ajax_fl_builder_connect_service', 'FLBuilderServices::connect_service');
77
+ add_action('fl_ajax_fl_builder_render_service_fields', 'FLBuilderServices::render_fields');
78
+ add_action('fl_ajax_fl_builder_delete_service_account', 'FLBuilderServices::delete_account');
79
  add_action('fl_ajax_fl_builder_render_layout', 'FLBuilder::render_layout');
80
  add_action('fl_ajax_fl_builder_render_preview', 'FLBuilder::render_preview');
81
  add_action('fl_ajax_fl_builder_render_settings_form', 'FLBuilder::render_settings_form');
91
  add_action('fl_ajax_fl_builder_render_module_settings', 'FLBuilder::render_module_settings');
92
 
93
  /* Actions */
 
94
  add_action('init', 'FLBuilder::register_templates_post_type');
95
  add_action('send_headers', 'FLBuilder::no_cache_headers');
96
  add_action('wp', 'FLBuilder::ajax');
103
  add_action('wp_footer', 'FLBuilder::render_ui');
104
 
105
  /* Filters */
106
+ add_filter('found_posts', 'FLBuilderLoop::found_posts', 1, 2);
107
  add_filter('body_class', 'FLBuilder::body_class');
108
  add_filter('wp_default_editor', 'FLBuilder::default_editor');
109
  add_filter('mce_css', 'FLBuilder::add_editor_css');
img/templates/coming-soon.jpg ADDED
Binary file
img/templates/pricing.jpg ADDED
Binary file
img/templates/signup.jpg ADDED
Binary file
img/templates/subscribe.jpg ADDED
Binary file
includes/column-css.php CHANGED
@@ -4,7 +4,13 @@
4
 
5
  <?php if(!empty($col->settings->text_color)) : ?>
6
  .fl-node-<?php echo $col->node; ?>,
7
- .fl-node-<?php echo $col->node; ?> * {
 
 
 
 
 
 
8
  color: #<?php echo $col->settings->text_color; ?>;
9
  }
10
  <?php endif; ?>
4
 
5
  <?php if(!empty($col->settings->text_color)) : ?>
6
  .fl-node-<?php echo $col->node; ?>,
7
+ .fl-node-<?php echo $col->node; ?> a,
8
+ .fl-node-<?php echo $col->node; ?> h1,
9
+ .fl-node-<?php echo $col->node; ?> h2,
10
+ .fl-node-<?php echo $col->node; ?> h3,
11
+ .fl-node-<?php echo $col->node; ?> h4,
12
+ .fl-node-<?php echo $col->node; ?> h5,
13
+ .fl-node-<?php echo $col->node; ?> h6 {
14
  color: #<?php echo $col->settings->text_color; ?>;
15
  }
16
  <?php endif; ?>
includes/field-button.php ADDED
@@ -0,0 +1 @@
 
1
+ <span class="fl-builder-button<?php if ( isset( $field['class'] ) ) echo ' '. $field['class']; ?>" href="javascript:void(0);" onclick="return false;"><?php echo $field['label']; ?></span>
includes/field.php CHANGED
@@ -4,13 +4,19 @@
4
  <th>
5
  <label for="<?php echo $name; ?>">
6
  <?php
 
 
 
 
 
 
 
7
 
8
- echo $field['label'];
9
-
10
- if(isset($i)) {
11
- echo ' <span class="fl-builder-field-index">' . ($i + 1) . '</span>';
12
- }
13
-
14
  ?>
15
  <?php if(isset($field['help'])) : ?>
16
  <span class="fl-help-tooltip">
4
  <th>
5
  <label for="<?php echo $name; ?>">
6
  <?php
7
+
8
+ if ( 'button' == $field['type'] ) {
9
+ echo '&nbsp;';
10
+ }
11
+ else {
12
+
13
+ echo $field['label'];
14
 
15
+ if ( isset( $i ) ) {
16
+ echo ' <span class="fl-builder-field-index">' . ( $i + 1 ) . '</span>';
17
+ }
18
+ }
19
+
 
20
  ?>
21
  <?php if(isset($field['help'])) : ?>
22
  <span class="fl-help-tooltip">
includes/global-settings.php CHANGED
@@ -112,10 +112,20 @@ FLBuilder::register_settings_form('global', array(
112
  ),
113
  'toggle' => array(
114
  '1' => array(
115
- 'fields' => array('responsive_breakpoint', 'medium_breakpoint')
116
  )
117
  )
118
  ),
 
 
 
 
 
 
 
 
 
 
119
  'medium_breakpoint' => array(
120
  'type' => 'text',
121
  'label' => __('Medium Device Breakpoint', 'fl-builder'),
112
  ),
113
  'toggle' => array(
114
  '1' => array(
115
+ 'fields' => array('auto_spacing', 'responsive_breakpoint', 'medium_breakpoint')
116
  )
117
  )
118
  ),
119
+ 'auto_spacing' => array(
120
+ 'type' => 'select',
121
+ 'label' => _x( 'Enable Auto Spacing', 'General settings form field label. Intended meaning: "Enable auto spacing for responsive layouts?"', 'fl-builder' ),
122
+ 'default' => '1',
123
+ 'options' => array(
124
+ '0' => __('No', 'fl-builder'),
125
+ '1' => __('Yes', 'fl-builder')
126
+ ),
127
+ 'help' => __('When auto spacing is enabled, the builder will automatically adjust the margins and padding in your layout once the small device breakpoint is reached. Most users will want to leave this enabled.', 'fl-builder')
128
+ ),
129
  'medium_breakpoint' => array(
130
  'type' => 'text',
131
  'label' => __('Medium Device Breakpoint', 'fl-builder'),
includes/js-config.php CHANGED
@@ -22,6 +22,8 @@ var FLBuilderStrings = {
22
  column: '<?php esc_attr_e('Column', 'fl-builder') ?>',
23
  columnSettings: '<?php esc_attr_e('Column Settings', 'fl-builder') ?>',
24
  contentSliderSelectLayout: '<?php esc_attr_e('Please select either a background layout or content layout before submitting.', 'fl-builder'); ?>',
 
 
25
  deleteFieldMessage: '<?php esc_attr_e('Do you really want to delete this item?', 'fl-builder'); ?>',
26
  deleteModuleMessage: '<?php esc_attr_e('Do you really want to delete this module? All content data will be permanently deleted.', 'fl-builder') ?>',
27
  deleteRowMessage: '<?php esc_attr_e('Do you really want to delete this row? All content data will be permanently deleted.', 'fl-builder') ?>',
@@ -54,6 +56,7 @@ var FLBuilderStrings = {
54
  photoPage: '<?php esc_attr_e('Photo Page', 'fl-builder'); ?>',
55
  photoSelected: '<?php esc_attr_e('Photo Selected', 'fl-builder'); ?>',
56
  photosSelected: '<?php esc_attr_e('Photos Selected', 'fl-builder'); ?>',
 
57
  publish: '<?php esc_attr_e('Publish Changes', 'fl-builder'); ?>',
58
  remove: '<?php esc_attr_e('Remove', 'fl-builder'); ?>',
59
  row: '<?php esc_attr_e('Row', 'fl-builder') ?>',
@@ -64,6 +67,9 @@ var FLBuilderStrings = {
64
  selectPhotos: '<?php esc_attr_e('Select Photos', 'fl-builder'); ?>',
65
  selectVideo: '<?php esc_attr_e('Select Video', 'fl-builder'); ?>',
66
  settings: '<?php _ex( '%s Settings', '%s stands for module name.', 'fl-builder' ); ?>',
 
 
 
67
  takeHelpTour: '<?php esc_attr_e('Take a Tour', 'fl-builder'); ?>',
68
  templateAppend: '<?php esc_attr_e('Append New Layout', 'fl-builder'); ?>',
69
  templateReplace: '<?php esc_attr_e('Replace Existing Layout', 'fl-builder'); ?>',
22
  column: '<?php esc_attr_e('Column', 'fl-builder') ?>',
23
  columnSettings: '<?php esc_attr_e('Column Settings', 'fl-builder') ?>',
24
  contentSliderSelectLayout: '<?php esc_attr_e('Please select either a background layout or content layout before submitting.', 'fl-builder'); ?>',
25
+ deleteAccount: '<?php esc_attr_e('Remove Account', 'fl-builder'); ?>',
26
+ deleteAccountWarning: '<?php esc_attr_e('Are you sure you want to remove this account? Other modules that are connected to it will be affected.', 'fl-builder'); ?>',
27
  deleteFieldMessage: '<?php esc_attr_e('Do you really want to delete this item?', 'fl-builder'); ?>',
28
  deleteModuleMessage: '<?php esc_attr_e('Do you really want to delete this module? All content data will be permanently deleted.', 'fl-builder') ?>',
29
  deleteRowMessage: '<?php esc_attr_e('Do you really want to delete this row? All content data will be permanently deleted.', 'fl-builder') ?>',
56
  photoPage: '<?php esc_attr_e('Photo Page', 'fl-builder'); ?>',
57
  photoSelected: '<?php esc_attr_e('Photo Selected', 'fl-builder'); ?>',
58
  photosSelected: '<?php esc_attr_e('Photos Selected', 'fl-builder'); ?>',
59
+ pleaseWait: '<?php esc_attr_e('Please Wait...', 'fl-builder'); ?>',
60
  publish: '<?php esc_attr_e('Publish Changes', 'fl-builder'); ?>',
61
  remove: '<?php esc_attr_e('Remove', 'fl-builder'); ?>',
62
  row: '<?php esc_attr_e('Row', 'fl-builder') ?>',
67
  selectPhotos: '<?php esc_attr_e('Select Photos', 'fl-builder'); ?>',
68
  selectVideo: '<?php esc_attr_e('Select Video', 'fl-builder'); ?>',
69
  settings: '<?php _ex( '%s Settings', '%s stands for module name.', 'fl-builder' ); ?>',
70
+ subscriptionModuleAccountError: '<?php esc_attr_e('Please select an account before saving.', 'fl-builder'); ?>',
71
+ subscriptionModuleConnectError: '<?php esc_attr_e('Please connect an account before saving.', 'fl-builder'); ?>',
72
+ subscriptionModuleListError: '<?php esc_attr_e('Please select a list before saving.', 'fl-builder'); ?>',
73
  takeHelpTour: '<?php esc_attr_e('Take a Tour', 'fl-builder'); ?>',
74
  templateAppend: '<?php esc_attr_e('Append New Layout', 'fl-builder'); ?>',
75
  templateReplace: '<?php esc_attr_e('Replace Existing Layout', 'fl-builder'); ?>',
includes/loop-settings.php CHANGED
@@ -4,6 +4,7 @@ FLBuilderModel::default_settings($settings, array(
4
  'post_type' => 'post',
5
  'order_by' => 'date',
6
  'order' => 'DESC',
 
7
  'users' => ''
8
  ));
9
 
@@ -45,6 +46,15 @@ FLBuilderModel::default_settings($settings, array(
45
  )
46
  ), $settings);
47
 
 
 
 
 
 
 
 
 
 
48
  ?>
49
  </table>
50
  </div>
4
  'post_type' => 'post',
5
  'order_by' => 'date',
6
  'order' => 'DESC',
7
+ 'offset' => 0,
8
  'users' => ''
9
  ));
10
 
46
  )
47
  ), $settings);
48
 
49
+ // Offset
50
+ FLBuilder::render_settings_field('offset', array(
51
+ 'type' => 'text',
52
+ 'label' => __('Offset', 'fl-builder'),
53
+ 'default' => '0',
54
+ 'size' => '4',
55
+ 'help' => __('Skip this many posts that match the specified criteria.', 'fl-builder')
56
+ ), $settings);
57
+
58
  ?>
59
  </table>
60
  </div>
includes/row-css.php CHANGED
@@ -1,8 +1,12 @@
1
  <?php if(!empty($row->settings->text_color)) : ?>
2
- .fl-node-<?php echo $row->node; ?> {
3
- color: #<?php echo $row->settings->text_color; ?>;
4
- }
5
- .fl-node-<?php echo $row->node; ?> * {
 
 
 
 
6
  color: #<?php echo $row->settings->text_color; ?>;
7
  }
8
  <?php endif; ?>
1
  <?php if(!empty($row->settings->text_color)) : ?>
2
+ .fl-node-<?php echo $row->node; ?>,
3
+ .fl-node-<?php echo $row->node; ?> a,
4
+ .fl-node-<?php echo $row->node; ?> h1,
5
+ .fl-node-<?php echo $row->node; ?> h2,
6
+ .fl-node-<?php echo $row->node; ?> h3,
7
+ .fl-node-<?php echo $row->node; ?> h4,
8
+ .fl-node-<?php echo $row->node; ?> h5,
9
+ .fl-node-<?php echo $row->node; ?> h6 {
10
  color: #<?php echo $row->settings->text_color; ?>;
11
  }
12
  <?php endif; ?>
includes/service-settings.php ADDED
@@ -0,0 +1,41 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <div class="fl-builder-service-settings">
2
+ <table class="fl-form-table">
3
+ <?php
4
+
5
+ // Get the service type.
6
+ $service_type = null;
7
+
8
+ if ( isset( $section['services'] ) && $section['services'] != 'all' ) {
9
+ $service_type = $section['services'];
10
+ }
11
+
12
+ // Get the service data.
13
+ $services = FLBuilderServices::get_services_data( $service_type );
14
+
15
+ // Remove services that don't meet the requirements.
16
+ if ( isset( $services['mailpoet'] ) && ! class_exists( 'WYSIJA' ) ) {
17
+ unset( $services['mailpoet'] );
18
+ }
19
+
20
+ // Build the select options.
21
+ $options = array( '' => __( 'Choose...', 'fl-builder' ) );
22
+
23
+ foreach ( $services as $key => $service ) {
24
+ $options[ $key ] = $service['name'];
25
+ }
26
+
27
+ // Render the service select.
28
+ FLBuilder::render_settings_field( 'service', array(
29
+ 'row_class' => 'fl-builder-service-select-row',
30
+ 'class' => 'fl-builder-service-select',
31
+ 'type' => 'select',
32
+ 'label' => __( 'Service', 'fl-builder' ),
33
+ 'options' => $options,
34
+ 'preview' => array(
35
+ 'type' => 'none'
36
+ )
37
+ ), $settings );
38
+
39
+ ?>
40
+ </table>
41
+ </div>
includes/updater-config.php CHANGED
@@ -3,7 +3,7 @@
3
  if(class_exists('FLUpdater')) {
4
  FLUpdater::add_product(array(
5
  'name' => 'Beaver Builder Plugin (Lite Version)',
6
- 'version' => '1.5.3',
7
  'slug' => 'bb-plugin',
8
  'type' => 'plugin'
9
  ));
3
  if(class_exists('FLUpdater')) {
4
  FLUpdater::add_product(array(
5
  'name' => 'Beaver Builder Plugin (Lite Version)',
6
+ 'version' => '1.5.5',
7
  'slug' => 'bb-plugin',
8
  'type' => 'plugin'
9
  ));
includes/vendor/aweber/aweber.php ADDED
@@ -0,0 +1,292 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ require_once('exceptions.php');
3
+ require_once('oauth_adapter.php');
4
+ require_once('oauth_application.php');
5
+ require_once('aweber_response.php');
6
+ require_once('aweber_collection.php');
7
+ require_once('aweber_entry_data_array.php');
8
+ require_once('aweber_entry.php');
9
+
10
+ /**
11
+ * AWeberServiceProvider
12
+ *
13
+ * Provides specific AWeber information or implementing OAuth.
14
+ * @uses OAuthServiceProvider
15
+ * @package
16
+ * @version $id$
17
+ */
18
+ class AWeberServiceProvider implements OAuthServiceProvider {
19
+
20
+ /**
21
+ * @var String Location for API calls
22
+ */
23
+ public $baseUri = 'https://api.aweber.com/1.0';
24
+
25
+ /**
26
+ * @var String Location to request an access token
27
+ */
28
+ public $accessTokenUrl = 'https://auth.aweber.com/1.0/oauth/access_token';
29
+
30
+ /**
31
+ * @var String Location to authorize an Application
32
+ */
33
+ public $authorizeUrl = 'https://auth.aweber.com/1.0/oauth/authorize';
34
+
35
+ /**
36
+ * @var String Location to request a request token
37
+ */
38
+ public $requestTokenUrl = 'https://auth.aweber.com/1.0/oauth/request_token';
39
+
40
+
41
+ public function getBaseUri() {
42
+ return $this->baseUri;
43
+ }
44
+
45
+ public function removeBaseUri($url) {
46
+ return str_replace($this->getBaseUri(), '', $url);
47
+ }
48
+
49
+ public function getAccessTokenUrl() {
50
+ return $this->accessTokenUrl;
51
+ }
52
+
53
+ public function getAuthorizeUrl() {
54
+ return $this->authorizeUrl;
55
+ }
56
+
57
+ public function getRequestTokenUrl() {
58
+ return $this->requestTokenUrl;
59
+ }
60
+
61
+ public function getAuthTokenFromUrl() { return ''; }
62
+ public function getUserData() { return ''; }
63
+
64
+ }
65
+
66
+ /**
67
+ * AWeberAPIBase
68
+ *
69
+ * Base object that all AWeberAPI objects inherit from. Allows specific pieces
70
+ * of functionality to be shared across any object in the API, such as the
71
+ * ability to introspect the collections map.
72
+ *
73
+ * @package
74
+ * @version $id$
75
+ */
76
+ class AWeberAPIBase {
77
+
78
+ /**
79
+ * Maintains data about what children collections a given object type
80
+ * contains.
81
+ */
82
+ static protected $_collectionMap = array(
83
+ 'account' => array('lists', 'integrations'),
84
+ 'broadcast_campaign' => array('links', 'messages', 'stats'),
85
+ 'followup_campaign' => array('links', 'messages', 'stats'),
86
+ 'link' => array('clicks'),
87
+ 'list' => array('campaigns', 'custom_fields', 'subscribers',
88
+ 'web_forms', 'web_form_split_tests'),
89
+ 'web_form' => array(),
90
+ 'web_form_split_test' => array('components'),
91
+ );
92
+
93
+ /**
94
+ * loadFromUrl
95
+ *
96
+ * Creates an object, either collection or entry, based on the given
97
+ * URL.
98
+ *
99
+ * @param mixed $url URL for this request
100
+ * @access public
101
+ * @return AWeberEntry or AWeberCollection
102
+ */
103
+ public function loadFromUrl($url) {
104
+ $data = $this->adapter->request('GET', $url);
105
+ return $this->readResponse($data, $url);
106
+ }
107
+
108
+ protected function _cleanUrl($url) {
109
+ return str_replace($this->adapter->app->getBaseUri(), '', $url);
110
+ }
111
+
112
+ /**
113
+ * readResponse
114
+ *
115
+ * Interprets a response, and creates the appropriate object from it.
116
+ * @param mixed $response Data returned from a request to the AWeberAPI
117
+ * @param mixed $url URL that this data was requested from
118
+ * @access protected
119
+ * @return mixed
120
+ */
121
+ protected function readResponse($response, $url) {
122
+ $this->adapter->parseAsError($response);
123
+ if (!empty($response['id'])) {
124
+ return new AWeberEntry($response, $url, $this->adapter);
125
+ } else if (array_key_exists('entries', $response)) {
126
+ return new AWeberCollection($response, $url, $this->adapter);
127
+ }
128
+ return false;
129
+ }
130
+ }
131
+
132
+ /**
133
+ * AWeberAPI
134
+ *
135
+ * Creates a connection to the AWeberAPI for a given consumer application.
136
+ * This is generally the starting point for this library. Instances can be
137
+ * created directly with consumerKey and consumerSecret.
138
+ * @uses AWeberAPIBase
139
+ * @package
140
+ * @version $id$
141
+ */
142
+ class AWeberAPI extends AWeberAPIBase {
143
+
144
+ /**
145
+ * @var String Consumer Key
146
+ */
147
+ public $consumerKey = false;
148
+
149
+ /**
150
+ * @var String Consumer Secret
151
+ */
152
+ public $consumerSecret = false;
153
+
154
+ /**
155
+ * @var Object - Populated in setAdapter()
156
+ */
157
+ public $adapter = false;
158
+
159
+ /**
160
+ * Uses the app's authorization code to fetch an access token
161
+ *
162
+ * @param String Authorization code from authorize app page
163
+ */
164
+ public static function getDataFromAweberID($string) {
165
+ list($consumerKey, $consumerSecret, $requestToken, $tokenSecret, $verifier) = AWeberAPI::_parseAweberID($string);
166
+
167
+ if (!$verifier) {
168
+ return null;
169
+ }
170
+ $aweber = new AweberAPI($consumerKey, $consumerSecret);
171
+ $aweber->adapter->user->requestToken = $requestToken;
172
+ $aweber->adapter->user->tokenSecret = $tokenSecret;
173
+ $aweber->adapter->user->verifier = $verifier;
174
+ list($accessToken, $accessSecret) = $aweber->getAccessToken();
175
+ return array($consumerKey, $consumerSecret, $accessToken, $accessSecret);
176
+ }
177
+
178
+ protected static function _parseAWeberID($string) {
179
+ $values = explode('|', $string);
180
+ if (count($values) < 5) {
181
+ return null;
182
+ }
183
+ return array_slice($values, 0, 5);
184
+ }
185
+
186
+ /**
187
+ * Sets the consumer key and secret for the API object. The
188
+ * key and secret are listed in the My Apps page in the labs.aweber.com
189
+ * Control Panel OR, in the case of distributed apps, will be returned
190
+ * from the getDataFromAweberID() function
191
+ *
192
+ * @param String Consumer Key
193
+ * @param String Consumer Secret
194
+ * @return null
195
+ */
196
+ public function __construct($key, $secret) {
197
+ // Load key / secret
198
+ $this->consumerKey = $key;
199
+ $this->consumerSecret = $secret;
200
+
201
+ $this->setAdapter();
202
+ }
203
+
204
+ /**
205
+ * Returns the authorize URL by appending the request
206
+ * token to the end of the Authorize URI, if it exists
207
+ *
208
+ * @return string The Authorization URL
209
+ */
210
+ public function getAuthorizeUrl() {
211
+ $requestToken = $this->user->requestToken;
212
+ return (empty($requestToken)) ?
213
+ $this->adapter->app->getAuthorizeUrl()
214
+ :
215
+ $this->adapter->app->getAuthorizeUrl() . "?oauth_token={$this->user->requestToken}";
216
+ }
217
+
218
+ /**
219
+ * Sets the adapter for use with the API
220
+ */
221
+ public function setAdapter($adapter=null) {
222
+ if (empty($adapter)) {
223
+ $serviceProvider = new AWeberServiceProvider();
224
+ $adapter = new OAuthApplication($serviceProvider);
225
+ $adapter->consumerKey = $this->consumerKey;
226
+ $adapter->consumerSecret = $this->consumerSecret;
227
+ }
228
+ $this->adapter = $adapter;
229
+ }
230
+
231
+ /**
232
+ * Fetches account data for the associated account
233
+ *
234
+ * @param String Access Token (Only optional/cached if you called getAccessToken() earlier
235
+ * on the same page)
236
+ * @param String Access Token Secret (Only optional/cached if you called getAccessToken() earlier
237
+ * on the same page)
238
+ * @return Object AWeberCollection Object with the requested
239
+ * account data
240
+ */
241
+ public function getAccount($token=false, $secret=false) {
242
+ if ($token && $secret) {
243
+ $user = new OAuthUser();
244
+ $user->accessToken = $token;
245
+ $user->tokenSecret = $secret;
246
+ $this->adapter->user = $user;
247
+ }
248
+
249
+ $body = $this->adapter->request('GET', '/accounts');
250
+ $accounts = $this->readResponse($body, '/accounts');
251
+ return $accounts[0];
252
+ }
253
+
254
+ /**
255
+ * PHP Automagic
256
+ */
257
+ public function __get($item) {
258
+ if ($item == 'user') return $this->adapter->user;
259
+ trigger_error("Could not find \"{$item}\"");
260
+ }
261
+
262
+ /**
263
+ * Request a request token from AWeber and associate the
264
+ * provided $callbackUrl with the new token
265
+ * @param String The URL where users should be redirected
266
+ * once they authorize your app
267
+ * @return Array Contains the request token as the first item
268
+ * and the request token secret as the second item of the array
269
+ */
270
+ public function getRequestToken($callbackUrl) {
271
+ $requestToken = $this->adapter->getRequestToken($callbackUrl);
272
+ return array($requestToken, $this->user->tokenSecret);
273
+ }
274
+
275
+ /**
276
+ * Request an access token using the request tokens stored in the
277
+ * current user object. You would want to first set the request tokens
278
+ * on the user before calling this function via:
279
+ *
280
+ * $aweber->user->tokenSecret = $_COOKIE['requestTokenSecret'];
281
+ * $aweber->user->requestToken = $_GET['oauth_token'];
282
+ * $aweber->user->verifier = $_GET['oauth_verifier'];
283
+ *
284
+ * @return Array Contains the access token as the first item
285
+ * and the access token secret as the second item of the array
286
+ */
287
+ public function getAccessToken() {
288
+ return $this->adapter->getAccessToken();
289
+ }
290
+ }
291
+
292
+ ?>
includes/vendor/aweber/aweber_api.php ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ if (class_exists('AWeberAPI')) {
4
+ trigger_error("Duplicate: Another AWeberAPI client library is already in scope.", E_USER_WARNING);
5
+ }
6
+ else {
7
+ require_once('aweber.php');
8
+ }
includes/vendor/aweber/aweber_collection.php ADDED
@@ -0,0 +1,268 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class AWeberCollection extends AWeberResponse implements ArrayAccess, Iterator, Countable {
3
+
4
+ protected $pageSize = 100;
5
+ protected $pageStart = 0;
6
+
7
+ protected function _updatePageSize() {
8
+
9
+ # grab the url, or prev and next url and pull ws.size from it
10
+ $url = $this->url;
11
+ if (array_key_exists('next_collection_link', $this->data)) {
12
+ $url = $this->data['next_collection_link'];
13
+
14
+ } elseif (array_key_exists('prev_collection_link', $this->data)) {
15
+ $url = $this->data['prev_collection_link'];
16
+ }
17
+
18
+ # scan querystring for ws_size
19
+ $url_parts = parse_url($url);
20
+
21
+ # we have a query string
22
+ if (array_key_exists('query', $url_parts)) {
23
+ parse_str($url_parts['query'], $params);
24
+
25
+ # we have a ws_size
26
+ if (array_key_exists('ws_size', $params)) {
27
+
28
+ # set pageSize
29
+ $this->pageSize = $params['ws_size'];
30
+ return;
31
+ }
32
+ }
33
+
34
+ # we dont have one, just count the # of entries
35
+ $this->pageSize = count($this->data['entries']);
36
+ }
37
+
38
+ public function __construct($response, $url, $adapter) {
39
+ parent::__construct($response, $url, $adapter);
40
+ $this->_updatePageSize();
41
+ }
42
+
43
+ /**
44
+ * @var array Holds list of keys that are not publicly accessible
45
+ */
46
+ protected $_privateData = array(
47
+ 'entries',
48
+ 'start',
49
+ 'next_collection_link',
50
+ );
51
+
52
+ /**
53
+ * getById
54
+ *
55
+ * Gets an entry object of this collection type with the given id
56
+ * @param mixed $id ID of the entry you are requesting
57
+ * @access public
58
+ * @return AWeberEntry
59
+ */
60
+ public function getById($id) {
61
+ $data = $this->adapter->request('GET', "{$this->url}/{$id}");
62
+ $url = "{$this->url}/{$id}";
63
+ return new AWeberEntry($data, $url, $this->adapter);
64
+ }
65
+
66
+ /** getParentEntry
67
+ *
68
+ * Gets an entry's parent entry
69
+ * Returns NULL if no parent entry
70
+ */
71
+ public function getParentEntry(){
72
+ $url_parts = explode('/', $this->url);
73
+ $size = count($url_parts);
74
+
75
+ # Remove collection id and slash from end of url
76
+ $url = substr($this->url, 0, -strlen($url_parts[$size-1])-1);
77
+
78
+ try {
79
+ $data = $this->adapter->request('GET', $url);
80
+ return new AWeberEntry($data, $url, $this->adapter);
81
+ } catch (Exception $e) {
82
+ return NULL;
83
+ }
84
+ }
85
+
86
+ /**
87
+ * _type
88
+ *
89
+ * Interpret what type of resources are held in this collection by
90
+ * analyzing the URL
91
+ *
92
+ * @access protected
93
+ * @return void
94
+ */
95
+ protected function _type() {
96
+ $urlParts = explode('/', $this->url);
97
+ $type = array_pop($urlParts);
98
+ return $type;
99
+ }
100
+
101
+ /**
102
+ * create
103
+ *
104
+ * Invoke the API method to CREATE a new entry resource.
105
+ *
106
+ * Note: Not all entry resources are eligible to be created, please
107
+ * refer to the AWeber API Reference Documentation at
108
+ * https://labs.aweber.com/docs/reference/1.0 for more
109
+ * details on which entry resources may be created and what
110
+ * attributes are required for creating resources.
111
+ *
112
+ * @access public
113
+ * @param params mixed associtative array of key/value pairs.
114
+ * @return AWeberEntry(Resource) The new resource created
115
+ */
116
+ public function create($kv_pairs) {
117
+ # Create Resource
118
+ $params = array_merge(array('ws.op' => 'create'), $kv_pairs);
119
+ $data = $this->adapter->request('POST', $this->url, $params, array('return' => 'headers'));
120
+
121
+ # Return new Resource
122
+ $url = $data['Location'];
123
+ $resource_data = $this->adapter->request('GET', $url);
124
+ return new AWeberEntry($resource_data, $url, $this->adapter);
125
+ }
126
+
127
+ /**
128
+ * find
129
+ *
130
+ * Invoke the API 'find' operation on a collection to return a subset
131
+ * of that collection. Not all collections support the 'find' operation.
132
+ * refer to https://labs.aweber.com/docs/reference/1.0 for more information.
133
+ *
134
+ * @param mixed $search_data Associative array of key/value pairs used as search filters
135
+ * * refer to https://labs.aweber.com/docs/reference/1.0 for a
136
+ * complete list of valid search filters.
137
+ * * filtering on attributes that require additional permissions to
138
+ * display requires an app authorized with those additional permissions.
139
+ * @access public
140
+ * @return AWeberCollection
141
+ */
142
+ public function find($search_data) {
143
+ # invoke find operation
144
+ $params = array_merge($search_data, array('ws.op' => 'find'));
145
+ $data = $this->adapter->request('GET', $this->url, $params);
146
+
147
+ # get total size
148
+ $ts_params = array_merge($params, array('ws.show' => 'total_size'));
149
+ $total_size = $this->adapter->request('GET', $this->url, $ts_params, array('return' => 'integer'));
150
+ $data['total_size'] = $total_size;
151
+
152
+ # return collection
153
+ return $this->readResponse($data, $this->url);
154
+ }
155
+
156
+ /*
157
+ * ArrayAccess Functions
158
+ *
159
+ * Allows this object to be accessed via bracket notation (ie $obj[$x])
160
+ * http://php.net/manual/en/class.arrayaccess.php
161
+ */
162
+
163
+ public function offsetSet($offset, $value) {}
164
+ public function offsetUnset($offset) {}
165
+ public function offsetExists($offset) {
166
+
167
+ if ($offset >=0 && $offset < $this->total_size) {
168
+ return true;
169
+ }
170
+ return false;
171
+ }
172
+ protected function _fetchCollectionData($offset) {
173
+
174
+ # we dont have a next page, we're done
175
+ if (!array_key_exists('next_collection_link', $this->data)) {
176
+ return null;
177
+ }
178
+
179
+ # snag query string args from collection
180
+ $parsed = parse_url($this->data['next_collection_link']);
181
+
182
+ # parse the query string to get params
183
+ $pairs = explode('&', $parsed['query']);
184
+ foreach ($pairs as $pair) {
185
+ list($key, $val) = explode('=', $pair);
186
+ $params[$key] = $val;
187
+ }
188
+
189
+ # calculate new args
190
+ $limit = $params['ws.size'];
191
+ $pagination_offset = intval($offset / $limit) * $limit;
192
+ $params['ws.start'] = $pagination_offset;
193
+
194
+ # fetch data, exclude query string
195
+ $url_parts = explode('?', $this->url);
196
+ $data = $this->adapter->request('GET', $url_parts[0], $params);
197
+ $this->pageStart = $params['ws.start'];
198
+ $this->pageSize = $params['ws.size'];
199
+
200
+ $collection_data = array('entries', 'next_collection_link', 'prev_collection_link', 'ws.start');
201
+
202
+ foreach ($collection_data as $item) {
203
+ if (!array_key_exists($item, $this->data)) {
204
+ continue;
205
+ }
206
+ if (!array_key_exists($item, $data)) {
207
+ continue;
208
+ }
209
+ $this->data[$item] = $data[$item];
210
+ }
211
+ }
212
+
213
+ public function offsetGet($offset) {
214
+
215
+ if (!$this->offsetExists($offset)) {
216
+ return null;
217
+ }
218
+
219
+ $limit = $this->pageSize;
220
+ $pagination_offset = intval($offset / $limit) * $limit;
221
+
222
+ # load collection page if needed
223
+ if ($pagination_offset !== $this->pageStart) {
224
+ $this->_fetchCollectionData($offset);
225
+ }
226
+
227
+ $entry = $this->data['entries'][$offset - $pagination_offset];
228
+
229
+ # we have an entry, cast it to an AWeberEntry and return it
230
+ $entry_url = $this->adapter->app->removeBaseUri($entry['self_link']);
231
+ return new AWeberEntry($entry, $entry_url, $this->adapter);
232
+ }
233
+
234
+ /*
235
+ * Iterator
236
+ */
237
+ protected $_iterationKey = 0;
238
+
239
+ public function current() {
240
+ return $this->offsetGet($this->_iterationKey);
241
+ }
242
+
243
+ public function key() {
244
+ return $this->_iterationKey;
245
+ }
246
+
247
+ public function next() {
248
+ $this->_iterationKey++;
249
+ }
250
+
251
+ public function rewind() {
252
+ $this->_iterationKey = 0;
253
+ }
254
+
255
+ public function valid() {
256
+ return $this->offsetExists($this->key());
257
+ }
258
+
259
+ /*
260
+ * Countable interface methods
261
+ * Allows PHP's count() and sizeOf() functions to act on this object
262
+ * http://www.php.net/manual/en/class.countable.php
263
+ */
264
+
265
+ public function count() {
266
+ return $this->total_size;
267
+ }
268
+ }
includes/vendor/aweber/aweber_entry.php ADDED
@@ -0,0 +1,343 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class AWeberEntry extends AWeberResponse {
4
+
5
+ /**
6
+ * @var array Holds list of data keys that are not publicly accessible
7
+ */
8
+ protected $_privateData = array(
9
+ 'resource_type_link',
10
+ 'http_etag',
11
+ );
12
+
13
+ /**
14
+ * @var array Stores local modifications that have not been saved
15
+ */
16
+ protected $_localDiff = array();
17
+
18
+ /**
19
+ * @var array Holds AWeberCollection objects already instantiated, keyed by
20
+ * their resource name (plural)
21
+ */
22
+ protected $_collections = array();
23
+
24
+ /**
25
+ * attrs
26
+ *
27
+ * Provides a simple array of all the available data (and collections) available
28
+ * in this entry.
29
+ *
30
+ * @access public
31
+ * @return array
32
+ */
33
+ public function attrs() {
34
+ $attrs = array();
35
+ foreach ($this->data as $key => $value) {
36
+ if (!in_array($key, $this->_privateData) && !strpos($key, 'collection_link')) {
37
+ $attrs[$key] = $value;
38
+ }
39
+ }
40
+ if (!empty(AWeberAPI::$_collectionMap[$this->type])) {
41
+ foreach (AWeberAPI::$_collectionMap[$this->type] as $child) {
42
+ $attrs[$child] = 'collection';
43
+ }
44
+ }
45
+ return $attrs;
46
+ }
47
+
48
+ /**
49
+ * _type
50
+ *
51
+ * Used to pull the name of this resource from its resource_type_link
52
+ * @access protected
53
+ * @return String
54
+ */
55
+ protected function _type() {
56
+ if (empty($this->type)) {
57
+ $typeLink = $this->data['resource_type_link'];
58
+ if (empty($typeLink)) return null;
59
+ list($url, $type) = explode('#', $typeLink);
60
+ $this->type = $type;
61
+ }
62
+ return $this->type;
63
+ }
64
+
65
+ /**
66
+ * delete
67
+ *
68
+ * Delete this object from the AWeber system. May not be supported
69
+ * by all entry types.
70
+ * @access public
71
+ * @return boolean Returns true if it is successfully deleted, false
72
+ * if the delete request failed.
73
+ */
74
+ public function delete() {
75
+ $this->adapter->request('DELETE', $this->url, array(), array('return' => 'status'));
76
+ return true;
77
+ }
78
+
79
+ /**
80
+ * move
81
+ *
82
+ * Invoke the API method to MOVE an entry resource to a different List.
83
+ *
84
+ * Note: Not all entry resources are eligible to be moved, please
85
+ * refer to the AWeber API Reference Documentation at
86
+ * https://labs.aweber.com/docs/reference/1.0 for more
87
+ * details on which entry resources may be moved and if there
88
+ * are any requirements for moving that resource.
89
+ *
90
+ * @access public
91
+ * @param AWeberEntry(List) List to move Resource (this) too.
92
+ * @return mixed AWeberEntry(Resource) Resource created on List ($list)
93
+ * or False if resource was not created.
94
+ */
95
+ public function move($list, $last_followup_message_number_sent=NULL) {
96
+ # Move Resource
97
+ $params = array(
98
+ 'ws.op' => 'move',
99
+ 'list_link' => $list->self_link
100
+ );
101
+ if (isset($last_followup_message_number_sent)) {
102
+ $params['last_followup_message_number_sent'] = $last_followup_message_number_sent;
103
+ }
104
+
105
+ $data = $this->adapter->request('POST', $this->url, $params, array('return' => 'headers'));
106
+
107
+ # Return new Resource
108
+ $url = $data['Location'];
109
+ $resource_data = $this->adapter->request('GET', $url);
110
+ return new AWeberEntry($resource_data, $url, $this->adapter);
111
+ }
112
+
113
+ /**
114
+ * save
115
+ *
116
+ * Saves the current state of this object if it has been changed.
117
+ * @access public
118
+ * @return void
119
+ */
120
+ public function save() {
121
+ if (!empty($this->_localDiff)) {
122
+ $data = $this->adapter->request('PATCH', $this->url, $this->_localDiff, array('return' => 'status'));
123
+ }
124
+ $this->_localDiff = array();
125
+ return true;
126
+
127
+ }
128
+
129
+ /**
130
+ * __get
131
+ *
132
+ * Used to look up items in data, and special properties like type and
133
+ * child collections dynamically.
134
+ *
135
+ * @param String $value Attribute being accessed
136
+ * @access public
137
+ * @throws AWeberResourceNotImplemented
138
+ * @return mixed
139
+ */
140
+ public function __get($value) {
141
+ if (in_array($value, $this->_privateData)) {
142
+ return null;
143
+ }
144
+ if (!empty($this->data) && array_key_exists($value, $this->data)) {
145
+ if (is_array($this->data[$value])) {
146
+ $array = new AWeberEntryDataArray($this->data[$value], $value, $this);
147
+ $this->data[$value] = $array;
148
+ }
149
+ return $this->data[$value];
150
+ }
151
+ if ($value == 'type') return $this->_type();
152
+ if ($this->_isChildCollection($value)) {
153
+ return $this->_getCollection($value);
154
+ }
155
+ throw new AWeberResourceNotImplemented($this, $value);
156
+ }
157
+
158
+ /**
159
+ * __set
160
+ *
161
+ * If the key provided is part of the data array, then update it in the
162
+ * data array. Otherwise, use the default __set() behavior.
163
+ *
164
+ * @param mixed $key Key of the attr being set
165
+ * @param mixed $value Value being set to the $key attr
166
+ * @access public
167
+ */
168
+ public function __set($key, $value) {
169
+ if (array_key_exists($key, $this->data)) {
170
+ $this->_localDiff[$key] = $value;
171
+ return $this->data[$key] = $value;
172
+ } else {
173
+ return parent::__set($key, $value);
174
+ }
175
+ }
176
+
177
+ /**
178
+ * findSubscribers
179
+ *
180
+ * Looks through all lists for subscribers
181
+ * that match the given filter
182
+ * @access public
183
+ * @return AWeberCollection
184
+ */
185
+ public function findSubscribers($search_data) {
186
+ $this->_methodFor(array('account'));
187
+ $params = array_merge($search_data, array('ws.op' => 'findSubscribers'));
188
+ $data = $this->adapter->request('GET', $this->url, $params);
189
+
190
+ $ts_params = array_merge($params, array('ws.show' => 'total_size'));
191
+ $total_size = $this->adapter->request('GET', $this->url, $ts_params, array('return' => 'integer'));
192
+
193
+ # return collection
194
+ $data['total_size'] = $total_size;
195
+ $url = $this->url . '?'. http_build_query($params);
196
+ return new AWeberCollection($data, $url, $this->adapter);
197
+ }
198
+
199
+ /**
200
+ * getActivity
201
+ *
202
+ * Returns analytics activity for a given subscriber
203
+ * @access public
204
+ * @return AWeberCollection
205
+ */
206
+ public function getActivity() {
207
+ $this->_methodFor(array('subscriber'));
208
+ $params = array('ws.op' => 'getActivity');
209
+ $data = $this->adapter->request('GET', $this->url, $params);
210
+
211
+ $ts_params = array_merge($params, array('ws.show' => 'total_size'));
212
+ $total_size = $this->adapter->request('GET', $this->url, $ts_params, array('return' => 'integer'));
213
+
214
+ # return collection
215
+ $data['total_size'] = $total_size;
216
+ $url = $this->url . '?'. http_build_query($params);
217
+ return new AWeberCollection($data, $url, $this->adapter);
218
+ }
219
+
220
+ /** getParentEntry
221
+ *
222
+ * Gets an entry's parent entry
223
+ * Returns NULL if no parent entry
224
+ */
225
+ public function getParentEntry(){
226
+ $url_parts = explode('/', $this->url);
227
+ $size = count($url_parts);
228
+
229
+ #Remove entry id and slash from end of url
230
+ $url = substr($this->url, 0, -strlen($url_parts[$size-1])-1);
231
+
232
+ #Remove collection name and slash from end of url
233
+ $url = substr($url, 0, -strlen($url_parts[$size-2])-1);
234
+
235
+ try {
236
+ $data = $this->adapter->request('GET', $url);
237
+ return new AWeberEntry($data, $url, $this->adapter);
238
+ } catch (Exception $e) {
239
+ return NULL;
240
+ }
241
+ }
242
+
243
+ /**
244
+ * getWebForms
245
+ *
246
+ * Gets all web_forms for this account
247
+ * @access public
248
+ * @return array
249
+ */
250
+ public function getWebForms() {
251
+ $this->_methodFor(array('account'));
252
+ $data = $this->adapter->request('GET', $this->url.'?ws.op=getWebForms', array(),
253
+ array('allow_empty' => true));
254
+ return $this->_parseNamedOperation($data);
255
+ }
256
+
257
+
258
+ /**
259
+ * getWebFormSplitTests
260
+ *
261
+ * Gets all web_form split tests for this account
262
+ * @access public
263
+ * @return array
264
+ */
265
+ public function getWebFormSplitTests() {
266
+ $this->_methodFor(array('account'));
267
+ $data = $this->adapter->request('GET', $this->url.'?ws.op=getWebFormSplitTests', array(),
268
+ array('allow_empty' => true));
269
+ return $this->_parseNamedOperation($data);
270
+ }
271
+
272
+ /**
273
+ * _parseNamedOperation
274
+ *
275
+ * Turns a dumb array of json into an array of Entries. This is NOT
276
+ * a collection, but simply an array of entries, as returned from a
277
+ * named operation.
278
+ *
279
+ * @param array $data
280
+ * @access protected
281
+ * @return array
282
+ */
283
+ protected function _parseNamedOperation($data) {
284
+ $results = array();
285
+ foreach($data as $entryData) {
286
+ $results[] = new AWeberEntry($entryData, str_replace($this->adapter->app->getBaseUri(), '',
287
+ $entryData['self_link']), $this->adapter);
288
+ }
289
+ return $results;
290
+ }
291
+
292
+ /**
293
+ * _methodFor
294
+ *
295
+ * Raises exception if $this->type is not in array entryTypes.
296
+ * Used to restrict methods to specific entry type(s).
297
+ * @param mixed $entryTypes Array of entry types as strings, ie array('account')
298
+ * @access protected
299
+ * @return void
300
+ */
301
+ protected function _methodFor($entryTypes) {
302
+ if (in_array($this->type, $entryTypes)) return true;
303
+ throw new AWeberMethodNotImplemented($this);
304
+ }
305
+
306
+ /**
307
+ * _getCollection
308
+ *
309
+ * Returns the AWeberCollection object representing the given
310
+ * collection name, relative to this entry.
311
+ *
312
+ * @param String $value The name of the sub-collection
313
+ * @access protected
314
+ * @return AWeberCollection
315
+ */
316
+ protected function _getCollection($value) {
317
+ if (empty($this->_collections[$value])) {
318
+ $url = "{$this->url}/{$value}";
319
+ $data = $this->adapter->request('GET', $url);
320
+ $this->_collections[$value] = new AWeberCollection($data, $url, $this->adapter);
321
+ }
322
+ return $this->_collections[$value];
323
+ }
324
+
325
+
326
+ /**
327
+ * _isChildCollection
328
+ *
329
+ * Is the given name of a collection a child collection of this entry?
330
+ *
331
+ * @param String $value The name of the collection we are looking for
332
+ * @access protected
333
+ * @return boolean
334
+ * @throws AWeberResourceNotImplemented
335
+ */
336
+ protected function _isChildCollection($value) {
337
+ $this->_type();
338
+ if (!empty(AWeberAPI::$_collectionMap[$this->type]) &&
339
+ in_array($value, AWeberAPI::$_collectionMap[$this->type])) return true;
340
+ return false;
341
+ }
342
+
343
+ }
includes/vendor/aweber/aweber_entry_data_array.php ADDED
@@ -0,0 +1,68 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class AWeberEntryDataArray implements ArrayAccess, Countable, Iterator {
4
+ private $counter = 0;
5
+
6
+ protected $data;
7
+ protected $keys;
8
+ protected $name;
9
+ protected $parent;
10
+
11
+ public function __construct($data, $name, $parent) {
12
+ $this->data = $data;
13
+ $this->keys = array_keys($data);
14
+ $this->name = $name;
15
+ $this->parent = $parent;
16
+ }
17
+
18
+ public function count() {
19
+ return sizeOf($this->data);
20
+ }
21
+
22
+ public function offsetExists($offset) {
23
+ return (isset($this->data[$offset]));
24
+ }
25
+
26
+ public function offsetGet($offset) {
27
+ return $this->data[$offset];
28
+ }
29
+
30
+ public function offsetSet($offset, $value) {
31
+ $this->data[$offset] = $value;
32
+ $this->parent->{$this->name} = $this->data;
33
+ return $value;
34
+ }
35
+
36
+ public function offsetUnset($offset) {
37
+ unset($this->data[$offset]);
38
+ }
39
+
40
+ public function rewind() {
41
+ $this->counter = 0;
42
+ }
43
+
44
+ public function current() {
45
+ return $this->data[$this->key()];
46
+ }
47
+
48
+ public function key() {
49
+ return $this->keys[$this->counter];
50
+ }
51
+
52
+ public function next() {
53
+ $this->counter++;
54
+ }
55
+
56
+ public function valid() {
57
+ if ($this->counter >= sizeOf($this->data)) {
58
+ return false;
59
+ }
60
+ return true;
61
+ }
62
+
63
+
64
+ }
65
+
66
+
67
+
68
+ ?>
includes/vendor/aweber/aweber_response.php ADDED
@@ -0,0 +1,73 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * AWeberResponse
5
+ *
6
+ * Base class for objects that represent a response from the AWeberAPI.
7
+ * Responses will exist as one of the two AWeberResponse subclasses:
8
+ * - AWeberEntry - a single instance of an AWeber resource
9
+ * - AWeberCollection - a collection of AWeber resources
10
+ * @uses AWeberAPIBase
11
+ * @package
12
+ * @version $id$
13
+ */
14
+ class AWeberResponse extends AWeberAPIBase {
15
+
16
+ public $adapter = false;
17
+ public $data = array();
18
+ public $_dynamicData = array();
19
+
20
+ /**
21
+ * __construct
22
+ *
23
+ * Creates a new AWeberRespones
24
+ *
25
+ * @param mixed $response Data returned by the API servers
26
+ * @param mixed $url URL we hit to get the data
27
+ * @param mixed $adapter OAuth adapter used for future interactions
28
+ * @access public
29
+ * @return void
30
+ */
31
+ public function __construct($response, $url, $adapter) {
32
+ $this->adapter = $adapter;
33
+ $this->url = $url;
34
+ $this->data = $response;
35
+ }
36
+
37
+ /**
38
+ * __set
39
+ *
40
+ * Manual re-implementation of __set, allows sub classes to access
41
+ * the default behavior by using the parent:: format.
42
+ *
43
+ * @param mixed $key Key of the attr being set
44
+ * @param mixed $value Value being set to the attr
45
+ * @access public
46
+ */
47
+ public function __set($key, $value) {
48
+ $this->{$key} = $value;
49
+ }
50
+
51
+ /**
52
+ * __get
53
+ *
54
+ * PHP "MagicMethod" to allow for dynamic objects. Defers first to the
55
+ * data in $this->data.
56
+ *
57
+ * @param String $value Name of the attribute requested
58
+ * @access public
59
+ * @return mixed
60
+ */
61
+ public function __get($value) {
62
+ if (in_array($value, $this->_privateData)) {
63
+ return null;
64
+ }
65
+ if (array_key_exists($value, $this->data)) {
66
+ return $this->data[$value];
67
+ }
68
+ if ($value == 'type') return $this->_type();
69
+ }
70
+
71
+ }
72
+
73
+
includes/vendor/aweber/curl_object.php ADDED
@@ -0,0 +1,103 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * CurlInterface
5
+ *
6
+ * An object-oriented shim that wraps the standard PHP cURL library.
7
+ *
8
+ * This interface has been created so that cURL functionality can be stubbed
9
+ * out for unit testing, or swapped for an alternative library.
10
+ *
11
+ * @see curl
12
+ * @package
13
+ * @version $id$
14
+ */
15
+ interface CurlInterface {
16
+
17
+ /**
18
+ * errNo
19
+ *
20
+ * Encapsulates curl_errno - Returns the last error number
21
+ * @param resource $ch - A cURL handle returned by init.
22
+ * @access public
23
+ * @return the error number or 0 if no error occured.
24
+ */
25
+ public function errno($ch);
26
+
27
+ /**
28
+ * error
29
+ *
30
+ * Encapsulates curl_error - Return last error string
31
+ * @param resource $ch - A cURL handle returned by init.
32
+ * @access public
33
+ * @return the error messge or '' if no error occured.
34
+ */
35
+ public function error($ch);
36
+
37
+ /**
38
+ * execute
39
+ *
40
+ * Encapsulates curl_exec - Perform a cURL session.
41
+ * @param resource $ch - A cURL handle returned by init.
42
+ * @access public
43
+ * @return TRUE on success, FALSE on failure.
44
+ */
45
+ public function execute($ch);
46
+
47
+ /**
48
+ * init
49
+ *
50
+ * Encapsulates curl_init - Initialize a cURL session.
51
+ * @param string $url - url to use.
52
+ * @access public
53
+ * @return cURL handle on success, FALSE on failure.
54
+ */
55
+ public function init($url);
56
+
57
+ /**
58
+ * setopt
59
+ *
60
+ * Encapsulates curl_setopt - Set an option for cURL transfer.
61
+ * @param resource $ch - A cURL handle returned by init.
62
+ * @param int $opt - The CURLOPT to set.
63
+ * @param mixed $value - The value to set.
64
+ * @access public
65
+ * @return True on success, FALSE on failure.
66
+ */
67
+ public function setopt ($ch , $option , $value);
68
+ }
69
+
70
+
71
+ /**
72
+ * CurlObject
73
+ *
74
+ * A concrete implementation of CurlInterface using the PHP cURL library.
75
+ *
76
+ * @package
77
+ * @version $id$
78
+ */
79
+ class CurlObject implements CurlInterface {
80
+
81
+ public function errno($ch) {
82
+ return curl_errno($ch);
83
+ }
84
+
85
+ public function error($ch) {
86
+ return curl_error($ch);
87
+ }
88
+
89
+ public function execute($ch) {
90
+ return curl_exec($ch);
91
+ }
92
+
93
+ public function init($url) {
94
+ return curl_init($url);
95
+ }
96
+
97
+ public function setopt ($ch , $option , $value) {
98
+ return curl_setopt($ch, $option, $value);
99
+ }
100
+
101
+ }
102
+
103
+ ?>
includes/vendor/aweber/curl_response.php ADDED
@@ -0,0 +1,51 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ # CurlResponse
4
+ #
5
+ # Author Sean Huber - shuber@huberry.com
6
+ # Date May 2008
7
+ #
8
+ # A basic CURL wrapper for PHP
9
+ #
10
+ # See the README for documentation/examples or http://php.net/curl for more information
11
+ # about the libcurl extension for PHP -- http://github.com/shuber/curl/tree/master
12
+ #
13
+
14
+ class CurlResponse
15
+ {
16
+ public $body = '';
17
+ public $headers = array();
18
+
19
+ public function __construct($response)
20
+ {
21
+ # Extract headers from response
22
+ $pattern = '#HTTP/\d\.\d.*?$.*?\r\n\r\n#ims';
23
+ preg_match_all($pattern, $response, $matches);
24
+ $headers = explode("\r\n", str_replace("\r\n\r\n", '', array_pop($matches[0])));
25
+
26
+ # Extract the version and status from the first header
27
+ $version_and_status = array_shift($headers);
28
+ preg_match('#HTTP/(\d\.\d)\s(\d\d\d)\s(.*)#', $version_and_status, $matches);
29
+ $this->headers['Http-Version'] = $matches[1];
30
+ $this->headers['Status-Code'] = $matches[2];
31
+ $this->headers['Status'] = $matches[2].' '.$matches[3];
32
+
33
+ # Convert headers into an associative array
34
+ foreach ($headers as $header) {
35
+ preg_match('#(.*?)\:\s(.*)#', $header, $matches);
36
+ $this->headers[$matches[1]] = $matches[2];
37
+ }
38
+
39
+ # Remove the headers from the response body
40
+ $this->body = preg_replace($pattern, '', $response);
41
+ }
42
+
43
+ public function __toString()
44
+ {
45
+ return $this->body;
46
+ }
47
+
48
+ public function headers(){
49
+ return $this->headers;
50
+ }
51
+ }
includes/vendor/aweber/exceptions.php ADDED
@@ -0,0 +1,130 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class AWeberException extends Exception { }
4
+
5
+ /**
6
+ * Thrown when the API returns an error. (HTTP status >= 400)
7
+ *
8
+ *
9
+ * @uses AWeberException
10
+ * @package
11
+ * @version $id$
12
+ */
13
+ class AWeberAPIException extends AWeberException {
14
+
15
+ public $type;
16
+ public $status;
17
+ public $message;
18
+ public $documentation_url;
19
+ public $url;
20
+
21
+ public function __construct($error, $url) {
22
+ // record specific details of the API exception for processing
23
+ $this->url = $url;
24
+ $this->type = $error['type'];
25
+ $this->status = array_key_exists('status', $error) ? $error['status'] : '';
26
+ $this->message = $error['message'];
27
+ $this->documentation_url = $error['documentation_url'];
28
+
29
+ parent::__construct($this->message);
30
+ }
31
+ }
32
+
33
+ /**
34
+ * Thrown when attempting to use a resource that is not implemented.
35
+ *
36
+ * @uses AWeberException
37
+ * @package
38
+ * @version $id$
39
+ */
40
+ class AWeberResourceNotImplemented extends AWeberException {
41
+
42
+ public function __construct($object, $value) {
43
+ $this->object = $object;
44
+ $this->value = $value;
45
+ parent::__construct("Resource \"{$value}\" is not implemented on this resource.");
46
+ }
47
+ }
48
+
49
+ /**
50
+ * AWeberMethodNotImplemented
51
+ *
52
+ * Thrown when attempting to call a method that is not implemented for a resource
53
+ * / collection. Differs from standard method not defined errors, as this will
54
+ * be thrown when the method is infact implemented on the base class, but the
55
+ * current resource type does not provide access to that method (ie calling
56
+ * getByMessageNumber on a web_forms collection).
57
+ *
58
+ * @uses AWeberException
59
+ * @package
60
+ * @version $id$
61
+ */
62
+ class AWeberMethodNotImplemented extends AWeberException {
63
+
64
+ public function __construct($object) {
65
+ $this->object = $object;
66
+ parent::__construct("This method is not implemented by the current resource.");
67
+
68
+ }
69
+ }
70
+
71
+ /**
72
+ * AWeberOAuthException
73
+ *
74
+ * OAuth exception, as generated by an API JSON error response
75
+ * @uses AWeberException
76
+ * @package
77
+ * @version $id$
78
+ */
79
+ class AWeberOAuthException extends AWeberException {
80
+
81
+ public function __construct($type, $message) {
82
+ $this->type = $type;
83
+ $this->message = $message;
84
+ parent::__construct("{$type}: {$message}");
85
+ }
86
+ }
87
+
88
+ /**
89
+ * AWeberOAuthDataMissing
90
+ *
91
+ * Used when a specific piece or pieces of data was not found in the
92
+ * response. This differs from the exception that might be thrown as
93
+ * an AWeberOAuthException when parameters are not provided because
94
+ * it is not the servers' expectations that were not met, but rather
95
+ * the expecations of the client were not met by the server.
96
+ *
97
+ * @uses AWeberException
98
+ * @package
99
+ * @version $id$
100
+ */
101
+ class AWeberOAuthDataMissing extends AWeberException {
102
+
103
+ public function __construct($missing) {
104
+ if (!is_array($missing)) $missing = array($missing);
105
+ $this->missing = $missing;
106
+ $required = join(', ', $this->missing);
107
+ parent::__construct("OAuthDataMissing: Response was expected to contain: {$required}");
108
+
109
+ }
110
+ }
111
+
112
+ /**
113
+ * AWeberResponseError
114
+ *
115
+ * This is raised when the server returns a non-JSON response. This
116
+ * should only occur when there is a server or some type of connectivity
117
+ * issue.
118
+ *
119
+ * @uses AWeberException
120
+ * @package
121
+ * @version $id$
122
+ */
123
+ class AWeberResponseError extends AWeberException {
124
+
125
+ public function __construct($uri) {
126
+ $this->uri = $uri;
127
+ parent::__construct("Request for {$uri} did not respond properly.");
128
+ }
129
+
130
+ }
includes/vendor/aweber/oauth_adapter.php ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ interface AWeberOAuthAdapter {
4
+
5
+ public function request($method, $uri, $data = array());
6
+ public function getRequestToken($callbackUrl=false);
7
+
8
+ }
9
+
10
+
11
+ ?>
includes/vendor/aweber/oauth_application.php ADDED
@@ -0,0 +1,682 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ if (!class_exists('CurlObject')) require_once('curl_object.php');
3
+ if (!class_exists('CurlResponse')) require_once('curl_response.php');
4
+
5
+ /**
6
+ * OAuthServiceProvider
7
+ *
8
+ * Represents the service provider in the OAuth authentication model.
9
+ * The class that implements the service provider will contain the
10
+ * specific knowledge about the API we are interfacing with, and
11
+ * provide useful methods for interfacing with its API.
12
+ *
13
+ * For example, an OAuthServiceProvider would know the URLs necessary
14
+ * to perform specific actions, the type of data that the API calls
15
+ * would return, and would be responsible for manipulating the results
16
+ * into a useful manner.
17
+ *
18
+ * It should be noted that the methods enforced by the OAuthServiceProvider
19
+ * interface are made so that it can interact with our OAuthApplication
20
+ * cleanly, rather than from a general use perspective, though some
21
+ * methods for those purposes do exists (such as getUserData).
22
+ *
23
+ * @package
24
+ * @version $id$
25
+ */
26
+ interface OAuthServiceProvider {
27
+
28
+ public function getAccessTokenUrl();
29
+ public function getAuthorizeUrl();
30
+ public function getRequestTokenUrl();
31
+ public function getAuthTokenFromUrl();
32
+ public function getBaseUri();
33
+ public function getUserData();
34
+
35
+ }
36
+
37
+ /**
38
+ * OAuthApplication
39
+ *
40
+ * Base class to represent an OAuthConsumer application. This class is
41
+ * intended to be extended and modified for each ServiceProvider. Each
42
+ * OAuthServiceProvider should have a complementary OAuthApplication
43
+ *
44
+ * The OAuthApplication class should contain any details on preparing
45
+ * requires that is unique or specific to that specific service provider's
46
+ * implementation of the OAuth model.
47
+ *
48
+ * This base class is based on OAuth 1.0, designed with AWeber's implementation
49
+ * as a model. An OAuthApplication built to work with a different service
50
+ * provider (especially an OAuth2.0 Application) may alter or bypass portions
51
+ * of the logic in this class to meet the needs of the service provider it
52
+ * is designed to interface with.
53
+ *
54
+ * @package
55
+ * @version $id$
56
+ */
57
+ class OAuthApplication implements AWeberOAuthAdapter {
58
+ public $debug = false;
59
+
60
+ public $userAgent = 'AWeber OAuth Consumer Application 1.0 - https://labs.aweber.com/';
61
+
62
+ public $format = false;
63
+
64
+ public $requiresTokenSecret = true;
65
+
66
+ public $signatureMethod = 'HMAC-SHA1';
67
+ public $version = '1.0';
68
+
69
+ public $curl = false;
70
+
71
+ /**
72
+ * @var OAuthUser User currently interacting with the service provider
73
+ */
74
+ public $user = false;
75
+
76
+ // Data binding this OAuthApplication to the consumer application it is acting
77
+ // as a proxy for
78
+ public $consumerKey = false;
79
+ public $consumerSecret = false;
80
+
81
+ /**
82
+ * __construct
83
+ *
84
+ * Create a new OAuthApplication, based on an OAuthServiceProvider
85
+ * @access public
86
+ * @return void
87
+ */
88
+ public function __construct($parentApp = false) {
89
+ if ($parentApp) {
90
+ if (!is_a($parentApp, 'OAuthServiceProvider')) {
91
+ throw new Exception('Parent App must be a valid OAuthServiceProvider!');
92
+ }
93
+ $this->app = $parentApp;
94
+ }
95
+ $this->user = new OAuthUser();
96
+ $this->curl = new CurlObject();
97
+ }
98
+
99
+ /**
100
+ * request
101
+ *
102
+ * Implemented for a standard OAuth adapter interface
103
+ * @param mixed $method
104
+ * @param mixed $uri
105
+ * @param array $data
106
+ * @param array $options
107
+ * @access public
108
+ * @return void
109
+ */
110
+ public function request($method, $uri, $data = array(), $options = array()) {
111
+ $uri = $this->app->removeBaseUri($uri);
112
+ $url = $this->app->getBaseUri() . $uri;
113
+
114
+ # WARNING: non-primative items in data must be json serialized in GET and POST.
115
+ if ($method == 'POST' or $method == 'GET') {
116
+ foreach ($data as $key => $value) {
117
+ if (is_array($value)) {
118
+ $data[$key] = json_encode($value);
119
+ }
120
+ }
121
+ }
122
+
123
+ $response = $this->makeRequest($method, $url, $data);
124
+ if (!empty($options['return'])) {
125
+ if ($options['return'] == 'status') {
126
+ return $response->headers['Status-Code'];
127
+ }
128
+ if ($options['return'] == 'headers') {
129
+ return $response->headers;
130
+ }
131
+ if ($options['return'] == 'integer') {
132
+ return intval($response->body);
133
+ }
134
+ }
135
+
136
+ $data = json_decode($response->body, true);
137
+
138
+ if (empty($options['allow_empty']) && !isset($data)) {
139
+ throw new AWeberResponseError($uri);
140
+ }
141
+ return $data;
142
+ }
143
+
144
+ /**
145
+ * getRequestToken
146
+ *
147
+ * Gets a new request token / secret for this user.
148
+ * @access public
149
+ * @return void
150
+ */
151
+ public function getRequestToken($callbackUrl=false) {
152
+ $data = ($callbackUrl)? array('oauth_callback' => $callbackUrl) : array();
153
+ $resp = $this->makeRequest('POST', $this->app->getRequestTokenUrl(), $data);
154
+ $data = $this->parseResponse($resp);
155
+ $this->requiredFromResponse($data, array('oauth_token', 'oauth_token_secret'));
156
+ $this->user->requestToken = $data['oauth_token'];
157
+ $this->user->tokenSecret = $data['oauth_token_secret'];
158
+ return $data['oauth_token'];
159
+ }
160
+
161
+ /**
162
+ * getAccessToken
163
+ *
164
+ * Makes a request for access tokens. Requires that the current user has an authorized
165
+ * token and token secret.
166
+ *
167
+ * @access public
168
+ * @return void
169
+ */
170
+ public function getAccessToken() {
171
+ $resp = $this->makeRequest('POST', $this->app->getAccessTokenUrl(),
172
+ array('oauth_verifier' => $this->user->verifier)
173
+ );
174
+ $data = $this->parseResponse($resp);
175
+ $this->requiredFromResponse($data, array('oauth_token', 'oauth_token_secret'));
176
+
177
+ if (empty($data['oauth_token'])) {
178
+ throw new AWeberOAuthDataMissing('oauth_token');
179
+ }
180
+
181
+ $this->user->accessToken = $data['oauth_token'];
182
+ $this->user->tokenSecret = $data['oauth_token_secret'];
183
+ return array($data['oauth_token'], $data['oauth_token_secret']);
184
+ }
185
+
186
+ /**
187
+ * parseAsError
188
+ *
189
+ * Checks if response is an error. If it is, raise an appropriately
190
+ * configured exception.
191
+ *
192
+ * @param mixed $response Data returned from the server, in array form
193
+ * @access public
194
+ * @throws AWeberOAuthException
195
+ * @return void
196
+ */
197
+ public function parseAsError($response) {
198
+ if (!empty($response['error'])) {
199
+ throw new AWeberOAuthException($response['error']['type'],
200
+ $response['error']['message']);
201
+ }
202
+ }
203
+
204
+ /**
205
+ * requiredFromResponse
206
+ *
207
+ * Enforce that all the fields in requiredFields are present and not
208
+ * empty in data. If a required field is empty, throw an exception.
209
+ *
210
+ * @param mixed $data Array of data
211
+ * @param mixed $requiredFields Array of required field names.
212
+ * @access protected
213
+ * @return void
214
+ */
215
+ protected function requiredFromResponse($data, $requiredFields) {
216
+ foreach ($requiredFields as $field) {
217
+ if (empty($data[$field])) {
218
+ throw new AWeberOAuthDataMissing($field);
219
+ }
220
+ }
221
+ }
222
+
223
+ /**
224
+ * get
225
+ *
226
+ * Make a get request. Used to exchange user tokens with serice provider.
227
+ * @param mixed $url URL to make a get request from.
228
+ * @param array $data Data for the request.
229
+ * @access protected
230
+ * @return void
231
+ */
232
+ protected function get($url, $data) {
233
+ $url = $this->_addParametersToUrl($url, $data);
234
+ $handle = $this->curl->init($url);
235
+ $resp = $this->_sendRequest($handle);
236
+ return $resp;
237
+ }
238
+
239
+ /**
240
+ * _addParametersToUrl
241
+ *
242
+ * Adds the parameters in associative array $data to the
243
+ * given URL
244
+ * @param String $url URL
245
+ * @param array $data Parameters to be added as a query string to
246
+ * the URL provided
247
+ * @access protected
248
+ * @return void
249
+ */
250
+ protected function _addParametersToUrl($url, $data) {
251
+ if (!empty($data)) {
252
+ if (strpos($url, '?') === false) {
253
+ $url .= '?'.$this->buildData($data);
254
+ } else {
255
+ $url .= '&'.$this->buildData($data);
256
+ }
257
+ }
258
+ return $url;
259
+ }
260
+
261
+ /**
262
+ * generateNonce
263
+ *
264
+ * Generates a 'nonce', which is a unique request id based on the
265
+ * timestamp. If no timestamp is provided, generate one.
266
+ * @param mixed $timestamp Either a timestamp (epoch seconds) or false,
267
+ * in which case it will generate a timestamp.
268
+ * @access public
269
+ * @return string Returns a unique nonce
270
+ */
271
+ public function generateNonce($timestamp = false) {
272
+ if (!$timestamp) $timestamp = $this->generateTimestamp();
273
+ return md5($timestamp.'-'.rand(10000,99999).'-'.uniqid());
274
+ }
275
+
276
+ /**
277
+ * generateTimestamp
278
+ *
279
+ * Generates a timestamp, in seconds
280
+ * @access public
281
+ * @return int Timestamp, in epoch seconds
282
+ */
283
+ public function generateTimestamp() {
284
+ return time();
285
+ }
286
+
287
+ /**
288
+ * createSignature
289
+ *
290
+ * Creates a signature on the signature base and the signature key
291
+ * @param mixed $sigBase Base string of data to sign
292
+ * @param mixed $sigKey Key to sign the data with
293
+ * @access public
294
+ * @return string The signature
295
+ */
296
+ public function createSignature($sigBase, $sigKey) {
297
+ switch ($this->signatureMethod) {
298
+ case 'HMAC-SHA1':
299
+ default:
300
+ return base64_encode(hash_hmac('sha1', $sigBase, $sigKey, true));
301
+ }
302
+ }
303
+
304
+ /**
305
+ * encode
306
+ *
307
+ * Short-cut for utf8_encode / rawurlencode
308
+ * @param mixed $data Data to encode
309
+ * @access protected
310
+ * @return void Encoded data
311
+ */
312
+ protected function encode($data) {
313
+ return rawurlencode($data);
314
+ }
315
+
316
+ /**
317
+ * createSignatureKey
318
+ *
319
+ * Creates a key that will be used to sign our signature. Signatures
320
+ * are signed with the consumerSecret for this consumer application and
321
+ * the token secret of the user that the application is acting on behalf
322
+ * of.
323
+ * @access public
324
+ * @return void
325
+ */
326
+ public function createSignatureKey() {
327
+ return $this->consumerSecret.'&'.$this->user->tokenSecret;
328
+ }
329
+
330
+ /**
331
+ * getOAuthRequestData
332
+ *
333
+ * Get all the pre-signature, OAuth specific parameters for a request.
334
+ * @access public
335
+ * @return void
336
+ */
337
+ public function getOAuthRequestData() {
338
+ $token = $this->user->getHighestPriorityToken();
339
+ $ts = $this->generateTimestamp();
340
+ $nonce = $this->generateNonce($ts);
341
+ return array(
342
+ 'oauth_token' => $token,
343
+ 'oauth_consumer_key' => $this->consumerKey,
344
+ 'oauth_version' => $this->version,
345
+ 'oauth_timestamp' => $ts,
346
+ 'oauth_signature_method' => $this->signatureMethod,
347
+ 'oauth_nonce' => $nonce);
348
+ }
349
+
350
+
351
+ /**
352
+ * mergeOAuthData
353
+ *
354
+ * @param mixed $requestData
355
+ * @access public
356
+ * @return void
357
+ */
358
+ public function mergeOAuthData($requestData) {
359
+ $oauthData = $this->getOAuthRequestData();
360
+ return array_merge($requestData, $oauthData);
361
+ }
362
+
363
+ /**
364
+ * createSignatureBase
365
+ *
366
+ * @param mixed $method String name of HTTP method, such as "GET"
367
+ * @param mixed $url URL where this request will go
368
+ * @param mixed $data Array of params for this request. This should
369
+ * include ALL oauth properties except for the signature.
370
+ * @access public
371
+ * @return void
372
+ */
373
+ public function createSignatureBase($method, $url, $data) {
374
+ $method = $this->encode(strtoupper($method));
375
+ $query = parse_url($url, PHP_URL_QUERY);
376
+ if ($query) {
377
+ $parts = explode('?', $url, 2);
378
+ $url = array_shift($parts);
379
+ $items = explode('&', $query);
380
+ foreach ($items as $item) {
381
+ list($key, $value) = explode('=', $item);
382
+ $data[rawurldecode($key)] = rawurldecode($value);
383
+ }
384
+ }
385
+ $url = $this->encode($url);
386
+ $data = $this->encode($this->collapseDataForSignature($data));
387
+
388
+ return $method.'&'.$url.'&'.$data;
389
+ }
390
+
391
+ /**
392
+ * collapseDataForSignature
393
+ *
394
+ * Turns an array of request data into a string, as used by the oauth
395
+ * signature
396
+ * @param mixed $data
397
+ * @access public
398
+ * @return void
399
+ */
400
+ public function collapseDataForSignature($data) {
401
+ ksort($data);
402
+ $collapse = '';
403
+ foreach ($data as $key => $val) {
404
+ if (!empty($collapse)) $collapse .= '&';
405
+ $collapse .= $key.'='.$this->encode($val);
406
+ }
407
+ return $collapse;
408
+ }
409
+
410
+ /**
411
+ * signRequest
412
+ *
413
+ * Signs the request.
414
+ *
415
+ * @param mixed $method HTTP method
416
+ * @param mixed $url URL for the request
417
+ * @param mixed $data The data to be signed
418
+ * @access public
419
+ * @return array The data, with the signature.
420
+ */
421
+ public function signRequest($method, $url, $data) {
422
+ $base = $this->createSignatureBase($method, $url, $data);
423
+ $key = $this->createSignatureKey();
424
+ $data['oauth_signature'] = $this->createSignature($base, $key);
425
+ ksort($data);
426
+ return $data;
427
+ }
428
+
429
+
430
+ /**
431
+ * makeRequest
432
+ *
433
+ * Public facing function to make a request
434
+ *
435
+ * @param mixed $method
436
+ * @param mixed $url - Reserved characters in query params MUST be escaped
437
+ * @param mixed $data - Reserved characters in values MUST NOT be escaped
438
+ * @access public
439
+ * @return void
440
+ */
441
+ public function makeRequest($method, $url, $data=array()) {
442
+
443
+ if ($this->debug) echo "\n** {$method}: $url\n";
444
+
445
+ switch (strtoupper($method)) {
446
+ case 'POST':
447
+ $oauth = $this->prepareRequest($method, $url, $data);
448
+ $resp = $this->post($url, $oauth);
449
+ break;
450
+
451
+ case 'GET':
452
+ $oauth = $this->prepareRequest($method, $url, $data);
453
+ $resp = $this->get($url, $oauth, $data);
454
+ break;
455
+
456
+ case 'DELETE':
457
+ $oauth = $this->prepareRequest($method, $url, $data);
458
+ $resp = $this->delete($url, $oauth);
459
+ break;
460
+
461
+ case 'PATCH':
462
+ $oauth = $this->prepareRequest($method, $url, array());
463
+ $resp = $this->patch($url, $oauth, $data);
464
+ break;
465
+ }
466
+
467
+ // enable debug output
468
+ if ($this->debug) {
469
+ echo "<pre>";
470
+ print_r($oauth);
471
+ echo " --> Status: {$resp->headers['Status-Code']}\n";
472
+ echo " --> Body: {$resp->body}";
473
+ echo "</pre>";
474
+ }
475
+
476
+ if (!$resp) {
477
+ $msg = 'Unable to connect to the AWeber API. (' . $this->error . ')';
478
+ $error = array('message' => $msg, 'type' => 'APIUnreachableError',
479
+ 'documentation_url' => 'https://labs.aweber.com/docs/troubleshooting');
480
+ throw new AWeberAPIException($error, $url);
481
+ }
482
+
483
+ if($resp->headers['Status-Code'] >= 400) {
484
+ $data = json_decode($resp->body, true);
485
+ throw new AWeberAPIException($data['error'], $url);
486
+ }
487
+
488
+ return $resp;
489
+ }
490
+
491
+ /**
492
+ * put
493
+ *
494
+ * Prepare an OAuth put method.
495
+ *
496
+ * @param mixed $url URL where we are making the request to
497
+ * @param mixed $data Data that is used to make the request
498
+ * @access protected
499
+ * @return void
500
+ */
501
+ protected function patch($url, $oauth, $data) {
502
+ $url = $this->_addParametersToUrl($url, $oauth);
503
+ $handle = $this->curl->init($url);
504
+ $this->curl->setopt($handle, CURLOPT_CUSTOMREQUEST, 'PATCH');
505
+ $this->curl->setopt($handle, CURLOPT_POSTFIELDS, json_encode($data));
506
+ $resp = $this->_sendRequest($handle, array('Expect:', 'Content-Type: application/json'));
507
+ return $resp;
508
+ }
509
+
510
+ /**
511
+ * post
512
+ *
513
+ * Prepare an OAuth post method.
514
+ *
515
+ * @param mixed $url URL where we are making the request to
516
+ * @param mixed $data Data that is used to make the request
517
+ * @access protected
518
+ * @return void
519
+ */
520
+ protected function post($url, $oauth) {
521
+ $handle = $this->curl->init($url);
522
+ $postData = $this->buildData($oauth);
523
+ $this->curl->setopt($handle, CURLOPT_POST, true);
524
+ $this->curl->setopt($handle, CURLOPT_POSTFIELDS, $postData);
525
+ $resp = $this->_sendRequest($handle);
526
+ return $resp;
527
+ }
528
+
529
+ /**
530
+ * delete
531
+ *
532
+ * Makes a DELETE request
533
+ * @param mixed $url URL where we are making the request to
534
+ * @param mixed $data Data that is used in the request
535
+ * @access protected
536
+ * @return void
537
+ */
538
+ protected function delete($url, $data) {
539
+ $url = $this->_addParametersToUrl($url, $data);
540
+ $handle = $this->curl->init($url);
541
+ $this->curl->setopt($handle, CURLOPT_CUSTOMREQUEST, 'DELETE');
542
+ $resp = $this->_sendRequest($handle);
543
+ return $resp;
544
+ }
545
+
546
+ /**
547
+ * buildData
548
+ *
549
+ * Creates a string of data for either post or get requests.
550
+ * @param mixed $data Array of key value pairs
551
+ * @access public
552
+ * @return void
553
+ */
554
+ public function buildData($data) {
555
+ ksort($data);
556
+ $params = array();
557
+ foreach ($data as $key => $value) {
558
+ $params[] = $key.'='.$this->encode($value);
559
+ }
560
+ return implode('&', $params);
561
+ }
562
+
563
+ /**
564
+ * _sendRequest
565
+ *
566
+ * Actually makes a request.
567
+ * @param mixed $handle Curl handle
568
+ * @param array $headers Additional headers needed for request
569
+ * @access private
570
+ * @return void
571
+ */
572
+ private function _sendRequest($handle, $headers = array('Expect:')) {
573
+ $this->curl->setopt($handle, CURLOPT_RETURNTRANSFER, true);
574
+ $this->curl->setopt($handle, CURLOPT_HEADER, true);
575
+ $this->curl->setopt($handle, CURLOPT_HTTPHEADER, $headers);
576
+ $this->curl->setopt($handle, CURLOPT_USERAGENT, $this->userAgent);
577
+ $this->curl->setopt($handle, CURLOPT_SSL_VERIFYPEER, FALSE);
578
+ $this->curl->setopt($handle, CURLOPT_VERBOSE, FALSE);
579
+ $this->curl->setopt($handle, CURLOPT_CONNECTTIMEOUT, 10);
580
+ $this->curl->setopt($handle, CURLOPT_TIMEOUT, 90);
581
+ $resp = $this->curl->execute($handle);
582
+ if ($resp) {
583
+ return new CurlResponse($resp);
584
+ }
585
+ $this->error = $this->curl->errno($handle) . ' - ' .
586
+ $this->curl->error($handle);
587
+ return false;
588
+ }
589
+
590
+ /**
591
+ * prepareRequest
592
+ *
593
+ * @param mixed $method HTTP method
594
+ * @param mixed $url URL for the request
595
+ * @param mixed $data The data to generate oauth data and be signed
596
+ * @access public
597
+ * @return void The data, with all its OAuth variables and signature
598
+ */
599
+ public function prepareRequest($method, $url, $data) {
600
+ $data = $this->mergeOAuthData($data);
601
+ $data = $this->signRequest($method, $url, $data);
602
+ return $data;
603
+ }
604
+
605
+ /**
606
+ * parseResponse
607
+ *
608
+ * Parses the body of the response into an array
609
+ * @param mixed $string The body of a response
610
+ * @access public
611
+ * @return void
612
+ */
613
+ public function parseResponse($resp) {
614
+ $data = array();
615
+
616
+ if (!$resp) { return $data; }
617
+ if (empty($resp)) { return $data; }
618
+ if (empty($resp->body)) { return $data; }
619
+
620
+ switch ($this->format) {
621
+ case 'json':
622
+ $data = json_decode($resp->body);
623
+ break;
624
+ default:
625
+ parse_str($resp->body, $data);
626
+ }
627
+ $this->parseAsError($data);
628
+ return $data;
629
+ }
630
+
631
+ }
632
+
633
+ /**
634
+ * OAuthUser
635
+ *
636
+ * Simple data class representing the user in an OAuth application.
637
+ * @package
638
+ * @version $id$
639
+ */
640
+ class OAuthUser {
641
+
642
+ public $authorizedToken = false;
643
+ public $requestToken = false;
644
+ public $verifier = false;
645
+ public $tokenSecret = false;
646
+ public $accessToken = false;
647
+
648
+ /**
649
+ * isAuthorized
650
+ *
651
+ * Checks if this user is authorized.
652
+ * @access public
653
+ * @return void
654
+ */
655
+ public function isAuthorized() {
656
+ if (empty($this->authorizedToken) && empty($this->accessToken)) {
657
+ return false;
658
+ }
659
+ return true;
660
+ }
661
+
662
+
663
+ /**
664
+ * getHighestPriorityToken
665
+ *
666
+ * Returns highest priority token - used to define authorization
667
+ * state for a given OAuthUser
668
+ * @access public
669
+ * @return void
670
+ */
671
+ public function getHighestPriorityToken() {
672
+ if (!empty($this->accessToken)) return $this->accessToken;
673
+ if (!empty($this->authorizedToken)) return $this->authorizedToken;
674
+ if (!empty($this->requestToken)) return $this->requestToken;
675
+
676
+ // Return no token, new user
677
+ return '';
678
+ }
679
+
680
+ }
681
+
682
+ ?>
includes/vendor/campaign-monitor/class/base_classes.php ADDED
@@ -0,0 +1,287 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ require_once dirname(__FILE__).'/serialisation.php';
4
+ require_once dirname(__FILE__).'/transport.php';
5
+ require_once dirname(__FILE__).'/log.php';
6
+
7
+ define('CS_REST_WRAPPER_VERSION', '4.0.2');
8
+ define('CS_HOST', 'api.createsend.com');
9
+ define('CS_OAUTH_BASE_URI', 'https://'.CS_HOST.'/oauth');
10
+ define('CS_OAUTH_TOKEN_URI', CS_OAUTH_BASE_URI.'/token');
11
+ define('CS_REST_WEBHOOK_FORMAT_JSON', 'json');
12
+ define('CS_REST_WEBHOOK_FORMAT_XML', 'xml');
13
+
14
+ /**
15
+ * A general result object returned from all Campaign Monitor API calls.
16
+ * @author tobyb
17
+ *
18
+ */
19
+ class CS_REST_Wrapper_Result {
20
+ /**
21
+ * The deserialised result of the API call
22
+ * @var mixed
23
+ */
24
+ var $response;
25
+
26
+ /**
27
+ * The http status code of the API call
28
+ * @var int
29
+ */
30
+ var $http_status_code;
31
+
32
+ function CS_REST_Wrapper_Result($response, $code) {
33
+ $this->response = $response;
34
+ $this->http_status_code = $code;
35
+ }
36
+
37
+ /**
38
+ * Can be used to check if a call to the api resulted in a successful response.
39
+ * @return boolean False if the call failed. Check the response property for the failure reason.
40
+ * @access public
41
+ */
42
+ function was_successful() {
43
+ return $this->http_status_code >= 200 && $this->http_status_code < 300;
44
+ }
45
+ }
46
+
47
+ /**
48
+ * Base class for the create send PHP wrapper.
49
+ * This class includes functions to access the general data,
50
+ * i.e timezones, clients and getting your API Key from username and password
51
+ * @author tobyb
52
+ *
53
+ */
54
+ class CS_REST_Wrapper_Base {
55
+ /**
56
+ * The protocol to use while accessing the api
57
+ * @var string http or https
58
+ * @access private
59
+ */
60
+ var $_protocol;
61
+
62
+ /**
63
+ * The base route of the create send api.
64
+ * @var string
65
+ * @access private
66
+ */
67
+ var $_base_route;
68
+
69
+ /**
70
+ * The serialiser to use for serialisation and deserialisation
71
+ * of API request and response data
72
+ * @var CS_REST_JsonSerialiser or CS_REST_XmlSerialiser
73
+ * @access private
74
+ */
75
+ var $_serialiser;
76
+
77
+ /**
78
+ * The transport to use to send API requests
79
+ * @var CS_REST_CurlTransport or CS_REST_SocketTransport or your own custom transport.
80
+ * @access private
81
+ */
82
+ var $_transport;
83
+
84
+ /**
85
+ * The logger to use for debugging of all API requests
86
+ * @var CS_REST_Log
87
+ * @access private
88
+ */
89
+ var $_log;
90
+
91
+ /**
92
+ * The default options to use for each API request.
93
+ * These can be overridden by passing in an array as the call_options argument
94
+ * to a single api request.
95
+ * Valid options are:
96
+ *
97
+ * deserialise boolean:
98
+ * Set this to false if you want to get the raw response.
99
+ * This can be useful if your passing json directly to javascript.
100
+ *
101
+ * While there are clearly other options there is no need to change them.
102
+ * @var array
103
+ * @access private
104
+ */
105
+ var $_default_call_options;
106
+
107
+ /**
108
+ * Constructor.
109
+ * @param $auth_details array Authentication details to use for API calls.
110
+ * This array must take one of the following forms:
111
+ * If using OAuth to authenticate:
112
+ * array(
113
+ * 'access_token' => 'your access token',
114
+ * 'refresh_token' => 'your refresh token')
115
+ *
116
+ * Or if using an API key:
117
+ * array('api_key' => 'your api key')
118
+ *
119
+ * Note that this method will continue to work in the deprecated
120
+ * case when $auth_details is passed in as a string containing an
121
+ * API key.
122
+ * @param $protocol string The protocol to use for requests (http|https)
123
+ * @param $debug_level int The level of debugging required CS_REST_LOG_NONE | CS_REST_LOG_ERROR | CS_REST_LOG_WARNING | CS_REST_LOG_VERBOSE
124
+ * @param $host string The host to send API requests to. There is no need to change this
125
+ * @param $log CS_REST_Log The logger to use. Used for dependency injection
126
+ * @param $serialiser The serialiser to use. Used for dependency injection
127
+ * @param $transport The transport to use. Used for dependency injection
128
+ * @access public
129
+ */
130
+ function CS_REST_Wrapper_Base(
131
+ $auth_details,
132
+ $protocol = 'https',
133
+ $debug_level = CS_REST_LOG_NONE,
134
+ $host = CS_HOST,
135
+ $log = NULL,
136
+ $serialiser = NULL,
137
+ $transport = NULL) {
138
+
139
+ if (is_string($auth_details)) {
140
+ # If $auth_details is a string, assume it is an API key
141
+ $auth_details = array('api_key' => $auth_details);
142
+ }
143
+
144
+ $this->_log = is_null($log) ? new CS_REST_Log($debug_level) : $log;
145
+
146
+ $this->_protocol = $protocol;
147
+ $this->_base_route = $protocol.'://'.$host.'/api/v3.1/';
148
+
149
+ $this->_log->log_message('Creating wrapper for '.$this->_base_route, get_class($this), CS_REST_LOG_VERBOSE);
150
+
151
+ $this->_transport = is_null($transport) ?
152
+ CS_REST_TRANSPORT_get_available($this->is_secure(), $this->_log) :
153
+ $transport;
154
+
155
+ $transport_type = method_exists($this->_transport, 'get_type') ? $this->_transport->get_type() : 'Unknown';
156
+ $this->_log->log_message('Using '.$transport_type.' for transport', get_class($this), CS_REST_LOG_WARNING);
157
+
158
+ $this->_serialiser = is_null($serialiser) ?
159
+ CS_REST_SERIALISATION_get_available($this->_log) : $serialiser;
160
+
161
+ $this->_log->log_message('Using '.$this->_serialiser->get_type().' json serialising', get_class($this), CS_REST_LOG_WARNING);
162
+
163
+ $this->_default_call_options = array (
164
+ 'authdetails' => $auth_details,
165
+ 'userAgent' => 'CS_REST_Wrapper v'.CS_REST_WRAPPER_VERSION.
166
+ ' PHPv'.phpversion().' over '.$transport_type.' with '.$this->_serialiser->get_type(),
167
+ 'contentType' => 'application/json; charset=utf-8',
168
+ 'deserialise' => true,
169
+ 'host' => $host,
170
+ 'protocol' => $protocol
171
+ );
172
+ }
173
+
174
+ /**
175
+ * Refresh the current OAuth token using the current refresh token.
176
+ * @access public
177
+ */
178
+ function refresh_token() {
179
+ if (!isset($this->_default_call_options['authdetails']) ||
180
+ !isset($this->_default_call_options['authdetails']['refresh_token'])) {
181
+ trigger_error(
182
+ 'Error refreshing token. There is no refresh token set on this object.',
183
+ E_USER_ERROR);
184
+ return array(NULL, NULL, NULL);
185
+ }
186
+ $body = "grant_type=refresh_token&refresh_token=".urlencode(
187
+ $this->_default_call_options['authdetails']['refresh_token']);
188
+ $options = array('contentType' => 'application/x-www-form-urlencoded');
189
+ $wrap = new CS_REST_Wrapper_Base(
190
+ NULL, 'https', CS_REST_LOG_NONE, CS_HOST, NULL,
191
+ new CS_REST_DoNothingSerialiser(), NULL);
192
+
193
+ $result = $wrap->post_request(CS_OAUTH_TOKEN_URI, $body, $options);
194
+ if ($result->was_successful()) {
195
+ $access_token = $result->response->access_token;
196
+ $expires_in = $result->response->expires_in;
197
+ $refresh_token = $result->response->refresh_token;
198
+ $this->_default_call_options['authdetails'] = array(
199
+ 'access_token' => $access_token,
200
+ 'refresh_token' => $refresh_token
201
+ );
202
+ return array($access_token, $expires_in, $refresh_token);
203
+ } else {
204
+ trigger_error(
205
+ 'Error refreshing token. '.$result->response->error.': '.$result->response->error_description,
206
+ E_USER_ERROR);
207
+ return array(NULL, NULL, NULL);
208
+ }
209
+ }
210
+
211
+ /**
212
+ * @return boolean True if the wrapper is using SSL.
213
+ * @access public
214
+ */
215
+ function is_secure() {
216
+ return $this->_protocol === 'https';
217
+ }
218
+
219
+ function put_request($route, $data, $call_options = array()) {
220
+ return $this->_call($call_options, CS_REST_PUT, $route, $data);
221
+ }
222
+
223
+ function post_request($route, $data, $call_options = array()) {
224
+ return $this->_call($call_options, CS_REST_POST, $route, $data);
225
+ }
226
+
227
+ function delete_request($route, $call_options = array()) {
228
+ return $this->_call($call_options, CS_REST_DELETE, $route);
229
+ }
230
+
231
+ function get_request($route, $call_options = array()) {
232
+ return $this->_call($call_options, CS_REST_GET, $route);
233
+ }
234
+
235
+ function get_request_paged($route, $page_number, $page_size, $order_field, $order_direction,
236
+ $join_char = '&') {
237
+ if(!is_null($page_number)) {
238
+ $route .= $join_char.'page='.$page_number;
239
+ $join_char = '&';
240
+ }
241
+
242
+ if(!is_null($page_size)) {
243
+ $route .= $join_char.'pageSize='.$page_size;
244
+ $join_char = '&';
245
+ }
246
+
247
+ if(!is_null($order_field)) {
248
+ $route .= $join_char.'orderField='.$order_field;
249
+ $join_char = '&';
250
+ }
251
+
252
+ if(!is_null($order_direction)) {
253
+ $route .= $join_char.'orderDirection='.$order_direction;
254
+ $join_char = '&';
255
+ }
256
+
257
+ return $this->get_request($route);
258
+ }
259
+
260
+ /**
261
+ * Internal method to make a general API request based on the provided options
262
+ * @param $call_options
263
+ * @access private
264
+ */
265
+ function _call($call_options, $method, $route, $data = NULL) {
266
+ $call_options['route'] = $route;
267
+ $call_options['method'] = $method;
268
+
269
+ if(!is_null($data)) {
270
+ $call_options['data'] = $this->_serialiser->serialise($data);
271
+ }
272
+
273
+ $call_options = array_merge($this->_default_call_options, $call_options);
274
+ $this->_log->log_message('Making '.$call_options['method'].' call to: '.$call_options['route'], get_class($this), CS_REST_LOG_WARNING);
275
+
276
+ $call_result = $this->_transport->make_call($call_options);
277
+
278
+ $this->_log->log_message('Call result: <pre>'.var_export($call_result, true).'</pre>',
279
+ get_class($this), CS_REST_LOG_VERBOSE);
280
+
281
+ if($call_options['deserialise']) {
282
+ $call_result['response'] = $this->_serialiser->deserialise($call_result['response']);
283
+ }
284
+
285
+ return new CS_REST_Wrapper_Result($call_result['response'], $call_result['code']);
286
+ }
287
+ }
includes/vendor/campaign-monitor/class/cacert.pem ADDED
@@ -0,0 +1,3849 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ##
2
+ ## ca-bundle.crt -- Bundle of CA Root Certificates
3
+ ##
4
+ ## Certificate data from Mozilla as of: Thu Jun 28 15:03:08 2012
5
+ ##
6
+ ## This is a bundle of X.509 certificates of public Certificate Authorities
7
+ ## (CA). These were automatically extracted from Mozilla's root certificates
8
+ ## file (certdata.txt). This file can be found in the mozilla source tree:
9
+ ## http://mxr.mozilla.org/mozilla/source/security/nss/lib/ckfw/builtins/certdata.txt?raw=1
10
+ ##
11
+ ## It contains the certificates in PEM format and therefore
12
+ ## can be directly used with curl / libcurl / php_curl, or with
13
+ ## an Apache+mod_ssl webserver for SSL client authentication.
14
+ ## Just configure this file as the SSLCACertificateFile.
15
+ ##
16
+
17
+ # @(#) $RCSfile: certdata.txt,v $ $Revision: 1.85 $ $Date: 2012/06/28 13:50:18 $
18
+
19
+ GTE CyberTrust Global Root
20
+ ==========================
21
+ -----BEGIN CERTIFICATE-----
22
+ MIICWjCCAcMCAgGlMA0GCSqGSIb3DQEBBAUAMHUxCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9HVEUg
23
+ Q29ycG9yYXRpb24xJzAlBgNVBAsTHkdURSBDeWJlclRydXN0IFNvbHV0aW9ucywgSW5jLjEjMCEG
24
+ A1UEAxMaR1RFIEN5YmVyVHJ1c3QgR2xvYmFsIFJvb3QwHhcNOTgwODEzMDAyOTAwWhcNMTgwODEz
25
+ MjM1OTAwWjB1MQswCQYDVQQGEwJVUzEYMBYGA1UEChMPR1RFIENvcnBvcmF0aW9uMScwJQYDVQQL
26
+ Ex5HVEUgQ3liZXJUcnVzdCBTb2x1dGlvbnMsIEluYy4xIzAhBgNVBAMTGkdURSBDeWJlclRydXN0
27
+ IEdsb2JhbCBSb290MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCVD6C28FCc6HrHiM3dFw4u
28
+ sJTQGz0O9pTAipTHBsiQl8i4ZBp6fmw8U+E3KHNgf7KXUwefU/ltWJTSr41tiGeA5u2ylc9yMcql
29
+ HHK6XALnZELn+aks1joNrI1CqiQBOeacPwGFVw1Yh0X404Wqk2kmhXBIgD8SFcd5tB8FLztimQID
30
+ AQABMA0GCSqGSIb3DQEBBAUAA4GBAG3rGwnpXtlR22ciYaQqPEh346B8pt5zohQDhT37qw4wxYMW
31
+ M4ETCJ57NE7fQMh017l93PR2VX2bY1QY6fDq81yx2YtCHrnAlU66+tXifPVoYb+O7AWXX1uw16OF
32
+ NMQkpw0PlZPvy5TYnh+dXIVtx6quTx8itc2VrbqnzPmrC3p/
33
+ -----END CERTIFICATE-----
34
+
35
+ Thawte Server CA
36
+ ================
37
+ -----BEGIN CERTIFICATE-----
38
+ MIIDEzCCAnygAwIBAgIBATANBgkqhkiG9w0BAQQFADCBxDELMAkGA1UEBhMCWkExFTATBgNVBAgT
39
+ DFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2FwZSBUb3duMR0wGwYDVQQKExRUaGF3dGUgQ29uc3Vs
40
+ dGluZyBjYzEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjEZMBcGA1UE
41
+ AxMQVGhhd3RlIFNlcnZlciBDQTEmMCQGCSqGSIb3DQEJARYXc2VydmVyLWNlcnRzQHRoYXd0ZS5j
42
+ b20wHhcNOTYwODAxMDAwMDAwWhcNMjAxMjMxMjM1OTU5WjCBxDELMAkGA1UEBhMCWkExFTATBgNV
43
+ BAgTDFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2FwZSBUb3duMR0wGwYDVQQKExRUaGF3dGUgQ29u
44
+ c3VsdGluZyBjYzEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjEZMBcG
45
+ A1UEAxMQVGhhd3RlIFNlcnZlciBDQTEmMCQGCSqGSIb3DQEJARYXc2VydmVyLWNlcnRzQHRoYXd0
46
+ ZS5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANOkUG7I/1Zr5s9dtuoMaHVHoqrC2oQl
47
+ /Kj0R1HahbUgdJSGHg91yekIYfUGbTBuFRkC6VLAYttNmZ7iagxEOM3+vuNkCXDF/rFrKbYvScg7
48
+ 1CcEJRCXL+eQbcAoQpnXTEPew/UhbVSfXcNY4cDk2VuwuNy0e982OsK1ZiIS1ocNAgMBAAGjEzAR
49
+ MA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEEBQADgYEAB/pMaVz7lcxG7oWDTSEwjsrZqG9J
50
+ GubaUeNgcGyEYRGhGshIPllDfU+VPaGLtwtimHp1it2ITk6eQNuozDJ0uW8NxuOzRAvZim+aKZuZ
51
+ GCg70eNAKJpaPNW15yAbi8qkq43pUdniTCxZqdq5snUb9kLy78fyGPmJvKP/iiMucEc=
52
+ -----END CERTIFICATE-----
53
+
54
+ Thawte Premium Server CA
55
+ ========================
56
+ -----BEGIN CERTIFICATE-----
57
+ MIIDJzCCApCgAwIBAgIBATANBgkqhkiG9w0BAQQFADCBzjELMAkGA1UEBhMCWkExFTATBgNVBAgT
58
+ DFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2FwZSBUb3duMR0wGwYDVQQKExRUaGF3dGUgQ29uc3Vs
59
+ dGluZyBjYzEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjEhMB8GA1UE
60
+ AxMYVGhhd3RlIFByZW1pdW0gU2VydmVyIENBMSgwJgYJKoZIhvcNAQkBFhlwcmVtaXVtLXNlcnZl
61
+ ckB0aGF3dGUuY29tMB4XDTk2MDgwMTAwMDAwMFoXDTIwMTIzMTIzNTk1OVowgc4xCzAJBgNVBAYT
62
+ AlpBMRUwEwYDVQQIEwxXZXN0ZXJuIENhcGUxEjAQBgNVBAcTCUNhcGUgVG93bjEdMBsGA1UEChMU
63
+ VGhhd3RlIENvbnN1bHRpbmcgY2MxKDAmBgNVBAsTH0NlcnRpZmljYXRpb24gU2VydmljZXMgRGl2
64
+ aXNpb24xITAfBgNVBAMTGFRoYXd0ZSBQcmVtaXVtIFNlcnZlciBDQTEoMCYGCSqGSIb3DQEJARYZ
65
+ cHJlbWl1bS1zZXJ2ZXJAdGhhd3RlLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA0jY2
66
+ aovXwlue2oFBYo847kkEVdbQ7xwblRZH7xhINTpS9CtqBo87L+pW46+GjZ4X9560ZXUCTe/LCaIh
67
+ Udib0GfQug2SBhRz1JPLlyoAnFxODLz6FVL88kRu2hFKbgifLy3j+ao6hnO2RlNYyIkFvYMRuHM/
68
+ qgeN9EJN50CdHDcCAwEAAaMTMBEwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQQFAAOBgQAm
69
+ SCwWwlj66BZ0DKqqX1Q/8tfJeGBeXm43YyJ3Nn6yF8Q0ufUIhfzJATj/Tb7yFkJD57taRvvBxhEf
70
+ 8UqwKEbJw8RCfbz6q1lu1bdRiBHjpIUZa4JMpAwSremkrj/xw0llmozFyD4lt5SZu5IycQfwhl7t
71
+ UCemDaYj+bvLpgcUQg==
72
+ -----END CERTIFICATE-----
73
+
74
+ Equifax Secure CA
75
+ =================
76
+ -----BEGIN CERTIFICATE-----
77
+ MIIDIDCCAomgAwIBAgIENd70zzANBgkqhkiG9w0BAQUFADBOMQswCQYDVQQGEwJVUzEQMA4GA1UE
78
+ ChMHRXF1aWZheDEtMCsGA1UECxMkRXF1aWZheCBTZWN1cmUgQ2VydGlmaWNhdGUgQXV0aG9yaXR5
79
+ MB4XDTk4MDgyMjE2NDE1MVoXDTE4MDgyMjE2NDE1MVowTjELMAkGA1UEBhMCVVMxEDAOBgNVBAoT
80
+ B0VxdWlmYXgxLTArBgNVBAsTJEVxdWlmYXggU2VjdXJlIENlcnRpZmljYXRlIEF1dGhvcml0eTCB
81
+ nzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAwV2xWGcIYu6gmi0fCG2RFGiYCh7+2gRvE4RiIcPR
82
+ fM6fBeC4AfBONOziipUEZKzxa1NfBbPLZ4C/QgKO/t0BCezhABRP/PvwDN1Dulsr4R+AcJkVV5MW
83
+ 8Q+XarfCaCMczE1ZMKxRHjuvK9buY0V7xdlfUNLjUA86iOe/FP3gx7kCAwEAAaOCAQkwggEFMHAG
84
+ A1UdHwRpMGcwZaBjoGGkXzBdMQswCQYDVQQGEwJVUzEQMA4GA1UEChMHRXF1aWZheDEtMCsGA1UE
85
+ CxMkRXF1aWZheCBTZWN1cmUgQ2VydGlmaWNhdGUgQXV0aG9yaXR5MQ0wCwYDVQQDEwRDUkwxMBoG
86
+ A1UdEAQTMBGBDzIwMTgwODIyMTY0MTUxWjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAUSOZo+SvS
87
+ spXXR9gjIBBPM5iQn9QwHQYDVR0OBBYEFEjmaPkr0rKV10fYIyAQTzOYkJ/UMAwGA1UdEwQFMAMB
88
+ Af8wGgYJKoZIhvZ9B0EABA0wCxsFVjMuMGMDAgbAMA0GCSqGSIb3DQEBBQUAA4GBAFjOKer89961
89
+ zgK5F7WF0bnj4JXMJTENAKaSbn+2kmOeUJXRmm/kEd5jhW6Y7qj/WsjTVbJmcVfewCHrPSqnI0kB
90
+ BIZCe/zuf6IWUrVnZ9NA2zsmWLIodz2uFHdh1voqZiegDfqnc1zqcPGUIWVEX/r87yloqaKHee95
91
+ 70+sB3c4
92
+ -----END CERTIFICATE-----
93
+
94
+ Digital Signature Trust Co. Global CA 1
95
+ =======================================
96
+ -----BEGIN CERTIFICATE-----
97
+ MIIDKTCCApKgAwIBAgIENnAVljANBgkqhkiG9w0BAQUFADBGMQswCQYDVQQGEwJVUzEkMCIGA1UE
98
+ ChMbRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3QgQ28uMREwDwYDVQQLEwhEU1RDQSBFMTAeFw05ODEy
99
+ MTAxODEwMjNaFw0xODEyMTAxODQwMjNaMEYxCzAJBgNVBAYTAlVTMSQwIgYDVQQKExtEaWdpdGFs
100
+ IFNpZ25hdHVyZSBUcnVzdCBDby4xETAPBgNVBAsTCERTVENBIEUxMIGdMA0GCSqGSIb3DQEBAQUA
101
+ A4GLADCBhwKBgQCgbIGpzzQeJN3+hijM3oMv+V7UQtLodGBmE5gGHKlREmlvMVW5SXIACH7TpWJE
102
+ NySZj9mDSI+ZbZUTu0M7LklOiDfBu1h//uG9+LthzfNHwJmm8fOR6Hh8AMthyUQncWlVSn5JTe2i
103
+ o74CTADKAqjuAQIxZA9SLRN0dja1erQtcQIBA6OCASQwggEgMBEGCWCGSAGG+EIBAQQEAwIABzBo
104
+ BgNVHR8EYTBfMF2gW6BZpFcwVTELMAkGA1UEBhMCVVMxJDAiBgNVBAoTG0RpZ2l0YWwgU2lnbmF0
105
+ dXJlIFRydXN0IENvLjERMA8GA1UECxMIRFNUQ0EgRTExDTALBgNVBAMTBENSTDEwKwYDVR0QBCQw
106
+ IoAPMTk5ODEyMTAxODEwMjNagQ8yMDE4MTIxMDE4MTAyM1owCwYDVR0PBAQDAgEGMB8GA1UdIwQY
107
+ MBaAFGp5fpFpRhgTCgJ3pVlbYJglDqL4MB0GA1UdDgQWBBRqeX6RaUYYEwoCd6VZW2CYJQ6i+DAM
108
+ BgNVHRMEBTADAQH/MBkGCSqGSIb2fQdBAAQMMAobBFY0LjADAgSQMA0GCSqGSIb3DQEBBQUAA4GB
109
+ ACIS2Hod3IEGtgllsofIH160L+nEHvI8wbsEkBFKg05+k7lNQseSJqBcNJo4cvj9axY+IO6CizEq
110
+ kzaFI4iKPANo08kJD038bKTaKHKTDomAsH3+gG9lbRgzl4vCa4nuYD3Im+9/KzJic5PLPON74nZ4
111
+ RbyhkwS7hp86W0N6w4pl
112
+ -----END CERTIFICATE-----
113
+
114
+ Digital Signature Trust Co. Global CA 3
115
+ =======================================
116
+ -----BEGIN CERTIFICATE-----
117
+ MIIDKTCCApKgAwIBAgIENm7TzjANBgkqhkiG9w0BAQUFADBGMQswCQYDVQQGEwJVUzEkMCIGA1UE
118
+ ChMbRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3QgQ28uMREwDwYDVQQLEwhEU1RDQSBFMjAeFw05ODEy
119
+ MDkxOTE3MjZaFw0xODEyMDkxOTQ3MjZaMEYxCzAJBgNVBAYTAlVTMSQwIgYDVQQKExtEaWdpdGFs
120
+ IFNpZ25hdHVyZSBUcnVzdCBDby4xETAPBgNVBAsTCERTVENBIEUyMIGdMA0GCSqGSIb3DQEBAQUA
121
+ A4GLADCBhwKBgQC/k48Xku8zExjrEH9OFr//Bo8qhbxe+SSmJIi2A7fBw18DW9Fvrn5C6mYjuGOD
122
+ VvsoLeE4i7TuqAHhzhy2iCoiRoX7n6dwqUcUP87eZfCocfdPJmyMvMa1795JJ/9IKn3oTQPMx7JS
123
+ xhcxEzu1TdvIxPbDDyQq2gyd55FbgM2UnQIBA6OCASQwggEgMBEGCWCGSAGG+EIBAQQEAwIABzBo
124
+ BgNVHR8EYTBfMF2gW6BZpFcwVTELMAkGA1UEBhMCVVMxJDAiBgNVBAoTG0RpZ2l0YWwgU2lnbmF0
125
+ dXJlIFRydXN0IENvLjERMA8GA1UECxMIRFNUQ0EgRTIxDTALBgNVBAMTBENSTDEwKwYDVR0QBCQw
126
+ IoAPMTk5ODEyMDkxOTE3MjZagQ8yMDE4MTIwOTE5MTcyNlowCwYDVR0PBAQDAgEGMB8GA1UdIwQY
127
+ MBaAFB6CTShlgDzJQW6sNS5ay97u+DlbMB0GA1UdDgQWBBQegk0oZYA8yUFurDUuWsve7vg5WzAM
128
+ BgNVHRMEBTADAQH/MBkGCSqGSIb2fQdBAAQMMAobBFY0LjADAgSQMA0GCSqGSIb3DQEBBQUAA4GB
129
+ AEeNg61i8tuwnkUiBbmi1gMOOHLnnvx75pO2mqWilMg0HZHRxdf0CiUPPXiBng+xZ8SQTGPdXqfi
130
+ up/1902lMXucKS1M/mQ+7LZT/uqb7YLbdHVLB3luHtgZg3Pe9T7Qtd7nS2h9Qy4qIOF+oHhEngj1
131
+ mPnHfxsb1gYgAlihw6ID
132
+ -----END CERTIFICATE-----
133
+
134
+ Verisign Class 3 Public Primary Certification Authority
135
+ =======================================================
136
+ -----BEGIN CERTIFICATE-----
137
+ MIICPDCCAaUCEHC65B0Q2Sk0tjjKewPMur8wDQYJKoZIhvcNAQECBQAwXzELMAkGA1UEBhMCVVMx
138
+ FzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFzcyAzIFB1YmxpYyBQcmltYXJ5
139
+ IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTk2MDEyOTAwMDAwMFoXDTI4MDgwMTIzNTk1OVow
140
+ XzELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFzcyAz
141
+ IFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGfMA0GCSqGSIb3DQEBAQUA
142
+ A4GNADCBiQKBgQDJXFme8huKARS0EN8EQNvjV69qRUCPhAwL0TPZ2RHP7gJYHyX3KqhEBarsAx94
143
+ f56TuZoAqiN91qyFomNFx3InzPRMxnVx0jnvT0Lwdd8KkMaOIG+YD/isI19wKTakyYbnsZogy1Ol
144
+ hec9vn2a/iRFM9x2Fe0PonFkTGUugWhFpwIDAQABMA0GCSqGSIb3DQEBAgUAA4GBALtMEivPLCYA
145
+ TxQT3ab7/AoRhIzzKBxnki98tsX63/Dolbwdj2wsqFHMc9ikwFPwTtYmwHYBV4GSXiHx0bH/59Ah
146
+ WM1pF+NEHJwZRDmJXNycAA9WjQKZ7aKQRUzkuxCkPfAyAw7xzvjoyVGM5mKf5p/AfbdynMk2Omuf
147
+ Tqj/ZA1k
148
+ -----END CERTIFICATE-----
149
+
150
+ Verisign Class 1 Public Primary Certification Authority - G2
151
+ ============================================================
152
+ -----BEGIN CERTIFICATE-----
153
+ MIIDAjCCAmsCEEzH6qqYPnHTkxD4PTqJkZIwDQYJKoZIhvcNAQEFBQAwgcExCzAJBgNVBAYTAlVT
154
+ MRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoGA1UECxMzQ2xhc3MgMSBQdWJsaWMgUHJpbWFy
155
+ eSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcyMTowOAYDVQQLEzEoYykgMTk5OCBWZXJpU2ln
156
+ biwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MR8wHQYDVQQLExZWZXJpU2lnbiBUcnVz
157
+ dCBOZXR3b3JrMB4XDTk4MDUxODAwMDAwMFoXDTI4MDgwMTIzNTk1OVowgcExCzAJBgNVBAYTAlVT
158
+ MRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoGA1UECxMzQ2xhc3MgMSBQdWJsaWMgUHJpbWFy
159
+ eSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcyMTowOAYDVQQLEzEoYykgMTk5OCBWZXJpU2ln
160
+ biwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MR8wHQYDVQQLExZWZXJpU2lnbiBUcnVz
161
+ dCBOZXR3b3JrMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCq0Lq+Fi24g9TK0g+8djHKlNgd
162
+ k4xWArzZbxpvUjZudVYKVdPfQ4chEWWKfo+9Id5rMj8bhDSVBZ1BNeuS65bdqlk/AVNtmU/t5eIq
163
+ WpDBucSmFc/IReumXY6cPvBkJHalzasab7bYe1FhbqZ/h8jit+U03EGI6glAvnOSPWvndQIDAQAB
164
+ MA0GCSqGSIb3DQEBBQUAA4GBAKlPww3HZ74sy9mozS11534Vnjty637rXC0Jh9ZrbWB85a7FkCMM
165
+ XErQr7Fd88e2CtvgFZMN3QO8x3aKtd1Pw5sTdbgBwObJW2uluIncrKTdcu1OofdPvAbT6shkdHvC
166
+ lUGcZXNY8ZCaPGqxmMnEh7zPRW1F4m4iP/68DzFc6PLZ
167
+ -----END CERTIFICATE-----
168
+
169
+ Verisign Class 2 Public Primary Certification Authority - G2
170
+ ============================================================
171
+ -----BEGIN CERTIFICATE-----
172
+ MIIDAzCCAmwCEQC5L2DMiJ+hekYJuFtwbIqvMA0GCSqGSIb3DQEBBQUAMIHBMQswCQYDVQQGEwJV
173
+ UzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xPDA6BgNVBAsTM0NsYXNzIDIgUHVibGljIFByaW1h
174
+ cnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMjE6MDgGA1UECxMxKGMpIDE5OTggVmVyaVNp
175
+ Z24sIEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTEfMB0GA1UECxMWVmVyaVNpZ24gVHJ1
176
+ c3QgTmV0d29yazAeFw05ODA1MTgwMDAwMDBaFw0yODA4MDEyMzU5NTlaMIHBMQswCQYDVQQGEwJV
177
+ UzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xPDA6BgNVBAsTM0NsYXNzIDIgUHVibGljIFByaW1h
178
+ cnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMjE6MDgGA1UECxMxKGMpIDE5OTggVmVyaVNp
179
+ Z24sIEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTEfMB0GA1UECxMWVmVyaVNpZ24gVHJ1
180
+ c3QgTmV0d29yazCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAp4gBIXQs5xoD8JjhlzwPIQjx
181
+ nNuX6Zr8wgQGE75fUsjMHiwSViy4AWkszJkfrbCWrnkE8hM5wXuYuggs6MKEEyyqaekJ9MepAqRC
182
+ wiNPStjwDqL7MWzJ5m+ZJwf15vRMeJ5t60aG+rmGyVTyssSv1EYcWskVMP8NbPUtDm3Of3cCAwEA
183
+ ATANBgkqhkiG9w0BAQUFAAOBgQByLvl/0fFx+8Se9sVeUYpAmLho+Jscg9jinb3/7aHmZuovCfTK
184
+ 1+qlK5X2JGCGTUQug6XELaDTrnhpb3LabK4I8GOSN+a7xDAXrXfMSTWqz9iP0b63GJZHc2pUIjRk
185
+ LbYWm1lbtFFZOrMLFPQS32eg9K0yZF6xRnInjBJ7xUS0rg==
186
+ -----END CERTIFICATE-----
187
+
188
+ Verisign Class 3 Public Primary Certification Authority - G2
189
+ ============================================================
190
+ -----BEGIN CERTIFICATE-----
191
+ MIIDAjCCAmsCEH3Z/gfPqB63EHln+6eJNMYwDQYJKoZIhvcNAQEFBQAwgcExCzAJBgNVBAYTAlVT
192
+ MRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoGA1UECxMzQ2xhc3MgMyBQdWJsaWMgUHJpbWFy
193
+ eSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcyMTowOAYDVQQLEzEoYykgMTk5OCBWZXJpU2ln
194
+ biwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MR8wHQYDVQQLExZWZXJpU2lnbiBUcnVz
195
+ dCBOZXR3b3JrMB4XDTk4MDUxODAwMDAwMFoXDTI4MDgwMTIzNTk1OVowgcExCzAJBgNVBAYTAlVT
196
+ MRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoGA1UECxMzQ2xhc3MgMyBQdWJsaWMgUHJpbWFy
197
+ eSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcyMTowOAYDVQQLEzEoYykgMTk5OCBWZXJpU2ln
198
+ biwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MR8wHQYDVQQLExZWZXJpU2lnbiBUcnVz
199
+ dCBOZXR3b3JrMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDMXtERXVxp0KvTuWpMmR9ZmDCO
200
+ FoUgRm1HP9SFIIThbbP4pO0M8RcPO/mn+SXXwc+EY/J8Y8+iR/LGWzOOZEAEaMGAuWQcRXfH2G71
201
+ lSk8UOg013gfqLptQ5GVj0VXXn7F+8qkBOvqlzdUMG+7AUcyM83cV5tkaWH4mx0ciU9cZwIDAQAB
202
+ MA0GCSqGSIb3DQEBBQUAA4GBAFFNzb5cy5gZnBWyATl4Lk0PZ3BwmcYQWpSkU01UbSuvDV1Ai2TT
203
+ 1+7eVmGSX6bEHRBhNtMsJzzoKQm5EWR0zLVznxxIqbxhAe7iF6YM40AIOw7n60RzKprxaZLvcRTD
204
+ Oaxxp5EJb+RxBrO6WVcmeQD2+A2iMzAo1KpYoJ2daZH9
205
+ -----END CERTIFICATE-----
206
+
207
+ GlobalSign Root CA
208
+ ==================
209
+ -----BEGIN CERTIFICATE-----
210
+ MIIDdTCCAl2gAwIBAgILBAAAAAABFUtaw5QwDQYJKoZIhvcNAQEFBQAwVzELMAkGA1UEBhMCQkUx
211
+ GTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExEDAOBgNVBAsTB1Jvb3QgQ0ExGzAZBgNVBAMTEkds
212
+ b2JhbFNpZ24gUm9vdCBDQTAeFw05ODA5MDExMjAwMDBaFw0yODAxMjgxMjAwMDBaMFcxCzAJBgNV
213
+ BAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMRAwDgYDVQQLEwdSb290IENBMRswGQYD
214
+ VQQDExJHbG9iYWxTaWduIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDa
215
+ DuaZjc6j40+Kfvvxi4Mla+pIH/EqsLmVEQS98GPR4mdmzxzdzxtIK+6NiY6arymAZavpxy0Sy6sc
216
+ THAHoT0KMM0VjU/43dSMUBUc71DuxC73/OlS8pF94G3VNTCOXkNz8kHp1Wrjsok6Vjk4bwY8iGlb
217
+ Kk3Fp1S4bInMm/k8yuX9ifUSPJJ4ltbcdG6TRGHRjcdGsnUOhugZitVtbNV4FpWi6cgKOOvyJBNP
218
+ c1STE4U6G7weNLWLBYy5d4ux2x8gkasJU26Qzns3dLlwR5EiUWMWea6xrkEmCMgZK9FGqkjWZCrX
219
+ gzT/LCrBbBlDSgeF59N89iFo7+ryUp9/k5DPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV
220
+ HRMBAf8EBTADAQH/MB0GA1UdDgQWBBRge2YaRQ2XyolQL30EzTSo//z9SzANBgkqhkiG9w0BAQUF
221
+ AAOCAQEA1nPnfE920I2/7LqivjTFKDK1fPxsnCwrvQmeU79rXqoRSLblCKOzyj1hTdNGCbM+w6Dj
222
+ Y1Ub8rrvrTnhQ7k4o+YviiY776BQVvnGCv04zcQLcFGUl5gE38NflNUVyRRBnMRddWQVDf9VMOyG
223
+ j/8N7yy5Y0b2qvzfvGn9LhJIZJrglfCm7ymPAbEVtQwdpf5pLGkkeB6zpxxxYu7KyJesF12KwvhH
224
+ hm4qxFYxldBniYUr+WymXUadDKqC5JlR3XC321Y9YeRq4VzW9v493kHMB65jUr9TU/Qr6cf9tveC
225
+ X4XSQRjbgbMEHMUfpIBvFSDJ3gyICh3WZlXi/EjJKSZp4A==
226
+ -----END CERTIFICATE-----
227
+
228
+ GlobalSign Root CA - R2
229
+ =======================
230
+ -----BEGIN CERTIFICATE-----
231
+ MIIDujCCAqKgAwIBAgILBAAAAAABD4Ym5g0wDQYJKoZIhvcNAQEFBQAwTDEgMB4GA1UECxMXR2xv
232
+ YmFsU2lnbiBSb290IENBIC0gUjIxEzARBgNVBAoTCkdsb2JhbFNpZ24xEzARBgNVBAMTCkdsb2Jh
233
+ bFNpZ24wHhcNMDYxMjE1MDgwMDAwWhcNMjExMjE1MDgwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxT
234
+ aWduIFJvb3QgQ0EgLSBSMjETMBEGA1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2ln
235
+ bjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKbPJA6+Lm8omUVCxKs+IVSbC9N/hHD6
236
+ ErPLv4dfxn+G07IwXNb9rfF73OX4YJYJkhD10FPe+3t+c4isUoh7SqbKSaZeqKeMWhG8eoLrvozp
237
+ s6yWJQeXSpkqBy+0Hne/ig+1AnwblrjFuTosvNYSuetZfeLQBoZfXklqtTleiDTsvHgMCJiEbKjN
238
+ S7SgfQx5TfC4LcshytVsW33hoCmEofnTlEnLJGKRILzdC9XZzPnqJworc5HGnRusyMvo4KD0L5CL
239
+ TfuwNhv2GXqF4G3yYROIXJ/gkwpRl4pazq+r1feqCapgvdzZX99yqWATXgAByUr6P6TqBwMhAo6C
240
+ ygPCm48CAwEAAaOBnDCBmTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4E
241
+ FgQUm+IHV2ccHsBqBt5ZtJot39wZhi4wNgYDVR0fBC8wLTAroCmgJ4YlaHR0cDovL2NybC5nbG9i
242
+ YWxzaWduLm5ldC9yb290LXIyLmNybDAfBgNVHSMEGDAWgBSb4gdXZxwewGoG3lm0mi3f3BmGLjAN
243
+ BgkqhkiG9w0BAQUFAAOCAQEAmYFThxxol4aR7OBKuEQLq4GsJ0/WwbgcQ3izDJr86iw8bmEbTUsp
244
+ 9Z8FHSbBuOmDAGJFtqkIk7mpM0sYmsL4h4hO291xNBrBVNpGP+DTKqttVCL1OmLNIG+6KYnX3ZHu
245
+ 01yiPqFbQfXf5WRDLenVOavSot+3i9DAgBkcRcAtjOj4LaR0VknFBbVPFd5uRHg5h6h+u/N5GJG7
246
+ 9G+dwfCMNYxdAfvDbbnvRG15RjF+Cv6pgsH/76tuIMRQyV+dTZsXjAzlAcmgQWpzU/qlULRuJQ/7
247
+ TBj0/VLZjmmx6BEP3ojY+x1J96relc8geMJgEtslQIxq/H5COEBkEveegeGTLg==
248
+ -----END CERTIFICATE-----
249
+
250
+ ValiCert Class 1 VA
251
+ ===================
252
+ -----BEGIN CERTIFICATE-----
253
+ MIIC5zCCAlACAQEwDQYJKoZIhvcNAQEFBQAwgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0IFZhbGlkYXRp
254
+ b24gTmV0d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENs
255
+ YXNzIDEgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZh
256
+ bGljZXJ0LmNvbS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMB4XDTk5MDYyNTIy
257
+ MjM0OFoXDTE5MDYyNTIyMjM0OFowgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0IFZhbGlkYXRpb24gTmV0
258
+ d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENsYXNzIDEg
259
+ UG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZhbGljZXJ0
260
+ LmNvbS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMIGfMA0GCSqGSIb3DQEBAQUA
261
+ A4GNADCBiQKBgQDYWYJ6ibiWuqYvaG9YLqdUHAZu9OqNSLwxlBfw8068srg1knaw0KWlAdcAAxIi
262
+ GQj4/xEjm84H9b9pGib+TunRf50sQB1ZaG6m+FiwnRqP0z/x3BkGgagO4DrdyFNFCQbmD3DD+kCm
263
+ DuJWBQ8YTfwggtFzVXSNdnKgHZ0dwN0/cQIDAQABMA0GCSqGSIb3DQEBBQUAA4GBAFBoPUn0LBwG
264
+ lN+VYH+Wexf+T3GtZMjdd9LvWVXoP+iOBSoh8gfStadS/pyxtuJbdxdA6nLWI8sogTLDAHkY7FkX
265
+ icnGah5xyf23dKUlRWnFSKsZ4UWKJWsZ7uW7EvV/96aNUcPwnXS3qT6gpf+2SQMT2iLM7XGCK5nP
266
+ Orf1LXLI
267
+ -----END CERTIFICATE-----
268
+
269
+ ValiCert Class 2 VA
270
+ ===================
271
+ -----BEGIN CERTIFICATE-----
272
+ MIIC5zCCAlACAQEwDQYJKoZIhvcNAQEFBQAwgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0IFZhbGlkYXRp
273
+ b24gTmV0d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENs
274
+ YXNzIDIgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZh
275
+ bGljZXJ0LmNvbS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMB4XDTk5MDYyNjAw
276
+ MTk1NFoXDTE5MDYyNjAwMTk1NFowgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0IFZhbGlkYXRpb24gTmV0
277
+ d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENsYXNzIDIg
278
+ UG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZhbGljZXJ0
279
+ LmNvbS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMIGfMA0GCSqGSIb3DQEBAQUA
280
+ A4GNADCBiQKBgQDOOnHK5avIWZJV16vYdA757tn2VUdZZUcOBVXc65g2PFxTXdMwzzjsvUGJ7SVC
281
+ CSRrCl6zfN1SLUzm1NZ9WlmpZdRJEy0kTRxQb7XBhVQ7/nHk01xC+YDgkRoKWzk2Z/M/VXwbP7Rf
282
+ ZHM047QSv4dk+NoS/zcnwbNDu+97bi5p9wIDAQABMA0GCSqGSIb3DQEBBQUAA4GBADt/UG9vUJSZ
283
+ SWI4OB9L+KXIPqeCgfYrx+jFzug6EILLGACOTb2oWH+heQC1u+mNr0HZDzTuIYEZoDJJKPTEjlbV
284
+ UjP9UNV+mWwD5MlM/Mtsq2azSiGM5bUMMj4QssxsodyamEwCW/POuZ6lcg5Ktz885hZo+L7tdEy8
285
+ W9ViH0Pd
286
+ -----END CERTIFICATE-----
287
+
288
+ RSA Root Certificate 1
289
+ ======================
290
+ -----BEGIN CERTIFICATE-----
291
+ MIIC5zCCAlACAQEwDQYJKoZIhvcNAQEFBQAwgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0IFZhbGlkYXRp
292
+ b24gTmV0d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENs
293
+ YXNzIDMgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZh
294
+ bGljZXJ0LmNvbS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMB4XDTk5MDYyNjAw
295
+ MjIzM1oXDTE5MDYyNjAwMjIzM1owgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0IFZhbGlkYXRpb24gTmV0
296
+ d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENsYXNzIDMg
297
+ UG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZhbGljZXJ0
298
+ LmNvbS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMIGfMA0GCSqGSIb3DQEBAQUA
299
+ A4GNADCBiQKBgQDjmFGWHOjVsQaBalfDcnWTq8+epvzzFlLWLU2fNUSoLgRNB0mKOCn1dzfnt6td
300
+ 3zZxFJmP3MKS8edgkpfs2Ejcv8ECIMYkpChMMFp2bbFc893enhBxoYjHW5tBbcqwuI4V7q0zK89H
301
+ BFx1cQqYJJgpp0lZpd34t0NiYfPT4tBVPwIDAQABMA0GCSqGSIb3DQEBBQUAA4GBAFa7AliEZwgs
302
+ 3x/be0kz9dNnnfS0ChCzycUs4pJqcXgn8nCDQtM+z6lU9PHYkhaM0QTLS6vJn0WuPIqpsHEzXcjF
303
+ V9+vqDWzf4mH6eglkrh/hXqu1rweN1gqZ8mRzyqBPu3GOd/APhmcGcwTTYJBtYze4D1gCCAPRX5r
304
+ on+jjBXu
305
+ -----END CERTIFICATE-----
306
+
307
+ Verisign Class 1 Public Primary Certification Authority - G3
308
+ ============================================================
309
+ -----BEGIN CERTIFICATE-----
310
+ MIIEGjCCAwICEQCLW3VWhFSFCwDPrzhIzrGkMA0GCSqGSIb3DQEBBQUAMIHKMQswCQYDVQQGEwJV
311
+ UzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdv
312
+ cmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNl
313
+ IG9ubHkxRTBDBgNVBAMTPFZlcmlTaWduIENsYXNzIDEgUHVibGljIFByaW1hcnkgQ2VydGlmaWNh
314
+ dGlvbiBBdXRob3JpdHkgLSBHMzAeFw05OTEwMDEwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMIHKMQsw
315
+ CQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRy
316
+ dXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhv
317
+ cml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlTaWduIENsYXNzIDEgUHVibGljIFByaW1hcnkg
318
+ Q2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
319
+ ggEBAN2E1Lm0+afY8wR4nN493GwTFtl63SRRZsDHJlkNrAYIwpTRMx/wgzUfbhvI3qpuFU5UJ+/E
320
+ bRrsC+MO8ESlV8dAWB6jRx9x7GD2bZTIGDnt/kIYVt/kTEkQeE4BdjVjEjbdZrwBBDajVWjVojYJ
321
+ rKshJlQGrT/KFOCsyq0GHZXi+J3x4GD/wn91K0zM2v6HmSHquv4+VNfSWXjbPG7PoBMAGrgnoeS+
322
+ Z5bKoMWznN3JdZ7rMJpfo83ZrngZPyPpXNspva1VyBtUjGP26KbqxzcSXKMpHgLZ2x87tNcPVkeB
323
+ FQRKr4Mn0cVYiMHd9qqnoxjaaKptEVHhv2Vrn5Z20T0CAwEAATANBgkqhkiG9w0BAQUFAAOCAQEA
324
+ q2aN17O6x5q25lXQBfGfMY1aqtmqRiYPce2lrVNWYgFHKkTp/j90CxObufRNG7LRX7K20ohcs5/N
325
+ y9Sn2WCVhDr4wTcdYcrnsMXlkdpUpqwxga6X3s0IrLjAl4B/bnKk52kTlWUfxJM8/XmPBNQ+T+r3
326
+ ns7NZ3xPZQL/kYVUc8f/NveGLezQXk//EZ9yBta4GvFMDSZl4kSAHsef493oCtrspSCAaWihT37h
327
+ a88HQfqDjrw43bAuEbFrskLMmrz5SCJ5ShkPshw+IHTZasO+8ih4E1Z5T21Q6huwtVexN2ZYI/Pc
328
+ D98Kh8TvhgXVOBRgmaNL3gaWcSzy27YfpO8/7g==
329
+ -----END CERTIFICATE-----
330
+
331
+ Verisign Class 2 Public Primary Certification Authority - G3
332
+ ============================================================
333
+ -----BEGIN CERTIFICATE-----
334
+ MIIEGTCCAwECEGFwy0mMX5hFKeewptlQW3owDQYJKoZIhvcNAQEFBQAwgcoxCzAJBgNVBAYTAlVT
335
+ MRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjEfMB0GA1UECxMWVmVyaVNpZ24gVHJ1c3QgTmV0d29y
336
+ azE6MDgGA1UECxMxKGMpIDE5OTkgVmVyaVNpZ24sIEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ug
337
+ b25seTFFMEMGA1UEAxM8VmVyaVNpZ24gQ2xhc3MgMiBQdWJsaWMgUHJpbWFyeSBDZXJ0aWZpY2F0
338
+ aW9uIEF1dGhvcml0eSAtIEczMB4XDTk5MTAwMTAwMDAwMFoXDTM2MDcxNjIzNTk1OVowgcoxCzAJ
339
+ BgNVBAYTAlVTMRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjEfMB0GA1UECxMWVmVyaVNpZ24gVHJ1
340
+ c3QgTmV0d29yazE6MDgGA1UECxMxKGMpIDE5OTkgVmVyaVNpZ24sIEluYy4gLSBGb3IgYXV0aG9y
341
+ aXplZCB1c2Ugb25seTFFMEMGA1UEAxM8VmVyaVNpZ24gQ2xhc3MgMiBQdWJsaWMgUHJpbWFyeSBD
342
+ ZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEczMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC
343
+ AQEArwoNwtUs22e5LeWUJ92lvuCwTY+zYVY81nzD9M0+hsuiiOLh2KRpxbXiv8GmR1BeRjmL1Za6
344
+ tW8UvxDOJxOeBUebMXoT2B/Z0wI3i60sR/COgQanDTAM6/c8DyAd3HJG7qUCyFvDyVZpTMUYwZF7
345
+ C9UTAJu878NIPkZgIIUq1ZC2zYugzDLdt/1AVbJQHFauzI13TccgTacxdu9okoqQHgiBVrKtaaNS
346
+ 0MscxCM9H5n+TOgWY47GCI72MfbS+uV23bUckqNJzc0BzWjNqWm6o+sdDZykIKbBoMXRRkwXbdKs
347
+ Zj+WjOCE1Db/IlnF+RFgqF8EffIa9iVCYQ/ESrg+iQIDAQABMA0GCSqGSIb3DQEBBQUAA4IBAQA0
348
+ JhU8wI1NQ0kdvekhktdmnLfexbjQ5F1fdiLAJvmEOjr5jLX77GDx6M4EsMjdpwOPMPOY36TmpDHf
349
+ 0xwLRtxyID+u7gU8pDM/CzmscHhzS5kr3zDCVLCoO1Wh/hYozUK9dG6A2ydEp85EXdQbkJgNHkKU
350
+ sQAsBNB0owIFImNjzYO1+8FtYmtpdf1dcEG59b98377BMnMiIYtYgXsVkXq642RIsH/7NiXaldDx
351
+ JBQX3RiAa0YjOVT1jmIJBB2UkKab5iXiQkWquJCtvgiPqQtCGJTPcjnhsUPgKM+351psE2tJs//j
352
+ GHyJizNdrDPXp/naOlXJWBD5qu9ats9LS98q
353
+ -----END CERTIFICATE-----
354
+
355
+ Verisign Class 3 Public Primary Certification Authority - G3
356
+ ============================================================
357
+ -----BEGIN CERTIFICATE-----
358
+ MIIEGjCCAwICEQCbfgZJoz5iudXukEhxKe9XMA0GCSqGSIb3DQEBBQUAMIHKMQswCQYDVQQGEwJV
359
+ UzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdv
360
+ cmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNl
361
+ IG9ubHkxRTBDBgNVBAMTPFZlcmlTaWduIENsYXNzIDMgUHVibGljIFByaW1hcnkgQ2VydGlmaWNh
362
+ dGlvbiBBdXRob3JpdHkgLSBHMzAeFw05OTEwMDEwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMIHKMQsw
363
+ CQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRy
364
+ dXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhv
365
+ cml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlTaWduIENsYXNzIDMgUHVibGljIFByaW1hcnkg
366
+ Q2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
367
+ ggEBAMu6nFL8eB8aHm8bN3O9+MlrlBIwT/A2R/XQkQr1F8ilYcEWQE37imGQ5XYgwREGfassbqb1
368
+ EUGO+i2tKmFZpGcmTNDovFJbcCAEWNF6yaRpvIMXZK0Fi7zQWM6NjPXr8EJJC52XJ2cybuGukxUc
369
+ cLwgTS8Y3pKI6GyFVxEa6X7jJhFUokWWVYPKMIno3Nij7SqAP395ZVc+FSBmCC+Vk7+qRy+oRpfw
370
+ EuL+wgorUeZ25rdGt+INpsyow0xZVYnm6FNcHOqd8GIWC6fJXwzw3sJ2zq/3avL6QaaiMxTJ5Xpj
371
+ 055iN9WFZZ4O5lMkdBteHRJTW8cs54NJOxWuimi5V5cCAwEAATANBgkqhkiG9w0BAQUFAAOCAQEA
372
+ ERSWwauSCPc/L8my/uRan2Te2yFPhpk0djZX3dAVL8WtfxUfN2JzPtTnX84XA9s1+ivbrmAJXx5f
373
+ j267Cz3qWhMeDGBvtcC1IyIuBwvLqXTLR7sdwdela8wv0kL9Sd2nic9TutoAWii/gt/4uhMdUIaC
374
+ /Y4wjylGsB49Ndo4YhYYSq3mtlFs3q9i6wHQHiT+eo8SGhJouPtmmRQURVyu565pF4ErWjfJXir0
375
+ xuKhXFSbplQAz/DxwceYMBo7Nhbbo27q/a2ywtrvAkcTisDxszGtTxzhT5yvDwyd93gN2PQ1VoDa
376
+ t20Xj50egWTh/sVFuq1ruQp6Tk9LhO5L8X3dEQ==
377
+ -----END CERTIFICATE-----
378
+
379
+ Verisign Class 4 Public Primary Certification Authority - G3
380
+ ============================================================
381
+ -----BEGIN CERTIFICATE-----
382
+ MIIEGjCCAwICEQDsoKeLbnVqAc/EfMwvlF7XMA0GCSqGSIb3DQEBBQUAMIHKMQswCQYDVQQGEwJV
383
+ UzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdv
384
+ cmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNl
385
+ IG9ubHkxRTBDBgNVBAMTPFZlcmlTaWduIENsYXNzIDQgUHVibGljIFByaW1hcnkgQ2VydGlmaWNh
386
+ dGlvbiBBdXRob3JpdHkgLSBHMzAeFw05OTEwMDEwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMIHKMQsw
387
+ CQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRy
388
+ dXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhv
389
+ cml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlTaWduIENsYXNzIDQgUHVibGljIFByaW1hcnkg
390
+ Q2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
391
+ ggEBAK3LpRFpxlmr8Y+1GQ9Wzsy1HyDkniYlS+BzZYlZ3tCD5PUPtbut8XzoIfzk6AzufEUiGXaS
392
+ tBO3IFsJ+mGuqPKljYXCKtbeZjbSmwL0qJJgfJxptI8kHtCGUvYynEFYHiK9zUVilQhu0GbdU6LM
393
+ 8BDcVHOLBKFGMzNcF0C5nk3T875Vg+ixiY5afJqWIpA7iCXy0lOIAgwLePLmNxdLMEYH5IBtptiW
394
+ Lugs+BGzOA1mppvqySNb247i8xOOGlktqgLw7KSHZtzBP/XYufTsgsbSPZUd5cBPhMnZo0QoBmrX
395
+ Razwa2rvTl/4EYIeOGM0ZlDUPpNz+jDDZq3/ky2X7wMCAwEAATANBgkqhkiG9w0BAQUFAAOCAQEA
396
+ j/ola09b5KROJ1WrIhVZPMq1CtRK26vdoV9TxaBXOcLORyu+OshWv8LZJxA6sQU8wHcxuzrTBXtt
397
+ mhwwjIDLk5Mqg6sFUYICABFna/OIYUdfA5PVWw3g8dShMjWFsjrbsIKr0csKvE+MW8VLADsfKoKm
398
+ fjaF3H48ZwC15DtS4KjrXRX5xm3wrR0OhbepmnMUWluPQSjA1egtTaRezarZ7c7c2NU8Qh0XwRJd
399
+ RTjDOPP8hS6DRkiy1yBfkjaP53kPmF6Z6PDQpLv1U70qzlmwr25/bLvSHgCwIe34QWKCudiyxLtG
400
+ UPMxxY8BqHTr9Xgn2uf3ZkPznoM+IKrDNWCRzg==
401
+ -----END CERTIFICATE-----
402
+
403
+ Entrust.net Secure Server CA
404
+ ============================
405
+ -----BEGIN CERTIFICATE-----
406
+ MIIE2DCCBEGgAwIBAgIEN0rSQzANBgkqhkiG9w0BAQUFADCBwzELMAkGA1UEBhMCVVMxFDASBgNV
407
+ BAoTC0VudHJ1c3QubmV0MTswOQYDVQQLEzJ3d3cuZW50cnVzdC5uZXQvQ1BTIGluY29ycC4gYnkg
408
+ cmVmLiAobGltaXRzIGxpYWIuKTElMCMGA1UECxMcKGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRl
409
+ ZDE6MDgGA1UEAxMxRW50cnVzdC5uZXQgU2VjdXJlIFNlcnZlciBDZXJ0aWZpY2F0aW9uIEF1dGhv
410
+ cml0eTAeFw05OTA1MjUxNjA5NDBaFw0xOTA1MjUxNjM5NDBaMIHDMQswCQYDVQQGEwJVUzEUMBIG
411
+ A1UEChMLRW50cnVzdC5uZXQxOzA5BgNVBAsTMnd3dy5lbnRydXN0Lm5ldC9DUFMgaW5jb3JwLiBi
412
+ eSByZWYuIChsaW1pdHMgbGlhYi4pMSUwIwYDVQQLExwoYykgMTk5OSBFbnRydXN0Lm5ldCBMaW1p
413
+ dGVkMTowOAYDVQQDEzFFbnRydXN0Lm5ldCBTZWN1cmUgU2VydmVyIENlcnRpZmljYXRpb24gQXV0
414
+ aG9yaXR5MIGdMA0GCSqGSIb3DQEBAQUAA4GLADCBhwKBgQDNKIM0VBuJ8w+vN5Ex/68xYMmo6LIQ
415
+ aO2f55M28Qpku0f1BBc/I0dNxScZgSYMVHINiC3ZH5oSn7yzcdOAGT9HZnuMNSjSuQrfJNqc1lB5
416
+ gXpa0zf3wkrYKZImZNHkmGw6AIr1NJtl+O3jEP/9uElY3KDegjlrgbEWGWG5VLbmQwIBA6OCAdcw
417
+ ggHTMBEGCWCGSAGG+EIBAQQEAwIABzCCARkGA1UdHwSCARAwggEMMIHeoIHboIHYpIHVMIHSMQsw
418
+ CQYDVQQGEwJVUzEUMBIGA1UEChMLRW50cnVzdC5uZXQxOzA5BgNVBAsTMnd3dy5lbnRydXN0Lm5l
419
+ dC9DUFMgaW5jb3JwLiBieSByZWYuIChsaW1pdHMgbGlhYi4pMSUwIwYDVQQLExwoYykgMTk5OSBF
420
+ bnRydXN0Lm5ldCBMaW1pdGVkMTowOAYDVQQDEzFFbnRydXN0Lm5ldCBTZWN1cmUgU2VydmVyIENl
421
+ cnRpZmljYXRpb24gQXV0aG9yaXR5MQ0wCwYDVQQDEwRDUkwxMCmgJ6AlhiNodHRwOi8vd3d3LmVu
422
+ dHJ1c3QubmV0L0NSTC9uZXQxLmNybDArBgNVHRAEJDAigA8xOTk5MDUyNTE2MDk0MFqBDzIwMTkw
423
+ NTI1MTYwOTQwWjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAU8BdiE1U9s/8KAGv7UISX8+1i0Bow
424
+ HQYDVR0OBBYEFPAXYhNVPbP/CgBr+1CEl/PtYtAaMAwGA1UdEwQFMAMBAf8wGQYJKoZIhvZ9B0EA
425
+ BAwwChsEVjQuMAMCBJAwDQYJKoZIhvcNAQEFBQADgYEAkNwwAvpkdMKnCqV8IY00F6j7Rw7/JXyN
426
+ Ewr75Ji174z4xRAN95K+8cPV1ZVqBLssziY2ZcgxxufuP+NXdYR6Ee9GTxj005i7qIcyunL2POI9
427
+ n9cd2cNgQ4xYDiKWL2KjLB+6rQXvqzJ4h6BUcxm1XAX5Uj5tLUUL9wqT6u0G+bI=
428
+ -----END CERTIFICATE-----
429
+
430
+ Entrust.net Premium 2048 Secure Server CA
431
+ =========================================
432
+ -----BEGIN CERTIFICATE-----
433
+ MIIEXDCCA0SgAwIBAgIEOGO5ZjANBgkqhkiG9w0BAQUFADCBtDEUMBIGA1UEChMLRW50cnVzdC5u
434
+ ZXQxQDA+BgNVBAsUN3d3dy5lbnRydXN0Lm5ldC9DUFNfMjA0OCBpbmNvcnAuIGJ5IHJlZi4gKGxp
435
+ bWl0cyBsaWFiLikxJTAjBgNVBAsTHChjKSAxOTk5IEVudHJ1c3QubmV0IExpbWl0ZWQxMzAxBgNV
436
+ BAMTKkVudHJ1c3QubmV0IENlcnRpZmljYXRpb24gQXV0aG9yaXR5ICgyMDQ4KTAeFw05OTEyMjQx
437
+ NzUwNTFaFw0xOTEyMjQxODIwNTFaMIG0MRQwEgYDVQQKEwtFbnRydXN0Lm5ldDFAMD4GA1UECxQ3
438
+ d3d3LmVudHJ1c3QubmV0L0NQU18yMDQ4IGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxpYWIuKTEl
439
+ MCMGA1UECxMcKGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDEzMDEGA1UEAxMqRW50cnVzdC5u
440
+ ZXQgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgKDIwNDgpMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
441
+ MIIBCgKCAQEArU1LqRKGsuqjIAcVFmQqK0vRvwtKTY7tgHalZ7d4QMBzQshowNtTK91euHaYNZOL
442
+ Gp18EzoOH1u3Hs/lJBQesYGpjX24zGtLA/ECDNyrpUAkAH90lKGdCCmziAv1h3edVc3kw37XamSr
443
+ hRSGlVuXMlBvPci6Zgzj/L24ScF2iUkZ/cCovYmjZy/Gn7xxGWC4LeksyZB2ZnuU4q941mVTXTzW
444
+ nLLPKQP5L6RQstRIzgUyVYr9smRMDuSYB3Xbf9+5CFVghTAp+XtIpGmG4zU/HoZdenoVve8AjhUi
445
+ VBcAkCaTvA5JaJG/+EfTnZVCwQ5N328mz8MYIWJmQ3DW1cAH4QIDAQABo3QwcjARBglghkgBhvhC
446
+ AQEEBAMCAAcwHwYDVR0jBBgwFoAUVeSB0RGAvtiJuQijMfmhJAkWuXAwHQYDVR0OBBYEFFXkgdER
447
+ gL7YibkIozH5oSQJFrlwMB0GCSqGSIb2fQdBAAQQMA4bCFY1LjA6NC4wAwIEkDANBgkqhkiG9w0B
448
+ AQUFAAOCAQEAWUesIYSKF8mciVMeuoCFGsY8Tj6xnLZ8xpJdGGQC49MGCBFhfGPjK50xA3B20qMo
449
+ oPS7mmNz7W3lKtvtFKkrxjYR0CvrB4ul2p5cGZ1WEvVUKcgF7bISKo30Axv/55IQh7A6tcOdBTcS
450
+ o8f0FbnVpDkWm1M6I5HxqIKiaohowXkCIryqptau37AUX7iH0N18f3v/rxzP5tsHrV7bhZ3QKw0z
451
+ 2wTR5klAEyt2+z7pnIkPFc4YsIV4IU9rTw76NmfNB/L/CNDi3tm/Kq+4h4YhPATKt5Rof8886ZjX
452
+ OP/swNlQ8C5LWK5Gb9Auw2DaclVyvUxFnmG6v4SBkgPR0ml8xQ==
453
+ -----END CERTIFICATE-----
454
+
455
+ Baltimore CyberTrust Root
456
+ =========================
457
+ -----BEGIN CERTIFICATE-----
458
+ MIIDdzCCAl+gAwIBAgIEAgAAuTANBgkqhkiG9w0BAQUFADBaMQswCQYDVQQGEwJJRTESMBAGA1UE
459
+ ChMJQmFsdGltb3JlMRMwEQYDVQQLEwpDeWJlclRydXN0MSIwIAYDVQQDExlCYWx0aW1vcmUgQ3li
460
+ ZXJUcnVzdCBSb290MB4XDTAwMDUxMjE4NDYwMFoXDTI1MDUxMjIzNTkwMFowWjELMAkGA1UEBhMC
461
+ SUUxEjAQBgNVBAoTCUJhbHRpbW9yZTETMBEGA1UECxMKQ3liZXJUcnVzdDEiMCAGA1UEAxMZQmFs
462
+ dGltb3JlIEN5YmVyVHJ1c3QgUm9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKME
463
+ uyKrmD1X6CZymrV51Cni4eiVgLGw41uOKymaZN+hXe2wCQVt2yguzmKiYv60iNoS6zjrIZ3AQSsB
464
+ UnuId9Mcj8e6uYi1agnnc+gRQKfRzMpijS3ljwumUNKoUMMo6vWrJYeKmpYcqWe4PwzV9/lSEy/C
465
+ G9VwcPCPwBLKBsua4dnKM3p31vjsufFoREJIE9LAwqSuXmD+tqYF/LTdB1kC1FkYmGP1pWPgkAx9
466
+ XbIGevOF6uvUA65ehD5f/xXtabz5OTZydc93Uk3zyZAsuT3lySNTPx8kmCFcB5kpvcY67Oduhjpr
467
+ l3RjM71oGDHweI12v/yejl0qhqdNkNwnGjkCAwEAAaNFMEMwHQYDVR0OBBYEFOWdWTCCR1jMrPoI
468
+ VDaGezq1BE3wMBIGA1UdEwEB/wQIMAYBAf8CAQMwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEB
469
+ BQUAA4IBAQCFDF2O5G9RaEIFoN27TyclhAO992T9Ldcw46QQF+vaKSm2eT929hkTI7gQCvlYpNRh
470
+ cL0EYWoSihfVCr3FvDB81ukMJY2GQE/szKN+OMY3EU/t3WgxjkzSswF07r51XgdIGn9w/xZchMB5
471
+ hbgF/X++ZRGjD8ACtPhSNzkE1akxehi/oCr0Epn3o0WC4zxe9Z2etciefC7IpJ5OCBRLbf1wbWsa
472
+ Y71k5h+3zvDyny67G7fyUIhzksLi4xaNmjICq44Y3ekQEe5+NauQrz4wlHrQMz2nZQ/1/I6eYs9H
473
+ RCwBXbsdtTLSR9I4LtD+gdwyah617jzV/OeBHRnDJELqYzmp
474
+ -----END CERTIFICATE-----
475
+
476
+ Equifax Secure Global eBusiness CA
477
+ ==================================
478
+ -----BEGIN CERTIFICATE-----
479
+ MIICkDCCAfmgAwIBAgIBATANBgkqhkiG9w0BAQQFADBaMQswCQYDVQQGEwJVUzEcMBoGA1UEChMT
480
+ RXF1aWZheCBTZWN1cmUgSW5jLjEtMCsGA1UEAxMkRXF1aWZheCBTZWN1cmUgR2xvYmFsIGVCdXNp
481
+ bmVzcyBDQS0xMB4XDTk5MDYyMTA0MDAwMFoXDTIwMDYyMTA0MDAwMFowWjELMAkGA1UEBhMCVVMx
482
+ HDAaBgNVBAoTE0VxdWlmYXggU2VjdXJlIEluYy4xLTArBgNVBAMTJEVxdWlmYXggU2VjdXJlIEds
483
+ b2JhbCBlQnVzaW5lc3MgQ0EtMTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAuucXkAJlsTRV
484
+ PEnCUdXfp9E3j9HngXNBUmCbnaEXJnitx7HoJpQytd4zjTov2/KaelpzmKNc6fuKcxtc58O/gGzN
485
+ qfTWK8D3+ZmqY6KxRwIP1ORROhI8bIpaVIRw28HFkM9yRcuoWcDNM50/o5brhTMhHD4ePmBudpxn
486
+ hcXIw2ECAwEAAaNmMGQwEQYJYIZIAYb4QgEBBAQDAgAHMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0j
487
+ BBgwFoAUvqigdHJQa0S3ySPY+6j/s1draGwwHQYDVR0OBBYEFL6ooHRyUGtEt8kj2Puo/7NXa2hs
488
+ MA0GCSqGSIb3DQEBBAUAA4GBADDiAVGqx+pf2rnQZQ8w1j7aDRRJbpGTJxQx78T3LUX47Me/okEN
489
+ I7SS+RkAZ70Br83gcfxaz2TE4JaY0KNA4gGK7ycH8WUBikQtBmV1UsCGECAhX2xrD2yuCRyv8qIY
490
+ NMR1pHMc8Y3c7635s3a0kr/clRAevsvIO1qEYBlWlKlV
491
+ -----END CERTIFICATE-----
492
+
493
+ Equifax Secure eBusiness CA 1
494
+ =============================
495
+ -----BEGIN CERTIFICATE-----
496
+ MIICgjCCAeugAwIBAgIBBDANBgkqhkiG9w0BAQQFADBTMQswCQYDVQQGEwJVUzEcMBoGA1UEChMT
497
+ RXF1aWZheCBTZWN1cmUgSW5jLjEmMCQGA1UEAxMdRXF1aWZheCBTZWN1cmUgZUJ1c2luZXNzIENB
498
+ LTEwHhcNOTkwNjIxMDQwMDAwWhcNMjAwNjIxMDQwMDAwWjBTMQswCQYDVQQGEwJVUzEcMBoGA1UE
499
+ ChMTRXF1aWZheCBTZWN1cmUgSW5jLjEmMCQGA1UEAxMdRXF1aWZheCBTZWN1cmUgZUJ1c2luZXNz
500
+ IENBLTEwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAM4vGbwXt3fek6lfWg0XTzQaDJj0ItlZ
501
+ 1MRoRvC0NcWFAyDGr0WlIVFFQesWWDYyb+JQYmT5/VGcqiTZ9J2DKocKIdMSODRsjQBuWqDZQu4a
502
+ IZX5UkxVWsUPOE9G+m34LjXWHXzr4vCwdYDIqROsvojvOm6rXyo4YgKwEnv+j6YDAgMBAAGjZjBk
503
+ MBEGCWCGSAGG+EIBAQQEAwIABzAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFEp4MlIR21kW
504
+ Nl7fwRQ2QGpHfEyhMB0GA1UdDgQWBBRKeDJSEdtZFjZe38EUNkBqR3xMoTANBgkqhkiG9w0BAQQF
505
+ AAOBgQB1W6ibAxHm6VZMzfmpTMANmvPMZWnmJXbMWbfWVMMdzZmsGd20hdXgPfxiIKeES1hl8eL5
506
+ lSE/9dR+WB5Hh1Q+WKG1tfgq73HnvMP2sUlG4tega+VWeponmHxGYhTnyfxuAxJ5gDgdSIKN/Bf+
507
+ KpYrtWKmpj29f5JZzVoqgrI3eQ==
508
+ -----END CERTIFICATE-----
509
+
510
+ Equifax Secure eBusiness CA 2
511
+ =============================
512
+ -----BEGIN CERTIFICATE-----
513
+ MIIDIDCCAomgAwIBAgIEN3DPtTANBgkqhkiG9w0BAQUFADBOMQswCQYDVQQGEwJVUzEXMBUGA1UE
514
+ ChMORXF1aWZheCBTZWN1cmUxJjAkBgNVBAsTHUVxdWlmYXggU2VjdXJlIGVCdXNpbmVzcyBDQS0y
515
+ MB4XDTk5MDYyMzEyMTQ0NVoXDTE5MDYyMzEyMTQ0NVowTjELMAkGA1UEBhMCVVMxFzAVBgNVBAoT
516
+ DkVxdWlmYXggU2VjdXJlMSYwJAYDVQQLEx1FcXVpZmF4IFNlY3VyZSBlQnVzaW5lc3MgQ0EtMjCB
517
+ nzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA5Dk5kx5SBhsoNviyoynF7Y6yEb3+6+e0dMKP/wXn
518
+ 2Z0GvxLIPw7y1tEkshHe0XMJitSxLJgJDR5QRrKDpkWNYmi7hRsgcDKqQM2mll/EcTc/BPO3QSQ5
519
+ BxoeLmFYoBIL5aXfxavqN3HMHMg3OrmXUqesxWoklE6ce8/AatbfIb0CAwEAAaOCAQkwggEFMHAG
520
+ A1UdHwRpMGcwZaBjoGGkXzBdMQswCQYDVQQGEwJVUzEXMBUGA1UEChMORXF1aWZheCBTZWN1cmUx
521
+ JjAkBgNVBAsTHUVxdWlmYXggU2VjdXJlIGVCdXNpbmVzcyBDQS0yMQ0wCwYDVQQDEwRDUkwxMBoG
522
+ A1UdEAQTMBGBDzIwMTkwNjIzMTIxNDQ1WjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAUUJ4L6q9e
523
+ uSBIplBqy/3YIHqngnYwHQYDVR0OBBYEFFCeC+qvXrkgSKZQasv92CB6p4J2MAwGA1UdEwQFMAMB
524
+ Af8wGgYJKoZIhvZ9B0EABA0wCxsFVjMuMGMDAgbAMA0GCSqGSIb3DQEBBQUAA4GBAAyGgq3oThr1
525
+ jokn4jVYPSm0B482UJW/bsGe68SQsoWou7dC4A8HOd/7npCy0cE+U58DRLB+S/Rv5Hwf5+Kx5Lia
526
+ 78O9zt4LMjTZ3ijtM2vE1Nc9ElirfQkty3D1E4qUoSek1nDFbZS1yX2doNLGCEnZZpum0/QL3MUm
527
+ V+GRMOrN
528
+ -----END CERTIFICATE-----
529
+
530
+ AddTrust Low-Value Services Root
531
+ ================================
532
+ -----BEGIN CERTIFICATE-----
533
+ MIIEGDCCAwCgAwIBAgIBATANBgkqhkiG9w0BAQUFADBlMQswCQYDVQQGEwJTRTEUMBIGA1UEChML
534
+ QWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3b3JrMSEwHwYDVQQDExhBZGRU
535
+ cnVzdCBDbGFzcyAxIENBIFJvb3QwHhcNMDAwNTMwMTAzODMxWhcNMjAwNTMwMTAzODMxWjBlMQsw
536
+ CQYDVQQGEwJTRTEUMBIGA1UEChMLQWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBO
537
+ ZXR3b3JrMSEwHwYDVQQDExhBZGRUcnVzdCBDbGFzcyAxIENBIFJvb3QwggEiMA0GCSqGSIb3DQEB
538
+ AQUAA4IBDwAwggEKAoIBAQCWltQhSWDia+hBBwzexODcEyPNwTXH+9ZOEQpnXvUGW2ulCDtbKRY6
539
+ 54eyNAbFvAWlA3yCyykQruGIgb3WntP+LVbBFc7jJp0VLhD7Bo8wBN6ntGO0/7Gcrjyvd7ZWxbWr
540
+ oulpOj0OM3kyP3CCkplhbY0wCI9xP6ZIVxn4JdxLZlyldI+Yrsj5wAYi56xz36Uu+1LcsRVlIPo1
541
+ Zmne3yzxbrww2ywkEtvrNTVokMsAsJchPXQhI2U0K7t4WaPW4XY5mqRJjox0r26kmqPZm9I4XJui
542
+ GMx1I4S+6+JNM3GOGvDC+Mcdoq0Dlyz4zyXG9rgkMbFjXZJ/Y/AlyVMuH79NAgMBAAGjgdIwgc8w
543
+ HQYDVR0OBBYEFJWxtPCUtr3H2tERCSG+wa9J/RB7MAsGA1UdDwQEAwIBBjAPBgNVHRMBAf8EBTAD
544
+ AQH/MIGPBgNVHSMEgYcwgYSAFJWxtPCUtr3H2tERCSG+wa9J/RB7oWmkZzBlMQswCQYDVQQGEwJT
545
+ RTEUMBIGA1UEChMLQWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3b3JrMSEw
546
+ HwYDVQQDExhBZGRUcnVzdCBDbGFzcyAxIENBIFJvb3SCAQEwDQYJKoZIhvcNAQEFBQADggEBACxt
547
+ ZBsfzQ3duQH6lmM0MkhHma6X7f1yFqZzR1r0693p9db7RcwpiURdv0Y5PejuvE1Uhh4dbOMXJ0Ph
548
+ iVYrqW9yTkkz43J8KiOavD7/KCrto/8cI7pDVwlnTUtiBi34/2ydYB7YHEt9tTEv2dB8Xfjea4MY
549
+ eDdXL+gzB2ffHsdrKpV2ro9Xo/D0UrSpUwjP4E/TelOL/bscVjby/rK25Xa71SJlpz/+0WatC7xr
550
+ mYbvP33zGDLKe8bjq2RGlfgmadlVg3sslgf/WSxEo8bl6ancoWOAWiFeIc9TVPC6b4nbqKqVz4vj
551
+ ccweGyBECMB6tkD9xOQ14R0WHNC8K47Wcdk=
552
+ -----END CERTIFICATE-----
553
+
554
+ AddTrust External Root
555
+ ======================
556
+ -----BEGIN CERTIFICATE-----
557
+ MIIENjCCAx6gAwIBAgIBATANBgkqhkiG9w0BAQUFADBvMQswCQYDVQQGEwJTRTEUMBIGA1UEChML
558
+ QWRkVHJ1c3QgQUIxJjAkBgNVBAsTHUFkZFRydXN0IEV4dGVybmFsIFRUUCBOZXR3b3JrMSIwIAYD
559
+ VQQDExlBZGRUcnVzdCBFeHRlcm5hbCBDQSBSb290MB4XDTAwMDUzMDEwNDgzOFoXDTIwMDUzMDEw
560
+ NDgzOFowbzELMAkGA1UEBhMCU0UxFDASBgNVBAoTC0FkZFRydXN0IEFCMSYwJAYDVQQLEx1BZGRU
561
+ cnVzdCBFeHRlcm5hbCBUVFAgTmV0d29yazEiMCAGA1UEAxMZQWRkVHJ1c3QgRXh0ZXJuYWwgQ0Eg
562
+ Um9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALf3GjPm8gAELTngTlvtH7xsD821
563
+ +iO2zt6bETOXpClMfZOfvUq8k+0DGuOPz+VtUFrWlymUWoCwSXrbLpX9uMq/NzgtHj6RQa1wVsfw
564
+ Tz/oMp50ysiQVOnGXw94nZpAPA6sYapeFI+eh6FqUNzXmk6vBbOmcZSccbNQYArHE504B4YCqOmo
565
+ aSYYkKtMsE8jqzpPhNjfzp/haW+710LXa0Tkx63ubUFfclpxCDezeWWkWaCUN/cALw3CknLa0Dhy
566
+ 2xSoRcRdKn23tNbE7qzNE0S3ySvdQwAl+mG5aWpYIxG3pzOPVnVZ9c0p10a3CitlttNCbxWyuHv7
567
+ 7+ldU9U0WicCAwEAAaOB3DCB2TAdBgNVHQ4EFgQUrb2YejS0Jvf6xCZU7wO94CTLVBowCwYDVR0P
568
+ BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wgZkGA1UdIwSBkTCBjoAUrb2YejS0Jvf6xCZU7wO94CTL
569
+ VBqhc6RxMG8xCzAJBgNVBAYTAlNFMRQwEgYDVQQKEwtBZGRUcnVzdCBBQjEmMCQGA1UECxMdQWRk
570
+ VHJ1c3QgRXh0ZXJuYWwgVFRQIE5ldHdvcmsxIjAgBgNVBAMTGUFkZFRydXN0IEV4dGVybmFsIENB
571
+ IFJvb3SCAQEwDQYJKoZIhvcNAQEFBQADggEBALCb4IUlwtYj4g+WBpKdQZic2YR5gdkeWxQHIzZl
572
+ j7DYd7usQWxHYINRsPkyPef89iYTx4AWpb9a/IfPeHmJIZriTAcKhjW88t5RxNKWt9x+Tu5w/Rw5
573
+ 6wwCURQtjr0W4MHfRnXnJK3s9EK0hZNwEGe6nQY1ShjTK3rMUUKhemPR5ruhxSvCNr4TDea9Y355
574
+ e6cJDUCrat2PisP29owaQgVR1EX1n6diIWgVIEM8med8vSTYqZEXc4g/VhsxOBi0cQ+azcgOno4u
575
+ G+GMmIPLHzHxREzGBHNJdmAPx/i9F4BrLunMTA5amnkPIAou1Z5jJh5VkpTYghdae9C8x49OhgQ=
576
+ -----END CERTIFICATE-----
577
+
578
+ AddTrust Public Services Root
579
+ =============================
580
+ -----BEGIN CERTIFICATE-----
581
+ MIIEFTCCAv2gAwIBAgIBATANBgkqhkiG9w0BAQUFADBkMQswCQYDVQQGEwJTRTEUMBIGA1UEChML
582
+ QWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3b3JrMSAwHgYDVQQDExdBZGRU
583
+ cnVzdCBQdWJsaWMgQ0EgUm9vdDAeFw0wMDA1MzAxMDQxNTBaFw0yMDA1MzAxMDQxNTBaMGQxCzAJ
584
+ BgNVBAYTAlNFMRQwEgYDVQQKEwtBZGRUcnVzdCBBQjEdMBsGA1UECxMUQWRkVHJ1c3QgVFRQIE5l
585
+ dHdvcmsxIDAeBgNVBAMTF0FkZFRydXN0IFB1YmxpYyBDQSBSb290MIIBIjANBgkqhkiG9w0BAQEF
586
+ AAOCAQ8AMIIBCgKCAQEA6Rowj4OIFMEg2Dybjxt+A3S72mnTRqX4jsIMEZBRpS9mVEBV6tsfSlbu
587
+ nyNu9DnLoblv8n75XYcmYZ4c+OLspoH4IcUkzBEMP9smcnrHAZcHF/nXGCwwfQ56HmIexkvA/X1i
588
+ d9NEHif2P0tEs7c42TkfYNVRknMDtABp4/MUTu7R3AnPdzRGULD4EfL+OHn3Bzn+UZKXC1sIXzSG
589
+ Aa2Il+tmzV7R/9x98oTaunet3IAIx6eH1lWfl2royBFkuucZKT8Rs3iQhCBSWxHveNCD9tVIkNAw
590
+ HM+A+WD+eeSI8t0A65RF62WUaUC6wNW0uLp9BBGo6zEFlpROWCGOn9Bg/QIDAQABo4HRMIHOMB0G
591
+ A1UdDgQWBBSBPjfYkrAfd59ctKtzquf2NGAv+jALBgNVHQ8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB
592
+ /zCBjgYDVR0jBIGGMIGDgBSBPjfYkrAfd59ctKtzquf2NGAv+qFopGYwZDELMAkGA1UEBhMCU0Ux
593
+ FDASBgNVBAoTC0FkZFRydXN0IEFCMR0wGwYDVQQLExRBZGRUcnVzdCBUVFAgTmV0d29yazEgMB4G
594
+ A1UEAxMXQWRkVHJ1c3QgUHVibGljIENBIFJvb3SCAQEwDQYJKoZIhvcNAQEFBQADggEBAAP3FUr4
595
+ JNojVhaTdt02KLmuG7jD8WS6IBh4lSknVwW8fCr0uVFV2ocC3g8WFzH4qnkuCRO7r7IgGRLlk/lL
596
+ +YPoRNWyQSW/iHVv/xD8SlTQX/D67zZzfRs2RcYhbbQVuE7PnFylPVoAjgbjPGsye/Kf8Lb93/Ao
597
+ GEjwxrzQvzSAlsJKsW2Ox5BF3i9nrEUEo3rcVZLJR2bYGozH7ZxOmuASu7VqTITh4SINhwBk/ox9
598
+ Yjllpu9CtoAlEmEBqCQTcAARJl/6NVDFSMwGR+gn2HCNX2TmoUQmXiLsks3/QppEIW1cxeMiHV9H
599
+ EufOX1362KqxMy3ZdvJOOjMMK7MtkAY=
600
+ -----END CERTIFICATE-----
601
+
602
+ AddTrust Qualified Certificates Root
603
+ ====================================
604
+ -----BEGIN CERTIFICATE-----
605
+ MIIEHjCCAwagAwIBAgIBATANBgkqhkiG9w0BAQUFADBnMQswCQYDVQQGEwJTRTEUMBIGA1UEChML
606
+ QWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3b3JrMSMwIQYDVQQDExpBZGRU
607
+ cnVzdCBRdWFsaWZpZWQgQ0EgUm9vdDAeFw0wMDA1MzAxMDQ0NTBaFw0yMDA1MzAxMDQ0NTBaMGcx
608
+ CzAJBgNVBAYTAlNFMRQwEgYDVQQKEwtBZGRUcnVzdCBBQjEdMBsGA1UECxMUQWRkVHJ1c3QgVFRQ
609
+ IE5ldHdvcmsxIzAhBgNVBAMTGkFkZFRydXN0IFF1YWxpZmllZCBDQSBSb290MIIBIjANBgkqhkiG
610
+ 9w0BAQEFAAOCAQ8AMIIBCgKCAQEA5B6a/twJWoekn0e+EV+vhDTbYjx5eLfpMLXsDBwqxBb/4Oxx
611
+ 64r1EW7tTw2R0hIYLUkVAcKkIhPHEWT/IhKauY5cLwjPcWqzZwFZ8V1G87B4pfYOQnrjfxvM0PC3
612
+ KP0q6p6zsLkEqv32x7SxuCqg+1jxGaBvcCV+PmlKfw8i2O+tCBGaKZnhqkRFmhJePp1tUvznoD1o
613
+ L/BLcHwTOK28FSXx1s6rosAx1i+f4P8UWfyEk9mHfExUE+uf0S0R+Bg6Ot4l2ffTQO2kBhLEO+GR
614
+ wVY18BTcZTYJbqukB8c10cIDMzZbdSZtQvESa0NvS3GU+jQd7RNuyoB/mC9suWXY6QIDAQABo4HU
615
+ MIHRMB0GA1UdDgQWBBQ5lYtii1zJ1IC6WA+XPxUIQ8yYpzALBgNVHQ8EBAMCAQYwDwYDVR0TAQH/
616
+ BAUwAwEB/zCBkQYDVR0jBIGJMIGGgBQ5lYtii1zJ1IC6WA+XPxUIQ8yYp6FrpGkwZzELMAkGA1UE
617
+ BhMCU0UxFDASBgNVBAoTC0FkZFRydXN0IEFCMR0wGwYDVQQLExRBZGRUcnVzdCBUVFAgTmV0d29y
618
+ azEjMCEGA1UEAxMaQWRkVHJ1c3QgUXVhbGlmaWVkIENBIFJvb3SCAQEwDQYJKoZIhvcNAQEFBQAD
619
+ ggEBABmrder4i2VhlRO6aQTvhsoToMeqT2QbPxj2qC0sVY8FtzDqQmodwCVRLae/DLPt7wh/bDxG
620
+ GuoYQ992zPlmhpwsaPXpF/gxsxjE1kh9I0xowX67ARRvxdlu3rsEQmr49lx95dr6h+sNNVJn0J6X
621
+ dgWTP5XHAeZpVTh/EGGZyeNfpso+gmNIquIISD6q8rKFYqa0p9m9N5xotS1WfbC3P6CxB9bpT9ze
622
+ RXEwMn8bLgn5v1Kh7sKAPgZcLlVAwRv1cEWw3F369nJad9Jjzc9YiQBCYz95OdBEsIJuQRno3eDB
623
+ iFrRHnGTHyQwdOUeqN48Jzd/g66ed8/wMLH/S5noxqE=
624
+ -----END CERTIFICATE-----
625
+
626
+ Entrust Root Certification Authority
627
+ ====================================
628
+ -----BEGIN CERTIFICATE-----
629
+ MIIEkTCCA3mgAwIBAgIERWtQVDANBgkqhkiG9w0BAQUFADCBsDELMAkGA1UEBhMCVVMxFjAUBgNV
630
+ BAoTDUVudHJ1c3QsIEluYy4xOTA3BgNVBAsTMHd3dy5lbnRydXN0Lm5ldC9DUFMgaXMgaW5jb3Jw
631
+ b3JhdGVkIGJ5IHJlZmVyZW5jZTEfMB0GA1UECxMWKGMpIDIwMDYgRW50cnVzdCwgSW5jLjEtMCsG
632
+ A1UEAxMkRW50cnVzdCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA2MTEyNzIwMjM0
633
+ MloXDTI2MTEyNzIwNTM0MlowgbAxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1FbnRydXN0LCBJbmMu
634
+ MTkwNwYDVQQLEzB3d3cuZW50cnVzdC5uZXQvQ1BTIGlzIGluY29ycG9yYXRlZCBieSByZWZlcmVu
635
+ Y2UxHzAdBgNVBAsTFihjKSAyMDA2IEVudHJ1c3QsIEluYy4xLTArBgNVBAMTJEVudHJ1c3QgUm9v
636
+ dCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
637
+ ALaVtkNC+sZtKm9I35RMOVcF7sN5EUFoNu3s/poBj6E4KPz3EEZmLk0eGrEaTsbRwJWIsMn/MYsz
638
+ A9u3g3s+IIRe7bJWKKf44LlAcTfFy0cOlypowCKVYhXbR9n10Cv/gkvJrT7eTNuQgFA/CYqEAOww
639
+ Cj0Yzfv9KlmaI5UXLEWeH25DeW0MXJj+SKfFI0dcXv1u5x609mhF0YaDW6KKjbHjKYD+JXGIrb68
640
+ j6xSlkuqUY3kEzEZ6E5Nn9uss2rVvDlUccp6en+Q3X0dgNmBu1kmwhH+5pPi94DkZfs0Nw4pgHBN
641
+ rziGLp5/V6+eF67rHMsoIV+2HNjnogQi+dPa2MsCAwEAAaOBsDCBrTAOBgNVHQ8BAf8EBAMCAQYw
642
+ DwYDVR0TAQH/BAUwAwEB/zArBgNVHRAEJDAigA8yMDA2MTEyNzIwMjM0MlqBDzIwMjYxMTI3MjA1
643
+ MzQyWjAfBgNVHSMEGDAWgBRokORnpKZTgMeGZqTx90tD+4S9bTAdBgNVHQ4EFgQUaJDkZ6SmU4DH
644
+ hmak8fdLQ/uEvW0wHQYJKoZIhvZ9B0EABBAwDhsIVjcuMTo0LjADAgSQMA0GCSqGSIb3DQEBBQUA
645
+ A4IBAQCT1DCw1wMgKtD5Y+iRDAUgqV8ZyntyTtSx29CW+1RaGSwMCPeyvIWonX9tO1KzKtvn1ISM
646
+ Y/YPyyYBkVBs9F8U4pN0wBOeMDpQ47RgxRzwIkSNcUesyBrJ6ZuaAGAT/3B+XxFNSRuzFVJ7yVTa
647
+ v52Vr2ua2J7p8eRDjeIRRDq/r72DQnNSi6q7pynP9WQcCk3RvKqsnyrQ/39/2n3qse0wJcGE2jTS
648
+ W3iDVuycNsMm4hH2Z0kdkquM++v/eu6FSqdQgPCnXEqULl8FmTxSQeDNtGPPAUO6nIPcj2A781q0
649
+ tHuu2guQOHXvgR1m0vdXcDazv/wor3ElhVsT/h5/WrQ8
650
+ -----END CERTIFICATE-----
651
+
652
+ RSA Security 2048 v3
653
+ ====================
654
+ -----BEGIN CERTIFICATE-----
655
+ MIIDYTCCAkmgAwIBAgIQCgEBAQAAAnwAAAAKAAAAAjANBgkqhkiG9w0BAQUFADA6MRkwFwYDVQQK
656
+ ExBSU0EgU2VjdXJpdHkgSW5jMR0wGwYDVQQLExRSU0EgU2VjdXJpdHkgMjA0OCBWMzAeFw0wMTAy
657
+ MjIyMDM5MjNaFw0yNjAyMjIyMDM5MjNaMDoxGTAXBgNVBAoTEFJTQSBTZWN1cml0eSBJbmMxHTAb
658
+ BgNVBAsTFFJTQSBTZWN1cml0eSAyMDQ4IFYzMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC
659
+ AQEAt49VcdKA3XtpeafwGFAyPGJn9gqVB93mG/Oe2dJBVGutn3y+Gc37RqtBaB4Y6lXIL5F4iSj7
660
+ Jylg/9+PjDvJSZu1pJTOAeo+tWN7fyb9Gd3AIb2E0S1PRsNO3Ng3OTsor8udGuorryGlwSMiuLgb
661
+ WhOHV4PR8CDn6E8jQrAApX2J6elhc5SYcSa8LWrg903w8bYqODGBDSnhAMFRD0xS+ARaqn1y07iH
662
+ KrtjEAMqs6FPDVpeRrc9DvV07Jmf+T0kgYim3WBU6JU2PcYJk5qjEoAAVZkZR73QpXzDuvsf9/UP
663
+ +Ky5tfQ3mBMY3oVbtwyCO4dvlTlYMNpuAWgXIszACwIDAQABo2MwYTAPBgNVHRMBAf8EBTADAQH/
664
+ MA4GA1UdDwEB/wQEAwIBBjAfBgNVHSMEGDAWgBQHw1EwpKrpRa41JPr/JCwz0LGdjDAdBgNVHQ4E
665
+ FgQUB8NRMKSq6UWuNST6/yQsM9CxnYwwDQYJKoZIhvcNAQEFBQADggEBAF8+hnZuuDU8TjYcHnmY
666
+ v/3VEhF5Ug7uMYm83X/50cYVIeiKAVQNOvtUudZj1LGqlk2iQk3UUx+LEN5/Zb5gEydxiKRz44Rj
667
+ 0aRV4VCT5hsOedBnvEbIvz8XDZXmxpBp3ue0L96VfdASPz0+f00/FGj1EVDVwfSQpQgdMWD/YIwj
668
+ VAqv/qFuxdF6Kmh4zx6CCiC0H63lhbJqaHVOrSU3lIW+vaHU6rcMSzyd6BIA8F+sDeGscGNz9395
669
+ nzIlQnQFgCi/vcEkllgVsRch6YlL2weIZ/QVrXA+L02FO8K32/6YaCOJ4XQP3vTFhGMpG8zLB8kA
670
+ pKnXwiJPZ9d37CAFYd4=
671
+ -----END CERTIFICATE-----
672
+
673
+ GeoTrust Global CA
674
+ ==================
675
+ -----BEGIN CERTIFICATE-----
676
+ MIIDVDCCAjygAwIBAgIDAjRWMA0GCSqGSIb3DQEBBQUAMEIxCzAJBgNVBAYTAlVTMRYwFAYDVQQK
677
+ Ew1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9iYWwgQ0EwHhcNMDIwNTIxMDQw
678
+ MDAwWhcNMjIwNTIxMDQwMDAwWjBCMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5j
679
+ LjEbMBkGA1UEAxMSR2VvVHJ1c3QgR2xvYmFsIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
680
+ CgKCAQEA2swYYzD99BcjGlZ+W988bDjkcbd4kdS8odhM+KhDtgPpTSEHCIjaWC9mOSm9BXiLnTjo
681
+ BbdqfnGk5sRgprDvgOSJKA+eJdbtg/OtppHHmMlCGDUUna2YRpIuT8rxh0PBFpVXLVDviS2Aelet
682
+ 8u5fa9IAjbkU+BQVNdnARqN7csiRv8lVK83Qlz6cJmTM386DGXHKTubU1XupGc1V3sjs0l44U+Vc
683
+ T4wt/lAjNvxm5suOpDkZALeVAjmRCw7+OC7RHQWa9k0+bw8HHa8sHo9gOeL6NlMTOdReJivbPagU
684
+ vTLrGAMoUgRx5aszPeE4uwc2hGKceeoWMPRfwCvocWvk+QIDAQABo1MwUTAPBgNVHRMBAf8EBTAD
685
+ AQH/MB0GA1UdDgQWBBTAephojYn7qwVkDBF9qn1luMrMTjAfBgNVHSMEGDAWgBTAephojYn7qwVk
686
+ DBF9qn1luMrMTjANBgkqhkiG9w0BAQUFAAOCAQEANeMpauUvXVSOKVCUn5kaFOSPeCpilKInZ57Q
687
+ zxpeR+nBsqTP3UEaBU6bS+5Kb1VSsyShNwrrZHYqLizz/Tt1kL/6cdjHPTfStQWVYrmm3ok9Nns4
688
+ d0iXrKYgjy6myQzCsplFAMfOEVEiIuCl6rYVSAlk6l5PdPcFPseKUgzbFbS9bZvlxrFUaKnjaZC2
689
+ mqUPuLk/IH2uSrW4nOQdtqvmlKXBx4Ot2/Unhw4EbNX/3aBd7YdStysVAq45pmp06drE57xNNB6p
690
+ XE0zX5IJL4hmXXeXxx12E6nV5fEWCRE11azbJHFwLJhWC9kXtNHjUStedejV0NxPNO3CBWaAocvm
691
+ Mw==
692
+ -----END CERTIFICATE-----
693
+
694
+ GeoTrust Global CA 2
695
+ ====================
696
+ -----BEGIN CERTIFICATE-----
697
+ MIIDZjCCAk6gAwIBAgIBATANBgkqhkiG9w0BAQUFADBEMQswCQYDVQQGEwJVUzEWMBQGA1UEChMN
698
+ R2VvVHJ1c3QgSW5jLjEdMBsGA1UEAxMUR2VvVHJ1c3QgR2xvYmFsIENBIDIwHhcNMDQwMzA0MDUw
699
+ MDAwWhcNMTkwMzA0MDUwMDAwWjBEMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5j
700
+ LjEdMBsGA1UEAxMUR2VvVHJ1c3QgR2xvYmFsIENBIDIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw
701
+ ggEKAoIBAQDvPE1APRDfO1MA4Wf+lGAVPoWI8YkNkMgoI5kF6CsgncbzYEbYwbLVjDHZ3CB5JIG/
702
+ NTL8Y2nbsSpr7iFY8gjpeMtvy/wWUsiRxP89c96xPqfCfWbB9X5SJBri1WeR0IIQ13hLTytCOb1k
703
+ LUCgsBDTOEhGiKEMuzozKmKY+wCdE1l/bztyqu6mD4b5BWHqZ38MN5aL5mkWRxHCJ1kDs6ZgwiFA
704
+ Vvqgx306E+PsV8ez1q6diYD3Aecs9pYrEw15LNnA5IZ7S4wMcoKK+xfNAGw6EzywhIdLFnopsk/b
705
+ HdQL82Y3vdj2V7teJHq4PIu5+pIaGoSe2HSPqht/XvT+RSIhAgMBAAGjYzBhMA8GA1UdEwEB/wQF
706
+ MAMBAf8wHQYDVR0OBBYEFHE4NvICMVNHK266ZUapEBVYIAUJMB8GA1UdIwQYMBaAFHE4NvICMVNH
707
+ K266ZUapEBVYIAUJMA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQUFAAOCAQEAA/e1K6tdEPx7
708
+ srJerJsOflN4WT5CBP51o62sgU7XAotexC3IUnbHLB/8gTKY0UvGkpMzNTEv/NgdRN3ggX+d6Yvh
709
+ ZJFiCzkIjKx0nVnZellSlxG5FntvRdOW2TF9AjYPnDtuzywNA0ZF66D0f0hExghAzN4bcLUprbqL
710
+ OzRldRtxIR0sFAqwlpW41uryZfspuk/qkZN0abby/+Ea0AzRdoXLiiW9l14sbxWZJue2Kf8i7MkC
711
+ x1YAzUm5s2x7UwQa4qjJqhIFI8LO57sEAszAR6LkxCkvW0VXiVHuPOtSCP8HNR6fNWpHSlaY0VqF
712
+ H4z1Ir+rzoPz4iIprn2DQKi6bA==
713
+ -----END CERTIFICATE-----
714
+
715
+ GeoTrust Universal CA
716
+ =====================
717
+ -----BEGIN CERTIFICATE-----
718
+ MIIFaDCCA1CgAwIBAgIBATANBgkqhkiG9w0BAQUFADBFMQswCQYDVQQGEwJVUzEWMBQGA1UEChMN
719
+ R2VvVHJ1c3QgSW5jLjEeMBwGA1UEAxMVR2VvVHJ1c3QgVW5pdmVyc2FsIENBMB4XDTA0MDMwNDA1
720
+ MDAwMFoXDTI5MDMwNDA1MDAwMFowRTELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IElu
721
+ Yy4xHjAcBgNVBAMTFUdlb1RydXN0IFVuaXZlcnNhbCBDQTCCAiIwDQYJKoZIhvcNAQEBBQADggIP
722
+ ADCCAgoCggIBAKYVVaCjxuAfjJ0hUNfBvitbtaSeodlyWL0AG0y/YckUHUWCq8YdgNY96xCcOq9t
723
+ JPi8cQGeBvV8Xx7BDlXKg5pZMK4ZyzBIle0iN430SppyZj6tlcDgFgDgEB8rMQ7XlFTTQjOgNB0e
724
+ RXbdT8oYN+yFFXoZCPzVx5zw8qkuEKmS5j1YPakWaDwvdSEYfyh3peFhF7em6fgemdtzbvQKoiFs
725
+ 7tqqhZJmr/Z6a4LauiIINQ/PQvE1+mrufislzDoR5G2vc7J2Ha3QsnhnGqQ5HFELZ1aD/ThdDc7d
726
+ 8Lsrlh/eezJS/R27tQahsiFepdaVaH/wmZ7cRQg+59IJDTWU3YBOU5fXtQlEIGQWFwMCTFMNaN7V
727
+ qnJNk22CDtucvc+081xdVHppCZbW2xHBjXWotM85yM48vCR85mLK4b19p71XZQvk/iXttmkQ3Cga
728
+ Rr0BHdCXteGYO8A3ZNY9lO4L4fUorgtWv3GLIylBjobFS1J72HGrH4oVpjuDWtdYAVHGTEHZf9hB
729
+ Z3KiKN9gg6meyHv8U3NyWfWTehd2Ds735VzZC1U0oqpbtWpU5xPKV+yXbfReBi9Fi1jUIxaS5BZu
730
+ KGNZMN9QAZxjiRqf2xeUgnA3wySemkfWWspOqGmJch+RbNt+nhutxx9z3SxPGWX9f5NAEC7S8O08
731
+ ni4oPmkmM8V7AgMBAAGjYzBhMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFNq7LqqwDLiIJlF0
732
+ XG0D08DYj3rWMB8GA1UdIwQYMBaAFNq7LqqwDLiIJlF0XG0D08DYj3rWMA4GA1UdDwEB/wQEAwIB
733
+ hjANBgkqhkiG9w0BAQUFAAOCAgEAMXjmx7XfuJRAyXHEqDXsRh3ChfMoWIawC/yOsjmPRFWrZIRc
734
+ aanQmjg8+uUfNeVE44B5lGiku8SfPeE0zTBGi1QrlaXv9z+ZhP015s8xxtxqv6fXIwjhmF7DWgh2
735
+ qaavdy+3YL1ERmrvl/9zlcGO6JP7/TG37FcREUWbMPEaiDnBTzynANXH/KttgCJwpQzgXQQpAvvL
736
+ oJHRfNbDflDVnVi+QTjruXU8FdmbyUqDWcDaU/0zuzYYm4UPFd3uLax2k7nZAY1IEKj79TiG8dsK
737
+ xr2EoyNB3tZ3b4XUhRxQ4K5RirqNPnbiucon8l+f725ZDQbYKxek0nxru18UGkiPGkzns0ccjkxF
738
+ KyDuSN/n3QmOGKjaQI2SJhFTYXNd673nxE0pN2HrrDktZy4W1vUAg4WhzH92xH3kt0tm7wNFYGm2
739
+ DFKWkoRepqO1pD4r2czYG0eq8kTaT/kD6PAUyz/zg97QwVTjt+gKN02LIFkDMBmhLMi9ER/frslK
740
+ xfMnZmaGrGiR/9nmUxwPi1xpZQomyB40w11Re9epnAahNt3ViZS82eQtDF4JbAiXfKM9fJP/P6EU
741
+ p8+1Xevb2xzEdt+Iub1FBZUbrvxGakyvSOPOrg/SfuvmbJxPgWp6ZKy7PtXny3YuxadIwVyQD8vI
742
+ P/rmMuGNG2+k5o7Y+SlIis5z/iw=
743
+ -----END CERTIFICATE-----
744
+
745
+ GeoTrust Universal CA 2
746
+ =======================
747
+ -----BEGIN CERTIFICATE-----
748
+ MIIFbDCCA1SgAwIBAgIBATANBgkqhkiG9w0BAQUFADBHMQswCQYDVQQGEwJVUzEWMBQGA1UEChMN
749
+ R2VvVHJ1c3QgSW5jLjEgMB4GA1UEAxMXR2VvVHJ1c3QgVW5pdmVyc2FsIENBIDIwHhcNMDQwMzA0
750
+ MDUwMDAwWhcNMjkwMzA0MDUwMDAwWjBHMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3Qg
751
+ SW5jLjEgMB4GA1UEAxMXR2VvVHJ1c3QgVW5pdmVyc2FsIENBIDIwggIiMA0GCSqGSIb3DQEBAQUA
752
+ A4ICDwAwggIKAoICAQCzVFLByT7y2dyxUxpZKeexw0Uo5dfR7cXFS6GqdHtXr0om/Nj1XqduGdt0
753
+ DE81WzILAePb63p3NeqqWuDW6KFXlPCQo3RWlEQwAx5cTiuFJnSCegx2oG9NzkEtoBUGFF+3Qs17
754
+ j1hhNNwqCPkuwwGmIkQcTAeC5lvO0Ep8BNMZcyfwqph/Lq9O64ceJHdqXbboW0W63MOhBW9Wjo8Q
755
+ JqVJwy7XQYci4E+GymC16qFjwAGXEHm9ADwSbSsVsaxLse4YuU6W3Nx2/zu+z18DwPw76L5GG//a
756
+ QMJS9/7jOvdqdzXQ2o3rXhhqMcceujwbKNZrVMaqW9eiLBsZzKIC9ptZvTdrhrVtgrrY6slWvKk2
757
+ WP0+GfPtDCapkzj4T8FdIgbQl+rhrcZV4IErKIM6+vR7IVEAvlI4zs1meaj0gVbi0IMJR1FbUGrP
758
+ 20gaXT73y/Zl92zxlfgCOzJWgjl6W70viRu/obTo/3+NjN8D8WBOWBFM66M/ECuDmgFz2ZRthAAn
759
+ ZqzwcEAJQpKtT5MNYQlRJNiS1QuUYbKHsu3/mjX/hVTK7URDrBs8FmtISgocQIgfksILAAX/8sgC
760
+ SqSqqcyZlpwvWOB94b67B9xfBHJcMTTD7F8t4D1kkCLm0ey4Lt1ZrtmhN79UNdxzMk+MBB4zsslG
761
+ 8dhcyFVQyWi9qLo2CQIDAQABo2MwYTAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBR281Xh+qQ2
762
+ +/CfXGJx7Tz0RzgQKzAfBgNVHSMEGDAWgBR281Xh+qQ2+/CfXGJx7Tz0RzgQKzAOBgNVHQ8BAf8E
763
+ BAMCAYYwDQYJKoZIhvcNAQEFBQADggIBAGbBxiPz2eAubl/oz66wsCVNK/g7WJtAJDday6sWSf+z
764
+ dXkzoS9tcBc0kf5nfo/sm+VegqlVHy/c1FEHEv6sFj4sNcZj/NwQ6w2jqtB8zNHQL1EuxBRa3ugZ
765
+ 4T7GzKQp5y6EqgYweHZUcyiYWTjgAA1i00J9IZ+uPTqM1fp3DRgrFg5fNuH8KrUwJM/gYwx7WBr+
766
+ mbpCErGR9Hxo4sjoryzqyX6uuyo9DRXcNJW2GHSoag/HtPQTxORb7QrSpJdMKu0vbBKJPfEncKpq
767
+ A1Ihn0CoZ1Dy81of398j9tx4TuaYT1U6U+Pv8vSfx3zYWK8pIpe44L2RLrB27FcRz+8pRPPphXpg
768
+ Y+RdM4kX2TGq2tbzGDVyz4crL2MjhF2EjD9XoIj8mZEoJmmZ1I+XRL6O1UixpCgp8RW04eWe3fiP
769
+ pm8m1wk8OhwRDqZsN/etRIcsKMfYdIKz0G9KV7s1KSegi+ghp4dkNl3M2Basx7InQJJVOCiNUW7d
770
+ FGdTbHFcJoRNdVq2fmBWqU2t+5sel/MN2dKXVHfaPRK34B7vCAas+YWH6aLcr34YEoP9VhdBLtUp
771
+ gn2Z9DH2canPLAEnpQW5qrJITirvn5NSUZU8UnOOVkwXQMAJKOSLakhT2+zNVVXxxvjpoixMptEm
772
+ X36vWkzaH6byHCx+rgIW0lbQL1dTR+iS
773
+ -----END CERTIFICATE-----
774
+
775
+ UTN-USER First-Network Applications
776
+ ===================================
777
+ -----BEGIN CERTIFICATE-----
778
+ MIIEZDCCA0ygAwIBAgIQRL4Mi1AAJLQR0zYwS8AzdzANBgkqhkiG9w0BAQUFADCBozELMAkGA1UE
779
+ BhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2UgQ2l0eTEeMBwGA1UEChMVVGhl
780
+ IFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExhodHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xKzAp
781
+ BgNVBAMTIlVUTi1VU0VSRmlyc3QtTmV0d29yayBBcHBsaWNhdGlvbnMwHhcNOTkwNzA5MTg0ODM5
782
+ WhcNMTkwNzA5MTg1NzQ5WjCBozELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5T
783
+ YWx0IExha2UgQ2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExho
784
+ dHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xKzApBgNVBAMTIlVUTi1VU0VSRmlyc3QtTmV0d29yayBB
785
+ cHBsaWNhdGlvbnMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCz+5Gh5DZVhawGNFug
786
+ mliy+LUPBXeDrjKxdpJo7CNKyXY/45y2N3kDuatpjQclthln5LAbGHNhSuh+zdMvZOOmfAz6F4Cj
787
+ DUeJT1FxL+78P/m4FoCHiZMlIJpDgmkkdihZNaEdwH+DBmQWICzTSaSFtMBhf1EI+GgVkYDLpdXu
788
+ Ozr0hAReYFmnjDRy7rh4xdE7EkpvfmUnuaRVxblvQ6TFHSyZwFKkeEwVs0CYCGtDxgGwenv1axwi
789
+ P8vv/6jQOkt2FZ7S0cYu49tXGzKiuG/ohqY/cKvlcJKrRB5AUPuco2LkbG6gyN7igEL66S/ozjIE
790
+ j3yNtxyjNTwV3Z7DrpelAgMBAAGjgZEwgY4wCwYDVR0PBAQDAgHGMA8GA1UdEwEB/wQFMAMBAf8w
791
+ HQYDVR0OBBYEFPqGydvguul49Uuo1hXf8NPhahQ8ME8GA1UdHwRIMEYwRKBCoECGPmh0dHA6Ly9j
792
+ cmwudXNlcnRydXN0LmNvbS9VVE4tVVNFUkZpcnN0LU5ldHdvcmtBcHBsaWNhdGlvbnMuY3JsMA0G
793
+ CSqGSIb3DQEBBQUAA4IBAQCk8yXM0dSRgyLQzDKrm5ZONJFUICU0YV8qAhXhi6r/fWRRzwr/vH3Y
794
+ IWp4yy9Rb/hCHTO967V7lMPDqaAt39EpHx3+jz+7qEUqf9FuVSTiuwL7MT++6LzsQCv4AdRWOOTK
795
+ RIK1YSAhZ2X28AvnNPilwpyjXEAfhZOVBt5P1CeptqX8Fs1zMT+4ZSfP1FMa8Kxun08FDAOBp4Qp
796
+ xFq9ZFdyrTvPNximmMatBrTcCKME1SmklpoSZ0qMYEWd8SOasACcaLWYUNPvji6SZbFIPiG+FTAq
797
+ DbUMo2s/rn9X9R+WfN9v3YIwLGUbQErNaLly7HF27FSOH4UMAWr6pjisH8SE
798
+ -----END CERTIFICATE-----
799
+
800
+ America Online Root Certification Authority 1
801
+ =============================================
802
+ -----BEGIN CERTIFICATE-----
803
+ MIIDpDCCAoygAwIBAgIBATANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEcMBoGA1UEChMT
804
+ QW1lcmljYSBPbmxpbmUgSW5jLjE2MDQGA1UEAxMtQW1lcmljYSBPbmxpbmUgUm9vdCBDZXJ0aWZp
805
+ Y2F0aW9uIEF1dGhvcml0eSAxMB4XDTAyMDUyODA2MDAwMFoXDTM3MTExOTIwNDMwMFowYzELMAkG
806
+ A1UEBhMCVVMxHDAaBgNVBAoTE0FtZXJpY2EgT25saW5lIEluYy4xNjA0BgNVBAMTLUFtZXJpY2Eg
807
+ T25saW5lIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgMTCCASIwDQYJKoZIhvcNAQEBBQAD
808
+ ggEPADCCAQoCggEBAKgv6KRpBgNHw+kqmP8ZonCaxlCyfqXfaE0bfA+2l2h9LaaLl+lkhsmj76CG
809
+ v2BlnEtUiMJIxUo5vxTjWVXlGbR0yLQFOVwWpeKVBeASrlmLojNoWBym1BW32J/X3HGrfpq/m44z
810
+ DyL9Hy7nBzbvYjnF3cu6JRQj3gzGPTzOggjmZj7aUTsWOqMFf6Dch9Wc/HKpoH145LcxVR5lu9Rh
811
+ sCFg7RAycsWSJR74kEoYeEfffjA3PlAb2xzTa5qGUwew76wGePiEmf4hjUyAtgyC9mZweRrTT6PP
812
+ 8c9GsEsPPt2IYriMqQkoO3rHl+Ee5fSfwMCuJKDIodkP1nsmgmkyPacCAwEAAaNjMGEwDwYDVR0T
813
+ AQH/BAUwAwEB/zAdBgNVHQ4EFgQUAK3Zo/Z59m50qX8zPYEX10zPM94wHwYDVR0jBBgwFoAUAK3Z
814
+ o/Z59m50qX8zPYEX10zPM94wDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEBBQUAA4IBAQB8itEf
815
+ GDeC4Liwo+1WlchiYZwFos3CYiZhzRAW18y0ZTTQEYqtqKkFZu90821fnZmv9ov761KyBZiibyrF
816
+ VL0lvV+uyIbqRizBs73B6UlwGBaXCBOMIOAbLjpHyx7kADCVW/RFo8AasAFOq73AI25jP4BKxQft
817
+ 3OJvx8Fi8eNy1gTIdGcL+oiroQHIb/AUr9KZzVGTfu0uOMe9zkZQPXLjeSWdm4grECDdpbgyn43g
818
+ Kd8hdIaC2y+CMMbHNYaz+ZZfRtsMRf3zUMNvxsNIrUam4SdHCh0Om7bCd39j8uB9Gr784N/Xx6ds
819
+ sPmuujz9dLQR6FgNgLzTqIA6me11zEZ7
820
+ -----END CERTIFICATE-----
821
+
822
+ America Online Root Certification Authority 2
823
+ =============================================
824
+ -----BEGIN CERTIFICATE-----
825
+ MIIFpDCCA4ygAwIBAgIBATANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEcMBoGA1UEChMT
826
+ QW1lcmljYSBPbmxpbmUgSW5jLjE2MDQGA1UEAxMtQW1lcmljYSBPbmxpbmUgUm9vdCBDZXJ0aWZp
827
+ Y2F0aW9uIEF1dGhvcml0eSAyMB4XDTAyMDUyODA2MDAwMFoXDTM3MDkyOTE0MDgwMFowYzELMAkG
828
+ A1UEBhMCVVMxHDAaBgNVBAoTE0FtZXJpY2EgT25saW5lIEluYy4xNjA0BgNVBAMTLUFtZXJpY2Eg
829
+ T25saW5lIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgMjCCAiIwDQYJKoZIhvcNAQEBBQAD
830
+ ggIPADCCAgoCggIBAMxBRR3pPU0Q9oyxQcngXssNt79Hc9PwVU3dxgz6sWYFas14tNwC206B89en
831
+ fHG8dWOgXeMHDEjsJcQDIPT/DjsS/5uN4cbVG7RtIuOx238hZK+GvFciKtZHgVdEglZTvYYUAQv8
832
+ f3SkWq7xuhG1m1hagLQ3eAkzfDJHA1zEpYNI9FdWboE2JxhP7JsowtS013wMPgwr38oE18aO6lhO
833
+ qKSlGBxsRZijQdEt0sdtjRnxrXm3gT+9BoInLRBYBbV4Bbkv2wxrkJB+FFk4u5QkE+XRnRTf04JN
834
+ RvCAOVIyD+OEsnpD8l7eXz8d3eOyG6ChKiMDbi4BFYdcpnV1x5dhvt6G3NRI270qv0pV2uh9UPu0
835
+ gBe4lL8BPeraunzgWGcXuVjgiIZGZ2ydEEdYMtA1fHkqkKJaEBEjNa0vzORKW6fIJ/KD3l67Xnfn
836
+ 6KVuY8INXWHQjNJsWiEOyiijzirplcdIz5ZvHZIlyMbGwcEMBawmxNJ10uEqZ8A9W6Wa6897Gqid
837
+ FEXlD6CaZd4vKL3Ob5Rmg0gp2OpljK+T2WSfVVcmv2/LNzGZo2C7HK2JNDJiuEMhBnIMoVxtRsX6
838
+ Kc8w3onccVvdtjc+31D1uAclJuW8tf48ArO3+L5DwYcRlJ4jbBeKuIonDFRH8KmzwICMoCfrHRnj
839
+ B453cMor9H124HhnAgMBAAGjYzBhMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFE1FwWg4u3Op
840
+ aaEg5+31IqEjFNeeMB8GA1UdIwQYMBaAFE1FwWg4u3OpaaEg5+31IqEjFNeeMA4GA1UdDwEB/wQE
841
+ AwIBhjANBgkqhkiG9w0BAQUFAAOCAgEAZ2sGuV9FOypLM7PmG2tZTiLMubekJcmnxPBUlgtk87FY
842
+ T15R/LKXeydlwuXK5w0MJXti4/qftIe3RUavg6WXSIylvfEWK5t2LHo1YGwRgJfMqZJS5ivmae2p
843
+ +DYtLHe/YUjRYwu5W1LtGLBDQiKmsXeu3mnFzcccobGlHBD7GL4acN3Bkku+KVqdPzW+5X1R+FXg
844
+ JXUjhx5c3LqdsKyzadsXg8n33gy8CNyRnqjQ1xU3c6U1uPx+xURABsPr+CKAXEfOAuMRn0T//Zoy
845
+ zH1kUQ7rVyZ2OuMeIjzCpjbdGe+n/BLzJsBZMYVMnNjP36TMzCmT/5RtdlwTCJfy7aULTd3oyWgO
846
+ ZtMADjMSW7yV5TKQqLPGbIOtd+6Lfn6xqavT4fG2wLHqiMDn05DpKJKUe2h7lyoKZy2FAjgQ5ANh
847
+ 1NolNscIWC2hp1GvMApJ9aZphwctREZ2jirlmjvXGKL8nDgQzMY70rUXOm/9riW99XJZZLF0Kjhf
848
+ GEzfz3EEWjbUvy+ZnOjZurGV5gJLIaFb1cFPj65pbVPbAZO1XB4Y3WRayhgoPmMEEf0cjQAPuDff
849
+ Z4qdZqkCapH/E8ovXYO8h5Ns3CRRFgQlZvqz2cK6Kb6aSDiCmfS/O0oxGfm/jiEzFMpPVF/7zvuP
850
+ cX/9XhmgD0uRuMRUvAawRY8mkaKO/qk=
851
+ -----END CERTIFICATE-----
852
+
853
+ Visa eCommerce Root
854
+ ===================
855
+ -----BEGIN CERTIFICATE-----
856
+ MIIDojCCAoqgAwIBAgIQE4Y1TR0/BvLB+WUF1ZAcYjANBgkqhkiG9w0BAQUFADBrMQswCQYDVQQG
857
+ EwJVUzENMAsGA1UEChMEVklTQTEvMC0GA1UECxMmVmlzYSBJbnRlcm5hdGlvbmFsIFNlcnZpY2Ug
858
+ QXNzb2NpYXRpb24xHDAaBgNVBAMTE1Zpc2EgZUNvbW1lcmNlIFJvb3QwHhcNMDIwNjI2MDIxODM2
859
+ WhcNMjIwNjI0MDAxNjEyWjBrMQswCQYDVQQGEwJVUzENMAsGA1UEChMEVklTQTEvMC0GA1UECxMm
860
+ VmlzYSBJbnRlcm5hdGlvbmFsIFNlcnZpY2UgQXNzb2NpYXRpb24xHDAaBgNVBAMTE1Zpc2EgZUNv
861
+ bW1lcmNlIFJvb3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvV95WHm6h2mCxlCfL
862
+ F9sHP4CFT8icttD0b0/Pmdjh28JIXDqsOTPHH2qLJj0rNfVIsZHBAk4ElpF7sDPwsRROEW+1QK8b
863
+ RaVK7362rPKgH1g/EkZgPI2h4H3PVz4zHvtH8aoVlwdVZqW1LS7YgFmypw23RuwhY/81q6UCzyr0
864
+ TP579ZRdhE2o8mCP2w4lPJ9zcc+U30rq299yOIzzlr3xF7zSujtFWsan9sYXiwGd/BmoKoMWuDpI
865
+ /k4+oKsGGelT84ATB+0tvz8KPFUgOSwsAGl0lUq8ILKpeeUYiZGo3BxN77t+Nwtd/jmliFKMAGzs
866
+ GHxBvfaLdXe6YJ2E5/4tAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEG
867
+ MB0GA1UdDgQWBBQVOIMPPyw/cDMezUb+B4wg4NfDtzANBgkqhkiG9w0BAQUFAAOCAQEAX/FBfXxc
868
+ CLkr4NWSR/pnXKUTwwMhmytMiUbPWU3J/qVAtmPN3XEolWcRzCSs00Rsca4BIGsDoo8Ytyk6feUW
869
+ YFN4PMCvFYP3j1IzJL1kk5fui/fbGKhtcbP3LBfQdCVp9/5rPJS+TUtBjE7ic9DjkCJzQ83z7+pz
870
+ zkWKsKZJ/0x9nXGIxHYdkFsd7v3M9+79YKWxehZx0RbQfBI8bGmX265fOZpwLwU8GUYEmSA20GBu
871
+ YQa7FkKMcPcw++DbZqMAAb3mLNqRX6BGi01qnD093QVG/na/oAo85ADmJ7f/hC3euiInlhBx6yLt
872
+ 398znM/jra6O1I7mT1GvFpLgXPYHDw==
873
+ -----END CERTIFICATE-----
874
+
875
+ Certum Root CA
876
+ ==============
877
+ -----BEGIN CERTIFICATE-----
878
+ MIIDDDCCAfSgAwIBAgIDAQAgMA0GCSqGSIb3DQEBBQUAMD4xCzAJBgNVBAYTAlBMMRswGQYDVQQK
879
+ ExJVbml6ZXRvIFNwLiB6IG8uby4xEjAQBgNVBAMTCUNlcnR1bSBDQTAeFw0wMjA2MTExMDQ2Mzla
880
+ Fw0yNzA2MTExMDQ2MzlaMD4xCzAJBgNVBAYTAlBMMRswGQYDVQQKExJVbml6ZXRvIFNwLiB6IG8u
881
+ by4xEjAQBgNVBAMTCUNlcnR1bSBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAM6x
882
+ wS7TT3zNJc4YPk/EjG+AanPIW1H4m9LcuwBcsaD8dQPugfCI7iNS6eYVM42sLQnFdvkrOYCJ5JdL
883
+ kKWoePhzQ3ukYbDYWMzhbGZ+nPMJXlVjhNWo7/OxLjBos8Q82KxujZlakE403Daaj4GIULdtlkIJ
884
+ 89eVgw1BS7Bqa/j8D35in2fE7SZfECYPCE/wpFcozo+47UX2bu4lXapuOb7kky/ZR6By6/qmW6/K
885
+ Uz/iDsaWVhFu9+lmqSbYf5VT7QqFiLpPKaVCjF62/IUgAKpoC6EahQGcxEZjgoi2IrHu/qpGWX7P
886
+ NSzVttpd90gzFFS269lvzs2I1qsb2pY7HVkCAwEAAaMTMBEwDwYDVR0TAQH/BAUwAwEB/zANBgkq
887
+ hkiG9w0BAQUFAAOCAQEAuI3O7+cUus/usESSbLQ5PqKEbq24IXfS1HeCh+YgQYHu4vgRt2PRFze+
888
+ GXYkHAQaTOs9qmdvLdTN/mUxcMUbpgIKumB7bVjCmkn+YzILa+M6wKyrO7Do0wlRjBCDxjTgxSvg
889
+ GrZgFCdsMneMvLJymM/NzD+5yCRCFNZX/OYmQ6kd5YCQzgNUKD73P9P4Te1qCjqTE5s7FCMTY5w/
890
+ 0YcneeVMUeMBrYVdGjux1XMQpNPyvG5k9VpWkKjHDkx0Dy5xO/fIR/RpbxXyEV6DHpx8Uq79AtoS
891
+ qFlnGNu8cN2bsWntgM6JQEhqDjXKKWYVIZQs6GAqm4VKQPNriiTsBhYscw==
892
+ -----END CERTIFICATE-----
893
+
894
+ Comodo AAA Services root
895
+ ========================
896
+ -----BEGIN CERTIFICATE-----
897
+ MIIEMjCCAxqgAwIBAgIBATANBgkqhkiG9w0BAQUFADB7MQswCQYDVQQGEwJHQjEbMBkGA1UECAwS
898
+ R3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRowGAYDVQQKDBFDb21vZG8gQ0Eg
899
+ TGltaXRlZDEhMB8GA1UEAwwYQUFBIENlcnRpZmljYXRlIFNlcnZpY2VzMB4XDTA0MDEwMTAwMDAw
900
+ MFoXDTI4MTIzMTIzNTk1OVowezELMAkGA1UEBhMCR0IxGzAZBgNVBAgMEkdyZWF0ZXIgTWFuY2hl
901
+ c3RlcjEQMA4GA1UEBwwHU2FsZm9yZDEaMBgGA1UECgwRQ29tb2RvIENBIExpbWl0ZWQxITAfBgNV
902
+ BAMMGEFBQSBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
903
+ ggEBAL5AnfRu4ep2hxxNRUSOvkbIgwadwSr+GB+O5AL686tdUIoWMQuaBtDFcCLNSS1UY8y2bmhG
904
+ C1Pqy0wkwLxyTurxFa70VJoSCsN6sjNg4tqJVfMiWPPe3M/vg4aijJRPn2jymJBGhCfHdr/jzDUs
905
+ i14HZGWCwEiwqJH5YZ92IFCokcdmtet4YgNW8IoaE+oxox6gmf049vYnMlhvB/VruPsUK6+3qszW
906
+ Y19zjNoFmag4qMsXeDZRrOme9Hg6jc8P2ULimAyrL58OAd7vn5lJ8S3frHRNG5i1R8XlKdH5kBjH
907
+ Ypy+g8cmez6KJcfA3Z3mNWgQIJ2P2N7Sw4ScDV7oL8kCAwEAAaOBwDCBvTAdBgNVHQ4EFgQUoBEK
908
+ Iz6W8Qfs4q8p74Klf9AwpLQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wewYDVR0f
909
+ BHQwcjA4oDagNIYyaHR0cDovL2NybC5jb21vZG9jYS5jb20vQUFBQ2VydGlmaWNhdGVTZXJ2aWNl
910
+ cy5jcmwwNqA0oDKGMGh0dHA6Ly9jcmwuY29tb2RvLm5ldC9BQUFDZXJ0aWZpY2F0ZVNlcnZpY2Vz
911
+ LmNybDANBgkqhkiG9w0BAQUFAAOCAQEACFb8AvCb6P+k+tZ7xkSAzk/ExfYAWMymtrwUSWgEdujm
912
+ 7l3sAg9g1o1QGE8mTgHj5rCl7r+8dFRBv/38ErjHT1r0iWAFf2C3BUrz9vHCv8S5dIa2LX1rzNLz
913
+ Rt0vxuBqw8M0Ayx9lt1awg6nCpnBBYurDC/zXDrPbDdVCYfeU0BsWO/8tqtlbgT2G9w84FoVxp7Z
914
+ 8VlIMCFlA2zs6SFz7JsDoeA3raAVGI/6ugLOpyypEBMs1OUIJqsil2D4kF501KKaU73yqWjgom7C
915
+ 12yxow+ev+to51byrvLjKzg6CYG1a4XXvi3tPxq3smPi9WIsgtRqAEFQ8TmDn5XpNpaYbg==
916
+ -----END CERTIFICATE-----
917
+
918
+ Comodo Secure Services root
919
+ ===========================
920
+ -----BEGIN CERTIFICATE-----
921
+ MIIEPzCCAyegAwIBAgIBATANBgkqhkiG9w0BAQUFADB+MQswCQYDVQQGEwJHQjEbMBkGA1UECAwS
922
+ R3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRowGAYDVQQKDBFDb21vZG8gQ0Eg
923
+ TGltaXRlZDEkMCIGA1UEAwwbU2VjdXJlIENlcnRpZmljYXRlIFNlcnZpY2VzMB4XDTA0MDEwMTAw
924
+ MDAwMFoXDTI4MTIzMTIzNTk1OVowfjELMAkGA1UEBhMCR0IxGzAZBgNVBAgMEkdyZWF0ZXIgTWFu
925
+ Y2hlc3RlcjEQMA4GA1UEBwwHU2FsZm9yZDEaMBgGA1UECgwRQ29tb2RvIENBIExpbWl0ZWQxJDAi
926
+ BgNVBAMMG1NlY3VyZSBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczCCASIwDQYJKoZIhvcNAQEBBQADggEP
927
+ ADCCAQoCggEBAMBxM4KK0HDrc4eCQNUd5MvJDkKQ+d40uaG6EfQlhfPMcm3ye5drswfxdySRXyWP
928
+ 9nQ95IDC+DwN879A6vfIUtFyb+/Iq0G4bi4XKpVpDM3SHpR7LZQdqnXXs5jLrLxkU0C8j6ysNstc
929
+ rbvd4JQX7NFc0L/vpZXJkMWwrPsbQ996CF23uPJAGysnnlDOXmWCiIxe004MeuoIkbY2qitC++rC
930
+ oznl2yY4rYsK7hljxxwk3wN42ubqwUcaCwtGCd0C/N7Lh1/XMGNooa7cMqG6vv5Eq2i2pRcV/b3V
931
+ p6ea5EQz6YiO/O1R65NxTq0B50SOqy3LqP4BSUjwwN3HaNiS/j0CAwEAAaOBxzCBxDAdBgNVHQ4E
932
+ FgQUPNiTiMLAggnMAZkGkyDpnnAJY08wDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8w
933
+ gYEGA1UdHwR6MHgwO6A5oDeGNWh0dHA6Ly9jcmwuY29tb2RvY2EuY29tL1NlY3VyZUNlcnRpZmlj
934
+ YXRlU2VydmljZXMuY3JsMDmgN6A1hjNodHRwOi8vY3JsLmNvbW9kby5uZXQvU2VjdXJlQ2VydGlm
935
+ aWNhdGVTZXJ2aWNlcy5jcmwwDQYJKoZIhvcNAQEFBQADggEBAIcBbSMdflsXfcFhMs+P5/OKlFlm
936
+ 4J4oqF7Tt/Q05qo5spcWxYJvMqTpjOev/e/C6LlLqqP05tqNZSH7uoDrJiiFGv45jN5bBAS0VPmj
937
+ Z55B+glSzAVIqMk/IQQezkhr/IXownuvf7fM+F86/TXGDe+X3EyrEeFryzHRbPtIgKvcnDe4IRRL
938
+ DXE97IMzbtFuMhbsmMcWi1mmNKsFVy2T96oTy9IT4rcuO81rUBcJaD61JlfutuC23bkpgHl9j6Pw
939
+ pCikFcSF9CfUa7/lXORlAnZUtOM3ZiTTGWHIUhDlizeauan5Hb/qmZJhlv8BzaFfDbxxvA6sCx1H
940
+ RR3B7Hzs/Sk=
941
+ -----END CERTIFICATE-----
942
+
943
+ Comodo Trusted Services root
944
+ ============================
945
+ -----BEGIN CERTIFICATE-----
946
+ MIIEQzCCAyugAwIBAgIBATANBgkqhkiG9w0BAQUFADB/MQswCQYDVQQGEwJHQjEbMBkGA1UECAwS
947
+ R3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRowGAYDVQQKDBFDb21vZG8gQ0Eg
948
+ TGltaXRlZDElMCMGA1UEAwwcVHJ1c3RlZCBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczAeFw0wNDAxMDEw
949
+ MDAwMDBaFw0yODEyMzEyMzU5NTlaMH8xCzAJBgNVBAYTAkdCMRswGQYDVQQIDBJHcmVhdGVyIE1h
950
+ bmNoZXN0ZXIxEDAOBgNVBAcMB1NhbGZvcmQxGjAYBgNVBAoMEUNvbW9kbyBDQSBMaW1pdGVkMSUw
951
+ IwYDVQQDDBxUcnVzdGVkIENlcnRpZmljYXRlIFNlcnZpY2VzMIIBIjANBgkqhkiG9w0BAQEFAAOC
952
+ AQ8AMIIBCgKCAQEA33FvNlhTWvI2VFeAxHQIIO0Yfyod5jWaHiWsnOWWfnJSoBVC21ndZHoa0Lh7
953
+ 3TkVvFVIxO06AOoxEbrycXQaZ7jPM8yoMa+j49d/vzMtTGo87IvDktJTdyR0nAducPy9C1t2ul/y
954
+ /9c3S0pgePfw+spwtOpZqqPOSC+pw7ILfhdyFgymBwwbOM/JYrc/oJOlh0Hyt3BAd9i+FHzjqMB6
955
+ juljatEPmsbS9Is6FARW1O24zG71++IsWL1/T2sr92AkWCTOJu80kTrV44HQsvAEAtdbtz6SrGsS
956
+ ivnkBbA7kUlcsutT6vifR4buv5XAwAaf0lteERv0xwQ1KdJVXOTt6wIDAQABo4HJMIHGMB0GA1Ud
957
+ DgQWBBTFe1i97doladL3WRaoszLAeydb9DAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB
958
+ /zCBgwYDVR0fBHwwejA8oDqgOIY2aHR0cDovL2NybC5jb21vZG9jYS5jb20vVHJ1c3RlZENlcnRp
959
+ ZmljYXRlU2VydmljZXMuY3JsMDqgOKA2hjRodHRwOi8vY3JsLmNvbW9kby5uZXQvVHJ1c3RlZENl
960
+ cnRpZmljYXRlU2VydmljZXMuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQDIk4E7ibSvuIQSTI3S8Ntw
961
+ uleGFTQQuS9/HrCoiWChisJ3DFBKmwCL2Iv0QeLQg4pKHBQGsKNoBXAxMKdTmw7pSqBYaWcOrp32
962
+ pSxBvzwGa+RZzG0Q8ZZvH9/0BAKkn0U+yNj6NkZEUD+Cl5EfKNsYEYwq5GWDVxISjBc/lDb+XbDA
963
+ BHcTuPQV1T84zJQ6VdCsmPW6AF/ghhmBeC8owH7TzEIK9a5QoNE+xqFx7D+gIIxmOom0jtTYsU0l
964
+ R+4viMi14QVFwL4Ucd56/Y57fU0IlqUSc/AtyjcndBInTMu2l+nZrghtWjlA3QVHdWpaIbOjGM9O
965
+ 9y5Xt5hwXsjEeLBi
966
+ -----END CERTIFICATE-----
967
+
968
+ QuoVadis Root CA
969
+ ================
970
+ -----BEGIN CERTIFICATE-----
971
+ MIIF0DCCBLigAwIBAgIEOrZQizANBgkqhkiG9w0BAQUFADB/MQswCQYDVQQGEwJCTTEZMBcGA1UE
972
+ ChMQUXVvVmFkaXMgTGltaXRlZDElMCMGA1UECxMcUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0
973
+ eTEuMCwGA1UEAxMlUXVvVmFkaXMgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wMTAz
974
+ MTkxODMzMzNaFw0yMTAzMTcxODMzMzNaMH8xCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRp
975
+ cyBMaW1pdGVkMSUwIwYDVQQLExxSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MS4wLAYDVQQD
976
+ EyVRdW9WYWRpcyBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEF
977
+ AAOCAQ8AMIIBCgKCAQEAv2G1lVO6V/z68mcLOhrfEYBklbTRvM16z/Ypli4kVEAkOPcahdxYTMuk
978
+ J0KX0J+DisPkBgNbAKVRHnAEdOLB1Dqr1607BxgFjv2DrOpm2RgbaIr1VxqYuvXtdj182d6UajtL
979
+ F8HVj71lODqV0D1VNk7feVcxKh7YWWVJWCCYfqtffp/p1k3sg3Spx2zY7ilKhSoGFPlU5tPaZQeL
980
+ YzcS19Dsw3sgQUSj7cugF+FxZc4dZjH3dgEZyH0DWLaVSR2mEiboxgx24ONmy+pdpibu5cxfvWen
981
+ AScOospUxbF6lR1xHkopigPcakXBpBlebzbNw6Kwt/5cOOJSvPhEQ+aQuwIDAQABo4ICUjCCAk4w
982
+ PQYIKwYBBQUHAQEEMTAvMC0GCCsGAQUFBzABhiFodHRwczovL29jc3AucXVvdmFkaXNvZmZzaG9y
983
+ ZS5jb20wDwYDVR0TAQH/BAUwAwEB/zCCARoGA1UdIASCAREwggENMIIBCQYJKwYBBAG+WAABMIH7
984
+ MIHUBggrBgEFBQcCAjCBxxqBxFJlbGlhbmNlIG9uIHRoZSBRdW9WYWRpcyBSb290IENlcnRpZmlj
985
+ YXRlIGJ5IGFueSBwYXJ0eSBhc3N1bWVzIGFjY2VwdGFuY2Ugb2YgdGhlIHRoZW4gYXBwbGljYWJs
986
+ ZSBzdGFuZGFyZCB0ZXJtcyBhbmQgY29uZGl0aW9ucyBvZiB1c2UsIGNlcnRpZmljYXRpb24gcHJh
987
+ Y3RpY2VzLCBhbmQgdGhlIFF1b1ZhZGlzIENlcnRpZmljYXRlIFBvbGljeS4wIgYIKwYBBQUHAgEW
988
+ Fmh0dHA6Ly93d3cucXVvdmFkaXMuYm0wHQYDVR0OBBYEFItLbe3TKbkGGew5Oanwl4Rqy+/fMIGu
989
+ BgNVHSMEgaYwgaOAFItLbe3TKbkGGew5Oanwl4Rqy+/foYGEpIGBMH8xCzAJBgNVBAYTAkJNMRkw
990
+ FwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMSUwIwYDVQQLExxSb290IENlcnRpZmljYXRpb24gQXV0
991
+ aG9yaXR5MS4wLAYDVQQDEyVRdW9WYWRpcyBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggQ6
992
+ tlCLMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOCAQEAitQUtf70mpKnGdSkfnIYj9lo
993
+ fFIk3WdvOXrEql494liwTXCYhGHoG+NpGA7O+0dQoE7/8CQfvbLO9Sf87C9TqnN7Az10buYWnuul
994
+ LsS/VidQK2K6vkscPFVcQR0kvoIgR13VRH56FmjffU1RcHhXHTMe/QKZnAzNCgVPx7uOpHX6Sm2x
995
+ gI4JVrmcGmD+XcHXetwReNDWXcG31a0ymQM6isxUJTkxgXsTIlG6Rmyhu576BGxJJnSP0nPrzDCi
996
+ 5upZIof4l/UO/erMkqQWxFIY6iHOsfHmhIHluqmGKPJDWl0Snawe2ajlCmqnf6CHKc/yiU3U7MXi
997
+ 5nrQNiOKSnQ2+Q==
998
+ -----END CERTIFICATE-----
999
+
1000
+ QuoVadis Root CA 2
1001
+ ==================
1002
+ -----BEGIN CERTIFICATE-----
1003
+ MIIFtzCCA5+gAwIBAgICBQkwDQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCQk0xGTAXBgNVBAoT
1004
+ EFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMTElF1b1ZhZGlzIFJvb3QgQ0EgMjAeFw0wNjExMjQx
1005
+ ODI3MDBaFw0zMTExMjQxODIzMzNaMEUxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM
1006
+ aW1pdGVkMRswGQYDVQQDExJRdW9WYWRpcyBSb290IENBIDIwggIiMA0GCSqGSIb3DQEBAQUAA4IC
1007
+ DwAwggIKAoICAQCaGMpLlA0ALa8DKYrwD4HIrkwZhR0In6spRIXzL4GtMh6QRr+jhiYaHv5+HBg6
1008
+ XJxgFyo6dIMzMH1hVBHL7avg5tKifvVrbxi3Cgst/ek+7wrGsxDp3MJGF/hd/aTa/55JWpzmM+Yk
1009
+ lvc/ulsrHHo1wtZn/qtmUIttKGAr79dgw8eTvI02kfN/+NsRE8Scd3bBrrcCaoF6qUWD4gXmuVbB
1010
+ lDePSHFjIuwXZQeVikvfj8ZaCuWw419eaxGrDPmF60Tp+ARz8un+XJiM9XOva7R+zdRcAitMOeGy
1011
+ lZUtQofX1bOQQ7dsE/He3fbE+Ik/0XX1ksOR1YqI0JDs3G3eicJlcZaLDQP9nL9bFqyS2+r+eXyt
1012
+ 66/3FsvbzSUr5R/7mp/iUcw6UwxI5g69ybR2BlLmEROFcmMDBOAENisgGQLodKcftslWZvB1Jdxn
1013
+ wQ5hYIizPtGo/KPaHbDRsSNU30R2be1B2MGyIrZTHN81Hdyhdyox5C315eXbyOD/5YDXC2Og/zOh
1014
+ D7osFRXql7PSorW+8oyWHhqPHWykYTe5hnMz15eWniN9gqRMgeKh0bpnX5UHoycR7hYQe7xFSkyy
1015
+ BNKr79X9DFHOUGoIMfmR2gyPZFwDwzqLID9ujWc9Otb+fVuIyV77zGHcizN300QyNQliBJIWENie
1016
+ J0f7OyHj+OsdWwIDAQABo4GwMIGtMA8GA1UdEwEB/wQFMAMBAf8wCwYDVR0PBAQDAgEGMB0GA1Ud
1017
+ DgQWBBQahGK8SEwzJQTU7tD2A8QZRtGUazBuBgNVHSMEZzBlgBQahGK8SEwzJQTU7tD2A8QZRtGU
1018
+ a6FJpEcwRTELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMT
1019
+ ElF1b1ZhZGlzIFJvb3QgQ0EgMoICBQkwDQYJKoZIhvcNAQEFBQADggIBAD4KFk2fBluornFdLwUv
1020
+ Z+YTRYPENvbzwCYMDbVHZF34tHLJRqUDGCdViXh9duqWNIAXINzng/iN/Ae42l9NLmeyhP3ZRPx3
1021
+ UIHmfLTJDQtyU/h2BwdBR5YM++CCJpNVjP4iH2BlfF/nJrP3MpCYUNQ3cVX2kiF495V5+vgtJodm
1022
+ VjB3pjd4M1IQWK4/YY7yarHvGH5KWWPKjaJW1acvvFYfzznB4vsKqBUsfU16Y8Zsl0Q80m/DShcK
1023
+ +JDSV6IZUaUtl0HaB0+pUNqQjZRG4T7wlP0QADj1O+hA4bRuVhogzG9Yje0uRY/W6ZM/57Es3zrW
1024
+ IozchLsib9D45MY56QSIPMO661V6bYCZJPVsAfv4l7CUW+v90m/xd2gNNWQjrLhVoQPRTUIZ3Ph1
1025
+ WVaj+ahJefivDrkRoHy3au000LYmYjgahwz46P0u05B/B5EqHdZ+XIWDmbA4CD/pXvk1B+TJYm5X
1026
+ f6dQlfe6yJvmjqIBxdZmv3lh8zwc4bmCXF2gw+nYSL0ZohEUGW6yhhtoPkg3Goi3XZZenMfvJ2II
1027
+ 4pEZXNLxId26F0KCl3GBUzGpn/Z9Yr9y4aOTHcyKJloJONDO1w2AFrR4pTqHTI2KpdVGl/IsELm8
1028
+ VCLAAVBpQ570su9t+Oza8eOx79+Rj1QqCyXBJhnEUhAFZdWCEOrCMc0u
1029
+ -----END CERTIFICATE-----
1030
+
1031
+ QuoVadis Root CA 3
1032
+ ==================
1033
+ -----BEGIN CERTIFICATE-----
1034
+ MIIGnTCCBIWgAwIBAgICBcYwDQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCQk0xGTAXBgNVBAoT
1035
+ EFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMTElF1b1ZhZGlzIFJvb3QgQ0EgMzAeFw0wNjExMjQx
1036
+ OTExMjNaFw0zMTExMjQxOTA2NDRaMEUxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM
1037
+ aW1pdGVkMRswGQYDVQQDExJRdW9WYWRpcyBSb290IENBIDMwggIiMA0GCSqGSIb3DQEBAQUAA4IC
1038
+ DwAwggIKAoICAQDMV0IWVJzmmNPTTe7+7cefQzlKZbPoFog02w1ZkXTPkrgEQK0CSzGrvI2RaNgg
1039
+ DhoB4hp7Thdd4oq3P5kazethq8Jlph+3t723j/z9cI8LoGe+AaJZz3HmDyl2/7FWeUUrH556VOij
1040
+ KTVopAFPD6QuN+8bv+OPEKhyq1hX51SGyMnzW9os2l2ObjyjPtr7guXd8lyyBTNvijbO0BNO/79K
1041
+ DDRMpsMhvVAEVeuxu537RR5kFd5VAYwCdrXLoT9CabwvvWhDFlaJKjdhkf2mrk7AyxRllDdLkgbv
1042
+ BNDInIjbC3uBr7E9KsRlOni27tyAsdLTmZw67mtaa7ONt9XOnMK+pUsvFrGeaDsGb659n/je7Mwp
1043
+ p5ijJUMv7/FfJuGITfhebtfZFG4ZM2mnO4SJk8RTVROhUXhA+LjJou57ulJCg54U7QVSWllWp5f8
1044
+ nT8KKdjcT5EOE7zelaTfi5m+rJsziO+1ga8bxiJTyPbH7pcUsMV8eFLI8M5ud2CEpukqdiDtWAEX
1045
+ MJPpGovgc2PZapKUSU60rUqFxKMiMPwJ7Wgic6aIDFUhWMXhOp8q3crhkODZc6tsgLjoC2SToJyM
1046
+ Gf+z0gzskSaHirOi4XCPLArlzW1oUevaPwV/izLmE1xr/l9A4iLItLRkT9a6fUg+qGkM17uGcclz
1047
+ uD87nSVL2v9A6wIDAQABo4IBlTCCAZEwDwYDVR0TAQH/BAUwAwEB/zCB4QYDVR0gBIHZMIHWMIHT
1048
+ BgkrBgEEAb5YAAMwgcUwgZMGCCsGAQUFBwICMIGGGoGDQW55IHVzZSBvZiB0aGlzIENlcnRpZmlj
1049
+ YXRlIGNvbnN0aXR1dGVzIGFjY2VwdGFuY2Ugb2YgdGhlIFF1b1ZhZGlzIFJvb3QgQ0EgMyBDZXJ0
1050
+ aWZpY2F0ZSBQb2xpY3kgLyBDZXJ0aWZpY2F0aW9uIFByYWN0aWNlIFN0YXRlbWVudC4wLQYIKwYB
1051
+ BQUHAgEWIWh0dHA6Ly93d3cucXVvdmFkaXNnbG9iYWwuY29tL2NwczALBgNVHQ8EBAMCAQYwHQYD
1052
+ VR0OBBYEFPLAE+CCQz777i9nMpY1XNu4ywLQMG4GA1UdIwRnMGWAFPLAE+CCQz777i9nMpY1XNu4
1053
+ ywLQoUmkRzBFMQswCQYDVQQGEwJCTTEZMBcGA1UEChMQUXVvVmFkaXMgTGltaXRlZDEbMBkGA1UE
1054
+ AxMSUXVvVmFkaXMgUm9vdCBDQSAzggIFxjANBgkqhkiG9w0BAQUFAAOCAgEAT62gLEz6wPJv92ZV
1055
+ qyM07ucp2sNbtrCD2dDQ4iH782CnO11gUyeim/YIIirnv6By5ZwkajGxkHon24QRiSemd1o417+s
1056
+ hvzuXYO8BsbRd2sPbSQvS3pspweWyuOEn62Iix2rFo1bZhfZFvSLgNLd+LJ2w/w4E6oM3kJpK27z
1057
+ POuAJ9v1pkQNn1pVWQvVDVJIxa6f8i+AxeoyUDUSly7B4f/xI4hROJ/yZlZ25w9Rl6VSDE1JUZU2
1058
+ Pb+iSwwQHYaZTKrzchGT5Or2m9qoXadNt54CrnMAyNojA+j56hl0YgCUyyIgvpSnWbWCar6ZeXqp
1059
+ 8kokUvd0/bpO5qgdAm6xDYBEwa7TIzdfu4V8K5Iu6H6li92Z4b8nby1dqnuH/grdS/yO9SbkbnBC
1060
+ bjPsMZ57k8HkyWkaPcBrTiJt7qtYTcbQQcEr6k8Sh17rRdhs9ZgC06DYVYoGmRmioHfRMJ6szHXu
1061
+ g/WwYjnPbFfiTNKRCw51KBuav/0aQ/HKd/s7j2G4aSgWQgRecCocIdiP4b0jWy10QJLZYxkNc91p
1062
+ vGJHvOB0K7Lrfb5BG7XARsWhIstfTsEokt4YutUqKLsRixeTmJlglFwjz1onl14LBQaTNx47aTbr
1063
+ qZ5hHY8y2o4M1nQ+ewkk2gF3R8Q7zTSMmfXK4SVhM7JZG+Ju1zdXtg2pEto=
1064
+ -----END CERTIFICATE-----
1065
+
1066
+ Security Communication Root CA
1067
+ ==============================
1068
+ -----BEGIN CERTIFICATE-----
1069
+ MIIDWjCCAkKgAwIBAgIBADANBgkqhkiG9w0BAQUFADBQMQswCQYDVQQGEwJKUDEYMBYGA1UEChMP
1070
+ U0VDT00gVHJ1c3QubmV0MScwJQYDVQQLEx5TZWN1cml0eSBDb21tdW5pY2F0aW9uIFJvb3RDQTEw
1071
+ HhcNMDMwOTMwMDQyMDQ5WhcNMjMwOTMwMDQyMDQ5WjBQMQswCQYDVQQGEwJKUDEYMBYGA1UEChMP
1072
+ U0VDT00gVHJ1c3QubmV0MScwJQYDVQQLEx5TZWN1cml0eSBDb21tdW5pY2F0aW9uIFJvb3RDQTEw
1073
+ ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCzs/5/022x7xZ8V6UMbXaKL0u/ZPtM7orw
1074
+ 8yl89f/uKuDp6bpbZCKamm8sOiZpUQWZJtzVHGpxxpp9Hp3dfGzGjGdnSj74cbAZJ6kJDKaVv0uM
1075
+ DPpVmDvY6CKhS3E4eayXkmmziX7qIWgGmBSWh9JhNrxtJ1aeV+7AwFb9Ms+k2Y7CI9eNqPPYJayX
1076
+ 5HA49LY6tJ07lyZDo6G8SVlyTCMwhwFY9k6+HGhWZq/NQV3Is00qVUarH9oe4kA92819uZKAnDfd
1077
+ DJZkndwi92SL32HeFZRSFaB9UslLqCHJxrHty8OVYNEP8Ktw+N/LTX7s1vqr2b1/VPKl6Xn62dZ2
1078
+ JChzAgMBAAGjPzA9MB0GA1UdDgQWBBSgc0mZaNyFW2XjmygvV5+9M7wHSDALBgNVHQ8EBAMCAQYw
1079
+ DwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEAaECpqLvkT115swW1F7NgE+vGkl3g
1080
+ 0dNq/vu+m22/xwVtWSDEHPC32oRYAmP6SBbvT6UL90qY8j+eG61Ha2POCEfrUj94nK9NrvjVT8+a
1081
+ mCoQQTlSxN3Zmw7vkwGusi7KaEIkQmywszo+zenaSMQVy+n5Bw+SUEmK3TGXX8npN6o7WWWXlDLJ
1082
+ s58+OmJYxUmtYg5xpTKqL8aJdkNAExNnPaJUJRDL8Try2frbSVa7pv6nQTXD4IhhyYjH3zYQIphZ
1083
+ 6rBK+1YWc26sTfcioU+tHXotRSflMMFe8toTyyVCUZVHA4xsIcx0Qu1T/zOLjw9XARYvz6buyXAi
1084
+ FL39vmwLAw==
1085
+ -----END CERTIFICATE-----
1086
+
1087
+ Sonera Class 1 Root CA
1088
+ ======================
1089
+ -----BEGIN CERTIFICATE-----
1090
+ MIIDIDCCAgigAwIBAgIBJDANBgkqhkiG9w0BAQUFADA5MQswCQYDVQQGEwJGSTEPMA0GA1UEChMG
1091
+ U29uZXJhMRkwFwYDVQQDExBTb25lcmEgQ2xhc3MxIENBMB4XDTAxMDQwNjEwNDkxM1oXDTIxMDQw
1092
+ NjEwNDkxM1owOTELMAkGA1UEBhMCRkkxDzANBgNVBAoTBlNvbmVyYTEZMBcGA1UEAxMQU29uZXJh
1093
+ IENsYXNzMSBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALWJHytPZwp5/8Ue+H88
1094
+ 7dF+2rDNbS82rDTG29lkFwhjMDMiikzujrsPDUJVyZ0upe/3p4zDq7mXy47vPxVnqIJyY1MPQYx9
1095
+ EJUkoVqlBvqSV536pQHydekfvFYmUk54GWVYVQNYwBSujHxVX3BbdyMGNpfzJLWaRpXk3w0LBUXl
1096
+ 0fIdgrvGE+D+qnr9aTCU89JFhfzyMlsy3uhsXR/LpCJ0sICOXZT3BgBLqdReLjVQCfOAl/QMF645
1097
+ 2F/NM8EcyonCIvdFEu1eEpOdY6uCLrnrQkFEy0oaAIINnvmLVz5MxxftLItyM19yejhW1ebZrgUa
1098
+ HXVFsculJRwSVzb9IjcCAwEAAaMzMDEwDwYDVR0TAQH/BAUwAwEB/zARBgNVHQ4ECgQIR+IMi/ZT
1099
+ iFIwCwYDVR0PBAQDAgEGMA0GCSqGSIb3DQEBBQUAA4IBAQCLGrLJXWG04bkruVPRsoWdd44W7hE9
1100
+ 28Jj2VuXZfsSZ9gqXLar5V7DtxYvyOirHYr9qxp81V9jz9yw3Xe5qObSIjiHBxTZ/75Wtf0HDjxV
1101
+ yhbMp6Z3N/vbXB9OWQaHowND9Rart4S9Tu+fMTfwRvFAttEMpWT4Y14h21VOTzF2nBBhjrZTOqMR
1102
+ vq9tfB69ri3iDGnHhVNoomG6xT60eVR4ngrHAr5i0RGCS2UvkVrCqIexVmiUefkl98HVrhq4uz2P
1103
+ qYo4Ffdz0Fpg0YCw8NzVUM1O7pJIae2yIx4wzMiUyLb1O4Z/P6Yun/Y+LLWSlj7fLJOK/4GMDw9Z
1104
+ IRlXvVWa
1105
+ -----END CERTIFICATE-----
1106
+
1107
+ Sonera Class 2 Root CA
1108
+ ======================
1109
+ -----BEGIN CERTIFICATE-----
1110
+ MIIDIDCCAgigAwIBAgIBHTANBgkqhkiG9w0BAQUFADA5MQswCQYDVQQGEwJGSTEPMA0GA1UEChMG
1111
+ U29uZXJhMRkwFwYDVQQDExBTb25lcmEgQ2xhc3MyIENBMB4XDTAxMDQwNjA3Mjk0MFoXDTIxMDQw
1112
+ NjA3Mjk0MFowOTELMAkGA1UEBhMCRkkxDzANBgNVBAoTBlNvbmVyYTEZMBcGA1UEAxMQU29uZXJh
1113
+ IENsYXNzMiBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJAXSjWdyvANlsdE+hY3
1114
+ /Ei9vX+ALTU74W+oZ6m/AxxNjG8yR9VBaKQTBME1DJqEQ/xcHf+Js+gXGM2RX/uJ4+q/Tl18GybT
1115
+ dXnt5oTjV+WtKcT0OijnpXuENmmz/V52vaMtmdOQTiMofRhj8VQ7Jp12W5dCsv+u8E7s3TmVToMG
1116
+ f+dJQMjFAbJUWmYdPfz56TwKnoG4cPABi+QjVHzIrviQHgCWctRUz2EjvOr7nQKV0ba5cTppCD8P
1117
+ tOFCx4j1P5iop7oc4HFx71hXgVB6XGt0Rg6DA5jDjqhu8nYybieDwnPz3BjotJPqdURrBGAgcVeH
1118
+ nfO+oJAjPYok4doh28MCAwEAAaMzMDEwDwYDVR0TAQH/BAUwAwEB/zARBgNVHQ4ECgQISqCqWITT
1119
+ XjwwCwYDVR0PBAQDAgEGMA0GCSqGSIb3DQEBBQUAA4IBAQBazof5FnIVV0sd2ZvnoiYw7JNn39Yt
1120
+ 0jSv9zilzqsWuasvfDXLrNAPtEwr/IDva4yRXzZ299uzGxnq9LIR/WFxRL8oszodv7ND6J+/3DEI
1121
+ cbCdjdY0RzKQxmUk96BKfARzjzlvF4xytb1LyHr4e4PDKE6cCepnP7JnBBvDFNr450kkkdAdavph
1122
+ Oe9r5yF1BgfYErQhIHBCcYHaPJo2vqZbDWpsmh+Re/n570K6Tk6ezAyNlNzZRZxe7EJQY670XcSx
1123
+ EtzKO6gunRRaBXW37Ndj4ro1tgQIkejanZz2ZrUYrAqmVCY0M9IbwdR/GjqOC6oybtv8TyWf2TLH
1124
+ llpwrN9M
1125
+ -----END CERTIFICATE-----
1126
+
1127
+ Staat der Nederlanden Root CA
1128
+ =============================
1129
+ -----BEGIN CERTIFICATE-----
1130
+ MIIDujCCAqKgAwIBAgIEAJiWijANBgkqhkiG9w0BAQUFADBVMQswCQYDVQQGEwJOTDEeMBwGA1UE
1131
+ ChMVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSYwJAYDVQQDEx1TdGFhdCBkZXIgTmVkZXJsYW5kZW4g
1132
+ Um9vdCBDQTAeFw0wMjEyMTcwOTIzNDlaFw0xNTEyMTYwOTE1MzhaMFUxCzAJBgNVBAYTAk5MMR4w
1133
+ HAYDVQQKExVTdGFhdCBkZXIgTmVkZXJsYW5kZW4xJjAkBgNVBAMTHVN0YWF0IGRlciBOZWRlcmxh
1134
+ bmRlbiBSb290IENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAmNK1URF6gaYUmHFt
1135
+ vsznExvWJw56s2oYHLZhWtVhCb/ekBPHZ+7d89rFDBKeNVU+LCeIQGv33N0iYfXCxw719tV2U02P
1136
+ jLwYdjeFnejKScfST5gTCaI+Ioicf9byEGW07l8Y1Rfj+MX94p2i71MOhXeiD+EwR+4A5zN9RGca
1137
+ C1Hoi6CeUJhoNFIfLm0B8mBF8jHrqTFoKbt6QZ7GGX+UtFE5A3+y3qcym7RHjm+0Sq7lr7HcsBth
1138
+ vJly3uSJt3omXdozSVtSnA71iq3DuD3oBmrC1SoLbHuEvVYFy4ZlkuxEK7COudxwC0barbxjiDn6
1139
+ 22r+I/q85Ej0ZytqERAhSQIDAQABo4GRMIGOMAwGA1UdEwQFMAMBAf8wTwYDVR0gBEgwRjBEBgRV
1140
+ HSAAMDwwOgYIKwYBBQUHAgEWLmh0dHA6Ly93d3cucGtpb3ZlcmhlaWQubmwvcG9saWNpZXMvcm9v
1141
+ dC1wb2xpY3kwDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBSofeu8Y6R0E3QA7Jbg0zTBLL9s+DAN
1142
+ BgkqhkiG9w0BAQUFAAOCAQEABYSHVXQ2YcG70dTGFagTtJ+k/rvuFbQvBgwp8qiSpGEN/KtcCFtR
1143
+ EytNwiphyPgJWPwtArI5fZlmgb9uXJVFIGzmeafR2Bwp/MIgJ1HI8XxdNGdphREwxgDS1/PTfLbw
1144
+ MVcoEoJz6TMvplW0C5GUR5z6u3pCMuiufi3IvKwUv9kP2Vv8wfl6leF9fpb8cbDCTMjfRTTJzg3y
1145
+ nGQI0DvDKcWy7ZAEwbEpkcUwb8GpcjPM/l0WFywRaed+/sWDCN+83CI6LiBpIzlWYGeQiy52OfsR
1146
+ iJf2fL1LuCAWZwWN4jvBcj+UlTfHXbme2JOhF4//DGYVwSR8MnwDHTuhWEUykw==
1147
+ -----END CERTIFICATE-----
1148
+
1149
+ TDC Internet Root CA
1150
+ ====================
1151
+ -----BEGIN CERTIFICATE-----
1152
+ MIIEKzCCAxOgAwIBAgIEOsylTDANBgkqhkiG9w0BAQUFADBDMQswCQYDVQQGEwJESzEVMBMGA1UE
1153
+ ChMMVERDIEludGVybmV0MR0wGwYDVQQLExRUREMgSW50ZXJuZXQgUm9vdCBDQTAeFw0wMTA0MDUx
1154
+ NjMzMTdaFw0yMTA0MDUxNzAzMTdaMEMxCzAJBgNVBAYTAkRLMRUwEwYDVQQKEwxUREMgSW50ZXJu
1155
+ ZXQxHTAbBgNVBAsTFFREQyBJbnRlcm5ldCBSb290IENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
1156
+ MIIBCgKCAQEAxLhAvJHVYx/XmaCLDEAedLdInUaMArLgJF/wGROnN4NrXceO+YQwzho7+vvOi20j
1157
+ xsNuZp+Jpd/gQlBn+h9sHvTQBda/ytZO5GhgbEaqHF1j4QeGDmUApy6mcca8uYGoOn0a0vnRrEvL
1158
+ znWv3Hv6gXPU/Lq9QYjUdLP5Xjg6PEOo0pVOd20TDJ2PeAG3WiAfAzc14izbSysseLlJ28TQx5yc
1159
+ 5IogCSEWVmb/Bexb4/DPqyQkXsN/cHoSxNK1EKC2IeGNeGlVRGn1ypYcNIUXJXfi9i8nmHj9eQY6
1160
+ otZaQ8H/7AQ77hPv01ha/5Lr7K7a8jcDR0G2l8ktCkEiu7vmpwIDAQABo4IBJTCCASEwEQYJYIZI
1161
+ AYb4QgEBBAQDAgAHMGUGA1UdHwReMFwwWqBYoFakVDBSMQswCQYDVQQGEwJESzEVMBMGA1UEChMM
1162
+ VERDIEludGVybmV0MR0wGwYDVQQLExRUREMgSW50ZXJuZXQgUm9vdCBDQTENMAsGA1UEAxMEQ1JM
1163
+ MTArBgNVHRAEJDAigA8yMDAxMDQwNTE2MzMxN1qBDzIwMjEwNDA1MTcwMzE3WjALBgNVHQ8EBAMC
1164
+ AQYwHwYDVR0jBBgwFoAUbGQBx/2FbazI2p5QCIUItTxWqFAwHQYDVR0OBBYEFGxkAcf9hW2syNqe
1165
+ UAiFCLU8VqhQMAwGA1UdEwQFMAMBAf8wHQYJKoZIhvZ9B0EABBAwDhsIVjUuMDo0LjADAgSQMA0G
1166
+ CSqGSIb3DQEBBQUAA4IBAQBOQ8zR3R0QGwZ/t6T609lN+yOfI1Rb5osvBCiLtSdtiaHsmGnc540m
1167
+ gwV5dOy0uaOXwTUA/RXaOYE6lTGQ3pfphqiZdwzlWqCE/xIWrG64jcN7ksKsLtB9KOy282A4aW8+
1168
+ 2ARVPp7MVdK6/rtHBNcK2RYKNCn1WBPVT8+PVkuzHu7TmHnaCB4Mb7j4Fifvwm899qNLPg7kbWzb
1169
+ O0ESm70NRyN/PErQr8Cv9u8btRXE64PECV90i9kR+8JWsTz4cMo0jUNAE4z9mQNUecYu6oah9jrU
1170
+ Cbz0vGbMPVjQV0kK7iXiQe4T+Zs4NNEA9X7nlB38aQNiuJkFBT1reBK9sG9l
1171
+ -----END CERTIFICATE-----
1172
+
1173
+ TDC OCES Root CA
1174
+ ================
1175
+ -----BEGIN CERTIFICATE-----
1176
+ MIIFGTCCBAGgAwIBAgIEPki9xDANBgkqhkiG9w0BAQUFADAxMQswCQYDVQQGEwJESzEMMAoGA1UE
1177
+ ChMDVERDMRQwEgYDVQQDEwtUREMgT0NFUyBDQTAeFw0wMzAyMTEwODM5MzBaFw0zNzAyMTEwOTA5
1178
+ MzBaMDExCzAJBgNVBAYTAkRLMQwwCgYDVQQKEwNUREMxFDASBgNVBAMTC1REQyBPQ0VTIENBMIIB
1179
+ IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArGL2YSCyz8DGhdfjeebM7fI5kqSXLmSjhFuH
1180
+ nEz9pPPEXyG9VhDr2y5h7JNp46PMvZnDBfwGuMo2HP6QjklMxFaaL1a8z3sM8W9Hpg1DTeLpHTk0
1181
+ zY0s2RKY+ePhwUp8hjjEqcRhiNJerxomTdXkoCJHhNlktxmW/OwZ5LKXJk5KTMuPJItUGBxIYXvV
1182
+ iGjaXbXqzRowwYCDdlCqT9HU3Tjw7xb04QxQBr/q+3pJoSgrHPb8FTKjdGqPqcNiKXEx5TukYBde
1183
+ dObaE+3pHx8b0bJoc8YQNHVGEBDjkAB2QMuLt0MJIf+rTpPGWOmlgtt3xDqZsXKVSQTwtyv6e1mO
1184
+ 3QIDAQABo4ICNzCCAjMwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwgewGA1UdIASB
1185
+ 5DCB4TCB3gYIKoFQgSkBAQEwgdEwLwYIKwYBBQUHAgEWI2h0dHA6Ly93d3cuY2VydGlmaWthdC5k
1186
+ ay9yZXBvc2l0b3J5MIGdBggrBgEFBQcCAjCBkDAKFgNUREMwAwIBARqBgUNlcnRpZmlrYXRlciBm
1187
+ cmEgZGVubmUgQ0EgdWRzdGVkZXMgdW5kZXIgT0lEIDEuMi4yMDguMTY5LjEuMS4xLiBDZXJ0aWZp
1188
+ Y2F0ZXMgZnJvbSB0aGlzIENBIGFyZSBpc3N1ZWQgdW5kZXIgT0lEIDEuMi4yMDguMTY5LjEuMS4x
1189
+ LjARBglghkgBhvhCAQEEBAMCAAcwgYEGA1UdHwR6MHgwSKBGoESkQjBAMQswCQYDVQQGEwJESzEM
1190
+ MAoGA1UEChMDVERDMRQwEgYDVQQDEwtUREMgT0NFUyBDQTENMAsGA1UEAxMEQ1JMMTAsoCqgKIYm
1191
+ aHR0cDovL2NybC5vY2VzLmNlcnRpZmlrYXQuZGsvb2Nlcy5jcmwwKwYDVR0QBCQwIoAPMjAwMzAy
1192
+ MTEwODM5MzBagQ8yMDM3MDIxMTA5MDkzMFowHwYDVR0jBBgwFoAUYLWF7FZkfhIZJ2cdUBVLc647
1193
+ +RIwHQYDVR0OBBYEFGC1hexWZH4SGSdnHVAVS3OuO/kSMB0GCSqGSIb2fQdBAAQQMA4bCFY2LjA6
1194
+ NC4wAwIEkDANBgkqhkiG9w0BAQUFAAOCAQEACromJkbTc6gJ82sLMJn9iuFXehHTuJTXCRBuo7E4
1195
+ A9G28kNBKWKnctj7fAXmMXAnVBhOinxO5dHKjHiIzxvTkIvmI/gLDjNDfZziChmPyQE+dF10yYsc
1196
+ A+UYyAFMP8uXBV2YcaaYb7Z8vTd/vuGTJW1v8AqtFxjhA7wHKcitJuj4YfD9IQl+mo6paH1IYnK9
1197
+ AOoBmbgGglGBTvH1tJFUuSN6AJqfXY3gPGS5GhKSKseCRHI53OI8xthV9RVOyAUO28bQYqbsFbS1
1198
+ AoLbrIyigfCbmTH1ICCoiGEKB5+U/NDXG8wuF/MEJ3Zn61SD/aSQfgY9BKNDLdr8C2LqL19iUw==
1199
+ -----END CERTIFICATE-----
1200
+
1201
+ UTN DATACorp SGC Root CA
1202
+ ========================
1203
+ -----BEGIN CERTIFICATE-----
1204
+ MIIEXjCCA0agAwIBAgIQRL4Mi1AAIbQR0ypoBqmtaTANBgkqhkiG9w0BAQUFADCBkzELMAkGA1UE
1205
+ BhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2UgQ2l0eTEeMBwGA1UEChMVVGhl
1206
+ IFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExhodHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xGzAZ
1207
+ BgNVBAMTElVUTiAtIERBVEFDb3JwIFNHQzAeFw05OTA2MjQxODU3MjFaFw0xOTA2MjQxOTA2MzBa
1208
+ MIGTMQswCQYDVQQGEwJVUzELMAkGA1UECBMCVVQxFzAVBgNVBAcTDlNhbHQgTGFrZSBDaXR5MR4w
1209
+ HAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxITAfBgNVBAsTGGh0dHA6Ly93d3cudXNlcnRy
1210
+ dXN0LmNvbTEbMBkGA1UEAxMSVVROIC0gREFUQUNvcnAgU0dDMIIBIjANBgkqhkiG9w0BAQEFAAOC
1211
+ AQ8AMIIBCgKCAQEA3+5YEKIrblXEjr8uRgnn4AgPLit6E5Qbvfa2gI5lBZMAHryv4g+OGQ0SR+ys
1212
+ raP6LnD43m77VkIVni5c7yPeIbkFdicZD0/Ww5y0vpQZY/KmEQrrU0icvvIpOxboGqBMpsn0GFlo
1213
+ wHDyUwDAXlCCpVZvNvlK4ESGoE1O1kduSUrLZ9emxAW5jh70/P/N5zbgnAVssjMiFdC04MwXwLLA
1214
+ 9P4yPykqlXvY8qdOD1R8oQ2AswkDwf9c3V6aPryuvEeKaq5xyh+xKrhfQgUL7EYw0XILyulWbfXv
1215
+ 33i+Ybqypa4ETLyorGkVl73v67SMvzX41MPRKA5cOp9wGDMgd8SirwIDAQABo4GrMIGoMAsGA1Ud
1216
+ DwQEAwIBxjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRTMtGzz3/64PGgXYVOktKeRR20TzA9
1217
+ BgNVHR8ENjA0MDKgMKAuhixodHRwOi8vY3JsLnVzZXJ0cnVzdC5jb20vVVROLURBVEFDb3JwU0dD
1218
+ LmNybDAqBgNVHSUEIzAhBggrBgEFBQcDAQYKKwYBBAGCNwoDAwYJYIZIAYb4QgQBMA0GCSqGSIb3
1219
+ DQEBBQUAA4IBAQAnNZcAiosovcYzMB4p/OL31ZjUQLtgyr+rFywJNn9Q+kHcrpY6CiM+iVnJowft
1220
+ Gzet/Hy+UUla3joKVAgWRcKZsYfNjGjgaQPpxE6YsjuMFrMOoAyYUJuTqXAJyCyjj98C5OBxOvG0
1221
+ I3KgqgHf35g+FFCgMSa9KOlaMCZ1+XtgHI3zzVAmbQQnmt/VDUVHKWss5nbZqSl9Mt3JNjy9rjXx
1222
+ EZ4du5A/EkdOjtd+D2JzHVImOBwYSf0wdJrE5SIv2MCN7ZF6TACPcn9d2t0bi0Vr591pl6jFVkwP
1223
+ DPafepE39peC4N1xaf92P2BNPM/3mfnGV/TJVTl4uix5yaaIK/QI
1224
+ -----END CERTIFICATE-----
1225
+
1226
+ UTN USERFirst Email Root CA
1227
+ ===========================
1228
+ -----BEGIN CERTIFICATE-----
1229
+ MIIEojCCA4qgAwIBAgIQRL4Mi1AAJLQR0zYlJWfJiTANBgkqhkiG9w0BAQUFADCBrjELMAkGA1UE
1230
+ BhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2UgQ2l0eTEeMBwGA1UEChMVVGhl
1231
+ IFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExhodHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xNjA0
1232
+ BgNVBAMTLVVUTi1VU0VSRmlyc3QtQ2xpZW50IEF1dGhlbnRpY2F0aW9uIGFuZCBFbWFpbDAeFw05
1233
+ OTA3MDkxNzI4NTBaFw0xOTA3MDkxNzM2NThaMIGuMQswCQYDVQQGEwJVUzELMAkGA1UECBMCVVQx
1234
+ FzAVBgNVBAcTDlNhbHQgTGFrZSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsx
1235
+ ITAfBgNVBAsTGGh0dHA6Ly93d3cudXNlcnRydXN0LmNvbTE2MDQGA1UEAxMtVVROLVVTRVJGaXJz
1236
+ dC1DbGllbnQgQXV0aGVudGljYXRpb24gYW5kIEVtYWlsMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
1237
+ MIIBCgKCAQEAsjmFpPJ9q0E7YkY3rs3BYHW8OWX5ShpHornMSMxqmNVNNRm5pELlzkniii8efNIx
1238
+ B8dOtINknS4p1aJkxIW9hVE1eaROaJB7HHqkkqgX8pgV8pPMyaQylbsMTzC9mKALi+VuG6JG+ni8
1239
+ om+rWV6lL8/K2m2qL+usobNqqrcuZzWLeeEeaYji5kbNoKXqvgvOdjp6Dpvq/NonWz1zHyLmSGHG
1240
+ TPNpsaguG7bUMSAsvIKKjqQOpdeJQ/wWWq8dcdcRWdq6hw2v+vPhwvCkxWeM1tZUOt4KpLoDd7Nl
1241
+ yP0e03RiqhjKaJMeoYV+9Udly/hNVyh00jT/MLbu9mIwFIws6wIDAQABo4G5MIG2MAsGA1UdDwQE
1242
+ AwIBxjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBSJgmd9xJ0mcABLtFBIfN49rgRufTBYBgNV
1243
+ HR8EUTBPME2gS6BJhkdodHRwOi8vY3JsLnVzZXJ0cnVzdC5jb20vVVROLVVTRVJGaXJzdC1DbGll
1244
+ bnRBdXRoZW50aWNhdGlvbmFuZEVtYWlsLmNybDAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUH
1245
+ AwQwDQYJKoZIhvcNAQEFBQADggEBALFtYV2mGn98q0rkMPxTbyUkxsrt4jFcKw7u7mFVbwQ+zzne
1246
+ xRtJlOTrIEy05p5QLnLZjfWqo7NK2lYcYJeA3IKirUq9iiv/Cwm0xtcgBEXkzYABurorbs6q15L+
1247
+ 5K/r9CYdFip/bDCVNy8zEqx/3cfREYxRmLLQo5HQrfafnoOTHh1CuEava2bwm3/q4wMC5QJRwarV
1248
+ NZ1yQAOJujEdxRBoUp7fooXFXAimeOZTT7Hot9MUnpOmw2TjrH5xzbyf6QMbzPvprDHBr3wVdAKZ
1249
+ w7JHpsIyYdfHb0gkUSeh1YdV8nuPmD0Wnu51tvjQjvLzxq4oW6fw8zYX/MMF08oDSlQ=
1250
+ -----END CERTIFICATE-----
1251
+
1252
+ UTN USERFirst Hardware Root CA
1253
+ ==============================
1254
+ -----BEGIN CERTIFICATE-----
1255
+ MIIEdDCCA1ygAwIBAgIQRL4Mi1AAJLQR0zYq/mUK/TANBgkqhkiG9w0BAQUFADCBlzELMAkGA1UE
1256
+ BhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2UgQ2l0eTEeMBwGA1UEChMVVGhl
1257
+ IFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExhodHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xHzAd
1258
+ BgNVBAMTFlVUTi1VU0VSRmlyc3QtSGFyZHdhcmUwHhcNOTkwNzA5MTgxMDQyWhcNMTkwNzA5MTgx
1259
+ OTIyWjCBlzELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2UgQ2l0
1260
+ eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExhodHRwOi8vd3d3LnVz
1261
+ ZXJ0cnVzdC5jb20xHzAdBgNVBAMTFlVUTi1VU0VSRmlyc3QtSGFyZHdhcmUwggEiMA0GCSqGSIb3
1262
+ DQEBAQUAA4IBDwAwggEKAoIBAQCx98M4P7Sof885glFn0G2f0v9Y8+efK+wNiVSZuTiZFvfgIXlI
1263
+ wrthdBKWHTxqctU8EGc6Oe0rE81m65UJM6Rsl7HoxuzBdXmcRl6Nq9Bq/bkqVRcQVLMZ8Jr28bFd
1264
+ tqdt++BxF2uiiPsA3/4aMXcMmgF6sTLjKwEHOG7DpV4jvEWbe1DByTCP2+UretNb+zNAHqDVmBe8
1265
+ i4fDidNdoI6yqqr2jmmIBsX6iSHzCJ1pLgkzmykNRg+MzEk0sGlRvfkGzWitZky8PqxhvQqIDsjf
1266
+ Pe58BEydCl5rkdbux+0ojatNh4lz0G6k0B4WixThdkQDf2Os5M1JnMWS9KsyoUhbAgMBAAGjgbkw
1267
+ gbYwCwYDVR0PBAQDAgHGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFKFyXyYbKJhDlV0HN9WF
1268
+ lp1L0sNFMEQGA1UdHwQ9MDswOaA3oDWGM2h0dHA6Ly9jcmwudXNlcnRydXN0LmNvbS9VVE4tVVNF
1269
+ UkZpcnN0LUhhcmR3YXJlLmNybDAxBgNVHSUEKjAoBggrBgEFBQcDAQYIKwYBBQUHAwUGCCsGAQUF
1270
+ BwMGBggrBgEFBQcDBzANBgkqhkiG9w0BAQUFAAOCAQEARxkP3nTGmZev/K0oXnWO6y1n7k57K9cM
1271
+ //bey1WiCuFMVGWTYGufEpytXoMs61quwOQt9ABjHbjAbPLPSbtNk28GpgoiskliCE7/yMgUsogW
1272
+ XecB5BKV5UU0s4tpvc+0hY91UZ59Ojg6FEgSxvunOxqNDYJAB+gECJChicsZUN/KHAG8HQQZexB2
1273
+ lzvukJDKxA4fFm517zP4029bHpbj4HR3dHuKom4t3XbWOTCC8KucUvIqx69JXn7HaOWCgchqJ/kn
1274
+ iCrVWFCVH/A7HFe7fRQ5YiuayZSSKqMiDP+JJn1fIytH1xUdqWqeUQ0qUZ6B+dQ7XnASfxAynB67
1275
+ nfhmqA==
1276
+ -----END CERTIFICATE-----
1277
+
1278
+ UTN USERFirst Object Root CA
1279
+ ============================
1280
+ -----BEGIN CERTIFICATE-----
1281
+ MIIEZjCCA06gAwIBAgIQRL4Mi1AAJLQR0zYt4LNfGzANBgkqhkiG9w0BAQUFADCBlTELMAkGA1UE
1282
+ BhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2UgQ2l0eTEeMBwGA1UEChMVVGhl
1283
+ IFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExhodHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xHTAb
1284
+ BgNVBAMTFFVUTi1VU0VSRmlyc3QtT2JqZWN0MB4XDTk5MDcwOTE4MzEyMFoXDTE5MDcwOTE4NDAz
1285
+ NlowgZUxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJVVDEXMBUGA1UEBxMOU2FsdCBMYWtlIENpdHkx
1286
+ HjAcBgNVBAoTFVRoZSBVU0VSVFJVU1QgTmV0d29yazEhMB8GA1UECxMYaHR0cDovL3d3dy51c2Vy
1287
+ dHJ1c3QuY29tMR0wGwYDVQQDExRVVE4tVVNFUkZpcnN0LU9iamVjdDCCASIwDQYJKoZIhvcNAQEB
1288
+ BQADggEPADCCAQoCggEBAM6qgT+jo2F4qjEAVZURnicPHxzfOpuCaDDASmEd8S8O+r5596Uj71VR
1289
+ loTN2+O5bj4x2AogZ8f02b+U60cEPgLOKqJdhwQJ9jCdGIqXsqoc/EHSoTbL+z2RuufZcDX65OeQ
1290
+ w5ujm9M89RKZd7G3CeBo5hy485RjiGpq/gt2yb70IuRnuasaXnfBhQfdDWy/7gbHd2pBnqcP1/vu
1291
+ lBe3/IW+pKvEHDHd17bR5PDv3xaPslKT16HUiaEHLr/hARJCHhrh2JU022R5KP+6LhHC5ehbkkj7
1292
+ RwvCbNqtMoNB86XlQXD9ZZBt+vpRxPm9lisZBCzTbafc8H9vg2XiaquHhnUCAwEAAaOBrzCBrDAL
1293
+ BgNVHQ8EBAMCAcYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU2u1kdBScFDyr3ZmpvVsoTYs8
1294
+ ydgwQgYDVR0fBDswOTA3oDWgM4YxaHR0cDovL2NybC51c2VydHJ1c3QuY29tL1VUTi1VU0VSRmly
1295
+ c3QtT2JqZWN0LmNybDApBgNVHSUEIjAgBggrBgEFBQcDAwYIKwYBBQUHAwgGCisGAQQBgjcKAwQw
1296
+ DQYJKoZIhvcNAQEFBQADggEBAAgfUrE3RHjb/c652pWWmKpVZIC1WkDdIaXFwfNfLEzIR1pp6ujw
1297
+ NTX00CXzyKakh0q9G7FzCL3Uw8q2NbtZhncxzaeAFK4T7/yxSPlrJSUtUbYsbUXBmMiKVl0+7kNO
1298
+ PmsnjtA6S4ULX9Ptaqd1y9Fahy85dRNacrACgZ++8A+EVCBibGnU4U3GDZlDAQ0Slox4nb9QorFE
1299
+ qmrPF3rPbw/U+CRVX/A0FklmPlBGyWNxODFiuGK581OtbLUrohKqGU8J2l7nk8aOFAj+8DCAGKCG
1300
+ hU3IfdeLA/5u1fedFqySLKAj5ZyRUh+U3xeUc8OzwcFxBSAAeL0TUh2oPs0AH8g=
1301
+ -----END CERTIFICATE-----
1302
+
1303
+ Camerfirma Chambers of Commerce Root
1304
+ ====================================
1305
+ -----BEGIN CERTIFICATE-----
1306
+ MIIEvTCCA6WgAwIBAgIBADANBgkqhkiG9w0BAQUFADB/MQswCQYDVQQGEwJFVTEnMCUGA1UEChMe
1307
+ QUMgQ2FtZXJmaXJtYSBTQSBDSUYgQTgyNzQzMjg3MSMwIQYDVQQLExpodHRwOi8vd3d3LmNoYW1i
1308
+ ZXJzaWduLm9yZzEiMCAGA1UEAxMZQ2hhbWJlcnMgb2YgQ29tbWVyY2UgUm9vdDAeFw0wMzA5MzAx
1309
+ NjEzNDNaFw0zNzA5MzAxNjEzNDRaMH8xCzAJBgNVBAYTAkVVMScwJQYDVQQKEx5BQyBDYW1lcmZp
1310
+ cm1hIFNBIENJRiBBODI3NDMyODcxIzAhBgNVBAsTGmh0dHA6Ly93d3cuY2hhbWJlcnNpZ24ub3Jn
1311
+ MSIwIAYDVQQDExlDaGFtYmVycyBvZiBDb21tZXJjZSBSb290MIIBIDANBgkqhkiG9w0BAQEFAAOC
1312
+ AQ0AMIIBCAKCAQEAtzZV5aVdGDDg2olUkfzIx1L4L1DZ77F1c2VHfRtbunXF/KGIJPov7coISjlU
1313
+ xFF6tdpg6jg8gbLL8bvZkSM/SAFwdakFKq0fcfPJVD0dBmpAPrMMhe5cG3nCYsS4No41XQEMIwRH
1314
+ NaqbYE6gZj3LJgqcQKH0XZi/caulAGgq7YN6D6IUtdQis4CwPAxaUWktWBiP7Zme8a7ileb2R6jW
1315
+ DA+wWFjbw2Y3npuRVDM30pQcakjJyfKl2qUMI/cjDpwyVV5xnIQFUZot/eZOKjRa3spAN2cMVCFV
1316
+ d9oKDMyXroDclDZK9D7ONhMeU+SsTjoF7Nuucpw4i9A5O4kKPnf+dQIBA6OCAUQwggFAMBIGA1Ud
1317
+ EwEB/wQIMAYBAf8CAQwwPAYDVR0fBDUwMzAxoC+gLYYraHR0cDovL2NybC5jaGFtYmVyc2lnbi5v
1318
+ cmcvY2hhbWJlcnNyb290LmNybDAdBgNVHQ4EFgQU45T1sU3p26EpW1eLTXYGduHRooowDgYDVR0P
1319
+ AQH/BAQDAgEGMBEGCWCGSAGG+EIBAQQEAwIABzAnBgNVHREEIDAegRxjaGFtYmVyc3Jvb3RAY2hh
1320
+ bWJlcnNpZ24ub3JnMCcGA1UdEgQgMB6BHGNoYW1iZXJzcm9vdEBjaGFtYmVyc2lnbi5vcmcwWAYD
1321
+ VR0gBFEwTzBNBgsrBgEEAYGHLgoDATA+MDwGCCsGAQUFBwIBFjBodHRwOi8vY3BzLmNoYW1iZXJz
1322
+ aWduLm9yZy9jcHMvY2hhbWJlcnNyb290Lmh0bWwwDQYJKoZIhvcNAQEFBQADggEBAAxBl8IahsAi
1323
+ fJ/7kPMa0QOx7xP5IV8EnNrJpY0nbJaHkb5BkAFyk+cefV/2icZdp0AJPaxJRUXcLo0waLIJuvvD
1324
+ L8y6C98/d3tGfToSJI6WjzwFCm/SlCgdbQzALogi1djPHRPH8EjX1wWnz8dHnjs8NMiAT9QUu/wN
1325
+ UPf6s+xCX6ndbcj0dc97wXImsQEcXCz9ek60AcUFV7nnPKoF2YjpB0ZBzu9Bga5Y34OirsrXdx/n
1326
+ ADydb47kMgkdTXg0eDQ8lJsm7U9xxhl6vSAiSFr+S30Dt+dYvsYyTnQeaN2oaFuzPu5ifdmA6Ap1
1327
+ erfutGWaIZDgqtCYvDi1czyL+Nw=
1328
+ -----END CERTIFICATE-----
1329
+
1330
+ Camerfirma Global Chambersign Root
1331
+ ==================================
1332
+ -----BEGIN CERTIFICATE-----
1333
+ MIIExTCCA62gAwIBAgIBADANBgkqhkiG9w0BAQUFADB9MQswCQYDVQQGEwJFVTEnMCUGA1UEChMe
1334
+ QUMgQ2FtZXJmaXJtYSBTQSBDSUYgQTgyNzQzMjg3MSMwIQYDVQQLExpodHRwOi8vd3d3LmNoYW1i
1335
+ ZXJzaWduLm9yZzEgMB4GA1UEAxMXR2xvYmFsIENoYW1iZXJzaWduIFJvb3QwHhcNMDMwOTMwMTYx
1336
+ NDE4WhcNMzcwOTMwMTYxNDE4WjB9MQswCQYDVQQGEwJFVTEnMCUGA1UEChMeQUMgQ2FtZXJmaXJt
1337
+ YSBTQSBDSUYgQTgyNzQzMjg3MSMwIQYDVQQLExpodHRwOi8vd3d3LmNoYW1iZXJzaWduLm9yZzEg
1338
+ MB4GA1UEAxMXR2xvYmFsIENoYW1iZXJzaWduIFJvb3QwggEgMA0GCSqGSIb3DQEBAQUAA4IBDQAw
1339
+ ggEIAoIBAQCicKLQn0KuWxfH2H3PFIP8T8mhtxOviteePgQKkotgVvq0Mi+ITaFgCPS3CU6gSS9J
1340
+ 1tPfnZdan5QEcOw/Wdm3zGaLmFIoCQLfxS+EjXqXd7/sQJ0lcqu1PzKY+7e3/HKE5TWH+VX6ox8O
1341
+ by4o3Wmg2UIQxvi1RMLQQ3/bvOSiPGpVeAp3qdjqGTK3L/5cPxvusZjsyq16aUXjlg9V9ubtdepl
1342
+ 6DJWk0aJqCWKZQbua795B9Dxt6/tLE2Su8CoX6dnfQTyFQhwrJLWfQTSM/tMtgsL+xrJxI0DqX5c
1343
+ 8lCrEqWhz0hQpe/SyBoT+rB/sYIcd2oPX9wLlY/vQ37mRQklAgEDo4IBUDCCAUwwEgYDVR0TAQH/
1344
+ BAgwBgEB/wIBDDA/BgNVHR8EODA2MDSgMqAwhi5odHRwOi8vY3JsLmNoYW1iZXJzaWduLm9yZy9j
1345
+ aGFtYmVyc2lnbnJvb3QuY3JsMB0GA1UdDgQWBBRDnDafsJ4wTcbOX60Qq+UDpfqpFDAOBgNVHQ8B
1346
+ Af8EBAMCAQYwEQYJYIZIAYb4QgEBBAQDAgAHMCoGA1UdEQQjMCGBH2NoYW1iZXJzaWducm9vdEBj
1347
+ aGFtYmVyc2lnbi5vcmcwKgYDVR0SBCMwIYEfY2hhbWJlcnNpZ25yb290QGNoYW1iZXJzaWduLm9y
1348
+ ZzBbBgNVHSAEVDBSMFAGCysGAQQBgYcuCgEBMEEwPwYIKwYBBQUHAgEWM2h0dHA6Ly9jcHMuY2hh
1349
+ bWJlcnNpZ24ub3JnL2Nwcy9jaGFtYmVyc2lnbnJvb3QuaHRtbDANBgkqhkiG9w0BAQUFAAOCAQEA
1350
+ PDtwkfkEVCeR4e3t/mh/YV3lQWVPMvEYBZRqHN4fcNs+ezICNLUMbKGKfKX0j//U2K0X1S0E0T9Y
1351
+ gOKBWYi+wONGkyT+kL0mojAt6JcmVzWJdJYY9hXiryQZVgICsroPFOrGimbBhkVVi76SvpykBMdJ
1352
+ PJ7oKXqJ1/6v/2j1pReQvayZzKWGVwlnRtvWFsJG8eSpUPWP0ZIV018+xgBJOm5YstHRJw0lyDL4
1353
+ IBHNfTIzSJRUTN3cecQwn+uOuFW114hcxWokPbLTBQNRxgfvzBRydD1ucs4YKIxKoHflCStFREes
1354
+ t2d/AYoFWpO+ocH/+OcOZ6RHSXZddZAa9SaP8A==
1355
+ -----END CERTIFICATE-----
1356
+
1357
+ NetLock Qualified (Class QA) Root
1358
+ =================================
1359
+ -----BEGIN CERTIFICATE-----
1360
+ MIIG0TCCBbmgAwIBAgIBezANBgkqhkiG9w0BAQUFADCByTELMAkGA1UEBhMCSFUxETAPBgNVBAcT
1361
+ CEJ1ZGFwZXN0MScwJQYDVQQKEx5OZXRMb2NrIEhhbG96YXRiaXp0b25zYWdpIEtmdC4xGjAYBgNV
1362
+ BAsTEVRhbnVzaXR2YW55a2lhZG9rMUIwQAYDVQQDEzlOZXRMb2NrIE1pbm9zaXRldHQgS296amVn
1363
+ eXpvaSAoQ2xhc3MgUUEpIFRhbnVzaXR2YW55a2lhZG8xHjAcBgkqhkiG9w0BCQEWD2luZm9AbmV0
1364
+ bG9jay5odTAeFw0wMzAzMzAwMTQ3MTFaFw0yMjEyMTUwMTQ3MTFaMIHJMQswCQYDVQQGEwJIVTER
1365
+ MA8GA1UEBxMIQnVkYXBlc3QxJzAlBgNVBAoTHk5ldExvY2sgSGFsb3phdGJpenRvbnNhZ2kgS2Z0
1366
+ LjEaMBgGA1UECxMRVGFudXNpdHZhbnlraWFkb2sxQjBABgNVBAMTOU5ldExvY2sgTWlub3NpdGV0
1367
+ dCBLb3pqZWd5em9pIChDbGFzcyBRQSkgVGFudXNpdHZhbnlraWFkbzEeMBwGCSqGSIb3DQEJARYP
1368
+ aW5mb0BuZXRsb2NrLmh1MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAx1Ilstg91IRV
1369
+ CacbvWy5FPSKAtt2/GoqeKvld/Bu4IwjZ9ulZJm53QE+b+8tmjwi8F3JV6BVQX/yQ15YglMxZc4e
1370
+ 8ia6AFQer7C8HORSjKAyr7c3sVNnaHRnUPYtLmTeriZ539+Zhqurf4XsoPuAzPS4DB6TRWO53Lhb
1371
+ m+1bOdRfYrCnjnxmOCyqsQhjF2d9zL2z8cM/z1A57dEZgxXbhxInlrfa6uWdvLrqOU+L73Sa58XQ
1372
+ 0uqGURzk/mQIKAR5BevKxXEOC++r6uwSEaEYBTJp0QwsGj0lmT+1fMptsK6ZmfoIYOcZwvK9UdPM
1373
+ 0wKswREMgM6r3JSda6M5UzrWhQIDAMV9o4ICwDCCArwwEgYDVR0TAQH/BAgwBgEB/wIBBDAOBgNV
1374
+ HQ8BAf8EBAMCAQYwggJ1BglghkgBhvhCAQ0EggJmFoICYkZJR1lFTEVNISBFemVuIHRhbnVzaXR2
1375
+ YW55IGEgTmV0TG9jayBLZnQuIE1pbm9zaXRldHQgU3pvbGdhbHRhdGFzaSBTemFiYWx5emF0YWJh
1376
+ biBsZWlydCBlbGphcmFzb2sgYWxhcGphbiBrZXN6dWx0LiBBIG1pbm9zaXRldHQgZWxla3Ryb25p
1377
+ a3VzIGFsYWlyYXMgam9naGF0YXMgZXJ2ZW55ZXN1bGVzZW5laywgdmFsYW1pbnQgZWxmb2dhZGFz
1378
+ YW5hayBmZWx0ZXRlbGUgYSBNaW5vc2l0ZXR0IFN6b2xnYWx0YXRhc2kgU3phYmFseXphdGJhbiwg
1379
+ YXogQWx0YWxhbm9zIFN6ZXJ6b2Rlc2kgRmVsdGV0ZWxla2JlbiBlbG9pcnQgZWxsZW5vcnplc2kg
1380
+ ZWxqYXJhcyBtZWd0ZXRlbGUuIEEgZG9rdW1lbnR1bW9rIG1lZ3RhbGFsaGF0b2sgYSBodHRwczov
1381
+ L3d3dy5uZXRsb2NrLmh1L2RvY3MvIGNpbWVuIHZhZ3kga2VyaGV0b2sgYXogaW5mb0BuZXRsb2Nr
1382
+ Lm5ldCBlLW1haWwgY2ltZW4uIFdBUk5JTkchIFRoZSBpc3N1YW5jZSBhbmQgdGhlIHVzZSBvZiB0
1383
+ aGlzIGNlcnRpZmljYXRlIGFyZSBzdWJqZWN0IHRvIHRoZSBOZXRMb2NrIFF1YWxpZmllZCBDUFMg
1384
+ YXZhaWxhYmxlIGF0IGh0dHBzOi8vd3d3Lm5ldGxvY2suaHUvZG9jcy8gb3IgYnkgZS1tYWlsIGF0
1385
+ IGluZm9AbmV0bG9jay5uZXQwHQYDVR0OBBYEFAlqYhaSsFq7VQ7LdTI6MuWyIckoMA0GCSqGSIb3
1386
+ DQEBBQUAA4IBAQCRalCc23iBmz+LQuM7/KbD7kPgz/PigDVJRXYC4uMvBcXxKufAQTPGtpvQMznN
1387
+ wNuhrWw3AkxYQTvyl5LGSKjN5Yo5iWH5Upfpvfb5lHTocQ68d4bDBsxafEp+NFAwLvt/MpqNPfMg
1388
+ W/hqyobzMUwsWYACff44yTB1HLdV47yfuqhthCgFdbOLDcCRVCHnpgu0mfVRQdzNo0ci2ccBgcTc
1389
+ R08m6h/t280NmPSjnLRzMkqWmf68f8glWPhY83ZmiVSkpj7EUFy6iRiCdUgh0k8T6GB+B3bbELVR
1390
+ 5qq5aKrN9p2QdRLqOBrKROi3macqaJVmlaut74nLYKkGEsaUR+ko
1391
+ -----END CERTIFICATE-----
1392
+
1393
+ NetLock Notary (Class A) Root
1394
+ =============================
1395
+ -----BEGIN CERTIFICATE-----
1396
+ MIIGfTCCBWWgAwIBAgICAQMwDQYJKoZIhvcNAQEEBQAwga8xCzAJBgNVBAYTAkhVMRAwDgYDVQQI
1397
+ EwdIdW5nYXJ5MREwDwYDVQQHEwhCdWRhcGVzdDEnMCUGA1UEChMeTmV0TG9jayBIYWxvemF0Yml6
1398
+ dG9uc2FnaSBLZnQuMRowGAYDVQQLExFUYW51c2l0dmFueWtpYWRvazE2MDQGA1UEAxMtTmV0TG9j
1399
+ ayBLb3pqZWd5em9pIChDbGFzcyBBKSBUYW51c2l0dmFueWtpYWRvMB4XDTk5MDIyNDIzMTQ0N1oX
1400
+ DTE5MDIxOTIzMTQ0N1owga8xCzAJBgNVBAYTAkhVMRAwDgYDVQQIEwdIdW5nYXJ5MREwDwYDVQQH
1401
+ EwhCdWRhcGVzdDEnMCUGA1UEChMeTmV0TG9jayBIYWxvemF0Yml6dG9uc2FnaSBLZnQuMRowGAYD
1402
+ VQQLExFUYW51c2l0dmFueWtpYWRvazE2MDQGA1UEAxMtTmV0TG9jayBLb3pqZWd5em9pIChDbGFz
1403
+ cyBBKSBUYW51c2l0dmFueWtpYWRvMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvHSM
1404
+ D7tM9DceqQWC2ObhbHDqeLVu0ThEDaiDzl3S1tWBxdRL51uUcCbbO51qTGL3cfNk1mE7PetzozfZ
1405
+ z+qMkjvN9wfcZnSX9EUi3fRc4L9t875lM+QVOr/bmJBVOMTtplVjC7B4BPTjbsE/jvxReB+SnoPC
1406
+ /tmwqcm8WgD/qaiYdPv2LD4VOQ22BFWoDpggQrOxJa1+mm9dU7GrDPzr4PN6s6iz/0b2Y6LYOph7
1407
+ tqyF/7AlT3Rj5xMHpQqPBffAZG9+pyeAlt7ULoZgx2srXnN7F+eRP2QM2EsiNCubMvJIH5+hCoR6
1408
+ 4sKtlz2O1cH5VqNQ6ca0+pii7pXmKgOM3wIDAQABo4ICnzCCApswDgYDVR0PAQH/BAQDAgAGMBIG
1409
+ A1UdEwEB/wQIMAYBAf8CAQQwEQYJYIZIAYb4QgEBBAQDAgAHMIICYAYJYIZIAYb4QgENBIICURaC
1410
+ Ak1GSUdZRUxFTSEgRXplbiB0YW51c2l0dmFueSBhIE5ldExvY2sgS2Z0LiBBbHRhbGFub3MgU3pv
1411
+ bGdhbHRhdGFzaSBGZWx0ZXRlbGVpYmVuIGxlaXJ0IGVsamFyYXNvayBhbGFwamFuIGtlc3p1bHQu
1412
+ IEEgaGl0ZWxlc2l0ZXMgZm9seWFtYXRhdCBhIE5ldExvY2sgS2Z0LiB0ZXJtZWtmZWxlbG9zc2Vn
1413
+ LWJpenRvc2l0YXNhIHZlZGkuIEEgZGlnaXRhbGlzIGFsYWlyYXMgZWxmb2dhZGFzYW5hayBmZWx0
1414
+ ZXRlbGUgYXogZWxvaXJ0IGVsbGVub3J6ZXNpIGVsamFyYXMgbWVndGV0ZWxlLiBBeiBlbGphcmFz
1415
+ IGxlaXJhc2EgbWVndGFsYWxoYXRvIGEgTmV0TG9jayBLZnQuIEludGVybmV0IGhvbmxhcGphbiBh
1416
+ IGh0dHBzOi8vd3d3Lm5ldGxvY2submV0L2RvY3MgY2ltZW4gdmFneSBrZXJoZXRvIGF6IGVsbGVu
1417
+ b3J6ZXNAbmV0bG9jay5uZXQgZS1tYWlsIGNpbWVuLiBJTVBPUlRBTlQhIFRoZSBpc3N1YW5jZSBh
1418
+ bmQgdGhlIHVzZSBvZiB0aGlzIGNlcnRpZmljYXRlIGlzIHN1YmplY3QgdG8gdGhlIE5ldExvY2sg
1419
+ Q1BTIGF2YWlsYWJsZSBhdCBodHRwczovL3d3dy5uZXRsb2NrLm5ldC9kb2NzIG9yIGJ5IGUtbWFp
1420
+ bCBhdCBjcHNAbmV0bG9jay5uZXQuMA0GCSqGSIb3DQEBBAUAA4IBAQBIJEb3ulZv+sgoA0BO5TE5
1421
+ ayZrU3/b39/zcT0mwBQOxmd7I6gMc90Bu8bKbjc5VdXHjFYgDigKDtIqpLBJUsY4B/6+CgmM0ZjP
1422
+ ytoUMaFP0jn8DxEsQ8Pdq5PHVT5HfBgaANzze9jyf1JsIPQLX2lS9O74silg6+NJMSEN1rUQQeJB
1423
+ CWziGppWS3cC9qCbmieH6FUpccKQn0V4GuEVZD3QDtigdp+uxdAu6tYPVuxkf1qbFFgBJ34TUMdr
1424
+ KuZoPL9coAob4Q566eKAw+np9v1sEZ7Q5SgnK1QyQhSCdeZK8CtmdWOMovsEPoMOmzbwGOQmIMOM
1425
+ 8CgHrTwXZoi1/baI
1426
+ -----END CERTIFICATE-----
1427
+
1428
+ NetLock Business (Class B) Root
1429
+ ===============================
1430
+ -----BEGIN CERTIFICATE-----
1431
+ MIIFSzCCBLSgAwIBAgIBaTANBgkqhkiG9w0BAQQFADCBmTELMAkGA1UEBhMCSFUxETAPBgNVBAcT
1432
+ CEJ1ZGFwZXN0MScwJQYDVQQKEx5OZXRMb2NrIEhhbG96YXRiaXp0b25zYWdpIEtmdC4xGjAYBgNV
1433
+ BAsTEVRhbnVzaXR2YW55a2lhZG9rMTIwMAYDVQQDEylOZXRMb2NrIFV6bGV0aSAoQ2xhc3MgQikg
1434
+ VGFudXNpdHZhbnlraWFkbzAeFw05OTAyMjUxNDEwMjJaFw0xOTAyMjAxNDEwMjJaMIGZMQswCQYD
1435
+ VQQGEwJIVTERMA8GA1UEBxMIQnVkYXBlc3QxJzAlBgNVBAoTHk5ldExvY2sgSGFsb3phdGJpenRv
1436
+ bnNhZ2kgS2Z0LjEaMBgGA1UECxMRVGFudXNpdHZhbnlraWFkb2sxMjAwBgNVBAMTKU5ldExvY2sg
1437
+ VXpsZXRpIChDbGFzcyBCKSBUYW51c2l0dmFueWtpYWRvMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCB
1438
+ iQKBgQCx6gTsIKAjwo84YM/HRrPVG/77uZmeBNwcf4xKgZjupNTKihe5In+DCnVMm8Bp2GQ5o+2S
1439
+ o/1bXHQawEfKOml2mrriRBf8TKPV/riXiK+IA4kfpPIEPsgHC+b5sy96YhQJRhTKZPWLgLViqNhr
1440
+ 1nGTLbO/CVRY7QbrqHvcQ7GhaQIDAQABo4ICnzCCApswEgYDVR0TAQH/BAgwBgEB/wIBBDAOBgNV
1441
+ HQ8BAf8EBAMCAAYwEQYJYIZIAYb4QgEBBAQDAgAHMIICYAYJYIZIAYb4QgENBIICURaCAk1GSUdZ
1442
+ RUxFTSEgRXplbiB0YW51c2l0dmFueSBhIE5ldExvY2sgS2Z0LiBBbHRhbGFub3MgU3pvbGdhbHRh
1443
+ dGFzaSBGZWx0ZXRlbGVpYmVuIGxlaXJ0IGVsamFyYXNvayBhbGFwamFuIGtlc3p1bHQuIEEgaGl0
1444
+ ZWxlc2l0ZXMgZm9seWFtYXRhdCBhIE5ldExvY2sgS2Z0LiB0ZXJtZWtmZWxlbG9zc2VnLWJpenRv
1445
+ c2l0YXNhIHZlZGkuIEEgZGlnaXRhbGlzIGFsYWlyYXMgZWxmb2dhZGFzYW5hayBmZWx0ZXRlbGUg
1446
+ YXogZWxvaXJ0IGVsbGVub3J6ZXNpIGVsamFyYXMgbWVndGV0ZWxlLiBBeiBlbGphcmFzIGxlaXJh
1447
+ c2EgbWVndGFsYWxoYXRvIGEgTmV0TG9jayBLZnQuIEludGVybmV0IGhvbmxhcGphbiBhIGh0dHBz
1448
+ Oi8vd3d3Lm5ldGxvY2submV0L2RvY3MgY2ltZW4gdmFneSBrZXJoZXRvIGF6IGVsbGVub3J6ZXNA
1449
+ bmV0bG9jay5uZXQgZS1tYWlsIGNpbWVuLiBJTVBPUlRBTlQhIFRoZSBpc3N1YW5jZSBhbmQgdGhl
1450
+ IHVzZSBvZiB0aGlzIGNlcnRpZmljYXRlIGlzIHN1YmplY3QgdG8gdGhlIE5ldExvY2sgQ1BTIGF2
1451
+ YWlsYWJsZSBhdCBodHRwczovL3d3dy5uZXRsb2NrLm5ldC9kb2NzIG9yIGJ5IGUtbWFpbCBhdCBj
1452
+ cHNAbmV0bG9jay5uZXQuMA0GCSqGSIb3DQEBBAUAA4GBAATbrowXr/gOkDFOzT4JwG06sPgzTEdM
1453
+ 43WIEJessDgVkcYplswhwG08pXTP2IKlOcNl40JwuyKQ433bNXbhoLXan3BukxowOR0w2y7jfLKR
1454
+ stE3Kfq51hdcR0/jHTjrn9V7lagonhVK0dHQKwCXoOKSNitjrFgBazMpUIaD8QFI
1455
+ -----END CERTIFICATE-----
1456
+
1457
+ NetLock Express (Class C) Root
1458
+ ==============================
1459
+ -----BEGIN CERTIFICATE-----
1460
+ MIIFTzCCBLigAwIBAgIBaDANBgkqhkiG9w0BAQQFADCBmzELMAkGA1UEBhMCSFUxETAPBgNVBAcT
1461
+ CEJ1ZGFwZXN0MScwJQYDVQQKEx5OZXRMb2NrIEhhbG96YXRiaXp0b25zYWdpIEtmdC4xGjAYBgNV
1462
+ BAsTEVRhbnVzaXR2YW55a2lhZG9rMTQwMgYDVQQDEytOZXRMb2NrIEV4cHJlc3N6IChDbGFzcyBD
1463
+ KSBUYW51c2l0dmFueWtpYWRvMB4XDTk5MDIyNTE0MDgxMVoXDTE5MDIyMDE0MDgxMVowgZsxCzAJ
1464
+ BgNVBAYTAkhVMREwDwYDVQQHEwhCdWRhcGVzdDEnMCUGA1UEChMeTmV0TG9jayBIYWxvemF0Yml6
1465
+ dG9uc2FnaSBLZnQuMRowGAYDVQQLExFUYW51c2l0dmFueWtpYWRvazE0MDIGA1UEAxMrTmV0TG9j
1466
+ ayBFeHByZXNzeiAoQ2xhc3MgQykgVGFudXNpdHZhbnlraWFkbzCBnzANBgkqhkiG9w0BAQEFAAOB
1467
+ jQAwgYkCgYEA6+ywbGGKIyWvYCDj2Z/8kwvbXY2wobNAOoLO/XXgeDIDhlqGlZHtU/qdQPzm6N3Z
1468
+ W3oDvV3zOwzDUXmbrVWg6dADEK8KuhRC2VImESLH0iDMgqSaqf64gXadarfSNnU+sYYJ9m5tfk63
1469
+ euyucYT2BDMIJTLrdKwWRMbkQJMdf60CAwEAAaOCAp8wggKbMBIGA1UdEwEB/wQIMAYBAf8CAQQw
1470
+ DgYDVR0PAQH/BAQDAgAGMBEGCWCGSAGG+EIBAQQEAwIABzCCAmAGCWCGSAGG+EIBDQSCAlEWggJN
1471
+ RklHWUVMRU0hIEV6ZW4gdGFudXNpdHZhbnkgYSBOZXRMb2NrIEtmdC4gQWx0YWxhbm9zIFN6b2xn
1472
+ YWx0YXRhc2kgRmVsdGV0ZWxlaWJlbiBsZWlydCBlbGphcmFzb2sgYWxhcGphbiBrZXN6dWx0LiBB
1473
+ IGhpdGVsZXNpdGVzIGZvbHlhbWF0YXQgYSBOZXRMb2NrIEtmdC4gdGVybWVrZmVsZWxvc3NlZy1i
1474
+ aXp0b3NpdGFzYSB2ZWRpLiBBIGRpZ2l0YWxpcyBhbGFpcmFzIGVsZm9nYWRhc2FuYWsgZmVsdGV0
1475
+ ZWxlIGF6IGVsb2lydCBlbGxlbm9yemVzaSBlbGphcmFzIG1lZ3RldGVsZS4gQXogZWxqYXJhcyBs
1476
+ ZWlyYXNhIG1lZ3RhbGFsaGF0byBhIE5ldExvY2sgS2Z0LiBJbnRlcm5ldCBob25sYXBqYW4gYSBo
1477
+ dHRwczovL3d3dy5uZXRsb2NrLm5ldC9kb2NzIGNpbWVuIHZhZ3kga2VyaGV0byBheiBlbGxlbm9y
1478
+ emVzQG5ldGxvY2submV0IGUtbWFpbCBjaW1lbi4gSU1QT1JUQU5UISBUaGUgaXNzdWFuY2UgYW5k
1479
+ IHRoZSB1c2Ugb2YgdGhpcyBjZXJ0aWZpY2F0ZSBpcyBzdWJqZWN0IHRvIHRoZSBOZXRMb2NrIENQ
1480
+ UyBhdmFpbGFibGUgYXQgaHR0cHM6Ly93d3cubmV0bG9jay5uZXQvZG9jcyBvciBieSBlLW1haWwg
1481
+ YXQgY3BzQG5ldGxvY2submV0LjANBgkqhkiG9w0BAQQFAAOBgQAQrX/XDDKACtiG8XmYta3UzbM2
1482
+ xJZIwVzNmtkFLp++UOv0JhQQLdRmF/iewSf98e3ke0ugbLWrmldwpu2gpO0u9f38vf5NNwgMvOOW
1483
+ gyL1SRt/Syu0VMGAfJlOHdCM7tCs5ZL6dVb+ZKATj7i4Fp1hBWeAyNDYpQcCNJgEjTME1A==
1484
+ -----END CERTIFICATE-----
1485
+
1486
+ XRamp Global CA Root
1487
+ ====================
1488
+ -----BEGIN CERTIFICATE-----
1489
+ MIIEMDCCAxigAwIBAgIQUJRs7Bjq1ZxN1ZfvdY+grTANBgkqhkiG9w0BAQUFADCBgjELMAkGA1UE
1490
+ BhMCVVMxHjAcBgNVBAsTFXd3dy54cmFtcHNlY3VyaXR5LmNvbTEkMCIGA1UEChMbWFJhbXAgU2Vj
1491
+ dXJpdHkgU2VydmljZXMgSW5jMS0wKwYDVQQDEyRYUmFtcCBHbG9iYWwgQ2VydGlmaWNhdGlvbiBB
1492
+ dXRob3JpdHkwHhcNMDQxMTAxMTcxNDA0WhcNMzUwMTAxMDUzNzE5WjCBgjELMAkGA1UEBhMCVVMx
1493
+ HjAcBgNVBAsTFXd3dy54cmFtcHNlY3VyaXR5LmNvbTEkMCIGA1UEChMbWFJhbXAgU2VjdXJpdHkg
1494
+ U2VydmljZXMgSW5jMS0wKwYDVQQDEyRYUmFtcCBHbG9iYWwgQ2VydGlmaWNhdGlvbiBBdXRob3Jp
1495
+ dHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCYJB69FbS638eMpSe2OAtp87ZOqCwu
1496
+ IR1cRN8hXX4jdP5efrRKt6atH67gBhbim1vZZ3RrXYCPKZ2GG9mcDZhtdhAoWORlsH9KmHmf4MMx
1497
+ foArtYzAQDsRhtDLooY2YKTVMIJt2W7QDxIEM5dfT2Fa8OT5kavnHTu86M/0ay00fOJIYRyO82FE
1498
+ zG+gSqmUsE3a56k0enI4qEHMPJQRfevIpoy3hsvKMzvZPTeL+3o+hiznc9cKV6xkmxnr9A8ECIqs
1499
+ AxcZZPRaJSKNNCyy9mgdEm3Tih4U2sSPpuIjhdV6Db1q4Ons7Be7QhtnqiXtRYMh/MHJfNViPvry
1500
+ xS3T/dRlAgMBAAGjgZ8wgZwwEwYJKwYBBAGCNxQCBAYeBABDAEEwCwYDVR0PBAQDAgGGMA8GA1Ud
1501
+ EwEB/wQFMAMBAf8wHQYDVR0OBBYEFMZPoj0GY4QJnM5i5ASsjVy16bYbMDYGA1UdHwQvMC0wK6Ap
1502
+ oCeGJWh0dHA6Ly9jcmwueHJhbXBzZWN1cml0eS5jb20vWEdDQS5jcmwwEAYJKwYBBAGCNxUBBAMC
1503
+ AQEwDQYJKoZIhvcNAQEFBQADggEBAJEVOQMBG2f7Shz5CmBbodpNl2L5JFMn14JkTpAuw0kbK5rc
1504
+ /Kh4ZzXxHfARvbdI4xD2Dd8/0sm2qlWkSLoC295ZLhVbO50WfUfXN+pfTXYSNrsf16GBBEYgoyxt
1505
+ qZ4Bfj8pzgCT3/3JknOJiWSe5yvkHJEs0rnOfc5vMZnT5r7SHpDwCRR5XCOrTdLaIR9NmXmd4c8n
1506
+ nxCbHIgNsIpkQTG4DmyQJKSbXHGPurt+HBvbaoAPIbzp26a3QPSyi6mx5O+aGtA9aZnuqCij4Tyz
1507
+ 8LIRnM98QObd50N9otg6tamN8jSZxNQQ4Qb9CYQQO+7ETPTsJ3xCwnR8gooJybQDJbw=
1508
+ -----END CERTIFICATE-----
1509
+
1510
+ Go Daddy Class 2 CA
1511
+ ===================
1512
+ -----BEGIN CERTIFICATE-----
1513
+ MIIEADCCAuigAwIBAgIBADANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEhMB8GA1UEChMY
1514
+ VGhlIEdvIERhZGR5IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBEYWRkeSBDbGFzcyAyIENlcnRp
1515
+ ZmljYXRpb24gQXV0aG9yaXR5MB4XDTA0MDYyOTE3MDYyMFoXDTM0MDYyOTE3MDYyMFowYzELMAkG
1516
+ A1UEBhMCVVMxITAfBgNVBAoTGFRoZSBHbyBEYWRkeSBHcm91cCwgSW5jLjExMC8GA1UECxMoR28g
1517
+ RGFkZHkgQ2xhc3MgMiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASAwDQYJKoZIhvcNAQEBBQAD
1518
+ ggENADCCAQgCggEBAN6d1+pXGEmhW+vXX0iG6r7d/+TvZxz0ZWizV3GgXne77ZtJ6XCAPVYYYwhv
1519
+ 2vLM0D9/AlQiVBDYsoHUwHU9S3/Hd8M+eKsaA7Ugay9qK7HFiH7Eux6wwdhFJ2+qN1j3hybX2C32
1520
+ qRe3H3I2TqYXP2WYktsqbl2i/ojgC95/5Y0V4evLOtXiEqITLdiOr18SPaAIBQi2XKVlOARFmR6j
1521
+ YGB0xUGlcmIbYsUfb18aQr4CUWWoriMYavx4A6lNf4DD+qta/KFApMoZFv6yyO9ecw3ud72a9nmY
1522
+ vLEHZ6IVDd2gWMZEewo+YihfukEHU1jPEX44dMX4/7VpkI+EdOqXG68CAQOjgcAwgb0wHQYDVR0O
1523
+ BBYEFNLEsNKR1EwRcbNhyz2h/t2oatTjMIGNBgNVHSMEgYUwgYKAFNLEsNKR1EwRcbNhyz2h/t2o
1524
+ atTjoWekZTBjMQswCQYDVQQGEwJVUzEhMB8GA1UEChMYVGhlIEdvIERhZGR5IEdyb3VwLCBJbmMu
1525
+ MTEwLwYDVQQLEyhHbyBEYWRkeSBDbGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggEAMAwG
1526
+ A1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBADJL87LKPpH8EsahB4yOd6AzBhRckB4Y9wim
1527
+ PQoZ+YeAEW5p5JYXMP80kWNyOO7MHAGjHZQopDH2esRU1/blMVgDoszOYtuURXO1v0XJJLXVggKt
1528
+ I3lpjbi2Tc7PTMozI+gciKqdi0FuFskg5YmezTvacPd+mSYgFFQlq25zheabIZ0KbIIOqPjCDPoQ
1529
+ HmyW74cNxA9hi63ugyuV+I6ShHI56yDqg+2DzZduCLzrTia2cyvk0/ZM/iZx4mERdEr/VxqHD3VI
1530
+ Ls9RaRegAhJhldXRQLIQTO7ErBBDpqWeCtWVYpoNz4iCxTIM5CufReYNnyicsbkqWletNw+vHX/b
1531
+ vZ8=
1532
+ -----END CERTIFICATE-----
1533
+
1534
+ Starfield Class 2 CA
1535
+ ====================
1536
+ -----BEGIN CERTIFICATE-----
1537
+ MIIEDzCCAvegAwIBAgIBADANBgkqhkiG9w0BAQUFADBoMQswCQYDVQQGEwJVUzElMCMGA1UEChMc
1538
+ U3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UECxMpU3RhcmZpZWxkIENsYXNzIDIg
1539
+ Q2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDQwNjI5MTczOTE2WhcNMzQwNjI5MTczOTE2WjBo
1540
+ MQswCQYDVQQGEwJVUzElMCMGA1UEChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAG
1541
+ A1UECxMpU3RhcmZpZWxkIENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggEgMA0GCSqG
1542
+ SIb3DQEBAQUAA4IBDQAwggEIAoIBAQC3Msj+6XGmBIWtDBFk385N78gDGIc/oav7PKaf8MOh2tTY
1543
+ bitTkPskpD6E8J7oX+zlJ0T1KKY/e97gKvDIr1MvnsoFAZMej2YcOadN+lq2cwQlZut3f+dZxkqZ
1544
+ JRRU6ybH838Z1TBwj6+wRir/resp7defqgSHo9T5iaU0X9tDkYI22WY8sbi5gv2cOj4QyDvvBmVm
1545
+ epsZGD3/cVE8MC5fvj13c7JdBmzDI1aaK4UmkhynArPkPw2vCHmCuDY96pzTNbO8acr1zJ3o/WSN
1546
+ F4Azbl5KXZnJHoe0nRrA1W4TNSNe35tfPe/W93bC6j67eA0cQmdrBNj41tpvi/JEoAGrAgEDo4HF
1547
+ MIHCMB0GA1UdDgQWBBS/X7fRzt0fhvRbVazc1xDCDqmI5zCBkgYDVR0jBIGKMIGHgBS/X7fRzt0f
1548
+ hvRbVazc1xDCDqmI56FspGowaDELMAkGA1UEBhMCVVMxJTAjBgNVBAoTHFN0YXJmaWVsZCBUZWNo
1549
+ bm9sb2dpZXMsIEluYy4xMjAwBgNVBAsTKVN0YXJmaWVsZCBDbGFzcyAyIENlcnRpZmljYXRpb24g
1550
+ QXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAAWdP4id0ckaVaGs
1551
+ afPzWdqbAYcaT1epoXkJKtv3L7IezMdeatiDh6GX70k1PncGQVhiv45YuApnP+yz3SFmH8lU+nLM
1552
+ PUxA2IGvd56Deruix/U0F47ZEUD0/CwqTRV/p2JdLiXTAAsgGh1o+Re49L2L7ShZ3U0WixeDyLJl
1553
+ xy16paq8U4Zt3VekyvggQQto8PT7dL5WXXp59fkdheMtlb71cZBDzI0fmgAKhynpVSJYACPq4xJD
1554
+ KVtHCN2MQWplBqjlIapBtJUhlbl90TSrE9atvNziPTnNvT51cKEYWQPJIrSPnNVeKtelttQKbfi3
1555
+ QBFGmh95DmK/D5fs4C8fF5Q=
1556
+ -----END CERTIFICATE-----
1557
+
1558
+ StartCom Certification Authority
1559
+ ================================
1560
+ -----BEGIN CERTIFICATE-----
1561
+ MIIHyTCCBbGgAwIBAgIBATANBgkqhkiG9w0BAQUFADB9MQswCQYDVQQGEwJJTDEWMBQGA1UEChMN
1562
+ U3RhcnRDb20gTHRkLjErMCkGA1UECxMiU2VjdXJlIERpZ2l0YWwgQ2VydGlmaWNhdGUgU2lnbmlu
1563
+ ZzEpMCcGA1UEAxMgU3RhcnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDYwOTE3MTk0
1564
+ NjM2WhcNMzYwOTE3MTk0NjM2WjB9MQswCQYDVQQGEwJJTDEWMBQGA1UEChMNU3RhcnRDb20gTHRk
1565
+ LjErMCkGA1UECxMiU2VjdXJlIERpZ2l0YWwgQ2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMg
1566
+ U3RhcnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAw
1567
+ ggIKAoICAQDBiNsJvGxGfHiflXu1M5DycmLWwTYgIiRezul38kMKogZkpMyONvg45iPwbm2xPN1y
1568
+ o4UcodM9tDMr0y+v/uqwQVlntsQGfQqedIXWeUyAN3rfOQVSWff0G0ZDpNKFhdLDcfN1YjS6LIp/
1569
+ Ho/u7TTQEceWzVI9ujPW3U3eCztKS5/CJi/6tRYccjV3yjxd5srhJosaNnZcAdt0FCX+7bWgiA/d
1570
+ eMotHweXMAEtcnn6RtYTKqi5pquDSR3l8u/d5AGOGAqPY1MWhWKpDhk6zLVmpsJrdAfkK+F2PrRt
1571
+ 2PZE4XNiHzvEvqBTViVsUQn3qqvKv3b9bZvzndu/PWa8DFaqr5hIlTpL36dYUNk4dalb6kMMAv+Z
1572
+ 6+hsTXBbKWWc3apdzK8BMewM69KN6Oqce+Zu9ydmDBpI125C4z/eIT574Q1w+2OqqGwaVLRcJXrJ
1573
+ osmLFqa7LH4XXgVNWG4SHQHuEhANxjJ/GP/89PrNbpHoNkm+Gkhpi8KWTRoSsmkXwQqQ1vp5Iki/
1574
+ untp+HDH+no32NgN0nZPV/+Qt+OR0t3vwmC3Zzrd/qqc8NSLf3Iizsafl7b4r4qgEKjZ+xjGtrVc
1575
+ UjyJthkqcwEKDwOzEmDyei+B26Nu/yYwl/WL3YlXtq09s68rxbd2AvCl1iuahhQqcvbjM4xdCUsT
1576
+ 37uMdBNSSwIDAQABo4ICUjCCAk4wDAYDVR0TBAUwAwEB/zALBgNVHQ8EBAMCAa4wHQYDVR0OBBYE
1577
+ FE4L7xqkQFulF2mHMMo0aEPQQa7yMGQGA1UdHwRdMFswLKAqoCiGJmh0dHA6Ly9jZXJ0LnN0YXJ0
1578
+ Y29tLm9yZy9zZnNjYS1jcmwuY3JsMCugKaAnhiVodHRwOi8vY3JsLnN0YXJ0Y29tLm9yZy9zZnNj
1579
+ YS1jcmwuY3JsMIIBXQYDVR0gBIIBVDCCAVAwggFMBgsrBgEEAYG1NwEBATCCATswLwYIKwYBBQUH
1580
+ AgEWI2h0dHA6Ly9jZXJ0LnN0YXJ0Y29tLm9yZy9wb2xpY3kucGRmMDUGCCsGAQUFBwIBFilodHRw
1581
+ Oi8vY2VydC5zdGFydGNvbS5vcmcvaW50ZXJtZWRpYXRlLnBkZjCB0AYIKwYBBQUHAgIwgcMwJxYg
1582
+ U3RhcnQgQ29tbWVyY2lhbCAoU3RhcnRDb20pIEx0ZC4wAwIBARqBl0xpbWl0ZWQgTGlhYmlsaXR5
1583
+ LCByZWFkIHRoZSBzZWN0aW9uICpMZWdhbCBMaW1pdGF0aW9ucyogb2YgdGhlIFN0YXJ0Q29tIENl
1584
+ cnRpZmljYXRpb24gQXV0aG9yaXR5IFBvbGljeSBhdmFpbGFibGUgYXQgaHR0cDovL2NlcnQuc3Rh
1585
+ cnRjb20ub3JnL3BvbGljeS5wZGYwEQYJYIZIAYb4QgEBBAQDAgAHMDgGCWCGSAGG+EIBDQQrFilT
1586
+ dGFydENvbSBGcmVlIFNTTCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTANBgkqhkiG9w0BAQUFAAOC
1587
+ AgEAFmyZ9GYMNPXQhV59CuzaEE44HF7fpiUFS5Eyweg78T3dRAlbB0mKKctmArexmvclmAk8jhvh
1588
+ 3TaHK0u7aNM5Zj2gJsfyOZEdUauCe37Vzlrk4gNXcGmXCPleWKYK34wGmkUWFjgKXlf2Ysd6AgXm
1589
+ vB618p70qSmD+LIU424oh0TDkBreOKk8rENNZEXO3SipXPJzewT4F+irsfMuXGRuczE6Eri8sxHk
1590
+ fY+BUZo7jYn0TZNmezwD7dOaHZrzZVD1oNB1ny+v8OqCQ5j4aZyJecRDjkZy42Q2Eq/3JR44iZB3
1591
+ fsNrarnDy0RLrHiQi+fHLB5LEUTINFInzQpdn4XBidUaePKVEFMy3YCEZnXZtWgo+2EuvoSoOMCZ
1592
+ EoalHmdkrQYuL6lwhceWD3yJZfWOQ1QOq92lgDmUYMA0yZZwLKMS9R9Ie70cfmu3nZD0Ijuu+Pwq
1593
+ yvqCUqDvr0tVk+vBtfAii6w0TiYiBKGHLHVKt+V9E9e4DGTANtLJL4YSjCMJwRuCO3NJo2pXh5Tl
1594
+ 1njFmUNj403gdy3hZZlyaQQaRwnmDwFWJPsfvw55qVguucQJAX6Vum0ABj6y6koQOdjQK/W/7HW/
1595
+ lwLFCRsI3FU34oH7N4RDYiDK51ZLZer+bMEkkyShNOsF/5oirpt9P/FlUQqmMGqz9IgcgA38coro
1596
+ g14=
1597
+ -----END CERTIFICATE-----
1598
+
1599
+ Taiwan GRCA
1600
+ ===========
1601
+ -----BEGIN CERTIFICATE-----
1602
+ MIIFcjCCA1qgAwIBAgIQH51ZWtcvwgZEpYAIaeNe9jANBgkqhkiG9w0BAQUFADA/MQswCQYDVQQG
1603
+ EwJUVzEwMC4GA1UECgwnR292ZXJubWVudCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4X
1604
+ DTAyMTIwNTEzMjMzM1oXDTMyMTIwNTEzMjMzM1owPzELMAkGA1UEBhMCVFcxMDAuBgNVBAoMJ0dv
1605
+ dmVybm1lbnQgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCAiIwDQYJKoZIhvcNAQEBBQAD
1606
+ ggIPADCCAgoCggIBAJoluOzMonWoe/fOW1mKydGGEghU7Jzy50b2iPN86aXfTEc2pBsBHH8eV4qN
1607
+ w8XRIePaJD9IK/ufLqGU5ywck9G/GwGHU5nOp/UKIXZ3/6m3xnOUT0b3EEk3+qhZSV1qgQdW8or5
1608
+ BtD3cCJNtLdBuTK4sfCxw5w/cP1T3YGq2GN49thTbqGsaoQkclSGxtKyyhwOeYHWtXBiCAEuTk8O
1609
+ 1RGvqa/lmr/czIdtJuTJV6L7lvnM4T9TjGxMfptTCAtsF/tnyMKtsc2AtJfcdgEWFelq16TheEfO
1610
+ htX7MfP6Mb40qij7cEwdScevLJ1tZqa2jWR+tSBqnTuBto9AAGdLiYa4zGX+FVPpBMHWXx1E1wov
1611
+ J5pGfaENda1UhhXcSTvxls4Pm6Dso3pdvtUqdULle96ltqqvKKyskKw4t9VoNSZ63Pc78/1Fm9G7
1612
+ Q3hub/FCVGqY8A2tl+lSXunVanLeavcbYBT0peS2cWeqH+riTcFCQP5nRhc4L0c/cZyu5SHKYS1t
1613
+ B6iEfC3uUSXxY5Ce/eFXiGvviiNtsea9P63RPZYLhY3Naye7twWb7LuRqQoHEgKXTiCQ8P8NHuJB
1614
+ O9NAOueNXdpm5AKwB1KYXA6OM5zCppX7VRluTI6uSw+9wThNXo+EHWbNxWCWtFJaBYmOlXqYwZE8
1615
+ lSOyDvR5tMl8wUohAgMBAAGjajBoMB0GA1UdDgQWBBTMzO/MKWCkO7GStjz6MmKPrCUVOzAMBgNV
1616
+ HRMEBTADAQH/MDkGBGcqBwAEMTAvMC0CAQAwCQYFKw4DAhoFADAHBgVnKgMAAAQUA5vwIhP/lSg2
1617
+ 09yewDL7MTqKUWUwDQYJKoZIhvcNAQEFBQADggIBAECASvomyc5eMN1PhnR2WPWus4MzeKR6dBcZ
1618
+ TulStbngCnRiqmjKeKBMmo4sIy7VahIkv9Ro04rQ2JyftB8M3jh+Vzj8jeJPXgyfqzvS/3WXy6Tj
1619
+ Zwj/5cAWtUgBfen5Cv8b5Wppv3ghqMKnI6mGq3ZW6A4M9hPdKmaKZEk9GhiHkASfQlK3T8v+R0F2
1620
+ Ne//AHY2RTKbxkaFXeIksB7jSJaYV0eUVXoPQbFEJPPB/hprv4j9wabak2BegUqZIJxIZhm1AHlU
1621
+ D7gsL0u8qV1bYH+Mh6XgUmMqvtg7hUAV/h62ZT/FS9p+tXo1KaMuephgIqP0fSdOLeq0dDzpD6Qz
1622
+ DxARvBMB1uUO07+1EqLhRSPAzAhuYbeJq4PjJB7mXQfnHyA+z2fI56wwbSdLaG5LKlwCCDTb+Hbk
1623
+ Z6MmnD+iMsJKxYEYMRBWqoTvLQr/uB930r+lWKBi5NdLkXWNiYCYfm3LU05er/ayl4WXudpVBrkk
1624
+ 7tfGOB5jGxI7leFYrPLfhNVfmS8NVVvmONsuP3LpSIXLuykTjx44VbnzssQwmSNOXfJIoRIM3BKQ
1625
+ CZBUkQM8R+XVyWXgt0t97EfTsws+rZ7QdAAO671RrcDeLMDDav7v3Aun+kbfYNucpllQdSNpc5Oy
1626
+ +fwC00fmcc4QAu4njIT/rEUNE1yDMuAlpYYsfPQS
1627
+ -----END CERTIFICATE-----
1628
+
1629
+ Firmaprofesional Root CA
1630
+ ========================
1631
+ -----BEGIN CERTIFICATE-----
1632
+ MIIEVzCCAz+gAwIBAgIBATANBgkqhkiG9w0BAQUFADCBnTELMAkGA1UEBhMCRVMxIjAgBgNVBAcT
1633
+ GUMvIE11bnRhbmVyIDI0NCBCYXJjZWxvbmExQjBABgNVBAMTOUF1dG9yaWRhZCBkZSBDZXJ0aWZp
1634
+ Y2FjaW9uIEZpcm1hcHJvZmVzaW9uYWwgQ0lGIEE2MjYzNDA2ODEmMCQGCSqGSIb3DQEJARYXY2FA
1635
+ ZmlybWFwcm9mZXNpb25hbC5jb20wHhcNMDExMDI0MjIwMDAwWhcNMTMxMDI0MjIwMDAwWjCBnTEL
1636
+ MAkGA1UEBhMCRVMxIjAgBgNVBAcTGUMvIE11bnRhbmVyIDI0NCBCYXJjZWxvbmExQjBABgNVBAMT
1637
+ OUF1dG9yaWRhZCBkZSBDZXJ0aWZpY2FjaW9uIEZpcm1hcHJvZmVzaW9uYWwgQ0lGIEE2MjYzNDA2
1638
+ ODEmMCQGCSqGSIb3DQEJARYXY2FAZmlybWFwcm9mZXNpb25hbC5jb20wggEiMA0GCSqGSIb3DQEB
1639
+ AQUAA4IBDwAwggEKAoIBAQDnIwNvbyOlXnjOlSztlB5uCp4Bx+ow0Syd3Tfom5h5VtP8c9/Qit5V
1640
+ j1H5WuretXDE7aTt/6MNbg9kUDGvASdYrv5sp0ovFy3Tc9UTHI9ZpTQsHVQERc1ouKDAA6XPhUJH
1641
+ lShbz++AbOCQl4oBPB3zhxAwJkh91/zpnZFx/0GaqUC1N5wpIE8fUuOgfRNtVLcK3ulqTgesrBlf
1642
+ 3H5idPayBQC6haD9HThuy1q7hryUZzM1gywfI834yJFxzJeL764P3CkDG8A563DtwW4O2GcLiam8
1643
+ NeTvtjS0pbbELaW+0MOUJEjb35bTALVmGotmBQ/dPz/LP6pemkr4tErvlTcbAgMBAAGjgZ8wgZww
1644
+ KgYDVR0RBCMwIYYfaHR0cDovL3d3dy5maXJtYXByb2Zlc2lvbmFsLmNvbTASBgNVHRMBAf8ECDAG
1645
+ AQH/AgEBMCsGA1UdEAQkMCKADzIwMDExMDI0MjIwMDAwWoEPMjAxMzEwMjQyMjAwMDBaMA4GA1Ud
1646
+ DwEB/wQEAwIBBjAdBgNVHQ4EFgQUMwugZtHq2s7eYpMEKFK1FH84aLcwDQYJKoZIhvcNAQEFBQAD
1647
+ ggEBAEdz/o0nVPD11HecJ3lXV7cVVuzH2Fi3AQL0M+2TUIiefEaxvT8Ub/GzR0iLjJcG1+p+o1wq
1648
+ u00vR+L4OQbJnC4xGgN49Lw4xiKLMzHwFgQEffl25EvXwOaD7FnMP97/T2u3Z36mhoEyIwOdyPdf
1649
+ wUpgpZKpsaSgYMN4h7Mi8yrrW6ntBas3D7Hi05V2Y1Z0jFhyGzflZKG+TQyTmAyX9odtsz/ny4Cm
1650
+ 7YjHX1BiAuiZdBbQ5rQ58SfLyEDW44YQqSMSkuBpQWOnryULwMWSyx6Yo1q6xTMPoJcB3X/ge9YG
1651
+ VM+h4k0460tQtcsm9MracEpqoeJ5quGnM/b9Sh/22WA=
1652
+ -----END CERTIFICATE-----
1653
+
1654
+ Wells Fargo Root CA
1655
+ ===================
1656
+ -----BEGIN CERTIFICATE-----
1657
+ MIID5TCCAs2gAwIBAgIEOeSXnjANBgkqhkiG9w0BAQUFADCBgjELMAkGA1UEBhMCVVMxFDASBgNV
1658
+ BAoTC1dlbGxzIEZhcmdvMSwwKgYDVQQLEyNXZWxscyBGYXJnbyBDZXJ0aWZpY2F0aW9uIEF1dGhv
1659
+ cml0eTEvMC0GA1UEAxMmV2VsbHMgRmFyZ28gUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwHhcN
1660
+ MDAxMDExMTY0MTI4WhcNMjEwMTE0MTY0MTI4WjCBgjELMAkGA1UEBhMCVVMxFDASBgNVBAoTC1dl
1661
+ bGxzIEZhcmdvMSwwKgYDVQQLEyNXZWxscyBGYXJnbyBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEv
1662
+ MC0GA1UEAxMmV2VsbHMgRmFyZ28gUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwggEiMA0GCSqG
1663
+ SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDVqDM7Jvk0/82bfuUER84A4n135zHCLielTWi5MbqNQ1mX
1664
+ x3Oqfz1cQJ4F5aHiidlMuD+b+Qy0yGIZLEWukR5zcUHESxP9cMIlrCL1dQu3U+SlK93OvRw6esP3
1665
+ E48mVJwWa2uv+9iWsWCaSOAlIiR5NM4OJgALTqv9i86C1y8IcGjBqAr5dE8Hq6T54oN+J3N0Prj5
1666
+ OEL8pahbSCOz6+MlsoCultQKnMJ4msZoGK43YjdeUXWoWGPAUe5AeH6orxqg4bB4nVCMe+ez/I4j
1667
+ sNtlAHCEAQgAFG5Uhpq6zPk3EPbg3oQtnaSFN9OH4xXQwReQfhkhahKpdv0SAulPIV4XAgMBAAGj
1668
+ YTBfMA8GA1UdEwEB/wQFMAMBAf8wTAYDVR0gBEUwQzBBBgtghkgBhvt7hwcBCzAyMDAGCCsGAQUF
1669
+ BwIBFiRodHRwOi8vd3d3LndlbGxzZmFyZ28uY29tL2NlcnRwb2xpY3kwDQYJKoZIhvcNAQEFBQAD
1670
+ ggEBANIn3ZwKdyu7IvICtUpKkfnRLb7kuxpo7w6kAOnu5+/u9vnldKTC2FJYxHT7zmu1Oyl5GFrv
1671
+ m+0fazbuSCUlFLZWohDo7qd/0D+j0MNdJu4HzMPBJCGHHt8qElNvQRbn7a6U+oxy+hNH8Dx+rn0R
1672
+ OhPs7fpvcmR7nX1/Jv16+yWt6j4pf0zjAFcysLPp7VMX2YuyFA4w6OXVE8Zkr8QA1dhYJPz1j+zx
1673
+ x32l2w8n0cbyQIjmH/ZhqPRCyLk306m+LFZ4wnKbWV01QIroTmMatukgalHizqSQ33ZwmVxwQ023
1674
+ tqcZZE6St8WRPH9IFmV7Fv3L/PvZ1dZPIWU7Sn9Ho/s=
1675
+ -----END CERTIFICATE-----
1676
+
1677
+ Swisscom Root CA 1
1678
+ ==================
1679
+ -----BEGIN CERTIFICATE-----
1680
+ MIIF2TCCA8GgAwIBAgIQXAuFXAvnWUHfV8w/f52oNjANBgkqhkiG9w0BAQUFADBkMQswCQYDVQQG
1681
+ EwJjaDERMA8GA1UEChMIU3dpc3Njb20xJTAjBgNVBAsTHERpZ2l0YWwgQ2VydGlmaWNhdGUgU2Vy
1682
+ dmljZXMxGzAZBgNVBAMTElN3aXNzY29tIFJvb3QgQ0EgMTAeFw0wNTA4MTgxMjA2MjBaFw0yNTA4
1683
+ MTgyMjA2MjBaMGQxCzAJBgNVBAYTAmNoMREwDwYDVQQKEwhTd2lzc2NvbTElMCMGA1UECxMcRGln
1684
+ aXRhbCBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczEbMBkGA1UEAxMSU3dpc3Njb20gUm9vdCBDQSAxMIIC
1685
+ IjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA0LmwqAzZuz8h+BvVM5OAFmUgdbI9m2BtRsiM
1686
+ MW8Xw/qabFbtPMWRV8PNq5ZJkCoZSx6jbVfd8StiKHVFXqrWW/oLJdihFvkcxC7mlSpnzNApbjyF
1687
+ NDhhSbEAn9Y6cV9Nbc5fuankiX9qUvrKm/LcqfmdmUc/TilftKaNXXsLmREDA/7n29uj/x2lzZAe
1688
+ AR81sH8A25Bvxn570e56eqeqDFdvpG3FEzuwpdntMhy0XmeLVNxzh+XTF3xmUHJd1BpYwdnP2IkC
1689
+ b6dJtDZd0KTeByy2dbcokdaXvij1mB7qWybJvbCXc9qukSbraMH5ORXWZ0sKbU/Lz7DkQnGMU3nn
1690
+ 7uHbHaBuHYwadzVcFh4rUx80i9Fs/PJnB3r1re3WmquhsUvhzDdf/X/NTa64H5xD+SpYVUNFvJbN
1691
+ cA78yeNmuk6NO4HLFWR7uZToXTNShXEuT46iBhFRyePLoW4xCGQMwtI89Tbo19AOeCMgkckkKmUp
1692
+ WyL3Ic6DXqTz3kvTaI9GdVyDCW4pa8RwjPWd1yAv/0bSKzjCL3UcPX7ape8eYIVpQtPM+GP+HkM5
1693
+ haa2Y0EQs3MevNP6yn0WR+Kn1dCjigoIlmJWbjTb2QK5MHXjBNLnj8KwEUAKrNVxAmKLMb7dxiNY
1694
+ MUJDLXT5xp6mig/p/r+D5kNXJLrvRjSq1xIBOO0CAwEAAaOBhjCBgzAOBgNVHQ8BAf8EBAMCAYYw
1695
+ HQYDVR0hBBYwFDASBgdghXQBUwABBgdghXQBUwABMBIGA1UdEwEB/wQIMAYBAf8CAQcwHwYDVR0j
1696
+ BBgwFoAUAyUv3m+CATpcLNwroWm1Z9SM0/0wHQYDVR0OBBYEFAMlL95vggE6XCzcK6FptWfUjNP9
1697
+ MA0GCSqGSIb3DQEBBQUAA4ICAQA1EMvspgQNDQ/NwNurqPKIlwzfky9NfEBWMXrrpA9gzXrzvsMn
1698
+ jgM+pN0S734edAY8PzHyHHuRMSG08NBsl9Tpl7IkVh5WwzW9iAUPWxAaZOHHgjD5Mq2eUCzneAXQ
1699
+ MbFamIp1TpBcahQq4FJHgmDmHtqBsfsUC1rxn9KVuj7QG9YVHaO+htXbD8BJZLsuUBlL0iT43R4H
1700
+ VtA4oJVwIHaM190e3p9xxCPvgxNcoyQVTSlAPGrEqdi3pkSlDfTgnXceQHAm/NrZNuR55LU/vJtl
1701
+ vrsRls/bxig5OgjOR1tTWsWZ/l2p3e9M1MalrQLmjAcSHm8D0W+go/MpvRLHUKKwf4ipmXeascCl
1702
+ OS5cfGniLLDqN2qk4Vrh9VDlg++luyqI54zb/W1elxmofmZ1a3Hqv7HHb6D0jqTsNFFbjCYDcKF3
1703
+ 1QESVwA12yPeDooomf2xEG9L/zgtYE4snOtnta1J7ksfrK/7DZBaZmBwXarNeNQk7shBoJMBkpxq
1704
+ nvy5JMWzFYJ+vq6VK+uxwNrjAWALXmmshFZhvnEX/h0TD/7Gh0Xp/jKgGg0TpJRVcaUWi7rKibCy
1705
+ x/yP2FS1k2Kdzs9Z+z0YzirLNRWCXf9UIltxUvu3yf5gmwBBZPCqKuy2QkPOiWaByIufOVQDJdMW
1706
+ NY6E0F/6MBr1mmz0DlP5OlvRHA==
1707
+ -----END CERTIFICATE-----
1708
+
1709
+ DigiCert Assured ID Root CA
1710
+ ===========================
1711
+ -----BEGIN CERTIFICATE-----
1712
+ MIIDtzCCAp+gAwIBAgIQDOfg5RfYRv6P5WD8G/AwOTANBgkqhkiG9w0BAQUFADBlMQswCQYDVQQG
1713
+ EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSQw
1714
+ IgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgQ0EwHhcNMDYxMTEwMDAwMDAwWhcNMzEx
1715
+ MTEwMDAwMDAwWjBlMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQL
1716
+ ExB3d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgQ0Ew
1717
+ ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCtDhXO5EOAXLGH87dg+XESpa7cJpSIqvTO
1718
+ 9SA5KFhgDPiA2qkVlTJhPLWxKISKityfCgyDF3qPkKyK53lTXDGEKvYPmDI2dsze3Tyoou9q+yHy
1719
+ UmHfnyDXH+Kx2f4YZNISW1/5WBg1vEfNoTb5a3/UsDg+wRvDjDPZ2C8Y/igPs6eD1sNuRMBhNZYW
1720
+ /lmci3Zt1/GiSw0r/wty2p5g0I6QNcZ4VYcgoc/lbQrISXwxmDNsIumH0DJaoroTghHtORedmTpy
1721
+ oeb6pNnVFzF1roV9Iq4/AUaG9ih5yLHa5FcXxH4cDrC0kqZWs72yl+2qp/C3xag/lRbQ/6GW6whf
1722
+ GHdPAgMBAAGjYzBhMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRF
1723
+ 66Kv9JLLgjEtUYunpyGd823IDzAfBgNVHSMEGDAWgBRF66Kv9JLLgjEtUYunpyGd823IDzANBgkq
1724
+ hkiG9w0BAQUFAAOCAQEAog683+Lt8ONyc3pklL/3cmbYMuRCdWKuh+vy1dneVrOfzM4UKLkNl2Bc
1725
+ EkxY5NM9g0lFWJc1aRqoR+pWxnmrEthngYTffwk8lOa4JiwgvT2zKIn3X/8i4peEH+ll74fg38Fn
1726
+ SbNd67IJKusm7Xi+fT8r87cmNW1fiQG2SVufAQWbqz0lwcy2f8Lxb4bG+mRo64EtlOtCt/qMHt1i
1727
+ 8b5QZ7dsvfPxH2sMNgcWfzd8qVttevESRmCD1ycEvkvOl77DZypoEd+A5wwzZr8TDRRu838fYxAe
1728
+ +o0bJW1sj6W3YQGx0qMmoRBxna3iw/nDmVG3KwcIzi7mULKn+gpFL6Lw8g==
1729
+ -----END CERTIFICATE-----
1730
+
1731
+ DigiCert Global Root CA
1732
+ =======================
1733
+ -----BEGIN CERTIFICATE-----
1734
+ MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBhMQswCQYDVQQG
1735
+ EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSAw
1736
+ HgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBDQTAeFw0wNjExMTAwMDAwMDBaFw0zMTExMTAw
1737
+ MDAwMDBaMGExCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3
1738
+ dy5kaWdpY2VydC5jb20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENBMIIBIjANBgkq
1739
+ hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4jvhEXLeqKTTo1eqUKKPC3eQyaKl7hLOllsBCSDMAZOn
1740
+ TjC3U/dDxGkAV53ijSLdhwZAAIEJzs4bg7/fzTtxRuLWZscFs3YnFo97nh6Vfe63SKMI2tavegw5
1741
+ BmV/Sl0fvBf4q77uKNd0f3p4mVmFaG5cIzJLv07A6Fpt43C/dxC//AH2hdmoRBBYMql1GNXRor5H
1742
+ 4idq9Joz+EkIYIvUX7Q6hL+hqkpMfT7PT19sdl6gSzeRntwi5m3OFBqOasv+zbMUZBfHWymeMr/y
1743
+ 7vrTC0LUq7dBMtoM1O/4gdW7jVg/tRvoSSiicNoxBN33shbyTApOB6jtSj1etX+jkMOvJwIDAQAB
1744
+ o2MwYTAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA95QNVbRTLtm
1745
+ 8KPiGxvDl7I90VUwHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUwDQYJKoZIhvcNAQEF
1746
+ BQADggEBAMucN6pIExIK+t1EnE9SsPTfrgT1eXkIoyQY/EsrhMAtudXH/vTBH1jLuG2cenTnmCmr
1747
+ EbXjcKChzUyImZOMkXDiqw8cvpOp/2PV5Adg06O/nVsJ8dWO41P0jmP6P6fbtGbfYmbW0W5BjfIt
1748
+ tep3Sp+dWOIrWcBAI+0tKIJFPnlUkiaY4IBIqDfv8NZ5YBberOgOzW6sRBc4L0na4UU+Krk2U886
1749
+ UAb3LujEV0lsYSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQk
1750
+ CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4=
1751
+ -----END CERTIFICATE-----
1752
+
1753
+ DigiCert High Assurance EV Root CA
1754
+ ==================================
1755
+ -----BEGIN CERTIFICATE-----
1756
+ MIIDxTCCAq2gAwIBAgIQAqxcJmoLQJuPC3nyrkYldzANBgkqhkiG9w0BAQUFADBsMQswCQYDVQQG
1757
+ EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSsw
1758
+ KQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5jZSBFViBSb290IENBMB4XDTA2MTExMDAwMDAw
1759
+ MFoXDTMxMTExMDAwMDAwMFowbDELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZ
1760
+ MBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTErMCkGA1UEAxMiRGlnaUNlcnQgSGlnaCBBc3N1cmFu
1761
+ Y2UgRVYgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMbM5XPm+9S75S0t
1762
+ Mqbf5YE/yc0lSbZxKsPVlDRnogocsF9ppkCxxLeyj9CYpKlBWTrT3JTWPNt0OKRKzE0lgvdKpVMS
1763
+ OO7zSW1xkX5jtqumX8OkhPhPYlG++MXs2ziS4wblCJEMxChBVfvLWokVfnHoNb9Ncgk9vjo4UFt3
1764
+ MRuNs8ckRZqnrG0AFFoEt7oT61EKmEFBIk5lYYeBQVCmeVyJ3hlKV9Uu5l0cUyx+mM0aBhakaHPQ
1765
+ NAQTXKFx01p8VdteZOE3hzBWBOURtCmAEvF5OYiiAhF8J2a3iLd48soKqDirCmTCv2ZdlYTBoSUe
1766
+ h10aUAsgEsxBu24LUTi4S8sCAwEAAaNjMGEwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQFMAMB
1767
+ Af8wHQYDVR0OBBYEFLE+w2kD+L9HAdSYJhoIAu9jZCvDMB8GA1UdIwQYMBaAFLE+w2kD+L9HAdSY
1768
+ JhoIAu9jZCvDMA0GCSqGSIb3DQEBBQUAA4IBAQAcGgaX3NecnzyIZgYIVyHbIUf4KmeqvxgydkAQ
1769
+ V8GK83rZEWWONfqe/EW1ntlMMUu4kehDLI6zeM7b41N5cdblIZQB2lWHmiRk9opmzN6cN82oNLFp
1770
+ myPInngiK3BD41VHMWEZ71jFhS9OMPagMRYjyOfiZRYzy78aG6A9+MpeizGLYAiJLQwGXFK3xPkK
1771
+ mNEVX58Svnw2Yzi9RKR/5CYrCsSXaQ3pjOLAEFe4yHYSkVXySGnYvCoCWw9E1CAx2/S6cCZdkGCe
1772
+ vEsXCS+0yx5DaMkHJ8HSXPfqIbloEpw8nL+e/IBcm2PN7EeqJSdnoDfzAIJ9VNep+OkuE6N36B9K
1773
+ -----END CERTIFICATE-----
1774
+
1775
+ Certplus Class 2 Primary CA
1776
+ ===========================
1777
+ -----BEGIN CERTIFICATE-----
1778
+ MIIDkjCCAnqgAwIBAgIRAIW9S/PY2uNp9pTXX8OlRCMwDQYJKoZIhvcNAQEFBQAwPTELMAkGA1UE
1779
+ BhMCRlIxETAPBgNVBAoTCENlcnRwbHVzMRswGQYDVQQDExJDbGFzcyAyIFByaW1hcnkgQ0EwHhcN
1780
+ OTkwNzA3MTcwNTAwWhcNMTkwNzA2MjM1OTU5WjA9MQswCQYDVQQGEwJGUjERMA8GA1UEChMIQ2Vy
1781
+ dHBsdXMxGzAZBgNVBAMTEkNsYXNzIDIgUHJpbWFyeSBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEP
1782
+ ADCCAQoCggEBANxQltAS+DXSCHh6tlJw/W/uz7kRy1134ezpfgSN1sxvc0NXYKwzCkTsA18cgCSR
1783
+ 5aiRVhKC9+Ar9NuuYS6JEI1rbLqzAr3VNsVINyPi8Fo3UjMXEuLRYE2+L0ER4/YXJQyLkcAbmXuZ
1784
+ Vg2v7tK8R1fjeUl7NIknJITesezpWE7+Tt9avkGtrAjFGA7v0lPubNCdEgETjdyAYveVqUSISnFO
1785
+ YFWe2yMZeVYHDD9jC1yw4r5+FfyUM1hBOHTE4Y+L3yasH7WLO7dDWWuwJKZtkIvEcupdM5i3y95e
1786
+ e++U8Rs+yskhwcWYAqqi9lt3m/V+llU0HGdpwPFC40es/CgcZlUCAwEAAaOBjDCBiTAPBgNVHRME
1787
+ CDAGAQH/AgEKMAsGA1UdDwQEAwIBBjAdBgNVHQ4EFgQU43Mt38sOKAze3bOkynm4jrvoMIkwEQYJ
1788
+ YIZIAYb4QgEBBAQDAgEGMDcGA1UdHwQwMC4wLKAqoCiGJmh0dHA6Ly93d3cuY2VydHBsdXMuY29t
1789
+ L0NSTC9jbGFzczIuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQCnVM+IRBnL39R/AN9WM2K191EBkOvD
1790
+ P9GIROkkXe/nFL0gt5o8AP5tn9uQ3Nf0YtaLcF3n5QRIqWh8yfFC82x/xXp8HVGIutIKPidd3i1R
1791
+ TtMTZGnkLuPT55sJmabglZvOGtd/vjzOUrMRFcEPF80Du5wlFbqidon8BvEY0JNLDnyCt6X09l/+
1792
+ 7UCmnYR0ObncHoUW2ikbhiMAybuJfm6AiB4vFLQDJKgybwOaRywwvlbGp0ICcBvqQNi6BQNwB6SW
1793
+ //1IMwrh3KWBkJtN3X3n57LNXMhqlfil9o3EXXgIvnsG1knPGTZQIy4I5p4FTUcY1Rbpsda2ENW7
1794
+ l7+ijrRU
1795
+ -----END CERTIFICATE-----
1796
+
1797
+ DST Root CA X3
1798
+ ==============
1799
+ -----BEGIN CERTIFICATE-----
1800
+ MIIDSjCCAjKgAwIBAgIQRK+wgNajJ7qJMDmGLvhAazANBgkqhkiG9w0BAQUFADA/MSQwIgYDVQQK
1801
+ ExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMTDkRTVCBSb290IENBIFgzMB4X
1802
+ DTAwMDkzMDIxMTIxOVoXDTIxMDkzMDE0MDExNVowPzEkMCIGA1UEChMbRGlnaXRhbCBTaWduYXR1
1803
+ cmUgVHJ1c3QgQ28uMRcwFQYDVQQDEw5EU1QgUm9vdCBDQSBYMzCCASIwDQYJKoZIhvcNAQEBBQAD
1804
+ ggEPADCCAQoCggEBAN+v6ZdQCINXtMxiZfaQguzH0yxrMMpb7NnDfcdAwRgUi+DoM3ZJKuM/IUmT
1805
+ rE4Orz5Iy2Xu/NMhD2XSKtkyj4zl93ewEnu1lcCJo6m67XMuegwGMoOifooUMM0RoOEqOLl5CjH9
1806
+ UL2AZd+3UWODyOKIYepLYYHsUmu5ouJLGiifSKOeDNoJjj4XLh7dIN9bxiqKqy69cK3FCxolkHRy
1807
+ xXtqqzTWMIn/5WgTe1QLyNau7Fqckh49ZLOMxt+/yUFw7BZy1SbsOFU5Q9D8/RhcQPGX69Wam40d
1808
+ utolucbY38EVAjqr2m7xPi71XAicPNaDaeQQmxkqtilX4+U9m5/wAl0CAwEAAaNCMEAwDwYDVR0T
1809
+ AQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFMSnsaR7LHH62+FLkHX/xBVghYkQ
1810
+ MA0GCSqGSIb3DQEBBQUAA4IBAQCjGiybFwBcqR7uKGY3Or+Dxz9LwwmglSBd49lZRNI+DT69ikug
1811
+ dB/OEIKcdBodfpga3csTS7MgROSR6cz8faXbauX+5v3gTt23ADq1cEmv8uXrAvHRAosZy5Q6XkjE
1812
+ GB5YGV8eAlrwDPGxrancWYaLbumR9YbK+rlmM6pZW87ipxZzR8srzJmwN0jP41ZL9c8PDHIyh8bw
1813
+ RLtTcm1D9SZImlJnt1ir/md2cXjbDaJWFBM5JDGFoqgCWjBH4d1QB7wCCZAA62RjYJsWvIjJEubS
1814
+ fZGL+T0yjWW06XyxV3bqxbYoOb8VZRzI9neWagqNdwvYkQsEjgfbKbYK7p2CNTUQ
1815
+ -----END CERTIFICATE-----
1816
+
1817
+ DST ACES CA X6
1818
+ ==============
1819
+ -----BEGIN CERTIFICATE-----
1820
+ MIIECTCCAvGgAwIBAgIQDV6ZCtadt3js2AdWO4YV2TANBgkqhkiG9w0BAQUFADBbMQswCQYDVQQG
1821
+ EwJVUzEgMB4GA1UEChMXRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3QxETAPBgNVBAsTCERTVCBBQ0VT
1822
+ MRcwFQYDVQQDEw5EU1QgQUNFUyBDQSBYNjAeFw0wMzExMjAyMTE5NThaFw0xNzExMjAyMTE5NTha
1823
+ MFsxCzAJBgNVBAYTAlVTMSAwHgYDVQQKExdEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdDERMA8GA1UE
1824
+ CxMIRFNUIEFDRVMxFzAVBgNVBAMTDkRTVCBBQ0VTIENBIFg2MIIBIjANBgkqhkiG9w0BAQEFAAOC
1825
+ AQ8AMIIBCgKCAQEAuT31LMmU3HWKlV1j6IR3dma5WZFcRt2SPp/5DgO0PWGSvSMmtWPuktKe1jzI
1826
+ DZBfZIGxqAgNTNj50wUoUrQBJcWVHAx+PhCEdc/BGZFjz+iokYi5Q1K7gLFViYsx+tC3dr5BPTCa
1827
+ pCIlF3PoHuLTrCq9Wzgh1SpL11V94zpVvddtawJXa+ZHfAjIgrrep4c9oW24MFbCswKBXy314pow
1828
+ GCi4ZtPLAZZv6opFVdbgnf9nKxcCpk4aahELfrd755jWjHZvwTvbUJN+5dCOHze4vbrGn2zpfDPy
1829
+ MjwmR/onJALJfh1biEITajV8fTXpLmaRcpPVMibEdPVTo7NdmvYJywIDAQABo4HIMIHFMA8GA1Ud
1830
+ EwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgHGMB8GA1UdEQQYMBaBFHBraS1vcHNAdHJ1c3Rkc3Qu
1831
+ Y29tMGIGA1UdIARbMFkwVwYKYIZIAWUDAgEBATBJMEcGCCsGAQUFBwIBFjtodHRwOi8vd3d3LnRy
1832
+ dXN0ZHN0LmNvbS9jZXJ0aWZpY2F0ZXMvcG9saWN5L0FDRVMtaW5kZXguaHRtbDAdBgNVHQ4EFgQU
1833
+ CXIGThhDD+XWzMNqizF7eI+og7gwDQYJKoZIhvcNAQEFBQADggEBAKPYjtay284F5zLNAdMEA+V2
1834
+ 5FYrnJmQ6AgwbN99Pe7lv7UkQIRJ4dEorsTCOlMwiPH1d25Ryvr/ma8kXxug/fKshMrfqfBfBC6t
1835
+ Fr8hlxCBPeP/h40y3JTlR4peahPJlJU90u7INJXQgNStMgiAVDzgvVJT11J8smk/f3rPanTK+gQq
1836
+ nExaBqXpIK1FZg9p8d2/6eMyi/rgwYZNcjwu2JN4Cir42NInPRmJX1p7ijvMDNpRrscL9yuwNwXs
1837
+ vFcj4jjSm2jzVhKIT0J8uDHEtdvkyCE06UgRNe76x5JXxZ805Mf29w4LTJxoeHtxMcfrHuBnQfO3
1838
+ oKfN5XozNmr6mis=
1839
+ -----END CERTIFICATE-----
1840
+
1841
+ TURKTRUST Certificate Services Provider Root 1
1842
+ ==============================================
1843
+ -----BEGIN CERTIFICATE-----
1844
+ MIID+zCCAuOgAwIBAgIBATANBgkqhkiG9w0BAQUFADCBtzE/MD0GA1UEAww2VMOcUktUUlVTVCBF
1845
+ bGVrdHJvbmlrIFNlcnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sxc8SxMQswCQYDVQQGDAJUUjEP
1846
+ MA0GA1UEBwwGQU5LQVJBMVYwVAYDVQQKDE0oYykgMjAwNSBUw5xSS1RSVVNUIEJpbGdpIMSwbGV0
1847
+ acWfaW0gdmUgQmlsacWfaW0gR8O8dmVubGnEn2kgSGl6bWV0bGVyaSBBLsWeLjAeFw0wNTA1MTMx
1848
+ MDI3MTdaFw0xNTAzMjIxMDI3MTdaMIG3MT8wPQYDVQQDDDZUw5xSS1RSVVNUIEVsZWt0cm9uaWsg
1849
+ U2VydGlmaWthIEhpem1ldCBTYcSfbGF5xLFjxLFzxLExCzAJBgNVBAYMAlRSMQ8wDQYDVQQHDAZB
1850
+ TktBUkExVjBUBgNVBAoMTShjKSAyMDA1IFTDnFJLVFJVU1QgQmlsZ2kgxLBsZXRpxZ9pbSB2ZSBC
1851
+ aWxpxZ9pbSBHw7x2ZW5sacSfaSBIaXptZXRsZXJpIEEuxZ4uMIIBIjANBgkqhkiG9w0BAQEFAAOC
1852
+ AQ8AMIIBCgKCAQEAylIF1mMD2Bxf3dJ7XfIMYGFbazt0K3gNfUW9InTojAPBxhEqPZW8qZSwu5GX
1853
+ yGl8hMW0kWxsE2qkVa2kheiVfrMArwDCBRj1cJ02i67L5BuBf5OI+2pVu32Fks66WJ/bMsW9Xe8i
1854
+ Si9BB35JYbOG7E6mQW6EvAPs9TscyB/C7qju6hJKjRTP8wrgUDn5CDX4EVmt5yLqS8oUBt5CurKZ
1855
+ 8y1UiBAG6uEaPj1nH/vO+3yC6BFdSsG5FOpU2WabfIl9BJpiyelSPJ6c79L1JuTm5Rh8i27fbMx4
1856
+ W09ysstcP4wFjdFMjK2Sx+F4f2VsSQZQLJ4ywtdKxnWKWU51b0dewQIDAQABoxAwDjAMBgNVHRME
1857
+ BTADAQH/MA0GCSqGSIb3DQEBBQUAA4IBAQAV9VX/N5aAWSGk/KEVTCD21F/aAyT8z5Aa9CEKmu46
1858
+ sWrv7/hg0Uw2ZkUd82YCdAR7kjCo3gp2D++Vbr3JN+YaDayJSFvMgzbC9UZcWYJWtNX+I7TYVBxE
1859
+ q8Sn5RTOPEFhfEPmzcSBCYsk+1Ql1haolgxnB2+zUEfjHCQo3SqYpGH+2+oSN7wBGjSFvW5P55Fy
1860
+ B0SFHljKVETd96y5y4khctuPwGkplyqjrhgjlxxBKot8KsF8kOipKMDTkcatKIdAaLX/7KfS0zgY
1861
+ nNN9aV3wxqUeJBujR/xpB2jn5Jq07Q+hh4cCzofSSE7hvP/L8XKSRGQDJereW26fyfJOrN3H
1862
+ -----END CERTIFICATE-----
1863
+
1864
+ TURKTRUST Certificate Services Provider Root 2
1865
+ ==============================================
1866
+ -----BEGIN CERTIFICATE-----
1867
+ MIIEPDCCAySgAwIBAgIBATANBgkqhkiG9w0BAQUFADCBvjE/MD0GA1UEAww2VMOcUktUUlVTVCBF
1868
+ bGVrdHJvbmlrIFNlcnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sxc8SxMQswCQYDVQQGEwJUUjEP
1869
+ MA0GA1UEBwwGQW5rYXJhMV0wWwYDVQQKDFRUw5xSS1RSVVNUIEJpbGdpIMSwbGV0acWfaW0gdmUg
1870
+ QmlsacWfaW0gR8O8dmVubGnEn2kgSGl6bWV0bGVyaSBBLsWeLiAoYykgS2FzxLFtIDIwMDUwHhcN
1871
+ MDUxMTA3MTAwNzU3WhcNMTUwOTE2MTAwNzU3WjCBvjE/MD0GA1UEAww2VMOcUktUUlVTVCBFbGVr
1872
+ dHJvbmlrIFNlcnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sxc8SxMQswCQYDVQQGEwJUUjEPMA0G
1873
+ A1UEBwwGQW5rYXJhMV0wWwYDVQQKDFRUw5xSS1RSVVNUIEJpbGdpIMSwbGV0acWfaW0gdmUgQmls
1874
+ acWfaW0gR8O8dmVubGnEn2kgSGl6bWV0bGVyaSBBLsWeLiAoYykgS2FzxLFtIDIwMDUwggEiMA0G
1875
+ CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCpNn7DkUNMwxmYCMjHWHtPFoylzkkBH3MOrHUTpvqe
1876
+ LCDe2JAOCtFp0if7qnefJ1Il4std2NiDUBd9irWCPwSOtNXwSadktx4uXyCcUHVPr+G1QRT0mJKI
1877
+ x+XlZEdhR3n9wFHxwZnn3M5q+6+1ATDcRhzviuyV79z/rxAc653YsKpqhRgNF8k+v/Gb0AmJQv2g
1878
+ QrSdiVFVKc8bcLyEVK3BEx+Y9C52YItdP5qtygy/p1Zbj3e41Z55SZI/4PGXJHpsmxcPbe9TmJEr
1879
+ 5A++WXkHeLuXlfSfadRYhwqp48y2WBmfJiGxxFmNskF1wK1pzpwACPI2/z7woQ8arBT9pmAPAgMB
1880
+ AAGjQzBBMB0GA1UdDgQWBBTZN7NOBf3Zz58SFq62iS/rJTqIHDAPBgNVHQ8BAf8EBQMDBwYAMA8G
1881
+ A1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAHJglrfJ3NgpXiOFX7KzLXb7iNcX/ntt
1882
+ Rbj2hWyfIvwqECLsqrkw9qtY1jkQMZkpAL2JZkH7dN6RwRgLn7Vhy506vvWolKMiVW4XSf/SKfE4
1883
+ Jl3vpao6+XF75tpYHdN0wgH6PmlYX63LaL4ULptswLbcoCb6dxriJNoaN+BnrdFzgw2lGh1uEpJ+
1884
+ hGIAF728JRhX8tepb1mIvDS3LoV4nZbcFMMsilKbloxSZj2GFotHuFEJjOp9zYhys2AzsfAKRO8P
1885
+ 9Qk3iCQOLGsgOqL6EfJANZxEaGM7rDNvY7wsu/LSy3Z9fYjYHcgFHW68lKlmjHdxx/qR+i9Rnuk5
1886
+ UrbnBEI=
1887
+ -----END CERTIFICATE-----
1888
+
1889
+ SwissSign Platinum CA - G2
1890
+ ==========================
1891
+ -----BEGIN CERTIFICATE-----
1892
+ MIIFwTCCA6mgAwIBAgIITrIAZwwDXU8wDQYJKoZIhvcNAQEFBQAwSTELMAkGA1UEBhMCQ0gxFTAT
1893
+ BgNVBAoTDFN3aXNzU2lnbiBBRzEjMCEGA1UEAxMaU3dpc3NTaWduIFBsYXRpbnVtIENBIC0gRzIw
1894
+ HhcNMDYxMDI1MDgzNjAwWhcNMzYxMDI1MDgzNjAwWjBJMQswCQYDVQQGEwJDSDEVMBMGA1UEChMM
1895
+ U3dpc3NTaWduIEFHMSMwIQYDVQQDExpTd2lzc1NpZ24gUGxhdGludW0gQ0EgLSBHMjCCAiIwDQYJ
1896
+ KoZIhvcNAQEBBQADggIPADCCAgoCggIBAMrfogLi2vj8Bxax3mCq3pZcZB/HL37PZ/pEQtZ2Y5Wu
1897
+ 669yIIpFR4ZieIbWIDkm9K6j/SPnpZy1IiEZtzeTIsBQnIJ71NUERFzLtMKfkr4k2HtnIuJpX+UF
1898
+ eNSH2XFwMyVTtIc7KZAoNppVRDBopIOXfw0enHb/FZ1glwCNioUD7IC+6ixuEFGSzH7VozPY1kne
1899
+ WCqv9hbrS3uQMpe5up1Y8fhXSQQeol0GcN1x2/ndi5objM89o03Oy3z2u5yg+gnOI2Ky6Q0f4nIo
1900
+ j5+saCB9bzuohTEJfwvH6GXp43gOCWcwizSC+13gzJ2BbWLuCB4ELE6b7P6pT1/9aXjvCR+htL/6
1901
+ 8++QHkwFix7qepF6w9fl+zC8bBsQWJj3Gl/QKTIDE0ZNYWqFTFJ0LwYfexHihJfGmfNtf9dng34T
1902
+ aNhxKFrYzt3oEBSa/m0jh26OWnA81Y0JAKeqvLAxN23IhBQeW71FYyBrS3SMvds6DsHPWhaPpZjy
1903
+ domyExI7C3d3rLvlPClKknLKYRorXkzig3R3+jVIeoVNjZpTxN94ypeRSCtFKwH3HBqi7Ri6Cr2D
1904
+ +m+8jVeTO9TUps4e8aCxzqv9KyiaTxvXw3LbpMS/XUz13XuWae5ogObnmLo2t/5u7Su9IPhlGdpV
1905
+ CX4l3P5hYnL5fhgC72O00Puv5TtjjGePAgMBAAGjgawwgakwDgYDVR0PAQH/BAQDAgEGMA8GA1Ud
1906
+ EwEB/wQFMAMBAf8wHQYDVR0OBBYEFFCvzAeHFUdvOMW0ZdHelarp35zMMB8GA1UdIwQYMBaAFFCv
1907
+ zAeHFUdvOMW0ZdHelarp35zMMEYGA1UdIAQ/MD0wOwYJYIV0AVkBAQEBMC4wLAYIKwYBBQUHAgEW
1908
+ IGh0dHA6Ly9yZXBvc2l0b3J5LnN3aXNzc2lnbi5jb20vMA0GCSqGSIb3DQEBBQUAA4ICAQAIhab1
1909
+ Fgz8RBrBY+D5VUYI/HAcQiiWjrfFwUF1TglxeeVtlspLpYhg0DB0uMoI3LQwnkAHFmtllXcBrqS3
1910
+ NQuB2nEVqXQXOHtYyvkv+8Bldo1bAbl93oI9ZLi+FHSjClTTLJUYFzX1UWs/j6KWYTl4a0vlpqD4
1911
+ U99REJNi54Av4tHgvI42Rncz7Lj7jposiU0xEQ8mngS7twSNC/K5/FqdOxa3L8iYq/6KUFkuozv8
1912
+ KV2LwUvJ4ooTHbG/u0IdUt1O2BReEMYxB+9xJ/cbOQncguqLs5WGXv312l0xpuAxtpTmREl0xRbl
1913
+ 9x8DYSjFyMsSoEJL+WuICI20MhjzdZ/EfwBPBZWcoxcCw7NTm6ogOSkrZvqdr16zktK1puEa+S1B
1914
+ aYEUtLS17Yk9zvupnTVCRLEcFHOBzyoBNZox1S2PbYTfgE1X4z/FhHXaicYwu+uPyyIIoK6q8QNs
1915
+ OktNCaUOcsZWayFCTiMlFGiudgp8DAdwZPmaL/YFOSbGDI8Zf0NebvRbFS/bYV3mZy8/CJT5YLSY
1916
+ Mdp08YSTcU1f+2BY0fvEwW2JorsgH51xkcsymxM9Pn2SUjWskpSi0xjCfMfqr3YFFt1nJ8J+HAci
1917
+ IfNAChs0B0QTwoRqjt8ZWr9/6x3iGjjRXK9HkmuAtTClyY3YqzGBH9/CZjfTk6mFhnll0g==
1918
+ -----END CERTIFICATE-----
1919
+
1920
+ SwissSign Gold CA - G2
1921
+ ======================
1922
+ -----BEGIN CERTIFICATE-----
1923
+ MIIFujCCA6KgAwIBAgIJALtAHEP1Xk+wMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNVBAYTAkNIMRUw
1924
+ EwYDVQQKEwxTd2lzc1NpZ24gQUcxHzAdBgNVBAMTFlN3aXNzU2lnbiBHb2xkIENBIC0gRzIwHhcN
1925
+ MDYxMDI1MDgzMDM1WhcNMzYxMDI1MDgzMDM1WjBFMQswCQYDVQQGEwJDSDEVMBMGA1UEChMMU3dp
1926
+ c3NTaWduIEFHMR8wHQYDVQQDExZTd2lzc1NpZ24gR29sZCBDQSAtIEcyMIICIjANBgkqhkiG9w0B
1927
+ AQEFAAOCAg8AMIICCgKCAgEAr+TufoskDhJuqVAtFkQ7kpJcyrhdhJJCEyq8ZVeCQD5XJM1QiyUq
1928
+ t2/876LQwB8CJEoTlo8jE+YoWACjR8cGp4QjK7u9lit/VcyLwVcfDmJlD909Vopz2q5+bbqBHH5C
1929
+ jCA12UNNhPqE21Is8w4ndwtrvxEvcnifLtg+5hg3Wipy+dpikJKVyh+c6bM8K8vzARO/Ws/BtQpg
1930
+ vd21mWRTuKCWs2/iJneRjOBiEAKfNA+k1ZIzUd6+jbqEemA8atufK+ze3gE/bk3lUIbLtK/tREDF
1931
+ ylqM2tIrfKjuvqblCqoOpd8FUrdVxyJdMmqXl2MT28nbeTZ7hTpKxVKJ+STnnXepgv9VHKVxaSvR
1932
+ AiTysybUa9oEVeXBCsdtMDeQKuSeFDNeFhdVxVu1yzSJkvGdJo+hB9TGsnhQ2wwMC3wLjEHXuend
1933
+ jIj3o02yMszYF9rNt85mndT9Xv+9lz4pded+p2JYryU0pUHHPbwNUMoDAw8IWh+Vc3hiv69yFGkO
1934
+ peUDDniOJihC8AcLYiAQZzlG+qkDzAQ4embvIIO1jEpWjpEA/I5cgt6IoMPiaG59je883WX0XaxR
1935
+ 7ySArqpWl2/5rX3aYT+YdzylkbYcjCbaZaIJbcHiVOO5ykxMgI93e2CaHt+28kgeDrpOVG2Y4OGi
1936
+ GqJ3UM/EY5LsRxmd6+ZrzsECAwEAAaOBrDCBqTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUw
1937
+ AwEB/zAdBgNVHQ4EFgQUWyV7lqRlUX64OfPAeGZe6Drn8O4wHwYDVR0jBBgwFoAUWyV7lqRlUX64
1938
+ OfPAeGZe6Drn8O4wRgYDVR0gBD8wPTA7BglghXQBWQECAQEwLjAsBggrBgEFBQcCARYgaHR0cDov
1939
+ L3JlcG9zaXRvcnkuc3dpc3NzaWduLmNvbS8wDQYJKoZIhvcNAQEFBQADggIBACe645R88a7A3hfm
1940
+ 5djV9VSwg/S7zV4Fe0+fdWavPOhWfvxyeDgD2StiGwC5+OlgzczOUYrHUDFu4Up+GC9pWbY9ZIEr
1941
+ 44OE5iKHjn3g7gKZYbge9LgriBIWhMIxkziWMaa5O1M/wySTVltpkuzFwbs4AOPsF6m43Md8AYOf
1942
+ Mke6UiI0HTJ6CVanfCU2qT1L2sCCbwq7EsiHSycR+R4tx5M/nttfJmtS2S6K8RTGRI0Vqbe/vd6m
1943
+ Gu6uLftIdxf+u+yvGPUqUfA5hJeVbG4bwyvEdGB5JbAKJ9/fXtI5z0V9QkvfsywexcZdylU6oJxp
1944
+ mo/a77KwPJ+HbBIrZXAVUjEaJM9vMSNQH4xPjyPDdEFjHFWoFN0+4FFQz/EbMFYOkrCChdiDyyJk
1945
+ vC24JdVUorgG6q2SpCSgwYa1ShNqR88uC1aVVMvOmttqtKay20EIhid392qgQmwLOM7XdVAyksLf
1946
+ KzAiSNDVQTglXaTpXZ/GlHXQRf0wl0OPkKsKx4ZzYEppLd6leNcG2mqeSz53OiATIgHQv2ieY2Br
1947
+ NU0LbbqhPcCT4H8js1WtciVORvnSFu+wZMEBnunKoGqYDs/YYPIvSbjkQuE4NRb0yG5P94FW6Lqj
1948
+ viOvrv1vA+ACOzB2+httQc8Bsem4yWb02ybzOqR08kkkW8mw0FfB+j564ZfJ
1949
+ -----END CERTIFICATE-----
1950
+
1951
+ SwissSign Silver CA - G2
1952
+ ========================
1953
+ -----BEGIN CERTIFICATE-----
1954
+ MIIFvTCCA6WgAwIBAgIITxvUL1S7L0swDQYJKoZIhvcNAQEFBQAwRzELMAkGA1UEBhMCQ0gxFTAT
1955
+ BgNVBAoTDFN3aXNzU2lnbiBBRzEhMB8GA1UEAxMYU3dpc3NTaWduIFNpbHZlciBDQSAtIEcyMB4X
1956
+ DTA2MTAyNTA4MzI0NloXDTM2MTAyNTA4MzI0NlowRzELMAkGA1UEBhMCQ0gxFTATBgNVBAoTDFN3
1957
+ aXNzU2lnbiBBRzEhMB8GA1UEAxMYU3dpc3NTaWduIFNpbHZlciBDQSAtIEcyMIICIjANBgkqhkiG
1958
+ 9w0BAQEFAAOCAg8AMIICCgKCAgEAxPGHf9N4Mfc4yfjDmUO8x/e8N+dOcbpLj6VzHVxumK4DV644
1959
+ N0MvFz0fyM5oEMF4rhkDKxD6LHmD9ui5aLlV8gREpzn5/ASLHvGiTSf5YXu6t+WiE7brYT7QbNHm
1960
+ +/pe7R20nqA1W6GSy/BJkv6FCgU+5tkL4k+73JU3/JHpMjUi0R86TieFnbAVlDLaYQ1HTWBCrpJH
1961
+ 6INaUFjpiou5XaHc3ZlKHzZnu0jkg7Y360g6rw9njxcH6ATK72oxh9TAtvmUcXtnZLi2kUpCe2Uu
1962
+ MGoM9ZDulebyzYLs2aFK7PayS+VFheZteJMELpyCbTapxDFkH4aDCyr0NQp4yVXPQbBH6TCfmb5h
1963
+ qAaEuSh6XzjZG6k4sIN/c8HDO0gqgg8hm7jMqDXDhBuDsz6+pJVpATqJAHgE2cn0mRmrVn5bi4Y5
1964
+ FZGkECwJMoBgs5PAKrYYC51+jUnyEEp/+dVGLxmSo5mnJqy7jDzmDrxHB9xzUfFwZC8I+bRHHTBs
1965
+ ROopN4WSaGa8gzj+ezku01DwH/teYLappvonQfGbGHLy9YR0SslnxFSuSGTfjNFusB3hB48IHpmc
1966
+ celM2KX3RxIfdNFRnobzwqIjQAtz20um53MGjMGg6cFZrEb65i/4z3GcRm25xBWNOHkDRUjvxF3X
1967
+ CO6HOSKGsg0PWEP3calILv3q1h8CAwEAAaOBrDCBqTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/
1968
+ BAUwAwEB/zAdBgNVHQ4EFgQUF6DNweRBtjpbO8tFnb0cwpj6hlgwHwYDVR0jBBgwFoAUF6DNweRB
1969
+ tjpbO8tFnb0cwpj6hlgwRgYDVR0gBD8wPTA7BglghXQBWQEDAQEwLjAsBggrBgEFBQcCARYgaHR0
1970
+ cDovL3JlcG9zaXRvcnkuc3dpc3NzaWduLmNvbS8wDQYJKoZIhvcNAQEFBQADggIBAHPGgeAn0i0P
1971
+ 4JUw4ppBf1AsX19iYamGamkYDHRJ1l2E6kFSGG9YrVBWIGrGvShpWJHckRE1qTodvBqlYJ7YH39F
1972
+ kWnZfrt4csEGDyrOj4VwYaygzQu4OSlWhDJOhrs9xCrZ1x9y7v5RoSJBsXECYxqCsGKrXlcSH9/L
1973
+ 3XWgwF15kIwb4FDm3jH+mHtwX6WQ2K34ArZv02DdQEsixT2tOnqfGhpHkXkzuoLcMmkDlm4fS/Bx
1974
+ /uNncqCxv1yL5PqZIseEuRuNI5c/7SXgz2W79WEE790eslpBIlqhn10s6FvJbakMDHiqYMZWjwFa
1975
+ DGi8aRl5xB9+lwW/xekkUV7U1UtT7dkjWjYDZaPBA61BMPNGG4WQr2W11bHkFlt4dR2Xem1ZqSqP
1976
+ e97Dh4kQmUlzeMg9vVE1dCrV8X5pGyq7O70luJpaPXJhkGaH7gzWTdQRdAtq/gsD/KNVV4n+Ssuu
1977
+ WxcFyPKNIzFTONItaj+CuY0IavdeQXRuwxF+B6wpYJE/OMpXEA29MC/HpeZBoNquBYeaoKRlbEwJ
1978
+ DIm6uNO5wJOKMPqN5ZprFQFOZ6raYlY+hAhm0sQ2fac+EPyI4NSA5QC9qvNOBqN6avlicuMJT+ub
1979
+ DgEj8Z+7fNzcbBGXJbLytGMU0gYqZ4yD9c7qB9iaah7s5Aq7KkzrCWA5zspi2C5u
1980
+ -----END CERTIFICATE-----
1981
+
1982
+ GeoTrust Primary Certification Authority
1983
+ ========================================
1984
+ -----BEGIN CERTIFICATE-----
1985
+ MIIDfDCCAmSgAwIBAgIQGKy1av1pthU6Y2yv2vrEoTANBgkqhkiG9w0BAQUFADBYMQswCQYDVQQG
1986
+ EwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjExMC8GA1UEAxMoR2VvVHJ1c3QgUHJpbWFyeSBD
1987
+ ZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNjExMjcwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMFgx
1988
+ CzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTEwLwYDVQQDEyhHZW9UcnVzdCBQ
1989
+ cmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
1990
+ CgKCAQEAvrgVe//UfH1nrYNke8hCUy3f9oQIIGHWAVlqnEQRr+92/ZV+zmEwu3qDXwK9AWbK7hWN
1991
+ b6EwnL2hhZ6UOvNWiAAxz9juapYC2e0DjPt1befquFUWBRaa9OBesYjAZIVcFU2Ix7e64HXprQU9
1992
+ nceJSOC7KMgD4TCTZF5SwFlwIjVXiIrxlQqD17wxcwE07e9GceBrAqg1cmuXm2bgyxx5X9gaBGge
1993
+ RwLmnWDiNpcB3841kt++Z8dtd1k7j53WkBWUvEI0EME5+bEnPn7WinXFsq+W06Lem+SYvn3h6YGt
1994
+ tm/81w7a4DSwDRp35+MImO9Y+pyEtzavwt+s0vQQBnBxNQIDAQABo0IwQDAPBgNVHRMBAf8EBTAD
1995
+ AQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQULNVQQZcVi/CPNmFbSvtr2ZnJM5IwDQYJKoZI
1996
+ hvcNAQEFBQADggEBAFpwfyzdtzRP9YZRqSa+S7iq8XEN3GHHoOo0Hnp3DwQ16CePbJC/kRYkRj5K
1997
+ Ts4rFtULUh38H2eiAkUxT87z+gOneZ1TatnaYzr4gNfTmeGl4b7UVXGYNTq+k+qurUKykG/g/CFN
1998
+ NWMziUnWm07Kx+dOCQD32sfvmWKZd7aVIl6KoKv0uHiYyjgZmclynnjNS6yvGaBzEi38wkG6gZHa
1999
+ Floxt/m0cYASSJlyc1pZU8FjUjPtp8nSOQJw+uCxQmYpqptR7TBUIhRf2asdweSU8Pj1K/fqynhG
2000
+ 1riR/aYNKxoUAT6A8EKglQdebc3MS6RFjasS6LPeWuWgfOgPIh1a6Vk=
2001
+ -----END CERTIFICATE-----
2002
+
2003
+ thawte Primary Root CA
2004
+ ======================
2005
+ -----BEGIN CERTIFICATE-----
2006
+ MIIEIDCCAwigAwIBAgIQNE7VVyDV7exJ9C/ON9srbTANBgkqhkiG9w0BAQUFADCBqTELMAkGA1UE
2007
+ BhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2
2008
+ aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMvKGMpIDIwMDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhv
2009
+ cml6ZWQgdXNlIG9ubHkxHzAdBgNVBAMTFnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwHhcNMDYxMTE3
2010
+ MDAwMDAwWhcNMzYwNzE2MjM1OTU5WjCBqTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwg
2011
+ SW5jLjEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMv
2012
+ KGMpIDIwMDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxHzAdBgNVBAMT
2013
+ FnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCs
2014
+ oPD7gFnUnMekz52hWXMJEEUMDSxuaPFsW0hoSVk3/AszGcJ3f8wQLZU0HObrTQmnHNK4yZc2AreJ
2015
+ 1CRfBsDMRJSUjQJib+ta3RGNKJpchJAQeg29dGYvajig4tVUROsdB58Hum/u6f1OCyn1PoSgAfGc
2016
+ q/gcfomk6KHYcWUNo1F77rzSImANuVud37r8UVsLr5iy6S7pBOhih94ryNdOwUxkHt3Ph1i6Sk/K
2017
+ aAcdHJ1KxtUvkcx8cXIcxcBn6zL9yZJclNqFwJu/U30rCfSMnZEfl2pSy94JNqR32HuHUETVPm4p
2018
+ afs5SSYeCaWAe0At6+gnhcn+Yf1+5nyXHdWdAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYD
2019
+ VR0PAQH/BAQDAgEGMB0GA1UdDgQWBBR7W0XPr87Lev0xkhpqtvNG61dIUDANBgkqhkiG9w0BAQUF
2020
+ AAOCAQEAeRHAS7ORtvzw6WfUDW5FvlXok9LOAz/t2iWwHVfLHjp2oEzsUHboZHIMpKnxuIvW1oeE
2021
+ uzLlQRHAd9mzYJ3rG9XRbkREqaYB7FViHXe4XI5ISXycO1cRrK1zN44veFyQaEfZYGDm/Ac9IiAX
2022
+ xPcW6cTYcvnIc3zfFi8VqT79aie2oetaupgf1eNNZAqdE8hhuvU5HIe6uL17In/2/qxAeeWsEG89
2023
+ jxt5dovEN7MhGITlNgDrYyCZuen+MwS7QcjBAvlEYyCegc5C09Y/LHbTY5xZ3Y+m4Q6gLkH3LpVH
2024
+ z7z9M/P2C2F+fpErgUfCJzDupxBdN49cOSvkBPB7jVaMaA==
2025
+ -----END CERTIFICATE-----
2026
+
2027
+ VeriSign Class 3 Public Primary Certification Authority - G5
2028
+ ============================================================
2029
+ -----BEGIN CERTIFICATE-----
2030
+ MIIE0zCCA7ugAwIBAgIQGNrRniZ96LtKIVjNzGs7SjANBgkqhkiG9w0BAQUFADCByjELMAkGA1UE
2031
+ BhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBO
2032
+ ZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVk
2033
+ IHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRp
2034
+ ZmljYXRpb24gQXV0aG9yaXR5IC0gRzUwHhcNMDYxMTA4MDAwMDAwWhcNMzYwNzE2MjM1OTU5WjCB
2035
+ yjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2ln
2036
+ biBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJpU2lnbiwgSW5jLiAtIEZvciBh
2037
+ dXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmlt
2038
+ YXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw
2039
+ ggEKAoIBAQCvJAgIKXo1nmAMqudLO07cfLw8RRy7K+D+KQL5VwijZIUVJ/XxrcgxiV0i6CqqpkKz
2040
+ j/i5Vbext0uz/o9+B1fs70PbZmIVYc9gDaTY3vjgw2IIPVQT60nKWVSFJuUrjxuf6/WhkcIzSdhD
2041
+ Y2pSS9KP6HBRTdGJaXvHcPaz3BJ023tdS1bTlr8Vd6Gw9KIl8q8ckmcY5fQGBO+QueQA5N06tRn/
2042
+ Arr0PO7gi+s3i+z016zy9vA9r911kTMZHRxAy3QkGSGT2RT+rCpSx4/VBEnkjWNHiDxpg8v+R70r
2043
+ fk/Fla4OndTRQ8Bnc+MUCH7lP59zuDMKz10/NIeWiu5T6CUVAgMBAAGjgbIwga8wDwYDVR0TAQH/
2044
+ BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwbQYIKwYBBQUHAQwEYTBfoV2gWzBZMFcwVRYJaW1hZ2Uv
2045
+ Z2lmMCEwHzAHBgUrDgMCGgQUj+XTGoasjY5rw8+AatRIGCx7GS4wJRYjaHR0cDovL2xvZ28udmVy
2046
+ aXNpZ24uY29tL3ZzbG9nby5naWYwHQYDVR0OBBYEFH/TZafC3ey78DAJ80M5+gKvMzEzMA0GCSqG
2047
+ SIb3DQEBBQUAA4IBAQCTJEowX2LP2BqYLz3q3JktvXf2pXkiOOzEp6B4Eq1iDkVwZMXnl2YtmAl+
2048
+ X6/WzChl8gGqCBpH3vn5fJJaCGkgDdk+bW48DW7Y5gaRQBi5+MHt39tBquCWIMnNZBU4gcmU7qKE
2049
+ KQsTb47bDN0lAtukixlE0kF6BWlKWE9gyn6CagsCqiUXObXbf+eEZSqVir2G3l6BFoMtEMze/aiC
2050
+ Km0oHw0LxOXnGiYZ4fQRbxC1lfznQgUy286dUV4otp6F01vvpX1FQHKOtw5rDgb7MzVIcbidJ4vE
2051
+ ZV8NhnacRHr2lVz2XTIIM6RUthg/aFzyQkqFOFSDX9HoLPKsEdao7WNq
2052
+ -----END CERTIFICATE-----
2053
+
2054
+ SecureTrust CA
2055
+ ==============
2056
+ -----BEGIN CERTIFICATE-----
2057
+ MIIDuDCCAqCgAwIBAgIQDPCOXAgWpa1Cf/DrJxhZ0DANBgkqhkiG9w0BAQUFADBIMQswCQYDVQQG
2058
+ EwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24xFzAVBgNVBAMTDlNlY3VyZVRy
2059
+ dXN0IENBMB4XDTA2MTEwNzE5MzExOFoXDTI5MTIzMTE5NDA1NVowSDELMAkGA1UEBhMCVVMxIDAe
2060
+ BgNVBAoTF1NlY3VyZVRydXN0IENvcnBvcmF0aW9uMRcwFQYDVQQDEw5TZWN1cmVUcnVzdCBDQTCC
2061
+ ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKukgeWVzfX2FI7CT8rU4niVWJxB4Q2ZQCQX
2062
+ OZEzZum+4YOvYlyJ0fwkW2Gz4BERQRwdbvC4u/jep4G6pkjGnx29vo6pQT64lO0pGtSO0gMdA+9t
2063
+ DWccV9cGrcrI9f4Or2YlSASWC12juhbDCE/RRvgUXPLIXgGZbf2IzIaowW8xQmxSPmjL8xk037uH
2064
+ GFaAJsTQ3MBv396gwpEWoGQRS0S8Hvbn+mPeZqx2pHGj7DaUaHp3pLHnDi+BeuK1cobvomuL8A/b
2065
+ 01k/unK8RCSc43Oz969XL0Imnal0ugBS8kvNU3xHCzaFDmapCJcWNFfBZveA4+1wVMeT4C4oFVmH
2066
+ ursCAwEAAaOBnTCBmjATBgkrBgEEAYI3FAIEBh4EAEMAQTALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/
2067
+ BAUwAwEB/zAdBgNVHQ4EFgQUQjK2FvoE/f5dS3rD/fdMQB1aQ68wNAYDVR0fBC0wKzApoCegJYYj
2068
+ aHR0cDovL2NybC5zZWN1cmV0cnVzdC5jb20vU1RDQS5jcmwwEAYJKwYBBAGCNxUBBAMCAQAwDQYJ
2069
+ KoZIhvcNAQEFBQADggEBADDtT0rhWDpSclu1pqNlGKa7UTt36Z3q059c4EVlew3KW+JwULKUBRSu
2070
+ SceNQQcSc5R+DCMh/bwQf2AQWnL1mA6s7Ll/3XpvXdMc9P+IBWlCqQVxyLesJugutIxq/3HcuLHf
2071
+ mbx8IVQr5Fiiu1cprp6poxkmD5kuCLDv/WnPmRoJjeOnnyvJNjR7JLN4TJUXpAYmHrZkUjZfYGfZ
2072
+ nMUFdAvnZyPSCPyI6a6Lf+Ew9Dd+/cYy2i2eRDAwbO4H3tI0/NL/QPZL9GZGBlSm8jIKYyYwa5vR
2073
+ 3ItHuuG51WLQoqD0ZwV4KWMabwTW+MZMo5qxN7SN5ShLHZ4swrhovO0C7jE=
2074
+ -----END CERTIFICATE-----
2075
+
2076
+ Secure Global CA
2077
+ ================
2078
+ -----BEGIN CERTIFICATE-----
2079
+ MIIDvDCCAqSgAwIBAgIQB1YipOjUiolN9BPI8PjqpTANBgkqhkiG9w0BAQUFADBKMQswCQYDVQQG
2080
+ EwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24xGTAXBgNVBAMTEFNlY3VyZSBH
2081
+ bG9iYWwgQ0EwHhcNMDYxMTA3MTk0MjI4WhcNMjkxMjMxMTk1MjA2WjBKMQswCQYDVQQGEwJVUzEg
2082
+ MB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24xGTAXBgNVBAMTEFNlY3VyZSBHbG9iYWwg
2083
+ Q0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvNS7YrGxVaQZx5RNoJLNP2MwhR/jx
2084
+ YDiJiQPpvepeRlMJ3Fz1Wuj3RSoC6zFh1ykzTM7HfAo3fg+6MpjhHZevj8fcyTiW89sa/FHtaMbQ
2085
+ bqR8JNGuQsiWUGMu4P51/pinX0kuleM5M2SOHqRfkNJnPLLZ/kG5VacJjnIFHovdRIWCQtBJwB1g
2086
+ 8NEXLJXr9qXBkqPFwqcIYA1gBBCWeZ4WNOaptvolRTnIHmX5k/Wq8VLcmZg9pYYaDDUz+kulBAYV
2087
+ HDGA76oYa8J719rO+TMg1fW9ajMtgQT7sFzUnKPiXB3jqUJ1XnvUd+85VLrJChgbEplJL4hL/VBi
2088
+ 0XPnj3pDAgMBAAGjgZ0wgZowEwYJKwYBBAGCNxQCBAYeBABDAEEwCwYDVR0PBAQDAgGGMA8GA1Ud
2089
+ EwEB/wQFMAMBAf8wHQYDVR0OBBYEFK9EBMJBfkiD2045AuzshHrmzsmkMDQGA1UdHwQtMCswKaAn
2090
+ oCWGI2h0dHA6Ly9jcmwuc2VjdXJldHJ1c3QuY29tL1NHQ0EuY3JsMBAGCSsGAQQBgjcVAQQDAgEA
2091
+ MA0GCSqGSIb3DQEBBQUAA4IBAQBjGghAfaReUw132HquHw0LURYD7xh8yOOvaliTFGCRsoTciE6+
2092
+ OYo68+aCiV0BN7OrJKQVDpI1WkpEXk5X+nXOH0jOZvQ8QCaSmGwb7iRGDBezUqXbpZGRzzfTb+cn
2093
+ CDpOGR86p1hcF895P4vkp9MmI50mD1hp/Ed+stCNi5O/KU9DaXR2Z0vPB4zmAve14bRDtUstFJ/5
2094
+ 3CYNv6ZHdAbYiNE6KTCEztI5gGIbqMdXSbxqVVFnFUq+NQfk1XWYN3kwFNspnWzFacxHVaIw98xc
2095
+ f8LDmBxrThaA63p4ZUWiABqvDA1VZDRIuJK58bRQKfJPIx/abKwfROHdI3hRW8cW
2096
+ -----END CERTIFICATE-----
2097
+
2098
+ COMODO Certification Authority
2099
+ ==============================
2100
+ -----BEGIN CERTIFICATE-----
2101
+ MIIEHTCCAwWgAwIBAgIQToEtioJl4AsC7j41AkblPTANBgkqhkiG9w0BAQUFADCBgTELMAkGA1UE
2102
+ BhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgG
2103
+ A1UEChMRQ09NT0RPIENBIExpbWl0ZWQxJzAlBgNVBAMTHkNPTU9ETyBDZXJ0aWZpY2F0aW9uIEF1
2104
+ dGhvcml0eTAeFw0wNjEyMDEwMDAwMDBaFw0yOTEyMzEyMzU5NTlaMIGBMQswCQYDVQQGEwJHQjEb
2105
+ MBkGA1UECBMSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHEwdTYWxmb3JkMRowGAYDVQQKExFD
2106
+ T01PRE8gQ0EgTGltaXRlZDEnMCUGA1UEAxMeQ09NT0RPIENlcnRpZmljYXRpb24gQXV0aG9yaXR5
2107
+ MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0ECLi3LjkRv3UcEbVASY06m/weaKXTuH
2108
+ +7uIzg3jLz8GlvCiKVCZrts7oVewdFFxze1CkU1B/qnI2GqGd0S7WWaXUF601CxwRM/aN5VCaTww
2109
+ xHGzUvAhTaHYujl8HJ6jJJ3ygxaYqhZ8Q5sVW7euNJH+1GImGEaaP+vB+fGQV+useg2L23IwambV
2110
+ 4EajcNxo2f8ESIl33rXp+2dtQem8Ob0y2WIC8bGoPW43nOIv4tOiJovGuFVDiOEjPqXSJDlqR6sA
2111
+ 1KGzqSX+DT+nHbrTUcELpNqsOO9VUCQFZUaTNE8tja3G1CEZ0o7KBWFxB3NH5YoZEr0ETc5OnKVI
2112
+ rLsm9wIDAQABo4GOMIGLMB0GA1UdDgQWBBQLWOWLxkwVN6RAqTCpIb5HNlpW/zAOBgNVHQ8BAf8E
2113
+ BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zBJBgNVHR8EQjBAMD6gPKA6hjhodHRwOi8vY3JsLmNvbW9k
2114
+ b2NhLmNvbS9DT01PRE9DZXJ0aWZpY2F0aW9uQXV0aG9yaXR5LmNybDANBgkqhkiG9w0BAQUFAAOC
2115
+ AQEAPpiem/Yb6dc5t3iuHXIYSdOH5EOC6z/JqvWote9VfCFSZfnVDeFs9D6Mk3ORLgLETgdxb8CP
2116
+ OGEIqB6BCsAvIC9Bi5HcSEW88cbeunZrM8gALTFGTO3nnc+IlP8zwFboJIYmuNg4ON8qa90SzMc/
2117
+ RxdMosIGlgnW2/4/PEZB31jiVg88O8EckzXZOFKs7sjsLjBOlDW0JB9LeGna8gI4zJVSk/BwJVmc
2118
+ IGfE7vmLV2H0knZ9P4SNVbfo5azV8fUZVqZa+5Acr5Pr5RzUZ5ddBA6+C4OmF4O5MBKgxTMVBbkN
2119
+ +8cFduPYSo38NBejxiEovjBFMR7HeL5YYTisO+IBZQ==
2120
+ -----END CERTIFICATE-----
2121
+
2122
+ Network Solutions Certificate Authority
2123
+ =======================================
2124
+ -----BEGIN CERTIFICATE-----
2125
+ MIID5jCCAs6gAwIBAgIQV8szb8JcFuZHFhfjkDFo4DANBgkqhkiG9w0BAQUFADBiMQswCQYDVQQG
2126
+ EwJVUzEhMB8GA1UEChMYTmV0d29yayBTb2x1dGlvbnMgTC5MLkMuMTAwLgYDVQQDEydOZXR3b3Jr
2127
+ IFNvbHV0aW9ucyBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwHhcNMDYxMjAxMDAwMDAwWhcNMjkxMjMx
2128
+ MjM1OTU5WjBiMQswCQYDVQQGEwJVUzEhMB8GA1UEChMYTmV0d29yayBTb2x1dGlvbnMgTC5MLkMu
2129
+ MTAwLgYDVQQDEydOZXR3b3JrIFNvbHV0aW9ucyBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwggEiMA0G
2130
+ CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDkvH6SMG3G2I4rC7xGzuAnlt7e+foS0zwzc7MEL7xx
2131
+ jOWftiJgPl9dzgn/ggwbmlFQGiaJ3dVhXRncEg8tCqJDXRfQNJIg6nPPOCwGJgl6cvf6UDL4wpPT
2132
+ aaIjzkGxzOTVHzbRijr4jGPiFFlp7Q3Tf2vouAPlT2rlmGNpSAW+Lv8ztumXWWn4Zxmuk2GWRBXT
2133
+ crA/vGp97Eh/jcOrqnErU2lBUzS1sLnFBgrEsEX1QV1uiUV7PTsmjHTC5dLRfbIR1PtYMiKagMnc
2134
+ /Qzpf14Dl847ABSHJ3A4qY5usyd2mFHgBeMhqxrVhSI8KbWaFsWAqPS7azCPL0YCorEMIuDTAgMB
2135
+ AAGjgZcwgZQwHQYDVR0OBBYEFCEwyfsA106Y2oeqKtCnLrFAMadMMA4GA1UdDwEB/wQEAwIBBjAP
2136
+ BgNVHRMBAf8EBTADAQH/MFIGA1UdHwRLMEkwR6BFoEOGQWh0dHA6Ly9jcmwubmV0c29sc3NsLmNv
2137
+ bS9OZXR3b3JrU29sdXRpb25zQ2VydGlmaWNhdGVBdXRob3JpdHkuY3JsMA0GCSqGSIb3DQEBBQUA
2138
+ A4IBAQC7rkvnt1frf6ott3NHhWrB5KUd5Oc86fRZZXe1eltajSU24HqXLjjAV2CDmAaDn7l2em5Q
2139
+ 4LqILPxFzBiwmZVRDuwduIj/h1AcgsLj4DKAv6ALR8jDMe+ZZzKATxcheQxpXN5eNK4CtSbqUN9/
2140
+ GGUsyfJj4akH/nxxH2szJGoeBfcFaMBqEssuXmHLrijTfsK0ZpEmXzwuJF/LWA/rKOyvEZbz3Htv
2141
+ wKeI8lN3s2Berq4o2jUsbzRF0ybh3uxbTydrFny9RAQYgrOJeRcQcT16ohZO9QHNpGxlaKFJdlxD
2142
+ ydi8NmdspZS11My5vWo1ViHe2MPr+8ukYEywVaCge1ey
2143
+ -----END CERTIFICATE-----
2144
+
2145
+ WellsSecure Public Root Certificate Authority
2146
+ =============================================
2147
+ -----BEGIN CERTIFICATE-----
2148
+ MIIEvTCCA6WgAwIBAgIBATANBgkqhkiG9w0BAQUFADCBhTELMAkGA1UEBhMCVVMxIDAeBgNVBAoM
2149
+ F1dlbGxzIEZhcmdvIFdlbGxzU2VjdXJlMRwwGgYDVQQLDBNXZWxscyBGYXJnbyBCYW5rIE5BMTYw
2150
+ NAYDVQQDDC1XZWxsc1NlY3VyZSBQdWJsaWMgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwHhcN
2151
+ MDcxMjEzMTcwNzU0WhcNMjIxMjE0MDAwNzU0WjCBhTELMAkGA1UEBhMCVVMxIDAeBgNVBAoMF1dl
2152
+ bGxzIEZhcmdvIFdlbGxzU2VjdXJlMRwwGgYDVQQLDBNXZWxscyBGYXJnbyBCYW5rIE5BMTYwNAYD
2153
+ VQQDDC1XZWxsc1NlY3VyZSBQdWJsaWMgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwggEiMA0G
2154
+ CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDub7S9eeKPCCGeOARBJe+rWxxTkqxtnt3CxC5FlAM1
2155
+ iGd0V+PfjLindo8796jE2yljDpFoNoqXjopxaAkH5OjUDk/41itMpBb570OYj7OeUt9tkTmPOL13
2156
+ i0Nj67eT/DBMHAGTthP796EfvyXhdDcsHqRePGj4S78NuR4uNuip5Kf4D8uCdXw1LSLWwr8L87T8
2157
+ bJVhHlfXBIEyg1J55oNjz7fLY4sR4r1e6/aN7ZVyKLSsEmLpSjPmgzKuBXWVvYSV2ypcm44uDLiB
2158
+ K0HmOFafSZtsdvqKXfcBeYF8wYNABf5x/Qw/zE5gCQ5lRxAvAcAFP4/4s0HvWkJ+We/SlwxlAgMB
2159
+ AAGjggE0MIIBMDAPBgNVHRMBAf8EBTADAQH/MDkGA1UdHwQyMDAwLqAsoCqGKGh0dHA6Ly9jcmwu
2160
+ cGtpLndlbGxzZmFyZ28uY29tL3dzcHJjYS5jcmwwDgYDVR0PAQH/BAQDAgHGMB0GA1UdDgQWBBQm
2161
+ lRkQ2eihl5H/3BnZtQQ+0nMKajCBsgYDVR0jBIGqMIGngBQmlRkQ2eihl5H/3BnZtQQ+0nMKaqGB
2162
+ i6SBiDCBhTELMAkGA1UEBhMCVVMxIDAeBgNVBAoMF1dlbGxzIEZhcmdvIFdlbGxzU2VjdXJlMRww
2163
+ GgYDVQQLDBNXZWxscyBGYXJnbyBCYW5rIE5BMTYwNAYDVQQDDC1XZWxsc1NlY3VyZSBQdWJsaWMg
2164
+ Um9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHmCAQEwDQYJKoZIhvcNAQEFBQADggEBALkVsUSRzCPI
2165
+ K0134/iaeycNzXK7mQDKfGYZUMbVmO2rvwNa5U3lHshPcZeG1eMd/ZDJPHV3V3p9+N701NX3leZ0
2166
+ bh08rnyd2wIDBSxxSyU+B+NemvVmFymIGjifz6pBA4SXa5M4esowRBskRDPQ5NHcKDj0E0M1NSlj
2167
+ qHyita04pO2t/caaH/+Xc/77szWnk4bGdpEA5qxRFsQnMlzbc9qlk1eOPm01JghZ1edE13YgY+es
2168
+ E2fDbbFwRnzVlhE9iW9dqKHrjQrawx0zbKPqZxmamX9LPYNRKh3KL4YMon4QLSvUFpULB6ouFJJJ
2169
+ tylv2G0xffX8oRAHh84vWdw+WNs=
2170
+ -----END CERTIFICATE-----
2171
+
2172
+ COMODO ECC Certification Authority
2173
+ ==================================
2174
+ -----BEGIN CERTIFICATE-----
2175
+ MIICiTCCAg+gAwIBAgIQH0evqmIAcFBUTAGem2OZKjAKBggqhkjOPQQDAzCBhTELMAkGA1UEBhMC
2176
+ R0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UE
2177
+ ChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlvbiBB
2178
+ dXRob3JpdHkwHhcNMDgwMzA2MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBhTELMAkGA1UEBhMCR0Ix
2179
+ GzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UEChMR
2180
+ Q09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlvbiBBdXRo
2181
+ b3JpdHkwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQDR3svdcmCFYX7deSRFtSrYpn1PlILBs5BAH+X
2182
+ 4QokPB0BBO490o0JlwzgdeT6+3eKKvUDYEs2ixYjFq0JcfRK9ChQtP6IHG4/bC8vCVlbpVsLM5ni
2183
+ wz2J+Wos77LTBumjQjBAMB0GA1UdDgQWBBR1cacZSBm8nZ3qQUfflMRId5nTeTAOBgNVHQ8BAf8E
2184
+ BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjEA7wNbeqy3eApyt4jf/7VG
2185
+ FAkK+qDmfQjGGoe9GKhzvSbKYAydzpmfz1wPMOG+FDHqAjAU9JM8SaczepBGR7NjfRObTrdvGDeA
2186
+ U/7dIOA1mjbRxwG55tzd8/8dLDoWV9mSOdY=
2187
+ -----END CERTIFICATE-----
2188
+
2189
+ IGC/A
2190
+ =====
2191
+ -----BEGIN CERTIFICATE-----
2192
+ MIIEAjCCAuqgAwIBAgIFORFFEJQwDQYJKoZIhvcNAQEFBQAwgYUxCzAJBgNVBAYTAkZSMQ8wDQYD
2193
+ VQQIEwZGcmFuY2UxDjAMBgNVBAcTBVBhcmlzMRAwDgYDVQQKEwdQTS9TR0ROMQ4wDAYDVQQLEwVE
2194
+ Q1NTSTEOMAwGA1UEAxMFSUdDL0ExIzAhBgkqhkiG9w0BCQEWFGlnY2FAc2dkbi5wbS5nb3V2LmZy
2195
+ MB4XDTAyMTIxMzE0MjkyM1oXDTIwMTAxNzE0MjkyMlowgYUxCzAJBgNVBAYTAkZSMQ8wDQYDVQQI
2196
+ EwZGcmFuY2UxDjAMBgNVBAcTBVBhcmlzMRAwDgYDVQQKEwdQTS9TR0ROMQ4wDAYDVQQLEwVEQ1NT
2197
+ STEOMAwGA1UEAxMFSUdDL0ExIzAhBgkqhkiG9w0BCQEWFGlnY2FAc2dkbi5wbS5nb3V2LmZyMIIB
2198
+ IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsh/R0GLFMzvABIaIs9z4iPf930Pfeo2aSVz2
2199
+ TqrMHLmh6yeJ8kbpO0px1R2OLc/mratjUMdUC24SyZA2xtgv2pGqaMVy/hcKshd+ebUyiHDKcMCW
2200
+ So7kVc0dJ5S/znIq7Fz5cyD+vfcuiWe4u0dzEvfRNWk68gq5rv9GQkaiv6GFGvm/5P9JhfejcIYy
2201
+ HF2fYPepraX/z9E0+X1bF8bc1g4oa8Ld8fUzaJ1O/Id8NhLWo4DoQw1VYZTqZDdH6nfK0LJYBcNd
2202
+ frGoRpAxVs5wKpayMLh35nnAvSk7/ZR3TL0gzUEl4C7HG7vupARB0l2tEmqKm0f7yd1GQOGdPDPQ
2203
+ tQIDAQABo3cwdTAPBgNVHRMBAf8EBTADAQH/MAsGA1UdDwQEAwIBRjAVBgNVHSAEDjAMMAoGCCqB
2204
+ egF5AQEBMB0GA1UdDgQWBBSjBS8YYFDCiQrdKyFP/45OqDAxNjAfBgNVHSMEGDAWgBSjBS8YYFDC
2205
+ iQrdKyFP/45OqDAxNjANBgkqhkiG9w0BAQUFAAOCAQEABdwm2Pp3FURo/C9mOnTgXeQp/wYHE4RK
2206
+ q89toB9RlPhJy3Q2FLwV3duJL92PoF189RLrn544pEfMs5bZvpwlqwN+Mw+VgQ39FuCIvjfwbF3Q
2207
+ MZsyK10XZZOYYLxuj7GoPB7ZHPOpJkL5ZB3C55L29B5aqhlSXa/oovdgoPaN8In1buAKBQGVyYsg
2208
+ Crpa/JosPL3Dt8ldeCUFP1YUmwza+zpI/pdpXsoQhvdOlgQITeywvl3cO45Pwf2aNjSaTFR+FwNI
2209
+ lQgRHAdvhQh+XU3Endv7rs6y0bO4g2wdsrN58dhwmX7wEwLOXt1R0982gaEbeC9xs/FZTEYYKKuF
2210
+ 0mBWWg==
2211
+ -----END CERTIFICATE-----
2212
+
2213
+ Security Communication EV RootCA1
2214
+ =================================
2215
+ -----BEGIN CERTIFICATE-----
2216
+ MIIDfTCCAmWgAwIBAgIBADANBgkqhkiG9w0BAQUFADBgMQswCQYDVQQGEwJKUDElMCMGA1UEChMc
2217
+ U0VDT00gVHJ1c3QgU3lzdGVtcyBDTy4sTFRELjEqMCgGA1UECxMhU2VjdXJpdHkgQ29tbXVuaWNh
2218
+ dGlvbiBFViBSb290Q0ExMB4XDTA3MDYwNjAyMTIzMloXDTM3MDYwNjAyMTIzMlowYDELMAkGA1UE
2219
+ BhMCSlAxJTAjBgNVBAoTHFNFQ09NIFRydXN0IFN5c3RlbXMgQ08uLExURC4xKjAoBgNVBAsTIVNl
2220
+ Y3VyaXR5IENvbW11bmljYXRpb24gRVYgUm9vdENBMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC
2221
+ AQoCggEBALx/7FebJOD+nLpCeamIivqA4PUHKUPqjgo0No0c+qe1OXj/l3X3L+SqawSERMqm4miO
2222
+ /VVQYg+kcQ7OBzgtQoVQrTyWb4vVog7P3kmJPdZkLjjlHmy1V4qe70gOzXppFodEtZDkBp2uoQSX
2223
+ WHnvIEqCa4wiv+wfD+mEce3xDuS4GBPMVjZd0ZoeUWs5bmB2iDQL87PRsJ3KYeJkHcFGB7hj3R4z
2224
+ ZbOOCVVSPbW9/wfrrWFVGCypaZhKqkDFMxRldAD5kd6vA0jFQFTcD4SQaCDFkpbcLuUCRarAX1T4
2225
+ bepJz11sS6/vmsJWXMY1VkJqMF/Cq/biPT+zyRGPMUzXn0kCAwEAAaNCMEAwHQYDVR0OBBYEFDVK
2226
+ 9U2vP9eCOKyrcWUXdYydVZPmMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MA0GCSqG
2227
+ SIb3DQEBBQUAA4IBAQCoh+ns+EBnXcPBZsdAS5f8hxOQWsTvoMpfi7ent/HWtWS3irO4G8za+6xm
2228
+ iEHO6Pzk2x6Ipu0nUBsCMCRGef4Eh3CXQHPRwMFXGZpppSeZq51ihPZRwSzJIxXYKLerJRO1RuGG
2229
+ Av8mjMSIkh1W/hln8lXkgKNrnKt34VFxDSDbEJrbvXZ5B3eZKK2aXtqxT0QsNY6llsf9g/BYxnnW
2230
+ mHyojf6GPgcWkuF75x3sM3Z+Qi5KhfmRiWiEA4Glm5q+4zfFVKtWOxgtQaQM+ELbmaDgcm+7XeEW
2231
+ T1MKZPlO9L9OVL14bIjqv5wTJMJwaaJ/D8g8rQjJsJhAoyrniIPtd490
2232
+ -----END CERTIFICATE-----
2233
+
2234
+ OISTE WISeKey Global Root GA CA
2235
+ ===============================
2236
+ -----BEGIN CERTIFICATE-----
2237
+ MIID8TCCAtmgAwIBAgIQQT1yx/RrH4FDffHSKFTfmjANBgkqhkiG9w0BAQUFADCBijELMAkGA1UE
2238
+ BhMCQ0gxEDAOBgNVBAoTB1dJU2VLZXkxGzAZBgNVBAsTEkNvcHlyaWdodCAoYykgMjAwNTEiMCAG
2239
+ A1UECxMZT0lTVEUgRm91bmRhdGlvbiBFbmRvcnNlZDEoMCYGA1UEAxMfT0lTVEUgV0lTZUtleSBH
2240
+ bG9iYWwgUm9vdCBHQSBDQTAeFw0wNTEyMTExNjAzNDRaFw0zNzEyMTExNjA5NTFaMIGKMQswCQYD
2241
+ VQQGEwJDSDEQMA4GA1UEChMHV0lTZUtleTEbMBkGA1UECxMSQ29weXJpZ2h0IChjKSAyMDA1MSIw
2242
+ IAYDVQQLExlPSVNURSBGb3VuZGF0aW9uIEVuZG9yc2VkMSgwJgYDVQQDEx9PSVNURSBXSVNlS2V5
2243
+ IEdsb2JhbCBSb290IEdBIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAy0+zAJs9
2244
+ Nt350UlqaxBJH+zYK7LG+DKBKUOVTJoZIyEVRd7jyBxRVVuuk+g3/ytr6dTqvirdqFEr12bDYVxg
2245
+ Asj1znJ7O7jyTmUIms2kahnBAbtzptf2w93NvKSLtZlhuAGio9RN1AU9ka34tAhxZK9w8RxrfvbD
2246
+ d50kc3vkDIzh2TbhmYsFmQvtRTEJysIA2/dyoJaqlYfQjse2YXMNdmaM3Bu0Y6Kff5MTMPGhJ9vZ
2247
+ /yxViJGg4E8HsChWjBgbl0SOid3gF27nKu+POQoxhILYQBRJLnpB5Kf+42TMwVlxSywhp1t94B3R
2248
+ LoGbw9ho972WG6xwsRYUC9tguSYBBQIDAQABo1EwTzALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUw
2249
+ AwEB/zAdBgNVHQ4EFgQUswN+rja8sHnR3JQmthG+IbJphpQwEAYJKwYBBAGCNxUBBAMCAQAwDQYJ
2250
+ KoZIhvcNAQEFBQADggEBAEuh/wuHbrP5wUOxSPMowB0uyQlB+pQAHKSkq0lPjz0e701vvbyk9vIm
2251
+ MMkQyh2I+3QZH4VFvbBsUfk2ftv1TDI6QU9bR8/oCy22xBmddMVHxjtqD6wU2zz0c5ypBd8A3HR4
2252
+ +vg1YFkCExh8vPtNsCBtQ7tgMHpnM1zFmdH4LTlSc/uMqpclXHLZCB6rTjzjgTGfA6b7wP4piFXa
2253
+ hNVQA7bihKOmNqoROgHhGEvWRGizPflTdISzRpFGlgC3gCy24eMQ4tui5yiPAZZiFj4A4xylNoEY
2254
+ okxSdsARo27mHbrjWr42U8U+dY+GaSlYU7Wcu2+fXMUY7N0v4ZjJ/L7fCg0=
2255
+ -----END CERTIFICATE-----
2256
+
2257
+ S-TRUST Authentication and Encryption Root CA 2005 PN
2258
+ =====================================================
2259
+ -----BEGIN CERTIFICATE-----
2260
+ MIIEezCCA2OgAwIBAgIQNxkY5lNUfBq1uMtZWts1tzANBgkqhkiG9w0BAQUFADCBrjELMAkGA1UE
2261
+ BhMCREUxIDAeBgNVBAgTF0JhZGVuLVd1ZXJ0dGVtYmVyZyAoQlcpMRIwEAYDVQQHEwlTdHV0dGdh
2262
+ cnQxKTAnBgNVBAoTIERldXRzY2hlciBTcGFya2Fzc2VuIFZlcmxhZyBHbWJIMT4wPAYDVQQDEzVT
2263
+ LVRSVVNUIEF1dGhlbnRpY2F0aW9uIGFuZCBFbmNyeXB0aW9uIFJvb3QgQ0EgMjAwNTpQTjAeFw0w
2264
+ NTA2MjIwMDAwMDBaFw0zMDA2MjEyMzU5NTlaMIGuMQswCQYDVQQGEwJERTEgMB4GA1UECBMXQmFk
2265
+ ZW4tV3VlcnR0ZW1iZXJnIChCVykxEjAQBgNVBAcTCVN0dXR0Z2FydDEpMCcGA1UEChMgRGV1dHNj
2266
+ aGVyIFNwYXJrYXNzZW4gVmVybGFnIEdtYkgxPjA8BgNVBAMTNVMtVFJVU1QgQXV0aGVudGljYXRp
2267
+ b24gYW5kIEVuY3J5cHRpb24gUm9vdCBDQSAyMDA1OlBOMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
2268
+ MIIBCgKCAQEA2bVKwdMz6tNGs9HiTNL1toPQb9UY6ZOvJ44TzbUlNlA0EmQpoVXhOmCTnijJ4/Ob
2269
+ 4QSwI7+Vio5bG0F/WsPoTUzVJBY+h0jUJ67m91MduwwA7z5hca2/OnpYH5Q9XIHV1W/fuJvS9eXL
2270
+ g3KSwlOyggLrra1fFi2SU3bxibYs9cEv4KdKb6AwajLrmnQDaHgTncovmwsdvs91DSaXm8f1Xgqf
2271
+ eN+zvOyauu9VjxuapgdjKRdZYgkqeQd3peDRF2npW932kKvimAoA0SVtnteFhy+S8dF2g08LOlk3
2272
+ KC8zpxdQ1iALCvQm+Z845y2kuJuJja2tyWp9iRe79n+Ag3rm7QIDAQABo4GSMIGPMBIGA1UdEwEB
2273
+ /wQIMAYBAf8CAQAwDgYDVR0PAQH/BAQDAgEGMCkGA1UdEQQiMCCkHjAcMRowGAYDVQQDExFTVFJv
2274
+ bmxpbmUxLTIwNDgtNTAdBgNVHQ4EFgQUD8oeXHngovMpttKFswtKtWXsa1IwHwYDVR0jBBgwFoAU
2275
+ D8oeXHngovMpttKFswtKtWXsa1IwDQYJKoZIhvcNAQEFBQADggEBAK8B8O0ZPCjoTVy7pWMciDMD
2276
+ pwCHpB8gq9Yc4wYfl35UvbfRssnV2oDsF9eK9XvCAPbpEW+EoFolMeKJ+aQAPzFoLtU96G7m1R08
2277
+ P7K9n3frndOMusDXtk3sU5wPBG7qNWdX4wple5A64U8+wwCSersFiXOMy6ZNwPv2AtawB6MDwidA
2278
+ nwzkhYItr5pCHdDHjfhA7p0GVxzZotiAFP7hYy0yh9WUUpY6RsZxlj33mA6ykaqP2vROJAA5Veit
2279
+ F7nTNCtKqUDMFypVZUF0Qn71wK/Ik63yGFs9iQzbRzkk+OBM8h+wPQrKBU6JIRrjKpms/H+h8Q8b
2280
+ Hz2eBIPdltkdOpQ=
2281
+ -----END CERTIFICATE-----
2282
+
2283
+ Microsec e-Szigno Root CA
2284
+ =========================
2285
+ -----BEGIN CERTIFICATE-----
2286
+ MIIHqDCCBpCgAwIBAgIRAMy4579OKRr9otxmpRwsDxEwDQYJKoZIhvcNAQEFBQAwcjELMAkGA1UE
2287
+ BhMCSFUxETAPBgNVBAcTCEJ1ZGFwZXN0MRYwFAYDVQQKEw1NaWNyb3NlYyBMdGQuMRQwEgYDVQQL
2288
+ EwtlLVN6aWdubyBDQTEiMCAGA1UEAxMZTWljcm9zZWMgZS1Temlnbm8gUm9vdCBDQTAeFw0wNTA0
2289
+ MDYxMjI4NDRaFw0xNzA0MDYxMjI4NDRaMHIxCzAJBgNVBAYTAkhVMREwDwYDVQQHEwhCdWRhcGVz
2290
+ dDEWMBQGA1UEChMNTWljcm9zZWMgTHRkLjEUMBIGA1UECxMLZS1Temlnbm8gQ0ExIjAgBgNVBAMT
2291
+ GU1pY3Jvc2VjIGUtU3ppZ25vIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
2292
+ AQDtyADVgXvNOABHzNuEwSFpLHSQDCHZU4ftPkNEU6+r+ICbPHiN1I2uuO/TEdyB5s87lozWbxXG
2293
+ d36hL+BfkrYn13aaHUM86tnsL+4582pnS4uCzyL4ZVX+LMsvfUh6PXX5qqAnu3jCBspRwn5mS6/N
2294
+ oqdNAoI/gqyFxuEPkEeZlApxcpMqyabAvjxWTHOSJ/FrtfX9/DAFYJLG65Z+AZHCabEeHXtTRbjc
2295
+ QR/Ji3HWVBTji1R4P770Yjtb9aPs1ZJ04nQw7wHb4dSrmZsqa/i9phyGI0Jf7Enemotb9HI6QMVJ
2296
+ PqW+jqpx62z69Rrkav17fVVA71hu5tnVvCSrwe+3AgMBAAGjggQ3MIIEMzBnBggrBgEFBQcBAQRb
2297
+ MFkwKAYIKwYBBQUHMAGGHGh0dHBzOi8vcmNhLmUtc3ppZ25vLmh1L29jc3AwLQYIKwYBBQUHMAKG
2298
+ IWh0dHA6Ly93d3cuZS1zemlnbm8uaHUvUm9vdENBLmNydDAPBgNVHRMBAf8EBTADAQH/MIIBcwYD
2299
+ VR0gBIIBajCCAWYwggFiBgwrBgEEAYGoGAIBAQEwggFQMCgGCCsGAQUFBwIBFhxodHRwOi8vd3d3
2300
+ LmUtc3ppZ25vLmh1L1NaU1ovMIIBIgYIKwYBBQUHAgIwggEUHoIBEABBACAAdABhAG4A+gBzAO0A
2301
+ dAB2AOEAbgB5ACAA6QByAHQAZQBsAG0AZQB6AOkAcwDpAGgAZQB6ACAA6QBzACAAZQBsAGYAbwBn
2302
+ AGEAZADhAHMA4QBoAG8AegAgAGEAIABTAHoAbwBsAGcA4QBsAHQAYQB0APMAIABTAHoAbwBsAGcA
2303
+ 4QBsAHQAYQB0AOEAcwBpACAAUwB6AGEAYgDhAGwAeQB6AGEAdABhACAAcwB6AGUAcgBpAG4AdAAg
2304
+ AGsAZQBsAGwAIABlAGwAagDhAHIAbgBpADoAIABoAHQAdABwADoALwAvAHcAdwB3AC4AZQAtAHMA
2305
+ egBpAGcAbgBvAC4AaAB1AC8AUwBaAFMAWgAvMIHIBgNVHR8EgcAwgb0wgbqggbeggbSGIWh0dHA6
2306
+ Ly93d3cuZS1zemlnbm8uaHUvUm9vdENBLmNybIaBjmxkYXA6Ly9sZGFwLmUtc3ppZ25vLmh1L0NO
2307
+ PU1pY3Jvc2VjJTIwZS1Temlnbm8lMjBSb290JTIwQ0EsT1U9ZS1Temlnbm8lMjBDQSxPPU1pY3Jv
2308
+ c2VjJTIwTHRkLixMPUJ1ZGFwZXN0LEM9SFU/Y2VydGlmaWNhdGVSZXZvY2F0aW9uTGlzdDtiaW5h
2309
+ cnkwDgYDVR0PAQH/BAQDAgEGMIGWBgNVHREEgY4wgYuBEGluZm9AZS1zemlnbm8uaHWkdzB1MSMw
2310
+ IQYDVQQDDBpNaWNyb3NlYyBlLVN6aWduw7MgUm9vdCBDQTEWMBQGA1UECwwNZS1TemlnbsOzIEhT
2311
+ WjEWMBQGA1UEChMNTWljcm9zZWMgS2Z0LjERMA8GA1UEBxMIQnVkYXBlc3QxCzAJBgNVBAYTAkhV
2312
+ MIGsBgNVHSMEgaQwgaGAFMegSXUWYYTbMUuE0vE3QJDvTtz3oXakdDByMQswCQYDVQQGEwJIVTER
2313
+ MA8GA1UEBxMIQnVkYXBlc3QxFjAUBgNVBAoTDU1pY3Jvc2VjIEx0ZC4xFDASBgNVBAsTC2UtU3pp
2314
+ Z25vIENBMSIwIAYDVQQDExlNaWNyb3NlYyBlLVN6aWdubyBSb290IENBghEAzLjnv04pGv2i3Gal
2315
+ HCwPETAdBgNVHQ4EFgQUx6BJdRZhhNsxS4TS8TdAkO9O3PcwDQYJKoZIhvcNAQEFBQADggEBANMT
2316
+ nGZjWS7KXHAM/IO8VbH0jgdsZifOwTsgqRy7RlRw7lrMoHfqaEQn6/Ip3Xep1fvj1KcExJW4C+FE
2317
+ aGAHQzAxQmHl7tnlJNUb3+FKG6qfx1/4ehHqE5MAyopYse7tDk2016g2JnzgOsHVV4Lxdbb9iV/a
2318
+ 86g4nzUGCM4ilb7N1fy+W955a9x6qWVmvrElWl/tftOsRm1M9DKHtCAE4Gx4sHfRhUZLphK3dehK
2319
+ yVZs15KrnfVJONJPU+NVkBHbmJbGSfI+9J8b4PeI3CVimUTYc78/MPMMNz7UwiiAc7EBt51alhQB
2320
+ S6kRnSlqLtBdgcDPsiBDxwPgN05dCtxZICU=
2321
+ -----END CERTIFICATE-----
2322
+
2323
+ Certigna
2324
+ ========
2325
+ -----BEGIN CERTIFICATE-----
2326
+ MIIDqDCCApCgAwIBAgIJAP7c4wEPyUj/MA0GCSqGSIb3DQEBBQUAMDQxCzAJBgNVBAYTAkZSMRIw
2327
+ EAYDVQQKDAlEaGlteW90aXMxETAPBgNVBAMMCENlcnRpZ25hMB4XDTA3MDYyOTE1MTMwNVoXDTI3
2328
+ MDYyOTE1MTMwNVowNDELMAkGA1UEBhMCRlIxEjAQBgNVBAoMCURoaW15b3RpczERMA8GA1UEAwwI
2329
+ Q2VydGlnbmEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDIaPHJ1tazNHUmgh7stL7q
2330
+ XOEm7RFHYeGifBZ4QCHkYJ5ayGPhxLGWkv8YbWkj4Sti993iNi+RB7lIzw7sebYs5zRLcAglozyH
2331
+ GxnygQcPOJAZ0xH+hrTy0V4eHpbNgGzOOzGTtvKg0KmVEn2lmsxryIRWijOp5yIVUxbwzBfsV1/p
2332
+ ogqYCd7jX5xv3EjjhQsVWqa6n6xI4wmy9/Qy3l40vhx4XUJbzg4ij02Q130yGLMLLGq/jj8UEYkg
2333
+ DncUtT2UCIf3JR7VsmAA7G8qKCVuKj4YYxclPz5EIBb2JsglrgVKtOdjLPOMFlN+XPsRGgjBRmKf
2334
+ Irjxwo1p3Po6WAbfAgMBAAGjgbwwgbkwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUGu3+QTmQ
2335
+ tCRZvgHyUtVF9lo53BEwZAYDVR0jBF0wW4AUGu3+QTmQtCRZvgHyUtVF9lo53BGhOKQ2MDQxCzAJ
2336
+ BgNVBAYTAkZSMRIwEAYDVQQKDAlEaGlteW90aXMxETAPBgNVBAMMCENlcnRpZ25hggkA/tzjAQ/J
2337
+ SP8wDgYDVR0PAQH/BAQDAgEGMBEGCWCGSAGG+EIBAQQEAwIABzANBgkqhkiG9w0BAQUFAAOCAQEA
2338
+ hQMeknH2Qq/ho2Ge6/PAD/Kl1NqV5ta+aDY9fm4fTIrv0Q8hbV6lUmPOEvjvKtpv6zf+EwLHyzs+
2339
+ ImvaYS5/1HI93TDhHkxAGYwP15zRgzB7mFncfca5DClMoTOi62c6ZYTTluLtdkVwj7Ur3vkj1klu
2340
+ PBS1xp81HlDQwY9qcEQCYsuuHWhBp6pX6FOqB9IG9tUUBguRA3UsbHK1YZWaDYu5Def131TN3ubY
2341
+ 1gkIl2PlwS6wt0QmwCbAr1UwnjvVNioZBPRcHv/PLLf/0P2HQBHVESO7SMAhqaQoLf0V+LBOK/Qw
2342
+ WyH8EZE0vkHve52Xdf+XlcCWWC/qu0bXu+TZLg==
2343
+ -----END CERTIFICATE-----
2344
+
2345
+ AC Ra\xC3\xADz Certic\xC3\xA1mara S.A.
2346
+ ======================================
2347
+ -----BEGIN CERTIFICATE-----
2348
+ MIIGZjCCBE6gAwIBAgIPB35Sk3vgFeNX8GmMy+wMMA0GCSqGSIb3DQEBBQUAMHsxCzAJBgNVBAYT
2349
+ AkNPMUcwRQYDVQQKDD5Tb2NpZWRhZCBDYW1lcmFsIGRlIENlcnRpZmljYWNpw7NuIERpZ2l0YWwg
2350
+ LSBDZXJ0aWPDoW1hcmEgUy5BLjEjMCEGA1UEAwwaQUMgUmHDrXogQ2VydGljw6FtYXJhIFMuQS4w
2351
+ HhcNMDYxMTI3MjA0NjI5WhcNMzAwNDAyMjE0MjAyWjB7MQswCQYDVQQGEwJDTzFHMEUGA1UECgw+
2352
+ U29jaWVkYWQgQ2FtZXJhbCBkZSBDZXJ0aWZpY2FjacOzbiBEaWdpdGFsIC0gQ2VydGljw6FtYXJh
2353
+ IFMuQS4xIzAhBgNVBAMMGkFDIFJhw616IENlcnRpY8OhbWFyYSBTLkEuMIICIjANBgkqhkiG9w0B
2354
+ AQEFAAOCAg8AMIICCgKCAgEAq2uJo1PMSCMI+8PPUZYILrgIem08kBeGqentLhM0R7LQcNzJPNCN
2355
+ yu5LF6vQhbCnIwTLqKL85XXbQMpiiY9QngE9JlsYhBzLfDe3fezTf3MZsGqy2IiKLUV0qPezuMDU
2356
+ 2s0iiXRNWhU5cxh0T7XrmafBHoi0wpOQY5fzp6cSsgkiBzPZkc0OnB8OIMfuuzONj8LSWKdf/WU3
2357
+ 4ojC2I+GdV75LaeHM/J4Ny+LvB2GNzmxlPLYvEqcgxhaBvzz1NS6jBUJJfD5to0EfhcSM2tXSExP
2358
+ 2yYe68yQ54v5aHxwD6Mq0Do43zeX4lvegGHTgNiRg0JaTASJaBE8rF9ogEHMYELODVoqDA+bMMCm
2359
+ 8Ibbq0nXl21Ii/kDwFJnmxL3wvIumGVC2daa49AZMQyth9VXAnow6IYm+48jilSH5L887uvDdUhf
2360
+ HjlvgWJsxS3EF1QZtzeNnDeRyPYL1epjb4OsOMLzP96a++EjYfDIJss2yKHzMI+ko6Kh3VOz3vCa
2361
+ Mh+DkXkwwakfU5tTohVTP92dsxA7SH2JD/ztA/X7JWR1DhcZDY8AFmd5ekD8LVkH2ZD6mq093ICK
2362
+ 5lw1omdMEWux+IBkAC1vImHFrEsm5VoQgpukg3s0956JkSCXjrdCx2bD0Omk1vUgjcTDlaxECp1b
2363
+ czwmPS9KvqfJpxAe+59QafMCAwEAAaOB5jCB4zAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQE
2364
+ AwIBBjAdBgNVHQ4EFgQU0QnQ6dfOeXRU+Tows/RtLAMDG2gwgaAGA1UdIASBmDCBlTCBkgYEVR0g
2365
+ ADCBiTArBggrBgEFBQcCARYfaHR0cDovL3d3dy5jZXJ0aWNhbWFyYS5jb20vZHBjLzBaBggrBgEF
2366
+ BQcCAjBOGkxMaW1pdGFjaW9uZXMgZGUgZ2FyYW507WFzIGRlIGVzdGUgY2VydGlmaWNhZG8gc2Ug
2367
+ cHVlZGVuIGVuY29udHJhciBlbiBsYSBEUEMuMA0GCSqGSIb3DQEBBQUAA4ICAQBclLW4RZFNjmEf
2368
+ AygPU3zmpFmps4p6xbD/CHwso3EcIRNnoZUSQDWDg4902zNc8El2CoFS3UnUmjIz75uny3XlesuX
2369
+ EpBcunvFm9+7OSPI/5jOCk0iAUgHforA1SBClETvv3eiiWdIG0ADBaGJ7M9i4z0ldma/Jre7Ir5v
2370
+ /zlXdLp6yQGVwZVR6Kss+LGGIOk/yzVb0hfpKv6DExdA7ohiZVvVO2Dpezy4ydV/NgIlqmjCMRW3
2371
+ MGXrfx1IebHPOeJCgBbT9ZMj/EyXyVo3bHwi2ErN0o42gzmRkBDI8ck1fj+404HGIGQatlDCIaR4
2372
+ 3NAvO2STdPCWkPHv+wlaNECW8DYSwaN0jJN+Qd53i+yG2dIPPy3RzECiiWZIHiCznCNZc6lEc7wk
2373
+ eZBWN7PGKX6jD/EpOe9+XCgycDWs2rjIdWb8m0w5R44bb5tNAlQiM+9hup4phO9OSzNHdpdqy35f
2374
+ /RWmnkJDW2ZaiogN9xa5P1FlK2Zqi9E4UqLWRhH6/JocdJ6PlwsCT2TG9WjTSy3/pDceiz+/RL5h
2375
+ RqGEPQgnTIEgd4kI6mdAXmwIUV80WoyWaM3X94nCHNMyAK9Sy9NgWyo6R35rMDOhYil/SrnhLecU
2376
+ Iw4OGEfhefwVVdCx/CVxY3UzHCMrr1zZ7Ud3YA47Dx7SwNxkBYn8eNZcLCZDqQ==
2377
+ -----END CERTIFICATE-----
2378
+
2379
+ TC TrustCenter Class 2 CA II
2380
+ ============================
2381
+ -----BEGIN CERTIFICATE-----
2382
+ MIIEqjCCA5KgAwIBAgIOLmoAAQACH9dSISwRXDswDQYJKoZIhvcNAQEFBQAwdjELMAkGA1UEBhMC
2383
+ REUxHDAaBgNVBAoTE1RDIFRydXN0Q2VudGVyIEdtYkgxIjAgBgNVBAsTGVRDIFRydXN0Q2VudGVy
2384
+ IENsYXNzIDIgQ0ExJTAjBgNVBAMTHFRDIFRydXN0Q2VudGVyIENsYXNzIDIgQ0EgSUkwHhcNMDYw
2385
+ MTEyMTQzODQzWhcNMjUxMjMxMjI1OTU5WjB2MQswCQYDVQQGEwJERTEcMBoGA1UEChMTVEMgVHJ1
2386
+ c3RDZW50ZXIgR21iSDEiMCAGA1UECxMZVEMgVHJ1c3RDZW50ZXIgQ2xhc3MgMiBDQTElMCMGA1UE
2387
+ AxMcVEMgVHJ1c3RDZW50ZXIgQ2xhc3MgMiBDQSBJSTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC
2388
+ AQoCggEBAKuAh5uO8MN8h9foJIIRszzdQ2Lu+MNF2ujhoF/RKrLqk2jftMjWQ+nEdVl//OEd+DFw
2389
+ IxuInie5e/060smp6RQvkL4DUsFJzfb95AhmC1eKokKguNV/aVyQMrKXDcpK3EY+AlWJU+MaWss2
2390
+ xgdW94zPEfRMuzBwBJWl9jmM/XOBCH2JXjIeIqkiRUuwZi4wzJ9l/fzLganx4Duvo4bRierERXlQ
2391
+ Xa7pIXSSTYtZgo+U4+lK8edJsBTj9WLL1XK9H7nSn6DNqPoByNkN39r8R52zyFTfSUrxIan+GE7u
2392
+ SNQZu+995OKdy1u2bv/jzVrndIIFuoAlOMvkaZ6vQaoahPUCAwEAAaOCATQwggEwMA8GA1UdEwEB
2393
+ /wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBTjq1RMgKHbVkO3kUrL84J6E1wIqzCB
2394
+ 7QYDVR0fBIHlMIHiMIHfoIHcoIHZhjVodHRwOi8vd3d3LnRydXN0Y2VudGVyLmRlL2NybC92Mi90
2395
+ Y19jbGFzc18yX2NhX0lJLmNybIaBn2xkYXA6Ly93d3cudHJ1c3RjZW50ZXIuZGUvQ049VEMlMjBU
2396
+ cnVzdENlbnRlciUyMENsYXNzJTIwMiUyMENBJTIwSUksTz1UQyUyMFRydXN0Q2VudGVyJTIwR21i
2397
+ SCxPVT1yb290Y2VydHMsREM9dHJ1c3RjZW50ZXIsREM9ZGU/Y2VydGlmaWNhdGVSZXZvY2F0aW9u
2398
+ TGlzdD9iYXNlPzANBgkqhkiG9w0BAQUFAAOCAQEAjNfffu4bgBCzg/XbEeprS6iSGNn3Bzn1LL4G
2399
+ dXpoUxUc6krtXvwjshOg0wn/9vYua0Fxec3ibf2uWWuFHbhOIprtZjluS5TmVfwLG4t3wVMTZonZ
2400
+ KNaL80VKY7f9ewthXbhtvsPcW3nS7Yblok2+XnR8au0WOB9/WIFaGusyiC2y8zl3gK9etmF1Kdsj
2401
+ TYjKUCjLhdLTEKJZbtOTVAB6okaVhgWcqRmY5TFyDADiZ9lA4CQze28suVyrZZ0srHbqNZn1l7kP
2402
+ JOzHdiEoZa5X6AeIdUpWoNIFOqTmjZKILPPy4cHGYdtBxceb9w4aUUXCYWvcZCcXjFq32nQozZfk
2403
+ vQ==
2404
+ -----END CERTIFICATE-----
2405
+
2406
+ TC TrustCenter Class 3 CA II
2407
+ ============================
2408
+ -----BEGIN CERTIFICATE-----
2409
+ MIIEqjCCA5KgAwIBAgIOSkcAAQAC5aBd1j8AUb8wDQYJKoZIhvcNAQEFBQAwdjELMAkGA1UEBhMC
2410
+ REUxHDAaBgNVBAoTE1RDIFRydXN0Q2VudGVyIEdtYkgxIjAgBgNVBAsTGVRDIFRydXN0Q2VudGVy
2411
+ IENsYXNzIDMgQ0ExJTAjBgNVBAMTHFRDIFRydXN0Q2VudGVyIENsYXNzIDMgQ0EgSUkwHhcNMDYw
2412
+ MTEyMTQ0MTU3WhcNMjUxMjMxMjI1OTU5WjB2MQswCQYDVQQGEwJERTEcMBoGA1UEChMTVEMgVHJ1
2413
+ c3RDZW50ZXIgR21iSDEiMCAGA1UECxMZVEMgVHJ1c3RDZW50ZXIgQ2xhc3MgMyBDQTElMCMGA1UE
2414
+ AxMcVEMgVHJ1c3RDZW50ZXIgQ2xhc3MgMyBDQSBJSTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC
2415
+ AQoCggEBALTgu1G7OVyLBMVMeRwjhjEQY0NVJz/GRcekPewJDRoeIMJWHt4bNwcwIi9v8Qbxq63W
2416
+ yKthoy9DxLCyLfzDlml7forkzMA5EpBCYMnMNWju2l+QVl/NHE1bWEnrDgFPZPosPIlY2C8u4rBo
2417
+ 6SI7dYnWRBpl8huXJh0obazovVkdKyT21oQDZogkAHhg8fir/gKya/si+zXmFtGt9i4S5Po1auUZ
2418
+ uV3bOx4a+9P/FRQI2AlqukWdFHlgfa9Aigdzs5OW03Q0jTo3Kd5c7PXuLjHCINy+8U9/I1LZW+Jk
2419
+ 2ZyqBwi1Rb3R0DHBq1SfqdLDYmAD8bs5SpJKPQq5ncWg/jcCAwEAAaOCATQwggEwMA8GA1UdEwEB
2420
+ /wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBTUovyfs8PYA9NXXAek0CSnwPIA1DCB
2421
+ 7QYDVR0fBIHlMIHiMIHfoIHcoIHZhjVodHRwOi8vd3d3LnRydXN0Y2VudGVyLmRlL2NybC92Mi90
2422
+ Y19jbGFzc18zX2NhX0lJLmNybIaBn2xkYXA6Ly93d3cudHJ1c3RjZW50ZXIuZGUvQ049VEMlMjBU
2423
+ cnVzdENlbnRlciUyMENsYXNzJTIwMyUyMENBJTIwSUksTz1UQyUyMFRydXN0Q2VudGVyJTIwR21i
2424
+ SCxPVT1yb290Y2VydHMsREM9dHJ1c3RjZW50ZXIsREM9ZGU/Y2VydGlmaWNhdGVSZXZvY2F0aW9u
2425
+ TGlzdD9iYXNlPzANBgkqhkiG9w0BAQUFAAOCAQEANmDkcPcGIEPZIxpC8vijsrlNirTzwppVMXzE
2426
+ O2eatN9NDoqTSheLG43KieHPOh6sHfGcMrSOWXaiQYUlN6AT0PV8TtXqluJucsG7Kv5sbviRmEb8
2427
+ yRtXW+rIGjs/sFGYPAfaLFkB2otE6OF0/ado3VS6g0bsyEa1+K+XwDsJHI/OcpY9M1ZwvJbL2NV9
2428
+ IJqDnxrcOfHFcqMRA/07QlIp2+gB95tejNaNhk4Z+rwcvsUhpYeeeC422wlxo3I0+GzjBgnyXlal
2429
+ 092Y+tTmBvTwtiBjS+opvaqCZh77gaqnN60TGOaSw4HBM7uIHqHn4rS9MWwOUT1v+5ZWgOI2F9Hc
2430
+ 5A==
2431
+ -----END CERTIFICATE-----
2432
+
2433
+ TC TrustCenter Universal CA I
2434
+ =============================
2435
+ -----BEGIN CERTIFICATE-----
2436
+ MIID3TCCAsWgAwIBAgIOHaIAAQAC7LdggHiNtgYwDQYJKoZIhvcNAQEFBQAweTELMAkGA1UEBhMC
2437
+ REUxHDAaBgNVBAoTE1RDIFRydXN0Q2VudGVyIEdtYkgxJDAiBgNVBAsTG1RDIFRydXN0Q2VudGVy
2438
+ IFVuaXZlcnNhbCBDQTEmMCQGA1UEAxMdVEMgVHJ1c3RDZW50ZXIgVW5pdmVyc2FsIENBIEkwHhcN
2439
+ MDYwMzIyMTU1NDI4WhcNMjUxMjMxMjI1OTU5WjB5MQswCQYDVQQGEwJERTEcMBoGA1UEChMTVEMg
2440
+ VHJ1c3RDZW50ZXIgR21iSDEkMCIGA1UECxMbVEMgVHJ1c3RDZW50ZXIgVW5pdmVyc2FsIENBMSYw
2441
+ JAYDVQQDEx1UQyBUcnVzdENlbnRlciBVbml2ZXJzYWwgQ0EgSTCCASIwDQYJKoZIhvcNAQEBBQAD
2442
+ ggEPADCCAQoCggEBAKR3I5ZEr5D0MacQ9CaHnPM42Q9e3s9B6DGtxnSRJJZ4Hgmgm5qVSkr1YnwC
2443
+ qMqs+1oEdjneX/H5s7/zA1hV0qq34wQi0fiU2iIIAI3TfCZdzHd55yx4Oagmcw6iXSVphU9VDprv
2444
+ xrlE4Vc93x9UIuVvZaozhDrzznq+VZeujRIPFDPiUHDDSYcTvFHe15gSWu86gzOSBnWLknwSaHtw
2445
+ ag+1m7Z3W0hZneTvWq3zwZ7U10VOylY0Ibw+F1tvdwxIAUMpsN0/lm7mlaoMwCC2/T42J5zjXM9O
2446
+ gdwZu5GQfezmlwQek8wiSdeXhrYTCjxDI3d+8NzmzSQfO4ObNDqDNOMCAwEAAaNjMGEwHwYDVR0j
2447
+ BBgwFoAUkqR1LKSevoFE63n8isWVpesQdXMwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC
2448
+ AYYwHQYDVR0OBBYEFJKkdSyknr6BROt5/IrFlaXrEHVzMA0GCSqGSIb3DQEBBQUAA4IBAQAo0uCG
2449
+ 1eb4e/CX3CJrO5UUVg8RMKWaTzqwOuAGy2X17caXJ/4l8lfmXpWMPmRgFVp/Lw0BxbFg/UU1z/Cy
2450
+ vwbZ71q+s2IhtNerNXxTPqYn8aEt2hojnczd7Dwtnic0XQ/CNnm8yUpiLe1r2X1BQ3y2qsrtYbE3
2451
+ ghUJGooWMNjsydZHcnhLEEYUjl8Or+zHL6sQ17bxbuyGssLoDZJz3KL0Dzq/YSMQiZxIQG5wALPT
2452
+ ujdEWBF6AmqI8Dc08BnprNRlc/ZpjGSUOnmFKbAWKwyCPwacx/0QK54PLLae4xW/2TYcuiUaUj0a
2453
+ 7CIMHOCkoj3w6DnPgcB77V0fb8XQC9eY
2454
+ -----END CERTIFICATE-----
2455
+
2456
+ Deutsche Telekom Root CA 2
2457
+ ==========================
2458
+ -----BEGIN CERTIFICATE-----
2459
+ MIIDnzCCAoegAwIBAgIBJjANBgkqhkiG9w0BAQUFADBxMQswCQYDVQQGEwJERTEcMBoGA1UEChMT
2460
+ RGV1dHNjaGUgVGVsZWtvbSBBRzEfMB0GA1UECxMWVC1UZWxlU2VjIFRydXN0IENlbnRlcjEjMCEG
2461
+ A1UEAxMaRGV1dHNjaGUgVGVsZWtvbSBSb290IENBIDIwHhcNOTkwNzA5MTIxMTAwWhcNMTkwNzA5
2462
+ MjM1OTAwWjBxMQswCQYDVQQGEwJERTEcMBoGA1UEChMTRGV1dHNjaGUgVGVsZWtvbSBBRzEfMB0G
2463
+ A1UECxMWVC1UZWxlU2VjIFRydXN0IENlbnRlcjEjMCEGA1UEAxMaRGV1dHNjaGUgVGVsZWtvbSBS
2464
+ b290IENBIDIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCrC6M14IspFLEUha88EOQ5
2465
+ bzVdSq7d6mGNlUn0b2SjGmBmpKlAIoTZ1KXleJMOaAGtuU1cOs7TuKhCQN/Po7qCWWqSG6wcmtoI
2466
+ KyUn+WkjR/Hg6yx6m/UTAtB+NHzCnjwAWav12gz1MjwrrFDa1sPeg5TKqAyZMg4ISFZbavva4VhY
2467
+ AUlfckE8FQYBjl2tqriTtM2e66foai1SNNs671x1Udrb8zH57nGYMsRUFUQM+ZtV7a3fGAigo4aK
2468
+ Se5TBY8ZTNXeWHmb0mocQqvF1afPaA+W5OFhmHZhyJF81j4A4pFQh+GdCuatl9Idxjp9y7zaAzTV
2469
+ jlsB9WoHtxa2bkp/AgMBAAGjQjBAMB0GA1UdDgQWBBQxw3kbuvVT1xfgiXotF2wKsyudMzAPBgNV
2470
+ HRMECDAGAQH/AgEFMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOCAQEAlGRZrTlk5ynr
2471
+ E/5aw4sTV8gEJPB0d8Bg42f76Ymmg7+Wgnxu1MM9756AbrsptJh6sTtU6zkXR34ajgv8HzFZMQSy
2472
+ zhfzLMdiNlXiItiJVbSYSKpk+tYcNthEeFpaIzpXl/V6ME+un2pMSyuOoAPjPuCp1NJ70rOo4nI8
2473
+ rZ7/gFnkm0W09juwzTkZmDLl6iFhkOQxIY40sfcvNUqFENrnijchvllj4PKFiDFT1FQUhXB59C4G
2474
+ dyd1Lx+4ivn+xbrYNuSD7Odlt79jWvNGr4GUN9RBjNYj1h7P9WgbRGOiWrqnNVmh5XAFmw4jV5mU
2475
+ Cm26OWMohpLzGITY+9HPBVZkVw==
2476
+ -----END CERTIFICATE-----
2477
+
2478
+ ComSign CA
2479
+ ==========
2480
+ -----BEGIN CERTIFICATE-----
2481
+ MIIDkzCCAnugAwIBAgIQFBOWgxRVjOp7Y+X8NId3RDANBgkqhkiG9w0BAQUFADA0MRMwEQYDVQQD
2482
+ EwpDb21TaWduIENBMRAwDgYDVQQKEwdDb21TaWduMQswCQYDVQQGEwJJTDAeFw0wNDAzMjQxMTMy
2483
+ MThaFw0yOTAzMTkxNTAyMThaMDQxEzARBgNVBAMTCkNvbVNpZ24gQ0ExEDAOBgNVBAoTB0NvbVNp
2484
+ Z24xCzAJBgNVBAYTAklMMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA8ORUaSvTx49q
2485
+ ROR+WCf4C9DklBKK8Rs4OC8fMZwG1Cyn3gsqrhqg455qv588x26i+YtkbDqthVVRVKU4VbirgwTy
2486
+ P2Q298CNQ0NqZtH3FyrV7zb6MBBC11PN+fozc0yz6YQgitZBJzXkOPqUm7h65HkfM/sb2CEJKHxN
2487
+ GGleZIp6GZPKfuzzcuc3B1hZKKxC+cX/zT/npfo4sdAMx9lSGlPWgcxCejVb7Us6eva1jsz/D3zk
2488
+ YDaHL63woSV9/9JLEYhwVKZBqGdTUkJe5DSe5L6j7KpiXd3DTKaCQeQzC6zJMw9kglcq/QytNuEM
2489
+ rkvF7zuZ2SOzW120V+x0cAwqTwIDAQABo4GgMIGdMAwGA1UdEwQFMAMBAf8wPQYDVR0fBDYwNDAy
2490
+ oDCgLoYsaHR0cDovL2ZlZGlyLmNvbXNpZ24uY28uaWwvY3JsL0NvbVNpZ25DQS5jcmwwDgYDVR0P
2491
+ AQH/BAQDAgGGMB8GA1UdIwQYMBaAFEsBmz5WGmU2dst7l6qSBe4y5ygxMB0GA1UdDgQWBBRLAZs+
2492
+ VhplNnbLe5eqkgXuMucoMTANBgkqhkiG9w0BAQUFAAOCAQEA0Nmlfv4pYEWdfoPPbrxHbvUanlR2
2493
+ QnG0PFg/LUAlQvaBnPGJEMgOqnhPOAlXsDzACPw1jvFIUY0McXS6hMTXcpuEfDhOZAYnKuGntewI
2494
+ mbQKDdSFc8gS4TXt8QUxHXOZDOuWyt3T5oWq8Ir7dcHyCTxlZWTzTNity4hp8+SDtwy9F1qWF8pb
2495
+ /627HOkthIDYIb6FUtnUdLlphbpN7Sgy6/lhSuTENh4Z3G+EER+V9YMoGKgzkkMn3V0TBEVPh9VG
2496
+ zT2ouvDzuFYkRes3x+F2T3I5GN9+dHLHcy056mDmrRGiVod7w2ia/viMcKjfZTL0pECMocJEAw6U
2497
+ AGegcQCCSA==
2498
+ -----END CERTIFICATE-----
2499
+
2500
+ ComSign Secured CA
2501
+ ==================
2502
+ -----BEGIN CERTIFICATE-----
2503
+ MIIDqzCCApOgAwIBAgIRAMcoRwmzuGxFjB36JPU2TukwDQYJKoZIhvcNAQEFBQAwPDEbMBkGA1UE
2504
+ AxMSQ29tU2lnbiBTZWN1cmVkIENBMRAwDgYDVQQKEwdDb21TaWduMQswCQYDVQQGEwJJTDAeFw0w
2505
+ NDAzMjQxMTM3MjBaFw0yOTAzMTYxNTA0NTZaMDwxGzAZBgNVBAMTEkNvbVNpZ24gU2VjdXJlZCBD
2506
+ QTEQMA4GA1UEChMHQ29tU2lnbjELMAkGA1UEBhMCSUwwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw
2507
+ ggEKAoIBAQDGtWhfHZQVw6QIVS3joFd67+l0Kru5fFdJGhFeTymHDEjWaueP1H5XJLkGieQcPOqs
2508
+ 49ohgHMhCu95mGwfCP+hUH3ymBvJVG8+pSjsIQQPRbsHPaHA+iqYHU4Gk/v1iDurX8sWv+bznkqH
2509
+ 7Rnqwp9D5PGBpX8QTz7RSmKtUxvLg/8HZaWSLWapW7ha9B20IZFKF3ueMv5WJDmyVIRD9YTC2LxB
2510
+ kMyd1mja6YJQqTtoz7VdApRgFrFD2UNd3V2Hbuq7s8lr9gOUCXDeFhF6K+h2j0kQmHe5Y1yLM5d1
2511
+ 9guMsqtb3nQgJT/j8xH5h2iGNXHDHYwt6+UarA9z1YJZQIDTAgMBAAGjgacwgaQwDAYDVR0TBAUw
2512
+ AwEB/zBEBgNVHR8EPTA7MDmgN6A1hjNodHRwOi8vZmVkaXIuY29tc2lnbi5jby5pbC9jcmwvQ29t
2513
+ U2lnblNlY3VyZWRDQS5jcmwwDgYDVR0PAQH/BAQDAgGGMB8GA1UdIwQYMBaAFMFL7XC29z58ADsA
2514
+ j8c+DkWfHl3sMB0GA1UdDgQWBBTBS+1wtvc+fAA7AI/HPg5Fnx5d7DANBgkqhkiG9w0BAQUFAAOC
2515
+ AQEAFs/ukhNQq3sUnjO2QiBq1BW9Cav8cujvR3qQrFHBZE7piL1DRYHjZiM/EoZNGeQFsOY3wo3a
2516
+ BijJD4mkU6l1P7CW+6tMM1X5eCZGbxs2mPtCdsGCuY7e+0X5YxtiOzkGynd6qDwJz2w2PQ8KRUtp
2517
+ FhpFfTMDZflScZAmlaxMDPWLkz/MdXSFmLr/YnpNH4n+rr2UAJm/EaXc4HnFFgt9AmEd6oX5AhVP
2518
+ 51qJThRv4zdLhfXBPGHg/QVBspJ/wx2g0K5SZGBrGMYmnNj1ZOQ2GmKfig8+/21OGVZOIJFsnzQz
2519
+ OjRXUDpvgV4GxvU+fE6OK85lBi5d0ipTdF7Tbieejw==
2520
+ -----END CERTIFICATE-----
2521
+
2522
+ Cybertrust Global Root
2523
+ ======================
2524
+ -----BEGIN CERTIFICATE-----
2525
+ MIIDoTCCAomgAwIBAgILBAAAAAABD4WqLUgwDQYJKoZIhvcNAQEFBQAwOzEYMBYGA1UEChMPQ3li
2526
+ ZXJ0cnVzdCwgSW5jMR8wHQYDVQQDExZDeWJlcnRydXN0IEdsb2JhbCBSb290MB4XDTA2MTIxNTA4
2527
+ MDAwMFoXDTIxMTIxNTA4MDAwMFowOzEYMBYGA1UEChMPQ3liZXJ0cnVzdCwgSW5jMR8wHQYDVQQD
2528
+ ExZDeWJlcnRydXN0IEdsb2JhbCBSb290MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA
2529
+ +Mi8vRRQZhP/8NN57CPytxrHjoXxEnOmGaoQ25yiZXRadz5RfVb23CO21O1fWLE3TdVJDm71aofW
2530
+ 0ozSJ8bi/zafmGWgE07GKmSb1ZASzxQG9Dvj1Ci+6A74q05IlG2OlTEQXO2iLb3VOm2yHLtgwEZL
2531
+ AfVJrn5GitB0jaEMAs7u/OePuGtm839EAL9mJRQr3RAwHQeWP032a7iPt3sMpTjr3kfb1V05/Iin
2532
+ 89cqdPHoWqI7n1C6poxFNcJQZZXcY4Lv3b93TZxiyWNzFtApD0mpSPCzqrdsxacwOUBdrsTiXSZT
2533
+ 8M4cIwhhqJQZugRiQOwfOHB3EgZxpzAYXSUnpQIDAQABo4GlMIGiMA4GA1UdDwEB/wQEAwIBBjAP
2534
+ BgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBS2CHsNesysIEyGVjJez6tuhS1wVzA/BgNVHR8EODA2
2535
+ MDSgMqAwhi5odHRwOi8vd3d3Mi5wdWJsaWMtdHJ1c3QuY29tL2NybC9jdC9jdHJvb3QuY3JsMB8G
2536
+ A1UdIwQYMBaAFLYIew16zKwgTIZWMl7Pq26FLXBXMA0GCSqGSIb3DQEBBQUAA4IBAQBW7wojoFRO
2537
+ lZfJ+InaRcHUowAl9B8Tq7ejhVhpwjCt2BWKLePJzYFa+HMjWqd8BfP9IjsO0QbE2zZMcwSO5bAi
2538
+ 5MXzLqXZI+O4Tkogp24CJJ8iYGd7ix1yCcUxXOl5n4BHPa2hCwcUPUf/A2kaDAtE52Mlp3+yybh2
2539
+ hO0j9n0Hq0V+09+zv+mKts2oomcrUtW3ZfA5TGOgkXmTUg9U3YO7n9GPp1Nzw8v/MOx8BLjYRB+T
2540
+ X3EJIrduPuocA06dGiBh+4E37F78CkWr1+cXVdCg6mCbpvbjjFspwgZgFJ0tl0ypkxWdYcQBX0jW
2541
+ WL1WMRJOEcgh4LMRkWXbtKaIOM5V
2542
+ -----END CERTIFICATE-----
2543
+
2544
+ ePKI Root Certification Authority
2545
+ =================================
2546
+ -----BEGIN CERTIFICATE-----
2547
+ MIIFsDCCA5igAwIBAgIQFci9ZUdcr7iXAF7kBtK8nTANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQG
2548
+ EwJUVzEjMCEGA1UECgwaQ2h1bmdod2EgVGVsZWNvbSBDby4sIEx0ZC4xKjAoBgNVBAsMIWVQS0kg
2549
+ Um9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNDEyMjAwMjMxMjdaFw0zNDEyMjAwMjMx
2550
+ MjdaMF4xCzAJBgNVBAYTAlRXMSMwIQYDVQQKDBpDaHVuZ2h3YSBUZWxlY29tIENvLiwgTHRkLjEq
2551
+ MCgGA1UECwwhZVBLSSBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIICIjANBgkqhkiG9w0B
2552
+ AQEFAAOCAg8AMIICCgKCAgEA4SUP7o3biDN1Z82tH306Tm2d0y8U82N0ywEhajfqhFAHSyZbCUNs
2553
+ IZ5qyNUD9WBpj8zwIuQf5/dqIjG3LBXy4P4AakP/h2XGtRrBp0xtInAhijHyl3SJCRImHJ7K2RKi
2554
+ lTza6We/CKBk49ZCt0Xvl/T29de1ShUCWH2YWEtgvM3XDZoTM1PRYfl61dd4s5oz9wCGzh1NlDiv
2555
+ qOx4UXCKXBCDUSH3ET00hl7lSM2XgYI1TBnsZfZrxQWh7kcT1rMhJ5QQCtkkO7q+RBNGMD+XPNjX
2556
+ 12ruOzjjK9SXDrkb5wdJfzcq+Xd4z1TtW0ado4AOkUPB1ltfFLqfpo0kR0BZv3I4sjZsN/+Z0V0O
2557
+ WQqraffAsgRFelQArr5T9rXn4fg8ozHSqf4hUmTFpmfwdQcGlBSBVcYn5AGPF8Fqcde+S/uUWH1+
2558
+ ETOxQvdibBjWzwloPn9s9h6PYq2lY9sJpx8iQkEeb5mKPtf5P0B6ebClAZLSnT0IFaUQAS2zMnao
2559
+ lQ2zepr7BxB4EW/hj8e6DyUadCrlHJhBmd8hh+iVBmoKs2pHdmX2Os+PYhcZewoozRrSgx4hxyy/
2560
+ vv9haLdnG7t4TY3OZ+XkwY63I2binZB1NJipNiuKmpS5nezMirH4JYlcWrYvjB9teSSnUmjDhDXi
2561
+ Zo1jDiVN1Rmy5nk3pyKdVDECAwEAAaNqMGgwHQYDVR0OBBYEFB4M97Zn8uGSJglFwFU5Lnc/Qkqi
2562
+ MAwGA1UdEwQFMAMBAf8wOQYEZyoHAAQxMC8wLQIBADAJBgUrDgMCGgUAMAcGBWcqAwAABBRFsMLH
2563
+ ClZ87lt4DJX5GFPBphzYEDANBgkqhkiG9w0BAQUFAAOCAgEACbODU1kBPpVJufGBuvl2ICO1J2B0
2564
+ 1GqZNF5sAFPZn/KmsSQHRGoqxqWOeBLoR9lYGxMqXnmbnwoqZ6YlPwZpVnPDimZI+ymBV3QGypzq
2565
+ KOg4ZyYr8dW1P2WT+DZdjo2NQCCHGervJ8A9tDkPJXtoUHRVnAxZfVo9QZQlUgjgRywVMRnVvwdV
2566
+ xrsStZf0X4OFunHB2WyBEXYKCrC/gpf36j36+uwtqSiUO1bd0lEursC9CBWMd1I0ltabrNMdjmEP
2567
+ NXubrjlpC2JgQCA2j6/7Nu4tCEoduL+bXPjqpRugc6bY+G7gMwRfaKonh+3ZwZCc7b3jajWvY9+r
2568
+ GNm65ulK6lCKD2GTHuItGeIwlDWSXQ62B68ZgI9HkFFLLk3dheLSClIKF5r8GrBQAuUBo2M3IUxE
2569
+ xJtRmREOc5wGj1QupyheRDmHVi03vYVElOEMSyycw5KFNGHLD7ibSkNS/jQ6fbjpKdx2qcgw+BRx
2570
+ gMYeNkh0IkFch4LoGHGLQYlE535YW6i4jRPpp2zDR+2zGp1iro2C6pSe3VkQw63d4k3jMdXH7Ojy
2571
+ sP6SHhYKGvzZ8/gntsm+HbRsZJB/9OTEW9c3rkIO3aQab3yIVMUWbuF6aC74Or8NpDyJO3inTmOD
2572
+ BCEIZ43ygknQW/2xzQ+DhNQ+IIX3Sj0rnP0qCglN6oH4EZw=
2573
+ -----END CERTIFICATE-----
2574
+
2575
+ T\xc3\x9c\x42\xC4\xB0TAK UEKAE K\xC3\xB6k Sertifika Hizmet Sa\xC4\x9Flay\xc4\xb1\x63\xc4\xb1s\xc4\xb1 - S\xC3\xBCr\xC3\xBCm 3
2576
+ =============================================================================================================================
2577
+ -----BEGIN CERTIFICATE-----
2578
+ MIIFFzCCA/+gAwIBAgIBETANBgkqhkiG9w0BAQUFADCCASsxCzAJBgNVBAYTAlRSMRgwFgYDVQQH
2579
+ DA9HZWJ6ZSAtIEtvY2FlbGkxRzBFBgNVBAoMPlTDvHJraXllIEJpbGltc2VsIHZlIFRla25vbG9q
2580
+ aWsgQXJhxZ90xLFybWEgS3VydW11IC0gVMOcQsSwVEFLMUgwRgYDVQQLDD9VbHVzYWwgRWxla3Ry
2581
+ b25payB2ZSBLcmlwdG9sb2ppIEFyYcWfdMSxcm1hIEVuc3RpdMO8c8O8IC0gVUVLQUUxIzAhBgNV
2582
+ BAsMGkthbXUgU2VydGlmaWthc3lvbiBNZXJrZXppMUowSAYDVQQDDEFUw5xCxLBUQUsgVUVLQUUg
2583
+ S8O2ayBTZXJ0aWZpa2EgSGl6bWV0IFNhxJ9sYXnEsWPEsXPEsSAtIFPDvHLDvG0gMzAeFw0wNzA4
2584
+ MjQxMTM3MDdaFw0xNzA4MjExMTM3MDdaMIIBKzELMAkGA1UEBhMCVFIxGDAWBgNVBAcMD0dlYnpl
2585
+ IC0gS29jYWVsaTFHMEUGA1UECgw+VMO8cmtpeWUgQmlsaW1zZWwgdmUgVGVrbm9sb2ppayBBcmHF
2586
+ n3TEsXJtYSBLdXJ1bXUgLSBUw5xCxLBUQUsxSDBGBgNVBAsMP1VsdXNhbCBFbGVrdHJvbmlrIHZl
2587
+ IEtyaXB0b2xvamkgQXJhxZ90xLFybWEgRW5zdGl0w7xzw7wgLSBVRUtBRTEjMCEGA1UECwwaS2Ft
2588
+ dSBTZXJ0aWZpa2FzeW9uIE1lcmtlemkxSjBIBgNVBAMMQVTDnELEsFRBSyBVRUtBRSBLw7ZrIFNl
2589
+ cnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sxc8SxIC0gU8O8csO8bSAzMIIBIjANBgkqhkiG9w0B
2590
+ AQEFAAOCAQ8AMIIBCgKCAQEAim1L/xCIOsP2fpTo6iBkcK4hgb46ezzb8R1Sf1n68yJMlaCQvEhO
2591
+ Eav7t7WNeoMojCZG2E6VQIdhn8WebYGHV2yKO7Rm6sxA/OOqbLLLAdsyv9Lrhc+hDVXDWzhXcLh1
2592
+ xnnRFDDtG1hba+818qEhTsXOfJlfbLm4IpNQp81McGq+agV/E5wrHur+R84EpW+sky58K5+eeROR
2593
+ 6Oqeyjh1jmKwlZMq5d/pXpduIF9fhHpEORlAHLpVK/swsoHvhOPc7Jg4OQOFCKlUAwUp8MmPi+oL
2594
+ hmUZEdPpCSPeaJMDyTYcIW7OjGbxmTDY17PDHfiBLqi9ggtm/oLL4eAagsNAgQIDAQABo0IwQDAd
2595
+ BgNVHQ4EFgQUvYiHyY/2pAoLquvF/pEjnatKijIwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQF
2596
+ MAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAB18+kmPNOm3JpIWmgV050vQbTlswyb2zrgxvMTfvCr4
2597
+ N5EY3ATIZJkrGG2AA1nJrvhY0D7twyOfaTyGOBye79oneNGEN3GKPEs5z35FBtYt2IpNeBLWrcLT
2598
+ y9LQQfMmNkqblWwM7uXRQydmwYj3erMgbOqwaSvHIOgMA8RBBZniP+Rr+KCGgceExh/VS4ESshYh
2599
+ LBOhgLJeDEoTniDYYkCrkOpkSi+sDQESeUWoL4cZaMjihccwsnX5OD+ywJO0a+IDRM5noN+J1q2M
2600
+ dqMTw5RhK2vZbMEHCiIHhWyFJEapvj+LeISCfiQMnf2BN+MlqO02TpUsyZyQ2uypQjyttgI=
2601
+ -----END CERTIFICATE-----
2602
+
2603
+ Buypass Class 2 CA 1
2604
+ ====================
2605
+ -----BEGIN CERTIFICATE-----
2606
+ MIIDUzCCAjugAwIBAgIBATANBgkqhkiG9w0BAQUFADBLMQswCQYDVQQGEwJOTzEdMBsGA1UECgwU
2607
+ QnV5cGFzcyBBUy05ODMxNjMzMjcxHTAbBgNVBAMMFEJ1eXBhc3MgQ2xhc3MgMiBDQSAxMB4XDTA2
2608
+ MTAxMzEwMjUwOVoXDTE2MTAxMzEwMjUwOVowSzELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1eXBh
2609
+ c3MgQVMtOTgzMTYzMzI3MR0wGwYDVQQDDBRCdXlwYXNzIENsYXNzIDIgQ0EgMTCCASIwDQYJKoZI
2610
+ hvcNAQEBBQADggEPADCCAQoCggEBAIs8B0XY9t/mx8q6jUPFR42wWsE425KEHK8T1A9vNkYgxC7M
2611
+ cXA0ojTTNy7Y3Tp3L8DrKehc0rWpkTSHIln+zNvnma+WwajHQN2lFYxuyHyXA8vmIPLXl18xoS83
2612
+ 0r7uvqmtqEyeIWZDO6i88wmjONVZJMHCR3axiFyCO7srpgTXjAePzdVBHfCuuCkslFJgNJQ72uA4
2613
+ 0Z0zPhX0kzLFANq1KWYOOngPIVJfAuWSeyXTkh4vFZ2B5J2O6O+JzhRMVB0cgRJNcKi+EAUXfh/R
2614
+ uFdV7c27UsKwHnjCTTZoy1YmwVLBvXb3WNVyfh9EdrsAiR0WnVE1703CVu9r4Iw7DekCAwEAAaNC
2615
+ MEAwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUP42aWYv8e3uco684sDntkHGA1sgwDgYDVR0P
2616
+ AQH/BAQDAgEGMA0GCSqGSIb3DQEBBQUAA4IBAQAVGn4TirnoB6NLJzKyQJHyIdFkhb5jatLPgcIV
2617
+ 1Xp+DCmsNx4cfHZSldq1fyOhKXdlyTKdqC5Wq2B2zha0jX94wNWZUYN/Xtm+DKhQ7SLHrQVMdvvt
2618
+ 7h5HZPb3J31cKA9FxVxiXqaakZG3Uxcu3K1gnZZkOb1naLKuBctN518fV4bVIJwo+28TOPX2EZL2
2619
+ fZleHwzoq0QkKXJAPTZSr4xYkHPB7GEseaHsh7U/2k3ZIQAw3pDaDtMaSKk+hQsUi4y8QZ5q9w5w
2620
+ wDX3OaJdZtB7WZ+oRxKaJyOkLY4ng5IgodcVf/EuGO70SH8vf/GhGLWhC5SgYiAynB321O+/TIho
2621
+ -----END CERTIFICATE-----
2622
+
2623
+ Buypass Class 3 CA 1
2624
+ ====================
2625
+ -----BEGIN CERTIFICATE-----
2626
+ MIIDUzCCAjugAwIBAgIBAjANBgkqhkiG9w0BAQUFADBLMQswCQYDVQQGEwJOTzEdMBsGA1UECgwU
2627
+ QnV5cGFzcyBBUy05ODMxNjMzMjcxHTAbBgNVBAMMFEJ1eXBhc3MgQ2xhc3MgMyBDQSAxMB4XDTA1
2628
+ MDUwOTE0MTMwM1oXDTE1MDUwOTE0MTMwM1owSzELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1eXBh
2629
+ c3MgQVMtOTgzMTYzMzI3MR0wGwYDVQQDDBRCdXlwYXNzIENsYXNzIDMgQ0EgMTCCASIwDQYJKoZI
2630
+ hvcNAQEBBQADggEPADCCAQoCggEBAKSO13TZKWTeXx+HgJHqTjnmGcZEC4DVC69TB4sSveZn8AKx
2631
+ ifZgisRbsELRwCGoy+Gb72RRtqfPFfV0gGgEkKBYouZ0plNTVUhjP5JW3SROjvi6K//zNIqeKNc0
2632
+ n6wv1g/xpC+9UrJJhW05NfBEMJNGJPO251P7vGGvqaMU+8IXF4Rs4HyI+MkcVyzwPX6UvCWThOia
2633
+ AJpFBUJXgPROztmuOfbIUxAMZTpHe2DC1vqRycZxbL2RhzyRhkmr8w+gbCZ2Xhysm3HljbybIR6c
2634
+ 1jh+JIAVMYKWsUnTYjdbiAwKYjT+p0h+mbEwi5A3lRyoH6UsjfRVyNvdWQrCrXig9IsCAwEAAaNC
2635
+ MEAwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUOBTmyPCppAP0Tj4io1vy1uCtQHQwDgYDVR0P
2636
+ AQH/BAQDAgEGMA0GCSqGSIb3DQEBBQUAA4IBAQABZ6OMySU9E2NdFm/soT4JXJEVKirZgCFPBdy7
2637
+ pYmrEzMqnji3jG8CcmPHc3ceCQa6Oyh7pEfJYWsICCD8igWKH7y6xsL+z27sEzNxZy5p+qksP2bA
2638
+ EllNC1QCkoS72xLvg3BweMhT+t/Gxv/ciC8HwEmdMldg0/L2mSlf56oBzKwzqBwKu5HEA6BvtjT5
2639
+ htOzdlSY9EqBs1OdTUDs5XcTRa9bqh/YL0yCe/4qxFi7T/ye/QNlGioOw6UgFpRreaaiErS7GqQj
2640
+ el/wroQk5PMr+4okoyeYZdowdXb8GZHo2+ubPzK/QJcHJrrM85SFSnonk8+QQtS4Wxam58tAA915
2641
+ -----END CERTIFICATE-----
2642
+
2643
+ EBG Elektronik Sertifika Hizmet Sa\xC4\x9Flay\xc4\xb1\x63\xc4\xb1s\xc4\xb1
2644
+ ==========================================================================
2645
+ -----BEGIN CERTIFICATE-----
2646
+ MIIF5zCCA8+gAwIBAgIITK9zQhyOdAIwDQYJKoZIhvcNAQEFBQAwgYAxODA2BgNVBAMML0VCRyBF
2647
+ bGVrdHJvbmlrIFNlcnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sxc8SxMTcwNQYDVQQKDC5FQkcg
2648
+ QmlsacWfaW0gVGVrbm9sb2ppbGVyaSB2ZSBIaXptZXRsZXJpIEEuxZ4uMQswCQYDVQQGEwJUUjAe
2649
+ Fw0wNjA4MTcwMDIxMDlaFw0xNjA4MTQwMDMxMDlaMIGAMTgwNgYDVQQDDC9FQkcgRWxla3Ryb25p
2650
+ ayBTZXJ0aWZpa2EgSGl6bWV0IFNhxJ9sYXnEsWPEsXPEsTE3MDUGA1UECgwuRUJHIEJpbGnFn2lt
2651
+ IFRla25vbG9qaWxlcmkgdmUgSGl6bWV0bGVyaSBBLsWeLjELMAkGA1UEBhMCVFIwggIiMA0GCSqG
2652
+ SIb3DQEBAQUAA4ICDwAwggIKAoICAQDuoIRh0DpqZhAy2DE4f6en5f2h4fuXd7hxlugTlkaDT7by
2653
+ X3JWbhNgpQGR4lvFzVcfd2NR/y8927k/qqk153nQ9dAktiHq6yOU/im/+4mRDGSaBUorzAzu8T2b
2654
+ gmmkTPiab+ci2hC6X5L8GCcKqKpE+i4stPtGmggDg3KriORqcsnlZR9uKg+ds+g75AxuetpX/dfr
2655
+ eYteIAbTdgtsApWjluTLdlHRKJ2hGvxEok3MenaoDT2/F08iiFD9rrbskFBKW5+VQarKD7JK/oCZ
2656
+ TqNGFav4c0JqwmZ2sQomFd2TkuzbqV9UIlKRcF0T6kjsbgNs2d1s/OsNA/+mgxKb8amTD8UmTDGy
2657
+ Y5lhcucqZJnSuOl14nypqZoaqsNW2xCaPINStnuWt6yHd6i58mcLlEOzrz5z+kI2sSXFCjEmN1Zn
2658
+ uqMLfdb3ic1nobc6HmZP9qBVFCVMLDMNpkGMvQQxahByCp0OLna9XvNRiYuoP1Vzv9s6xiQFlpJI
2659
+ qkuNKgPlV5EQ9GooFW5Hd4RcUXSfGenmHmMWOeMRFeNYGkS9y8RsZteEBt8w9DeiQyJ50hBs37vm
2660
+ ExH8nYQKE3vwO9D8owrXieqWfo1IhR5kX9tUoqzVegJ5a9KK8GfaZXINFHDk6Y54jzJ0fFfy1tb0
2661
+ Nokb+Clsi7n2l9GkLqq+CxnCRelwXQIDAJ3Zo2MwYTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB
2662
+ /wQEAwIBBjAdBgNVHQ4EFgQU587GT/wWZ5b6SqMHwQSny2re2kcwHwYDVR0jBBgwFoAU587GT/wW
2663
+ Z5b6SqMHwQSny2re2kcwDQYJKoZIhvcNAQEFBQADggIBAJuYml2+8ygjdsZs93/mQJ7ANtyVDR2t
2664
+ FcU22NU57/IeIl6zgrRdu0waypIN30ckHrMk2pGI6YNw3ZPX6bqz3xZaPt7gyPvT/Wwp+BVGoGgm
2665
+ zJNSroIBk5DKd8pNSe/iWtkqvTDOTLKBtjDOWU/aWR1qeqRFsIImgYZ29fUQALjuswnoT4cCB64k
2666
+ XPBfrAowzIpAoHMEwfuJJPaaHFy3PApnNgUIMbOv2AFoKuB4j3TeuFGkjGwgPaL7s9QJ/XvCgKqT
2667
+ bCmYIai7FvOpEl90tYeY8pUm3zTvilORiF0alKM/fCL414i6poyWqD1SNGKfAB5UVUJnxk1Gj7sU
2668
+ RT0KlhaOEKGXmdXTMIXM3rRyt7yKPBgpaP3ccQfuJDlq+u2lrDgv+R4QDgZxGhBM/nV+/x5XOULK
2669
+ 1+EVoVZVWRvRo68R2E7DpSvvkL/A7IITW43WciyTTo9qKd+FPNMN4KIYEsxVL0e3p5sC/kH2iExt
2670
+ 2qkBR4NkJ2IQgtYSe14DHzSpyZH+r11thie3I6p1GMog57AP14kOpmciY/SDQSsGS7tY1dHXt7kQ
2671
+ Y9iJSrSq3RZj9W6+YKH47ejWkE8axsWgKdOnIaj1Wjz3x0miIZpKlVIglnKaZsv30oZDfCK+lvm9
2672
+ AahH3eU7QPl1K5srRmSGjR70j/sHd9DqSaIcjVIUpgqT
2673
+ -----END CERTIFICATE-----
2674
+
2675
+ certSIGN ROOT CA
2676
+ ================
2677
+ -----BEGIN CERTIFICATE-----
2678
+ MIIDODCCAiCgAwIBAgIGIAYFFnACMA0GCSqGSIb3DQEBBQUAMDsxCzAJBgNVBAYTAlJPMREwDwYD
2679
+ VQQKEwhjZXJ0U0lHTjEZMBcGA1UECxMQY2VydFNJR04gUk9PVCBDQTAeFw0wNjA3MDQxNzIwMDRa
2680
+ Fw0zMTA3MDQxNzIwMDRaMDsxCzAJBgNVBAYTAlJPMREwDwYDVQQKEwhjZXJ0U0lHTjEZMBcGA1UE
2681
+ CxMQY2VydFNJR04gUk9PVCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALczuX7I
2682
+ JUqOtdu0KBuqV5Do0SLTZLrTk+jUrIZhQGpgV2hUhE28alQCBf/fm5oqrl0Hj0rDKH/v+yv6efHH
2683
+ rfAQUySQi2bJqIirr1qjAOm+ukbuW3N7LBeCgV5iLKECZbO9xSsAfsT8AzNXDe3i+s5dRdY4zTW2
2684
+ ssHQnIFKquSyAVwdj1+ZxLGt24gh65AIgoDzMKND5pCCrlUoSe1b16kQOA7+j0xbm0bqQfWwCHTD
2685
+ 0IgztnzXdN/chNFDDnU5oSVAKOp4yw4sLjmdjItuFhwvJoIQ4uNllAoEwF73XVv4EOLQunpL+943
2686
+ AAAaWyjj0pxzPjKHmKHJUS/X3qwzs08CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8B
2687
+ Af8EBAMCAcYwHQYDVR0OBBYEFOCMm9slSbPxfIbWskKHC9BroNnkMA0GCSqGSIb3DQEBBQUAA4IB
2688
+ AQA+0hyJLjX8+HXd5n9liPRyTMks1zJO890ZeUe9jjtbkw9QSSQTaxQGcu8J06Gh40CEyecYMnQ8
2689
+ SG4Pn0vU9x7Tk4ZkVJdjclDVVc/6IJMCopvDI5NOFlV2oHB5bc0hH88vLbwZ44gx+FkagQnIl6Z0
2690
+ x2DEW8xXjrJ1/RsCCdtZb3KTafcxQdaIOL+Hsr0Wefmq5L6IJd1hJyMctTEHBDa0GpC9oHRxUIlt
2691
+ vBTjD4au8as+x6AJzKNI0eDbZOeStc+vckNwi/nDhDwTqn6Sm1dTk/pwwpEOMfmbZ13pljheX7Nz
2692
+ TogVZ96edhBiIL5VaZVDADlN9u6wWk5JRFRYX0KD
2693
+ -----END CERTIFICATE-----
2694
+
2695
+ CNNIC ROOT
2696
+ ==========
2697
+ -----BEGIN CERTIFICATE-----
2698
+ MIIDVTCCAj2gAwIBAgIESTMAATANBgkqhkiG9w0BAQUFADAyMQswCQYDVQQGEwJDTjEOMAwGA1UE
2699
+ ChMFQ05OSUMxEzARBgNVBAMTCkNOTklDIFJPT1QwHhcNMDcwNDE2MDcwOTE0WhcNMjcwNDE2MDcw
2700
+ OTE0WjAyMQswCQYDVQQGEwJDTjEOMAwGA1UEChMFQ05OSUMxEzARBgNVBAMTCkNOTklDIFJPT1Qw
2701
+ ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDTNfc/c3et6FtzF8LRb+1VvG7q6KR5smzD
2702
+ o+/hn7E7SIX1mlwhIhAsxYLO2uOabjfhhyzcuQxauohV3/2q2x8x6gHx3zkBwRP9SFIhxFXf2tiz
2703
+ VHa6dLG3fdfA6PZZxU3Iva0fFNrfWEQlMhkqx35+jq44sDB7R3IJMfAw28Mbdim7aXZOV/kbZKKT
2704
+ VrdvmW7bCgScEeOAH8tjlBAKqeFkgjH5jCftppkA9nCTGPihNIaj3XrCGHn2emU1z5DrvTOTn1Or
2705
+ czvmmzQgLx3vqR1jGqCA2wMv+SYahtKNu6m+UjqHZ0gNv7Sg2Ca+I19zN38m5pIEo3/PIKe38zrK
2706
+ y5nLAgMBAAGjczBxMBEGCWCGSAGG+EIBAQQEAwIABzAfBgNVHSMEGDAWgBRl8jGtKvf33VKWCscC
2707
+ wQ7vptU7ETAPBgNVHRMBAf8EBTADAQH/MAsGA1UdDwQEAwIB/jAdBgNVHQ4EFgQUZfIxrSr3991S
2708
+ lgrHAsEO76bVOxEwDQYJKoZIhvcNAQEFBQADggEBAEs17szkrr/Dbq2flTtLP1se31cpolnKOOK5
2709
+ Gv+e5m4y3R6u6jW39ZORTtpC4cMXYFDy0VwmuYK36m3knITnA3kXr5g9lNvHugDnuL8BV8F3RTIM
2710
+ O/G0HAiw/VGgod2aHRM2mm23xzy54cXZF/qD1T0VoDy7HgviyJA/qIYM/PmLXoXLT1tLYhFHxUV8
2711
+ BS9BsZ4QaRuZluBVeftOhpm4lNqGOGqTo+fLbuXf6iFViZx9fX+Y9QCJ7uOEwFyWtcVG6kbghVW2
2712
+ G8kS1sHNzYDzAgE8yGnLRUhj2JTQ7IUOO04RZfSCjKY9ri4ilAnIXOo8gV0WKgOXFlUJ24pBgp5m
2713
+ mxE=
2714
+ -----END CERTIFICATE-----
2715
+
2716
+ ApplicationCA - Japanese Government
2717
+ ===================================
2718
+ -----BEGIN CERTIFICATE-----
2719
+ MIIDoDCCAoigAwIBAgIBMTANBgkqhkiG9w0BAQUFADBDMQswCQYDVQQGEwJKUDEcMBoGA1UEChMT
2720
+ SmFwYW5lc2UgR292ZXJubWVudDEWMBQGA1UECxMNQXBwbGljYXRpb25DQTAeFw0wNzEyMTIxNTAw
2721
+ MDBaFw0xNzEyMTIxNTAwMDBaMEMxCzAJBgNVBAYTAkpQMRwwGgYDVQQKExNKYXBhbmVzZSBHb3Zl
2722
+ cm5tZW50MRYwFAYDVQQLEw1BcHBsaWNhdGlvbkNBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
2723
+ CgKCAQEAp23gdE6Hj6UG3mii24aZS2QNcfAKBZuOquHMLtJqO8F6tJdhjYq+xpqcBrSGUeQ3DnR4
2724
+ fl+Kf5Sk10cI/VBaVuRorChzoHvpfxiSQE8tnfWuREhzNgaeZCw7NCPbXCbkcXmP1G55IrmTwcrN
2725
+ wVbtiGrXoDkhBFcsovW8R0FPXjQilbUfKW1eSvNNcr5BViCH/OlQR9cwFO5cjFW6WY2H/CPek9AE
2726
+ jP3vbb3QesmlOmpyM8ZKDQUXKi17safY1vC+9D/qDihtQWEjdnjDuGWk81quzMKq2edY3rZ+nYVu
2727
+ nyoKb58DKTCXKB28t89UKU5RMfkntigm/qJj5kEW8DOYRwIDAQABo4GeMIGbMB0GA1UdDgQWBBRU
2728
+ WssmP3HMlEYNllPqa0jQk/5CdTAOBgNVHQ8BAf8EBAMCAQYwWQYDVR0RBFIwUKROMEwxCzAJBgNV
2729
+ BAYTAkpQMRgwFgYDVQQKDA/ml6XmnKzlm73mlL/lupwxIzAhBgNVBAsMGuOCouODl+ODquOCseOD
2730
+ vOOCt+ODp+ODs0NBMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBADlqRHZ3ODrs
2731
+ o2dGD/mLBqj7apAxzn7s2tGJfHrrLgy9mTLnsCTWw//1sogJhyzjVOGjprIIC8CFqMjSnHH2HZ9g
2732
+ /DgzE+Ge3Atf2hZQKXsvcJEPmbo0NI2VdMV+eKlmXb3KIXdCEKxmJj3ekav9FfBv7WxfEPjzFvYD
2733
+ io+nEhEMy/0/ecGc/WLuo89UDNErXxc+4z6/wCs+CZv+iKZ+tJIX/COUgb1up8WMwusRRdv4QcmW
2734
+ dupwX3kSa+SjB1oF7ydJzyGfikwJcGapJsErEU4z0g781mzSDjJkaP+tBXhfAx2o45CsJOAPQKdL
2735
+ rosot4LKGAfmt1t06SAZf7IbiVQ=
2736
+ -----END CERTIFICATE-----
2737
+
2738
+ GeoTrust Primary Certification Authority - G3
2739
+ =============================================
2740
+ -----BEGIN CERTIFICATE-----
2741
+ MIID/jCCAuagAwIBAgIQFaxulBmyeUtB9iepwxgPHzANBgkqhkiG9w0BAQsFADCBmDELMAkGA1UE
2742
+ BhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xOTA3BgNVBAsTMChjKSAyMDA4IEdlb1RydXN0
2743
+ IEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTE2MDQGA1UEAxMtR2VvVHJ1c3QgUHJpbWFy
2744
+ eSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEczMB4XDTA4MDQwMjAwMDAwMFoXDTM3MTIwMTIz
2745
+ NTk1OVowgZgxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTkwNwYDVQQLEzAo
2746
+ YykgMjAwOCBHZW9UcnVzdCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxNjA0BgNVBAMT
2747
+ LUdlb1RydXN0IFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMzCCASIwDQYJKoZI
2748
+ hvcNAQEBBQADggEPADCCAQoCggEBANziXmJYHTNXOTIz+uvLh4yn1ErdBojqZI4xmKU4kB6Yzy5j
2749
+ K/BGvESyiaHAKAxJcCGVn2TAppMSAmUmhsalifD614SgcK9PGpc/BkTVyetyEH3kMSj7HGHmKAdE
2750
+ c5IiaacDiGydY8hS2pgn5whMcD60yRLBxWeDXTPzAxHsatBT4tG6NmCUgLthY2xbF37fQJQeqw3C
2751
+ IShwiP/WJmxsYAQlTlV+fe+/lEjetx3dcI0FX4ilm/LC7urRQEFtYjgdVgbFA0dRIBn8exALDmKu
2752
+ dlW/X3e+PkkBUz2YJQN2JFodtNuJ6nnltrM7P7pMKEF/BqxqjsHQ9gUdfeZChuOl1UcCAwEAAaNC
2753
+ MEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFMR5yo6hTgMdHNxr
2754
+ 2zFblD4/MH8tMA0GCSqGSIb3DQEBCwUAA4IBAQAtxRPPVoB7eni9n64smefv2t+UXglpp+duaIy9
2755
+ cr5HqQ6XErhK8WTTOd8lNNTBzU6B8A8ExCSzNJbGpqow32hhc9f5joWJ7w5elShKKiePEI4ufIbE
2756
+ Ap7aDHdlDkQNkv39sxY2+hENHYwOB4lqKVb3cvTdFZx3NWZXqxNT2I7BQMXXExZacse3aQHEerGD
2757
+ AWh9jUGhlBjBJVz88P6DAod8DQ3PLghcSkANPuyBYeYk28rgDi0Hsj5W3I31QYUHSJsMC8tJP33s
2758
+ t/3LjWeJGqvtux6jAAgIFyqCXDFdRootD4abdNlF+9RAsXqqaC2Gspki4cErx5z481+oghLrGREt
2759
+ -----END CERTIFICATE-----
2760
+
2761
+ thawte Primary Root CA - G2
2762
+ ===========================
2763
+ -----BEGIN CERTIFICATE-----
2764
+ MIICiDCCAg2gAwIBAgIQNfwmXNmET8k9Jj1Xm67XVjAKBggqhkjOPQQDAzCBhDELMAkGA1UEBhMC
2765
+ VVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjE4MDYGA1UECxMvKGMpIDIwMDcgdGhhd3RlLCBJbmMu
2766
+ IC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxJDAiBgNVBAMTG3RoYXd0ZSBQcmltYXJ5IFJvb3Qg
2767
+ Q0EgLSBHMjAeFw0wNzExMDUwMDAwMDBaFw0zODAxMTgyMzU5NTlaMIGEMQswCQYDVQQGEwJVUzEV
2768
+ MBMGA1UEChMMdGhhd3RlLCBJbmMuMTgwNgYDVQQLEy8oYykgMjAwNyB0aGF3dGUsIEluYy4gLSBG
2769
+ b3IgYXV0aG9yaXplZCB1c2Ugb25seTEkMCIGA1UEAxMbdGhhd3RlIFByaW1hcnkgUm9vdCBDQSAt
2770
+ IEcyMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEotWcgnuVnfFSeIf+iha/BebfowJPDQfGAFG6DAJS
2771
+ LSKkQjnE/o/qycG+1E3/n3qe4rF8mq2nhglzh9HnmuN6papu+7qzcMBniKI11KOasf2twu8x+qi5
2772
+ 8/sIxpHR+ymVo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQU
2773
+ mtgAMADna3+FGO6Lts6KDPgR4bswCgYIKoZIzj0EAwMDaQAwZgIxAN344FdHW6fmCsO99YCKlzUN
2774
+ G4k8VIZ3KMqh9HneteY4sPBlcIx/AlTCv//YoT7ZzwIxAMSNlPzcU9LcnXgWHxUzI1NS41oxXZ3K
2775
+ rr0TKUQNJ1uo52icEvdYPy5yAlejj6EULg==
2776
+ -----END CERTIFICATE-----
2777
+
2778
+ thawte Primary Root CA - G3
2779
+ ===========================
2780
+ -----BEGIN CERTIFICATE-----
2781
+ MIIEKjCCAxKgAwIBAgIQYAGXt0an6rS0mtZLL/eQ+zANBgkqhkiG9w0BAQsFADCBrjELMAkGA1UE
2782
+ BhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2
2783
+ aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMvKGMpIDIwMDggdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhv
2784
+ cml6ZWQgdXNlIG9ubHkxJDAiBgNVBAMTG3RoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EgLSBHMzAeFw0w
2785
+ ODA0MDIwMDAwMDBaFw0zNzEyMDEyMzU5NTlaMIGuMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMdGhh
2786
+ d3RlLCBJbmMuMSgwJgYDVQQLEx9DZXJ0aWZpY2F0aW9uIFNlcnZpY2VzIERpdmlzaW9uMTgwNgYD
2787
+ VQQLEy8oYykgMjAwOCB0aGF3dGUsIEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTEkMCIG
2788
+ A1UEAxMbdGhhd3RlIFByaW1hcnkgUm9vdCBDQSAtIEczMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
2789
+ MIIBCgKCAQEAsr8nLPvb2FvdeHsbnndmgcs+vHyu86YnmjSjaDFxODNi5PNxZnmxqWWjpYvVj2At
2790
+ P0LMqmsywCPLLEHd5N/8YZzic7IilRFDGF/Eth9XbAoFWCLINkw6fKXRz4aviKdEAhN0cXMKQlkC
2791
+ +BsUa0Lfb1+6a4KinVvnSr0eAXLbS3ToO39/fR8EtCab4LRarEc9VbjXsCZSKAExQGbY2SS99irY
2792
+ 7CFJXJv2eul/VTV+lmuNk5Mny5K76qxAwJ/C+IDPXfRa3M50hqY+bAtTyr2SzhkGcuYMXDhpxwTW
2793
+ vGzOW/b3aJzcJRVIiKHpqfiYnODz1TEoYRFsZ5aNOZnLwkUkOQIDAQABo0IwQDAPBgNVHRMBAf8E
2794
+ BTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUrWyqlGCc7eT/+j4KdCtjA/e2Wb8wDQYJ
2795
+ KoZIhvcNAQELBQADggEBABpA2JVlrAmSicY59BDlqQ5mU1143vokkbvnRFHfxhY0Cu9qRFHqKweK
2796
+ A3rD6z8KLFIWoCtDuSWQP3CpMyVtRRooOyfPqsMpQhvfO0zAMzRbQYi/aytlryjvsvXDqmbOe1bu
2797
+ t8jLZ8HJnBoYuMTDSQPxYA5QzUbF83d597YV4Djbxy8ooAw/dyZ02SUS2jHaGh7cKUGRIjxpp7sC
2798
+ 8rZcJwOJ9Abqm+RyguOhCcHpABnTPtRwa7pxpqpYrvS76Wy274fMm7v/OeZWYdMKp8RcTGB7BXcm
2799
+ er/YB1IsYvdwY9k5vG8cwnncdimvzsUsZAReiDZuMdRAGmI0Nj81Aa6sY6A=
2800
+ -----END CERTIFICATE-----
2801
+
2802
+ GeoTrust Primary Certification Authority - G2
2803
+ =============================================
2804
+ -----BEGIN CERTIFICATE-----
2805
+ MIICrjCCAjWgAwIBAgIQPLL0SAoA4v7rJDteYD7DazAKBggqhkjOPQQDAzCBmDELMAkGA1UEBhMC
2806
+ VVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xOTA3BgNVBAsTMChjKSAyMDA3IEdlb1RydXN0IElu
2807
+ Yy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTE2MDQGA1UEAxMtR2VvVHJ1c3QgUHJpbWFyeSBD
2808
+ ZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcyMB4XDTA3MTEwNTAwMDAwMFoXDTM4MDExODIzNTk1
2809
+ OVowgZgxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTkwNwYDVQQLEzAoYykg
2810
+ MjAwNyBHZW9UcnVzdCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxNjA0BgNVBAMTLUdl
2811
+ b1RydXN0IFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMjB2MBAGByqGSM49AgEG
2812
+ BSuBBAAiA2IABBWx6P0DFUPlrOuHNxFi79KDNlJ9RVcLSo17VDs6bl8VAsBQps8lL33KSLjHUGMc
2813
+ KiEIfJo22Av+0SbFWDEwKCXzXV2juLaltJLtbCyf691DiaI8S0iRHVDsJt/WYC69IaNCMEAwDwYD
2814
+ VR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFBVfNVdRVfslsq0DafwBo/q+
2815
+ EVXVMAoGCCqGSM49BAMDA2cAMGQCMGSWWaboCd6LuvpaiIjwH5HTRqjySkwCY/tsXzjbLkGTqQ7m
2816
+ ndwxHLKgpxgceeHHNgIwOlavmnRs9vuD4DPTCF+hnMJbn0bWtsuRBmOiBuczrD6ogRLQy7rQkgu2
2817
+ npaqBA+K
2818
+ -----END CERTIFICATE-----
2819
+
2820
+ VeriSign Universal Root Certification Authority
2821
+ ===============================================
2822
+ -----BEGIN CERTIFICATE-----
2823
+ MIIEuTCCA6GgAwIBAgIQQBrEZCGzEyEDDrvkEhrFHTANBgkqhkiG9w0BAQsFADCBvTELMAkGA1UE
2824
+ BhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBO
2825
+ ZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwOCBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVk
2826
+ IHVzZSBvbmx5MTgwNgYDVQQDEy9WZXJpU2lnbiBVbml2ZXJzYWwgUm9vdCBDZXJ0aWZpY2F0aW9u
2827
+ IEF1dGhvcml0eTAeFw0wODA0MDIwMDAwMDBaFw0zNzEyMDEyMzU5NTlaMIG9MQswCQYDVQQGEwJV
2828
+ UzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdv
2829
+ cmsxOjA4BgNVBAsTMShjKSAyMDA4IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNl
2830
+ IG9ubHkxODA2BgNVBAMTL1ZlcmlTaWduIFVuaXZlcnNhbCBSb290IENlcnRpZmljYXRpb24gQXV0
2831
+ aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAx2E3XrEBNNti1xWb/1hajCMj
2832
+ 1mCOkdeQmIN65lgZOIzF9uVkhbSicfvtvbnazU0AtMgtc6XHaXGVHzk8skQHnOgO+k1KxCHfKWGP
2833
+ MiJhgsWHH26MfF8WIFFE0XBPV+rjHOPMee5Y2A7Cs0WTwCznmhcrewA3ekEzeOEz4vMQGn+HLL72
2834
+ 9fdC4uW/h2KJXwBL38Xd5HVEMkE6HnFuacsLdUYI0crSK5XQz/u5QGtkjFdN/BMReYTtXlT2NJ8I
2835
+ AfMQJQYXStrxHXpma5hgZqTZ79IugvHw7wnqRMkVauIDbjPTrJ9VAMf2CGqUuV/c4DPxhGD5WycR
2836
+ tPwW8rtWaoAljQIDAQABo4GyMIGvMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMG0G
2837
+ CCsGAQUFBwEMBGEwX6FdoFswWTBXMFUWCWltYWdlL2dpZjAhMB8wBwYFKw4DAhoEFI/l0xqGrI2O
2838
+ a8PPgGrUSBgsexkuMCUWI2h0dHA6Ly9sb2dvLnZlcmlzaWduLmNvbS92c2xvZ28uZ2lmMB0GA1Ud
2839
+ DgQWBBS2d/ppSEefUxLVwuoHMnYH0ZcHGTANBgkqhkiG9w0BAQsFAAOCAQEASvj4sAPmLGd75JR3
2840
+ Y8xuTPl9Dg3cyLk1uXBPY/ok+myDjEedO2Pzmvl2MpWRsXe8rJq+seQxIcaBlVZaDrHC1LGmWazx
2841
+ Y8u4TB1ZkErvkBYoH1quEPuBUDgMbMzxPcP1Y+Oz4yHJJDnp/RVmRvQbEdBNc6N9Rvk97ahfYtTx
2842
+ P/jgdFcrGJ2BtMQo2pSXpXDrrB2+BxHw1dvd5Yzw1TKwg+ZX4o+/vqGqvz0dtdQ46tewXDpPaj+P
2843
+ wGZsY6rp2aQW9IHRlRQOfc2VNNnSj3BzgXucfr2YYdhFh5iQxeuGMMY1v/D/w1WIg0vvBZIGcfK4
2844
+ mJO37M2CYfE45k+XmCpajQ==
2845
+ -----END CERTIFICATE-----
2846
+
2847
+ VeriSign Class 3 Public Primary Certification Authority - G4
2848
+ ============================================================
2849
+ -----BEGIN CERTIFICATE-----
2850
+ MIIDhDCCAwqgAwIBAgIQL4D+I4wOIg9IZxIokYesszAKBggqhkjOPQQDAzCByjELMAkGA1UEBhMC
2851
+ VVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBOZXR3
2852
+ b3JrMTowOAYDVQQLEzEoYykgMjAwNyBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVz
2853
+ ZSBvbmx5MUUwQwYDVQQDEzxWZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmlj
2854
+ YXRpb24gQXV0aG9yaXR5IC0gRzQwHhcNMDcxMTA1MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCByjEL
2855
+ MAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2lnbiBU
2856
+ cnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNyBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRo
2857
+ b3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5
2858
+ IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzQwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAASnVnp8
2859
+ Utpkmw4tXNherJI9/gHmGUo9FANL+mAnINmDiWn6VMaaGF5VKmTeBvaNSjutEDxlPZCIBIngMGGz
2860
+ rl0Bp3vefLK+ymVhAIau2o970ImtTR1ZmkGxvEeA3J5iw/mjgbIwga8wDwYDVR0TAQH/BAUwAwEB
2861
+ /zAOBgNVHQ8BAf8EBAMCAQYwbQYIKwYBBQUHAQwEYTBfoV2gWzBZMFcwVRYJaW1hZ2UvZ2lmMCEw
2862
+ HzAHBgUrDgMCGgQUj+XTGoasjY5rw8+AatRIGCx7GS4wJRYjaHR0cDovL2xvZ28udmVyaXNpZ24u
2863
+ Y29tL3ZzbG9nby5naWYwHQYDVR0OBBYEFLMWkf3upm7ktS5Jj4d4gYDs5bG1MAoGCCqGSM49BAMD
2864
+ A2gAMGUCMGYhDBgmYFo4e1ZC4Kf8NoRRkSAsdk1DPcQdhCPQrNZ8NQbOzWm9kA3bbEhCHQ6qQgIx
2865
+ AJw9SDkjOVgaFRJZap7v1VmyHVIsmXHNxynfGyphe3HR3vPA5Q06Sqotp9iGKt0uEA==
2866
+ -----END CERTIFICATE-----
2867
+
2868
+ NetLock Arany (Class Gold) Főtanúsítvány
2869
+ ============================================
2870
+ -----BEGIN CERTIFICATE-----
2871
+ MIIEFTCCAv2gAwIBAgIGSUEs5AAQMA0GCSqGSIb3DQEBCwUAMIGnMQswCQYDVQQGEwJIVTERMA8G
2872
+ A1UEBwwIQnVkYXBlc3QxFTATBgNVBAoMDE5ldExvY2sgS2Z0LjE3MDUGA1UECwwuVGFuw7pzw610
2873
+ dsOhbnlraWFkw7NrIChDZXJ0aWZpY2F0aW9uIFNlcnZpY2VzKTE1MDMGA1UEAwwsTmV0TG9jayBB
2874
+ cmFueSAoQ2xhc3MgR29sZCkgRsWRdGFuw7pzw610dsOhbnkwHhcNMDgxMjExMTUwODIxWhcNMjgx
2875
+ MjA2MTUwODIxWjCBpzELMAkGA1UEBhMCSFUxETAPBgNVBAcMCEJ1ZGFwZXN0MRUwEwYDVQQKDAxO
2876
+ ZXRMb2NrIEtmdC4xNzA1BgNVBAsMLlRhbsO6c8OtdHbDoW55a2lhZMOzayAoQ2VydGlmaWNhdGlv
2877
+ biBTZXJ2aWNlcykxNTAzBgNVBAMMLE5ldExvY2sgQXJhbnkgKENsYXNzIEdvbGQpIEbFkXRhbsO6
2878
+ c8OtdHbDoW55MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxCRec75LbRTDofTjl5Bu
2879
+ 0jBFHjzuZ9lk4BqKf8owyoPjIMHj9DrTlF8afFttvzBPhCf2nx9JvMaZCpDyD/V/Q4Q3Y1GLeqVw
2880
+ /HpYzY6b7cNGbIRwXdrzAZAj/E4wqX7hJ2Pn7WQ8oLjJM2P+FpD/sLj916jAwJRDC7bVWaaeVtAk
2881
+ H3B5r9s5VA1lddkVQZQBr17s9o3x/61k/iCa11zr/qYfCGSji3ZVrR47KGAuhyXoqq8fxmRGILdw
2882
+ fzzeSNuWU7c5d+Qa4scWhHaXWy+7GRWF+GmF9ZmnqfI0p6m2pgP8b4Y9VHx2BJtr+UBdADTHLpl1
2883
+ neWIA6pN+APSQnbAGwIDAKiLo0UwQzASBgNVHRMBAf8ECDAGAQH/AgEEMA4GA1UdDwEB/wQEAwIB
2884
+ BjAdBgNVHQ4EFgQUzPpnk/C2uNClwB7zU/2MU9+D15YwDQYJKoZIhvcNAQELBQADggEBAKt/7hwW
2885
+ qZw8UQCgwBEIBaeZ5m8BiFRhbvG5GK1Krf6BQCOUL/t1fC8oS2IkgYIL9WHxHG64YTjrgfpioTta
2886
+ YtOUZcTh5m2C+C8lcLIhJsFyUR+MLMOEkMNaj7rP9KdlpeuY0fsFskZ1FSNqb4VjMIDw1Z4fKRzC
2887
+ bLBQWV2QWzuoDTDPv31/zvGdg73JRm4gpvlhUbohL3u+pRVjodSVh/GeufOJ8z2FuLjbvrW5Kfna
2888
+ NwUASZQDhETnv0Mxz3WLJdH0pmT1kvarBes96aULNmLazAZfNou2XjG4Kvte9nHfRCaexOYNkbQu
2889
+ dZWAUWpLMKawYqGT8ZvYzsRjdT9ZR7E=
2890
+ -----END CERTIFICATE-----
2891
+
2892
+ Staat der Nederlanden Root CA - G2
2893
+ ==================================
2894
+ -----BEGIN CERTIFICATE-----
2895
+ MIIFyjCCA7KgAwIBAgIEAJiWjDANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJOTDEeMBwGA1UE
2896
+ CgwVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSswKQYDVQQDDCJTdGFhdCBkZXIgTmVkZXJsYW5kZW4g
2897
+ Um9vdCBDQSAtIEcyMB4XDTA4MDMyNjExMTgxN1oXDTIwMDMyNTExMDMxMFowWjELMAkGA1UEBhMC
2898
+ TkwxHjAcBgNVBAoMFVN0YWF0IGRlciBOZWRlcmxhbmRlbjErMCkGA1UEAwwiU3RhYXQgZGVyIE5l
2899
+ ZGVybGFuZGVuIFJvb3QgQ0EgLSBHMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMVZ
2900
+ 5291qj5LnLW4rJ4L5PnZyqtdj7U5EILXr1HgO+EASGrP2uEGQxGZqhQlEq0i6ABtQ8SpuOUfiUtn
2901
+ vWFI7/3S4GCI5bkYYCjDdyutsDeqN95kWSpGV+RLufg3fNU254DBtvPUZ5uW6M7XxgpT0GtJlvOj
2902
+ CwV3SPcl5XCsMBQgJeN/dVrlSPhOewMHBPqCYYdu8DvEpMfQ9XQ+pV0aCPKbJdL2rAQmPlU6Yiil
2903
+ e7Iwr/g3wtG61jj99O9JMDeZJiFIhQGp5Rbn3JBV3w/oOM2ZNyFPXfUib2rFEhZgF1XyZWampzCR
2904
+ OME4HYYEhLoaJXhena/MUGDWE4dS7WMfbWV9whUYdMrhfmQpjHLYFhN9C0lK8SgbIHRrxT3dsKpI
2905
+ CT0ugpTNGmXZK4iambwYfp/ufWZ8Pr2UuIHOzZgweMFvZ9C+X+Bo7d7iscksWXiSqt8rYGPy5V65
2906
+ 48r6f1CGPqI0GAwJaCgRHOThuVw+R7oyPxjMW4T182t0xHJ04eOLoEq9jWYv6q012iDTiIJh8BIi
2907
+ trzQ1aTsr1SIJSQ8p22xcik/Plemf1WvbibG/ufMQFxRRIEKeN5KzlW/HdXZt1bv8Hb/C3m1r737
2908
+ qWmRRpdogBQ2HbN/uymYNqUg+oJgYjOk7Na6B6duxc8UpufWkjTYgfX8HV2qXB72o007uPc5AgMB
2909
+ AAGjgZcwgZQwDwYDVR0TAQH/BAUwAwEB/zBSBgNVHSAESzBJMEcGBFUdIAAwPzA9BggrBgEFBQcC
2910
+ ARYxaHR0cDovL3d3dy5wa2lvdmVyaGVpZC5ubC9wb2xpY2llcy9yb290LXBvbGljeS1HMjAOBgNV
2911
+ HQ8BAf8EBAMCAQYwHQYDVR0OBBYEFJFoMocVHYnitfGsNig0jQt8YojrMA0GCSqGSIb3DQEBCwUA
2912
+ A4ICAQCoQUpnKpKBglBu4dfYszk78wIVCVBR7y29JHuIhjv5tLySCZa59sCrI2AGeYwRTlHSeYAz
2913
+ +51IvuxBQ4EffkdAHOV6CMqqi3WtFMTC6GY8ggen5ieCWxjmD27ZUD6KQhgpxrRW/FYQoAUXvQwj
2914
+ f/ST7ZwaUb7dRUG/kSS0H4zpX897IZmflZ85OkYcbPnNe5yQzSipx6lVu6xiNGI1E0sUOlWDuYaN
2915
+ kqbG9AclVMwWVxJKgnjIFNkXgiYtXSAfea7+1HAWFpWD2DU5/1JddRwWxRNVz0fMdWVSSt7wsKfk
2916
+ CpYL+63C4iWEst3kvX5ZbJvw8NjnyvLplzh+ib7M+zkXYT9y2zqR2GUBGR2tUKRXCnxLvJxxcypF
2917
+ URmFzI79R6d0lR2o0a9OF7FpJsKqeFdbxU2n5Z4FF5TKsl+gSRiNNOkmbEgeqmiSBeGCc1qb3Adb
2918
+ CG19ndeNIdn8FCCqwkXfP+cAslHkwvgFuXkajDTznlvkN1trSt8sV4pAWja63XVECDdCcAz+3F4h
2919
+ oKOKwJCcaNpQ5kUQR3i2TtJlycM33+FCY7BXN0Ute4qcvwXqZVUz9zkQxSgqIXobisQk+T8VyJoV
2920
+ IPVVYpbtbZNQvOSqeK3Zywplh6ZmwcSBo3c6WB4L7oOLnR7SUqTMHW+wmG2UMbX4cQrcufx9MmDm
2921
+ 66+KAQ==
2922
+ -----END CERTIFICATE-----
2923
+
2924
+ CA Disig
2925
+ ========
2926
+ -----BEGIN CERTIFICATE-----
2927
+ MIIEDzCCAvegAwIBAgIBATANBgkqhkiG9w0BAQUFADBKMQswCQYDVQQGEwJTSzETMBEGA1UEBxMK
2928
+ QnJhdGlzbGF2YTETMBEGA1UEChMKRGlzaWcgYS5zLjERMA8GA1UEAxMIQ0EgRGlzaWcwHhcNMDYw
2929
+ MzIyMDEzOTM0WhcNMTYwMzIyMDEzOTM0WjBKMQswCQYDVQQGEwJTSzETMBEGA1UEBxMKQnJhdGlz
2930
+ bGF2YTETMBEGA1UEChMKRGlzaWcgYS5zLjERMA8GA1UEAxMIQ0EgRGlzaWcwggEiMA0GCSqGSIb3
2931
+ DQEBAQUAA4IBDwAwggEKAoIBAQCS9jHBfYj9mQGp2HvycXXxMcbzdWb6UShGhJd4NLxs/LxFWYgm
2932
+ GErENx+hSkS943EE9UQX4j/8SFhvXJ56CbpRNyIjZkMhsDxkovhqFQ4/61HhVKndBpnXmjxUizkD
2933
+ Pw/Fzsbrg3ICqB9x8y34dQjbYkzo+s7552oftms1grrijxaSfQUMbEYDXcDtab86wYqg6I7ZuUUo
2934
+ hwjstMoVvoLdtUSLLa2GDGhibYVW8qwUYzrG0ZmsNHhWS8+2rT+MitcE5eN4TPWGqvWP+j1scaMt
2935
+ ymfraHtuM6kMgiioTGohQBUgDCZbg8KpFhXAJIJdKxatymP2dACw30PEEGBWZ2NFAgMBAAGjgf8w
2936
+ gfwwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUjbJJaJ1yCCW5wCf1UJNWSEZx+Y8wDgYDVR0P
2937
+ AQH/BAQDAgEGMDYGA1UdEQQvMC2BE2Nhb3BlcmF0b3JAZGlzaWcuc2uGFmh0dHA6Ly93d3cuZGlz
2938
+ aWcuc2svY2EwZgYDVR0fBF8wXTAtoCugKYYnaHR0cDovL3d3dy5kaXNpZy5zay9jYS9jcmwvY2Ff
2939
+ ZGlzaWcuY3JsMCygKqAohiZodHRwOi8vY2EuZGlzaWcuc2svY2EvY3JsL2NhX2Rpc2lnLmNybDAa
2940
+ BgNVHSAEEzARMA8GDSuBHpGT5goAAAABAQEwDQYJKoZIhvcNAQEFBQADggEBAF00dGFMrzvY/59t
2941
+ WDYcPQuBDRIrRhCA/ec8J9B6yKm2fnQwM6M6int0wHl5QpNt/7EpFIKrIYwvF/k/Ji/1WcbvgAa3
2942
+ mkkp7M5+cTxqEEHA9tOasnxakZzArFvITV734VP/Q3f8nktnbNfzg9Gg4H8l37iYC5oyOGwwoPP/
2943
+ CBUz91BKez6jPiCp3C9WgArtQVCwyfTssuMmRAAOb54GvCKWU3BlxFAKRmukLyeBEicTXxChds6K
2944
+ ezfqwzlhA5WYOudsiCUI/HloDYd9Yvi0X/vF2Ey9WLw/Q1vUHgFNPGO+I++MzVpQuGhU+QqZMxEA
2945
+ 4Z7CRneC9VkGjCFMhwnN5ag=
2946
+ -----END CERTIFICATE-----
2947
+
2948
+ Juur-SK
2949
+ =======
2950
+ -----BEGIN CERTIFICATE-----
2951
+ MIIE5jCCA86gAwIBAgIEO45L/DANBgkqhkiG9w0BAQUFADBdMRgwFgYJKoZIhvcNAQkBFglwa2lA
2952
+ c2suZWUxCzAJBgNVBAYTAkVFMSIwIAYDVQQKExlBUyBTZXJ0aWZpdHNlZXJpbWlza2Vza3VzMRAw
2953
+ DgYDVQQDEwdKdXVyLVNLMB4XDTAxMDgzMDE0MjMwMVoXDTE2MDgyNjE0MjMwMVowXTEYMBYGCSqG
2954
+ SIb3DQEJARYJcGtpQHNrLmVlMQswCQYDVQQGEwJFRTEiMCAGA1UEChMZQVMgU2VydGlmaXRzZWVy
2955
+ aW1pc2tlc2t1czEQMA4GA1UEAxMHSnV1ci1TSzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
2956
+ ggEBAIFxNj4zB9bjMI0TfncyRsvPGbJgMUaXhvSYRqTCZUXP00B841oiqBB4M8yIsdOBSvZiF3tf
2957
+ TQou0M+LI+5PAk676w7KvRhj6IAcjeEcjT3g/1tf6mTll+g/mX8MCgkzABpTpyHhOEvWgxutr2TC
2958
+ +Rx6jGZITWYfGAriPrsfB2WThbkasLnE+w0R9vXW+RvHLCu3GFH+4Hv2qEivbDtPL+/40UceJlfw
2959
+ UR0zlv/vWT3aTdEVNMfqPxZIe5EcgEMPPbgFPtGzlc3Yyg/CQ2fbt5PgIoIuvvVoKIO5wTtpeyDa
2960
+ Tpxt4brNj3pssAki14sL2xzVWiZbDcDq5WDQn/413z8CAwEAAaOCAawwggGoMA8GA1UdEwEB/wQF
2961
+ MAMBAf8wggEWBgNVHSAEggENMIIBCTCCAQUGCisGAQQBzh8BAQEwgfYwgdAGCCsGAQUFBwICMIHD
2962
+ HoHAAFMAZQBlACAAcwBlAHIAdABpAGYAaQBrAGEAYQB0ACAAbwBuACAAdgDkAGwAagBhAHMAdABh
2963
+ AHQAdQBkACAAQQBTAC0AaQBzACAAUwBlAHIAdABpAGYAaQB0AHMAZQBlAHIAaQBtAGkAcwBrAGUA
2964
+ cwBrAHUAcwAgAGEAbABhAG0ALQBTAEsAIABzAGUAcgB0AGkAZgBpAGsAYQBhAHQAaQBkAGUAIABr
2965
+ AGkAbgBuAGkAdABhAG0AaQBzAGUAawBzMCEGCCsGAQUFBwIBFhVodHRwOi8vd3d3LnNrLmVlL2Nw
2966
+ cy8wKwYDVR0fBCQwIjAgoB6gHIYaaHR0cDovL3d3dy5zay5lZS9qdXVyL2NybC8wHQYDVR0OBBYE
2967
+ FASqekej5ImvGs8KQKcYP2/v6X2+MB8GA1UdIwQYMBaAFASqekej5ImvGs8KQKcYP2/v6X2+MA4G
2968
+ A1UdDwEB/wQEAwIB5jANBgkqhkiG9w0BAQUFAAOCAQEAe8EYlFOiCfP+JmeaUOTDBS8rNXiRTHyo
2969
+ ERF5TElZrMj3hWVcRrs7EKACr81Ptcw2Kuxd/u+gkcm2k298gFTsxwhwDY77guwqYHhpNjbRxZyL
2970
+ abVAyJRld/JXIWY7zoVAtjNjGr95HvxcHdMdkxuLDF2FvZkwMhgJkVLpfKG6/2SSmuz+Ne6ML678
2971
+ IIbsSt4beDI3poHSna9aEhbKmVv8b20OxaAehsmR0FyYgl9jDIpaq9iVpszLita/ZEuOyoqysOkh
2972
+ Mp6qqIWYNIE5ITuoOlIyPfZrN4YGWhWY3PARZv40ILcD9EEQfTmEeZZyY7aWAuVrua0ZTbvGRNs2
2973
+ yyqcjg==
2974
+ -----END CERTIFICATE-----
2975
+
2976
+ Hongkong Post Root CA 1
2977
+ =======================
2978
+ -----BEGIN CERTIFICATE-----
2979
+ MIIDMDCCAhigAwIBAgICA+gwDQYJKoZIhvcNAQEFBQAwRzELMAkGA1UEBhMCSEsxFjAUBgNVBAoT
2980
+ DUhvbmdrb25nIFBvc3QxIDAeBgNVBAMTF0hvbmdrb25nIFBvc3QgUm9vdCBDQSAxMB4XDTAzMDUx
2981
+ NTA1MTMxNFoXDTIzMDUxNTA0NTIyOVowRzELMAkGA1UEBhMCSEsxFjAUBgNVBAoTDUhvbmdrb25n
2982
+ IFBvc3QxIDAeBgNVBAMTF0hvbmdrb25nIFBvc3QgUm9vdCBDQSAxMIIBIjANBgkqhkiG9w0BAQEF
2983
+ AAOCAQ8AMIIBCgKCAQEArP84tulmAknjorThkPlAj3n54r15/gK97iSSHSL22oVyaf7XPwnU3ZG1
2984
+ ApzQjVrhVcNQhrkpJsLj2aDxaQMoIIBFIi1WpztUlVYiWR8o3x8gPW2iNr4joLFutbEnPzlTCeqr
2985
+ auh0ssJlXI6/fMN4hM2eFvz1Lk8gKgifd/PFHsSaUmYeSF7jEAaPIpjhZY4bXSNmO7ilMlHIhqqh
2986
+ qZ5/dpTCpmy3QfDVyAY45tQM4vM7TG1QjMSDJ8EThFk9nnV0ttgCXjqQesBCNnLsak3c78QA3xMY
2987
+ V18meMjWCnl3v/evt3a5pQuEF10Q6m/hq5URX208o1xNg1vysxmKgIsLhwIDAQABoyYwJDASBgNV
2988
+ HRMBAf8ECDAGAQH/AgEDMA4GA1UdDwEB/wQEAwIBxjANBgkqhkiG9w0BAQUFAAOCAQEADkbVPK7i
2989
+ h9legYsCmEEIjEy82tvuJxuC52pF7BaLT4Wg87JwvVqWuspube5Gi27nKi6Wsxkz67SfqLI37pio
2990
+ l7Yutmcn1KZJ/RyTZXaeQi/cImyaT/JaFTmxcdcrUehtHJjA2Sr0oYJ71clBoiMBdDhViw+5Lmei
2991
+ IAQ32pwL0xch4I+XeTRvhEgCIDMb5jREn5Fw9IBehEPCKdJsEhTkYY2sEJCehFC78JZvRZ+K88ps
2992
+ T/oROhUVRsPNH4NbLUES7VBnQRM9IauUiqpOfMGx+6fWtScvl6tu4B3i0RwsH0Ti/L6RoZz71ilT
2993
+ c4afU9hDDl3WY4JxHYB0yvbiAmvZWg==
2994
+ -----END CERTIFICATE-----
2995
+
2996
+ SecureSign RootCA11
2997
+ ===================
2998
+ -----BEGIN CERTIFICATE-----
2999
+ MIIDbTCCAlWgAwIBAgIBATANBgkqhkiG9w0BAQUFADBYMQswCQYDVQQGEwJKUDErMCkGA1UEChMi
3000
+ SmFwYW4gQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcywgSW5jLjEcMBoGA1UEAxMTU2VjdXJlU2lnbiBS
3001
+ b290Q0ExMTAeFw0wOTA0MDgwNDU2NDdaFw0yOTA0MDgwNDU2NDdaMFgxCzAJBgNVBAYTAkpQMSsw
3002
+ KQYDVQQKEyJKYXBhbiBDZXJ0aWZpY2F0aW9uIFNlcnZpY2VzLCBJbmMuMRwwGgYDVQQDExNTZWN1
3003
+ cmVTaWduIFJvb3RDQTExMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA/XeqpRyQBTvL
3004
+ TJszi1oURaTnkBbR31fSIRCkF/3frNYfp+TbfPfs37gD2pRY/V1yfIw/XwFndBWW4wI8h9uuywGO
3005
+ wvNmxoVF9ALGOrVisq/6nL+k5tSAMJjzDbaTj6nU2DbysPyKyiyhFTOVMdrAG/LuYpmGYz+/3ZMq
3006
+ g6h2uRMft85OQoWPIucuGvKVCbIFtUROd6EgvanyTgp9UK31BQ1FT0Zx/Sg+U/sE2C3XZR1KG/rP
3007
+ O7AxmjVuyIsG0wCR8pQIZUyxNAYAeoni8McDWc/V1uinMrPmmECGxc0nEovMe863ETxiYAcjPitA
3008
+ bpSACW22s293bzUIUPsCh8U+iQIDAQABo0IwQDAdBgNVHQ4EFgQUW/hNT7KlhtQ60vFjmqC+CfZX
3009
+ t94wDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAKCh
3010
+ OBZmLqdWHyGcBvod7bkixTgm2E5P7KN/ed5GIaGHd48HCJqypMWvDzKYC3xmKbabfSVSSUOrTC4r
3011
+ bnpwrxYO4wJs+0LmGJ1F2FXI6Dvd5+H0LgscNFxsWEr7jIhQX5Ucv+2rIrVls4W6ng+4reV6G4pQ
3012
+ Oh29Dbx7VFALuUKvVaAYga1lme++5Jy/xIWrQbJUb9wlze144o4MjQlJ3WN7WmmWAiGovVJZ6X01
3013
+ y8hSyn+B/tlr0/cR7SXf+Of5pPpyl4RTDaXQMhhRdlkUbA/r7F+AjHVDg8OFmP9Mni0N5HeDk061
3014
+ lgeLKBObjBmNQSdJQO7e5iNEOdyhIta6A/I=
3015
+ -----END CERTIFICATE-----
3016
+
3017
+ ACEDICOM Root
3018
+ =============
3019
+ -----BEGIN CERTIFICATE-----
3020
+ MIIFtTCCA52gAwIBAgIIYY3HhjsBggUwDQYJKoZIhvcNAQEFBQAwRDEWMBQGA1UEAwwNQUNFRElD
3021
+ T00gUm9vdDEMMAoGA1UECwwDUEtJMQ8wDQYDVQQKDAZFRElDT00xCzAJBgNVBAYTAkVTMB4XDTA4
3022
+ MDQxODE2MjQyMloXDTI4MDQxMzE2MjQyMlowRDEWMBQGA1UEAwwNQUNFRElDT00gUm9vdDEMMAoG
3023
+ A1UECwwDUEtJMQ8wDQYDVQQKDAZFRElDT00xCzAJBgNVBAYTAkVTMIICIjANBgkqhkiG9w0BAQEF
3024
+ AAOCAg8AMIICCgKCAgEA/5KV4WgGdrQsyFhIyv2AVClVYyT/kGWbEHV7w2rbYgIB8hiGtXxaOLHk
3025
+ WLn709gtn70yN78sFW2+tfQh0hOR2QetAQXW8713zl9CgQr5auODAKgrLlUTY4HKRxx7XBZXehuD
3026
+ YAQ6PmXDzQHe3qTWDLqO3tkE7hdWIpuPY/1NFgu3e3eM+SW10W2ZEi5PGrjm6gSSrj0RuVFCPYew
3027
+ MYWveVqc/udOXpJPQ/yrOq2lEiZmueIM15jO1FillUAKt0SdE3QrwqXrIhWYENiLxQSfHY9g5QYb
3028
+ m8+5eaA9oiM/Qj9r+hwDezCNzmzAv+YbX79nuIQZ1RXve8uQNjFiybwCq0Zfm/4aaJQ0PZCOrfbk
3029
+ HQl/Sog4P75n/TSW9R28MHTLOO7VbKvU/PQAtwBbhTIWdjPp2KOZnQUAqhbm84F9b32qhm2tFXTT
3030
+ xKJxqvQUfecyuB+81fFOvW8XAjnXDpVCOscAPukmYxHqC9FK/xidstd7LzrZlvvoHpKuE1XI2Sf2
3031
+ 3EgbsCTBheN3nZqk8wwRHQ3ItBTutYJXCb8gWH8vIiPYcMt5bMlL8qkqyPyHK9caUPgn6C9D4zq9
3032
+ 2Fdx/c6mUlv53U3t5fZvie27k5x2IXXwkkwp9y+cAS7+UEaeZAwUswdbxcJzbPEHXEUkFDWug/Fq
3033
+ TYl6+rPYLWbwNof1K1MCAwEAAaOBqjCBpzAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFKaz
3034
+ 4SsrSbbXc6GqlPUB53NlTKxQMA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUprPhKytJttdzoaqU
3035
+ 9QHnc2VMrFAwRAYDVR0gBD0wOzA5BgRVHSAAMDEwLwYIKwYBBQUHAgEWI2h0dHA6Ly9hY2VkaWNv
3036
+ bS5lZGljb21ncm91cC5jb20vZG9jMA0GCSqGSIb3DQEBBQUAA4ICAQDOLAtSUWImfQwng4/F9tqg
3037
+ aHtPkl7qpHMyEVNEskTLnewPeUKzEKbHDZ3Ltvo/Onzqv4hTGzz3gvoFNTPhNahXwOf9jU8/kzJP
3038
+ eGYDdwdY6ZXIfj7QeQCM8htRM5u8lOk6e25SLTKeI6RF+7YuE7CLGLHdztUdp0J/Vb77W7tH1Pwk
3039
+ zQSulgUV1qzOMPPKC8W64iLgpq0i5ALudBF/TP94HTXa5gI06xgSYXcGCRZj6hitoocf8seACQl1
3040
+ ThCojz2GuHURwCRiipZ7SkXp7FnFvmuD5uHorLUwHv4FB4D54SMNUI8FmP8sX+g7tq3PgbUhh8oI
3041
+ KiMnMCArz+2UW6yyetLHKKGKC5tNSixthT8Jcjxn4tncB7rrZXtaAWPWkFtPF2Y9fwsZo5NjEFIq
3042
+ nxQWWOLcpfShFosOkYuByptZ+thrkQdlVV9SH686+5DdaaVbnG0OLLb6zqylfDJKZ0DcMDQj3dcE
3043
+ I2bw/FWAp/tmGYI1Z2JwOV5vx+qQQEQIHriy1tvuWacNGHk0vFQYXlPKNFHtRQrmjseCNj6nOGOp
3044
+ MCwXEGCSn1WHElkQwg9naRHMTh5+Spqtr0CodaxWkHS4oJyleW/c6RrIaQXpuvoDs3zk4E7Czp3o
3045
+ tkYNbn5XOmeUwssfnHdKZ05phkOTOPu220+DkdRgfks+KzgHVZhepA==
3046
+ -----END CERTIFICATE-----
3047
+
3048
+ Verisign Class 1 Public Primary Certification Authority
3049
+ =======================================================
3050
+ -----BEGIN CERTIFICATE-----
3051
+ MIICPDCCAaUCED9pHoGc8JpK83P/uUii5N0wDQYJKoZIhvcNAQEFBQAwXzELMAkGA1UEBhMCVVMx
3052
+ FzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFzcyAxIFB1YmxpYyBQcmltYXJ5
3053
+ IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTk2MDEyOTAwMDAwMFoXDTI4MDgwMjIzNTk1OVow
3054
+ XzELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFzcyAx
3055
+ IFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGfMA0GCSqGSIb3DQEBAQUA
3056
+ A4GNADCBiQKBgQDlGb9to1ZhLZlIcfZn3rmN67eehoAKkQ76OCWvRoiC5XOooJskXQ0fzGVuDLDQ
3057
+ VoQYh5oGmxChc9+0WDlrbsH2FdWoqD+qEgaNMax/sDTXjzRniAnNFBHiTkVWaR94AoDa3EeRKbs2
3058
+ yWNcxeDXLYd7obcysHswuiovMaruo2fa2wIDAQABMA0GCSqGSIb3DQEBBQUAA4GBAFgVKTk8d6Pa
3059
+ XCUDfGD67gmZPCcQcMgMCeazh88K4hiWNWLMv5sneYlfycQJ9M61Hd8qveXbhpxoJeUwfLaJFf5n
3060
+ 0a3hUKw8fGJLj7qE1xIVGx/KXQ/BUpQqEZnae88MNhPVNdwQGVnqlMEAv3WP2fr9dgTbYruQagPZ
3061
+ RjXZ+Hxb
3062
+ -----END CERTIFICATE-----
3063
+
3064
+ Verisign Class 3 Public Primary Certification Authority
3065
+ =======================================================
3066
+ -----BEGIN CERTIFICATE-----
3067
+ MIICPDCCAaUCEDyRMcsf9tAbDpq40ES/Er4wDQYJKoZIhvcNAQEFBQAwXzELMAkGA1UEBhMCVVMx
3068
+ FzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFzcyAzIFB1YmxpYyBQcmltYXJ5
3069
+ IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTk2MDEyOTAwMDAwMFoXDTI4MDgwMjIzNTk1OVow
3070
+ XzELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFzcyAz
3071
+ IFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGfMA0GCSqGSIb3DQEBAQUA
3072
+ A4GNADCBiQKBgQDJXFme8huKARS0EN8EQNvjV69qRUCPhAwL0TPZ2RHP7gJYHyX3KqhEBarsAx94
3073
+ f56TuZoAqiN91qyFomNFx3InzPRMxnVx0jnvT0Lwdd8KkMaOIG+YD/isI19wKTakyYbnsZogy1Ol
3074
+ hec9vn2a/iRFM9x2Fe0PonFkTGUugWhFpwIDAQABMA0GCSqGSIb3DQEBBQUAA4GBABByUqkFFBky
3075
+ CEHwxWsKzH4PIRnN5GfcX6kb5sroc50i2JhucwNhkcV8sEVAbkSdjbCxlnRhLQ2pRdKkkirWmnWX
3076
+ bj9T/UWZYB2oK0z5XqcJ2HUw19JlYD1n1khVdWk/kfVIC0dpImmClr7JyDiGSnoscxlIaU5rfGW/
3077
+ D/xwzoiQ
3078
+ -----END CERTIFICATE-----
3079
+
3080
+ Microsec e-Szigno Root CA 2009
3081
+ ==============================
3082
+ -----BEGIN CERTIFICATE-----
3083
+ MIIECjCCAvKgAwIBAgIJAMJ+QwRORz8ZMA0GCSqGSIb3DQEBCwUAMIGCMQswCQYDVQQGEwJIVTER
3084
+ MA8GA1UEBwwIQnVkYXBlc3QxFjAUBgNVBAoMDU1pY3Jvc2VjIEx0ZC4xJzAlBgNVBAMMHk1pY3Jv
3085
+ c2VjIGUtU3ppZ25vIFJvb3QgQ0EgMjAwOTEfMB0GCSqGSIb3DQEJARYQaW5mb0BlLXN6aWduby5o
3086
+ dTAeFw0wOTA2MTYxMTMwMThaFw0yOTEyMzAxMTMwMThaMIGCMQswCQYDVQQGEwJIVTERMA8GA1UE
3087
+ BwwIQnVkYXBlc3QxFjAUBgNVBAoMDU1pY3Jvc2VjIEx0ZC4xJzAlBgNVBAMMHk1pY3Jvc2VjIGUt
3088
+ U3ppZ25vIFJvb3QgQ0EgMjAwOTEfMB0GCSqGSIb3DQEJARYQaW5mb0BlLXN6aWduby5odTCCASIw
3089
+ DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOn4j/NjrdqG2KfgQvvPkd6mJviZpWNwrZuuyjNA
3090
+ fW2WbqEORO7hE52UQlKavXWFdCyoDh2Tthi3jCyoz/tccbna7P7ofo/kLx2yqHWH2Leh5TvPmUpG
3091
+ 0IMZfcChEhyVbUr02MelTTMuhTlAdX4UfIASmFDHQWe4oIBhVKZsTh/gnQ4H6cm6M+f+wFUoLAKA
3092
+ pxn1ntxVUwOXewdI/5n7N4okxFnMUBBjjqqpGrCEGob5X7uxUG6k0QrM1XF+H6cbfPVTbiJfyyvm
3093
+ 1HxdrtbCxkzlBQHZ7Vf8wSN5/PrIJIOV87VqUQHQd9bpEqH5GoP7ghu5sJf0dgYzQ0mg/wu1+rUC
3094
+ AwEAAaOBgDB+MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBTLD8bf
3095
+ QkPMPcu1SCOhGnqmKrs0aDAfBgNVHSMEGDAWgBTLD8bfQkPMPcu1SCOhGnqmKrs0aDAbBgNVHREE
3096
+ FDASgRBpbmZvQGUtc3ppZ25vLmh1MA0GCSqGSIb3DQEBCwUAA4IBAQDJ0Q5eLtXMs3w+y/w9/w0o
3097
+ lZMEyL/azXm4Q5DwpL7v8u8hmLzU1F0G9u5C7DBsoKqpyvGvivo/C3NqPuouQH4frlRheesuCDfX
3098
+ I/OMn74dseGkddug4lQUsbocKaQY9hK6ohQU4zE1yED/t+AFdlfBHFny+L/k7SViXITwfn4fs775
3099
+ tyERzAMBVnCnEJIeGzSBHq2cGsMEPO0CYdYeBvNfOofyK/FFh+U9rNHHV4S9a67c2Pm2G2JwCz02
3100
+ yULyMtd6YebS2z3PyKnJm9zbWETXbzivf3jTo60adbocwTZ8jx5tHMN1Rq41Bab2XD0h7lbwyYIi
3101
+ LXpUq3DDfSJlgnCW
3102
+ -----END CERTIFICATE-----
3103
+
3104
+ E-Guven Kok Elektronik Sertifika Hizmet Saglayicisi
3105
+ ===================================================
3106
+ -----BEGIN CERTIFICATE-----
3107
+ MIIDtjCCAp6gAwIBAgIQRJmNPMADJ72cdpW56tustTANBgkqhkiG9w0BAQUFADB1MQswCQYDVQQG
3108
+ EwJUUjEoMCYGA1UEChMfRWxla3Ryb25payBCaWxnaSBHdXZlbmxpZ2kgQS5TLjE8MDoGA1UEAxMz
3109
+ ZS1HdXZlbiBLb2sgRWxla3Ryb25payBTZXJ0aWZpa2EgSGl6bWV0IFNhZ2xheWljaXNpMB4XDTA3
3110
+ MDEwNDExMzI0OFoXDTE3MDEwNDExMzI0OFowdTELMAkGA1UEBhMCVFIxKDAmBgNVBAoTH0VsZWt0
3111
+ cm9uaWsgQmlsZ2kgR3V2ZW5saWdpIEEuUy4xPDA6BgNVBAMTM2UtR3V2ZW4gS29rIEVsZWt0cm9u
3112
+ aWsgU2VydGlmaWthIEhpem1ldCBTYWdsYXlpY2lzaTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC
3113
+ AQoCggEBAMMSIJ6wXgBljU5Gu4Bc6SwGl9XzcslwuedLZYDBS75+PNdUMZTe1RK6UxYC6lhj71vY
3114
+ 8+0qGqpxSKPcEC1fX+tcS5yWCEIlKBHMilpiAVDV6wlTL/jDj/6z/P2douNffb7tC+Bg62nsM+3Y
3115
+ jfsSSYMAyYuXjDtzKjKzEve5TfL0TW3H5tYmNwjy2f1rXKPlSFxYvEK+A1qBuhw1DADT9SN+cTAI
3116
+ JjjcJRFHLfO6IxClv7wC90Nex/6wN1CZew+TzuZDLMN+DfIcQ2Zgy2ExR4ejT669VmxMvLz4Bcpk
3117
+ 9Ok0oSy1c+HCPujIyTQlCFzz7abHlJ+tiEMl1+E5YP6sOVkCAwEAAaNCMEAwDgYDVR0PAQH/BAQD
3118
+ AgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFJ/uRLOU1fqRTy7ZVZoEVtstxNulMA0GCSqG
3119
+ SIb3DQEBBQUAA4IBAQB/X7lTW2M9dTLn+sR0GstG30ZpHFLPqk/CaOv/gKlR6D1id4k9CnU58W5d
3120
+ F4dvaAXBlGzZXd/aslnLpRCKysw5zZ/rTt5S/wzw9JKp8mxTq5vSR6AfdPebmvEvFZ96ZDAYBzwq
3121
+ D2fK/A+JYZ1lpTzlvBNbCNvj/+27BrtqBrF6T2XGgv0enIu1De5Iu7i9qgi0+6N8y5/NkHZchpZ4
3122
+ Vwpm+Vganf2XKWDeEaaQHBkc7gGWIjQ0LpH5t8Qn0Xvmv/uARFoW5evg1Ao4vOSR49XrXMGs3xtq
3123
+ fJ7lddK2l4fbzIcrQzqECK+rPNv3PGYxhrCdU3nt+CPeQuMtgvEP5fqX
3124
+ -----END CERTIFICATE-----
3125
+
3126
+ GlobalSign Root CA - R3
3127
+ =======================
3128
+ -----BEGIN CERTIFICATE-----
3129
+ MIIDXzCCAkegAwIBAgILBAAAAAABIVhTCKIwDQYJKoZIhvcNAQELBQAwTDEgMB4GA1UECxMXR2xv
3130
+ YmFsU2lnbiBSb290IENBIC0gUjMxEzARBgNVBAoTCkdsb2JhbFNpZ24xEzARBgNVBAMTCkdsb2Jh
3131
+ bFNpZ24wHhcNMDkwMzE4MTAwMDAwWhcNMjkwMzE4MTAwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxT
3132
+ aWduIFJvb3QgQ0EgLSBSMzETMBEGA1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2ln
3133
+ bjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMwldpB5BngiFvXAg7aEyiie/QV2EcWt
3134
+ iHL8RgJDx7KKnQRfJMsuS+FggkbhUqsMgUdwbN1k0ev1LKMPgj0MK66X17YUhhB5uzsTgHeMCOFJ
3135
+ 0mpiLx9e+pZo34knlTifBtc+ycsmWQ1z3rDI6SYOgxXG71uL0gRgykmmKPZpO/bLyCiR5Z2KYVc3
3136
+ rHQU3HTgOu5yLy6c+9C7v/U9AOEGM+iCK65TpjoWc4zdQQ4gOsC0p6Hpsk+QLjJg6VfLuQSSaGjl
3137
+ OCZgdbKfd/+RFO+uIEn8rUAVSNECMWEZXriX7613t2Saer9fwRPvm2L7DWzgVGkWqQPabumDk3F2
3138
+ xmmFghcCAwEAAaNCMEAwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYE
3139
+ FI/wS3+oLkUkrk1Q+mOai97i3Ru8MA0GCSqGSIb3DQEBCwUAA4IBAQBLQNvAUKr+yAzv95ZURUm7
3140
+ lgAJQayzE4aGKAczymvmdLm6AC2upArT9fHxD4q/c2dKg8dEe3jgr25sbwMpjjM5RcOO5LlXbKr8
3141
+ EpbsU8Yt5CRsuZRj+9xTaGdWPoO4zzUhw8lo/s7awlOqzJCK6fBdRoyV3XpYKBovHd7NADdBj+1E
3142
+ bddTKJd+82cEHhXXipa0095MJ6RMG3NzdvQXmcIfeg7jLQitChws/zyrVQ4PkX4268NXSb7hLi18
3143
+ YIvDQVETI53O9zJrlAGomecsMx86OyXShkDOOyyGeMlhLxS67ttVb9+E7gUJTb0o2HLO02JQZR7r
3144
+ kpeDMdmztcpHWD9f
3145
+ -----END CERTIFICATE-----
3146
+
3147
+ TC TrustCenter Universal CA III
3148
+ ===============================
3149
+ -----BEGIN CERTIFICATE-----
3150
+ MIID4TCCAsmgAwIBAgIOYyUAAQACFI0zFQLkbPQwDQYJKoZIhvcNAQEFBQAwezELMAkGA1UEBhMC
3151
+ REUxHDAaBgNVBAoTE1RDIFRydXN0Q2VudGVyIEdtYkgxJDAiBgNVBAsTG1RDIFRydXN0Q2VudGVy
3152
+ IFVuaXZlcnNhbCBDQTEoMCYGA1UEAxMfVEMgVHJ1c3RDZW50ZXIgVW5pdmVyc2FsIENBIElJSTAe
3153
+ Fw0wOTA5MDkwODE1MjdaFw0yOTEyMzEyMzU5NTlaMHsxCzAJBgNVBAYTAkRFMRwwGgYDVQQKExNU
3154
+ QyBUcnVzdENlbnRlciBHbWJIMSQwIgYDVQQLExtUQyBUcnVzdENlbnRlciBVbml2ZXJzYWwgQ0Ex
3155
+ KDAmBgNVBAMTH1RDIFRydXN0Q2VudGVyIFVuaXZlcnNhbCBDQSBJSUkwggEiMA0GCSqGSIb3DQEB
3156
+ AQUAA4IBDwAwggEKAoIBAQDC2pxisLlxErALyBpXsq6DFJmzNEubkKLF5+cvAqBNLaT6hdqbJYUt
3157
+ QCggbergvbFIgyIpRJ9Og+41URNzdNW88jBmlFPAQDYvDIRlzg9uwliT6CwLOunBjvvya8o84pxO
3158
+ juT5fdMnnxvVZ3iHLX8LR7PH6MlIfK8vzArZQe+f/prhsq75U7Xl6UafYOPfjdN/+5Z+s7Vy+Eut
3159
+ CHnNaYlAJ/Uqwa1D7KRTyGG299J5KmcYdkhtWyUB0SbFt1dpIxVbYYqt8Bst2a9c8SaQaanVDED1
3160
+ M4BDj5yjdipFtK+/fz6HP3bFzSreIMUWWMv5G/UPyw0RUmS40nZid4PxWJ//AgMBAAGjYzBhMB8G
3161
+ A1UdIwQYMBaAFFbn4VslQ4Dg9ozhcbyO5YAvxEjiMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/
3162
+ BAQDAgEGMB0GA1UdDgQWBBRW5+FbJUOA4PaM4XG8juWAL8RI4jANBgkqhkiG9w0BAQUFAAOCAQEA
3163
+ g8ev6n9NCjw5sWi+e22JLumzCecYV42FmhfzdkJQEw/HkG8zrcVJYCtsSVgZ1OK+t7+rSbyUyKu+
3164
+ KGwWaODIl0YgoGhnYIg5IFHYaAERzqf2EQf27OysGh+yZm5WZ2B6dF7AbZc2rrUNXWZzwCUyRdhK
3165
+ BgePxLcHsU0GDeGl6/R1yrqc0L2z0zIkTO5+4nYES0lT2PLpVDP85XEfPRRclkvxOvIAu2y0+pZV
3166
+ CIgJwcyRGSmwIC3/yzikQOEXvnlhgP8HA4ZMTnsGnxGGjYnuJ8Tb4rwZjgvDwxPHLQNjO9Po5KIq
3167
+ woIIlBZU8O8fJ5AluA0OKBtHd0e9HKgl8ZS0Zg==
3168
+ -----END CERTIFICATE-----
3169
+
3170
+ Autoridad de Certificacion Firmaprofesional CIF A62634068
3171
+ =========================================================
3172
+ -----BEGIN CERTIFICATE-----
3173
+ MIIGFDCCA/ygAwIBAgIIU+w77vuySF8wDQYJKoZIhvcNAQEFBQAwUTELMAkGA1UEBhMCRVMxQjBA
3174
+ BgNVBAMMOUF1dG9yaWRhZCBkZSBDZXJ0aWZpY2FjaW9uIEZpcm1hcHJvZmVzaW9uYWwgQ0lGIEE2
3175
+ MjYzNDA2ODAeFw0wOTA1MjAwODM4MTVaFw0zMDEyMzEwODM4MTVaMFExCzAJBgNVBAYTAkVTMUIw
3176
+ QAYDVQQDDDlBdXRvcmlkYWQgZGUgQ2VydGlmaWNhY2lvbiBGaXJtYXByb2Zlc2lvbmFsIENJRiBB
3177
+ NjI2MzQwNjgwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDKlmuO6vj78aI14H9M2uDD
3178
+ Utd9thDIAl6zQyrET2qyyhxdKJp4ERppWVevtSBC5IsP5t9bpgOSL/UR5GLXMnE42QQMcas9UX4P
3179
+ B99jBVzpv5RvwSmCwLTaUbDBPLutN0pcyvFLNg4kq7/DhHf9qFD0sefGL9ItWY16Ck6WaVICqjaY
3180
+ 7Pz6FIMMNx/Jkjd/14Et5cS54D40/mf0PmbR0/RAz15iNA9wBj4gGFrO93IbJWyTdBSTo3OxDqqH
3181
+ ECNZXyAFGUftaI6SEspd/NYrspI8IM/hX68gvqB2f3bl7BqGYTM+53u0P6APjqK5am+5hyZvQWyI
3182
+ plD9amML9ZMWGxmPsu2bm8mQ9QEM3xk9Dz44I8kvjwzRAv4bVdZO0I08r0+k8/6vKtMFnXkIoctX
3183
+ MbScyJCyZ/QYFpM6/EfY0XiWMR+6KwxfXZmtY4laJCB22N/9q06mIqqdXuYnin1oKaPnirjaEbsX
3184
+ LZmdEyRG98Xi2J+Of8ePdG1asuhy9azuJBCtLxTa/y2aRnFHvkLfuwHb9H/TKI8xWVvTyQKmtFLK
3185
+ bpf7Q8UIJm+K9Lv9nyiqDdVF8xM6HdjAeI9BZzwelGSuewvF6NkBiDkal4ZkQdU7hwxu+g/GvUgU
3186
+ vzlN1J5Bto+WHWOWk9mVBngxaJ43BjuAiUVhOSPHG0SjFeUc+JIwuwIDAQABo4HvMIHsMBIGA1Ud
3187
+ EwEB/wQIMAYBAf8CAQEwDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBRlzeurNR4APn7VdMActHNH
3188
+ DhpkLzCBpgYDVR0gBIGeMIGbMIGYBgRVHSAAMIGPMC8GCCsGAQUFBwIBFiNodHRwOi8vd3d3LmZp
3189
+ cm1hcHJvZmVzaW9uYWwuY29tL2NwczBcBggrBgEFBQcCAjBQHk4AUABhAHMAZQBvACAAZABlACAA
3190
+ bABhACAAQgBvAG4AYQBuAG8AdgBhACAANAA3ACAAQgBhAHIAYwBlAGwAbwBuAGEAIAAwADgAMAAx
3191
+ ADcwDQYJKoZIhvcNAQEFBQADggIBABd9oPm03cXF661LJLWhAqvdpYhKsg9VSytXjDvlMd3+xDLx
3192
+ 51tkljYyGOylMnfX40S2wBEqgLk9am58m9Ot/MPWo+ZkKXzR4Tgegiv/J2Wv+xYVxC5xhOW1//qk
3193
+ R71kMrv2JYSiJ0L1ILDCExARzRAVukKQKtJE4ZYm6zFIEv0q2skGz3QeqUvVhyj5eTSSPi5E6PaP
3194
+ T481PyWzOdxjKpBrIF/EUhJOlywqrJ2X3kjyo2bbwtKDlaZmp54lD+kLM5FlClrD2VQS3a/DTg4f
3195
+ Jl4N3LON7NWBcN7STyQF82xO9UxJZo3R/9ILJUFI/lGExkKvgATP0H5kSeTy36LssUzAKh3ntLFl
3196
+ osS88Zj0qnAHY7S42jtM+kAiMFsRpvAFDsYCA0irhpuF3dvd6qJ2gHN99ZwExEWN57kci57q13XR
3197
+ crHedUTnQn3iV2t93Jm8PYMo6oCTjcVMZcFwgbg4/EMxsvYDNEeyrPsiBsse3RdHHF9mudMaotoR
3198
+ saS8I8nkvof/uZS2+F0gStRf571oe2XyFR7SOqkt6dhrJKyXWERHrVkY8SFlcN7ONGCoQPHzPKTD
3199
+ KCOM/iczQ0CgFzzr6juwcqajuUpLXhZI9LK8yIySxZ2frHI2vDSANGupi5LAuBft7HZT9SQBjLMi
3200
+ 6Et8Vcad+qMUu2WFbm5PEn4KPJ2V
3201
+ -----END CERTIFICATE-----
3202
+
3203
+ Izenpe.com
3204
+ ==========
3205
+ -----BEGIN CERTIFICATE-----
3206
+ MIIF8TCCA9mgAwIBAgIQALC3WhZIX7/hy/WL1xnmfTANBgkqhkiG9w0BAQsFADA4MQswCQYDVQQG
3207
+ EwJFUzEUMBIGA1UECgwLSVpFTlBFIFMuQS4xEzARBgNVBAMMCkl6ZW5wZS5jb20wHhcNMDcxMjEz
3208
+ MTMwODI4WhcNMzcxMjEzMDgyNzI1WjA4MQswCQYDVQQGEwJFUzEUMBIGA1UECgwLSVpFTlBFIFMu
3209
+ QS4xEzARBgNVBAMMCkl6ZW5wZS5jb20wggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDJ
3210
+ 03rKDx6sp4boFmVqscIbRTJxldn+EFvMr+eleQGPicPK8lVx93e+d5TzcqQsRNiekpsUOqHnJJAK
3211
+ ClaOxdgmlOHZSOEtPtoKct2jmRXagaKH9HtuJneJWK3W6wyyQXpzbm3benhB6QiIEn6HLmYRY2xU
3212
+ +zydcsC8Lv/Ct90NduM61/e0aL6i9eOBbsFGb12N4E3GVFWJGjMxCrFXuaOKmMPsOzTFlUFpfnXC
3213
+ PCDFYbpRR6AgkJOhkEvzTnyFRVSa0QUmQbC1TR0zvsQDyCV8wXDbO/QJLVQnSKwv4cSsPsjLkkxT
3214
+ OTcj7NMB+eAJRE1NZMDhDVqHIrytG6P+JrUV86f8hBnp7KGItERphIPzidF0BqnMC9bC3ieFUCbK
3215
+ F7jJeodWLBoBHmy+E60QrLUk9TiRodZL2vG70t5HtfG8gfZZa88ZU+mNFctKy6lvROUbQc/hhqfK
3216
+ 0GqfvEyNBjNaooXlkDWgYlwWTvDjovoDGrQscbNYLN57C9saD+veIR8GdwYDsMnvmfzAuU8Lhij+
3217
+ 0rnq49qlw0dpEuDb8PYZi+17cNcC1u2HGCgsBCRMd+RIihrGO5rUD8r6ddIBQFqNeb+Lz0vPqhbB
3218
+ leStTIo+F5HUsWLlguWABKQDfo2/2n+iD5dPDNMN+9fR5XJ+HMh3/1uaD7euBUbl8agW7EekFwID
3219
+ AQABo4H2MIHzMIGwBgNVHREEgagwgaWBD2luZm9AaXplbnBlLmNvbaSBkTCBjjFHMEUGA1UECgw+
3220
+ SVpFTlBFIFMuQS4gLSBDSUYgQTAxMzM3MjYwLVJNZXJjLlZpdG9yaWEtR2FzdGVpeiBUMTA1NSBG
3221
+ NjIgUzgxQzBBBgNVBAkMOkF2ZGEgZGVsIE1lZGl0ZXJyYW5lbyBFdG9yYmlkZWEgMTQgLSAwMTAx
3222
+ MCBWaXRvcmlhLUdhc3RlaXowDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0O
3223
+ BBYEFB0cZQ6o8iV7tJHP5LGx5r1VdGwFMA0GCSqGSIb3DQEBCwUAA4ICAQB4pgwWSp9MiDrAyw6l
3224
+ Fn2fuUhfGI8NYjb2zRlrrKvV9pF9rnHzP7MOeIWblaQnIUdCSnxIOvVFfLMMjlF4rJUT3sb9fbga
3225
+ kEyrkgPH7UIBzg/YsfqikuFgba56awmqxinuaElnMIAkejEWOVt+8Rwu3WwJrfIxwYJOubv5vr8q
3226
+ hT/AQKM6WfxZSzwoJNu0FXWuDYi6LnPAvViH5ULy617uHjAimcs30cQhbIHsvm0m5hzkQiCeR7Cs
3227
+ g1lwLDXWrzY0tM07+DKo7+N4ifuNRSzanLh+QBxh5z6ikixL8s36mLYp//Pye6kfLqCTVyvehQP5
3228
+ aTfLnnhqBbTFMXiJ7HqnheG5ezzevh55hM6fcA5ZwjUukCox2eRFekGkLhObNA5me0mrZJfQRsN5
3229
+ nXJQY6aYWwa9SG3YOYNw6DXwBdGqvOPbyALqfP2C2sJbUjWumDqtujWTI6cfSN01RpiyEGjkpTHC
3230
+ ClguGYEQyVB1/OpaFs4R1+7vUIgtYf8/QnMFlEPVjjxOAToZpR9GTnfQXeWBIiGH/pR9hNiTrdZo
3231
+ Q0iy2+tzJOeRf1SktoA+naM8THLCV8Sg1Mw4J87VBp6iSNnpn86CcDaTmjvfliHjWbcM2pE38P1Z
3232
+ WrOZyGlsQyYBNWNgVYkDOnXYukrZVP/u3oDYLdE41V4tC5h9Pmzb/CaIxw==
3233
+ -----END CERTIFICATE-----
3234
+
3235
+ Chambers of Commerce Root - 2008
3236
+ ================================
3237
+ -----BEGIN CERTIFICATE-----
3238
+ MIIHTzCCBTegAwIBAgIJAKPaQn6ksa7aMA0GCSqGSIb3DQEBBQUAMIGuMQswCQYDVQQGEwJFVTFD
3239
+ MEEGA1UEBxM6TWFkcmlkIChzZWUgY3VycmVudCBhZGRyZXNzIGF0IHd3dy5jYW1lcmZpcm1hLmNv
3240
+ bS9hZGRyZXNzKTESMBAGA1UEBRMJQTgyNzQzMjg3MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMu
3241
+ QS4xKTAnBgNVBAMTIENoYW1iZXJzIG9mIENvbW1lcmNlIFJvb3QgLSAyMDA4MB4XDTA4MDgwMTEy
3242
+ Mjk1MFoXDTM4MDczMTEyMjk1MFowga4xCzAJBgNVBAYTAkVVMUMwQQYDVQQHEzpNYWRyaWQgKHNl
3243
+ ZSBjdXJyZW50IGFkZHJlc3MgYXQgd3d3LmNhbWVyZmlybWEuY29tL2FkZHJlc3MpMRIwEAYDVQQF
3244
+ EwlBODI3NDMyODcxGzAZBgNVBAoTEkFDIENhbWVyZmlybWEgUy5BLjEpMCcGA1UEAxMgQ2hhbWJl
3245
+ cnMgb2YgQ29tbWVyY2UgUm9vdCAtIDIwMDgwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC
3246
+ AQCvAMtwNyuAWko6bHiUfaN/Gh/2NdW928sNRHI+JrKQUrpjOyhYb6WzbZSm891kDFX29ufyIiKA
3247
+ XuFixrYp4YFs8r/lfTJqVKAyGVn+H4vXPWCGhSRv4xGzdz4gljUha7MI2XAuZPeEklPWDrCQiorj
3248
+ h40G072QDuKZoRuGDtqaCrsLYVAGUvGef3bsyw/QHg3PmTA9HMRFEFis1tPo1+XqxQEHd9ZR5gN/
3249
+ ikilTWh1uem8nk4ZcfUyS5xtYBkL+8ydddy/Js2Pk3g5eXNeJQ7KXOt3EgfLZEFHcpOrUMPrCXZk
3250
+ NNI5t3YRCQ12RcSprj1qr7V9ZS+UWBDsXHyvfuK2GNnQm05aSd+pZgvMPMZ4fKecHePOjlO+Bd5g
3251
+ D2vlGts/4+EhySnB8esHnFIbAURRPHsl18TlUlRdJQfKFiC4reRB7noI/plvg6aRArBsNlVq5331
3252
+ lubKgdaX8ZSD6e2wsWsSaR6s+12pxZjptFtYer49okQ6Y1nUCyXeG0+95QGezdIp1Z8XGQpvvwyQ
3253
+ 0wlf2eOKNcx5Wk0ZN5K3xMGtr/R5JJqyAQuxr1yW84Ay+1w9mPGgP0revq+ULtlVmhduYJ1jbLhj
3254
+ ya6BXBg14JC7vjxPNyK5fuvPnnchpj04gftI2jE9K+OJ9dC1vX7gUMQSibMjmhAxhduub+84Mxh2
3255
+ EQIDAQABo4IBbDCCAWgwEgYDVR0TAQH/BAgwBgEB/wIBDDAdBgNVHQ4EFgQU+SSsD7K1+HnA+mCI
3256
+ G8TZTQKeFxkwgeMGA1UdIwSB2zCB2IAU+SSsD7K1+HnA+mCIG8TZTQKeFxmhgbSkgbEwga4xCzAJ
3257
+ BgNVBAYTAkVVMUMwQQYDVQQHEzpNYWRyaWQgKHNlZSBjdXJyZW50IGFkZHJlc3MgYXQgd3d3LmNh
3258
+ bWVyZmlybWEuY29tL2FkZHJlc3MpMRIwEAYDVQQFEwlBODI3NDMyODcxGzAZBgNVBAoTEkFDIENh
3259
+ bWVyZmlybWEgUy5BLjEpMCcGA1UEAxMgQ2hhbWJlcnMgb2YgQ29tbWVyY2UgUm9vdCAtIDIwMDiC
3260
+ CQCj2kJ+pLGu2jAOBgNVHQ8BAf8EBAMCAQYwPQYDVR0gBDYwNDAyBgRVHSAAMCowKAYIKwYBBQUH
3261
+ AgEWHGh0dHA6Ly9wb2xpY3kuY2FtZXJmaXJtYS5jb20wDQYJKoZIhvcNAQEFBQADggIBAJASryI1
3262
+ wqM58C7e6bXpeHxIvj99RZJe6dqxGfwWPJ+0W2aeaufDuV2I6A+tzyMP3iU6XsxPpcG1Lawk0lgH
3263
+ 3qLPaYRgM+gQDROpI9CF5Y57pp49chNyM/WqfcZjHwj0/gF/JM8rLFQJ3uIrbZLGOU8W6jx+ekbU
3264
+ RWpGqOt1glanq6B8aBMz9p0w8G8nOSQjKpD9kCk18pPfNKXG9/jvjA9iSnyu0/VU+I22mlaHFoI6
3265
+ M6taIgj3grrqLuBHmrS1RaMFO9ncLkVAO+rcf+g769HsJtg1pDDFOqxXnrN2pSB7+R5KBWIBpih1
3266
+ YJeSDW4+TTdDDZIVnBgizVGZoCkaPF+KMjNbMMeJL0eYD6MDxvbxrN8y8NmBGuScvfaAFPDRLLmF
3267
+ 9dijscilIeUcE5fuDr3fKanvNFNb0+RqE4QGtjICxFKuItLcsiFCGtpA8CnJ7AoMXOLQusxI0zcK
3268
+ zBIKinmwPQN/aUv0NCB9szTqjktk9T79syNnFQ0EuPAtwQlRPLJsFfClI9eDdOTlLsn+mCdCxqvG
3269
+ nrDQWzilm1DefhiYtUU79nm06PcaewaD+9CL2rvHvRirCG88gGtAPxkZumWK5r7VXNM21+9AUiRg
3270
+ OGcEMeyP84LG3rlV8zsxkVrctQgVrXYlCg17LofiDKYGvCYQbTed7N14jHyAxfDZd0jQ
3271
+ -----END CERTIFICATE-----
3272
+
3273
+ Global Chambersign Root - 2008
3274
+ ==============================
3275
+ -----BEGIN CERTIFICATE-----
3276
+ MIIHSTCCBTGgAwIBAgIJAMnN0+nVfSPOMA0GCSqGSIb3DQEBBQUAMIGsMQswCQYDVQQGEwJFVTFD
3277
+ MEEGA1UEBxM6TWFkcmlkIChzZWUgY3VycmVudCBhZGRyZXNzIGF0IHd3dy5jYW1lcmZpcm1hLmNv
3278
+ bS9hZGRyZXNzKTESMBAGA1UEBRMJQTgyNzQzMjg3MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMu
3279
+ QS4xJzAlBgNVBAMTHkdsb2JhbCBDaGFtYmVyc2lnbiBSb290IC0gMjAwODAeFw0wODA4MDExMjMx
3280
+ NDBaFw0zODA3MzExMjMxNDBaMIGsMQswCQYDVQQGEwJFVTFDMEEGA1UEBxM6TWFkcmlkIChzZWUg
3281
+ Y3VycmVudCBhZGRyZXNzIGF0IHd3dy5jYW1lcmZpcm1hLmNvbS9hZGRyZXNzKTESMBAGA1UEBRMJ
3282
+ QTgyNzQzMjg3MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMuQS4xJzAlBgNVBAMTHkdsb2JhbCBD
3283
+ aGFtYmVyc2lnbiBSb290IC0gMjAwODCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMDf
3284
+ VtPkOpt2RbQT2//BthmLN0EYlVJH6xedKYiONWwGMi5HYvNJBL99RDaxccy9Wglz1dmFRP+RVyXf
3285
+ XjaOcNFccUMd2drvXNL7G706tcuto8xEpw2uIRU/uXpbknXYpBI4iRmKt4DS4jJvVpyR1ogQC7N0
3286
+ ZJJ0YPP2zxhPYLIj0Mc7zmFLmY/CDNBAspjcDahOo7kKrmCgrUVSY7pmvWjg+b4aqIG7HkF4ddPB
3287
+ /gBVsIdU6CeQNR1MM62X/JcumIS/LMmjv9GYERTtY/jKmIhYF5ntRQOXfjyGHoiMvvKRhI9lNNgA
3288
+ TH23MRdaKXoKGCQwoze1eqkBfSbW+Q6OWfH9GzO1KTsXO0G2Id3UwD2ln58fQ1DJu7xsepeY7s2M
3289
+ H/ucUa6LcL0nn3HAa6x9kGbo1106DbDVwo3VyJ2dwW3Q0L9R5OP4wzg2rtandeavhENdk5IMagfe
3290
+ Ox2YItaswTXbo6Al/3K1dh3ebeksZixShNBFks4c5eUzHdwHU1SjqoI7mjcv3N2gZOnm3b2u/GSF
3291
+ HTynyQbehP9r6GsaPMWis0L7iwk+XwhSx2LE1AVxv8Rk5Pihg+g+EpuoHtQ2TS9x9o0o9oOpE9Jh
3292
+ wZG7SMA0j0GMS0zbaRL/UJScIINZc+18ofLx/d33SdNDWKBWY8o9PeU1VlnpDsogzCtLkykPAgMB
3293
+ AAGjggFqMIIBZjASBgNVHRMBAf8ECDAGAQH/AgEMMB0GA1UdDgQWBBS5CcqcHtvTbDprru1U8VuT
3294
+ BjUuXjCB4QYDVR0jBIHZMIHWgBS5CcqcHtvTbDprru1U8VuTBjUuXqGBsqSBrzCBrDELMAkGA1UE
3295
+ BhMCRVUxQzBBBgNVBAcTOk1hZHJpZCAoc2VlIGN1cnJlbnQgYWRkcmVzcyBhdCB3d3cuY2FtZXJm
3296
+ aXJtYS5jb20vYWRkcmVzcykxEjAQBgNVBAUTCUE4Mjc0MzI4NzEbMBkGA1UEChMSQUMgQ2FtZXJm
3297
+ aXJtYSBTLkEuMScwJQYDVQQDEx5HbG9iYWwgQ2hhbWJlcnNpZ24gUm9vdCAtIDIwMDiCCQDJzdPp
3298
+ 1X0jzjAOBgNVHQ8BAf8EBAMCAQYwPQYDVR0gBDYwNDAyBgRVHSAAMCowKAYIKwYBBQUHAgEWHGh0
3299
+ dHA6Ly9wb2xpY3kuY2FtZXJmaXJtYS5jb20wDQYJKoZIhvcNAQEFBQADggIBAICIf3DekijZBZRG
3300
+ /5BXqfEv3xoNa/p8DhxJJHkn2EaqbylZUohwEurdPfWbU1Rv4WCiqAm57OtZfMY18dwY6fFn5a+6
3301
+ ReAJ3spED8IXDneRRXozX1+WLGiLwUePmJs9wOzL9dWCkoQ10b42OFZyMVtHLaoXpGNR6woBrX/s
3302
+ dZ7LoR/xfxKxueRkf2fWIyr0uDldmOghp+G9PUIadJpwr2hsUF1Jz//7Dl3mLEfXgTpZALVza2Mg
3303
+ 9jFFCDkO9HB+QHBaP9BrQql0PSgvAm11cpUJjUhjxsYjV5KTXjXBjfkK9yydYhz2rXzdpjEetrHH
3304
+ foUm+qRqtdpjMNHvkzeyZi99Bffnt0uYlDXA2TopwZ2yUDMdSqlapskD7+3056huirRXhOukP9Du
3305
+ qqqHW2Pok+JrqNS4cnhrG+055F3Lm6qH1U9OAP7Zap88MQ8oAgF9mOinsKJknnn4SPIVqczmyETr
3306
+ P3iZ8ntxPjzxmKfFGBI/5rsoM0LpRQp8bfKGeS/Fghl9CYl8slR2iK7ewfPM4W7bMdaTrpmg7yVq
3307
+ c5iJWzouE4gev8CSlDQb4ye3ix5vQv/n6TebUB0tovkC7stYWDpxvGjjqsGvHCgfotwjZT+B6q6Z
3308
+ 09gwzxMNTxXJhLynSC34MCN32EZLeW32jO06f2ARePTpm67VVMB0gNELQp/B
3309
+ -----END CERTIFICATE-----
3310
+
3311
+ Go Daddy Root Certificate Authority - G2
3312
+ ========================================
3313
+ -----BEGIN CERTIFICATE-----
3314
+ MIIDxTCCAq2gAwIBAgIBADANBgkqhkiG9w0BAQsFADCBgzELMAkGA1UEBhMCVVMxEDAOBgNVBAgT
3315
+ B0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxGjAYBgNVBAoTEUdvRGFkZHkuY29tLCBJbmMu
3316
+ MTEwLwYDVQQDEyhHbyBEYWRkeSBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5
3317
+ MDkwMTAwMDAwMFoXDTM3MTIzMTIzNTk1OVowgYMxCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6
3318
+ b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMRowGAYDVQQKExFHb0RhZGR5LmNvbSwgSW5jLjExMC8G
3319
+ A1UEAxMoR28gRGFkZHkgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZI
3320
+ hvcNAQEBBQADggEPADCCAQoCggEBAL9xYgjx+lk09xvJGKP3gElY6SKDE6bFIEMBO4Tx5oVJnyfq
3321
+ 9oQbTqC023CYxzIBsQU+B07u9PpPL1kwIuerGVZr4oAH/PMWdYA5UXvl+TW2dE6pjYIT5LY/qQOD
3322
+ +qK+ihVqf94Lw7YZFAXK6sOoBJQ7RnwyDfMAZiLIjWltNowRGLfTshxgtDj6AozO091GB94KPutd
3323
+ fMh8+7ArU6SSYmlRJQVhGkSBjCypQ5Yj36w6gZoOKcUcqeldHraenjAKOc7xiID7S13MMuyFYkMl
3324
+ NAJWJwGRtDtwKj9useiciAF9n9T521NtYJ2/LOdYq7hfRvzOxBsDPAnrSTFcaUaz4EcCAwEAAaNC
3325
+ MEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFDqahQcQZyi27/a9
3326
+ BUFuIMGU2g/eMA0GCSqGSIb3DQEBCwUAA4IBAQCZ21151fmXWWcDYfF+OwYxdS2hII5PZYe096ac
3327
+ vNjpL9DbWu7PdIxztDhC2gV7+AJ1uP2lsdeu9tfeE8tTEH6KRtGX+rcuKxGrkLAngPnon1rpN5+r
3328
+ 5N9ss4UXnT3ZJE95kTXWXwTrgIOrmgIttRD02JDHBHNA7XIloKmf7J6raBKZV8aPEjoJpL1E/QYV
3329
+ N8Gb5DKj7Tjo2GTzLH4U/ALqn83/B2gX2yKQOC16jdFU8WnjXzPKej17CuPKf1855eJ1usV2GDPO
3330
+ LPAvTK33sefOT6jEm0pUBsV/fdUID+Ic/n4XuKxe9tQWskMJDE32p2u0mYRlynqI4uJEvlz36hz1
3331
+ -----END CERTIFICATE-----
3332
+
3333
+ Starfield Root Certificate Authority - G2
3334
+ =========================================
3335
+ -----BEGIN CERTIFICATE-----
3336
+ MIID3TCCAsWgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBjzELMAkGA1UEBhMCVVMxEDAOBgNVBAgT
3337
+ B0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoTHFN0YXJmaWVsZCBUZWNobm9s
3338
+ b2dpZXMsIEluYy4xMjAwBgNVBAMTKVN0YXJmaWVsZCBSb290IENlcnRpZmljYXRlIEF1dGhvcml0
3339
+ eSAtIEcyMB4XDTA5MDkwMTAwMDAwMFoXDTM3MTIzMTIzNTk1OVowgY8xCzAJBgNVBAYTAlVTMRAw
3340
+ DgYDVQQIEwdBcml6b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFyZmllbGQg
3341
+ VGVjaG5vbG9naWVzLCBJbmMuMTIwMAYDVQQDEylTdGFyZmllbGQgUm9vdCBDZXJ0aWZpY2F0ZSBB
3342
+ dXRob3JpdHkgLSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL3twQP89o/8ArFv
3343
+ W59I2Z154qK3A2FWGMNHttfKPTUuiUP3oWmb3ooa/RMgnLRJdzIpVv257IzdIvpy3Cdhl+72WoTs
3344
+ bhm5iSzchFvVdPtrX8WJpRBSiUZV9Lh1HOZ/5FSuS/hVclcCGfgXcVnrHigHdMWdSL5stPSksPNk
3345
+ N3mSwOxGXn/hbVNMYq/NHwtjuzqd+/x5AJhhdM8mgkBj87JyahkNmcrUDnXMN/uLicFZ8WJ/X7Nf
3346
+ ZTD4p7dNdloedl40wOiWVpmKs/B/pM293DIxfJHP4F8R+GuqSVzRmZTRouNjWwl2tVZi4Ut0HZbU
3347
+ JtQIBFnQmA4O5t78w+wfkPECAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC
3348
+ AQYwHQYDVR0OBBYEFHwMMh+n2TB/xH1oo2Kooc6rB1snMA0GCSqGSIb3DQEBCwUAA4IBAQARWfol
3349
+ TwNvlJk7mh+ChTnUdgWUXuEok21iXQnCoKjUsHU48TRqneSfioYmUeYs0cYtbpUgSpIB7LiKZ3sx
3350
+ 4mcujJUDJi5DnUox9g61DLu34jd/IroAow57UvtruzvE03lRTs2Q9GcHGcg8RnoNAX3FWOdt5oUw
3351
+ F5okxBDgBPfg8n/Uqgr/Qh037ZTlZFkSIHc40zI+OIF1lnP6aI+xy84fxez6nH7PfrHxBy22/L/K
3352
+ pL/QlwVKvOoYKAKQvVR4CSFx09F9HdkWsKlhPdAKACL8x3vLCWRFCztAgfd9fDL1mMpYjn0q7pBZ
3353
+ c2T5NnReJaH1ZgUufzkVqSr7UIuOhWn0
3354
+ -----END CERTIFICATE-----
3355
+
3356
+ Starfield Services Root Certificate Authority - G2
3357
+ ==================================================
3358
+ -----BEGIN CERTIFICATE-----
3359
+ MIID7zCCAtegAwIBAgIBADANBgkqhkiG9w0BAQsFADCBmDELMAkGA1UEBhMCVVMxEDAOBgNVBAgT
3360
+ B0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoTHFN0YXJmaWVsZCBUZWNobm9s
3361
+ b2dpZXMsIEluYy4xOzA5BgNVBAMTMlN0YXJmaWVsZCBTZXJ2aWNlcyBSb290IENlcnRpZmljYXRl
3362
+ IEF1dGhvcml0eSAtIEcyMB4XDTA5MDkwMTAwMDAwMFoXDTM3MTIzMTIzNTk1OVowgZgxCzAJBgNV
3363
+ BAYTAlVTMRAwDgYDVQQIEwdBcml6b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxT
3364
+ dGFyZmllbGQgVGVjaG5vbG9naWVzLCBJbmMuMTswOQYDVQQDEzJTdGFyZmllbGQgU2VydmljZXMg
3365
+ Um9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC
3366
+ AQoCggEBANUMOsQq+U7i9b4Zl1+OiFOxHz/Lz58gE20pOsgPfTz3a3Y4Y9k2YKibXlwAgLIvWX/2
3367
+ h/klQ4bnaRtSmpDhcePYLQ1Ob/bISdm28xpWriu2dBTrz/sm4xq6HZYuajtYlIlHVv8loJNwU4Pa
3368
+ hHQUw2eeBGg6345AWh1KTs9DkTvnVtYAcMtS7nt9rjrnvDH5RfbCYM8TWQIrgMw0R9+53pBlbQLP
3369
+ LJGmpufehRhJfGZOozptqbXuNC66DQO4M99H67FrjSXZm86B0UVGMpZwh94CDklDhbZsc7tk6mFB
3370
+ rMnUVN+HL8cisibMn1lUaJ/8viovxFUcdUBgF4UCVTmLfwUCAwEAAaNCMEAwDwYDVR0TAQH/BAUw
3371
+ AwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFJxfAN+qAdcwKziIorhtSpzyEZGDMA0GCSqG
3372
+ SIb3DQEBCwUAA4IBAQBLNqaEd2ndOxmfZyMIbw5hyf2E3F/YNoHN2BtBLZ9g3ccaaNnRbobhiCPP
3373
+ E95Dz+I0swSdHynVv/heyNXBve6SbzJ08pGCL72CQnqtKrcgfU28elUSwhXqvfdqlS5sdJ/PHLTy
3374
+ xQGjhdByPq1zqwubdQxtRbeOlKyWN7Wg0I8VRw7j6IPdj/3vQQF3zCepYoUz8jcI73HPdwbeyBkd
3375
+ iEDPfUYd/x7H4c7/I9vG+o1VTqkC50cRRj70/b17KSa7qWFiNyi2LSr2EIZkyXCn0q23KXB56jza
3376
+ YyWf/Wi3MOxw+3WKt21gZ7IeyLnp2KhvAotnDU0mV3HaIPzBSlCNsSi6
3377
+ -----END CERTIFICATE-----
3378
+
3379
+ AffirmTrust Commercial
3380
+ ======================
3381
+ -----BEGIN CERTIFICATE-----
3382
+ MIIDTDCCAjSgAwIBAgIId3cGJyapsXwwDQYJKoZIhvcNAQELBQAwRDELMAkGA1UEBhMCVVMxFDAS
3383
+ BgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVzdCBDb21tZXJjaWFsMB4XDTEw
3384
+ MDEyOTE0MDYwNloXDTMwMTIzMTE0MDYwNlowRDELMAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmly
3385
+ bVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVzdCBDb21tZXJjaWFsMIIBIjANBgkqhkiG9w0BAQEF
3386
+ AAOCAQ8AMIIBCgKCAQEA9htPZwcroRX1BiLLHwGy43NFBkRJLLtJJRTWzsO3qyxPxkEylFf6Eqdb
3387
+ DuKPHx6GGaeqtS25Xw2Kwq+FNXkyLbscYjfysVtKPcrNcV/pQr6U6Mje+SJIZMblq8Yrba0F8PrV
3388
+ C8+a5fBQpIs7R6UjW3p6+DM/uO+Zl+MgwdYoic+U+7lF7eNAFxHUdPALMeIrJmqbTFeurCA+ukV6
3389
+ BfO9m2kVrn1OIGPENXY6BwLJN/3HR+7o8XYdcxXyl6S1yHp52UKqK39c/s4mT6NmgTWvRLpUHhww
3390
+ MmWd5jyTXlBOeuM61G7MGvv50jeuJCqrVwMiKA1JdX+3KNp1v47j3A55MQIDAQABo0IwQDAdBgNV
3391
+ HQ4EFgQUnZPGU4teyq8/nx4P5ZmVvCT2lI8wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC
3392
+ AQYwDQYJKoZIhvcNAQELBQADggEBAFis9AQOzcAN/wr91LoWXym9e2iZWEnStB03TX8nfUYGXUPG
3393
+ hi4+c7ImfU+TqbbEKpqrIZcUsd6M06uJFdhrJNTxFq7YpFzUf1GO7RgBsZNjvbz4YYCanrHOQnDi
3394
+ qX0GJX0nof5v7LMeJNrjS1UaADs1tDvZ110w/YETifLCBivtZ8SOyUOyXGsViQK8YvxO8rUzqrJv
3395
+ 0wqiUOP2O+guRMLbZjipM1ZI8W0bM40NjD9gN53Tym1+NH4Nn3J2ixufcv1SNUFFApYvHLKac0kh
3396
+ sUlHRUe072o0EclNmsxZt9YCnlpOZbWUrhvfKbAW8b8Angc6F2S1BLUjIZkKlTuXfO8=
3397
+ -----END CERTIFICATE-----
3398
+
3399
+ AffirmTrust Networking
3400
+ ======================
3401
+ -----BEGIN CERTIFICATE-----
3402
+ MIIDTDCCAjSgAwIBAgIIfE8EORzUmS0wDQYJKoZIhvcNAQEFBQAwRDELMAkGA1UEBhMCVVMxFDAS
3403
+ BgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVzdCBOZXR3b3JraW5nMB4XDTEw
3404
+ MDEyOTE0MDgyNFoXDTMwMTIzMTE0MDgyNFowRDELMAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmly
3405
+ bVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVzdCBOZXR3b3JraW5nMIIBIjANBgkqhkiG9w0BAQEF
3406
+ AAOCAQ8AMIIBCgKCAQEAtITMMxcua5Rsa2FSoOujz3mUTOWUgJnLVWREZY9nZOIG41w3SfYvm4SE
3407
+ Hi3yYJ0wTsyEheIszx6e/jarM3c1RNg1lho9Nuh6DtjVR6FqaYvZ/Ls6rnla1fTWcbuakCNrmreI
3408
+ dIcMHl+5ni36q1Mr3Lt2PpNMCAiMHqIjHNRqrSK6mQEubWXLviRmVSRLQESxG9fhwoXA3hA/Pe24
3409
+ /PHxI1Pcv2WXb9n5QHGNfb2V1M6+oF4nI979ptAmDgAp6zxG8D1gvz9Q0twmQVGeFDdCBKNwV6gb
3410
+ h+0t+nvujArjqWaJGctB+d1ENmHP4ndGyH329JKBNv3bNPFyfvMMFr20FQIDAQABo0IwQDAdBgNV
3411
+ HQ4EFgQUBx/S55zawm6iQLSwelAQUHTEyL0wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC
3412
+ AQYwDQYJKoZIhvcNAQEFBQADggEBAIlXshZ6qML91tmbmzTCnLQyFE2npN/svqe++EPbkTfOtDIu
3413
+ UFUaNU52Q3Eg75N3ThVwLofDwR1t3Mu1J9QsVtFSUzpE0nPIxBsFZVpikpzuQY0x2+c06lkh1QF6
3414
+ 12S4ZDnNye2v7UsDSKegmQGA3GWjNq5lWUhPgkvIZfFXHeVZLgo/bNjR9eUJtGxUAArgFU2HdW23
3415
+ WJZa3W3SAKD0m0i+wzekujbgfIeFlxoVot4uolu9rxj5kFDNcFn4J2dHy8egBzp90SxdbBk6ZrV9
3416
+ /ZFvgrG+CJPbFEfxojfHRZ48x3evZKiT3/Zpg4Jg8klCNO1aAFSFHBY2kgxc+qatv9s=
3417
+ -----END CERTIFICATE-----
3418
+
3419
+ AffirmTrust Premium
3420
+ ===================
3421
+ -----BEGIN CERTIFICATE-----
3422
+ MIIFRjCCAy6gAwIBAgIIbYwURrGmCu4wDQYJKoZIhvcNAQEMBQAwQTELMAkGA1UEBhMCVVMxFDAS
3423
+ BgNVBAoMC0FmZmlybVRydXN0MRwwGgYDVQQDDBNBZmZpcm1UcnVzdCBQcmVtaXVtMB4XDTEwMDEy
3424
+ OTE0MTAzNloXDTQwMTIzMTE0MTAzNlowQTELMAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmlybVRy
3425
+ dXN0MRwwGgYDVQQDDBNBZmZpcm1UcnVzdCBQcmVtaXVtMIICIjANBgkqhkiG9w0BAQEFAAOCAg8A
3426
+ MIICCgKCAgEAxBLfqV/+Qd3d9Z+K4/as4Tx4mrzY8H96oDMq3I0gW64tb+eT2TZwamjPjlGjhVtn
3427
+ BKAQJG9dKILBl1fYSCkTtuG+kU3fhQxTGJoeJKJPj/CihQvL9Cl/0qRY7iZNyaqoe5rZ+jjeRFcV
3428
+ 5fiMyNlI4g0WJx0eyIOFJbe6qlVBzAMiSy2RjYvmia9mx+n/K+k8rNrSs8PhaJyJ+HoAVt70VZVs
3429
+ +7pk3WKL3wt3MutizCaam7uqYoNMtAZ6MMgpv+0GTZe5HMQxK9VfvFMSF5yZVylmd2EhMQcuJUmd
3430
+ GPLu8ytxjLW6OQdJd/zvLpKQBY0tL3d770O/Nbua2Plzpyzy0FfuKE4mX4+QaAkvuPjcBukumj5R
3431
+ p9EixAqnOEhss/n/fauGV+O61oV4d7pD6kh/9ti+I20ev9E2bFhc8e6kGVQa9QPSdubhjL08s9NI
3432
+ S+LI+H+SqHZGnEJlPqQewQcDWkYtuJfzt9WyVSHvutxMAJf7FJUnM7/oQ0dG0giZFmA7mn7S5u04
3433
+ 6uwBHjxIVkkJx0w3AJ6IDsBz4W9m6XJHMD4Q5QsDyZpCAGzFlH5hxIrff4IaC1nEWTJ3s7xgaVY5
3434
+ /bQGeyzWZDbZvUjthB9+pSKPKrhC9IK31FOQeE4tGv2Bb0TXOwF0lkLgAOIua+rF7nKsu7/+6qqo
3435
+ +Nz2snmKtmcCAwEAAaNCMEAwHQYDVR0OBBYEFJ3AZ6YMItkm9UWrpmVSESfYRaxjMA8GA1UdEwEB
3436
+ /wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBDAUAA4ICAQCzV00QYk465KzquByv
3437
+ MiPIs0laUZx2KI15qldGF9X1Uva3ROgIRL8YhNILgM3FEv0AVQVhh0HctSSePMTYyPtwni94loMg
3438
+ Nt58D2kTiKV1NpgIpsbfrM7jWNa3Pt668+s0QNiigfV4Py/VpfzZotReBA4Xrf5B8OWycvpEgjNC
3439
+ 6C1Y91aMYj+6QrCcDFx+LmUmXFNPALJ4fqENmS2NuB2OosSw/WDQMKSOyARiqcTtNd56l+0OOF6S
3440
+ L5Nwpamcb6d9Ex1+xghIsV5n61EIJenmJWtSKZGc0jlzCFfemQa0W50QBuHCAKi4HEoCChTQwUHK
3441
+ +4w1IX2COPKpVJEZNZOUbWo6xbLQu4mGk+ibyQ86p3q4ofB4Rvr8Ny/lioTz3/4E2aFooC8k4gmV
3442
+ BtWVyuEklut89pMFu+1z6S3RdTnX5yTb2E5fQ4+e0BQ5v1VwSJlXMbSc7kqYA5YwH2AG7hsj/oFg
3443
+ IxpHYoWlzBk0gG+zrBrjn/B7SK3VAdlntqlyk+otZrWyuOQ9PLLvTIzq6we/qzWaVYa8GKa1qF60
3444
+ g2xraUDTn9zxw2lrueFtCfTxqlB2Cnp9ehehVZZCmTEJ3WARjQUwfuaORtGdFNrHF+QFlozEJLUb
3445
+ zxQHskD4o55BhrwE0GuWyCqANP2/7waj3VjFhT0+j/6eKeC2uAloGRwYQw==
3446
+ -----END CERTIFICATE-----
3447
+
3448
+ AffirmTrust Premium ECC
3449
+ =======================
3450
+ -----BEGIN CERTIFICATE-----
3451
+ MIIB/jCCAYWgAwIBAgIIdJclisc/elQwCgYIKoZIzj0EAwMwRTELMAkGA1UEBhMCVVMxFDASBgNV
3452
+ BAoMC0FmZmlybVRydXN0MSAwHgYDVQQDDBdBZmZpcm1UcnVzdCBQcmVtaXVtIEVDQzAeFw0xMDAx
3453
+ MjkxNDIwMjRaFw00MDEyMzExNDIwMjRaMEUxCzAJBgNVBAYTAlVTMRQwEgYDVQQKDAtBZmZpcm1U
3454
+ cnVzdDEgMB4GA1UEAwwXQWZmaXJtVHJ1c3QgUHJlbWl1bSBFQ0MwdjAQBgcqhkjOPQIBBgUrgQQA
3455
+ IgNiAAQNMF4bFZ0D0KF5Nbc6PJJ6yhUczWLznCZcBz3lVPqj1swS6vQUX+iOGasvLkjmrBhDeKzQ
3456
+ N8O9ss0s5kfiGuZjuD0uL3jET9v0D6RoTFVya5UdThhClXjMNzyR4ptlKymjQjBAMB0GA1UdDgQW
3457
+ BBSaryl6wBE1NSZRMADDav5A1a7WPDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAK
3458
+ BggqhkjOPQQDAwNnADBkAjAXCfOHiFBar8jAQr9HX/VsaobgxCd05DhT1wV/GzTjxi+zygk8N53X
3459
+ 57hG8f2h4nECMEJZh0PUUd+60wkyWs6Iflc9nF9Ca/UHLbXwgpP5WW+uZPpY5Yse42O+tYHNbwKM
3460
+ eQ==
3461
+ -----END CERTIFICATE-----
3462
+
3463
+ Certum Trusted Network CA
3464
+ =========================
3465
+ -----BEGIN CERTIFICATE-----
3466
+ MIIDuzCCAqOgAwIBAgIDBETAMA0GCSqGSIb3DQEBBQUAMH4xCzAJBgNVBAYTAlBMMSIwIAYDVQQK
3467
+ ExlVbml6ZXRvIFRlY2hub2xvZ2llcyBTLkEuMScwJQYDVQQLEx5DZXJ0dW0gQ2VydGlmaWNhdGlv
3468
+ biBBdXRob3JpdHkxIjAgBgNVBAMTGUNlcnR1bSBUcnVzdGVkIE5ldHdvcmsgQ0EwHhcNMDgxMDIy
3469
+ MTIwNzM3WhcNMjkxMjMxMTIwNzM3WjB+MQswCQYDVQQGEwJQTDEiMCAGA1UEChMZVW5pemV0byBU
3470
+ ZWNobm9sb2dpZXMgUy5BLjEnMCUGA1UECxMeQ2VydHVtIENlcnRpZmljYXRpb24gQXV0aG9yaXR5
3471
+ MSIwIAYDVQQDExlDZXJ0dW0gVHJ1c3RlZCBOZXR3b3JrIENBMIIBIjANBgkqhkiG9w0BAQEFAAOC
3472
+ AQ8AMIIBCgKCAQEA4/t9o3K6wvDJFIf1awFO4W5AB7ptJ11/91sts1rHUV+rpDKmYYe2bg+G0jAC
3473
+ l/jXaVehGDldamR5xgFZrDwxSjh80gTSSyjoIF87B6LMTXPb865Px1bVWqeWifrzq2jUI4ZZJ88J
3474
+ J7ysbnKDHDBy3+Ci6dLhdHUZvSqeexVUBBvXQzmtVSjF4hq79MDkrjhJM8x2hZ85RdKknvISjFH4
3475
+ fOQtf/WsX+sWn7Et0brMkUJ3TCXJkDhv2/DM+44el1k+1WBO5gUo7Ul5E0u6SNsv+XLTOcr+H9g0
3476
+ cvW0QM8xAcPs3hEtF10fuFDRXhmnad4HMyjKUJX5p1TLVIZQRan5SQIDAQABo0IwQDAPBgNVHRMB
3477
+ Af8EBTADAQH/MB0GA1UdDgQWBBQIds3LB/8k9sXN7buQvOKEN0Z19zAOBgNVHQ8BAf8EBAMCAQYw
3478
+ DQYJKoZIhvcNAQEFBQADggEBAKaorSLOAT2mo/9i0Eidi15ysHhE49wcrwn9I0j6vSrEuVUEtRCj
3479
+ jSfeC4Jj0O7eDDd5QVsisrCaQVymcODU0HfLI9MA4GxWL+FpDQ3Zqr8hgVDZBqWo/5U30Kr+4rP1
3480
+ mS1FhIrlQgnXdAIv94nYmem8J9RHjboNRhx3zxSkHLmkMcScKHQDNP8zGSal6Q10tz6XxnboJ5aj
3481
+ Zt3hrvJBW8qYVoNzcOSGGtIxQbovvi0TWnZvTuhOgQ4/WwMioBK+ZlgRSssDxLQqKi2WF+A5VLxI
3482
+ 03YnnZotBqbJ7DnSq9ufmgsnAjUpsUCV5/nonFWIGUbWtzT1fs45mtk48VH3Tyw=
3483
+ -----END CERTIFICATE-----
3484
+
3485
+ Certinomis - Autorité Racine
3486
+ =============================
3487
+ -----BEGIN CERTIFICATE-----
3488
+ MIIFnDCCA4SgAwIBAgIBATANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJGUjETMBEGA1UEChMK
3489
+ Q2VydGlub21pczEXMBUGA1UECxMOMDAwMiA0MzM5OTg5MDMxJjAkBgNVBAMMHUNlcnRpbm9taXMg
3490
+ LSBBdXRvcml0w6kgUmFjaW5lMB4XDTA4MDkxNzA4Mjg1OVoXDTI4MDkxNzA4Mjg1OVowYzELMAkG
3491
+ A1UEBhMCRlIxEzARBgNVBAoTCkNlcnRpbm9taXMxFzAVBgNVBAsTDjAwMDIgNDMzOTk4OTAzMSYw
3492
+ JAYDVQQDDB1DZXJ0aW5vbWlzIC0gQXV0b3JpdMOpIFJhY2luZTCCAiIwDQYJKoZIhvcNAQEBBQAD
3493
+ ggIPADCCAgoCggIBAJ2Fn4bT46/HsmtuM+Cet0I0VZ35gb5j2CN2DpdUzZlMGvE5x4jYF1AMnmHa
3494
+ wE5V3udauHpOd4cN5bjr+p5eex7Ezyh0x5P1FMYiKAT5kcOrJ3NqDi5N8y4oH3DfVS9O7cdxbwly
3495
+ Lu3VMpfQ8Vh30WC8Tl7bmoT2R2FFK/ZQpn9qcSdIhDWerP5pqZ56XjUl+rSnSTV3lqc2W+HN3yNw
3496
+ 2F1MpQiD8aYkOBOo7C+ooWfHpi2GR+6K/OybDnT0K0kCe5B1jPyZOQE51kqJ5Z52qz6WKDgmi92N
3497
+ jMD2AR5vpTESOH2VwnHu7XSu5DaiQ3XV8QCb4uTXzEIDS3h65X27uK4uIJPT5GHfceF2Z5c/tt9q
3498
+ c1pkIuVC28+BA5PY9OMQ4HL2AHCs8MF6DwV/zzRpRbWT5BnbUhYjBYkOjUjkJW+zeL9i9Qf6lSTC
3499
+ lrLooyPCXQP8w9PlfMl1I9f09bze5N/NgL+RiH2nE7Q5uiy6vdFrzPOlKO1Enn1So2+WLhl+HPNb
3500
+ xxaOu2B9d2ZHVIIAEWBsMsGoOBvrbpgT1u449fCfDu/+MYHB0iSVL1N6aaLwD4ZFjliCK0wi1F6g
3501
+ 530mJ0jfJUaNSih8hp75mxpZuWW/Bd22Ql095gBIgl4g9xGC3srYn+Y3RyYe63j3YcNBZFgCQfna
3502
+ 4NH4+ej9Uji29YnfAgMBAAGjWzBZMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0G
3503
+ A1UdDgQWBBQNjLZh2kS40RR9w759XkjwzspqsDAXBgNVHSAEEDAOMAwGCiqBegFWAgIAAQEwDQYJ
3504
+ KoZIhvcNAQEFBQADggIBACQ+YAZ+He86PtvqrxyaLAEL9MW12Ukx9F1BjYkMTv9sov3/4gbIOZ/x
3505
+ WqndIlgVqIrTseYyCYIDbNc/CMf4uboAbbnW/FIyXaR/pDGUu7ZMOH8oMDX/nyNTt7buFHAAQCva
3506
+ R6s0fl6nVjBhK4tDrP22iCj1a7Y+YEq6QpA0Z43q619FVDsXrIvkxmUP7tCMXWY5zjKn2BCXwH40
3507
+ nJ+U8/aGH88bc62UeYdocMMzpXDn2NU4lG9jeeu/Cg4I58UvD0KgKxRA/yHgBcUn4YQRE7rWhh1B
3508
+ CxMjidPJC+iKunqjo3M3NYB9Ergzd0A4wPpeMNLytqOx1qKVl4GbUu1pTP+A5FPbVFsDbVRfsbjv
3509
+ JL1vnxHDx2TCDyhihWZeGnuyt++uNckZM6i4J9szVb9o4XVIRFb7zdNIu0eJOqxp9YDG5ERQL1TE
3510
+ qkPFMTFYvZbF6nVsmnWxTfj3l/+WFvKXTej28xH5On2KOG4Ey+HTRRWqpdEdnV1j6CTmNhTih60b
3511
+ WfVEm/vXd3wfAXBioSAaosUaKPQhA+4u2cGA6rnZgtZbdsLLO7XSAPCjDuGtbkD326C00EauFddE
3512
+ wk01+dIL8hf2rGbVJLJP0RyZwG71fet0BLj5TXcJ17TPBzAJ8bgAVtkXFhYKK4bfjwEZGuW7gmP/
3513
+ vgt2Fl43N+bYdJeimUV5
3514
+ -----END CERTIFICATE-----
3515
+
3516
+ Root CA Generalitat Valenciana
3517
+ ==============================
3518
+ -----BEGIN CERTIFICATE-----
3519
+ MIIGizCCBXOgAwIBAgIEO0XlaDANBgkqhkiG9w0BAQUFADBoMQswCQYDVQQGEwJFUzEfMB0GA1UE
3520
+ ChMWR2VuZXJhbGl0YXQgVmFsZW5jaWFuYTEPMA0GA1UECxMGUEtJR1ZBMScwJQYDVQQDEx5Sb290
3521
+ IENBIEdlbmVyYWxpdGF0IFZhbGVuY2lhbmEwHhcNMDEwNzA2MTYyMjQ3WhcNMjEwNzAxMTUyMjQ3
3522
+ WjBoMQswCQYDVQQGEwJFUzEfMB0GA1UEChMWR2VuZXJhbGl0YXQgVmFsZW5jaWFuYTEPMA0GA1UE
3523
+ CxMGUEtJR1ZBMScwJQYDVQQDEx5Sb290IENBIEdlbmVyYWxpdGF0IFZhbGVuY2lhbmEwggEiMA0G
3524
+ CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDGKqtXETcvIorKA3Qdyu0togu8M1JAJke+WmmmO3I2
3525
+ F0zo37i7L3bhQEZ0ZQKQUgi0/6iMweDHiVYQOTPvaLRfX9ptI6GJXiKjSgbwJ/BXufjpTjJ3Cj9B
3526
+ ZPPrZe52/lSqfR0grvPXdMIKX/UIKFIIzFVd0g/bmoGlu6GzwZTNVOAydTGRGmKy3nXiz0+J2ZGQ
3527
+ D0EbtFpKd71ng+CT516nDOeB0/RSrFOyA8dEJvt55cs0YFAQexvba9dHq198aMpunUEDEO5rmXte
3528
+ JajCq+TA81yc477OMUxkHl6AovWDfgzWyoxVjr7gvkkHD6MkQXpYHYTqWBLI4bft75PelAgxAgMB
3529
+ AAGjggM7MIIDNzAyBggrBgEFBQcBAQQmMCQwIgYIKwYBBQUHMAGGFmh0dHA6Ly9vY3NwLnBraS5n
3530
+ dmEuZXMwEgYDVR0TAQH/BAgwBgEB/wIBAjCCAjQGA1UdIASCAiswggInMIICIwYKKwYBBAG/VQIB
3531
+ ADCCAhMwggHoBggrBgEFBQcCAjCCAdoeggHWAEEAdQB0AG8AcgBpAGQAYQBkACAAZABlACAAQwBl
3532
+ AHIAdABpAGYAaQBjAGEAYwBpAPMAbgAgAFIAYQDtAHoAIABkAGUAIABsAGEAIABHAGUAbgBlAHIA
3533
+ YQBsAGkAdABhAHQAIABWAGEAbABlAG4AYwBpAGEAbgBhAC4ADQAKAEwAYQAgAEQAZQBjAGwAYQBy
3534
+ AGEAYwBpAPMAbgAgAGQAZQAgAFAAcgDhAGMAdABpAGMAYQBzACAAZABlACAAQwBlAHIAdABpAGYA
3535
+ aQBjAGEAYwBpAPMAbgAgAHEAdQBlACAAcgBpAGcAZQAgAGUAbAAgAGYAdQBuAGMAaQBvAG4AYQBt
3536
+ AGkAZQBuAHQAbwAgAGQAZQAgAGwAYQAgAHAAcgBlAHMAZQBuAHQAZQAgAEEAdQB0AG8AcgBpAGQA
3537
+ YQBkACAAZABlACAAQwBlAHIAdABpAGYAaQBjAGEAYwBpAPMAbgAgAHMAZQAgAGUAbgBjAHUAZQBu
3538
+ AHQAcgBhACAAZQBuACAAbABhACAAZABpAHIAZQBjAGMAaQDzAG4AIAB3AGUAYgAgAGgAdAB0AHAA
3539
+ OgAvAC8AdwB3AHcALgBwAGsAaQAuAGcAdgBhAC4AZQBzAC8AYwBwAHMwJQYIKwYBBQUHAgEWGWh0
3540
+ dHA6Ly93d3cucGtpLmd2YS5lcy9jcHMwHQYDVR0OBBYEFHs100DSHHgZZu90ECjcPk+yeAT8MIGV
3541
+ BgNVHSMEgY0wgYqAFHs100DSHHgZZu90ECjcPk+yeAT8oWykajBoMQswCQYDVQQGEwJFUzEfMB0G
3542
+ A1UEChMWR2VuZXJhbGl0YXQgVmFsZW5jaWFuYTEPMA0GA1UECxMGUEtJR1ZBMScwJQYDVQQDEx5S
3543
+ b290IENBIEdlbmVyYWxpdGF0IFZhbGVuY2lhbmGCBDtF5WgwDQYJKoZIhvcNAQEFBQADggEBACRh
3544
+ TvW1yEICKrNcda3FbcrnlD+laJWIwVTAEGmiEi8YPyVQqHxK6sYJ2fR1xkDar1CdPaUWu20xxsdz
3545
+ Ckj+IHLtb8zog2EWRpABlUt9jppSCS/2bxzkoXHPjCpaF3ODR00PNvsETUlR4hTJZGH71BTg9J63
3546
+ NI8KJr2XXPR5OkowGcytT6CYirQxlyric21+eLj4iIlPsSKRZEv1UN4D2+XFducTZnV+ZfsBn5OH
3547
+ iJ35Rld8TWCvmHMTI6QgkYH60GFmuH3Rr9ZvHmw96RH9qfmCIoaZM3Fa6hlXPZHNqcCjbgcTpsnt
3548
+ +GijnsNacgmHKNHEc8RzGF9QdRYxn7fofMM=
3549
+ -----END CERTIFICATE-----
3550
+
3551
+ A-Trust-nQual-03
3552
+ ================
3553
+ -----BEGIN CERTIFICATE-----
3554
+ MIIDzzCCAregAwIBAgIDAWweMA0GCSqGSIb3DQEBBQUAMIGNMQswCQYDVQQGEwJBVDFIMEYGA1UE
3555
+ Cgw/QS1UcnVzdCBHZXMuIGYuIFNpY2hlcmhlaXRzc3lzdGVtZSBpbSBlbGVrdHIuIERhdGVudmVy
3556
+ a2VociBHbWJIMRkwFwYDVQQLDBBBLVRydXN0LW5RdWFsLTAzMRkwFwYDVQQDDBBBLVRydXN0LW5R
3557
+ dWFsLTAzMB4XDTA1MDgxNzIyMDAwMFoXDTE1MDgxNzIyMDAwMFowgY0xCzAJBgNVBAYTAkFUMUgw
3558
+ RgYDVQQKDD9BLVRydXN0IEdlcy4gZi4gU2ljaGVyaGVpdHNzeXN0ZW1lIGltIGVsZWt0ci4gRGF0
3559
+ ZW52ZXJrZWhyIEdtYkgxGTAXBgNVBAsMEEEtVHJ1c3QtblF1YWwtMDMxGTAXBgNVBAMMEEEtVHJ1
3560
+ c3QtblF1YWwtMDMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCtPWFuA/OQO8BBC4SA
3561
+ zewqo51ru27CQoT3URThoKgtUaNR8t4j8DRE/5TrzAUjlUC5B3ilJfYKvUWG6Nm9wASOhURh73+n
3562
+ yfrBJcyFLGM/BWBzSQXgYHiVEEvc+RFZznF/QJuKqiTfC0Li21a8StKlDJu3Qz7dg9MmEALP6iPE
3563
+ SU7l0+m0iKsMrmKS1GWH2WrX9IWf5DMiJaXlyDO6w8dB3F/GaswADm0yqLaHNgBid5seHzTLkDx4
3564
+ iHQF63n1k3Flyp3HaxgtPVxO59X4PzF9j4fsCiIvI+n+u33J4PTs63zEsMMtYrWacdaxaujs2e3V
3565
+ cuy+VwHOBVWf3tFgiBCzAgMBAAGjNjA0MA8GA1UdEwEB/wQFMAMBAf8wEQYDVR0OBAoECERqlWdV
3566
+ eRFPMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOCAQEAVdRU0VlIXLOThaq/Yy/kgM40
3567
+ ozRiPvbY7meIMQQDbwvUB/tOdQ/TLtPAF8fGKOwGDREkDg6lXb+MshOWcdzUzg4NCmgybLlBMRmr
3568
+ sQd7TZjTXLDR8KdCoLXEjq/+8T/0709GAHbrAvv5ndJAlseIOrifEXnzgGWovR/TeIGgUUw3tKZd
3569
+ JXDRZslo+S4RFGjxVJgIrCaSD96JntT6s3kr0qN51OyLrIdTaEJMUVF0HhsnLuP1Hyl0Te2v9+GS
3570
+ mYHovjrHF1D2t8b8m7CKa9aIA5GPBnc6hQLdmNVDeD/GMBWsm2vLV7eJUYs66MmEDNuxUCAKGkq6
3571
+ ahq97BvIxYSazQ==
3572
+ -----END CERTIFICATE-----
3573
+
3574
+ TWCA Root Certification Authority
3575
+ =================================
3576
+ -----BEGIN CERTIFICATE-----
3577
+ MIIDezCCAmOgAwIBAgIBATANBgkqhkiG9w0BAQUFADBfMQswCQYDVQQGEwJUVzESMBAGA1UECgwJ
3578
+ VEFJV0FOLUNBMRAwDgYDVQQLDAdSb290IENBMSowKAYDVQQDDCFUV0NBIFJvb3QgQ2VydGlmaWNh
3579
+ dGlvbiBBdXRob3JpdHkwHhcNMDgwODI4MDcyNDMzWhcNMzAxMjMxMTU1OTU5WjBfMQswCQYDVQQG
3580
+ EwJUVzESMBAGA1UECgwJVEFJV0FOLUNBMRAwDgYDVQQLDAdSb290IENBMSowKAYDVQQDDCFUV0NB
3581
+ IFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK
3582
+ AoIBAQCwfnK4pAOU5qfeCTiRShFAh6d8WWQUe7UREN3+v9XAu1bihSX0NXIP+FPQQeFEAcK0HMMx
3583
+ QhZHhTMidrIKbw/lJVBPhYa+v5guEGcevhEFhgWQxFnQfHgQsIBct+HHK3XLfJ+utdGdIzdjp9xC
3584
+ oi2SBBtQwXu4PhvJVgSLL1KbralW6cH/ralYhzC2gfeXRfwZVzsrb+RH9JlF/h3x+JejiB03HFyP
3585
+ 4HYlmlD4oFT/RJB2I9IyxsOrBr/8+7/zrX2SYgJbKdM1o5OaQ2RgXbL6Mv87BK9NQGr5x+PvI/1r
3586
+ y+UPizgN7gr8/g+YnzAx3WxSZfmLgb4i4RxYA7qRG4kHAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIB
3587
+ BjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRqOFsmjd6LWvJPelSDGRjjCDWmujANBgkqhkiG
3588
+ 9w0BAQUFAAOCAQEAPNV3PdrfibqHDAhUaiBQkr6wQT25JmSDCi/oQMCXKCeCMErJk/9q56YAf4lC
3589
+ mtYR5VPOL8zy2gXE/uJQxDqGfczafhAJO5I1KlOy/usrBdlsXebQ79NqZp4VKIV66IIArB6nCWlW
3590
+ QtNoURi+VJq/REG6Sb4gumlc7rh3zc5sH62Dlhh9DrUUOYTxKOkto557HnpyWoOzeW/vtPzQCqVY
3591
+ T0bf+215WfKEIlKuD8z7fDvnaspHYcN6+NOSBB+4IIThNlQWx0DeO4pz3N/GCUzf7Nr/1FNCocny
3592
+ Yh0igzyXxfkZYiesZSLX0zzG5Y6yU8xJzrww/nsOM5D77dIUkR8Hrw==
3593
+ -----END CERTIFICATE-----
3594
+
3595
+ Security Communication RootCA2
3596
+ ==============================
3597
+ -----BEGIN CERTIFICATE-----
3598
+ MIIDdzCCAl+gAwIBAgIBADANBgkqhkiG9w0BAQsFADBdMQswCQYDVQQGEwJKUDElMCMGA1UEChMc
3599
+ U0VDT00gVHJ1c3QgU3lzdGVtcyBDTy4sTFRELjEnMCUGA1UECxMeU2VjdXJpdHkgQ29tbXVuaWNh
3600
+ dGlvbiBSb290Q0EyMB4XDTA5MDUyOTA1MDAzOVoXDTI5MDUyOTA1MDAzOVowXTELMAkGA1UEBhMC
3601
+ SlAxJTAjBgNVBAoTHFNFQ09NIFRydXN0IFN5c3RlbXMgQ08uLExURC4xJzAlBgNVBAsTHlNlY3Vy
3602
+ aXR5IENvbW11bmljYXRpb24gUm9vdENBMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
3603
+ ANAVOVKxUrO6xVmCxF1SrjpDZYBLx/KWvNs2l9amZIyoXvDjChz335c9S672XewhtUGrzbl+dp++
3604
+ +T42NKA7wfYxEUV0kz1XgMX5iZnK5atq1LXaQZAQwdbWQonCv/Q4EpVMVAX3NuRFg3sUZdbcDE3R
3605
+ 3n4MqzvEFb46VqZab3ZpUql6ucjrappdUtAtCms1FgkQhNBqyjoGADdH5H5XTz+L62e4iKrFvlNV
3606
+ spHEfbmwhRkGeC7bYRr6hfVKkaHnFtWOojnflLhwHyg/i/xAXmODPIMqGplrz95Zajv8bxbXH/1K
3607
+ EOtOghY6rCcMU/Gt1SSwawNQwS08Ft1ENCcadfsCAwEAAaNCMEAwHQYDVR0OBBYEFAqFqXdlBZh8
3608
+ QIH4D5csOPEK7DzPMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEB
3609
+ CwUAA4IBAQBMOqNErLlFsceTfsgLCkLfZOoc7llsCLqJX2rKSpWeeo8HxdpFcoJxDjrSzG+ntKEj
3610
+ u/Ykn8sX/oymzsLS28yN/HH8AynBbF0zX2S2ZTuJbxh2ePXcokgfGT+Ok+vx+hfuzU7jBBJV1uXk
3611
+ 3fs+BXziHV7Gp7yXT2g69ekuCkO2r1dcYmh8t/2jioSgrGK+KwmHNPBqAbubKVY8/gA3zyNs8U6q
3612
+ tnRGEmyR7jTV7JqR50S+kDFy1UkC9gLl9B/rfNmWVan/7Ir5mUf/NVoCqgTLiluHcSmRvaS0eg29
3613
+ mvVXIwAHIRc/SjnRBUkLp7Y3gaVdjKozXoEofKd9J+sAro03
3614
+ -----END CERTIFICATE-----
3615
+
3616
+ EC-ACC
3617
+ ======
3618
+ -----BEGIN CERTIFICATE-----
3619
+ MIIFVjCCBD6gAwIBAgIQ7is969Qh3hSoYqwE893EATANBgkqhkiG9w0BAQUFADCB8zELMAkGA1UE
3620
+ BhMCRVMxOzA5BgNVBAoTMkFnZW5jaWEgQ2F0YWxhbmEgZGUgQ2VydGlmaWNhY2lvIChOSUYgUS0w
3621
+ ODAxMTc2LUkpMSgwJgYDVQQLEx9TZXJ2ZWlzIFB1YmxpY3MgZGUgQ2VydGlmaWNhY2lvMTUwMwYD
3622
+ VQQLEyxWZWdldSBodHRwczovL3d3dy5jYXRjZXJ0Lm5ldC92ZXJhcnJlbCAoYykwMzE1MDMGA1UE
3623
+ CxMsSmVyYXJxdWlhIEVudGl0YXRzIGRlIENlcnRpZmljYWNpbyBDYXRhbGFuZXMxDzANBgNVBAMT
3624
+ BkVDLUFDQzAeFw0wMzAxMDcyMzAwMDBaFw0zMTAxMDcyMjU5NTlaMIHzMQswCQYDVQQGEwJFUzE7
3625
+ MDkGA1UEChMyQWdlbmNpYSBDYXRhbGFuYSBkZSBDZXJ0aWZpY2FjaW8gKE5JRiBRLTA4MDExNzYt
3626
+ SSkxKDAmBgNVBAsTH1NlcnZlaXMgUHVibGljcyBkZSBDZXJ0aWZpY2FjaW8xNTAzBgNVBAsTLFZl
3627
+ Z2V1IGh0dHBzOi8vd3d3LmNhdGNlcnQubmV0L3ZlcmFycmVsIChjKTAzMTUwMwYDVQQLEyxKZXJh
3628
+ cnF1aWEgRW50aXRhdHMgZGUgQ2VydGlmaWNhY2lvIENhdGFsYW5lczEPMA0GA1UEAxMGRUMtQUND
3629
+ MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsyLHT+KXQpWIR4NA9h0X84NzJB5R85iK
3630
+ w5K4/0CQBXCHYMkAqbWUZRkiFRfCQ2xmRJoNBD45b6VLeqpjt4pEndljkYRm4CgPukLjbo73FCeT
3631
+ ae6RDqNfDrHrZqJyTxIThmV6PttPB/SnCWDaOkKZx7J/sxaVHMf5NLWUhdWZXqBIoH7nF2W4onW4
3632
+ HvPlQn2v7fOKSGRdghST2MDk/7NQcvJ29rNdQlB50JQ+awwAvthrDk4q7D7SzIKiGGUzE3eeml0a
3633
+ E9jD2z3Il3rucO2n5nzbcc8tlGLfbdb1OL4/pYUKGbio2Al1QnDE6u/LDsg0qBIimAy4E5S2S+zw
3634
+ 0JDnJwIDAQABo4HjMIHgMB0GA1UdEQQWMBSBEmVjX2FjY0BjYXRjZXJ0Lm5ldDAPBgNVHRMBAf8E
3635
+ BTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUoMOLRKo3pUW/l4Ba0fF4opvpXY0wfwYD
3636
+ VR0gBHgwdjB0BgsrBgEEAfV4AQMBCjBlMCwGCCsGAQUFBwIBFiBodHRwczovL3d3dy5jYXRjZXJ0
3637
+ Lm5ldC92ZXJhcnJlbDA1BggrBgEFBQcCAjApGidWZWdldSBodHRwczovL3d3dy5jYXRjZXJ0Lm5l
3638
+ dC92ZXJhcnJlbCAwDQYJKoZIhvcNAQEFBQADggEBAKBIW4IB9k1IuDlVNZyAelOZ1Vr/sXE7zDkJ
3639
+ lF7W2u++AVtd0x7Y/X1PzaBB4DSTv8vihpw3kpBWHNzrKQXlxJ7HNd+KDM3FIUPpqojlNcAZQmNa
3640
+ Al6kSBg6hW/cnbw/nZzBh7h6YQjpdwt/cKt63dmXLGQehb+8dJahw3oS7AwaboMMPOhyRp/7SNVe
3641
+ l+axofjk70YllJyJ22k4vuxcDlbHZVHlUIiIv0LVKz3l+bqeLrPK9HOSAgu+TGbrIP65y7WZf+a2
3642
+ E/rKS03Z7lNGBjvGTq2TWoF+bCpLagVFjPIhpDGQh2xlnJ2lYJU6Un/10asIbvPuW/mIPX64b24D
3643
+ 5EI=
3644
+ -----END CERTIFICATE-----
3645
+
3646
+ Hellenic Academic and Research Institutions RootCA 2011
3647
+ =======================================================
3648
+ -----BEGIN CERTIFICATE-----
3649
+ MIIEMTCCAxmgAwIBAgIBADANBgkqhkiG9w0BAQUFADCBlTELMAkGA1UEBhMCR1IxRDBCBgNVBAoT
3650
+ O0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgQ2VydC4gQXV0aG9y
3651
+ aXR5MUAwPgYDVQQDEzdIZWxsZW5pYyBBY2FkZW1pYyBhbmQgUmVzZWFyY2ggSW5zdGl0dXRpb25z
3652
+ IFJvb3RDQSAyMDExMB4XDTExMTIwNjEzNDk1MloXDTMxMTIwMTEzNDk1MlowgZUxCzAJBgNVBAYT
3653
+ AkdSMUQwQgYDVQQKEztIZWxsZW5pYyBBY2FkZW1pYyBhbmQgUmVzZWFyY2ggSW5zdGl0dXRpb25z
3654
+ IENlcnQuIEF1dGhvcml0eTFAMD4GA1UEAxM3SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJlc2VhcmNo
3655
+ IEluc3RpdHV0aW9ucyBSb290Q0EgMjAxMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
3656
+ AKlTAOMupvaO+mDYLZU++CwqVE7NuYRhlFhPjz2L5EPzdYmNUeTDN9KKiE15HrcS3UN4SoqS5tdI
3657
+ 1Q+kOilENbgH9mgdVc04UfCMJDGFr4PJfel3r+0ae50X+bOdOFAPplp5kYCvN66m0zH7tSYJnTxa
3658
+ 71HFK9+WXesyHgLacEnsbgzImjeN9/E2YEsmLIKe0HjzDQ9jpFEw4fkrJxIH2Oq9GGKYsFk3fb7u
3659
+ 8yBRQlqD75O6aRXxYp2fmTmCobd0LovUxQt7L/DICto9eQqakxylKHJzkUOap9FNhYS5qXSPFEDH
3660
+ 3N6sQWRstBmbAmNtJGSPRLIl6s5ddAxjMlyNh+UCAwEAAaOBiTCBhjAPBgNVHRMBAf8EBTADAQH/
3661
+ MAsGA1UdDwQEAwIBBjAdBgNVHQ4EFgQUppFC/RNhSiOeCKQp5dgTBCPuQSUwRwYDVR0eBEAwPqA8
3662
+ MAWCAy5ncjAFggMuZXUwBoIELmVkdTAGggQub3JnMAWBAy5ncjAFgQMuZXUwBoEELmVkdTAGgQQu
3663
+ b3JnMA0GCSqGSIb3DQEBBQUAA4IBAQAf73lB4XtuP7KMhjdCSk4cNx6NZrokgclPEg8hwAOXhiVt
3664
+ XdMiKahsog2p6z0GW5k6x8zDmjR/qw7IThzh+uTczQ2+vyT+bOdrwg3IBp5OjWEopmr95fZi6hg8
3665
+ TqBTnbI6nOulnJEWtk2C4AwFSKls9cz4y51JtPACpf1wA+2KIaWuE4ZJwzNzvoc7dIsXRSZMFpGD
3666
+ /md9zU1jZ/rzAxKWeAaNsWftjj++n08C9bMJL/NMh98qy5V8AcysNnq/onN694/BtZqhFLKPM58N
3667
+ 7yLcZnuEvUUXBj08yrl3NI/K6s8/MT7jiOOASSXIl7WdmplNsDz4SgCbZN2fOUvRJ9e4
3668
+ -----END CERTIFICATE-----
3669
+
3670
+ Actalis Authentication Root CA
3671
+ ==============================
3672
+ -----BEGIN CERTIFICATE-----
3673
+ MIIFuzCCA6OgAwIBAgIIVwoRl0LE48wwDQYJKoZIhvcNAQELBQAwazELMAkGA1UEBhMCSVQxDjAM
3674
+ BgNVBAcMBU1pbGFuMSMwIQYDVQQKDBpBY3RhbGlzIFMucC5BLi8wMzM1ODUyMDk2NzEnMCUGA1UE
3675
+ AwweQWN0YWxpcyBBdXRoZW50aWNhdGlvbiBSb290IENBMB4XDTExMDkyMjExMjIwMloXDTMwMDky
3676
+ MjExMjIwMlowazELMAkGA1UEBhMCSVQxDjAMBgNVBAcMBU1pbGFuMSMwIQYDVQQKDBpBY3RhbGlz
3677
+ IFMucC5BLi8wMzM1ODUyMDk2NzEnMCUGA1UEAwweQWN0YWxpcyBBdXRoZW50aWNhdGlvbiBSb290
3678
+ IENBMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAp8bEpSmkLO/lGMWwUKNvUTufClrJ
3679
+ wkg4CsIcoBh/kbWHuUA/3R1oHwiD1S0eiKD4j1aPbZkCkpAW1V8IbInX4ay8IMKx4INRimlNAJZa
3680
+ by/ARH6jDuSRzVju3PvHHkVH3Se5CAGfpiEd9UEtL0z9KK3giq0itFZljoZUj5NDKd45RnijMCO6
3681
+ zfB9E1fAXdKDa0hMxKufgFpbOr3JpyI/gCczWw63igxdBzcIy2zSekciRDXFzMwujt0q7bd9Zg1f
3682
+ YVEiVRvjRuPjPdA1YprbrxTIW6HMiRvhMCb8oJsfgadHHwTrozmSBp+Z07/T6k9QnBn+locePGX2
3683
+ oxgkg4YQ51Q+qDp2JE+BIcXjDwL4k5RHILv+1A7TaLndxHqEguNTVHnd25zS8gebLra8Pu2Fbe8l
3684
+ EfKXGkJh90qX6IuxEAf6ZYGyojnP9zz/GPvG8VqLWeICrHuS0E4UT1lF9gxeKF+w6D9Fz8+vm2/7
3685
+ hNN3WpVvrJSEnu68wEqPSpP4RCHiMUVhUE4Q2OM1fEwZtN4Fv6MGn8i1zeQf1xcGDXqVdFUNaBr8
3686
+ EBtiZJ1t4JWgw5QHVw0U5r0F+7if5t+L4sbnfpb2U8WANFAoWPASUHEXMLrmeGO89LKtmyuy/uE5
3687
+ jF66CyCU3nuDuP/jVo23Eek7jPKxwV2dpAtMK9myGPW1n0sCAwEAAaNjMGEwHQYDVR0OBBYEFFLY
3688
+ iDrIn3hm7YnzezhwlMkCAjbQMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUUtiIOsifeGbt
3689
+ ifN7OHCUyQICNtAwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBCwUAA4ICAQALe3KHwGCmSUyI
3690
+ WOYdiPcUZEim2FgKDk8TNd81HdTtBjHIgT5q1d07GjLukD0R0i70jsNjLiNmsGe+b7bAEzlgqqI0
3691
+ JZN1Ut6nna0Oh4lScWoWPBkdg/iaKWW+9D+a2fDzWochcYBNy+A4mz+7+uAwTc+G02UQGRjRlwKx
3692
+ K3JCaKygvU5a2hi/a5iB0P2avl4VSM0RFbnAKVy06Ij3Pjaut2L9HmLecHgQHEhb2rykOLpn7VU+
3693
+ Xlff1ANATIGk0k9jpwlCCRT8AKnCgHNPLsBA2RF7SOp6AsDT6ygBJlh0wcBzIm2Tlf05fbsq4/aC
3694
+ 4yyXX04fkZT6/iyj2HYauE2yOE+b+h1IYHkm4vP9qdCa6HCPSXrW5b0KDtst842/6+OkfcvHlXHo
3695
+ 2qN8xcL4dJIEG4aspCJTQLas/kx2z/uUMsA1n3Y/buWQbqCmJqK4LL7RK4X9p2jIugErsWx0Hbhz
3696
+ lefut8cl8ABMALJ+tguLHPPAUJ4lueAI3jZm/zel0btUZCzJJ7VLkn5l/9Mt4blOvH+kQSGQQXem
3697
+ OR/qnuOf0GZvBeyqdn6/axag67XH/JJULysRJyU3eExRarDzzFhdFPFqSBX/wge2sY0PjlxQRrM9
3698
+ vwGYT7JZVEc+NHt4bVaTLnPqZih4zR0Uv6CPLy64Lo7yFIrM6bV8+2ydDKXhlg==
3699
+ -----END CERTIFICATE-----
3700
+
3701
+ Trustis FPS Root CA
3702
+ ===================
3703
+ -----BEGIN CERTIFICATE-----
3704
+ MIIDZzCCAk+gAwIBAgIQGx+ttiD5JNM2a/fH8YygWTANBgkqhkiG9w0BAQUFADBFMQswCQYDVQQG
3705
+ EwJHQjEYMBYGA1UEChMPVHJ1c3RpcyBMaW1pdGVkMRwwGgYDVQQLExNUcnVzdGlzIEZQUyBSb290
3706
+ IENBMB4XDTAzMTIyMzEyMTQwNloXDTI0MDEyMTExMzY1NFowRTELMAkGA1UEBhMCR0IxGDAWBgNV
3707
+ BAoTD1RydXN0aXMgTGltaXRlZDEcMBoGA1UECxMTVHJ1c3RpcyBGUFMgUm9vdCBDQTCCASIwDQYJ
3708
+ KoZIhvcNAQEBBQADggEPADCCAQoCggEBAMVQe547NdDfxIzNjpvto8A2mfRC6qc+gIMPpqdZh8mQ
3709
+ RUN+AOqGeSoDvT03mYlmt+WKVoaTnGhLaASMk5MCPjDSNzoiYYkchU59j9WvezX2fihHiTHcDnlk
3710
+ H5nSW7r+f2C/revnPDgpai/lkQtV/+xvWNUtyd5MZnGPDNcE2gfmHhjjvSkCqPoc4Vu5g6hBSLwa
3711
+ cY3nYuUtsuvffM/bq1rKMfFMIvMFE/eC+XN5DL7XSxzA0RU8k0Fk0ea+IxciAIleH2ulrG6nS4zt
3712
+ o3Lmr2NNL4XSFDWaLk6M6jKYKIahkQlBOrTh4/L68MkKokHdqeMDx4gVOxzUGpTXn2RZEm0CAwEA
3713
+ AaNTMFEwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBS6+nEleYtXQSUhhgtx67JkDoshZzAd
3714
+ BgNVHQ4EFgQUuvpxJXmLV0ElIYYLceuyZA6LIWcwDQYJKoZIhvcNAQEFBQADggEBAH5Y//01GX2c
3715
+ GE+esCu8jowU/yyg2kdbw++BLa8F6nRIW/M+TgfHbcWzk88iNVy2P3UnXwmWzaD+vkAMXBJV+JOC
3716
+ yinpXj9WV4s4NvdFGkwozZ5BuO1WTISkQMi4sKUraXAEasP41BIy+Q7DsdwyhEQsb8tGD+pmQQ9P
3717
+ 8Vilpg0ND2HepZ5dfWWhPBfnqFVO76DH7cZEf1T1o+CP8HxVIo8ptoGj4W1OLBuAZ+ytIJ8MYmHV
3718
+ l/9D7S3B2l0pKoU/rGXuhg8FjZBf3+6f9L/uHfuY5H+QK4R4EA5sSVPvFVtlRkpdr7r7OnIdzfYl
3719
+ iB6XzCGcKQENZetX2fNXlrtIzYE=
3720
+ -----END CERTIFICATE-----
3721
+
3722
+ StartCom Certification Authority
3723
+ ================================
3724
+ -----BEGIN CERTIFICATE-----
3725
+ MIIHhzCCBW+gAwIBAgIBLTANBgkqhkiG9w0BAQsFADB9MQswCQYDVQQGEwJJTDEWMBQGA1UEChMN
3726
+ U3RhcnRDb20gTHRkLjErMCkGA1UECxMiU2VjdXJlIERpZ2l0YWwgQ2VydGlmaWNhdGUgU2lnbmlu
3727
+ ZzEpMCcGA1UEAxMgU3RhcnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDYwOTE3MTk0
3728
+ NjM3WhcNMzYwOTE3MTk0NjM2WjB9MQswCQYDVQQGEwJJTDEWMBQGA1UEChMNU3RhcnRDb20gTHRk
3729
+ LjErMCkGA1UECxMiU2VjdXJlIERpZ2l0YWwgQ2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMg
3730
+ U3RhcnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAw
3731
+ ggIKAoICAQDBiNsJvGxGfHiflXu1M5DycmLWwTYgIiRezul38kMKogZkpMyONvg45iPwbm2xPN1y
3732
+ o4UcodM9tDMr0y+v/uqwQVlntsQGfQqedIXWeUyAN3rfOQVSWff0G0ZDpNKFhdLDcfN1YjS6LIp/
3733
+ Ho/u7TTQEceWzVI9ujPW3U3eCztKS5/CJi/6tRYccjV3yjxd5srhJosaNnZcAdt0FCX+7bWgiA/d
3734
+ eMotHweXMAEtcnn6RtYTKqi5pquDSR3l8u/d5AGOGAqPY1MWhWKpDhk6zLVmpsJrdAfkK+F2PrRt
3735
+ 2PZE4XNiHzvEvqBTViVsUQn3qqvKv3b9bZvzndu/PWa8DFaqr5hIlTpL36dYUNk4dalb6kMMAv+Z
3736
+ 6+hsTXBbKWWc3apdzK8BMewM69KN6Oqce+Zu9ydmDBpI125C4z/eIT574Q1w+2OqqGwaVLRcJXrJ
3737
+ osmLFqa7LH4XXgVNWG4SHQHuEhANxjJ/GP/89PrNbpHoNkm+Gkhpi8KWTRoSsmkXwQqQ1vp5Iki/
3738
+ untp+HDH+no32NgN0nZPV/+Qt+OR0t3vwmC3Zzrd/qqc8NSLf3Iizsafl7b4r4qgEKjZ+xjGtrVc
3739
+ UjyJthkqcwEKDwOzEmDyei+B26Nu/yYwl/WL3YlXtq09s68rxbd2AvCl1iuahhQqcvbjM4xdCUsT
3740
+ 37uMdBNSSwIDAQABo4ICEDCCAgwwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYD
3741
+ VR0OBBYEFE4L7xqkQFulF2mHMMo0aEPQQa7yMB8GA1UdIwQYMBaAFE4L7xqkQFulF2mHMMo0aEPQ
3742
+ Qa7yMIIBWgYDVR0gBIIBUTCCAU0wggFJBgsrBgEEAYG1NwEBATCCATgwLgYIKwYBBQUHAgEWImh0
3743
+ dHA6Ly93d3cuc3RhcnRzc2wuY29tL3BvbGljeS5wZGYwNAYIKwYBBQUHAgEWKGh0dHA6Ly93d3cu
3744
+ c3RhcnRzc2wuY29tL2ludGVybWVkaWF0ZS5wZGYwgc8GCCsGAQUFBwICMIHCMCcWIFN0YXJ0IENv
3745
+ bW1lcmNpYWwgKFN0YXJ0Q29tKSBMdGQuMAMCAQEagZZMaW1pdGVkIExpYWJpbGl0eSwgcmVhZCB0
3746
+ aGUgc2VjdGlvbiAqTGVnYWwgTGltaXRhdGlvbnMqIG9mIHRoZSBTdGFydENvbSBDZXJ0aWZpY2F0
3747
+ aW9uIEF1dGhvcml0eSBQb2xpY3kgYXZhaWxhYmxlIGF0IGh0dHA6Ly93d3cuc3RhcnRzc2wuY29t
3748
+ L3BvbGljeS5wZGYwEQYJYIZIAYb4QgEBBAQDAgAHMDgGCWCGSAGG+EIBDQQrFilTdGFydENvbSBG
3749
+ cmVlIFNTTCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTANBgkqhkiG9w0BAQsFAAOCAgEAjo/n3JR5
3750
+ fPGFf59Jb2vKXfuM/gTFwWLRfUKKvFO3lANmMD+x5wqnUCBVJX92ehQN6wQOQOY+2IirByeDqXWm
3751
+ N3PH/UvSTa0XQMhGvjt/UfzDtgUx3M2FIk5xt/JxXrAaxrqTi3iSSoX4eA+D/i+tLPfkpLst0OcN
3752
+ Org+zvZ49q5HJMqjNTbOx8aHmNrs++myziebiMMEofYLWWivydsQD032ZGNcpRJvkrKTlMeIFw6T
3753
+ tn5ii5B/q06f/ON1FE8qMt9bDeD1e5MNq6HPh+GlBEXoPBKlCcWw0bdT82AUuoVpaiF8H3VhFyAX
3754
+ e2w7QSlc4axa0c2Mm+tgHRns9+Ww2vl5GKVFP0lDV9LdJNUso/2RjSe15esUBppMeyG7Oq0wBhjA
3755
+ 2MFrLH9ZXF2RsXAiV+uKa0hK1Q8p7MZAwC+ITGgBF3f0JBlPvfrhsiAhS90a2Cl9qrjeVOwhVYBs
3756
+ HvUwyKMQ5bLmKhQxw4UtjJixhlpPiVktucf3HMiKf8CdBUrmQk9io20ppB+Fq9vlgcitKj1MXVuE
3757
+ JnHEhV5xJMqlG2zYYdMa4FTbzrqpMrUi9nNBCV24F10OD5mQ1kfabwo6YigUZ4LZ8dCAWZvLMdib
3758
+ D4x3TrVoivJs9iQOLWxwxXPR3hTQcY+203sC9uO41Alua551hDnmfyWl8kgAwKQB2j8=
3759
+ -----END CERTIFICATE-----
3760
+
3761
+ StartCom Certification Authority G2
3762
+ ===================================
3763
+ -----BEGIN CERTIFICATE-----
3764
+ MIIFYzCCA0ugAwIBAgIBOzANBgkqhkiG9w0BAQsFADBTMQswCQYDVQQGEwJJTDEWMBQGA1UEChMN
3765
+ U3RhcnRDb20gTHRkLjEsMCoGA1UEAxMjU3RhcnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkg
3766
+ RzIwHhcNMTAwMTAxMDEwMDAxWhcNMzkxMjMxMjM1OTAxWjBTMQswCQYDVQQGEwJJTDEWMBQGA1UE
3767
+ ChMNU3RhcnRDb20gTHRkLjEsMCoGA1UEAxMjU3RhcnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3Jp
3768
+ dHkgRzIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC2iTZbB7cgNr2Cu+EWIAOVeq8O
3769
+ o1XJJZlKxdBWQYeQTSFgpBSHO839sj60ZwNq7eEPS8CRhXBF4EKe3ikj1AENoBB5uNsDvfOpL9HG
3770
+ 4A/LnooUCri99lZi8cVytjIl2bLzvWXFDSxu1ZJvGIsAQRSCb0AgJnooD/Uefyf3lLE3PbfHkffi
3771
+ Aez9lInhzG7TNtYKGXmu1zSCZf98Qru23QumNK9LYP5/Q0kGi4xDuFby2X8hQxfqp0iVAXV16iul
3772
+ Q5XqFYSdCI0mblWbq9zSOdIxHWDirMxWRST1HFSr7obdljKF+ExP6JV2tgXdNiNnvP8V4so75qbs
3773
+ O+wmETRIjfaAKxojAuuKHDp2KntWFhxyKrOq42ClAJ8Em+JvHhRYW6Vsi1g8w7pOOlz34ZYrPu8H
3774
+ vKTlXcxNnw3h3Kq74W4a7I/htkxNeXJdFzULHdfBR9qWJODQcqhaX2YtENwvKhOuJv4KHBnM0D4L
3775
+ nMgJLvlblnpHnOl68wVQdJVznjAJ85eCXuaPOQgeWeU1FEIT/wCc976qUM/iUUjXuG+v+E5+M5iS
3776
+ FGI6dWPPe/regjupuznixL0sAA7IF6wT700ljtizkC+p2il9Ha90OrInwMEePnWjFqmveiJdnxMa
3777
+ z6eg6+OGCtP95paV1yPIN93EfKo2rJgaErHgTuixO/XWb/Ew1wIDAQABo0IwQDAPBgNVHRMBAf8E
3778
+ BTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUS8W0QGutHLOlHGVuRjaJhwUMDrYwDQYJ
3779
+ KoZIhvcNAQELBQADggIBAHNXPyzVlTJ+N9uWkusZXn5T50HsEbZH77Xe7XRcxfGOSeD8bpkTzZ+K
3780
+ 2s06Ctg6Wgk/XzTQLwPSZh0avZyQN8gMjgdalEVGKua+etqhqaRpEpKwfTbURIfXUfEpY9Z1zRbk
3781
+ J4kd+MIySP3bmdCPX1R0zKxnNBFi2QwKN4fRoxdIjtIXHfbX/dtl6/2o1PXWT6RbdejF0mCy2wl+
3782
+ JYt7ulKSnj7oxXehPOBKc2thz4bcQ///If4jXSRK9dNtD2IEBVeC2m6kMyV5Sy5UGYvMLD0w6dEG
3783
+ /+gyRr61M3Z3qAFdlsHB1b6uJcDJHgoJIIihDsnzb02CVAAgp9KP5DlUFy6NHrgbuxu9mk47EDTc
3784
+ nIhT76IxW1hPkWLIwpqazRVdOKnWvvgTtZ8SafJQYqz7Fzf07rh1Z2AQ+4NQ+US1dZxAF7L+/Xld
3785
+ blhYXzD8AK6vM8EOTmy6p6ahfzLbOOCxchcKK5HsamMm7YnUeMx0HgX4a/6ManY5Ka5lIxKVCCIc
3786
+ l85bBu4M4ru8H0ST9tg4RQUh7eStqxK2A6RCLi3ECToDZ2mEmuFZkIoohdVddLHRDiBYmxOlsGOm
3787
+ 7XtH/UVVMKTumtTm4ofvmMkyghEpIrwACjFeLQ/Ajulrso8uBtjRkcfGEvRM/TAXw8HaOFvjqerm
3788
+ obp573PYtlNXLfbQ4ddI
3789
+ -----END CERTIFICATE-----
3790
+
3791
+ Buypass Class 2 Root CA
3792
+ =======================
3793
+ -----BEGIN CERTIFICATE-----
3794
+ MIIFWTCCA0GgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJOTzEdMBsGA1UECgwU
3795
+ QnV5cGFzcyBBUy05ODMxNjMzMjcxIDAeBgNVBAMMF0J1eXBhc3MgQ2xhc3MgMiBSb290IENBMB4X
3796
+ DTEwMTAyNjA4MzgwM1oXDTQwMTAyNjA4MzgwM1owTjELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1
3797
+ eXBhc3MgQVMtOTgzMTYzMzI3MSAwHgYDVQQDDBdCdXlwYXNzIENsYXNzIDIgUm9vdCBDQTCCAiIw
3798
+ DQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANfHXvfBB9R3+0Mh9PT1aeTuMgHbo4Yf5FkNuud1
3799
+ g1Lr6hxhFUi7HQfKjK6w3Jad6sNgkoaCKHOcVgb/S2TwDCo3SbXlzwx87vFKu3MwZfPVL4O2fuPn
3800
+ 9Z6rYPnT8Z2SdIrkHJasW4DptfQxh6NR/Md+oW+OU3fUl8FVM5I+GC911K2GScuVr1QGbNgGE41b
3801
+ /+EmGVnAJLqBcXmQRFBoJJRfuLMR8SlBYaNByyM21cHxMlAQTn/0hpPshNOOvEu/XAFOBz3cFIqU
3802
+ CqTqc/sLUegTBxj6DvEr0VQVfTzh97QZQmdiXnfgolXsttlpF9U6r0TtSsWe5HonfOV116rLJeff
3803
+ awrbD02TTqigzXsu8lkBarcNuAeBfos4GzjmCleZPe4h6KP1DBbdi+w0jpwqHAAVF41og9JwnxgI
3804
+ zRFo1clrUs3ERo/ctfPYV3Me6ZQ5BL/T3jjetFPsaRyifsSP5BtwrfKi+fv3FmRmaZ9JUaLiFRhn
3805
+ Bkp/1Wy1TbMz4GHrXb7pmA8y1x1LPC5aAVKRCfLf6o3YBkBjqhHk/sM3nhRSP/TizPJhk9H9Z2vX
3806
+ Uq6/aKtAQ6BXNVN48FP4YUIHZMbXb5tMOA1jrGKvNouicwoN9SG9dKpN6nIDSdvHXx1iY8f93ZHs
3807
+ M+71bbRuMGjeyNYmsHVee7QHIJihdjK4TWxPAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYD
3808
+ VR0OBBYEFMmAd+BikoL1RpzzuvdMw964o605MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsF
3809
+ AAOCAgEAU18h9bqwOlI5LJKwbADJ784g7wbylp7ppHR/ehb8t/W2+xUbP6umwHJdELFx7rxP462s
3810
+ A20ucS6vxOOto70MEae0/0qyexAQH6dXQbLArvQsWdZHEIjzIVEpMMpghq9Gqx3tOluwlN5E40EI
3811
+ osHsHdb9T7bWR9AUC8rmyrV7d35BH16Dx7aMOZawP5aBQW9gkOLo+fsicdl9sz1Gv7SEr5AcD48S
3812
+ aq/v7h56rgJKihcrdv6sVIkkLE8/trKnToyokZf7KcZ7XC25y2a2t6hbElGFtQl+Ynhw/qlqYLYd
3813
+ DnkM/crqJIByw5c/8nerQyIKx+u2DISCLIBrQYoIwOula9+ZEsuK1V6ADJHgJgg2SMX6OBE1/yWD
3814
+ LfJ6v9r9jv6ly0UsH8SIU653DtmadsWOLB2jutXsMq7Aqqz30XpN69QH4kj3Io6wpJ9qzo6ysmD0
3815
+ oyLQI+uUWnpp3Q+/QFesa1lQ2aOZ4W7+jQF5JyMV3pKdewlNWudLSDBaGOYKbeaP4NK75t98biGC
3816
+ wWg5TbSYWGZizEqQXsP6JwSxeRV0mcy+rSDeJmAc61ZRpqPq5KM/p/9h3PFaTWwyI0PurKju7koS
3817
+ CTxdccK+efrCh2gdC/1cacwG0Jp9VJkqyTkaGa9LKkPzY11aWOIv4x3kqdbQCtCev9eBCfHJxyYN
3818
+ rJgWVqA=
3819
+ -----END CERTIFICATE-----
3820
+
3821
+ Buypass Class 3 Root CA
3822
+ =======================
3823
+ -----BEGIN CERTIFICATE-----
3824
+ MIIFWTCCA0GgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJOTzEdMBsGA1UECgwU
3825
+ QnV5cGFzcyBBUy05ODMxNjMzMjcxIDAeBgNVBAMMF0J1eXBhc3MgQ2xhc3MgMyBSb290IENBMB4X
3826
+ DTEwMTAyNjA4Mjg1OFoXDTQwMTAyNjA4Mjg1OFowTjELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1
3827
+ eXBhc3MgQVMtOTgzMTYzMzI3MSAwHgYDVQQDDBdCdXlwYXNzIENsYXNzIDMgUm9vdCBDQTCCAiIw
3828
+ DQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAKXaCpUWUOOV8l6ddjEGMnqb8RB2uACatVI2zSRH
3829
+ sJ8YZLya9vrVediQYkwiL944PdbgqOkcLNt4EemOaFEVcsfzM4fkoF0LXOBXByow9c3EN3coTRiR
3830
+ 5r/VUv1xLXA+58bEiuPwKAv0dpihi4dVsjoT/Lc+JzeOIuOoTyrvYLs9tznDDgFHmV0ST9tD+leh
3831
+ 7fmdvhFHJlsTmKtdFoqwNxxXnUX/iJY2v7vKB3tvh2PX0DJq1l1sDPGzbjniazEuOQAnFN44wOwZ
3832
+ ZoYS6J1yFhNkUsepNxz9gjDthBgd9K5c/3ATAOux9TN6S9ZV+AWNS2mw9bMoNlwUxFFzTWsL8TQH
3833
+ 2xc519woe2v1n/MuwU8XKhDzzMro6/1rqy6any2CbgTUUgGTLT2G/H783+9CHaZr77kgxve9oKeV
3834
+ /afmiSTYzIw0bOIjL9kSGiG5VZFvC5F5GQytQIgLcOJ60g7YaEi7ghM5EFjp2CoHxhLbWNvSO1UQ
3835
+ RwUVZ2J+GGOmRj8JDlQyXr8NYnon74Do29lLBlo3WiXQCBJ31G8JUJc9yB3D34xFMFbG02SrZvPA
3836
+ Xpacw8Tvw3xrizp5f7NJzz3iiZ+gMEuFuZyUJHmPfWupRWgPK9Dx2hzLabjKSWJtyNBjYt1gD1iq
3837
+ j6G8BaVmos8bdrKEZLFMOVLAMLrwjEsCsLa3AgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYD
3838
+ VR0OBBYEFEe4zf/lb+74suwvTg75JbCOPGvDMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsF
3839
+ AAOCAgEAACAjQTUEkMJAYmDv4jVM1z+s4jSQuKFvdvoWFqRINyzpkMLyPPgKn9iB5btb2iUspKdV
3840
+ cSQy9sgL8rxq+JOssgfCX5/bzMiKqr5qb+FJEMwx14C7u8jYog5kV+qi9cKpMRXSIGrs/CIBKM+G
3841
+ uIAeqcwRpTzyFrNHnfzSgCHEy9BHcEGhyoMZCCxt8l13nIoUE9Q2HJLw5QY33KbmkJs4j1xrG0aG
3842
+ Q0JfPgEHU1RdZX33inOhmlRaHylDFCfChQ+1iHsaO5S3HWCntZznKWlXWpuTekMwGwPXYshApqr8
3843
+ ZORK15FTAaggiG6cX0S5y2CBNOxv033aSF/rtJC8LakcC6wc1aJoIIAE1vyxjy+7SjENSoYc6+I2
3844
+ KSb12tjE8nVhz36udmNKekBlk4f4HoCMhuWG1o8O/FMsYOgWYRqiPkN7zTlgVGr18okmAWiDSKIz
3845
+ 6MkEkbIRNBE+6tBDGR8Dk5AM/1E9V/RBbuHLoL7ryWPNbczk+DaqaJ3tvV2XcEQNtg413OEMXbug
3846
+ UZTLfhbrES+jkkXITHHZvMmZUldGL1DPvTVp9D0VzgalLA8+9oG6lLvDu79leNKGef9JOxqDDPDe
3847
+ eOzI8k1MGt6CKfjBWtrt7uYnXuhF0J0cUahoq0Tj0Itq4/g7u9xN12TyUb7mqqta6THuBrxzvxNi
3848
+ Cp/HuZc=
3849
+ -----END CERTIFICATE-----
includes/vendor/campaign-monitor/class/log.php ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ define('CS_REST_LOG_VERBOSE', 1000);
3
+ define('CS_REST_LOG_WARNING', 500);
4
+ define('CS_REST_LOG_ERROR', 250);
5
+ define('CS_REST_LOG_NONE', 0);
6
+
7
+ class CS_REST_Log {
8
+ var $_level;
9
+
10
+ function CS_REST_Log($level) {
11
+ $this->_level = $level;
12
+ }
13
+
14
+ function log_message($message, $module, $level) {
15
+ if($this->_level >= $level) {
16
+ echo date('G:i:s').' - '.$module.': '.$message."<br />\n";
17
+ }
18
+ }
19
+ }
includes/vendor/campaign-monitor/class/serialisation.php ADDED
@@ -0,0 +1,129 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ if (!class_exists('Services_JSON', false)) {
4
+ require_once dirname(__FILE__).'/services_json.php';
5
+ }
6
+
7
+ function CS_REST_SERIALISATION_get_available($log) {
8
+ $log->log_message('Getting serialiser', __FUNCTION__, CS_REST_LOG_VERBOSE);
9
+ if(function_exists('json_decode') && function_exists('json_encode')) {
10
+ return new CS_REST_NativeJsonSerialiser($log);
11
+ } else {
12
+ return new CS_REST_ServicesJsonSerialiser($log);
13
+ }
14
+ }
15
+ class CS_REST_BaseSerialiser {
16
+
17
+ var $_log;
18
+
19
+ function CS_REST_BaseSerialiser($log) {
20
+ $this->_log = $log;
21
+ }
22
+
23
+ /**
24
+ * Recursively ensures that all data values are utf-8 encoded.
25
+ * @param array $data All values of this array are checked for utf-8 encoding.
26
+ */
27
+ function check_encoding($data) {
28
+
29
+ foreach($data as $k => $v) {
30
+ // If the element is a sub-array then recusively encode the array
31
+ if(is_array($v)) {
32
+ $data[$k] = $this->check_encoding($v);
33
+ // Otherwise if the element is a string then we need to check the encoding
34
+ } else if(is_string($v)) {
35
+ if((function_exists('mb_detect_encoding') && mb_detect_encoding($v) !== 'UTF-8') ||
36
+ (function_exists('mb_check_encoding') && !mb_check_encoding($v, 'UTF-8'))) {
37
+ // The string is using some other encoding, make sure we utf-8 encode
38
+ $v = utf8_encode($v);
39
+ }
40
+
41
+ $data[$k] = $v;
42
+ }
43
+ }
44
+
45
+ return $data;
46
+ }
47
+ }
48
+
49
+ class CS_REST_DoNothingSerialiser extends CS_REST_BaseSerialiser {
50
+ function CS_REST_DoNothingSerialiser() {}
51
+ function get_type() { return 'do_nothing'; }
52
+ function serialise($data) { return $data; }
53
+ function deserialise($text) {
54
+ $data = json_decode($text);
55
+ return is_null($data) ? $text : $data;
56
+ }
57
+ function check_encoding($data) { return $data; }
58
+ }
59
+
60
+ class CS_REST_NativeJsonSerialiser extends CS_REST_BaseSerialiser {
61
+
62
+ function CS_REST_NativeJsonSerialiser($log) {
63
+ $this->CS_REST_BaseSerialiser($log);
64
+ }
65
+
66
+ function get_format() {
67
+ return 'json';
68
+ }
69
+
70
+ function get_type() {
71
+ return 'native';
72
+ }
73
+
74
+ function serialise($data) {
75
+ if(is_null($data) || $data == '') return '';
76
+ return json_encode($this->check_encoding($data));
77
+ }
78
+
79
+ function deserialise($text) {
80
+ $data = json_decode($text);
81
+
82
+ return $this->strip_surrounding_quotes(is_null($data) ? $text : $data);
83
+ }
84
+
85
+ /**
86
+ * We've had sporadic reports of people getting ID's from create routes with the surrounding quotes present.
87
+ * There is no case where these should be present. Just get rid of it.
88
+ */
89
+ function strip_surrounding_quotes($data) {
90
+ if(is_string($data)) {
91
+ return trim($data, '"');
92
+ }
93
+
94
+ return $data;
95
+ }
96
+ }
97
+
98
+ class CS_REST_ServicesJsonSerialiser extends CS_REST_BaseSerialiser {
99
+
100
+ var $_serialiser;
101
+
102
+ function CS_REST_ServicesJsonSerialiser($log) {
103
+ $this->CS_REST_BaseSerialiser($log);
104
+ $this->_serialiser = new Services_JSON();
105
+ }
106
+
107
+ function get_content_type() {
108
+ return 'application/json';
109
+ }
110
+
111
+ function get_format() {
112
+ return 'json';
113
+ }
114
+
115
+ function get_type() {
116
+ return 'services_json';
117
+ }
118
+
119
+ function serialise($data) {
120
+ if(is_null($data) || $data == '') return '';
121
+ return $this->_serialiser->encode($this->check_encoding($data));
122
+ }
123
+
124
+ function deserialise($text) {
125
+ $data = $this->_serialiser->decode($text);
126
+
127
+ return is_null($data) ? $text : $data;
128
+ }
129
+ }
includes/vendor/campaign-monitor/class/services_json.php ADDED
@@ -0,0 +1,782 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Converts to and from JSON format.
5
+ *
6
+ * JSON (JavaScript Object Notation) is a lightweight data-interchange
7
+ * format. It is easy for humans to read and write. It is easy for machines
8
+ * to parse and generate. It is based on a subset of the JavaScript
9
+ * Programming Language, Standard ECMA-262 3rd Edition - December 1999.
10
+ * This feature can also be found in Python. JSON is a text format that is
11
+ * completely language independent but uses conventions that are familiar
12
+ * to programmers of the C-family of languages, including C, C++, C#, Java,
13
+ * JavaScript, Perl, TCL, and many others. These properties make JSON an
14
+ * ideal data-interchange language.
15
+ *
16
+ * This package provides a simple encoder and decoder for JSON notation. It
17
+ * is intended for use with client-side Javascript applications that make
18
+ * use of HTTPRequest to perform server communication functions - data can
19
+ * be encoded into JSON notation for use in a client-side javascript, or
20
+ * decoded from incoming Javascript requests. JSON format is native to
21
+ * Javascript, and can be directly eval()'ed with no further parsing
22
+ * overhead
23
+ *
24
+ * All strings should be in ASCII or UTF-8 format!
25
+ *
26
+ * LICENSE: Redistribution and use in source and binary forms, with or
27
+ * without modification, are permitted provided that the following
28
+ * conditions are met: Redistributions of source code must retain the
29
+ * above copyright notice, this list of conditions and the following
30
+ * disclaimer. Redistributions in binary form must reproduce the above
31
+ * copyright notice, this list of conditions and the following disclaimer
32
+ * in the documentation and/or other materials provided with the
33
+ * distribution.
34
+ *
35
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
36
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
37
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
38
+ * NO EVENT SHALL CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
39
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
40
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
41
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
42
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
43
+ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
44
+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
45
+ * DAMAGE.
46
+ *
47
+ * @category
48
+ * @package Services_JSON
49
+ * @author Michal Migurski <mike-json@teczno.com>
50
+ * @author Matt Knapp <mdknapp[at]gmail[dot]com>
51
+ * @author Brett Stimmerman <brettstimmerman[at]gmail[dot]com>
52
+ * @copyright 2005 Michal Migurski
53
+ * @version CVS: $Id: JSON.php,v 1.31 2006/06/28 05:54:17 migurski Exp $
54
+ * @license http://www.opensource.org/licenses/bsd-license.php
55
+ * @link http://pear.php.net/pepr/pepr-proposal-show.php?id=198
56
+ */
57
+
58
+ /**
59
+ * Marker constant for Services_JSON::decode(), used to flag stack state
60
+ */
61
+ define('SERVICES_JSON_SLICE', 1);
62
+
63
+ /**
64
+ * Marker constant for Services_JSON::decode(), used to flag stack state
65
+ */
66
+ define('SERVICES_JSON_IN_STR', 2);
67
+
68
+ /**
69
+ * Marker constant for Services_JSON::decode(), used to flag stack state
70
+ */
71
+ define('SERVICES_JSON_IN_ARR', 3);
72
+
73
+ /**
74
+ * Marker constant for Services_JSON::decode(), used to flag stack state
75
+ */
76
+ define('SERVICES_JSON_IN_OBJ', 4);
77
+
78
+ /**
79
+ * Marker constant for Services_JSON::decode(), used to flag stack state
80
+ */
81
+ define('SERVICES_JSON_IN_CMT', 5);
82
+
83
+ /**
84
+ * Behavior switch for Services_JSON::decode()
85
+ */
86
+ define('SERVICES_JSON_LOOSE_TYPE', 16);
87
+
88
+ /**
89
+ * Behavior switch for Services_JSON::decode()
90
+ */
91
+ define('SERVICES_JSON_SUPPRESS_ERRORS', 32);
92
+
93
+ /**
94
+ * Converts to and from JSON format.
95
+ *
96
+ * Brief example of use:
97
+ *
98
+ * <code>
99
+ * // create a new instance of Services_JSON
100
+ * $json = new Services_JSON();
101
+ *
102
+ * // convert a complexe value to JSON notation, and send it to the browser
103
+ * $value = array('foo', 'bar', array(1, 2, 'baz'), array(3, array(4)));
104
+ * $output = $json->encode($value);
105
+ *
106
+ * print($output);
107
+ * // prints: ["foo","bar",[1,2,"baz"],[3,[4]]]
108
+ *
109
+ * // accept incoming POST data, assumed to be in JSON notation
110
+ * $input = file_get_contents('php://input', 1000000);
111
+ * $value = $json->decode($input);
112
+ * </code>
113
+ */
114
+ class Services_JSON
115
+ {
116
+ /**
117
+ * constructs a new JSON instance
118
+ *
119
+ * @param int $use object behavior flags; combine with boolean-OR
120
+ *
121
+ * possible values:
122
+ * - SERVICES_JSON_LOOSE_TYPE: loose typing.
123
+ * "{...}" syntax creates associative arrays
124
+ * instead of objects in decode().
125
+ * - SERVICES_JSON_SUPPRESS_ERRORS: error suppression.
126
+ * Values which can't be encoded (e.g. resources)
127
+ * appear as NULL instead of throwing errors.
128
+ * By default, a deeply-nested resource will
129
+ * bubble up with an error, so all return values
130
+ * from encode() should be checked with isError()
131
+ */
132
+ function Services_JSON($use = 0)
133
+ {
134
+ $this->use = $use;
135
+ }
136
+
137
+ /**
138
+ * convert a string from one UTF-16 char to one UTF-8 char
139
+ *
140
+ * Normally should be handled by mb_convert_encoding, but
141
+ * provides a slower PHP-only method for installations
142
+ * that lack the multibye string extension.
143
+ *
144
+ * @param string $utf16 UTF-16 character
145
+ * @return string UTF-8 character
146
+ * @access private
147
+ */
148
+ function utf162utf8($utf16)
149
+ {
150
+ // oh please oh please oh please oh please oh please
151
+ if(function_exists('mb_convert_encoding')) {
152
+ return mb_convert_encoding($utf16, 'UTF-8', 'UTF-16');
153
+ }
154
+
155
+ $bytes = (ord($utf16{0}) << 8) | ord($utf16{1});
156
+
157
+ switch(true) {
158
+ case ((0x7F & $bytes) == $bytes):
159
+ // this case should never be reached, because we are in ASCII range
160
+ // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
161
+ return chr(0x7F & $bytes);
162
+
163
+ case (0x07FF & $bytes) == $bytes:
164
+ // return a 2-byte UTF-8 character
165
+ // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
166
+ return chr(0xC0 | (($bytes >> 6) & 0x1F))
167
+ . chr(0x80 | ($bytes & 0x3F));
168
+
169
+ case (0xFFFF & $bytes) == $bytes:
170
+ // return a 3-byte UTF-8 character
171
+ // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
172
+ return chr(0xE0 | (($bytes >> 12) & 0x0F))
173
+ . chr(0x80 | (($bytes >> 6) & 0x3F))
174
+ . chr(0x80 | ($bytes & 0x3F));
175
+ }
176
+
177
+ // ignoring UTF-32 for now, sorry
178
+ return '';
179
+ }
180
+
181
+ /**
182
+ * convert a string from one UTF-8 char to one UTF-16 char
183
+ *
184
+ * Normally should be handled by mb_convert_encoding, but
185
+ * provides a slower PHP-only method for installations
186
+ * that lack the multibye string extension.
187
+ *
188
+ * @param string $utf8 UTF-8 character
189
+ * @return string UTF-16 character
190
+ * @access private
191
+ */
192
+ function utf82utf16($utf8)
193
+ {
194
+ // oh please oh please oh please oh please oh please
195
+ if(function_exists('mb_convert_encoding')) {
196
+ return mb_convert_encoding($utf8, 'UTF-16', 'UTF-8');
197
+ }
198
+
199
+ switch(strlen($utf8)) {
200
+ case 1:
201
+ // this case should never be reached, because we are in ASCII range
202
+ // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
203
+ return $utf8;
204
+
205
+ case 2:
206
+ // return a UTF-16 character from a 2-byte UTF-8 char
207
+ // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
208
+ return chr(0x07 & (ord($utf8{0}) >> 2))
209
+ . chr((0xC0 & (ord($utf8{0}) << 6))
210
+ | (0x3F & ord($utf8{1})));
211
+
212
+ case 3:
213
+ // return a UTF-16 character from a 3-byte UTF-8 char
214
+ // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
215
+ return chr((0xF0 & (ord($utf8{0}) << 4))
216
+ | (0x0F & (ord($utf8{1}) >> 2)))
217
+ . chr((0xC0 & (ord($utf8{1}) << 6))
218
+ | (0x7F & ord($utf8{2})));
219
+ }
220
+
221
+ // ignoring UTF-32 for now, sorry
222
+ return '';
223
+ }
224
+
225
+ /**
226
+ * encodes an arbitrary variable into JSON format
227
+ *
228
+ * @param mixed $var any number, boolean, string, array, or object to be encoded.
229
+ * see argument 1 to Services_JSON() above for array-parsing behavior.
230
+ * if var is a strng, note that encode() always expects it
231
+ * to be in ASCII or UTF-8 format!
232
+ *
233
+ * @return mixed JSON string representation of input var or an error if a problem occurs
234
+ * @access public
235
+ */
236
+ function encode($var)
237
+ {
238
+ switch (gettype($var)) {
239
+ case 'boolean':
240
+ return $var ? 'true' : 'false';
241
+
242
+ case 'NULL':
243
+ return 'null';
244
+
245
+ case 'integer':
246
+ return (int) $var;
247
+
248
+ case 'double':
249
+ case 'float':
250
+ return (float) $var;
251
+
252
+ case 'string':
253
+ // STRINGS ARE EXPECTED TO BE IN ASCII OR UTF-8 FORMAT
254
+ $ascii = '';
255
+ $strlen_var = strlen($var);
256
+
257
+ /*
258
+ * Iterate over every character in the string,
259
+ * escaping with a slash or encoding to UTF-8 where necessary
260
+ */
261
+ for ($c = 0; $c < $strlen_var; ++$c) {
262
+
263
+ $ord_var_c = ord($var{$c});
264
+
265
+ switch (true) {
266
+ case $ord_var_c == 0x08:
267
+ $ascii .= '\b';
268
+ break;
269
+ case $ord_var_c == 0x09:
270
+ $ascii .= '\t';
271
+ break;
272
+ case $ord_var_c == 0x0A:
273
+ $ascii .= '\n';
274
+ break;
275
+ case $ord_var_c == 0x0C:
276
+ $ascii .= '\f';
277
+ break;
278
+ case $ord_var_c == 0x0D:
279
+ $ascii .= '\r';
280
+ break;
281
+
282
+ case $ord_var_c == 0x22:
283
+ case $ord_var_c == 0x2F:
284
+ case $ord_var_c == 0x5C:
285
+ // double quote, slash, slosh
286
+ $ascii .= '\\'.$var{$c};
287
+ break;
288
+
289
+ case (($ord_var_c >= 0x20) && ($ord_var_c <= 0x7F)):
290
+ // characters U-00000000 - U-0000007F (same as ASCII)
291
+ $ascii .= $var{$c};
292
+ break;
293
+
294
+ case (($ord_var_c & 0xE0) == 0xC0):
295
+ // characters U-00000080 - U-000007FF, mask 110XXXXX
296
+ // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
297
+ $char = pack('C*', $ord_var_c, ord($var{$c + 1}));
298
+ $c += 1;
299
+ $utf16 = $this->utf82utf16($char);
300
+ $ascii .= sprintf('\u%04s', bin2hex($utf16));
301
+ break;
302
+
303
+ case (($ord_var_c & 0xF0) == 0xE0):
304
+ // characters U-00000800 - U-0000FFFF, mask 1110XXXX
305
+ // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
306
+ $char = pack('C*', $ord_var_c,
307
+ ord($var{$c + 1}),
308
+ ord($var{$c + 2}));
309
+ $c += 2;
310
+ $utf16 = $this->utf82utf16($char);
311
+ $ascii .= sprintf('\u%04s', bin2hex($utf16));
312
+ break;
313
+
314
+ case (($ord_var_c & 0xF8) == 0xF0):
315
+ // characters U-00010000 - U-001FFFFF, mask 11110XXX
316
+ // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
317
+ $char = pack('C*', $ord_var_c,
318
+ ord($var{$c + 1}),
319
+ ord($var{$c + 2}),
320
+ ord($var{$c + 3}));
321
+ $c += 3;
322
+ $utf16 = $this->utf82utf16($char);
323
+ $ascii .= sprintf('\u%04s', bin2hex($utf16));
324
+ break;
325
+
326
+ case (($ord_var_c & 0xFC) == 0xF8):
327
+ // characters U-00200000 - U-03FFFFFF, mask 111110XX
328
+ // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
329
+ $char = pack('C*', $ord_var_c,
330
+ ord($var{$c + 1}),
331
+ ord($var{$c + 2}),
332
+ ord($var{$c + 3}),
333
+ ord($var{$c + 4}));
334
+ $c += 4;
335
+ $utf16 = $this->utf82utf16($char);
336
+ $ascii .= sprintf('\u%04s', bin2hex($utf16));
337
+ break;
338
+
339
+ case (($ord_var_c & 0xFE) == 0xFC):
340
+ // characters U-04000000 - U-7FFFFFFF, mask 1111110X
341
+ // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
342
+ $char = pack('C*', $ord_var_c,
343
+ ord($var{$c + 1}),
344
+ ord($var{$c + 2}),
345
+ ord($var{$c + 3}),
346
+ ord($var{$c + 4}),
347
+ ord($var{$c + 5}));
348
+ $c += 5;
349
+ $utf16 = $this->utf82utf16($char);
350
+ $ascii .= sprintf('\u%04s', bin2hex($utf16));
351
+ break;
352
+ }
353
+ }
354
+
355
+ return '"'.$ascii.'"';
356
+
357
+ case 'array':
358
+ /*
359
+ * As per JSON spec if any array key is not an integer
360
+ * we must treat the the whole array as an object. We
361
+ * also try to catch a sparsely populated associative
362
+ * array with numeric keys here because some JS engines
363
+ * will create an array with empty indexes up to
364
+ * max_index which can cause memory issues and because
365
+ * the keys, which may be relevant, will be remapped
366
+ * otherwise.
367
+ *
368
+ * As per the ECMA and JSON specification an object may
369
+ * have any string as a property. Unfortunately due to
370
+ * a hole in the ECMA specification if the key is a
371
+ * ECMA reserved word or starts with a digit the
372
+ * parameter is only accessible using ECMAScript's
373
+ * bracket notation.
374
+ */
375
+
376
+ // treat as a JSON object
377
+ if (is_array($var) && count($var) && (array_keys($var) !== range(0, sizeof($var) - 1))) {
378
+ $properties = array_map(array($this, 'name_value'),
379
+ array_keys($var),
380
+ array_values($var));
381
+
382
+ foreach($properties as $property) {
383
+ if($this->isError($property)) {
384
+ return $property;
385
+ }
386
+ }
387
+
388
+ return '{' . join(',', $properties) . '}';
389
+ }
390
+
391
+ // treat it like a regular array
392
+ $elements = array_map(array($this, 'encode'), $var);
393
+
394
+ foreach($elements as $element) {
395
+ if($this->isError($element)) {
396
+ return $element;
397
+ }
398
+ }
399
+
400
+ return '[' . join(',', $elements) . ']';
401
+
402
+ case 'object':
403
+ $vars = get_object_vars($var);
404
+
405
+ $properties = array_map(array($this, 'name_value'),
406
+ array_keys($vars),
407
+ array_values($vars));
408
+
409
+ foreach($properties as $property) {
410
+ if($this->isError($property)) {
411
+ return $property;
412
+ }
413
+ }
414
+
415
+ return '{' . join(',', $properties) . '}';
416
+
417
+ default:
418
+ return ($this->use & SERVICES_JSON_SUPPRESS_ERRORS)
419
+ ? 'null'
420
+ : new Services_JSON_Error(gettype($var)." can not be encoded as JSON string");
421
+ }
422
+ }
423
+
424
+ /**
425
+ * array-walking function for use in generating JSON-formatted name-value pairs
426
+ *
427
+ * @param string $name name of key to use
428
+ * @param mixed $value reference to an array element to be encoded
429
+ *
430
+ * @return string JSON-formatted name-value pair, like '"name":value'
431
+ * @access private
432
+ */
433
+ function name_value($name, $value)
434
+ {
435
+ $encoded_value = $this->encode($value);
436
+
437
+ if($this->isError($encoded_value)) {
438
+ return $encoded_value;
439
+ }
440
+
441
+ return $this->encode(strval($name)) . ':' . $encoded_value;
442
+ }
443
+
444
+ /**
445
+ * reduce a string by removing leading and trailing comments and whitespace
446
+ *
447
+ * @param $str string string value to strip of comments and whitespace
448
+ *
449
+ * @return string string value stripped of comments and whitespace
450
+ * @access private
451
+ */
452
+ function reduce_string($str)
453
+ {
454
+ $str = preg_replace(array(
455
+
456
+ // eliminate single line comments in '// ...' form
457
+ '#^\s*//(.+)$#m',
458
+
459
+ // eliminate multi-line comments in '/* ... */' form, at start of string
460
+ '#^\s*/\*(.+)\*/#Us',
461
+
462
+ // eliminate multi-line comments in '/* ... */' form, at end of string
463
+ '#/\*(.+)\*/\s*$#Us'
464
+
465
+ ), '', $str);
466
+
467
+ // eliminate extraneous space
468
+ return trim($str);
469
+ }
470
+
471
+ /**
472
+ * decodes a JSON string into appropriate variable
473
+ *
474
+ * @param string $str JSON-formatted string
475
+ *
476
+ * @return mixed number, boolean, string, array, or object
477
+ * corresponding to given JSON input string.
478
+ * See argument 1 to Services_JSON() above for object-output behavior.
479
+ * Note that decode() always returns strings
480
+ * in ASCII or UTF-8 format!
481
+ * @access public
482
+ */
483
+ function decode($str)
484
+ {
485
+ $str = $this->reduce_string($str);
486
+
487
+ switch (strtolower($str)) {
488
+ case 'true':
489
+ return true;
490
+
491
+ case 'false':
492
+ return false;
493
+
494
+ case 'null':
495
+ return null;
496
+
497
+ default:
498
+ $m = array();
499
+
500
+ if (is_numeric($str)) {
501
+ // Lookie-loo, it's a number
502
+
503
+ // This would work on its own, but I'm trying to be
504
+ // good about returning integers where appropriate:
505
+ // return (float)$str;
506
+
507
+ // Return float or int, as appropriate
508
+ return ((float)$str == (integer)$str)
509
+ ? (integer)$str
510
+ : (float)$str;
511
+
512
+ } elseif (preg_match('/^("|\').*(\1)$/s', $str, $m) && $m[1] == $m[2]) {
513
+ // STRINGS RETURNED IN UTF-8 FORMAT
514
+ $delim = substr($str, 0, 1);
515
+ $chrs = substr($str, 1, -1);
516
+ $utf8 = '';
517
+ $strlen_chrs = strlen($chrs);
518
+
519
+ for ($c = 0; $c < $strlen_chrs; ++$c) {
520
+
521
+ $substr_chrs_c_2 = substr($chrs, $c, 2);
522
+ $ord_chrs_c = ord($chrs{$c});
523
+
524
+ switch (true) {
525
+ case $substr_chrs_c_2 == '\b':
526
+ $utf8 .= chr(0x08);
527
+ ++$c;
528
+ break;
529
+ case $substr_chrs_c_2 == '\t':
530
+ $utf8 .= chr(0x09);
531
+ ++$c;
532
+ break;
533
+ case $substr_chrs_c_2 == '\n':
534
+ $utf8 .= chr(0x0A);
535
+ ++$c;
536
+ break;
537
+ case $substr_chrs_c_2 == '\f':
538
+ $utf8 .= chr(0x0C);
539
+ ++$c;
540
+ break;
541
+ case $substr_chrs_c_2 == '\r':
542
+ $utf8 .= chr(0x0D);
543
+ ++$c;
544
+ break;
545
+
546
+ case $substr_chrs_c_2 == '\\"':
547
+ case $substr_chrs_c_2 == '\\\'':
548
+ case $substr_chrs_c_2 == '\\\\':
549
+ case $substr_chrs_c_2 == '\\/':
550
+ if (($delim == '"' && $substr_chrs_c_2 != '\\\'') ||
551
+ ($delim == "'" && $substr_chrs_c_2 != '\\"')) {
552
+ $utf8 .= $chrs{++$c};
553
+ }
554
+ break;
555
+
556
+ case preg_match('/\\\u[0-9A-F]{4}/i', substr($chrs, $c, 6)):
557
+ // single, escaped unicode character
558
+ $utf16 = chr(hexdec(substr($chrs, ($c + 2), 2)))
559
+ . chr(hexdec(substr($chrs, ($c + 4), 2)));
560
+ $utf8 .= $this->utf162utf8($utf16);
561
+ $c += 5;
562
+ break;
563
+
564
+ case ($ord_chrs_c >= 0x20) && ($ord_chrs_c <= 0x7F):
565
+ $utf8 .= $chrs{$c};
566
+ break;
567
+
568
+ case ($ord_chrs_c & 0xE0) == 0xC0:
569
+ // characters U-00000080 - U-000007FF, mask 110XXXXX
570
+ //see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
571
+ $utf8 .= substr($chrs, $c, 2);
572
+ ++$c;
573
+ break;
574
+
575
+ case ($ord_chrs_c & 0xF0) == 0xE0:
576
+ // characters U-00000800 - U-0000FFFF, mask 1110XXXX
577
+ // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
578
+ $utf8 .= substr($chrs, $c, 3);
579
+ $c += 2;
580
+ break;
581
+
582
+ case ($ord_chrs_c & 0xF8) == 0xF0:
583
+ // characters U-00010000 - U-001FFFFF, mask 11110XXX
584
+ // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
585
+ $utf8 .= substr($chrs, $c, 4);
586
+ $c += 3;
587
+ break;
588
+
589
+ case ($ord_chrs_c & 0xFC) == 0xF8:
590
+ // characters U-00200000 - U-03FFFFFF, mask 111110XX
591
+ // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
592
+ $utf8 .= substr($chrs, $c, 5);
593
+ $c += 4;
594
+ break;
595
+
596
+ case ($ord_chrs_c & 0xFE) == 0xFC:
597
+ // characters U-04000000 - U-7FFFFFFF, mask 1111110X
598
+ // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
599
+ $utf8 .= substr($chrs, $c, 6);
600
+ $c += 5;
601
+ break;
602
+
603
+ }
604
+
605
+ }
606
+
607
+ return $utf8;
608
+
609
+ } elseif (preg_match('/^\[.*\]$/s', $str) || preg_match('/^\{.*\}$/s', $str)) {
610
+ // array, or object notation
611
+
612
+ if ($str{0} == '[') {
613
+ $stk = array(SERVICES_JSON_IN_ARR);
614
+ $arr = array();
615
+ } else {
616
+ if ($this->use & SERVICES_JSON_LOOSE_TYPE) {
617
+ $stk = array(SERVICES_JSON_IN_OBJ);
618
+ $obj = array();
619
+ } else {
620
+ $stk = array(SERVICES_JSON_IN_OBJ);
621
+ $obj = new stdClass();
622
+ }
623
+ }
624
+
625
+ array_push($stk, array('what' => SERVICES_JSON_SLICE,
626
+ 'where' => 0,
627
+ 'delim' => false));
628
+
629
+ $chrs = substr($str, 1, -1);
630
+ $chrs = $this->reduce_string($chrs);
631
+
632
+ if ($chrs == '') {
633
+ if (reset($stk) == SERVICES_JSON_IN_ARR) {
634
+ return $arr;
635
+
636
+ } else {
637
+ return $obj;
638
+
639
+ }
640
+ }
641
+
642
+ //print("\nparsing {$chrs}\n");
643
+
644
+ $strlen_chrs = strlen($chrs);
645
+
646
+ for ($c = 0; $c <= $strlen_chrs; ++$c) {
647
+
648
+ $top = end($stk);
649
+ $substr_chrs_c_2 = substr($chrs, $c, 2);
650
+
651
+ if (($c == $strlen_chrs) || (($chrs{$c} == ',') && ($top['what'] == SERVICES_JSON_SLICE))) {
652
+ // found a comma that is not inside a string, array, etc.,
653
+ // OR we've reached the end of the character list
654
+ $slice = substr($chrs, $top['where'], ($c - $top['where']));
655
+ array_push($stk, array('what' => SERVICES_JSON_SLICE, 'where' => ($c + 1), 'delim' => false));
656
+ //print("Found split at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n");
657
+
658
+ if (reset($stk) == SERVICES_JSON_IN_ARR) {
659
+ // we are in an array, so just push an element onto the stack
660
+ array_push($arr, $this->decode($slice));
661
+
662
+ } elseif (reset($stk) == SERVICES_JSON_IN_OBJ) {
663
+ // we are in an object, so figure
664
+ // out the property name and set an
665
+ // element in an associative array,
666
+ // for now
667
+ $parts = array();
668
+
669
+ if (preg_match('/^\s*(["\'].*[^\\\]["\'])\s*:\s*(\S.*),?$/Uis', $slice, $parts)) {
670
+ // "name":value pair
671
+ $key = $this->decode($parts[1]);
672
+ $val = $this->decode($parts[2]);
673
+
674
+ if ($this->use & SERVICES_JSON_LOOSE_TYPE) {
675
+ $obj[$key] = $val;
676
+ } else {
677
+ $obj->$key = $val;
678
+ }
679
+ } elseif (preg_match('/^\s*(\w+)\s*:\s*(\S.*),?$/Uis', $slice, $parts)) {
680
+ // name:value pair, where name is unquoted
681
+ $key = $parts[1];
682
+ $val = $this->decode($parts[2]);
683
+
684
+ if ($this->use & SERVICES_JSON_LOOSE_TYPE) {
685
+ $obj[$key] = $val;
686
+ } else {
687
+ $obj->$key = $val;
688
+ }
689
+ }
690
+
691
+ }
692
+
693
+ } elseif ((($chrs{$c} == '"') || ($chrs{$c} == "'")) && ($top['what'] != SERVICES_JSON_IN_STR)) {
694
+ // found a quote, and we are not inside a string
695
+ array_push($stk, array('what' => SERVICES_JSON_IN_STR, 'where' => $c, 'delim' => $chrs{$c}));
696
+ //print("Found start of string at {$c}\n");
697
+
698
+ } elseif (($chrs{$c} == $top['delim']) &&
699
+ ($top['what'] == SERVICES_JSON_IN_STR) &&
700
+ ((strlen(substr($chrs, 0, $c)) - strlen(rtrim(substr($chrs, 0, $c), '\\'))) % 2 != 1)) {
701
+ // found a quote, we're in a string, and it's not escaped
702
+ // we know that it's not escaped becase there is _not_ an
703
+ // odd number of backslashes at the end of the string so far
704
+ array_pop($stk);
705
+ //print("Found end of string at {$c}: ".substr($chrs, $top['where'], (1 + 1 + $c - $top['where']))."\n");
706
+
707
+ } elseif (($chrs{$c} == '[') &&
708
+ in_array($top['what'], array(SERVICES_JSON_SLICE, SERVICES_JSON_IN_ARR, SERVICES_JSON_IN_OBJ))) {
709
+ // found a left-bracket, and we are in an array, object, or slice
710
+ array_push($stk, array('what' => SERVICES_JSON_IN_ARR, 'where' => $c, 'delim' => false));
711
+ //print("Found start of array at {$c}\n");
712
+
713
+ } elseif (($chrs{$c} == ']') && ($top['what'] == SERVICES_JSON_IN_ARR)) {
714
+ // found a right-bracket, and we're in an array
715
+ array_pop($stk);
716
+ //print("Found end of array at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n");
717
+
718
+ } elseif (($chrs{$c} == '{') &&
719
+ in_array($top['what'], array(SERVICES_JSON_SLICE, SERVICES_JSON_IN_ARR, SERVICES_JSON_IN_OBJ))) {
720
+ // found a left-brace, and we are in an array, object, or slice
721
+ array_push($stk, array('what' => SERVICES_JSON_IN_OBJ, 'where' => $c, 'delim' => false));
722
+ //print("Found start of object at {$c}\n");
723
+
724
+ } elseif (($chrs{$c} == '}') && ($top['what'] == SERVICES_JSON_IN_OBJ)) {
725
+ // found a right-brace, and we're in an object
726
+ array_pop($stk);
727
+ //print("Found end of object at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n");
728
+
729
+ } elseif (($substr_chrs_c_2 == '/*') &&
730
+ in_array($top['what'], array(SERVICES_JSON_SLICE, SERVICES_JSON_IN_ARR, SERVICES_JSON_IN_OBJ))) {
731
+ // found a comment start, and we are in an array, object, or slice
732
+ array_push($stk, array('what' => SERVICES_JSON_IN_CMT, 'where' => $c, 'delim' => false));
733
+ $c++;
734
+ //print("Found start of comment at {$c}\n");
735
+
736
+ } elseif (($substr_chrs_c_2 == '*/') && ($top['what'] == SERVICES_JSON_IN_CMT)) {
737
+ // found a comment end, and we're in one now
738
+ array_pop($stk);
739
+ $c++;
740
+
741
+ for ($i = $top['where']; $i <= $c; ++$i)
742
+ $chrs = substr_replace($chrs, ' ', $i, 1);
743
+
744
+ //print("Found end of comment at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n");
745
+
746
+ }
747
+
748
+ }
749
+
750
+ if (reset($stk) == SERVICES_JSON_IN_ARR) {
751
+ return $arr;
752
+
753
+ } elseif (reset($stk) == SERVICES_JSON_IN_OBJ) {
754
+ return $obj;
755
+
756
+ }
757
+
758
+ }
759
+ }
760
+ }
761
+
762
+ function isError($data, $code = null)
763
+ {
764
+ if (is_object($data) && (get_class($data) == 'services_json_error' ||
765
+ is_subclass_of($data, 'services_json_error'))) {
766
+ return true;
767
+ }
768
+
769
+ return false;
770
+ }
771
+ }
772
+
773
+ class Services_JSON_Error
774
+ {
775
+ function Services_JSON_Error($message = 'unknown error', $code = null,
776
+ $mode = null, $options = null, $userinfo = null)
777
+ {
778
+
779
+ }
780
+ }
781
+
782
+ ?>
includes/vendor/campaign-monitor/class/transport.php ADDED
@@ -0,0 +1,335 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ define('CS_REST_GET', 'GET');
4
+ define('CS_REST_POST', 'POST');
5
+ define('CS_REST_PUT', 'PUT');
6
+ define('CS_REST_DELETE', 'DELETE');
7
+ if (false === defined('CS_REST_SOCKET_TIMEOUT')) {
8
+ define('CS_REST_SOCKET_TIMEOUT', 10);
9
+ }
10
+ if (false === defined('CS_REST_CALL_TIMEOUT')) {
11
+ define('CS_REST_CALL_TIMEOUT', 10);
12
+ }
13
+
14
+ function CS_REST_TRANSPORT_get_available($requires_ssl, $log) {
15
+ if(function_exists('curl_init') && function_exists('curl_exec')) {
16
+ return new CS_REST_CurlTransport($log);
17
+ } else if(CS_REST_TRANSPORT_can_use_raw_socket($requires_ssl)) {
18
+ return new CS_REST_SocketTransport($log);
19
+ } else {
20
+ $log->log_message('No transport is available', __FUNCTION__, CS_REST_LOG_ERROR);
21
+ trigger_error('No transport is available.'.
22
+ ($requires_ssl ? ' Try using non-secure (http) mode or ' : ' Please ').
23
+ 'ensure the cURL extension is loaded', E_USER_ERROR);
24
+ }
25
+ }
26
+ function CS_REST_TRANSPORT_can_use_raw_socket($requires_ssl) {
27
+ if(function_exists('fsockopen')) {
28
+ if($requires_ssl) {
29
+ return extension_loaded('openssl');
30
+ }
31
+
32
+ return true;
33
+ }
34
+
35
+ return false;
36
+ }
37
+ class CS_REST_BaseTransport {
38
+
39
+ var $_log;
40
+
41
+ function CS_REST_BaseTransport($log) {
42
+ $this->_log = $log;
43
+ }
44
+
45
+ function split_and_inflate($response, $may_be_compressed) {
46
+ $ra = explode("\r\n\r\n", $response);
47
+
48
+ $result = array_pop($ra);
49
+ $headers = array_pop($ra);
50
+
51
+ if($may_be_compressed && preg_match('/^Content-Encoding:\s+gzip\s+$/im', $headers)) {
52
+ $original_length = strlen($response);
53
+ $result = gzinflate(substr($result, 10, -8));
54
+
55
+ $this->_log->log_message('Inflated gzipped response: '.$original_length.' bytes ->'.
56
+ strlen($result).' bytes', get_class(), CS_REST_LOG_VERBOSE);
57
+ }
58
+
59
+ return array($headers, $result);
60
+ }
61
+ }
62
+ /**
63
+ * Provide HTTP request functionality via cURL extensions
64
+ *
65
+ * @author tobyb
66
+ * @since 1.0
67
+ */
68
+ class CS_REST_CurlTransport extends CS_REST_BaseTransport {
69
+
70
+ var $_curl_zlib;
71
+
72
+ function CS_REST_CurlTransport($log) {
73
+ $this->CS_REST_BaseTransport($log);
74
+
75
+ $curl_version = curl_version();
76
+ $this->_curl_zlib = isset($curl_version['libz_version']);
77
+ }
78
+
79
+ /**
80
+ * @return string The type of transport used
81
+ */
82
+ function get_type() {
83
+ return 'cURL';
84
+ }
85
+
86
+ function make_call($call_options) {
87
+ $ch = curl_init();
88
+
89
+ curl_setopt($ch, CURLOPT_URL, $call_options['route']);
90
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
91
+ curl_setopt($ch, CURLOPT_HEADER, true);
92
+ $headers = array();
93
+ $headers[] = 'Content-Type: '.$call_options['contentType'];
94
+
95
+
96
+ if (array_key_exists('authdetails', $call_options) &&
97
+ isset($call_options['authdetails'])) {
98
+ if (array_key_exists('username', $call_options['authdetails']) &&
99
+ array_key_exists('password', $call_options['authdetails'])) {
100
+ # Authenticating using basic auth for retrieving user's API key.
101
+ curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
102
+ curl_setopt($ch, CURLOPT_USERPWD, $call_options['authdetails']['username'].':'.$call_options['authdetails']['password']);
103
+ } elseif (array_key_exists('access_token', $call_options['authdetails'])) {
104
+ # Authenticating using OAuth.
105
+ $access_token = $call_options['authdetails']['access_token'];
106
+ $headers[] = 'Authorization: Bearer '.$access_token;
107
+ } elseif (array_key_exists('api_key', $call_options['authdetails'])) {
108
+ # Authenticating using an API key.
109
+ curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
110
+ $api_key = $call_options['authdetails']['api_key'];
111
+ curl_setopt($ch, CURLOPT_USERPWD, $api_key.':nopass');
112
+ }
113
+ }
114
+
115
+ curl_setopt($ch, CURLOPT_USERAGENT, $call_options['userAgent']);
116
+ curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, CS_REST_SOCKET_TIMEOUT);
117
+ curl_setopt($ch, CURLOPT_TIMEOUT, CS_REST_CALL_TIMEOUT);
118
+
119
+ $inflate_response = false;
120
+ if($this->_curl_zlib) {
121
+ $this->_log->log_message('curl+zlib support available. Requesting gzipped response.',
122
+ get_class($this), CS_REST_LOG_VERBOSE);
123
+ curl_setopt($ch, CURLOPT_ENCODING, 'gzip');
124
+ } else if(function_exists('gzinflate')) {
125
+ $headers[] = 'Accept-Encoding: gzip';
126
+ $inflate_response = true;
127
+ }
128
+
129
+ if($call_options['protocol'] === 'https') {
130
+ curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
131
+ curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
132
+
133
+ if(strlen(ini_get('curl.cainfo')) === 0) {
134
+ curl_setopt($ch, CURLOPT_CAINFO, dirname(__FILE__).'/cacert.pem');
135
+ }
136
+ }
137
+
138
+ switch($call_options['method']) {
139
+ case CS_REST_PUT:
140
+ curl_setopt($ch, CURLOPT_CUSTOMREQUEST, CS_REST_PUT);
141
+ $headers[] = 'Content-Length: '.strlen($call_options['data']);
142
+ curl_setopt($ch, CURLOPT_POSTFIELDS, $call_options['data']);
143
+ break;
144
+ case CS_REST_POST:
145
+ curl_setopt($ch, CURLOPT_POST, true);
146
+ curl_setopt($ch, CURLOPT_POSTFIELDS, isset($call_options['data']) ? $call_options['data'] : '');
147
+ break;
148
+ case CS_REST_DELETE:
149
+ curl_setopt($ch, CURLOPT_CUSTOMREQUEST, CS_REST_DELETE);
150
+ break;
151
+ }
152
+
153
+ if(count($headers) > 0) {
154
+ curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
155
+ }
156
+
157
+ $response = curl_exec($ch);
158
+
159
+ if(!$response && $response !== '') {
160
+ $this->_log->log_message('Error making request with curl_error: '.curl_errno($ch),
161
+ get_class($this), CS_REST_LOG_ERROR);
162
+ trigger_error('Error making request with curl_error: '.curl_error($ch), E_USER_ERROR);
163
+ }
164
+
165
+ list( $headers, $result ) = $this->split_and_inflate($response, $inflate_response);
166
+
167
+ $this->_log->log_message('API Call Info for '.$call_options['method'].' '.
168
+ curl_getinfo($ch, CURLINFO_EFFECTIVE_URL).': '.curl_getinfo($ch, CURLINFO_SIZE_UPLOAD).
169
+ ' bytes uploaded. '.curl_getinfo($ch, CURLINFO_SIZE_DOWNLOAD).' bytes downloaded'.
170
+ ' Total time (seconds): '.curl_getinfo($ch, CURLINFO_TOTAL_TIME),
171
+ get_class($this), CS_REST_LOG_VERBOSE);
172
+
173
+ $result = array(
174
+ 'code' => curl_getinfo($ch, CURLINFO_HTTP_CODE),
175
+ 'response' => $result
176
+ );
177
+
178
+ curl_close($ch);
179
+
180
+ return $result;
181
+ }
182
+ }
183
+
184
+ class CS_REST_SocketWrapper {
185
+ var $socket;
186
+
187
+ function open($domain, $port) {
188
+ $this->socket = fsockopen($domain, $port, $errno, $errstr, CS_REST_SOCKET_TIMEOUT);
189
+
190
+ if(!$this->socket) {
191
+ die('Error making request with '.$errno.': '.$errstr);
192
+ return false;
193
+ } else if(function_exists('stream_set_timeout')) {
194
+ stream_set_timeout($this->socket, CS_REST_SOCKET_TIMEOUT);
195
+ }
196
+
197
+ return true;
198
+ }
199
+
200
+ function write($data) {
201
+ fwrite($this->socket, $data);
202
+ }
203
+
204
+ function read() {
205
+ ob_start();
206
+ fpassthru($this->socket);
207
+
208
+ return ob_get_clean();
209
+ }
210
+
211
+ function close() {
212
+ fclose($this->socket);
213
+ }
214
+ }
215
+
216
+ class CS_REST_SocketTransport extends CS_REST_BaseTransport {
217
+
218
+ var $_socket_wrapper;
219
+
220
+ function CS_REST_SocketTransport($log, $socket_wrapper = NULL) {
221
+ $this->CS_REST_BaseTransport($log);
222
+
223
+ if(is_null($socket_wrapper)) {
224
+ $socket_wrapper = new CS_REST_SocketWrapper();
225
+ }
226
+
227
+ $this->_socket_wrapper = $socket_wrapper;
228
+ }
229
+
230
+ /**
231
+ * @return string The type of transport used
232
+ */
233
+ function get_type() {
234
+ return 'Socket';
235
+ }
236
+
237
+ function make_call($call_options) {
238
+ $start_host = strpos($call_options['route'], $call_options['host']);
239
+ $host_len = strlen($call_options['host']);
240
+
241
+ $domain = substr($call_options['route'], $start_host, $host_len);
242
+ $host = $domain;
243
+ $path = substr($call_options['route'], $start_host + $host_len);
244
+ $protocol = substr($call_options['route'], 0, $start_host);
245
+ $port = 80;
246
+
247
+ $this->_log->log_message('Creating socket to '.$domain.' over '.$protocol.' for request to '.$path,
248
+ get_class($this), CS_REST_LOG_VERBOSE);
249
+
250
+ if($protocol === 'https://') {
251
+ $domain = 'ssl://'.$domain;
252
+ $port = 443;
253
+ }
254
+
255
+ if($this->_socket_wrapper->open($domain, $port)) {
256
+ $inflate_response = function_exists('gzinflate');
257
+
258
+ $request = $this->_build_request($call_options, $host, $path, $inflate_response);
259
+ $this->_log->log_message('Sending <pre>'.$request.'</pre> down the socket',
260
+ get_class($this), CS_REST_LOG_VERBOSE);
261
+
262
+ $this->_socket_wrapper->write($request);
263
+ $response = $this->_socket_wrapper->read();
264
+ $this->_socket_wrapper->close();
265
+
266
+ $this->_log->log_message('API Call Info for '.$call_options['method'].' '.
267
+ $call_options['route'].': '.strlen($request).
268
+ ' bytes uploaded. '.strlen($response).' bytes downloaded',
269
+ get_class($this), CS_REST_LOG_VERBOSE);
270
+
271
+ list( $headers, $result ) = $this->split_and_inflate($response, $inflate_response);
272
+
273
+ $this->_log->log_message('Received headers <pre>'.$headers.'</pre>',
274
+ get_class($this), CS_REST_LOG_VERBOSE);
275
+
276
+ return array(
277
+ 'code' => $this->_get_status_code($headers),
278
+ 'response' => trim($result)
279
+ );
280
+ }
281
+ }
282
+
283
+ function _get_status_code($headers) {
284
+ if (preg_match('%^\s*HTTP/1\.1 (?P<code>\d{3})%', $headers, $regs)) {
285
+ $this->_log->log_message('Got HTTP Status Code: '.$regs['code'],
286
+ get_class($this), CS_REST_LOG_VERBOSE);
287
+ return $regs['code'];
288
+ }
289
+
290
+ $this->_log->log_message('Failed to get HTTP status code from request headers <pre>'.$headers.'</pre>',
291
+ get_class($this), CS_REST_LOG_ERROR);
292
+ trigger_error('Failed to get HTTP status code from request', E_USER_ERROR);
293
+ }
294
+
295
+ function _build_request($call_options, $host, $path, $accept_gzip) {
296
+ $request_auth_details = '';
297
+
298
+ if (array_key_exists('authdetails', $call_options)) {
299
+ if (array_key_exists('username', $call_options['authdetails']) &&
300
+ array_key_exists('password', $call_options['authdetails'])) {
301
+ # Authenticating using basic auth for retrieving user's API key.
302
+ $request_auth_details .= 'Authorization: Basic '.base64_encode($call_options['authdetails']['username'].':'.$call_options['authdetails']['password'])."\n";
303
+ } elseif (array_key_exists('access_token', $call_options['authdetails'])) {
304
+ # Authenticating using OAuth.
305
+ $access_token = $call_options['authdetails']['access_token'];
306
+ $request_auth_details .= 'Authorization: Bearer '.$access_token."\n";
307
+ } elseif (array_key_exists('api_key', $call_options['authdetails'])) {
308
+ # Authenticating using an API key.
309
+ $api_key = $call_options['authdetails']['api_key'];
310
+ $request_auth_details .= 'Authorization: Basic '.base64_encode($api_key.':nopass')."\n";
311
+ }
312
+ }
313
+
314
+ $request =
315
+ $call_options['method'].' '.$path." HTTP/1.1\n".
316
+ 'Host: '.$host."\n".
317
+ $request_auth_details.
318
+ 'User-Agent: '.$call_options['userAgent']."\n".
319
+ "Connection: Close\n".
320
+ 'Content-Type: '.$call_options['contentType']."\n";
321
+
322
+ if($accept_gzip) {
323
+ $request .=
324
+ "Accept-Encoding: gzip\n";
325
+ }
326
+
327
+ if(isset($call_options['data'])) {
328
+ $request .=
329
+ 'Content-Length: '.strlen($call_options['data'])."\n\n".
330
+ $call_options['data'];
331
+ }
332
+
333
+ return $request."\n\n";
334
+ }
335
+ }
includes/vendor/campaign-monitor/csrest_administrators.php ADDED
@@ -0,0 +1,108 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ require_once dirname(__FILE__).'/class/base_classes.php';
3
+
4
+ /**
5
+ * Class to access the administrator resources from the create send API.
6
+ * This class includes functions to add and remove administrators,
7
+ * along with getting details for a single administrator
8
+ * @author pauld
9
+ *
10
+ */
11
+ class CS_REST_Administrators extends CS_REST_Wrapper_Base {
12
+
13
+ /**
14
+ * The base route of the people resource.
15
+ * @var string
16
+ * @access private
17
+ */
18
+ var $_admins_base_route;
19
+
20
+ /**
21
+ * Constructor.
22
+ * @param $auth_details array Authentication details to use for API calls.
23
+ * This array must take one of the following forms:
24
+ * If using OAuth to authenticate:
25
+ * array(
26
+ * 'access_token' => 'your access token',
27
+ * 'refresh_token' => 'your refresh token')
28
+ *
29
+ * Or if using an API key:
30
+ * array('api_key' => 'your api key')
31
+ * @param $protocol string The protocol to use for requests (http|https)
32
+ * @param $debug_level int The level of debugging required CS_REST_LOG_NONE | CS_REST_LOG_ERROR | CS_REST_LOG_WARNING | CS_REST_LOG_VERBOSE
33
+ * @param $host string The host to send API requests to. There is no need to change this
34
+ * @param $log CS_REST_Log The logger to use. Used for dependency injection
35
+ * @param $serialiser The serialiser to use. Used for dependency injection
36
+ * @param $transport The transport to use. Used for dependency injection
37
+ * @access public
38
+ */
39
+ function CS_REST_Administrators (
40
+ $auth_details,
41
+ $protocol = 'https',
42
+ $debug_level = CS_REST_LOG_NONE,
43
+ $host = 'api.createsend.com',
44
+ $log = NULL,
45
+ $serialiser = NULL,
46
+ $transport = NULL) {
47
+
48
+ $this->CS_REST_Wrapper_Base($auth_details, $protocol, $debug_level, $host, $log, $serialiser, $transport);
49
+ $this->_admins_base_route = $this->_base_route.'admins';
50
+ }
51
+
52
+ /**
53
+ * Adds a new administrator to the current account
54
+ * @param array $admin The administrator details to use during creation.
55
+ * This array should be of the form
56
+ * array (
57
+ * 'EmailAddress' => The new administrator email address
58
+ * 'Name' => The name of the new administrator
59
+ * )
60
+ * @access public
61
+ * @return CS_REST_Wrapper_Result A successful response will be empty
62
+ */
63
+ function add($admin) {
64
+ return $this->post_request($this->_admins_base_route.'.json', $admin);
65
+ }
66
+
67
+ /**
68
+ * Updates details for an existing administrator associated with the current account
69
+ * @param string $email The email address of the administrator to be updated
70
+ * @param array $admin The updated administrator details to use for the update.
71
+ * This array should be of the form
72
+ * array (
73
+ * 'EmailAddress' => The new email address
74
+ * 'Name' => The updated name of the administrator
75
+ * )
76
+ * @access public
77
+ * @return CS_REST_Wrapper_Result A successful response will be empty
78
+ */
79
+ function update($email, $admin) {
80
+ return $this->put_request($this->_admins_base_route.'.json?email='.urlencode($email), $admin);
81
+ }
82
+
83
+ /**
84
+ * Gets the details for a specific administrator
85
+ * @access public
86
+ * @return CS_REST_Wrapper_Result A successful response will be an object of the form
87
+ * {
88
+ * 'EmailAddress' => The email address of the administrator
89
+ * 'Name' => The name of the administrator
90
+ * 'Status' => The status of the administrator
91
+ * )
92
+ * }
93
+ */
94
+ function get($email) {
95
+ return $this->get_request($this->_admins_base_route.'.json?email='.urlencode($email));
96
+ }
97
+
98
+
99
+ /**
100
+ * deletes the given administrator from the current account
101
+ * @param string $email The email address of the administrator to delete
102
+ * @access public
103
+ * @return CS_REST_Wrapper_Result A successful response will be empty
104
+ */
105
+ function delete($email) {
106
+ return $this->delete_request($this->_admins_base_route.'.json?email='.urlencode($email));
107
+ }
108
+ }
includes/vendor/campaign-monitor/csrest_campaigns.php ADDED
@@ -0,0 +1,439 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ require_once dirname(__FILE__).'/class/base_classes.php';
3
+
4
+ /**
5
+ * Class to access a campaigns resources from the create send API.
6
+ * This class includes functions to create and send campaigns,
7
+ * along with accessing lists of campaign specific resources i.e reporting statistics
8
+ * @author tobyb
9
+ *
10
+ */
11
+ class CS_REST_Campaigns extends CS_REST_Wrapper_Base {
12
+
13
+ /**
14
+ * The base route of the campaigns resource.
15
+ * @var string
16
+ * @access private
17
+ */
18
+ var $_campaigns_base_route;
19
+
20
+ /**
21
+ * Constructor.
22
+ * @param $campaign_id string The campaign id to access (Ignored for create requests)
23
+ * @param $auth_details array Authentication details to use for API calls.
24
+ * This array must take one of the following forms:
25
+ * If using OAuth to authenticate:
26
+ * array(
27
+ * 'access_token' => 'your access token',
28
+ * 'refresh_token' => 'your refresh token')
29
+ *
30
+ * Or if using an API key:
31
+ * array('api_key' => 'your api key')
32
+ * @param $protocol string The protocol to use for requests (http|https)
33
+ * @param $debug_level int The level of debugging required CS_REST_LOG_NONE | CS_REST_LOG_ERROR | CS_REST_LOG_WARNING | CS_REST_LOG_VERBOSE
34
+ * @param $host string The host to send API requests to. There is no need to change this
35
+ * @param $log CS_REST_Log The logger to use. Used for dependency injection
36
+ * @param $serialiser The serialiser to use. Used for dependency injection
37
+ * @param $transport The transport to use. Used for dependency injection
38
+ * @access public
39
+ */
40
+ function CS_REST_Campaigns (
41
+ $campaign_id,
42
+ $auth_details,
43
+ $protocol = 'https',
44
+ $debug_level = CS_REST_LOG_NONE,
45
+ $host = 'api.createsend.com',
46
+ $log = NULL,
47
+ $serialiser = NULL,
48
+ $transport = NULL) {
49
+
50
+ $this->CS_REST_Wrapper_Base($auth_details, $protocol, $debug_level, $host, $log, $serialiser, $transport);
51
+ $this->set_campaign_id($campaign_id);
52
+ }
53
+
54
+ /**
55
+ * Change the campaign id used for calls after construction
56
+ * @param $campaign_id
57
+ * @access public
58
+ */
59
+ function set_campaign_id($campaign_id) {
60
+ $this->_campaigns_base_route = $this->_base_route.'campaigns/'.$campaign_id.'/';
61
+ }
62
+
63
+ /**
64
+ * Creates a new campaign based on the provided campaign info.
65
+ * At least on of the ListIDs and Segments parameters must be provided
66
+ * @param string $client_id The client to create the campaign for
67
+ * @param array $campaign_info The campaign information to use during creation.
68
+ * This array should be of the form
69
+ * array(
70
+ * 'Subject' => string required The campaign subject
71
+ * 'Name' => string required The campaign name
72
+ * 'FromName' => string required The From name for the campaign
73
+ * 'FromEmail' => string required The From address for the campaign
74
+ * 'ReplyTo' => string required The Reply-To address for the campaign
75
+ * 'HtmlUrl' => string required A url to download the campaign HTML from
76
+ * 'TextUrl' => string optional A url to download the campaign
77
+ * text version from. If not provided, text content will be
78
+ * automatically generated from HTML content.
79
+ * 'ListIDs' => array<string> optional An array of list ids to send the campaign to
80
+ * 'SegmentIDs' => array<string> optional An array of segment ids to send the campaign to.
81
+ * )
82
+ * @access public
83
+ * @return CS_REST_Wrapper_Result A successful response will be the ID of the newly created campaign
84
+ */
85
+ function create($client_id, $campaign_info) {
86
+ return $this->post_request($this->_base_route.'campaigns/'.$client_id.'.json', $campaign_info);
87
+ }
88
+
89
+ /**
90
+ * Creates a new campaign from a template based on the info provided.
91
+ * At least on of the ListIDs and Segments parameters must be provided
92
+ * @param string $client_id The client to create the campaign for
93
+ * @param array $campaign_info The campaign information to use during creation.
94
+ * This array should be of the form
95
+ * array(
96
+ * 'Subject' => string required The campaign subject
97
+ * 'Name' => string required The campaign name
98
+ * 'FromName' => string required The From name for the campaign
99
+ * 'FromEmail' => string required The From address for the campaign
100
+ * 'ReplyTo' => string required The Reply-To address for the campaign
101
+ * 'ListIDs' => array<string> optional An array of list ids to send the campaign to
102
+ * 'SegmentIDs' => array<string> optional An array of segment ids to send the campaign to
103
+ * 'TemplateID' => string required The ID of the template to use
104
+ * 'TemplateContent' => array required The content which will be used to fill the editable areas of the template
105
+ * )
106
+ * @access public
107
+ * @return CS_REST_Wrapper_Result A successful response will be the ID of the newly created campaign
108
+ */
109
+ function create_from_template($client_id, $campaign_info) {
110
+ return $this->post_request($this->_base_route.'campaigns/'.$client_id.'/fromtemplate.json', $campaign_info);
111
+ }
112
+
113
+ /**
114
+ * Sends a preview of an existing campaign to the specified recipients.
115
+ * @param array<string> $recipients The recipients to send the preview to.
116
+ * @param string $personalize How to personalize the campaign content. Valid options are:
117
+ * 'Random': Choose a random campaign recipient and use their personalisation data
118
+ * 'Fallback': Use the fallback terms specified in the campaign content
119
+ * @access public
120
+ * @return CS_REST_Wrapper_Result A successful response will be empty
121
+ */
122
+ function send_preview($recipients, $personalize = 'Random') {
123
+ $preview_data = array(
124
+ 'PreviewRecipients' => $recipients,
125
+ 'Personalize' => $personalize
126
+ );
127
+
128
+ return $this->post_request($this->_campaigns_base_route.'sendpreview.json', $preview_data);
129
+ }
130
+
131
+ /**
132
+ * Sends an existing campaign based on the scheduling information provided
133
+ * @param array $schedule The campaign scheduling information.
134
+ * This array should be of the form
135
+ * array (
136
+ * 'ConfirmationEmail' => string required The email address to send a confirmation email to,
137
+ * 'SendDate' => string required The date to send the campaign or 'immediately'.
138
+ * The date should be in the format 'y-M-d'
139
+ * )
140
+ * @access public
141
+ * @return CS_REST_Wrapper_Result A successful response will be empty
142
+ */
143
+ function send($schedule) {
144
+ return $this->post_request($this->_campaigns_base_route.'send.json', $schedule);
145
+ }
146
+
147
+ /**
148
+ * Unschedules the campaign, moving it back into the drafts. If the campaign has been sent or is
149
+ * in the process of sending, this api request will fail.
150
+ * @access public
151
+ * @return CS_REST_Wrapper_Result A successful response will be empty
152
+ */
153
+ function unschedule() {
154
+ return $this->post_request($this->_campaigns_base_route.'unschedule.json', NULL);
155
+ }
156
+
157
+ /**
158
+ * Deletes an existing campaign from the system
159
+ * @access public
160
+ * @return CS_REST_Wrapper_Result A successful response will be empty
161
+ */
162
+ function delete() {
163
+ return $this->delete_request(trim($this->_campaigns_base_route, '/').'.json');
164
+ }
165
+
166
+ /**
167
+ * Gets all email addresses on the current clients suppression list
168
+ * @param int $page_number The page number to get
169
+ * @param int $page_size The number of records per page
170
+ * @param string $order_field The field to order the record set by ('EMAIL', 'LIST')
171
+ * @param string $order_direction The direction to order the record set ('ASC', 'DESC')
172
+ * @access public
173
+ * @return CS_REST_Wrapper_Result A successful response will be an object of the form
174
+ * {
175
+ * 'ResultsOrderedBy' => The field the results are ordered by
176
+ * 'OrderDirection' => The order direction
177
+ * 'PageNumber' => The page number for the result set
178
+ * 'PageSize' => The page size used
179
+ * 'RecordsOnThisPage' => The number of records returned
180
+ * 'TotalNumberOfRecords' => The total number of records available
181
+ * 'NumberOfPages' => The total number of pages for this collection
182
+ * 'Results' => array(
183
+ * {
184
+ * 'EmailAddress' => The suppressed email address
185
+ * 'ListID' => The ID of the list this subscriber comes from
186
+ * }
187
+ * )
188
+ * }
189
+ */
190
+ function get_recipients($page_number = NULL, $page_size = NULL, $order_field = NULL,
191
+ $order_direction = NULL) {
192
+ return $this->get_request_paged($this->_campaigns_base_route.'recipients.json', $page_number,
193
+ $page_size, $order_field, $order_direction, '?');
194
+ }
195
+
196
+ /**
197
+ * Gets all bounces recorded for a campaign
198
+ * @param string $since The date to start getting bounces from
199
+ * @param int $page_number The page number to get
200
+ * @param int $page_size The number of records per page
201
+ * @param string $order_field The field to order the record set by ('EMAIL', 'LIST', 'DATE')
202
+ * @param string $order_direction The direction to order the record set ('ASC', 'DESC')
203
+ * @access public
204
+ * @return CS_REST_Wrapper_Result A successful response will be an object of the form
205
+ * {
206
+ * 'ResultsOrderedBy' => The field the results are ordered by
207
+ * 'OrderDirection' => The order direction
208
+ * 'PageNumber' => The page number for the result set
209
+ * 'PageSize' => The page size used
210
+ * 'RecordsOnThisPage' => The number of records returned
211
+ * 'TotalNumberOfRecords' => The total number of records available
212
+ * 'NumberOfPages' => The total number of pages for this collection
213
+ * 'Results' => array(
214
+ * {
215
+ * 'EmailAddress' => The email that bounced
216
+ * 'ListID' => The ID of the list the subscriber was on
217
+ * 'BounceType' => The type of bounce
218
+ * 'Date' => The date the bounce message was received
219
+ * 'Reason' => The reason for the bounce
220
+ * }
221
+ * )
222
+ * }
223
+ * )
224
+ */
225
+ function get_bounces($since = '', $page_number = NULL, $page_size = NULL, $order_field = NULL,
226
+ $order_direction = NULL) {
227
+ return $this->get_request_paged($this->_campaigns_base_route.'bounces.json?date='.urlencode($since),
228
+ $page_number, $page_size, $order_field, $order_direction);
229
+ }
230
+
231
+ /**
232
+ * Gets the lists a campaign was sent to
233
+ * @access public
234
+ * @return CS_REST_Wrapper_Result A successful response will be an object of the form
235
+ * {
236
+ * 'Lists' => array(
237
+ * {
238
+ * 'ListID' => The list id
239
+ * 'Name' => The list name
240
+ * }
241
+ * ),
242
+ * 'Segments' => array(
243
+ * {
244
+ * 'ListID' => The list id of the segment
245
+ * 'SegmentID' => The id of the segment
246
+ * 'Title' => The title of the segment
247
+ * }
248
+ * )
249
+ * }
250
+ */
251
+ function get_lists_and_segments() {
252
+ return $this->get_request($this->_campaigns_base_route.'listsandsegments.json');
253
+ }
254
+
255
+ /**
256
+ * Gets a summary of all campaign reporting statistics
257
+ * @access public
258
+ * @return CS_REST_Wrapper_Result A successful response will be an object of the form
259
+ * {
260
+ * 'Recipients' => The total recipients of the campaign
261
+ * 'TotalOpened' => The total number of opens recorded
262
+ * 'Clicks' => The total number of recorded clicks
263
+ * 'Unsubscribed' => The number of recipients who unsubscribed
264
+ * 'Bounced' => The number of recipients who bounced
265
+ * 'UniqueOpened' => The number of recipients who opened
266
+ * 'WebVersionURL' => The url of the web version of the campaign
267
+ * 'WebVersionTextURL' => The url of the web version of the text version of the campaign
268
+ * 'WorldviewURL' => The public Worldview URL for the campaign
269
+ * 'Forwards' => The number of times the campaign has been forwarded to a friend
270
+ * 'Likes' => The number of times the campaign has been 'liked' on Facebook
271
+ * 'Mentions' => The number of times the campaign has been tweeted about
272
+ * 'SpamComplaints' => The number of recipients who marked the campaign as spam
273
+ * }
274
+ */
275
+ function get_summary() {
276
+ return $this->get_request($this->_campaigns_base_route.'summary.json');
277
+ }
278
+
279
+ /**
280
+ * Gets the email clients that subscribers used to open the campaign
281
+ * @access public
282
+ * @return CS_REST_Wrapper_Result A successful response will be an object of the form
283
+ * array(
284
+ * {
285
+ * Client => The email client name
286
+ * Version => The email client version
287
+ * Percentage => The percentage of subscribers who used this email client
288
+ * Subscribers => The actual number of subscribers who used this email client
289
+ * }
290
+ * )
291
+ */
292
+ function get_email_client_usage() {
293
+ return $this->get_request($this->_campaigns_base_route.'emailclientusage.json');
294
+ }
295
+
296
+ /**
297
+ * Gets all opens recorded for a campaign since the provided date
298
+ * @param string $since The date to start getting opens from
299
+ * @param int $page_number The page number to get
300
+ * @param int $page_size The number of records per page
301
+ * @param string $order_field The field to order the record set by ('EMAIL', 'LIST', 'DATE')
302
+ * @param string $order_direction The direction to order the record set ('ASC', 'DESC')
303
+ * @access public
304
+ * @return CS_REST_Wrapper_Result A successful response will be an object of the form
305
+ * {
306
+ * 'ResultsOrderedBy' => The field the results are ordered by
307
+ * 'OrderDirection' => The order direction
308
+ * 'PageNumber' => The page number for the result set
309
+ * 'PageSize' => The page size used
310
+ * 'RecordsOnThisPage' => The number of records returned
311
+ * 'TotalNumberOfRecords' => The total number of records available
312
+ * 'NumberOfPages' => The total number of pages for this collection
313
+ * 'Results' => array(
314
+ * {
315
+ * 'EmailAddress' => The email address of the subscriber who opened
316
+ * 'ListID' => The list id of the list containing the subscriber
317
+ * 'Date' => The date of the open
318
+ * 'IPAddress' => The ip address where the open originated
319
+ * 'Latitude' => The geocoded latitude from the IP address
320
+ * 'Longitude' => The geocoded longitude from the IP address
321
+ * 'City' => The geocoded city from the IP address
322
+ * 'Region' => The geocoded region from the IP address
323
+ * 'CountryCode' => The geocoded two letter country code from the IP address
324
+ * 'CountryName' => The geocoded full country name from the IP address
325
+ * }
326
+ * )
327
+ * }
328
+ */
329
+ function get_opens($since = '', $page_number = NULL, $page_size = NULL, $order_field = NULL,
330
+ $order_direction = NULL) {
331
+ return $this->get_request_paged($this->_campaigns_base_route.'opens.json?date='.urlencode($since),
332
+ $page_number, $page_size, $order_field, $order_direction);
333
+ }
334
+
335
+ /**
336
+ * Gets all clicks recorded for a campaign since the provided date
337
+ * @param string $since The date to start getting clicks from
338
+ * @param int $page_number The page number to get
339
+ * @param int $page_size The number of records per page
340
+ * @param string $order_field The field to order the record set by ('EMAIL', 'LIST', 'DATE')
341
+ * @param string $order_direction The direction to order the record set ('ASC', 'DESC')
342
+ * @access public
343
+ * @return CS_REST_Wrapper_Result A successful response will be an object of the form
344
+ * {
345
+ * 'ResultsOrderedBy' => The field the results are ordered by
346
+ * 'OrderDirection' => The order direction
347
+ * 'PageNumber' => The page number for the result set
348
+ * 'PageSize' => The page size used
349
+ * 'RecordsOnThisPage' => The number of records returned
350
+ * 'TotalNumberOfRecords' => The total number of records available
351
+ * 'NumberOfPages' => The total number of pages for this collection
352
+ * 'Results' => array(
353
+ * {
354
+ * 'EmailAddress' => The email address of the subscriber who clicked
355
+ * 'ListID' => The list id of the list containing the subscriber
356
+ * 'Date' => The date of the click
357
+ * 'IPAddress' => The ip address where the click originated
358
+ * 'URL' => The url that the subscriber clicked on
359
+ * 'Latitude' => The geocoded latitude from the IP address
360
+ * 'Longitude' => The geocoded longitude from the IP address
361
+ * 'City' => The geocoded city from the IP address
362
+ * 'Region' => The geocoded region from the IP address
363
+ * 'CountryCode' => The geocoded two letter country code from the IP address
364
+ * 'CountryName' => The geocoded full country name from the IP address
365
+ * }
366
+ * )
367
+ * }
368
+ */
369
+ function get_clicks($since = '', $page_number = NULL, $page_size = NULL, $order_field = NULL,
370
+ $order_direction = NULL) {
371
+ return $this->get_request_paged($this->_campaigns_base_route.'clicks.json?date='.urlencode($since),
372
+ $page_number, $page_size, $order_field, $order_direction);
373
+ }
374
+
375
+ /**
376
+ * Gets all unsubscribes recorded for a campaign since the provided date
377
+ * @param string $since The date to start getting unsubscribes from
378
+ * @param int $page_number The page number to get
379
+ * @param int $page_size The number of records per page
380
+ * @param string $order_field The field to order the record set by ('EMAIL', 'LIST', 'DATE')
381
+ * @param string $order_direction The direction to order the record set ('ASC', 'DESC')
382
+ * @access public
383
+ * @return CS_REST_Wrapper_Result A successful response will be an object of the form
384
+ * {
385
+ * 'ResultsOrderedBy' => The field the results are ordered by
386
+ * 'OrderDirection' => The order direction
387
+ * 'PageNumber' => The page number for the result set
388
+ * 'PageSize' => The page size used
389
+ * 'RecordsOnThisPage' => The number of records returned
390
+ * 'TotalNumberOfRecords' => The total number of records available
391
+ * 'NumberOfPages' => The total number of pages for this collection
392
+ * 'Results' => array(
393
+ * {
394
+ * 'EmailAddress' => The email address of the subscriber who unsubscribed
395
+ * 'ListID' => The list id of the list containing the subscriber
396
+ * 'Date' => The date of the unsubscribe
397
+ * 'IPAddress' => The ip address where the unsubscribe originated
398
+ * }
399
+ * )
400
+ * }
401
+ */
402
+ function get_unsubscribes($since = '', $page_number = NULL, $page_size = NULL, $order_field = NULL,
403
+ $order_direction = NULL) {
404
+ return $this->get_request_paged($this->_campaigns_base_route.'unsubscribes.json?date='.urlencode($since),
405
+ $page_number, $page_size, $order_field, $order_direction);
406
+ }
407
+
408
+ /**
409
+ * Gets all spam complaints recorded for a campaign since the provided date
410
+ * @param string $since The date to start getting spam complaints from
411
+ * @param int $page_number The page number to get
412
+ * @param int $page_size The number of records per page
413
+ * @param string $order_field The field to order the record set by ('EMAIL', 'LIST', 'DATE')
414
+ * @param string $order_direction The direction to order the record set ('ASC', 'DESC')
415
+ * @access public
416
+ * @return CS_REST_Wrapper_Result A successful response will be an object of the form
417
+ * {
418
+ * 'ResultsOrderedBy' => The field the results are ordered by
419
+ * 'OrderDirection' => The order direction
420
+ * 'PageNumber' => The page number for the result set
421
+ * 'PageSize' => The page size used
422
+ * 'RecordsOnThisPage' => The number of records returned
423
+ * 'TotalNumberOfRecords' => The total number of records available
424
+ * 'NumberOfPages' => The total number of pages for this collection
425
+ * 'Results' => array(
426
+ * {
427
+ * 'EmailAddress' => The email address of the subscriber who unsubscribed
428
+ * 'ListID' => The list id of the list containing the subscriber
429
+ * 'Date' => The date of the unsubscribe
430
+ * }
431
+ * )
432
+ * }
433
+ */
434
+ function get_spam($since = '', $page_number = NULL, $page_size = NULL, $order_field = NULL,
435
+ $order_direction = NULL) {
436
+ return $this->get_request_paged($this->_campaigns_base_route.'spam.json?date='.urlencode($since),
437
+ $page_number, $page_size, $order_field, $order_direction);
438
+ }
439
+ }
includes/vendor/campaign-monitor/csrest_clients.php ADDED
@@ -0,0 +1,450 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ require_once dirname(__FILE__).'/class/base_classes.php';
3
+
4
+ /**
5
+ * Class to access a clients resources from the create send API.
6
+ * This class includes functions to create and edit clients,
7
+ * along with accessing lists of client specific resources e.g campaigns
8
+ * @author tobyb
9
+ *
10
+ */
11
+ class CS_REST_Clients extends CS_REST_Wrapper_Base {
12
+
13
+ /**
14
+ * The base route of the clients resource.
15
+ * @var string
16
+ * @access private
17
+ */
18
+ var $_clients_base_route;
19
+
20
+ /**
21
+ * Constructor.
22
+ * @param $client_id string The client id to access (Ignored for create requests)
23
+ * @param $auth_details array Authentication details to use for API calls.
24
+ * This array must take one of the following forms:
25
+ * If using OAuth to authenticate:
26
+ * array(
27
+ * 'access_token' => 'your access token',
28
+ * 'refresh_token' => 'your refresh token')
29
+ *
30
+ * Or if using an API key:
31
+ * array('api_key' => 'your api key')
32
+ * @param $protocol string The protocol to use for requests (http|https)
33
+ * @param $debug_level int The level of debugging required CS_REST_LOG_NONE | CS_REST_LOG_ERROR | CS_REST_LOG_WARNING | CS_REST_LOG_VERBOSE
34
+ * @param $host string The host to send API requests to. There is no need to change this
35
+ * @param $log CS_REST_Log The logger to use. Used for dependency injection
36
+ * @param $serialiser The serialiser to use. Used for dependency injection
37
+ * @param $transport The transport to use. Used for dependency injection
38
+ * @access public
39
+ */
40
+ function CS_REST_Clients(
41
+ $client_id,
42
+ $auth_details,
43
+ $protocol = 'https',
44
+ $debug_level = CS_REST_LOG_NONE,
45
+ $host = 'api.createsend.com',
46
+ $log = NULL,
47
+ $serialiser = NULL,
48
+ $transport = NULL) {
49
+
50
+ $this->CS_REST_Wrapper_Base($auth_details, $protocol, $debug_level, $host, $log, $serialiser, $transport);
51
+ $this->set_client_id($client_id);
52
+ }
53
+
54
+ /**
55
+ * Change the client id used for calls after construction
56
+ * @param $client_id
57
+ * @access public
58
+ */
59
+ function set_client_id($client_id) {
60
+ $this->_clients_base_route = $this->_base_route.'clients/'.$client_id.'/';
61
+ }
62
+
63
+ /**
64
+ * Gets a list of sent campaigns for the current client
65
+ * @access public
66
+ * @return CS_REST_Wrapper_Result A successful response will be an object of the form
67
+ * array(
68
+ * {
69
+ * 'WebVersionURL' => The web version url of the campaign
70
+ * 'WebVersionTextURL' => The web version url of the text version of the campaign
71
+ * 'CampaignID' => The id of the campaign
72
+ * 'Subject' => The campaign subject
73
+ * 'Name' => The name of the campaign
74
+ * 'FromName' => The from name for the campaign
75
+ * 'FromEmail' => The from email address for the campaign
76
+ * 'ReplyTo' => The reply to email address for the campaign
77
+ * 'SentDate' => The sent data of the campaign
78
+ * 'TotalRecipients' => The number of recipients of the campaign
79
+ * }
80
+ * )
81
+ */
82
+ function get_campaigns() {
83
+ return $this->get_request($this->_clients_base_route.'campaigns.json');
84
+ }
85
+
86
+ /**
87
+ * Gets a list of scheduled campaigns for the current client
88
+ * @access public
89
+ * @return CS_REST_Wrapper_Result A successful response will be an object of the form
90
+ * array(
91
+ * {
92
+ * 'CampaignID' => The id of the campaign
93
+ * 'Name' => The name of the campaign
94
+ * 'Subject' => The subject of the campaign
95
+ * 'FromName' => The from name for the campaign
96
+ * 'FromEmail' => The from email address for the campaign
97
+ * 'ReplyTo' => The reply to email address for the campaign
98
+ * 'DateCreated' => The date the campaign was created
99
+ * 'PreviewURL' => The preview url of the campaign
100
+ * 'PreviewTextURL' => The preview url of the text version of the campaign
101
+ * 'DateScheduled' => The date the campaign is scheduled to be sent
102
+ * 'ScheduledTimeZone' => The time zone in which the campaign is scheduled to be sent at 'DateScheduled'
103
+ * }
104
+ * )
105
+ */
106
+ function get_scheduled() {
107
+ return $this->get_request($this->_clients_base_route.'scheduled.json');
108
+ }
109
+
110
+ /**
111
+ * Gets a list of draft campaigns for the current client
112
+ * @access public
113
+ * @return CS_REST_Wrapper_Result A successful response will be an object of the form
114
+ * array(
115
+ * {
116
+ * 'CampaignID' => The id of the campaign
117
+ * 'Name' => The name of the campaign
118
+ * 'Subject' => The subject of the campaign
119
+ * 'FromName' => The from name for the campaign
120
+ * 'FromEmail' => The from email address for the campaign
121
+ * 'ReplyTo' => The reply to email address for the campaign
122
+ * 'DateCreated' => The date the campaign was created
123
+ * 'PreviewURL' => The preview url of the draft campaign
124
+ * 'PreviewTextURL' => The preview url of the text version of the campaign
125
+ * }
126
+ * )
127
+ */
128
+ function get_drafts() {
129
+ return $this->get_request($this->_clients_base_route.'drafts.json');
130
+ }
131
+
132
+ /**
133
+ * Gets all subscriber lists the current client has created
134
+ * @access public
135
+ * @return CS_REST_Wrapper_Result A successful response will be an object of the form
136
+ * array(
137
+ * {
138
+ * 'ListID' => The id of the list
139
+ * 'Name' => The name of the list
140
+ * }
141
+ * )
142
+ */
143
+ function get_lists() {
144
+ return $this->get_request($this->_clients_base_route.'lists.json');
145
+ }
146
+
147
+ /**
148
+ * Gets the lists across a client to which a subscriber with a particular
149
+ * email address belongs.
150
+ * @param string $email_address Subscriber's email address.
151
+ * @access public
152
+ * @return CS_REST_Wrapper_Result A successful response will be an object of the form
153
+ * array(
154
+ * {
155
+ * 'ListID' => The id of the list
156
+ * 'ListName' => The name of the list
157
+ * 'SubscriberState' => The state of the subscriber in the list
158
+ * 'DateSubscriberAdded' => The date the subscriber was added
159
+ * }
160
+ * )
161
+ */
162
+ function get_lists_for_email($email_address) {
163
+ return $this->get_request($this->_clients_base_route .
164
+ 'listsforemail.json?email='.urlencode($email_address));
165
+ }
166
+
167
+ /**
168
+ * Gets all list segments the current client has created
169
+ * @access public
170
+ * @return CS_REST_Wrapper_Result A successful response will be an object of the form
171
+ * array(
172
+ * {
173
+ * 'ListID' => The id of the list owning this segment
174
+ * 'SegmentID' => The id of this segment
175
+ * 'Title' => The title of this segment
176
+ * }
177
+ * )
178
+ */
179
+ function get_segments() {
180
+ return $this->get_request($this->_clients_base_route.'segments.json');
181
+ }
182
+
183
+ /**
184
+ * Gets all email addresses on the current client's suppression list
185
+ * @param int $page_number The page number to get
186
+ * @param int $page_size The number of records per page
187
+ * @param string $order_field The field to order the record set by ('EMAIL', 'DATE')
188
+ * @param string $order_direction The direction to order the record set ('ASC', 'DESC')
189
+ * @access public
190
+ * @return CS_REST_Wrapper_Result A successful response will be an object of the form
191
+ * {
192
+ * 'ResultsOrderedBy' => The field the results are ordered by
193
+ * 'OrderDirection' => The order direction
194
+ * 'PageNumber' => The page number for the result set
195
+ * 'PageSize' => The page size used
196
+ * 'RecordsOnThisPage' => The number of records returned
197
+ * 'TotalNumberOfRecords' => The total number of records available
198
+ * 'NumberOfPages' => The total number of pages for this collection
199
+ * 'Results' => array(
200
+ * {
201
+ * 'EmailAddress' => The suppressed email address
202
+ * 'Date' => The date the email was suppressed
203
+ * 'State' => The state of the suppressed email
204
+ * }
205
+ * )
206
+ * }
207
+ */
208
+ function get_suppressionlist($page_number = NULL, $page_size = NULL, $order_field = NULL,
209
+ $order_direction = NULL) {
210
+
211
+ return $this->get_request_paged($this->_clients_base_route.'suppressionlist.json',
212
+ $page_number, $page_size, $order_field, $order_direction, '?');
213
+ }
214
+
215
+ /**
216
+ * Adds email addresses to a client's suppression list.
217
+ * @param array<string> $emails The email addresses to suppress.
218
+ * @access public
219
+ */
220
+ function suppress($emails) {
221
+ $data = array('EmailAddresses' => $emails);
222
+ return $this->post_request($this->_clients_base_route.'suppress.json', $data);
223
+ }
224
+
225
+ /**
226
+ * Unsuppresses an email address by removing it from the the client's
227
+ * suppression list.
228
+ * @param string $email The email address to be unsuppressed
229
+ * @access public
230
+ */
231
+ function unsuppress($email) {
232
+ return $this->put_request($this->_clients_base_route.'unsuppress.json?email=' . urlencode($email), '');
233
+ }
234
+
235
+ /**
236
+ * Gets all templates the current client has access to
237
+ * @access public
238
+ * @return CS_REST_Wrapper_Result A successful response will be an object of the form
239
+ * array(
240
+ * {
241
+ * 'TemplateID' => The id of the template
242
+ * 'Name' => The name of the template
243
+ * 'PreviewURL' => The url to preview the template from
244
+ * 'ScreenshotURL' => The url of the template screenshot
245
+ * }
246
+ * )
247
+ */
248
+ function get_templates() {
249
+ return $this->get_request($this->_clients_base_route.'templates.json');
250
+ }
251
+
252
+ /**
253
+ * Gets all templates the current client has access to
254
+ * @access public
255
+ * @return CS_REST_Wrapper_Result A successful response will be an object of the form
256
+ * {
257
+ * 'ApiKey' => The clients API Key, THIS IS NOT THE CLIENT ID
258
+ * 'BasicDetails' =>
259
+ * {
260
+ * 'ClientID' => The id of the client
261
+ * 'CompanyName' => The company name of the client
262
+ * 'ContactName' => The contact name of the client
263
+ * 'EmailAddress' => The clients contact email address
264
+ * 'Country' => The clients country
265
+ * 'TimeZone' => The clients timezone
266
+ * }
267
+ * 'BillingDetails' =>
268
+ * If on monthly billing
269
+ * {
270
+ * 'CurrentTier' => The current monthly tier the client sits in
271
+ * 'CurrentMonthlyRate' => The current pricing rate the client pays per month
272
+ * 'MarkupPercentage' => The percentage markup applied to the base rates
273
+ * 'Currency' => The currency paid in
274
+ * 'ClientPays' => Whether the client pays for themselves,
275
+ * 'MonthlyScheme' => Basic or Unlimited
276
+ * }
277
+ * If paying per campaign
278
+ * {
279
+ * 'CanPurchaseCredits' => Whether the client can purchase credits
280
+ * 'Credits' => The number of credits belonging to the client
281
+ * 'BaseDeliveryFee' => The base fee payable per campaign
282
+ * 'BaseRatePerRecipient' => The base fee payable per campaign recipient
283
+ * 'BaseDesignSpamTestRate' => The base fee payable per design and spam test
284
+ * 'MarkupOnDelivery' => The markup applied per campaign
285
+ * 'MarkupPerRecipient' => The markup applied per campaign recipient
286
+ * 'MarkupOnDesignSpamTest' => The markup applied per design and spam test
287
+ * 'Currency' => The currency fees are paid in
288
+ * 'ClientPays' => Whether client client pays for themselves
289
+ * }
290
+ * }
291
+ */
292
+ function get() {
293
+ return $this->get_request(trim($this->_clients_base_route, '/').'.json');
294
+ }
295
+
296
+ /**
297
+ * Deletes an existing client from the system
298
+ * @access public
299
+ * @return CS_REST_Wrapper_Result A successful response will be empty
300
+ */
301
+ function delete() {
302
+ return $this->delete_request(trim($this->_clients_base_route, '/').'.json');
303
+ }
304
+
305
+ /**
306
+ * Creates a new client based on the provided information
307
+ * @param array $client Basic information of the new client.
308
+ * This should be an array of the form
309
+ * array(
310
+ * 'CompanyName' => The company name of the client
311
+ * 'Country' => The clients country
312
+ * 'TimeZone' => The clients timezone
313
+ * )
314
+ * @access public
315
+ * @return CS_REST_Wrapper_Result A successful response will be the ID of the newly created client
316
+ */
317
+ function create($client) {
318
+ if(isset($client['ContactName'])) {
319
+ trigger_error('[DEPRECATION] Use Person->add to set name on a new person in a client. For now, we will create a default person with the name provided.', E_USER_NOTICE);
320
+ }
321
+ if(isset($client['EmailAddress'])) {
322
+ trigger_error('[DEPRECATION] Use Person->add to set email on a new person in a client. For now, we will create a default person with the email provided.', E_USER_NOTICE);
323
+ }
324
+ return $this->post_request($this->_base_route.'clients.json', $client);
325
+ }
326
+
327
+ /**
328
+ * Updates the basic information for a client
329
+ * @param array $client_basics Basic information of the client.
330
+ * This should be an array of the form
331
+ * array(
332
+ * 'CompanyName' => The company name of the client
333
+ * 'Country' => The clients country
334
+ * 'TimeZone' => The clients timezone
335
+ * )
336
+ * @access public
337
+ * @return CS_REST_Wrapper_Result A successful response will be empty
338
+ */
339
+ function set_basics($client_basics) {
340
+ if(isset($client['ContactName'])) {
341
+ trigger_error('[DEPRECATION] Use person->update to set name on a particular person in a client. For now, we will update the default person with the name provided.', E_USER_NOTICE);
342
+ }
343
+ if(isset($client['EmailAddress'])) {
344
+ trigger_error('[DEPRECATION] Use person->update to set email on a particular person in a client. For now, we will update the default person with the email address provided.', E_USER_NOTICE);
345
+ }
346
+ return $this->put_request($this->_clients_base_route.'setbasics.json', $client_basics);
347
+ }
348
+
349
+ /**
350
+ * Updates the billing details of the current client, setting the client to the payg billing model
351
+ * For clients not set to pay themselves then all fields below ClientPays are ignored
352
+ * All Markup fields are optional
353
+ * @param array $client_billing Payg billing details of the client.
354
+ * This should be an array of the form
355
+ * array(
356
+ * 'Currency' => The currency fees are paid in
357
+ * 'ClientPays' => Whether client client pays for themselves
358
+ * 'MarkupPercentage' => Can be used to set the percentage markup for all unset fees
359
+ * 'CanPurchaseCredits' => Whether the client can purchase credits
360
+ * 'MarkupOnDelivery' => The markup applied per campaign
361
+ * 'MarkupPerRecipient' => The markup applied per campaign recipient
362
+ * 'MarkupOnDesignSpamTest' => The markup applied per design and spam test
363
+ * )
364
+ * @access public
365
+ * @return CS_REST_Wrapper_Result A successful response will be empty
366
+ */
367
+ function set_payg_billing($client_billing) {
368
+ return $this->put_request($this->_clients_base_route.'setpaygbilling.json', $client_billing);
369
+ }
370
+
371
+ /**
372
+ * Updates the billing details of the current client, setting the client to the monthly billing model
373
+ * For clients not set to pay themselves then the markup percentage field is ignored
374
+ * @param array $client_billing Payg billing details of the client.
375
+ * This should be an array of the form
376
+ * array(
377
+ * 'Currency' => The currency fees are paid in
378
+ * 'ClientPays' => Whether client client pays for themselves
379
+ * 'MarkupPercentage' => Sets the percentage markup used for all monthly tiers
380
+ * )
381
+ * @access public
382
+ * @return CS_REST_Wrapper_Result A successful response will be empty
383
+ */
384
+ function set_monthly_billing($client_billing) {
385
+ return $this->put_request($this->_clients_base_route.'setmonthlybilling.json', $client_billing);
386
+ }
387
+
388
+ /**
389
+ * Transfer credits to or from this client.
390
+ *
391
+ * @param array $transfer_data Details for the credit transfer. This array
392
+ * should be of the form:
393
+ * array(
394
+ * 'Credits' => An in representing the number of credits to transfer.
395
+ * This value may be either positive if you want to allocate credits
396
+ * from your account to the client, or negative if you want to
397
+ * deduct credits from the client back into your account.
398
+ * 'CanUseMyCreditsWhenTheyRunOut' => A boolean value which if set
399
+ * to true, will allow the client to continue sending using your
400
+ * credits or payment details once they run out of credits, and if
401
+ * set to false, will prevent the client from using your credits to
402
+ * continue sending until you allocate more credits to them.
403
+ * )
404
+ * @access public
405
+ * @return CS_REST_Wrapper_Result A successful response will be an object
406
+ * of the form:
407
+ * {
408
+ * 'AccountCredits' => Integer representing credits in your account now
409
+ * 'ClientCredits' => Integer representing credits in this client's
410
+ * account now
411
+ * }
412
+ */
413
+ function transfer_credits($transfer_data) {
414
+ return $this->post_request($this->_clients_base_route.'credits.json',
415
+ $transfer_data);
416
+ }
417
+
418
+ /**
419
+ * returns the people associated with this client.
420
+ * @return CS_REST_Wrapper_Result A successful response will be an object of the form
421
+ * array({
422
+ * 'EmailAddress' => the email address of the person
423
+ * 'Name' => the name of the person
424
+ * 'AccessLevel' => the access level of the person
425
+ * 'Status' => the status of the person
426
+ * })
427
+ */
428
+ function get_people() {
429
+ return $this->get_request($this->_clients_base_route.'people.json');
430
+ }
431
+
432
+ /**
433
+ * retrieves the email address of the primary contact for this client
434
+ * @return CS_REST_Wrapper_Result a successful response will be an array in the form:
435
+ * array('EmailAddress'=> email address of primary contact)
436
+ */
437
+ function get_primary_contact() {
438
+ return $this->get_request($this->_clients_base_route.'primarycontact.json');
439
+ }
440
+
441
+ /**
442
+ * assigns the primary contact for this client to the person with the specified email address
443
+ * @param string $emailAddress the email address of the person designated to be the primary contact
444
+ * @return CS_REST_Wrapper_Result a successful response will be an array in the form:
445
+ * array('EmailAddress'=> email address of primary contact)
446
+ */
447
+ function set_primary_contact($emailAddress) {
448
+ return $this->put_request($this->_clients_base_route.'primarycontact.json?email=' . urlencode($emailAddress), '');
449
+ }
450
+ }
includes/vendor/campaign-monitor/csrest_general.php ADDED
@@ -0,0 +1,212 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ require_once dirname(__FILE__).'/class/base_classes.php';
4
+
5
+ /**
6
+ * Class to access general resources from the create send API.
7
+ * @author tobyb
8
+ *
9
+ */
10
+ class CS_REST_General extends CS_REST_Wrapper_Base {
11
+
12
+ /**
13
+ * Get the authorization URL for your application, given the application's
14
+ * Client ID, Client Secret, Redirect URI, Scope, and optional state data.
15
+ *
16
+ * @param $client_id int The Client ID of your registered OAuth application.
17
+ * @param $redirect_uri string The Redirect URI of your registered OAuth application.
18
+ * @param $scope string The comma-separated permission scope your application requires.
19
+ * See http://www.campaignmonitor.com/api/getting-started/#authenticating_with_oauth for details.
20
+ * @param $state string Optional state data to be included in the URL.
21
+ * @return string The authorization URL to which users of your application should be redirected.
22
+ * @access public
23
+ **/
24
+ public static function authorize_url(
25
+ $client_id, $redirect_uri, $scope, $state = NULL) {
26
+ $qs = "client_id=".urlencode($client_id);
27
+ $qs .= "&redirect_uri=".urlencode($redirect_uri);
28
+ $qs .= "&scope=".urlencode($scope);
29
+ if ($state) {
30
+ $qs .= "&state=".urlencode($state);
31
+ }
32
+ return CS_OAUTH_BASE_URI.'?'.$qs;
33
+ }
34
+
35
+ /**
36
+ * Exchange a provided OAuth code for an OAuth access token, 'expires in'
37
+ * value and refresh token.
38
+ *
39
+ * @param $client_id int The Client ID of your registered OAuth application.
40
+ * @param $client_secret string The Client Secret of your registered OAuth application.
41
+ * @param $redirect_uri string The Redirect URI of your registered OAuth application.
42
+ * @param $code string The unique OAuth code to be exchanged for an access token.
43
+ * @return CS_REST_Wrapper_Result A successful response will be an object of the form
44
+ * {
45
+ * 'access_token' => The access token to use for API calls
46
+ * 'expires_in' => The number of seconds until this access token expires
47
+ * 'refresh_token' => The refresh token to refresh the access token once it expires
48
+ * }
49
+ * @access public
50
+ **/
51
+ public static function exchange_token(
52
+ $client_id, $client_secret, $redirect_uri, $code) {
53
+
54
+ $body = "grant_type=authorization_code";
55
+ $body .= "&client_id=".urlencode($client_id);
56
+ $body .= "&client_secret=".urlencode($client_secret);
57
+ $body .= "&redirect_uri=".urlencode($redirect_uri);
58
+ $body .= "&code=".urlencode($code);
59
+
60
+ $options = array('contentType' => 'application/x-www-form-urlencoded');
61
+
62
+ $wrap = new CS_REST_Wrapper_Base(
63
+ NULL, 'https', CS_REST_LOG_NONE, CS_HOST, NULL,
64
+ new CS_REST_DoNothingSerialiser(), NULL);
65
+
66
+ return $wrap->post_request(CS_OAUTH_TOKEN_URI, $body, $options);
67
+ }
68
+
69
+ /**
70
+ * Constructor.
71
+ * @param $auth_details array Authentication details to use for API calls.
72
+ * This array must take one of the following forms:
73
+ * If using OAuth to authenticate:
74
+ * array(
75
+ * 'access_token' => 'your access token',
76
+ * 'refresh_token' => 'your refresh token')
77
+ *
78
+ * Or if using an API key:
79
+ * array('api_key' => 'your api key')
80
+ * @param $protocol string The protocol to use for requests (http|https)
81
+ * @param $debug_level int The level of debugging required CS_REST_LOG_NONE | CS_REST_LOG_ERROR | CS_REST_LOG_WARNING | CS_REST_LOG_VERBOSE
82
+ * @param $host string The host to send API requests to. There is no need to change this
83
+ * @param $log CS_REST_Log The logger to use. Used for dependency injection
84
+ * @param $serialiser The serialiser to use. Used for dependency injection
85
+ * @param $transport The transport to use. Used for dependency injection
86
+ * @access public
87
+ */
88
+ function CS_REST_Wrapper_Base(
89
+ $auth_details,
90
+ $protocol = 'https',
91
+ $debug_level = CS_REST_LOG_NONE,
92
+ $host = 'api.createsend.com',
93
+ $log = NULL,
94
+ $serialiser = NULL,
95
+ $transport = NULL) {
96
+ $this->CS_REST_Wrapper_Base($auth_details, $protocol, $debug_level, $host, $log, $serialiser, $transport);
97
+ }
98
+
99
+ /**
100
+ * Gets an array of valid timezones
101
+ * @access public
102
+ * @return CS_REST_Wrapper_Result A successful response will be an object of the form
103
+ * array<string>(timezones)
104
+ */
105
+ function get_timezones() {
106
+ return $this->get_request($this->_base_route.'timezones.json');
107
+ }
108
+
109
+ /**
110
+ * Gets the current date in your accounts timezone
111
+ * @access public
112
+ * @return CS_REST_Wrapper_Result A successful response will be an object of the form
113
+ * {
114
+ * 'SystemDate' => string The current system date in your accounts timezone
115
+ * }
116
+ */
117
+ function get_systemdate() {
118
+ return $this->get_request($this->_base_route.'systemdate.json');
119
+ }
120
+
121
+ /**
122
+ * Gets an array of valid countries
123
+ * @access public
124
+ * @return CS_REST_Wrapper_Result A successful response will be an object of the form
125
+ * array<string>(countries)
126
+ */
127
+ function get_countries() {
128
+ return $this->get_request($this->_base_route.'countries.json');
129
+ }
130
+
131
+ /**
132
+ * Gets an array of clients
133
+ * @access public
134
+ * @return CS_REST_Wrapper_Result A successful response will be an object of the form
135
+ * array(
136
+ * {
137
+ * 'ClientID' => The clients API ID,
138
+ * 'Name' => The clients name
139
+ * }
140
+ * )
141
+ */
142
+ function get_clients() {
143
+ return $this->get_request($this->_base_route.'clients.json');
144
+ }
145
+
146
+ /**
147
+ * Gets your billing details.
148
+ * @access public
149
+ * @return CS_REST_Wrapper_Result A successful response will be an object of the form
150
+ * {
151
+ * 'Credits' => The number of credits belonging to the account
152
+ * }
153
+ */
154
+ function get_billing_details() {
155
+ return $this->get_request($this->_base_route.'billingdetails.json');
156
+ }
157
+
158
+ /**
159
+ * Gets an array of administrators
160
+ * @access public
161
+ * @return CS_REST_Wrapper_Result A successful response will be an object of the form
162
+ * array(
163
+ * {
164
+ * 'EmailAddress' => The administrators email address
165
+ * 'Name' => The administrators name
166
+ * 'Status' => The administrators status
167
+ * }
168
+ * )
169
+ */
170
+ function get_administrators() {
171
+ return $this->get_request($this->_base_route.'admins.json');
172
+ }
173
+
174
+ /**
175
+ * Retrieves the email address of the primary contact for this account
176
+ * @return CS_REST_Wrapper_Result a successful response will be an array in the form:
177
+ * array('EmailAddress'=> email address of primary contact)
178
+ */
179
+ function get_primary_contact() {
180
+ return $this->get_request($this->_base_route.'primarycontact.json');
181
+ }
182
+
183
+ /**
184
+ * Assigns the primary contact for this account to the administrator with the specified email address
185
+ * @param $emailAddress string The email address of the administrator designated to be the primary contact
186
+ * @return CS_REST_Wrapper_Result a successful response will be an array in the form:
187
+ * array('EmailAddress'=> email address of primary contact)
188
+ */
189
+ function set_primary_contact($emailAddress) {
190
+ return $this->put_request($this->_base_route.'primarycontact.json?email=' . urlencode($emailAddress), '');
191
+ }
192
+
193
+ /**
194
+ * Get a URL which initiates a new external session for the user with the given email.
195
+ * Full details: http://www.campaignmonitor.com/api/account/#single_sign_on
196
+ *
197
+ * @param $session_options array Options for initiating the external login session.
198
+ * This should be an array of the form:
199
+ * array(
200
+ * 'Email' => 'The email address of the Campaign Monitor user for whom the login session should be created',
201
+ * 'Chrome' => 'Which 'chrome' to display - Must be either "all", "tabs", or "none"',
202
+ * 'Url' => 'The URL to display once logged in. e.g. "/subscribers/"',
203
+ * 'IntegratorID' => 'The Integrator ID. You need to contact Campaign Monitor support to get an Integrator ID.',
204
+ * 'ClientID' => 'The Client ID of the client which should be active once logged in to the Campaign Monitor account.' )
205
+ *
206
+ * @return CS_REST_Wrapper_Result A successful response will be an array of the form:
207
+ * array('SessionUrl'=> 'https://external1.createsend.com/cd/create/ABCDEF12/DEADBEEF?url=FEEDDAD1')
208
+ */
209
+ function external_session_url($session_options) {
210
+ return $this->put_request($this->_base_route.'externalsession.json', $session_options);
211
+ }
212
+ }
includes/vendor/campaign-monitor/csrest_lists.php ADDED
@@ -0,0 +1,587 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ require_once dirname(__FILE__).'/class/base_classes.php';
3
+
4
+ define('CS_REST_CUSTOM_FIELD_TYPE_TEXT', 'Text');
5
+ define('CS_REST_CUSTOM_FIELD_TYPE_NUMBER', 'Number');
6
+ define('CS_REST_CUSTOM_FIELD_TYPE_MULTI_SELECTONE', 'MultiSelectOne');
7
+ define('CS_REST_CUSTOM_FIELD_TYPE_MULTI_SELECTMANY', 'MultiSelectMany');
8
+ define('CS_REST_CUSTOM_FIELD_TYPE_DATE', 'Date');
9
+ define('CS_REST_CUSTOM_FIELD_TYPE_COUNTRY', 'Country');
10
+ define('CS_REST_CUSTOM_FIELD_TYPE_USSTATE', 'USState');
11
+
12
+ define('CS_REST_LIST_WEBHOOK_SUBSCRIBE', 'Subscribe');
13
+ define('CS_REST_LIST_WEBHOOK_DEACTIVATE', 'Deactivate');
14
+ define('CS_REST_LIST_WEBHOOK_UPDATE', 'Update');
15
+ define('CS_REST_LIST_UNSUBSCRIBE_SETTING_ALL_CLIENT_LISTS', 'AllClientLists');
16
+ define('CS_REST_LIST_UNSUBSCRIBE_SETTING_ONLY_THIS_LIST', 'OnlyThisList');
17
+
18
+ /**
19
+ * Class to access a lists resources from the create send API.
20
+ * This class includes functions to create lists and custom fields,
21
+ * along with accessing the subscribers of a specific list
22
+ * @author tobyb
23
+ *
24
+ */
25
+ class CS_REST_Lists extends CS_REST_Wrapper_Base {
26
+
27
+ /**
28
+ * The base route of the lists resource.
29
+ * @var string
30
+ * @access private
31
+ */
32
+ var $_lists_base_route;
33
+
34
+ /**
35
+ * Constructor.
36
+ * @param $list_id string The list id to access (Ignored for create requests)
37
+ * @param $auth_details array Authentication details to use for API calls.
38
+ * This array must take one of the following forms:
39
+ * If using OAuth to authenticate:
40
+ * array(
41
+ * 'access_token' => 'your access token',
42
+ * 'refresh_token' => 'your refresh token')
43
+ *
44
+ * Or if using an API key:
45
+ * array('api_key' => 'your api key')
46
+ * @param $protocol string The protocol to use for requests (http|https)
47
+ * @param $debug_level int The level of debugging required CS_REST_LOG_NONE | CS_REST_LOG_ERROR | CS_REST_LOG_WARNING | CS_REST_LOG_VERBOSE
48
+ * @param $host string The host to send API requests to. There is no need to change this
49
+ * @param $log CS_REST_Log The logger to use. Used for dependency injection
50
+ * @param $serialiser The serialiser to use. Used for dependency injection
51
+ * @param $transport The transport to use. Used for dependency injection
52
+ * @access public
53
+ */
54
+ function CS_REST_Lists (
55
+ $list_id,
56
+ $auth_details,
57
+ $protocol = 'https',
58
+ $debug_level = CS_REST_LOG_NONE,
59
+ $host = 'api.createsend.com',
60
+ $log = NULL,
61
+ $serialiser = NULL,
62
+ $transport = NULL) {
63
+
64
+ $this->CS_REST_Wrapper_Base($auth_details, $protocol, $debug_level, $host, $log, $serialiser, $transport);
65
+ $this->set_list_id($list_id);
66
+ }
67
+
68
+ /**
69
+ * Change the list id used for calls after construction
70
+ * @param $list_id
71
+ * @access public
72
+ */
73
+ function set_list_id($list_id) {
74
+ $this->_lists_base_route = $this->_base_route.'lists/'.$list_id.'/';
75
+ }
76
+
77
+ /**
78
+ * Creates a new list based on the provided details.
79
+ * Both the UnsubscribePage and the ConfirmationSuccessPage parameters are optional
80
+ * @param string $client_id The client to create the campaign for
81
+ * @param array $list_details The list details to use during creation.
82
+ * This array should be of the form
83
+ * array(
84
+ * 'Title' => string The list title
85
+ * 'UnsubscribePage' => string The page to redirect subscribers to when they unsubscribe
86
+ * 'ConfirmedOptIn' => boolean Whether this list requires confirmation of subscription
87
+ * 'ConfirmationSuccessPage' => string The page to redirect subscribers to when
88
+ * they confirm their subscription
89
+ * 'UnsubscribeSetting' => string Unsubscribe setting must be
90
+ * CS_REST_LIST_UNSUBSCRIBE_SETTING_ALL_CLIENT_LISTS or
91
+ * CS_REST_LIST_UNSUBSCRIBE_SETTING_ONLY_THIS_LIST.
92
+ * See the documentation for details: http://www.campaignmonitor.com/api/lists/#creating_a_list
93
+ * )
94
+ * @access public
95
+ * @return CS_REST_Wrapper_Result A successful response will be the ID of the newly created list
96
+ */
97
+ function create($client_id, $list_details) {
98
+ return $this->post_request($this->_base_route.'lists/'.$client_id.'.json', $list_details);
99
+ }
100
+
101
+ /**
102
+ * Updates the details of an existing list
103
+ * Both the UnsubscribePage and the ConfirmationSuccessPage parameters are optional
104
+ * @param string $client_id The client to create the campaign for
105
+ * @param array $list_details The list details to use during creation.
106
+ * This array should be of the form
107
+ * array(
108
+ * 'Title' => string The list title
109
+ * 'UnsubscribePage' => string The page to redirect subscribers to when they unsubscribe
110
+ * 'ConfirmedOptIn' => boolean Whether this list requires confirmation of subscription
111
+ * 'ConfirmationSuccessPage' => string The page to redirect subscribers to when
112
+ * they confirm their subscription
113
+ * 'UnsubscribeSetting' => string Unsubscribe setting must be
114
+ * CS_REST_LIST_UNSUBSCRIBE_SETTING_ALL_CLIENT_LISTS or
115
+ * CS_REST_LIST_UNSUBSCRIBE_SETTING_ONLY_THIS_LIST.
116
+ * See the documentation for details: http://www.campaignmonitor.com/api/lists/#updating_a_list
117
+ * 'AddUnsubscribesToSuppList' => boolean When UnsubscribeSetting
118
+ * is CS_REST_LIST_UNSUBSCRIBE_SETTING_ALL_CLIENT_LISTS,
119
+ * whether unsubscribes from this list should be added to the
120
+ * suppression list.
121
+ * 'ScrubActiveWithSuppList' => boolean When UnsubscribeSetting
122
+ * is CS_REST_LIST_UNSUBSCRIBE_SETTING_ALL_CLIENT_LISTS,
123
+ * whether active subscribers should be scrubbed against the
124
+ * suppression list.
125
+ * )
126
+ * @access public
127
+ * @return CS_REST_Wrapper_Result A successful response will be empty
128
+ */
129
+ function update($list_details) {
130
+ return $this->put_request(trim($this->_lists_base_route, '/').'.json', $list_details);
131
+ }
132
+
133
+ /**
134
+ * Creates a new custom field for the current list
135
+ * @param array $custom_field_details The details of the new custom field.
136
+ * This array should be of the form
137
+ * array(
138
+ * 'FieldName' => string The name of the new custom field
139
+ * 'DataType' => string The data type of the new custom field
140
+ * This should be one of
141
+ * CS_REST_CUSTOM_FIELD_TYPE_TEXT
142
+ * CS_REST_CUSTOM_FIELD_TYPE_NUMBER
143
+ * CS_REST_CUSTOM_FIELD_TYPE_MULTI_SELECTONE
144
+ * CS_REST_CUSTOM_FIELD_TYPE_MULTI_SELECTMANY
145
+ * CS_REST_CUSTOM_FIELD_TYPE_DATE
146
+ * CS_REST_CUSTOM_FIELD_TYPE_COUNTRY
147
+ * CS_REST_CUSTOM_FIELD_TYPE_USSTATE
148
+ * 'Options' => array<string> Valid options for either
149
+ * Multi-Optioned field data type.
150
+ * 'VisibleInPreferenceCenter' => boolean representing whether or
151
+ * not the field should be visible in the subscriber preference
152
+ * center.
153
+ * )
154
+ * @access public
155
+ * @return CS_REST_Wrapper_Result A successful response will be the
156
+ * personalisation tag of the newly created custom field
157
+ */
158
+ function create_custom_field($custom_field_details) {
159
+ return $this->post_request($this->_lists_base_route.'customfields.json', $custom_field_details);
160
+ }
161
+
162
+ /**
163
+ * Updates a custom field for the current list
164
+ * @param string $key The personalisation tag of the field to update
165
+ * @param array $custom_field_details The details of the new custom field.
166
+ * This array should be of the form
167
+ * array(
168
+ * 'FieldName' => string The new name for the field
169
+ * 'VisibleInPreferenceCenter' => boolean representing whether or
170
+ * not the field should be visible in the subscriber preference
171
+ * center.
172
+ * )
173
+ * @access public
174
+ * @return CS_REST_Wrapper_Result A successful response will be the
175
+ * personalisation tag of the updated custom field
176
+ */
177
+ function update_custom_field($key, $custom_field_details) {
178
+ return $this->put_request($this->_lists_base_route.'customfields/'.rawurlencode($key).'.json',
179
+ $custom_field_details);
180
+ }
181
+
182
+ /**
183
+ * Updates the optios for the given multi-optioned custom field
184
+ * @param string $key The personalisation tag of the field to update
185
+ * @param array<string> $new_options The set of options to add to the custom field
186
+ * @param boolean $keep_existing Whether to remove any existing options not contained in $new_options
187
+ * @access public
188
+ * @return CS_REST_Wrapper_Result A successful response will be empty
189
+ */
190
+ function update_field_options($key, $new_options, $keep_existing) {
191
+ $options = array(
192
+ 'KeepExistingOptions' => $keep_existing,
193
+ 'Options' => $new_options
194
+ );
195
+
196
+ return $this->put_request($this->_lists_base_route.'customfields/'.rawurlencode($key).'/options.json',
197
+ $options);
198
+ }
199
+
200
+ /**
201
+ * Deletes an existing list from the system
202
+ * @access public
203
+ * @return CS_REST_Wrapper_Result A successful response will be empty
204
+ */
205
+ function delete() {
206
+ return $this->delete_request(trim($this->_lists_base_route, '/').'.json');
207
+ }
208
+
209
+ /**
210
+ * Deletes an existing custom field from the system
211
+ * @access public
212
+ * @return CS_REST_Wrapper_Result A successful response will be empty
213
+ */
214
+ function delete_custom_field($key) {
215
+ return $this->delete_request($this->_lists_base_route.'customfields/'.rawurlencode($key).'.json');
216
+ }
217
+
218
+ /**
219
+ * Gets a list of all custom fields defined for the current list
220
+ * @access public
221
+ * @return CS_REST_Wrapper_Result A successful response will be an object of the form
222
+ * array(
223
+ * {
224
+ * 'FieldName' => The name of the custom field
225
+ * 'Key' => The personalisation tag of the custom field
226
+ * 'DataType' => The data type of the custom field
227
+ * 'FieldOptions' => Valid options for a multi-optioned custom field
228
+ * 'VisibleInPreferenceCenter' => Boolean representing whether or
229
+ * not the field is visible in the subscriber preference center
230
+ * }
231
+ * )
232
+ */
233
+ function get_custom_fields() {
234
+ return $this->get_request($this->_lists_base_route.'customfields.json');
235
+ }
236
+
237
+ /**
238
+ * Gets a list of all segments defined for the current list
239
+ * @access public
240
+ * @return CS_REST_Wrapper_Result A successful response will be an object of the form
241
+ * array(
242
+ * {
243
+ * 'ListID' => The current list id
244
+ * 'SegmentID' => The id of this segment
245
+ * 'Title' => The title of this segment
246
+ * }
247
+ * )
248
+ */
249
+ function get_segments() {
250
+ return $this->get_request($this->_lists_base_route.'segments.json');
251
+ }
252
+
253
+ /**
254
+ * Gets all active subscribers added since the given date
255
+ * @param string $added_since The date to start getting subscribers from
256
+ * @param int $page_number The page number to get
257
+ * @param int $page_size The number of records per page
258
+ * @param string $order_field The field to order the record set by ('EMAIL', 'NAME', 'DATE')
259
+ * @param string $order_direction The direction to order the record set ('ASC', 'DESC')
260
+ * @access public
261
+ * @return CS_REST_Wrapper_Result A successful response will be an object of the form
262
+ * {
263
+ * 'ResultsOrderedBy' => The field the results are ordered by
264
+ * 'OrderDirection' => The order direction
265
+ * 'PageNumber' => The page number for the result set
266
+ * 'PageSize' => The page size used
267
+ * 'RecordsOnThisPage' => The number of records returned
268
+ * 'TotalNumberOfRecords' => The total number of records available
269
+ * 'NumberOfPages' => The total number of pages for this collection
270
+ * 'Results' => array(
271
+ * {
272
+ * 'EmailAddress' => The email address of the subscriber
273
+ * 'Name' => The name of the subscriber
274
+ * 'Date' => The date that the subscriber was added to the list
275
+ * 'State' => The current state of the subscriber, will be 'Active'
276
+ * 'CustomFields' => array (
277
+ * {
278
+ * 'Key' => The personalisation tag of the custom field
279
+ * 'Value' => The value of the custom field for this subscriber
280
+ * }
281
+ * )
282
+ * }
283
+ * )
284
+ * }
285
+ */
286
+ function get_active_subscribers($added_since = '', $page_number = NULL,
287
+ $page_size = NULL, $order_field = NULL, $order_direction = NULL) {
288
+
289
+ return $this->get_request_paged($this->_lists_base_route.'active.json?date='.urlencode($added_since),
290
+ $page_number, $page_size, $order_field, $order_direction);
291
+ }
292
+
293
+ /**
294
+ * Gets all unconfirmed subscribers added since the given date
295
+ * @param string $added_since The date to start getting subscribers from
296
+ * @param int $page_number The page number to get
297
+ * @param int $page_size The number of records per page
298
+ * @param string $order_field The field to order the record set by ('EMAIL', 'NAME', 'DATE')
299
+ * @param string $order_direction The direction to order the record set ('ASC', 'DESC')
300
+ * @access public
301
+ * @return CS_REST_Wrapper_Result A successful response will be an object of the form
302
+ * {
303
+ * 'ResultsOrderedBy' => The field the results are ordered by
304
+ * 'OrderDirection' => The order direction
305
+ * 'PageNumber' => The page number for the result set
306
+ * 'PageSize' => The page size used
307
+ * 'RecordsOnThisPage' => The number of records returned
308
+ * 'TotalNumberOfRecords' => The total number of records available
309
+ * 'NumberOfPages' => The total number of pages for this collection
310
+ * 'Results' => array(
311
+ * {
312
+ * 'EmailAddress' => The email address of the subscriber
313
+ * 'Name' => The name of the subscriber
314
+ * 'Date' => The date that the subscriber was added to the list
315
+ * 'State' => The current state of the subscriber, will be 'Unconfirmed'
316
+ * 'CustomFields' => array (
317
+ * {
318
+ * 'Key' => The personalisation tag of the custom field
319
+ * 'Value' => The value of the custom field for this subscriber
320
+ * }
321
+ * )
322
+ * }
323
+ * )
324
+ * }
325
+ */
326
+ function get_unconfirmed_subscribers($added_since = '', $page_number = NULL,
327
+ $page_size = NULL, $order_field = NULL, $order_direction = NULL) {
328
+
329
+ return $this->get_request_paged($this->_lists_base_route.'unconfirmed.json?date='.urlencode($added_since),
330
+ $page_number, $page_size, $order_field, $order_direction);
331
+ }
332
+
333
+ /**
334
+ * Gets all bounced subscribers who have bounced out since the given date
335
+ * @param string $added_since The date to start getting subscribers from
336
+ * @param int $page_number The page number to get
337
+ * @param int $page_size The number of records per page
338
+ * @param string $order_field The field to order the record set by ('EMAIL', 'NAME', 'DATE')
339
+ * @param string $order_direction The direction to order the record set ('ASC', 'DESC')
340
+ * @access public
341
+ * @return CS_REST_Wrapper_Result A successful response will be an object of the form
342
+ * {
343
+ * 'ResultsOrderedBy' => The field the results are ordered by
344
+ * 'OrderDirection' => The order direction
345
+ * 'PageNumber' => The page number for the result set
346
+ * 'PageSize' => The page size used
347
+ * 'RecordsOnThisPage' => The number of records returned
348
+ * 'TotalNumberOfRecords' => The total number of records available
349
+ * 'NumberOfPages' => The total number of pages for this collection
350
+ * 'Results' => array(
351
+ * {
352
+ * 'EmailAddress' => The email address of the subscriber
353
+ * 'Name' => The name of the subscriber
354
+ * 'Date' => The date that the subscriber bounced out of the list
355
+ * 'State' => The current state of the subscriber, will be 'Bounced'
356
+ * 'CustomFields' => array (
357
+ * {
358
+ * 'Key' => The personalisation tag of the custom field
359
+ * 'Value' => The value of the custom field for this subscriber
360
+ * }
361
+ * )
362
+ * }
363
+ * )
364
+ * }
365
+ */
366
+ function get_bounced_subscribers($bounced_since = '', $page_number = NULL,
367
+ $page_size = NULL, $order_field = NULL, $order_direction = NULL) {
368
+
369
+ return $this->get_request_paged($this->_lists_base_route.'bounced.json?date='.urlencode($bounced_since),
370
+ $page_number, $page_size, $order_field, $order_direction);
371
+ }
372
+
373
+ /**
374
+ * Gets all unsubscribed subscribers who have unsubscribed since the given date
375
+ * @param string $added_since The date to start getting subscribers from
376
+ * @param int $page_number The page number to get
377
+ * @param int $page_size The number of records per page
378
+ * @param string $order_field The field to order the record set by ('EMAIL', 'NAME', 'DATE')
379
+ * @param string $order_direction The direction to order the record set ('ASC', 'DESC')
380
+ * @access public
381
+ * @return CS_REST_Wrapper_Result A successful response will be an object of the form
382
+ * {
383
+ * 'ResultsOrderedBy' => The field the results are ordered by
384
+ * 'OrderDirection' => The order direction
385
+ * 'PageNumber' => The page number for the result set
386
+ * 'PageSize' => The page size used
387
+ * 'RecordsOnThisPage' => The number of records returned
388
+ * 'TotalNumberOfRecords' => The total number of records available
389
+ * 'NumberOfPages' => The total number of pages for this collection
390
+ * 'Results' => array(
391
+ * {
392
+ * 'EmailAddress' => The email address of the subscriber
393
+ * 'Name' => The name of the subscriber
394
+ * 'Date' => The date that the subscriber was unsubscribed from the list
395
+ * 'State' => The current state of the subscriber, will be 'Unsubscribed'
396
+ * 'CustomFields' => array (
397
+ * {
398
+ * 'Key' => The personalisation tag of the custom field
399
+ * 'Value' => The value of the custom field for this subscriber
400
+ * }
401
+ * )
402
+ * }
403
+ * )
404
+ * }
405
+ */
406
+ function get_unsubscribed_subscribers($unsubscribed_since = '', $page_number = NULL,
407
+ $page_size = NULL, $order_field = NULL, $order_direction = NULL) {
408
+
409
+ return $this->get_request_paged($this->_lists_base_route.'unsubscribed.json?date='.urlencode($unsubscribed_since),
410
+ $page_number, $page_size, $order_field, $order_direction);
411
+ }
412
+
413
+ /**
414
+ * Gets all subscribers who have been deleted since the given date
415
+ * @param string $deleted_since The date to start getting subscribers from
416
+ * @param int $page_number The page number to get
417
+ * @param int $page_size The number of records per page
418
+ * @param string $order_field The field to order the record set by ('EMAIL', 'NAME', 'DATE')
419
+ * @param string $order_direction The direction to order the record set ('ASC', 'DESC')
420
+ * @access public
421
+ * @return CS_REST_Wrapper_Result A successful response will be an object of the form
422
+ * {
423
+ * 'ResultsOrderedBy' => The field the results are ordered by
424
+ * 'OrderDirection' => The order direction
425
+ * 'PageNumber' => The page number for the result set
426
+ * 'PageSize' => The page size used
427
+ * 'RecordsOnThisPage' => The number of records returned
428
+ * 'TotalNumberOfRecords' => The total number of records available
429
+ * 'NumberOfPages' => The total number of pages for this collection
430
+ * 'Results' => array(
431
+ * {
432
+ * 'EmailAddress' => The email address of the subscriber
433
+ * 'Name' => The name of the subscriber
434
+ * 'Date' => The date that the subscriber was deleted from the list
435
+ * 'State' => The current state of the subscriber, will be 'Deleted'
436
+ * 'CustomFields' => array (
437
+ * {
438
+ * 'Key' => The personalisation tag of the custom field
439
+ * 'Value' => The value of the custom field for this subscriber
440
+ * }
441
+ * )
442
+ * }
443
+ * )
444
+ * }
445
+ */
446
+ function get_deleted_subscribers($deleted_since = '', $page_number = NULL,
447
+ $page_size = NULL, $order_field = NULL, $order_direction = NULL) {
448
+
449
+ return $this->get_request_paged($this->_lists_base_route.'deleted.json?date='.urlencode($deleted_since),
450
+ $page_number, $page_size, $order_field, $order_direction);
451
+ }
452
+
453
+ /**
454
+ * Gets the basic details of the current list
455
+ * @access public
456
+ * @return CS_REST_Wrapper_Result A successful response will be an object of the form
457
+ * {
458
+ * 'ListID' => The id of the list
459
+ * 'Title' => The title of the list
460
+ * 'UnsubscribePage' => The page which subscribers are redirected to upon unsubscribing
461
+ * 'ConfirmedOptIn' => Whether the list is Double-Opt In
462
+ * 'ConfirmationSuccessPage' => The page which subscribers are
463
+ * redirected to upon confirming their subscription
464
+ * 'UnsubscribeSetting' => The unsubscribe setting for the list. Will
465
+ * be either CS_REST_LIST_UNSUBSCRIBE_SETTING_ALL_CLIENT_LISTS or
466
+ * CS_REST_LIST_UNSUBSCRIBE_SETTING_ONLY_THIS_LIST.
467
+ * }
468
+ */
469
+ function get() {
470
+ return $this->get_request(trim($this->_lists_base_route, '/').'.json');
471
+ }
472
+
473
+ /**
474
+ * Gets statistics for list subscriptions, deletions, bounces and unsubscriptions
475
+ * @access public
476
+ * @return CS_REST_Wrapper_Result A successful response will be an object of the form
477
+ * {
478
+ * 'TotalActiveSubscribers'
479
+ * 'NewActiveSubscribersToday'
480
+ * 'NewActiveSubscribersYesterday'
481
+ * 'NewActiveSubscribersThisWeek'
482
+ * 'NewActiveSubscribersThisMonth'
483
+ * 'NewActiveSubscribersThisYeay'
484
+ * 'TotalUnsubscribes'
485
+ * 'UnsubscribesToday'
486
+ * 'UnsubscribesYesterday'
487
+ * 'UnsubscribesThisWeek'
488
+ * 'UnsubscribesThisMonth'
489
+ * 'UnsubscribesThisYear'
490
+ * 'TotalDeleted'
491
+ * 'DeletedToday'
492
+ * 'DeletedYesterday'
493
+ * 'DeletedThisWeek'
494
+ * 'DeletedThisMonth'
495
+ * 'DeletedThisYear'
496
+ * 'TotalBounces'
497
+ * 'BouncesToday'
498
+ * 'BouncesYesterday'
499
+ * 'BouncesThisWeek'
500
+ * 'BouncesThisMonth'
501
+ * 'BouncesThisYear'
502
+ * }
503
+ */
504
+ function get_stats() {
505
+ return $this->get_request($this->_lists_base_route.'stats.json');
506
+ }
507
+
508
+ /**
509
+ * Gets the webhooks which are currently subcribed to event on this list
510
+ * @access public
511
+ * @return CS_REST_Wrapper_Result A successful response will be an object of the form
512
+ * array(
513
+ * {
514
+ * 'WebhookID' => The if of
515
+ * 'Events' => An array of the events this webhook is subscribed to ('Subscribe', 'Update', 'Deactivate')
516
+ * 'Url' => The url the webhook data will be POSTed to
517
+ * 'Status' => The current status of this webhook
518
+ * 'PayloadFormat' => The format in which data will be POSTed
519
+ * }
520
+ * )
521
+ */
522
+ function get_webhooks() {
523
+ return $this->get_request($this->_lists_base_route.'webhooks.json');
524
+ }
525
+
526
+ /**
527
+ * Creates a new webhook based on the provided details
528
+ * @param array $webhook The details of the new webhook
529
+ * This array should be of the form
530
+ * array(
531
+ * 'Events' => array<string> The events to subscribe to. Valid events are
532
+ * CS_REST_LIST_WEBHOOK_SUBSCRIBE,
533
+ * CS_REST_LIST_WEBHOOK_DEACTIVATE,
534
+ * CS_REST_LIST_WEBHOOK_UPDATE
535
+ * 'Url' => string The url of the page to POST the webhook events to
536
+ * 'PayloadFormat' => The format to use when POSTing webhook event data, either
537
+ * CS_REST_WEBHOOK_FORMAT_JSON or
538
+ * CS_REST_WEBHOOK_FORMAT_XML
539
+ * (xml or json)
540
+ * )
541
+ * @access public
542
+ * @return CS_REST_Wrapper_Result A successful response will be the ID of the newly created webhook
543
+ */
544
+ function create_webhook($webhook) {
545
+ return $this->post_request($this->_lists_base_route.'webhooks.json', $webhook);
546
+ }
547
+
548
+ /**
549
+ * Sends test events for the given webhook id
550
+ * @param string $webhook_id The id of the webhook to test
551
+ * @access public
552
+ * @return CS_REST_Wrapper_Result A successful response will be empty.
553
+ */
554
+ function test_webhook($webhook_id) {
555
+ return $this->get_request($this->_lists_base_route.'webhooks/'.$webhook_id.'/test.json');
556
+ }
557
+
558
+ /**
559
+ * Deletes an existing webhook from the system
560
+ * @param string $webhook_id The id of the webhook to delete
561
+ * @access public
562
+ * @return CS_REST_Wrapper_Result A successful response will be empty
563
+ */
564
+ function delete_webhook($webhook_id) {
565
+ return $this->delete_request($this->_lists_base_route.'webhooks/'.$webhook_id.'.json');
566
+ }
567
+
568
+ /**
569
+ * Activates an existing deactivated webhook
570
+ * @param string $webhook_id The id of the webhook to activate
571
+ * @access public
572
+ * @return CS_REST_Wrapper_Result A successful response will be empty
573
+ */
574
+ function activate_webhook($webhook_id) {
575
+ return $this->put_request($this->_lists_base_route.'webhooks/'.$webhook_id.'/activate.json', '');
576
+ }
577
+
578
+ /**
579
+ * Deactivates an existing activated webhook
580
+ * @param string $webhook_id The id of the webhook to deactivate
581
+ * @access public
582
+ * @return CS_REST_Wrapper_Result A successful response will be empty
583
+ */
584
+ function deactivate_webhook($webhook_id) {
585
+ return $this->put_request($this->_lists_base_route.'webhooks/'.$webhook_id.'/deactivate.json', '');
586
+ }
587
+ }
includes/vendor/campaign-monitor/csrest_people.php ADDED
@@ -0,0 +1,125 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ require_once dirname(__FILE__).'/class/base_classes.php';
3
+
4
+ /**
5
+ * Class to access the person resources from the create send API.
6
+ * This class includes functions to add and remove people,
7
+ * along with getting details for a single person
8
+ * @author tobyb
9
+ *
10
+ */
11
+ class CS_REST_People extends CS_REST_Wrapper_Base {
12
+
13
+ /**
14
+ * The base route of the people resource.
15
+ * @var string
16
+ * @access private
17
+ */
18
+ var $_people_base_route;
19
+
20
+ /**
21
+ * Constructor.
22
+ * @param $client_id string The client id that the people belong to
23
+ * @param $auth_details array Authentication details to use for API calls.
24
+ * This array must take one of the following forms:
25
+ * If using OAuth to authenticate:
26
+ * array(
27
+ * 'access_token' => 'your access token',
28
+ * 'refresh_token' => 'your refresh token')
29
+ *
30
+ * Or if using an API key:
31
+ * array('api_key' => 'your api key')
32
+ * @param $protocol string The protocol to use for requests (http|https)
33
+ * @param $debug_level int The level of debugging required CS_REST_LOG_NONE | CS_REST_LOG_ERROR | CS_REST_LOG_WARNING | CS_REST_LOG_VERBOSE
34
+ * @param $host string The host to send API requests to. There is no need to change this
35
+ * @param $log CS_REST_Log The logger to use. Used for dependency injection
36
+ * @param $serialiser The serialiser to use. Used for dependency injection
37
+ * @param $transport The transport to use. Used for dependency injection
38
+ * @access public
39
+ */
40
+ function CS_REST_People (
41
+ $client_id,
42
+ $auth_details,
43
+ $protocol = 'https',
44
+ $debug_level = CS_REST_LOG_NONE,
45
+ $host = 'api.createsend.com',
46
+ $log = NULL,
47
+ $serialiser = NULL,
48
+ $transport = NULL) {
49
+
50
+ $this->CS_REST_Wrapper_Base($auth_details, $protocol, $debug_level, $host, $log, $serialiser, $transport);
51
+ $this->set_client_id($client_id);
52
+
53
+ }
54
+
55
+ /**
56
+ * Change the client id used for calls after construction
57
+ * @param $client_id
58
+ * @access public
59
+ */
60
+ function set_client_id($client_id) {
61
+ $this->_people_base_route = $this->_base_route.'clients/'.$client_id . '/people';
62
+ }
63
+
64
+ /**
65
+ * Adds a new person to the specified client
66
+ * @param array $person The person details to use during creation.
67
+ * This array should be of the form
68
+ * array (
69
+ * 'EmailAddress' => The new person email address
70
+ * 'Name' => The name of the new person
71
+ * 'AccessLevel' => The access level of the new person. See http://www.campaignmonitor.com/api/clients/#setting_access_details for details
72
+ * 'Password' => (optional) if not specified, an invitation will be sent to the person by email
73
+ * )
74
+ * @access public
75
+ * @return CS_REST_Wrapper_Result A successful response will be empty
76
+ */
77
+ function add($person) {
78
+ return $this->post_request($this->_people_base_route.'.json', $person);
79
+ }
80
+
81
+ /**
82
+ * Updates details for an existing person associated with the specified client.
83
+ * @param string $email The email address of the person to be updated
84
+ * @param array $person The updated person details to use for the update.
85
+ * This array should be of the form
86
+ * array (
87
+ * 'EmailAddress' => The new email address
88
+ * 'Name' => The name of the person
89
+ * 'AccessLevel' => the access level of the person
90
+ * 'Password' => (optional) if specified, changes the password to the specified value
91
+ * )
92
+ * @access public
93
+ * @return CS_REST_Wrapper_Result A successful response will be empty
94
+ */
95
+ function update($email, $person) {
96
+ return $this->put_request($this->_people_base_route.'.json?email='.urlencode($email), $person);
97
+ }
98
+
99
+ /**
100
+ * Gets the details for a specific person
101
+ * @access public
102
+ * @return CS_REST_Wrapper_Result A successful response will be an object of the form
103
+ * {
104
+ * 'EmailAddress' => The email address of the person
105
+ * 'Name' => The name of the person
106
+ * 'Status' => The status of the person
107
+ * 'AccessLevel' => The access level of the person
108
+ * )
109
+ * }
110
+ */
111
+ function get($email) {
112
+ return $this->get_request($this->_people_base_route.'.json?email='.urlencode($email));
113
+ }
114
+
115
+
116
+ /**
117
+ * deletes the given person from the current client
118
+ * @param string $email The email address of the person to delete
119
+ * @access public
120
+ * @return CS_REST_Wrapper_Result A successful response will be empty
121
+ */
122
+ function delete($email) {
123
+ return $this->delete_request($this->_people_base_route.'.json?email='.urlencode($email));
124
+ }
125
+ }
includes/vendor/campaign-monitor/csrest_segments.php ADDED
@@ -0,0 +1,206 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ require_once dirname(__FILE__).'/class/base_classes.php';
3
+
4
+ /**
5
+ * Class to access a segments resources from the create send API.
6
+ * This class includes functions to create and edits segments
7
+ * along with accessing the subscribers of a specific segment
8
+ * @author tobyb
9
+ *
10
+ */
11
+ class CS_REST_Segments extends CS_REST_Wrapper_Base {
12
+
13
+ /**
14
+ * The base route of the lists resource.
15
+ * @var string
16
+ * @access private
17
+ */
18
+ var $_segments_base_route;
19
+
20
+ /**
21
+ * Constructor.
22
+ * @param $segment_id string The segment id to access (Ignored for create requests)
23
+ * @param $auth_details array Authentication details to use for API calls.
24
+ * This array must take one of the following forms:
25
+ * If using OAuth to authenticate:
26
+ * array(
27
+ * 'access_token' => 'your access token',
28
+ * 'refresh_token' => 'your refresh token')
29
+ *
30
+ * Or if using an API key:
31
+ * array('api_key' => 'your api key')
32
+ * @param $protocol string The protocol to use for requests (http|https)
33
+ * @param $debug_level int The level of debugging required CS_REST_LOG_NONE | CS_REST_LOG_ERROR | CS_REST_LOG_WARNING | CS_REST_LOG_VERBOSE
34
+ * @param $host string The host to send API requests to. There is no need to change this
35
+ * @param $log CS_REST_Log The logger to use. Used for dependency injection
36
+ * @param $serialiser The serialiser to use. Used for dependency injection
37
+ * @param $transport The transport to use. Used for dependency injection
38
+ * @access public
39
+ */
40
+ function CS_REST_Segments (
41
+ $segment_id,
42
+ $auth_details,
43
+ $protocol = 'https',
44
+ $debug_level = CS_REST_LOG_NONE,
45
+ $host = 'api.createsend.com',
46
+ $log = NULL,
47
+ $serialiser = NULL,
48
+ $transport = NULL) {
49
+
50
+ $this->CS_REST_Wrapper_Base($auth_details, $protocol, $debug_level, $host, $log, $serialiser, $transport);
51
+ $this->set_segment_id($segment_id);
52
+ }
53
+
54
+ /**
55
+ * Change the segment id used for calls after construction
56
+ * @param $segment_id
57
+ * @access public
58
+ */
59
+ function set_segment_id($segment_id) {
60
+ $this->_segments_base_route = $this->_base_route.'segments/'.$segment_id;
61
+ }
62
+
63
+ /**
64
+ * Creates a new segment on the given list with the provided details
65
+ * @param int $list_id The list on which to create the segment
66
+ * @param $segment_details The details of the new segment
67
+ * This should be an array of the form
68
+ * array(
69
+ * 'Title' => The title of the new segment
70
+ * 'RuleGroups' => array(
71
+ * array(
72
+ * 'Rules' => array(
73
+ * array(
74
+ * 'RuleType' => The subject of this rule
75
+ * 'Clause' => The specific clauses for this rule
76
+ * )
77
+ * )
78
+ * )
79
+ * )
80
+ * )
81
+ * @return CS_REST_Wrapper_Result A successful response will be the ID of the newly created segment
82
+ */
83
+ function create($list_id, $segment_details) {
84
+ return $this->post_request($this->_base_route.'segments/'.$list_id.'.json', $segment_details);
85
+ }
86
+
87
+ /**
88
+ * Updates the current segment with the provided details. Calls to this route will clear any existing rules
89
+ * @param $segment_details The new details for the segment
90
+ * This should be an array of the form
91
+ * array(
92
+ * 'Title' => The title of the new segment
93
+ * 'RuleGroups' => array(
94
+ * array(
95
+ * 'Rules' => array(
96
+ * array(
97
+ * 'RuleType' => The subject of this rule
98
+ * 'Clause' => The specific clauses for this rule
99
+ * )
100
+ * )
101
+ * )
102
+ * )
103
+ * )
104
+ * @return CS_REST_Wrapper_Result A successful response will be empty
105
+ */
106
+ function update($segment_details) {
107
+ return $this->put_request($this->_segments_base_route.'.json', $segment_details);
108
+ }
109
+
110
+ /**
111
+ * Adds the given rule to the current segment
112
+ * @param $rule The rule to add to the segment
113
+ * This should be an array of the form
114
+ * array(
115
+ * 'Rules' => array(
116
+ * array(
117
+ * 'RuleType' => The subject of this rule
118
+ * 'Clause' => The specific clauses for this rule
119
+ * )
120
+ * )
121
+ * )
122
+ * @return CS_REST_Wrapper_Result A successful response will be empty
123
+ */
124
+ function add_rulegroup($rulegroup) {
125
+ return $this->post_request($this->_segments_base_route.'/rules.json', $rulegroup);
126
+ }
127
+
128
+ /**
129
+ * Gets the details of the current segment
130
+ * @access public
131
+ * @return CS_REST_Wrapper_Result A successful response will be an object of the form
132
+ * {
133
+ * 'ActiveSubscribers' => The number of active subscribers in this segment
134
+ * 'Rules' => array(
135
+ * {
136
+ * 'Subject' => The subject of the rule
137
+ * 'Clauses' => array<string> The clauses making up this segment rule
138
+ * }
139
+ * ),
140
+ * 'ListID' => The ID of the list on which this segment is applied
141
+ * 'SegmentID' => The ID of this segment
142
+ * 'Title' => The title of this segment
143
+ * }
144
+ */
145
+ function get() {
146
+ return $this->get_request($this->_segments_base_route.'.json');
147
+ }
148
+
149
+ /**
150
+ * Deletes an existing segment from the system
151
+ * @access public
152
+ * @return CS_REST_Wrapper_Result A successful response will be empty
153
+ */
154
+ function delete() {
155
+ return $this->delete_request($this->_segments_base_route.'.json');
156
+ }
157
+
158
+ /**
159
+ * Deletes all rules for the current segment
160
+ * @access public
161
+ * @return CS_REST_Wrapper_Result A successful response will be empty
162
+ */
163
+ function clear_rules() {
164
+ return $this->delete_request($this->_segments_base_route.'/rules.json');
165
+ }
166
+
167
+ /**
168
+ * Gets a paged collection of subscribers which fall into the given segment
169
+ * @param string $subscribed_since The date to start getting subscribers from
170
+ * @param int $page_number The page number to get
171
+ * @param int $page_size The number of records per page
172
+ * @param string $order_field The field to order the record set by ('EMAIL', 'NAME', 'DATE')
173
+ * @param string $order_direction The direction to order the record set ('ASC', 'DESC')
174
+ * @access public
175
+ * @return CS_REST_Wrapper_Result A successful response will be an object of the form
176
+ * {
177
+ * 'ResultsOrderedBy' => The field the results are ordered by
178
+ * 'OrderDirection' => The order direction
179
+ * 'PageNumber' => The page number for the result set
180
+ * 'PageSize' => The page size used
181
+ * 'RecordsOnThisPage' => The number of records returned
182
+ * 'TotalNumberOfRecords' => The total number of records available
183
+ * 'NumberOfPages' => The total number of pages for this collection
184
+ * 'Results' => array(
185
+ * {
186
+ * 'EmailAddress' => The email address of the subscriber
187
+ * 'Name' => The name of the subscriber
188
+ * 'Date' => The date that the subscriber was added to the list
189
+ * 'State' => The current state of the subscriber, will be 'Active'
190
+ * 'CustomFields' => array (
191
+ * {
192
+ * 'Key' => The personalisation tag of the custom field
193
+ * 'Value' => The value of the custom field for this subscriber
194
+ * }
195
+ * )
196
+ * }
197
+ * )
198
+ * }
199
+ */
200
+ function get_subscribers($subscribed_since = '', $page_number = NULL,
201
+ $page_size = NULL, $order_field = NULL, $order_direction = NULL) {
202
+
203
+ return $this->get_request_paged($this->_segments_base_route.'/active.json?date='.urlencode($subscribed_since),
204
+ $page_number, $page_size, $order_field, $order_direction);
205
+ }
206
+ }
includes/vendor/campaign-monitor/csrest_subscribers.php ADDED
@@ -0,0 +1,231 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ require_once dirname(__FILE__).'/class/base_classes.php';
3
+
4
+ /**
5
+ * Class to access a subscribers resources from the create send API.
6
+ * This class includes functions to add and remove subscribers ,
7
+ * along with accessing statistics for a single subscriber
8
+ * @author tobyb
9
+ *
10
+ */
11
+ class CS_REST_Subscribers extends CS_REST_Wrapper_Base {
12
+
13
+ /**
14
+ * The base route of the subscriber resource.
15
+ * @var string
16
+ * @access private
17
+ */
18
+ var $_subscribers_base_route;
19
+
20
+ /**
21
+ * Constructor.
22
+ * @param $list_id string The list id to access (Ignored for create requests)
23
+ * @param $auth_details array Authentication details to use for API calls.
24
+ * This array must take one of the following forms:
25
+ * If using OAuth to authenticate:
26
+ * array(
27
+ * 'access_token' => 'your access token',
28
+ * 'refresh_token' => 'your refresh token')
29
+ *
30
+ * Or if using an API key:
31
+ * array('api_key' => 'your api key')
32
+ * @param $protocol string The protocol to use for requests (http|https)
33
+ * @param $debug_level int The level of debugging required CS_REST_LOG_NONE | CS_REST_LOG_ERROR | CS_REST_LOG_WARNING | CS_REST_LOG_VERBOSE
34
+ * @param $host string The host to send API requests to. There is no need to change this
35
+ * @param $log CS_REST_Log The logger to use. Used for dependency injection
36
+ * @param $serialiser The serialiser to use. Used for dependency injection
37
+ * @param $transport The transport to use. Used for dependency injection
38
+ * @access public
39
+ */
40
+ function CS_REST_Subscribers (
41
+ $list_id,
42
+ $auth_details,
43
+ $protocol = 'https',
44
+ $debug_level = CS_REST_LOG_NONE,
45
+ $host = 'api.createsend.com',
46
+ $log = NULL,
47
+ $serialiser = NULL,
48
+ $transport = NULL) {
49
+
50
+ $this->CS_REST_Wrapper_Base($auth_details, $protocol, $debug_level, $host, $log, $serialiser, $transport);
51
+ $this->set_list_id($list_id);
52
+
53
+ }
54
+
55
+ /**
56
+ * Change the list id used for calls after construction
57
+ * @param $list_id
58
+ * @access public
59
+ */
60
+ function set_list_id($list_id) {
61
+ $this->_subscribers_base_route = $this->_base_route.'subscribers/'.$list_id;
62
+ }
63
+
64
+ /**
65
+ * Adds a new subscriber to the specified list
66
+ * @param array $subscriber The subscriber details to use during creation.
67
+ * This array should be of the form
68
+ * array (
69
+ * 'EmailAddress' => The new subscribers email address
70
+ * 'Name' => The name of the new subscriber
71
+ * 'CustomFields' => array(
72
+ * array(
73
+ * 'Key' => The custom fields personalisation tag
74
+ * 'Value' => The value for this subscriber
75
+ * )
76
+ * )
77
+ * 'Resubscribe' => Whether we should resubscribe this subscriber if they already exist in the list
78
+ * 'RestartSubscriptionBasedAutoResponders' => Whether we should restart subscription based auto responders which are sent when the subscriber first subscribes to a list.
79
+ * )
80
+ * @access public
81
+ * @return CS_REST_Wrapper_Result A successful response will be empty
82
+ */
83
+ function add($subscriber) {
84
+ return $this->post_request($this->_subscribers_base_route.'.json', $subscriber);
85
+ }
86
+
87
+ /**
88
+ * Updates an existing subscriber (email, name, state, or custom fields) in the specified list.
89
+ * The update is performed even for inactive subscribers, but will return an error in the event of the
90
+ * given email not existing in the list.
91
+ * @param string $email The email address of the susbcriber to be updated
92
+ * @param array $subscriber The subscriber details to use for the update. Empty parameters will remain unchanged
93
+ * This array should be of the form
94
+ * array (
95
+ * 'EmailAddress' => The new email address
96
+ * 'Name' => The name of the subscriber
97
+ * 'CustomFields' => array(
98
+ * array(
99
+ * 'Key' => The custom fields personalisation tag
100
+ * 'Value' => The value for this subscriber
101
+ * 'Clear' => true/false (pass true to remove this custom field. in the case of a [multi-option, select many] field, pass an option in the 'Value' field to clear that option or leave Value blank to remove all options)
102
+ * )
103
+ * )
104
+ * 'Resubscribe' => Whether we should resubscribe this subscriber if they already exist in the list
105
+ * 'RestartSubscriptionBasedAutoResponders' => Whether we should restart subscription based auto responders which are sent when the subscriber first subscribes to a list.
106
+ * )
107
+ * @access public
108
+ * @return CS_REST_Wrapper_Result A successful response will be empty
109
+ */
110
+ function update($email, $subscriber) {
111
+ return $this->put_request($this->_subscribers_base_route.'.json?email='.urlencode($email), $subscriber);
112
+ }
113
+
114
+ /**
115
+ * Imports an array of subscribers into the current list
116
+ * @param array $subscribers An array of subscribers to import.
117
+ * This array should be of the form
118
+ * array (
119
+ * array (
120
+ * 'EmailAddress' => The new subscribers email address
121
+ * 'Name' => The name of the new subscriber
122
+ * 'CustomFields' => array(
123
+ * array(
124
+ * 'Key' => The custom fields personalisation tag
125
+ * 'Value' => The value for this subscriber
126
+ * 'Clear' => true/false (pass true to remove this custom field. in the case of a [multi-option, select many] field, pass an option in the 'Value' field to clear that option or leave Value blank to remove all options)
127
+ * )
128
+ * )
129
+ * )
130
+ * )
131
+ * @param $resubscribe Whether we should resubscribe any existing subscribers
132
+ * @param $queueSubscriptionBasedAutoResponders By default, subscription based auto responders do not trigger during an import. Pass a value of true to override this behaviour
133
+ * @param $restartSubscriptionBasedAutoResponders By default, subscription based auto responders will not be restarted
134
+ * @access public
135
+ * @return CS_REST_Wrapper_Result A successful response will be an object of the form
136
+ * {
137
+ * 'TotalUniqueEmailsSubmitted' => The number of unique emails submitted in the call
138
+ * 'TotalExistingSubscribers' => The number of subscribers who already existed in the list
139
+ * 'TotalNewSubscribers' => The number of new subscriptions to the list
140
+ * 'DuplicateEmailsInSubmission' => array<string> The emails which appeared more than once in the batch
141
+ * 'FailureDetails' => array (
142
+ * {
143
+ * 'EmailAddress' => The email address which failed
144
+ * 'Code' => The Create Send API Error code
145
+ * 'Message' => The reason for the failure
146
+ * }
147
+ * )
148
+ * }
149
+ *
150
+ */
151
+ function import($subscribers, $resubscribe, $queueSubscriptionBasedAutoResponders = false, $restartSubscriptionBasedAutoResponders = false) {
152
+ $subscribers = array(
153
+ 'Resubscribe' => $resubscribe,
154
+ 'QueueSubscriptionBasedAutoResponders' => $queueSubscriptionBasedAutoResponders,
155
+ 'Subscribers' => $subscribers,
156
+ 'RestartSubscriptionBasedAutoresponders' => $restartSubscriptionBasedAutoResponders
157
+ );
158
+
159
+ return $this->post_request($this->_subscribers_base_route.'/import.json', $subscribers);
160
+ }
161
+
162
+ /**
163
+ * Gets a subscriber details, including custom fields
164
+ * @access public
165
+ * @return CS_REST_Wrapper_Result A successful response will be an object of the form
166
+ * {
167
+ * 'EmailAddress' => The subscriber email address
168
+ * 'Name' => The subscribers name
169
+ * 'Date' => The date the subscriber was added to the list
170
+ * 'State' => The current state of the subscriber
171
+ * 'CustomFields' => array(
172
+ * {
173
+ * 'Key' => The custom fields personalisation tag
174
+ * 'Value' => The custom field value for this subscriber
175
+ * }
176
+ * )
177
+ * }
178
+ */
179
+ function get($email) {
180
+ return $this->get_request($this->_subscribers_base_route.'.json?email='.urlencode($email));
181
+ }
182
+
183
+ /**
184
+ * Gets the sending history to a specific subscriber
185
+ * @access public
186
+ * @return CS_REST_Wrapper_Result A successful response will be an object of the form
187
+ * array(
188
+ * {
189
+ * ID => The id of the email which was sent
190
+ * Type => 'Campaign'
191
+ * Name => The name of the email
192
+ * Actions => array(
193
+ * {
194
+ * Event => The type of action (Click, Open, Unsubscribe etc)
195
+ * Date => The date the event occurred
196
+ * IPAddress => The IP that the event originated from
197
+ * Detail => Any available details about the event i.e the URL for clicks
198
+ * }
199
+ * )
200
+ * }
201
+ * )
202
+ */
203
+ function get_history($email) {
204
+ return $this->get_request($this->_subscribers_base_route.'/history.json?email='.urlencode($email));
205
+ }
206
+
207
+ /**
208
+ * Unsubscribes the given subscriber from the current list
209
+ * @param string $email The email address to unsubscribe
210
+ * @access public
211
+ * @return CS_REST_Wrapper_Result A successful response will be empty
212
+ */
213
+ function unsubscribe($email) {
214
+ // We need to build the subscriber data structure.
215
+ $email = array(
216
+ 'EmailAddress' => $email
217
+ );
218
+
219
+ return $this->post_request($this->_subscribers_base_route.'/unsubscribe.json', $email);
220
+ }
221
+
222
+ /**
223
+ * deletes the given subscriber from the current list
224
+ * @param string $email The email address to delete
225
+ * @access public
226
+ * @return CS_REST_Wrapper_Result A successful response will be empty
227
+ */
228
+ function delete($email) {
229
+ return $this->delete_request($this->_subscribers_base_route.'.json?email='.urlencode($email));
230
+ }
231
+ }
includes/vendor/campaign-monitor/csrest_templates.php ADDED
@@ -0,0 +1,118 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ require_once dirname(__FILE__).'/class/base_classes.php';
3
+
4
+ /**
5
+ * Class to access a templates resources from the create send API.
6
+ * This class includes functions to create update and delete templates
7
+ * @author tobyb
8
+ *
9
+ */
10
+ class CS_REST_Templates extends CS_REST_Wrapper_Base {
11
+
12
+ /**
13
+ * The base route of the lists resource.
14
+ * @var string
15
+ * @access private
16
+ */
17
+ var $_templates_base_route;
18
+
19
+ /**
20
+ * Constructor.
21
+ * @param $list_id string The template id to access (Ignored for create requests)
22
+ * @param $auth_details array Authentication details to use for API calls.
23
+ * This array must take one of the following forms:
24
+ * If using OAuth to authenticate:
25
+ * array(
26
+ * 'access_token' => 'your access token',
27
+ * 'refresh_token' => 'your refresh token')
28
+ *
29
+ * Or if using an API key:
30
+ * array('api_key' => 'your api key')
31
+ * @param $protocol string The protocol to use for requests (http|https)
32
+ * @param $debug_level int The level of debugging required CS_REST_LOG_NONE | CS_REST_LOG_ERROR | CS_REST_LOG_WARNING | CS_REST_LOG_VERBOSE
33
+ * @param $host string The host to send API requests to. There is no need to change this
34
+ * @param $log CS_REST_Log The logger to use. Used for dependency injection
35
+ * @param $serialiser The serialiser to use. Used for dependency injection
36
+ * @param $transport The transport to use. Used for dependency injection
37
+ * @access public
38
+ */
39
+ function CS_REST_Templates (
40
+ $template_id,
41
+ $auth_details,
42
+ $protocol = 'https',
43
+ $debug_level = CS_REST_LOG_NONE,
44
+ $host = 'api.createsend.com',
45
+ $log = NULL,
46
+ $serialiser = NULL,
47
+ $transport = NULL) {
48
+
49
+ $this->CS_REST_Wrapper_Base($auth_details, $protocol, $debug_level, $host, $log, $serialiser, $transport);
50
+ $this->set_template_id($template_id);
51
+ }
52
+
53
+ /**
54
+ * Change the template id used for calls after construction
55
+ * @param $template_id
56
+ * @access public
57
+ */
58
+ function set_template_id($template_id) {
59
+ $this->_templates_base_route = $this->_base_route.'templates/'.$template_id.'.json';
60
+ }
61
+
62
+ /**
63
+ * Creates a new template for the specified client based on the provided data
64
+ * @param string $client_id The client to create the template for
65
+ * @param array $template_details The details of the template
66
+ * This should be an array of the form
67
+ * array(
68
+ * 'Name' => The name of the template
69
+ * 'HtmlPageURL' => The url where the template html can be accessed
70
+ * 'ZipFileURL' => The url where the template image zip can be accessed
71
+ * )
72
+ * @access public
73
+ * @return CS_REST_Wrapper_Result A successful response will be the ID of the newly created template
74
+ */
75
+ function create($client_id, $template_details) {
76
+ return $this->post_request($this->_base_route.'templates/'.$client_id.'.json', $template_details);
77
+ }
78
+
79
+ /**
80
+ * Updates the current template with the provided code
81
+ * @param array $template_details The details of the template
82
+ * This should be an array of the form
83
+ * array(
84
+ * 'Name' => The name of the template
85
+ * 'HtmlPageURL' => The url where the template html can be accessed
86
+ * 'ZipFileURL' => The url where the template image zip can be accessed
87
+ * )
88
+ * @access public
89
+ * @return CS_REST_Wrapper_Result A successful response will be empty
90
+ */
91
+ function update($template_details) {
92
+ return $this->put_request($this->_templates_base_route, $template_details);
93
+ }
94
+
95
+ /**
96
+ * Deletes the current template from the system
97
+ * @access public
98
+ * @return CS_REST_Wrapper_Result A successful response will be empty
99
+ */
100
+ function delete() {
101
+ return $this->delete_request($this->_templates_base_route);
102
+ }
103
+
104
+ /**
105
+ * Gets the basic details of the current template
106
+ * @access public
107
+ * @return CS_REST_Wrapper_Result A successful response will be an object of the form
108
+ * {
109
+ * 'TemplateID' => The id of the template
110
+ * 'Name' => The name of the template
111
+ * 'PreviewURL' => A url where the template can be previewed from
112
+ * 'ScreenshotURL' => The url of the template screenshot if one was provided
113
+ * }
114
+ */
115
+ function get() {
116
+ return $this->get_request($this->_templates_base_route);
117
+ }
118
+ }
includes/vendor/getresponse/getresponse.php ADDED
@@ -0,0 +1,576 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * GetResponsePHP is a PHP5 implementation of the GetResponse API
5
+ * @internal This wrapper is incomplete and subject to change.
6
+ * @authors Ben Tadiar <ben@bentadiar.co.uk>, Robert Staddon <robert@abundantdesigns.com>
7
+ * @copyright Copyright (c) 2010 Assembly Studios
8
+ * @link http://www.assemblystudios.co.uk
9
+ * @package GetResponsePHP
10
+ * @version 0.1.1
11
+ */
12
+
13
+ /**
14
+ * GetResponse Class
15
+ * @package GetResponsePHP
16
+ */
17
+ class GetResponse
18
+ {
19
+ /**
20
+ * GetResponse API key
21
+ * http://www.getresponse.com/my_api_key.html
22
+ * @var string
23
+ */
24
+ public $apiKey = 'PASS_API_KEY_WHEN_INSTANTIATING_CLASS';
25
+
26
+ /**
27
+ * GetResponse API URL
28
+ * @var string
29
+ * @access private
30
+ */
31
+ private $apiURL = 'http://api2.getresponse.com';
32
+
33
+ /**
34
+ * Text comparison operators used to filter results
35
+ * @var array
36
+ * @access private
37
+ */
38
+ private $textOperators = array('EQUALS', 'NOT_EQUALS', 'CONTAINS', 'NOT_CONTAINS', 'MATCHES');
39
+
40
+ /**
41
+ * Check cURL extension is loaded and that an API key has been passed
42
+ * @param string $apiKey GetResponse API key
43
+ * @return void
44
+ */
45
+ public function __construct($apiKey = null)
46
+ {
47
+ if(!extension_loaded('curl')) trigger_error('GetResponsePHP requires PHP cURL', E_USER_ERROR);
48
+ if(is_null($apiKey)) trigger_error('API key must be supplied', E_USER_ERROR);
49
+ $this->apiKey = $apiKey;
50
+ }
51
+
52
+ /**
53
+ * Test connection to the API, returns "pong" on success
54
+ * @return string
55
+ */
56
+ public function ping()
57
+ {
58
+ $request = $this->prepRequest('ping');
59
+ $response = $this->execute($request);
60
+ return $response->ping;
61
+ }
62
+
63
+ /**
64
+ * Get basic user account information
65
+ * @return object
66
+ */
67
+ public function getAccountInfo()
68
+ {
69
+ $request = $this->prepRequest('get_account_info');
70
+ $response = $this->execute($request);
71
+ return $response;
72
+ }
73
+
74
+ /**
75
+ * Get list of email addresses assigned to account
76
+ * @return object
77
+ */
78
+ public function getAccountFromFields()
79
+ {
80
+ $request = $this->prepRequest('get_account_from_fields');
81
+ $response = $this->execute($request);
82
+ return $response;
83
+ }
84
+
85
+ /**
86
+ * Get single email address assigned to an account using the account From Field ID
87
+ * @param string $id
88
+ * @return object
89
+ */
90
+ public function getAccountFromFieldByID($id)
91
+ {
92
+ $request = $this->prepRequest('get_account_from_field', array('account_from_field' => $id));
93
+ $response = $this->execute($request);
94
+ return $response;
95
+ }
96
+
97
+ /**
98
+ * Get single email address assigned to an account using an email address
99
+ * @param string $email
100
+ * @return object
101
+ */
102
+ public function getAccountFromFieldsByEmail($email)
103
+ {
104
+ $request = $this->prepRequest('get_account_from_fields');
105
+ $response = $this->execute($request);
106
+ foreach($response as $key => $account) if($account->email!=$email) unset($response->$key);
107
+ return $response;
108
+ }
109
+
110
+ /**
111
+ * Get a list of active campaigns, optionally filtered
112
+ * @param string $operator Comparison operator
113
+ * @param string $comparison Text/expression to compare against
114
+ * @return object
115
+ */
116
+ public function getCampaigns($operator = 'CONTAINS', $comparison = '%')
117
+ {
118
+ $params = null;
119
+ if(in_array($operator, $this->textOperators)) $params = array('name' => array($operator => $comparison));
120
+ $request = $this->prepRequest('get_campaigns', $params);
121
+ $response = $this->execute($request);
122
+ return $response;
123
+ }
124
+
125
+ /**
126
+ * Return a campaign by ID
127
+ * @param string $id Campaign ID
128
+ * @return object
129
+ */
130
+ public function getCampaignByID($id)
131
+ {
132
+ $request = $this->prepRequest('get_campaign', array('campaign' => $id));
133
+ $response = $this->execute($request);
134
+ return $response;
135
+ }
136
+
137
+ /**
138
+ * Return a campaign ID by name
139
+ * @param string $name Campaign Name
140
+ * @return string Campaign ID
141
+ */
142
+ public function getCampaignByName($name)
143
+ {
144
+ $request = $this->prepRequest('get_campaigns', array('name' => array('EQUALS' => $name)));
145
+ $response = $this->execute($request);
146
+ return key($response);
147
+ }
148
+
149
+ /**
150
+ * Return a list of messages, optionally filtered by multiple conditions
151
+ * @todo Implement all conditions, this is unfinished
152
+ * @param array|null $campaigns Optional argument to narrow results by campaign ID
153
+ * @param string|null $type Optional argument to narrow results by "newsletter", "autoresponder", or "draft"
154
+ * @param string $operator
155
+ * @param string $comparison
156
+ * @return object
157
+ */
158
+ public function getMessages($campaigns = null, $type = null, $operator = 'CONTAINS', $comparison = '%')
159
+ {
160
+ $params = null;
161
+ if(is_array($campaigns)) $params['campaigns'] = $campaigns;
162
+ if(is_string($type)) $params['type'] = $type;
163
+ $request = $this->prepRequest('get_messages', $params);
164
+ $response = $this->execute($request);
165
+ return $response;
166
+ }
167
+
168
+ /**
169
+ * Return a message by ID
170
+ * @param string $id Message ID
171
+ * @return object
172
+ */
173
+ public function getMessageByID($id)
174
+ {
175
+ $request = $this->prepRequest('get_message', array('message' => $id));
176
+ $response = $this->execute($request);
177
+ return $response;
178
+ }
179
+
180
+ /**
181
+ * Return an autoresponder message from a campaign by Cycle Day
182
+ * @param string $campaign Campaign ID
183
+ * @param string $cycle_day Cycle Day
184
+ * @return object
185
+ */
186
+ public function getMessageByCycleDay($campaign, $cycle_day)
187
+ {
188
+ $params['campaigns'] = array($campaign);
189
+ $params['type'] = "autoresponder";
190
+ $request = $this->prepRequest('get_messages', $params);
191
+ $response = $this->execute($request);
192
+ foreach($response as $key => $message) if($message->day_of_cycle!=$cycle_day) unset($response->$key);
193
+ return $response;
194
+ }
195
+
196
+ /**
197
+ * Return message contents by ID
198
+ * @param string $id Message ID
199
+ * @return object
200
+ */
201
+ public function getMessageContents($id)
202
+ {
203
+ $request = $this->prepRequest('get_message_contents', array('message' => $id));
204
+ $response = $this->execute($request);
205
+ return $response;
206
+ }
207
+
208
+ /**
209
+ * Return message statistics
210
+ * @param string $message Message ID
211
+ * @param string $grouping grouping
212
+ * @return object|null
213
+ */
214
+ public function getMessageStats($message, $grouping = "yearly")
215
+ {
216
+ $params['message'] = $message;
217
+ $params['grouping'] = $grouping;
218
+ $request = $this->prepRequest('get_message_stats', $params);
219
+ $response = $this->execute($request);
220
+ return $response;
221
+ }
222
+
223
+ /**
224
+ * Return autoresponder message contents by Cycle Day
225
+ * @param string $campaign Campaign ID
226
+ * @param string $cycle_day Cycle Day
227
+ * @return object|null
228
+ */
229
+ public function getMessageContentsByCycleDay($campaign, $cycle_day)
230
+ {
231
+ $params['campaigns'] = array($campaign);
232
+ $params['type'] = "autoresponder";
233
+ $request = $this->prepRequest('get_messages', $params);
234
+ $response = $this->execute($request);
235
+ foreach($response as $key => $message) if($message->day_of_cycle==$cycle_day) return $this->getMessageContents($key);
236
+ return null;
237
+ }
238
+
239
+ /**
240
+ * Add autoresponder to a campaign at a specific day of cycle
241
+ * @param string $campaign Campaign ID
242
+ * @param string $subject Subject of message
243
+ * @param array $contents Allowed keys are "plain" and "html", at least one is mandatory
244
+ * @param int $cycle_day
245
+ * @param string $from_field From Field ID obtained through getAccountFromFields()
246
+ * @param array $flags Enables extra functionality for a message: "clicktrack", "subscription_reminder", "openrate", "google_analytics"
247
+ * @return object
248
+ */
249
+ public function addAutoresponder($campaign, $subject, $cycle_day, $html = null, $plain = null, $from_field = null, $flags = null)
250
+ {
251
+ $params = array('campaign' => $campaign, 'subject' => $subject, 'day_of_cycle' => $cycle_day);
252
+ if(is_string($html)) $params['contents']['html'] = $html;
253
+ if(is_string($plain)) $params['contents']['plain'] = $plain;
254
+ if(is_string($from_field)) $params['from_field'] = $from_field;
255
+ if(is_array($flags)) $params['flags'] = $flags;
256
+ $request = $this->prepRequest('add_autoresponder', $params);
257
+ $response = $this->execute($request);
258
+ return $response;
259
+ }
260
+
261
+ /**
262
+ * Delete an autoresponder
263
+ * @param string $id
264
+ * @return object
265
+ */
266
+ public function deleteAutoresponder($id)
267
+ {
268
+ $request = $this->prepRequest('delete_autoresponder', array('message' => $id));
269
+ $response = $this->execute($request);
270
+ return $response;
271
+ }
272
+
273
+ /**
274
+ * Return a list of contacts, optionally filtered by multiple conditions
275
+ * @todo Implement all conditions, this is unfinished
276
+ * @param array|null $campaigns Optional argument to narrow results by campaign ID
277
+ * @param string $operator Optional argument to change operator (default is 'CONTAINS')
278
+ * See https://github.com/GetResponse/DevZone/tree/master/API#operators for additional operator options
279
+ * @param string $comparison
280
+ * @param array $fields (an associative array, the keys of which should enable/disable comparing name or email)
281
+ * @return object
282
+ */
283
+ public function getContacts($campaigns = null, $operator = 'CONTAINS', $comparison = '%', $fields = array('name' => true, 'email' => false))
284
+ {
285
+ $params = null;
286
+ if(is_array($campaigns)) $params['campaigns'] = $campaigns;
287
+ if($fields['name']) $params['name'] = $this->prepTextOp($operator, $comparison);
288
+ if($fields['email']) $params['email'] = $this->prepTextOp($operator, $comparison);
289
+ $request = $this->prepRequest('get_contacts', $params);
290
+ $response = $this->execute($request);
291
+ return $response;
292
+ }
293
+
294
+ /**
295
+ * Return a list of contacts by email address (optionally narrowed by campaign)
296
+ * @param string $email Email Address of Contact (or a string contained in the email address)
297
+ * @param array|null $campaigns Optional argument to narrow results by campaign ID
298
+ * @param string $operator Optional argument to change operator (default is 'CONTAINS')
299
+ * See https://github.com/GetResponse/DevZone/tree/master/API#operators for additional operator options
300
+ * @return object
301
+ */
302
+ public function getContactsByEmail($email, $campaigns = null, $operator = 'CONTAINS')
303
+ {
304
+ $params = null;
305
+ $params['email'] = $this->prepTextOp($operator, $email);
306
+ if(is_array($campaigns)) $params['campaigns'] = $campaigns;
307
+ $request = $this->prepRequest('get_contacts', $params);
308
+ $response = $this->execute($request);
309
+ return $response;
310
+ }
311
+
312
+ /**
313
+ * Return a list of contacts filtered by custom contact information
314
+ * $customs is an associative arrays, the keys of which should correspond to the
315
+ * custom field names of the customers you wish to retrieve.
316
+ * @param array|null $campaigns Optional argument to narrow results by campaign ID
317
+ * @param string $operator
318
+ * @param array $customs
319
+ * @param string $comparison
320
+ * @return object
321
+ */
322
+ public function getContactsByCustoms($campaigns = null, $customs, $operator = 'EQUALS')
323
+ {
324
+ $params = null;
325
+ if(is_array($campaigns)) $params['campaigns'] = $campaigns;
326
+ if(!is_array($customs)) trigger_error('Second argument must be an array', E_USER_ERROR);
327
+ foreach($customs as $key => $val) $params['customs'][] = array('name' => $key, 'content' => $this->prepTextOp($operator, $val));
328
+ $request = $this->prepRequest('get_contacts', $params);
329
+ $response = $this->execute($request);
330
+ return $response;
331
+ }
332
+
333
+ /**
334
+ * Return a contact by ID
335
+ * @param string $id User ID
336
+ * @return object
337
+ */
338
+ public function getContactByID($id)
339
+ {
340
+ $request = $this->prepRequest('get_contact', array('contact' => $id));
341
+ $response = $this->execute($request);
342
+ return $response;
343
+ }
344
+
345
+
346
+ /**
347
+ * Set a contact name
348
+ * @param string $id User ID
349
+ * @return object
350
+ */
351
+ public function setContactName($id, $name)
352
+ {
353
+ $request = $this->prepRequest('set_contact_name', array('contact' => $id, 'name' => $name));
354
+ $response = $this->execute($request);
355
+ return $response;
356
+ }
357
+
358
+ /**
359
+ * Set a contact cycle
360
+ * @param string $id User ID
361
+ * @param int $cycle_day Cycle Day
362
+ * @return object
363
+ */
364
+ public function setContactCycle($id, $cycle_day)
365
+ {
366
+ $request = $this->prepRequest('set_contact_cycle', array('contact' => $id, 'cycle_day' => $cycle_day));
367
+ $response = $this->execute($request);
368
+ return $response;
369
+ }
370
+
371
+ /**
372
+ * Set a contact campaign
373
+ * @param string $id User ID
374
+ * @param string $campaign Campaign ID
375
+ * @return object
376
+ */
377
+ public function setContactCampaign($id, $campaign)
378
+ {
379
+ $request = $this->prepRequest('move_contact', array('contact' => $id, 'campaign' => $campaign));
380
+ $response = $this->execute($request);
381
+ return $response;
382
+ }
383
+
384
+ /**
385
+ * Return a contacts custom information
386
+ * @param string $id User ID
387
+ * @return object
388
+ */
389
+ public function getContactCustoms($id)
390
+ {
391
+ $request = $this->prepRequest('get_contact_customs', array('contact' => $id));
392
+ $response = $this->execute($request);
393
+ return $response;
394
+ }
395
+
396
+
397
+ /**
398
+ * Set custom contact information
399
+ * $customs is an associative array, the keys of which should correspond to the
400
+ * custom field name you wish to add/modify/remove.
401
+ * Actions: added if not present, updated if present, removed if value is null
402
+ * @todo Implement multivalue customs.
403
+ * @param string $id User ID
404
+ * @param array $customs
405
+ * @return object
406
+ */
407
+ public function setContactCustoms($id, $customs)
408
+ {
409
+ if(!is_array($customs)) trigger_error('Second argument must be an array', E_USER_ERROR);
410
+ foreach($customs as $key => $val) $params[] = array('name' => $key, 'content' => $val);
411
+ $request = $this->prepRequest('set_contact_customs', array('contact' => $id, 'customs' => $params));
412
+ $response = $this->execute($request);
413
+ return $response;
414
+ }
415
+
416
+ /**
417
+ * Return a contacts GeoIP
418
+ * @param string $id User ID
419
+ * @return object
420
+ */
421
+ public function getContactGeoIP($id)
422
+ {
423
+ $request = $this->prepRequest('get_contact_geoip', array('contact' => $id));
424
+ $response = $this->execute($request);
425
+ return $response;
426
+ }
427
+
428
+ /**
429
+ * List dates when the messages were opened by contacts
430
+ * @param string $id User ID
431
+ * @return object
432
+ */
433
+ public function getContactOpens($id)
434
+ {
435
+ $request = $this->prepRequest('get_contact_opens', array('contact' => $id));
436
+ $response = $this->execute($request);
437
+ return $response;
438
+ }
439
+
440
+ /**
441
+ * List dates when the links in messages were clicked by contacts
442
+ * @param string $id User ID
443
+ * @return object
444
+ */
445
+ public function getContactClicks($id)
446
+ {
447
+ $request = $this->prepRequest('get_contact_clicks', array('contact' => $id));
448
+ $response = $this->execute($request);
449
+ return $response;
450
+ }
451
+
452
+ /**
453
+ * Add contact to the specified list (Requires email verification by contact)
454
+ * The return value of this function will be "queued", and on subsequent
455
+ * submission of the same email address will be "duplicated".
456
+ * @param string $campaign Campaign ID
457
+ * @param string $name Name of contact
458
+ * @param string $email Email address of contact
459
+ * @param string $action Standard, insert or update
460
+ * @param int $cycle_day
461
+ * @param array $customs
462
+ * @return object
463
+ */
464
+ public function addContact($campaign, $name, $email, $action = 'standard', $cycle_day = 0, $customs = array())
465
+ {
466
+ $params = array('campaign' => $campaign, 'action' => $action, 'name' => $name,
467
+ 'email' => $email, 'cycle_day' => $cycle_day, 'ip' => $_SERVER['REMOTE_ADDR']);
468
+ if(!empty($customs)) {
469
+ foreach($customs as $key => $val) $c[] = array('name' => $key, 'content' => $val);
470
+ $params['customs'] = $c;
471
+ }
472
+ $request = $this->prepRequest('add_contact', $params);
473
+ $response = $this->execute($request);
474
+ return $response;
475
+ }
476
+
477
+ /**
478
+ * Delete a contact
479
+ * @param string $id
480
+ * @return object
481
+ */
482
+ public function deleteContact($id)
483
+ {
484
+ $request = $this->prepRequest('delete_contact', array('contact' => $id));
485
+ $response = $this->execute($request);
486
+ return $response;
487
+ }
488
+
489
+ /**
490
+ * Get blacklist masks on account level
491
+ * Account is determined by API key
492
+ * @return object
493
+ */
494
+ public function getAccountBlacklist()
495
+ {
496
+ $request = $this->prepRequest('get_account_blacklist');
497
+ $response = $this->execute($request);
498
+ return $response;
499
+ }
500
+
501
+ /**
502
+ * Adds blacklist mask on account level
503
+ * @param string $mask
504
+ * @return object
505
+ */
506
+ public function addAccountBlacklist($mask)
507
+ {
508
+ $request = $this->prepRequest('add_account_blacklist', array('mask' => $mask));
509
+ $response = $this->execute($request);
510
+ return $response;
511
+ }
512
+
513
+ /**
514
+ * Delete blacklist mask on account level
515
+ * @param string $mask
516
+ * @return object
517
+ */
518
+ public function deleteAccountBlacklist($mask)
519
+ {
520
+ $request = $this->prepRequest('delete_account_blacklist', array('mask' => $mask));
521
+ $response = $this->execute($request);
522
+ return $response;
523
+ }
524
+
525
+ /**
526
+ * Return a key => value array for text comparison
527
+ * @param string $operator
528
+ * @param mixed $comparison
529
+ * @return array
530
+ * @access private
531
+ */
532
+ private function prepTextOp($operator, $comparison)
533
+ {
534
+ if(!in_array($operator, $this->textOperators)) trigger_error('Invalid text operator', E_USER_ERROR);
535
+ if($operator === 'CONTAINS') $comparison = '%'.$comparison.'%';
536
+ return array($operator => $comparison);
537
+ }
538
+
539
+ /**
540
+ * Return array as a JSON encoded string
541
+ * @param string $method API method to call
542
+ * @param array $params Array of parameters
543
+ * @return string JSON encoded string
544
+ * @access private
545
+ */
546
+ private function prepRequest($method, $params = null, $id = null)
547
+ {
548
+ $array = array($this->apiKey);
549
+ if(!is_null($params)) $array[1] = $params;
550
+ $request = json_encode(array('method' => $method, 'params' => $array, 'id' => $id));
551
+ return $request;
552
+ }
553
+
554
+ /**
555
+ * Executes an API call
556
+ * @param string $request JSON encoded array
557
+ * @return object
558
+ * @access private
559
+ */
560
+ private function execute($request)
561
+ {
562
+ $handle = curl_init($this->apiURL);
563
+ curl_setopt($handle, CURLOPT_POST, 1);
564
+ curl_setopt($handle, CURLOPT_POSTFIELDS, $request);
565
+ curl_setopt($handle, CURLOPT_HEADER, 'Content-type: application/json');
566
+ curl_setopt($handle, CURLOPT_RETURNTRANSFER, true);
567
+ $response = json_decode(curl_exec($handle));
568
+ if(curl_error($handle)) trigger_error(curl_error($handle), E_USER_ERROR);
569
+ $httpCode = curl_getinfo($handle, CURLINFO_HTTP_CODE);
570
+ if(!(($httpCode == '200') || ($httpCode == '204'))) trigger_error('API call failed. Server returned status code '.$httpCode, E_USER_ERROR);
571
+ curl_close($handle);
572
+ if(!$response->error) return $response->result;
573
+ }
574
+ }
575
+
576
+ ?>
includes/vendor/icontact/iContactApi.php ADDED
@@ -0,0 +1,1109 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * @name iContactApi
4
+ * @package iContact
5
+ * @author iContact <www.icontact.com>
6
+ * @description This class is a wrapper for the iContact API.
7
+ * It makes integrating iContact into your app as simple as
8
+ * calling a method.
9
+ * @version 2.0
10
+ **/
11
+ class iContactApi {
12
+
13
+ //////////////////////////////////////////////////////////////////////////////
14
+ /// Properties //////////////////////////////////////////////////////////////
15
+ ////////////////////////////////////////////////////////////////////////////
16
+
17
+ protected static $oInstance = null; // This holds the instance of this class
18
+ protected $iAccountId = null; // This holds the account ID
19
+ protected $iClientFolderId = null; // This holds the client folder ID
20
+ protected $aConfig = array(); // This is our array for pragmatically overriding configuration constants
21
+ protected $aErrors = array(); // This holds the errors encountered with the iContact API
22
+ protected $sLastRequest = null; // This holds the last request JSON
23
+ protected $sLastResponse = null; // This holds the last response JSON
24
+ protected $sRequestUri = null; // This stores the last used URL
25
+ protected $bSandbox = false; // This tells the system whether or not to use the iContact Sandbox or not
26
+ protected $aSearchParameters = array(); // This is our container for search params
27
+ protected $iTotal = 0; // If the results return a total, it will be stored here
28
+ protected $aWarnings = array(); // This holds the warnings encountered with the iContact API
29
+
30
+ //////////////////////////////////////////////////////////////////////////////
31
+ /// Singleton ///////////////////////////////////////////////////////////////
32
+ ////////////////////////////////////////////////////////////////////////////
33
+
34
+ /**
35
+ * This sets the singleton pattern instance
36
+ * @static
37
+ * @access public
38
+ * @param iContactApi $oInstance Instance to set to
39
+ * @return iContactApi $this
40
+ **/
41
+ public static function setInstance($oInstance) {
42
+
43
+ self::$oInstance = $oInstance;
44
+ // Return instance of class
45
+ return self::$oInstance;
46
+ }
47
+
48
+ /**
49
+ * This gets the singleton instance
50
+ * @static
51
+ * @access public
52
+ * @return iContactApi $this
53
+ **/
54
+ public static function getInstance() {
55
+ // Check to see if an instance has already
56
+ // been created
57
+ if (is_null(self::$oInstance)) {
58
+ // If not, return a new instance
59
+ self::$oInstance = new self();
60
+ return self::$oInstance;
61
+ } else {
62
+ // If so, return the previously created
63
+ // instance
64
+ return self::$oInstance;
65
+ }
66
+ }
67
+
68
+ /**
69
+ * This resets the singleton instance to null
70
+ * @static
71
+ * @access public
72
+ * @return void
73
+ **/
74
+ public static function resetInstance() {
75
+ // Reset the instance
76
+ self::$oInstance = null;
77
+ }
78
+
79
+ //////////////////////////////////////////////////////////////////////////////
80
+ /// Constructor /////////////////////////////////////////////////////////////
81
+ ////////////////////////////////////////////////////////////////////////////
82
+
83
+ /**
84
+ * This is our constuctor and simply checks for
85
+ * defined constants and configuration values and
86
+ * then builds the configuration from that
87
+ * @access protected
88
+ * @return iContactApi $this
89
+ **/
90
+ protected function __construct() {
91
+ // Check for constants
92
+ $aConstantMap = array(
93
+ // 'ICONTACT_APIVERSION',
94
+ // 'ICONTACT_APISANDBOXURL',
95
+ 'ICONTACT_APPID' => 'appId',
96
+ // 'ICONTACT_APIURL',
97
+ 'ICONTACT_APIUSERNAME' => 'apiUsername',
98
+ 'ICONTACT_APIPASSWORD' => 'apiPassword'
99
+ );
100
+ // Loop through the map
101
+ foreach ($aConstantMap as $sConstant => $sConfigKey) {
102
+ // Check for the defined constant
103
+ if (defined($sConstant)) {
104
+ // Set the configuration key to the contant's value
105
+ $this->aConfig[$sConfigKey] = constant($sConstant);
106
+ }
107
+ }
108
+ // Return instance
109
+ return $this;
110
+ }
111
+
112
+ //////////////////////////////////////////////////////////////////////////////
113
+ /// Public //////////////////////////////////////////////////////////////////
114
+ ////////////////////////////////////////////////////////////////////////////
115
+
116
+ /**
117
+ * This method adds a contact to your iContact account
118
+ * @access public
119
+ * @param string $sEmail
120
+ * @param string [$sStatus]
121
+ * @param string [$sPrefix]
122
+ * @param string [$sFirstName]
123
+ * @param string [$sLastName]
124
+ * @param string [$sSuffix]
125
+ * @param string [$sStreet]
126
+ * @param string [$sStreet2]
127
+ * @param string [$sCity]
128
+ * @param string [$sState]
129
+ * @param string [$sPostalCode]
130
+ * @param string [$sPhone]
131
+ * @param string [$sFax]
132
+ * @param string [$sBusiness]
133
+ *
134
+ * @return object
135
+ **/
136
+ public function addContact($sEmail, $sStatus = 'normal', $sPrefix = null, $sFirstName = null, $sLastName = null, $sSuffix = null, $sStreet = null, $sStreet2 = null, $sCity = null, $sState = null, $sPostalCode = null, $sPhone = null, $sFax = null, $sBusiness = null) {
137
+ // Valid statuses
138
+ $aValidStatuses = array('normal', 'bounced', 'donotcontact', 'pending', 'invitable', 'deleted');
139
+ // Contact placeholder
140
+ $aContact = array(
141
+ 'email' => $sEmail
142
+ );
143
+ // Check for a prefix
144
+ if (!empty($sPrefix)) {
145
+ // Add the new prefix
146
+ $aContact['prefix'] = (string) $sPrefix;
147
+ }
148
+ // Check for a first name
149
+ if (!empty($sFirstName)) {
150
+ // Add the new first name
151
+ $aContact['firstName'] = (string) $sFirstName;
152
+ }
153
+ // Check for a last name
154
+ if (!empty($sLastName)) {
155
+ // Add the new last name
156
+ $aContact['lastName'] = (string) $sLastName;
157
+ }
158
+ // Check for a suffix
159
+ if (!empty($sSuffix)) {
160
+ // Add the new suffix
161
+ $aContact['suffix'] = (string) $sSuffix;
162
+ }
163
+ // Check for a street
164
+ if (!empty($sStreet)) {
165
+ // Add the new street
166
+ $aContact['street'] = (string) $sStreet;
167
+ }
168
+ // Check for a street2
169
+ if (!empty($sStreet2)) {
170
+ // Add the new street 2
171
+ $aContact['street2'] = (string) $sStreet2;
172
+ }
173
+ // Check for a city
174
+ if (!empty($sCity)) {
175
+ // Add the new city
176
+ $aContact['city'] = (string) $sCity;
177
+ }
178
+ // Check for a state
179
+ if (!empty($sState)) {
180
+ // Add the new state
181
+ $aContact['state'] = (string) $sState;
182
+ }
183
+ // Check for a postal code
184
+ if (!empty($sPostalCode)) {
185
+ // Add the new postal code
186
+ $aContact['postalCode'] = (string) $sPostalCode;
187
+ }
188
+ // Check for a phone number
189
+ if (!empty($sPhone)) {
190
+ // Add the new phone number
191
+ $aContact['phone'] = (string) $sPhone;
192
+ }
193
+ // Check for a fax number
194
+ if (!empty($sFax)) {
195
+ // Add the new fax number
196
+ $aContact['fax'] = (string) $sFax;
197
+ }
198
+ // Check for a business name
199
+ if (!empty($sBusiness)) {
200
+ // Add the new business
201
+ $aContact['business'] = (string) $sBusiness;
202
+ }
203
+ // Check for a valid status
204
+ if (!empty($sStatus) && in_array($sStatus, $aValidStatuses)) {
205
+ // Add the new status
206
+ $aContact['status'] = $sStatus;
207
+ } else {
208
+ $aContact['status'] = 'normal';
209
+ }
210
+
211
+ // Make the call
212
+ $aContacts = $this->makeCall("/a/{$this->setAccountId()}/c/{$this->setClientFolderId()}/contacts", 'POST', array($aContact), 'contacts');
213
+ // Return the contact
214
+ return $aContacts[0];
215
+ }
216
+
217
+ /**
218
+ * This method adds a custom field or "term"
219
+ * to the array of search parameters
220
+ * @access public
221
+ * @param string $sName
222
+ * @param string $sValue
223
+ * @return iContactApi $this
224
+ **/
225
+ public function addCustomQueryField($sName, $sValue) {
226
+ // Add the field
227
+ $this->aSearchParameters[$sName] = (string) $sValue;
228
+ // Return instance
229
+ return $this;
230
+ }
231
+
232
+ /**
233
+ * This message adds a list to your iContact account
234
+ * @access public
235
+ * @param string $sName
236
+ * @param integer $iWelcomeMessageId
237
+ * @param bool [$bEmailOwnerOnChange]
238
+ * @param bool [$bWelcomeOnManualAdd]
239
+ * @param bool [$bWelcomeOnSignupAdd]
240
+ * @param string [$sDescription]
241
+ * @param string [$sPublicName]
242
+ * @return object
243
+ **/
244
+ public function addList($sName, $iWelcomeMessageId, $bEmailOwnerOnChange = true, $bWelcomeOnManualAdd = false, $bWelcomeOnSignupAdd = false, $sDescription = null, $sPublicName = null) {
245
+ // Setup the list
246
+ $aList = array(
247
+ 'name' => $sName,
248
+ 'welcomeMessageId' => $iWelcomeMessageId,
249
+ 'emailOwnerOnChange' => intval($bEmailOwnerOnChange),
250
+ 'welcomeOnManualAdd' => intval($bWelcomeOnManualAdd),
251
+ 'welcomeOnSignupAdd' => intval($bWelcomeOnSignupAdd),
252
+ 'description' => $sDescription,
253
+ 'publicname' => $sPublicName
254
+ );
255
+ // Make the call
256
+ $aLists = $this->makeCall("/a/{$this->setAccountId()}/c/{$this->setClientFolderId()}/lists", 'POST', array($aList), 'lists');
257
+ // Return the list
258
+ return $aLists[0];
259
+ }
260
+
261
+ /**
262
+ * This method adds a message to
263
+ * your iContact API account
264
+ * @access public
265
+ * @param string $sSubject
266
+ * @param integer $iCampaignId
267
+ * @param string [$sHtmlBody]
268
+ * @param string [$sTextBody]
269
+ * @param string [$sMessageName]
270
+ * @param integer [$iListId]
271
+ * @param string [$sMessageType]
272
+ * @return object
273
+ **/
274
+ public function addMessage($sSubject, $iCampaignId, $sHtmlBody = null, $sTextBody = null, $sMessageName = null, $iListId = null, $sMessageType = 'normal') {
275
+ // Valid message types
276
+ $aValidMessageTypes = array('normal', 'autoresponder', 'welcome', 'confirmation');
277
+ // Setup the message data
278
+ $aMessage = array(
279
+ 'campaignId' => $iCampaignId,
280
+ 'htmlBody' => $sHtmlBody,
281
+ 'messageName' => $sMessageName,
282
+ 'messageType' => (in_array($sMessageType, $aValidMessageTypes) ? $sMessageType : 'normal'),
283
+ 'subject' => $sSubject,
284
+ 'textBody' => $sTextBody
285
+ );
286
+ // Add the message
287
+ $aNewMessage = $this->makeCall("/a/{$this->setAccountId()}/c/{$this->setClientFolderId()}/messages", 'POST', array($aMessage), 'messages');
288
+ // Return the message data
289
+ return $aNewMessage[0];
290
+ }
291
+
292
+ /**
293
+ * This method adds a field to the order by
294
+ * key in the search parameters array
295
+ * @access public
296
+ * @param string $sField
297
+ * @param string [$sDirection]
298
+ * @return iContactApi $this
299
+ **/
300
+ public function addOrderBy($sField, $sDirection = null) {
301
+ // Check for existing order by parameters
302
+ if (empty($this->aSearchParameters['orderby'])) {
303
+ // Check for a direction
304
+ if (empty($sDirection)) {
305
+ // Add just the field
306
+ $this->aSearchParameters['orderby'] = (string) $sField;
307
+ } else {
308
+ // Add the field and direction
309
+ $this->aSearchParameters['orderby'] = (string) "{$sField}:{$sDirection}";
310
+ }
311
+ } else {
312
+ // Check for a direction
313
+ if (empty($sDirection)) {
314
+ // Append just the field
315
+ $this->aSearchParameters['orderby'] .= (string) ",{$sField}";
316
+ } else {
317
+ // Append the field and direction
318
+ $this->aSearchParameters['orderby'] .= (string) ",{$sField}:{$sDirection}";
319
+ }
320
+ }
321
+ // Return failure
322
+ return false;
323
+ }
324
+
325
+ /**
326
+ * This method handles the deleting of a single list
327
+ * @access public
328
+ * @param integer $iListId
329
+ * @return bool
330
+ **/
331
+ public function deleteList($iListId) {
332
+ // Delete the list
333
+ return $this->makeCall("/a/{$this->setAccountId()}/c/{$this->setClientFolderId()}/lists/{$iListId}", 'delete');
334
+ }
335
+
336
+ /**
337
+ * This method handles the handshaking between this app and the iContact API
338
+ * @access public
339
+ * @param string $sResource
340
+ * @param string $sMethod
341
+ * @param string $sReturnKey
342
+ * @param mixed $mPostData Array, object, or string
343
+ * @return array|object
344
+ **/
345
+ public function makeCall($sResource, $sMethod = 'GET', $mPostData = null, $sReturnKey = null) {
346
+ // List of needed constants
347
+ $aRequiredConfigs = array('apiPassword', 'apiUsername', 'appId');
348
+ // First off check for definitions
349
+ foreach ($aRequiredConfigs as $sKey) {
350
+ // Is it defined
351
+ if (empty($this->aConfig[$sKey])) {
352
+ // Set an error
353
+ $this->addError("{$sKey} is undefined.");
354
+ }
355
+ }
356
+ // Set the URI that we will be calling
357
+ $sApiUrl = (string) "{$this->getUrl()}{$sResource}";
358
+ // Initialize the cURL handle
359
+ $rHandle = curl_init();
360
+ // Give our handle headers
361
+ curl_setopt($rHandle, CURLOPT_HTTPHEADER, $this->getHeaders());
362
+ // Tell our handle that we
363
+ // want the data returned
364
+ curl_setopt($rHandle, CURLOPT_RETURNTRANSFER, true);
365
+ // Turn SSL verifcation off, so scripts do not get broken
366
+ curl_setopt($rHandle, CURLOPT_SSL_VERIFYPEER, false);
367
+ // Determine the request
368
+ // method we are using
369
+ switch (strtoupper($sMethod)) {
370
+ // Deleting data
371
+ case 'DELETE' :
372
+ // Set the cURL custom header
373
+ curl_setopt($rHandle, CURLOPT_CUSTOMREQUEST, 'DELETE');
374
+ break;
375
+ // Recieving data
376
+ case 'GET' :
377
+ // Check for a query string
378
+ if (!empty($this->aSearchParameters)) {
379
+ // Add the query string
380
+ $sApiUrl .= (string) '?'.http_build_query($this->aSearchParameters);
381
+ }
382
+ break;
383
+ // Sending data
384
+ case 'POST' :
385
+ // Check for POST data
386
+ if (empty($mPostData)) {
387
+ // Add an error, for there is no
388
+ // POST data to send to the API
389
+ $this->addError('No POST data was provided.');
390
+ } else {
391
+ // Tell our handle that
392
+ // we want to send data
393
+ curl_setopt($rHandle, CURLOPT_POST, true);
394
+ // Give our handle the data
395
+ curl_setopt($rHandle, CURLOPT_POSTFIELDS, json_encode($mPostData));
396
+ // Set the request JSON
397
+ $this->sLastRequest = (string) json_encode($mPostData);
398
+ }
399
+ break;
400
+ // Uploading data
401
+ case 'PUT' :
402
+ if (empty($mPostData)) {
403
+ // Is there data?
404
+ $this->addError('No file or data specified for PUT request');
405
+ } elseif (!is_string($mPostData) || !file_exists($mPostData)) {
406
+ // Not a file, so we assume this is just data
407
+ curl_setopt($rHandle, CURLOPT_CUSTOMREQUEST, "PUT");
408
+ curl_setopt($rHandle, CURLOPT_POSTFIELDS, $mPostData);
409
+ } else {
410
+ $rFileContentHandle = fopen($mPostData, 'r');
411
+ if ($rFileContentHandle === false) {
412
+ $this->addError('A non-existant file was specified for POST data, or the file could not be opened.');
413
+ } else {
414
+ // Found a file, so upload its contents
415
+ curl_setopt($rHandle, CURLOPT_PUT, true);
416
+ curl_setopt($rHandle, CURLOPT_INFILE, $rFileContentHandle);
417
+ }
418
+ }
419
+ break;
420
+ }
421
+ // Store the URL into the instance
422
+ $this->sRequestUri = (string) $sApiUrl;
423
+ // Give our handle a URL
424
+ curl_setopt($rHandle, CURLOPT_URL, $sApiUrl);
425
+ // Try to execute the handle
426
+ if (!$sResponse = curl_exec($rHandle)) {
427
+ // Add an error, for we could
428
+ // not even execute the handle
429
+ $this->addError('We were unable to execute the cURL handle.');
430
+ }
431
+ // Set the response JSON
432
+ $this->sLastResponse = (string) $sResponse;
433
+ // Try to decode the response
434
+ if ((!$aResponse = json_decode($sResponse)) && (strtoupper($sMethod) != 'DELETE')) {
435
+ // Add an error, for the API
436
+ // did not return valid JSON
437
+ $this->addError('The iContact API did not return valid JSON.');
438
+ }
439
+ // Close the cURL handle
440
+ curl_close($rHandle);
441
+ // Check for errors from the API
442
+ if (!empty($aResponse->errors)) {
443
+ // Loop through the errors
444
+ foreach ($aResponse->errors as $sError) {
445
+ // Add the error
446
+ $this->addError($sError, 1);
447
+ }
448
+ }
449
+ // Check for warnings from the API
450
+ if (!empty($aResponse->warnings)) {
451
+ // Loop through the warnings
452
+ foreach ($aResponse->warnings as $sWarning) {
453
+ // Add the warning
454
+ $this->addWarning($sWarning);
455
+ }
456
+ }
457
+ // Check for set errors
458
+ if (!empty($this->aErrors)) {
459
+ // Throw a new exception
460
+ throw new Exception('Errors have occurred and the system cannot continue. Use getErrors() for details.');
461
+ }
462
+ // Check for a total
463
+ if (!empty($aResponse->total)) {
464
+ // Store the total records
465
+ // into the current instsnce
466
+ $this->iTotal = (integer) $aResponse->total;
467
+ }
468
+ // Return the response
469
+ if (strtoupper($sMethod) == 'DELETE') {
470
+ // Return success
471
+ return true;
472
+ } elseif (empty($sReturnKey)) {
473
+ // Return the entire
474
+ // base response
475
+ return $aResponse;
476
+ } else {
477
+ // Return the narrowed resposne
478
+ return $aResponse->$sReturnKey;
479
+ }
480
+ }
481
+
482
+ /**
483
+ * This method sends a message
484
+ * @access public
485
+ * @param string $sIncludeListId
486
+ * @param integer $iMessageId
487
+ * @param string [$sExcludeListIds]
488
+ * @param string [$sExcludeSegmentIds]
489
+ * @param string [$sIncludeSegmentIds]
490
+ * @param string [$sScheduledTime]
491
+ * @return object
492
+ **/
493
+ public function sendMessage($sIncludeListIds, $iMessageId, $sExcludeListIds = null, $sExcludeSegmentIds = null, $sIncludeSegmentIds = null, $sScheduledTime = null) {
494
+ // Send the message
495
+ $aSends = $this->makeCall("/a/{$this->setAccountId()}/c/{$this->setClientFolderId()}/sends", 'POST', array(
496
+ array(
497
+ 'excludeListIds' => $sExcludeListIds,
498
+ 'excludeSegmentIds' => $sExcludeSegmentIds,
499
+ 'includeListIds' => $sIncludeListIds,
500
+ 'includeSegmentIds' => $sIncludeSegmentIds,
501
+ 'scheduledTime' => (empty($sScheduledTime) ? null : date('c', strtotime($sScheduledTime)))
502
+ )
503
+ ), 'sends');
504
+ // Return the send
505
+ return $aSends;
506
+ }
507
+
508
+ /**
509
+ * This method subscribes a contact to a list
510
+ * @access public
511
+ * @param integer $iContactId
512
+ * @param integer $iListId
513
+ * @param string $sStatus
514
+ * @return object
515
+ **/
516
+ public function subscribeContactToList($iContactId, $iListId, $sStatus = 'normal') {
517
+ // Valid statuses
518
+ $aValidStatuses = array('normal', 'pending', 'unsubscribed');
519
+ // Setup the subscription and make the call
520
+ $aSubscriptions = $this->makeCall("/a/{$this->setAccountId()}/c/{$this->setClientFolderId()}/subscriptions", 'POST', array(
521
+ array(
522
+ 'contactId' => $iContactId,
523
+ 'listId' => $iListId,
524
+ 'status' => $sStatus
525
+ )
526
+ ), 'subscriptions');
527
+ // Return the subscription
528
+ return $aSubscriptions;
529
+ }
530
+
531
+ /**
532
+ * This method updates a contact in your iContact account
533
+ * @access public
534
+ * @param integer $iContactId
535
+ * @param string $sEmail
536
+ * @param string $sPrefix
537
+ * @param string $sFirstName
538
+ * @param string $sLastName
539
+ * @param string $sSuffix
540
+ * @param string $sStreet
541
+ * @param string $sStreet2
542
+ * @param string $sCity
543
+ * @param string $sState
544
+ * @param string $sPostalCode
545
+ * @param string $sPhone
546
+ * @param string $sFax
547
+ * @param string $sBusiness
548
+ * @param string $sStatus
549
+ * @return bool|object
550
+ **/
551
+ public function updateContact($iContactId, $sEmail = null, $sPrefix = null, $sFirstName = null, $sLastName = null, $sSuffix = null, $sStreet = null, $sStreet2 = null, $sCity = null, $sState = null, $sPostalCode = null, $sPhone = null, $sFax = null, $sBusiness = null, $sStatus = null) {
552
+ // Valid statuses
553
+ $aValidStatuses = array('normal', 'bounced', 'donotcontact', 'pending', 'invitable', 'deleted');
554
+ // Contact placeholder
555
+ $aContact = array();
556
+ // Check for an email address
557
+ if (!empty($sEmail)) {
558
+ // Add the new email
559
+ $aContact['email'] = (string) $sEmail;
560
+ }
561
+ // Check for a prefix
562
+ if (!empty($sPrefix)) {
563
+ // Add the new prefix
564
+ $aContact['prefix'] = (string) $sPrefix;
565
+ }
566
+ // Check for a first name
567
+ if (!empty($sFirstName)) {
568
+ // Add the new first name
569
+ $aContact['firstName'] = (string) $sFirstName;
570
+ }
571
+ // Check for a last name
572
+ if (!empty($sLastName)) {
573
+ // Add the new last name
574
+ $aContact['lastName'] = (string) $sLastName;
575
+ }
576
+ // Check for a suffix
577
+ if (!empty($sSuffix)) {
578
+ // Add the new suffix
579
+ $aContact['suffix'] = (string) $sSuffix;
580
+ }
581
+ // Check for a street
582
+ if (!empty($sStreet)) {
583
+ // Add the new street
584
+ $aContact['street'] = (string) $sStreet;
585
+ }
586
+ // Check for a street2
587
+ if (!empty($sStreet2)) {
588
+ // Add the new street 2
589
+ $aContact['street2'] = (string) $sStreet2;
590
+ }
591
+ // Check for a city
592
+ if (!empty($sCity)) {
593
+ // Add the new city
594
+ $aContact['city'] = (string) $sCity;
595
+ }
596
+ // Check for a state
597
+ if (!empty($sState)) {
598
+ // Add the new state
599
+ $aContact['state'] = (string) $sState;
600
+ }
601
+ // Check for a postal code
602
+ if (!empty($sPostalCode)) {
603
+ // Add the new postal code
604
+ $aContact['postalCode'] = (string) $sPostalCode;
605
+ }
606
+ // Check for a phone number
607
+ if (!empty($sPhone)) {
608
+ // Add the new phone number
609
+ $aContact['phone'] = (string) $sPhone;
610
+ }
611
+ // Check for a fax number
612
+ if (!empty($sFax)) {
613
+ // Add the new fax number
614
+ $aContact['fax'] = (string) $sFax;
615
+ }
616
+ // Check for a business name
617
+ if (!empty($sBusiness)) {
618
+ // Add the new business
619
+ $aContact['business'] = (string) $sBusiness;
620
+ }
621
+ // Check for a valid status
622
+ if (!empty($sStatus) && in_array($sStatus, $aValidStatuses)) {
623
+ // Add the new status
624
+ $aContact['status'] = $sStatus;
625
+ }
626
+ // Make sure the contact isn't empty
627
+ if (!empty($aContact)) {
628
+ // Make the call
629
+ $oContact = $this->makeCall("/a/{$this->setAccountId()}/c/{$this->setClientFolderId()}/contacts/{$iContactId}", 'POST', array($aContact), 'contact');
630
+ // Return the contact
631
+ return $oContact;
632
+ }
633
+ // Inevitably return failure
634
+ return false;
635
+ }
636
+
637
+ /**
638
+ * This method uploads a CSV file to the iContact API
639
+ * @access public
640
+ * @param string $sFile
641
+ * @param integer [$iListId]
642
+ * @param integer [$iUploadId]
643
+ * @return string|bool
644
+ **/
645
+ public function uploadData($sFile, $iListId = null, $iUploadId = null) {
646
+ // Check for an upload ID
647
+ if (empty($iUploadId)) {
648
+ // Make the call
649
+ $aUploads = $this->makeCall("/a/{$this->setAccountId()}/c/{$this->setClientFolderId()}/uploads", 'POST', array(
650
+ array(
651
+ 'action' => 'add',
652
+ 'listIds' => $iListId
653
+ )
654
+ ), 'uploads');
655
+ // Store the uploadID
656
+ $iUploadId = $aUploads[0]->uploadId;
657
+ }
658
+ // Upload the data
659
+ if ($this->makeCall("/a/{$this->setAccountId()}/c/{$this->setClientFolderId()}/uploads/{$iUploadId}/data", 'PUT', $sFile, 'uploadId')) {
660
+ // Loop until the upload is complete
661
+ while (true) {
662
+ // Grab the upload
663
+ $aUpload = $this->getUpload($iUploadId);
664
+ // Check to see if the upload
665
+ // has finished uploading
666
+ if ($aUpload->status != 'receiving') {
667
+ // Return the upload
668
+ return $this->makeCall("/a/{$this->setAccountId()}/c{$this->setClientFolderId()}/uploads/{$iUploadId}/data", 'GET');
669
+ }
670
+ }
671
+ }
672
+ // Return failure
673
+ return false;
674
+ }
675
+
676
+ /**
677
+ * This message updates a list on your iContact account
678
+ * @access public
679
+ * @param string $sName
680
+ * @param integer $iListId
681
+ * @param string $sName
682
+ * @param integer $iWelcomeMessageId
683
+ * @param bool [$bEmailOwnerOnChange]
684
+ * @param bool [$bWelcomeOnManualAdd]
685
+ * @param bool [$bWelcomeOnSignupAdd]
686
+ * @param string [$sDescription]
687
+ * @param string [$sPublicName]
688
+ * @return object
689
+ **/
690
+ public function updateList($iListId, $sName, $iWelcomeMessageId, $bEmailOwnerOnChange = true, $bWelcomeOnManualAdd = false, $bWelcomeOnSignupAdd = false, $sDescription = null, $sPublicName = null) {
691
+ // Setup the list
692
+ $aList = array(
693
+ 'name' => $sName,
694
+ 'welcomeMessageId' => $iWelcomeMessageId,
695
+ 'emailOwnerOnChange' => intval($bEmailOwnerOnChange),
696
+ 'welcomeOnManualAdd' => intval($bWelcomeOnManualAdd),
697
+ 'welcomeOnSignupAdd' => intval($bWelcomeOnSignupAdd),
698
+ 'description' => $sDescription,
699
+ 'publicname' => $sPublicName
700
+ );
701
+ // Return the list
702
+ return $this->makeCall("/a/{$this->setAccountId()}/c/{$this->setClientFolderId()}/lists/{$iListId}", 'POST', $aList, 'list');;
703
+ }
704
+
705
+ /**
706
+ * This method tells the system whether
707
+ * or not to use the sandbox or not, the
708
+ * sandbox is turned off by defualt and
709
+ * by default this method turns it on
710
+ * @access public
711
+ * @param bool [$bUse]
712
+ * @return iContactApi $this
713
+ **/
714
+ public function useSandbox($bUse = true) {
715
+ // Set the sandbox status
716
+ $this->bSandbox = (bool) $bUse;
717
+ // Return instance
718
+ return $this;
719
+ }
720
+
721
+ //////////////////////////////////////////////////////////////////////////////
722
+ /// PROTECTED ///////////////////////////////////////////////////////////////
723
+ ////////////////////////////////////////////////////////////////////////////
724
+
725
+ /**
726
+ * This method appends an error to the list
727
+ * of errors encountered with the iContact API
728
+ * @access protected
729
+ * @param string $sText
730
+ * @param integer [$iCode]
731
+ * @return iContactApi $this
732
+ **/
733
+ protected function addError($sText) {
734
+ // Append the error
735
+ array_push($this->aErrors, $sText);
736
+ // Return instance
737
+ return $this;
738
+ }
739
+
740
+ /**
741
+ * This method appends a warning to the list
742
+ * of warnings encountered with the iContact API
743
+ * @access protected
744
+ * @param string $sText
745
+ * @return iContactApi $this
746
+ **/
747
+ public function addWarning($sText) {
748
+ // Append the warning
749
+ array_push($this->aWarnings, $sText);
750
+ // Return instance
751
+ return $this;
752
+ }
753
+
754
+ //////////////////////////////////////////////////////////////////////////////
755
+ /// Getters /////////////////////////////////////////////////////////////////
756
+ ////////////////////////////////////////////////////////////////////////////
757
+
758
+ /**
759
+ * This method grabs the campaigns associated
760
+ * your iContact account
761
+ * @access public
762
+ * @return object
763
+ **/
764
+ public function getCampaigns() {
765
+ // Make the call and return the data
766
+ return $this->makeCall("/a/{$this->setAccountId()}/c/{$this->setClientFolderId()}/campaigns", 'GET');
767
+ }
768
+
769
+ /**
770
+ * This method grabs a single contact
771
+ * from your iContact Account
772
+ * @access public
773
+ * @param integer $iContactId
774
+ * @return object
775
+ **/
776
+ public function getContact($iContactId) {
777
+ // Make the call and return the data
778
+ return $this->makeCall("/a/{$this->setAccountId()}/c/{$this->setClientFolderId()}/contacts/{$iContactId}", 'GET', null, 'contact');
779
+ }
780
+
781
+ /**
782
+ * This method grabs the contacts associated
783
+ * with you iContact API account
784
+ * @access public
785
+ * @return array
786
+ **/
787
+ public function getContacts() {
788
+ // Make the call and return the data
789
+ return $this->makeCall("/a/{$this->setAccountId()}/c/{$this->setClientFolderId()}/contacts", 'GET');
790
+ }
791
+
792
+ /**
793
+ * This method returns any set
794
+ * errors in the current instance
795
+ * @access public
796
+ * @return array|bool
797
+ **/
798
+ public function getErrors() {
799
+ // Check for errors
800
+ if (empty($this->aErrors)) {
801
+ // Return false, for
802
+ // there are no errors
803
+ return false;
804
+ } else {
805
+ // Return the errors
806
+ return $this->aErrors;
807
+ }
808
+ }
809
+
810
+ /**
811
+ * This method builds the header array
812
+ * for making calls to the API
813
+ * @access public
814
+ * @return array
815
+ **/
816
+ public function getHeaders() {
817
+ // Return the headers
818
+ return array(
819
+ 'Except:',
820
+ 'Accept: application/json',
821
+ 'Content-type: application/json',
822
+ 'Api-Version: ' . (defined('ICONTACT_APIVERSION') ? constant('ICONTACT_APIVERSION') : '2.2'),
823
+ 'Api-AppId: ' . (!empty($this->aConfig['appId']) ? $this->aConfig['appId'] : constant('ICONTACT_APPID')),
824
+ 'Api-Username: '. (!empty($this->aConfig['apiUsername']) ? $this->aConfig['apiUsername'] : constant('ICONTACT_APIUSERNAME')),
825
+ 'Api-Password: '. (!empty($this->aConfig['apiPassword']) ? $this->aConfig['apiPassword'] : constant('ICONTACT_APIPASSWORD'))
826
+ );
827
+ }
828
+
829
+ /**
830
+ * This method returns the last
831
+ * API POST request JSON
832
+ * @access public
833
+ * @param bool [$bDecode]
834
+ * @return string|object
835
+ **/
836
+ public function getLastRequest($bDecode = false) {
837
+ // Check to see if we need
838
+ // to decode the raw JSON
839
+ if ($bDecode === true) {
840
+ // Return the decoded JSON
841
+ return json_decode($this->sLastRequest);
842
+ }
843
+ // Return the raw JSON
844
+ return $this->sLastRequest;
845
+ }
846
+
847
+ /**
848
+ * This method returns the last
849
+ * API response JSON
850
+ * @access public
851
+ * @param bool [$bDecode]
852
+ * @return string|object
853
+ **/
854
+ public function getLastResponse($bDecode = false) {
855
+ // Check to see if we need
856
+ // to decode the raw JSON
857
+ if ($bDecode === true) {
858
+ // Return the decoded JSON
859
+ return json_decode($this->sLastResponse);
860
+ }
861
+ // Return the raw JSON
862
+ return $this->sLastResponse;
863
+ }
864
+
865
+ /**
866
+ * This method grabs a list of lists
867
+ * that are associated with you iContact
868
+ * API account
869
+ * @access public
870
+ * @return array
871
+ **/
872
+ public function getLists() {
873
+ // Make the call and return the lists
874
+ return $this->makeCall("/a/{$this->setAccountId()}/c/{$this->setClientFolderId()}/lists", 'GET', null, 'lists');
875
+ }
876
+
877
+ /**
878
+ * This method lists the opens of a
879
+ * single message based on the messageID
880
+ * @access public
881
+ * @param integer iMessageId
882
+ * @return integer
883
+ **/
884
+ public function getMessageOpens($iMessageId) {
885
+ // Make the call and return the data
886
+ return $this->makeCall("/a/{$this->setAccountId()}/c/{$this->setClientFolderId()}/messages/{$iMessageId}/opens", 'GET', null, 'total');
887
+ }
888
+
889
+ public function getMessages($sType = null) {
890
+ // Check for a message type
891
+ if (!empty($sType)) {
892
+ $this->addCustomQueryField('messageType', $sType);
893
+ }
894
+ // Return the messages
895
+ return $this->makeCall("/a/{$this->setAccountId()}/c/{$this->setClientFolderId()}/messages", 'GET', null, 'messages');
896
+ }
897
+
898
+ /**
899
+ * This method returns the URL
900
+ * that the last API request
901
+ * called
902
+ * @access public
903
+ * @return string
904
+ **/
905
+ public function getRequestUri() {
906
+ // Return the URL
907
+ return $this->sRequestUri;
908
+ }
909
+
910
+ /**
911
+ * This method returns the count of the
912
+ * total number of records from the most
913
+ * recent API call, if there is one
914
+ * @access public
915
+ * @return integer
916
+ **/
917
+ public function getTotal() {
918
+ // Return the total records
919
+ return $this->iTotal;
920
+ }
921
+
922
+ /**
923
+ * This method simply returns the base URL for
924
+ * your API/Sandbox account
925
+ * @access public
926
+ * @param bool [$bFull]
927
+ * @return string
928
+ **/
929
+ public function getUrl($bFull = false) {
930
+ // Set the sandbox URL
931
+ $sSandboxUrl = defined('ICONTACT_APISANDBOXURL') ? constant('ICONTACT_APISANDBOXURL') : 'https://app.sandbox.icontact.com/icp';
932
+ // Set the production URL
933
+ $sApiUrl = defined('ICONTACT_APIURL') ? constant('ICONTACT_APIURL') : 'https://app.icontact.com/icp';
934
+ // Determine which one needs to be returned with the URL
935
+ $sBaseUrl = ($this->bSandbox === true) ? $sSandboxUrl : $sApiUrl;
936
+ // Do we need to return the entire url or just
937
+ // the base url of the API service
938
+ if ($bFull === false) {
939
+ // Return the base url
940
+ return $sBaseUrl;
941
+ } else {
942
+ // Return the base url and account details
943
+ return $sBaseUrl . "/a/{$this->setAccountId()}/c/{$this->setClientFolderId()}";
944
+ }
945
+ }
946
+
947
+ /**
948
+ * This method grabs a specific upload
949
+ * @access public
950
+ * @param integer $iUploadId
951
+ * @return object
952
+ **/
953
+ public function getUpload($iUploadId) {
954
+ // Return the upload data
955
+ return $this->makeCall("/a/{$this->setAccountId()}/c{$this->setClientFolderId()}/uploads/{$iUploadId}/data");
956
+ }
957
+
958
+ /**
959
+ * This method grabs the uploads associated
960
+ * with your iContact Account
961
+ * @access public
962
+ * @return array
963
+ **/
964
+ public function getUploads() {
965
+ // Return the uploads
966
+ return $this->makeCall("/a/{$this->setAccountId()}/c{$this->setClientFolderId()}/uploads");
967
+ }
968
+
969
+ /**
970
+ * This method returns the warnings encountered
971
+ * while communicating with the iContact API
972
+ * @access public
973
+ * @return array
974
+ **/
975
+ public function getWarnings() {
976
+ // Return the current system warnings
977
+ return $this->aWarnings;
978
+ }
979
+
980
+ //////////////////////////////////////////////////////////////////////////////
981
+ /// Setters /////////////////////////////////////////////////////////////////
982
+ ////////////////////////////////////////////////////////////////////////////
983
+
984
+ /**
985
+ * This method fetches the Account ID
986
+ * from the iContact API if it has not
987
+ * already been stored in the instance
988
+ * @access public
989
+ * @param integer [$iAccountId]
990
+ * @return integer
991
+ **/
992
+ public function setAccountId($iAccountId = null) {
993
+ // Check for an overriding
994
+ // Account ID
995
+ if (!empty($iAccountId)) {
996
+ // Override the Account ID
997
+ $this->iAccountId = (integer) $iAccountId;
998
+ } else {
999
+ // Check to see if the
1000
+ // Account ID has already
1001
+ // been stored in the
1002
+ // instance
1003
+ if (empty($this->iAccountId)) {
1004
+ // Load the Account ID
1005
+ if ($aAccounts = $this->makeCall('/a/', 'get', null, 'accounts')) {
1006
+ // Set the account
1007
+ $aAccount = $aAccounts[0];
1008
+ // Make sure the account is active
1009
+ if (intval($aAccount->enabled) === 1) {
1010
+ // The account is active
1011
+ // set the Account ID
1012
+ $this->iAccountId = (integer) $aAccount->accountId;
1013
+ } else {
1014
+ // Set an error, for this account
1015
+ // has been disabled
1016
+ $this->addError('Your account has been disabled.');
1017
+ }
1018
+ }
1019
+ }
1020
+ }
1021
+ // Inevitably return instance
1022
+ return $this->iAccountId;
1023
+ }
1024
+
1025
+ /**
1026
+ * This method fetches the Client
1027
+ * Folder ID from the iContact API
1028
+ * if it has not already been stored
1029
+ * in the instance and the Account ID
1030
+ * has also been stored in the instance
1031
+ * @access public
1032
+ * @param integer [$iClientFolderId]
1033
+ * @return integer
1034
+ **/
1035
+ public function setClientFolderId($iClientFolderId = null) {
1036
+ // Check for an overriding
1037
+ // Client Folder ID
1038
+ if (!empty($iClientFolderId)) {
1039
+ // Set the Client Folder ID
1040
+ $this->iClientFolderId = (integer) $iClientFolderId;
1041
+ } elseif (empty($this->iClientFolderId)) {
1042
+ // Check for an Account ID
1043
+ if (empty($this->iAccountId)) {
1044
+ // Set the Account ID
1045
+ $this->setAccountId();
1046
+ }
1047
+ // Set the resource
1048
+ $sResource = (string) "/a/{$this->iAccountId}/c/";
1049
+ // Find the Client Folder ID
1050
+ if ($aClients = $this->makeCall($sResource, 'get', null, 'clientfolders')) {
1051
+ if (empty($aClients)) {
1052
+ // Add an error, for there
1053
+ // are no client folders
1054
+ $this->addError('No client folders were found for this account.');
1055
+ } else {
1056
+ // Grab the default client folder
1057
+ $aClient = $aClients[0];
1058
+ // Set the Client Folder ID
1059
+ $this->iClientFolderId = (integer) $aClient->clientFolderId;
1060
+ }
1061
+ }
1062
+ }
1063
+ // Inevitably return instance
1064
+ return $this->iClientFolderId;
1065
+ }
1066
+
1067
+ /**
1068
+ * This method sets configuration into the
1069
+ * plugin to pragmatically override constants
1070
+ * @access public
1071
+ * @param array $aConfig
1072
+ * @return iContactApi $this
1073
+ **/
1074
+ public function setConfig($aConfig) {
1075
+ // Combine the arrays
1076
+ $this->aConfig = (array) array_merge($this->aConfig, $aConfig);
1077
+ // Return instance
1078
+ return $this;
1079
+ }
1080
+
1081
+ /**
1082
+ * This method sets the result limit
1083
+ * for GET requests to the iContact API
1084
+ * @access public
1085
+ * @param integer $iLimit
1086
+ * @return iContactApi $this
1087
+ **/
1088
+ public function setLimit($iLimit) {
1089
+ // Set the limit in the search parameters
1090
+ $this->aSearchParameters['limit'] = (integer) $iLimit;
1091
+ // Return instance
1092
+ return $this;
1093
+ }
1094
+
1095
+ /**
1096
+ * This method sets the result index
1097
+ * offset for paginating results from
1098
+ * GET requests to the iContact API
1099
+ * @access public
1100
+ * @param integer $iOffset
1101
+ * @return iContactApi $this
1102
+ **/
1103
+ public function setOffset($iOffset) {
1104
+ // Set the offset in the search parameters
1105
+ $this->aSearchParameters['offset'] = (integer) $iOffset;
1106
+ // Return instance
1107
+ return $this;
1108
+ }
1109
+ }
includes/vendor/madmimi/MadMimi.class.php ADDED
@@ -0,0 +1,246 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ Mad Mimi for PHP
4
+ v2.0.3 - Cleaner, faster, and much easier to use and extend. (In my opinion!)
5
+
6
+ For release notes, see the README that should have been included.
7
+
8
+ _______________________________________
9
+
10
+ Copyright (C) 2010 Mad Mimi LLC
11
+ Authored by Nicholas Young <nicholas@madmimi.com> ...and a host of contributors.
12
+
13
+ Permission is hereby granted, free of charge, to any person obtaining a copy
14
+ of this software and associated documentation files (the "Software"), to deal
15
+ in the Software without restriction, including without limitation the rights
16
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
17
+ copies of the Software, and to permit persons to whom the Software is
18
+ furnished to do so, subject to the following conditions:
19
+
20
+ The above copyright notice and this permission notice shall be included in
21
+ all copies or substantial portions of the Software.
22
+
23
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
24
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
26
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
28
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
29
+ THE SOFTWARE.
30
+ */
31
+ if (!class_exists('Spyc')) {
32
+ require("Spyc.class.php");
33
+ }
34
+ if (!function_exists('curl_init')) {
35
+ die('Mad Mimi for PHP requires the PHP cURL extension.');
36
+ }
37
+ class MadMimi {
38
+ function __construct($email, $api_key, $debug = false) {
39
+ $this->username = $email;
40
+ $this->api_key = $api_key;
41
+ $this->debug = $debug;
42
+ }
43
+ function default_options() {
44
+ return array('username' => $this->username, 'api_key' => $this->api_key);
45
+ }
46
+ function DoRequest($path, $options, $return_status = false, $method = 'GET') {
47
+ if ($method == 'GET') {
48
+ $request_options = "?";
49
+ } else {
50
+ $request_options = "";
51
+ }
52
+ $request_options .= http_build_query($options);
53
+ $url = "https://api.madmimi.com{$path}";
54
+ if ($method == 'GET') {
55
+ $url .= $request_options;
56
+ }
57
+ $ch = curl_init();
58
+ curl_setopt($ch, CURLOPT_URL, $url);
59
+ // Fix libcurl vs. apache2
60
+ curl_setopt($ch, CURLOPT_HTTPHEADER, array("Expect:"));
61
+ if ($return_status == true) {
62
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, false);
63
+ } else {
64
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
65
+ }
66
+ switch($method) {
67
+ case 'GET':
68
+ break;
69
+ case 'POST':
70
+ curl_setopt($ch, CURLOPT_POST, TRUE);
71
+ curl_setopt($ch, CURLOPT_POSTFIELDS, $request_options);
72
+ break;
73
+ }
74
+ if ($this->debug == true) {
75
+ echo "URL: {$url}<br />";
76
+ if ($method == 'POST') {
77
+ echo "Request Options: {$request_options}";
78
+ }
79
+ } else {
80
+ $result = curl_exec($ch);
81
+ if( $result === false){
82
+ $error = curl_error($ch);
83
+ echo 'Curl error: ', $error, "\n";
84
+ die($error);
85
+ }
86
+ }
87
+ curl_close($ch);
88
+ if ($this->debug == false) {
89
+ return $result;
90
+ }
91
+ }
92
+ // This took years off my life. Seriously. -lkw
93
+ function escape_for_csv($s) {
94
+ // Watch out! We may have quotes! So quote them.
95
+ $s = str_replace('"', '""', $s);
96
+ if(preg_match('/,/', $s) || preg_match('/"/', $s) || preg_match("/\n/", $s)) {
97
+ // Quote the whole thing b/c we have a newline, comma or quote.
98
+ return '"'.$s.'"';
99
+ } else {
100
+ // False alarm. We're good.
101
+ return $s;
102
+ }
103
+ }
104
+ function build_csv($arr) {
105
+ $csv = "";
106
+ $keys = array_keys($arr);
107
+ foreach ($keys as $key => $value) {
108
+ $value = $this->escape_for_csv($value);
109
+ $csv .= $value . ",";
110
+ }
111
+ $csv = substr($csv, 0, -1);
112
+ $csv .= "\n";
113
+ foreach ($arr as $key => $value) {
114
+ $value = $this->escape_for_csv($value);
115
+ $csv .= $value . ",";
116
+ }
117
+ $csv = substr($csv, 0, -1);
118
+ $csv .= "\n";
119
+ return $csv;
120
+ }
121
+ function Import($csv_data, $return = false) {
122
+ $options = array('csv_file' => $csv_data) + $this->default_options();
123
+ $request = $this->DoRequest('/audience_members', $options, $return, 'POST');
124
+ return $request;
125
+ }
126
+ function Lists($return = false) {
127
+ $request = $this->DoRequest('/audience_lists/lists.xml', $this->default_options(), $return);
128
+ return $request;
129
+ }
130
+ function AddUser($user, $return = false) {
131
+ $csv = $this->build_csv($user);
132
+ return $this->Import($csv, $return);
133
+ }
134
+ function RemoveUser($email, $list_name, $return = false) {
135
+ $options = array('email' => $email) + $this->default_options();
136
+ $request = $this->DoRequest('/audience_lists/' . rawurlencode($list_name) . "/remove", $options, $return, 'POST');
137
+ return $request;
138
+ }
139
+ function Memberships($email, $return = false) {
140
+ $url = str_replace('%email%', $email, '/audience_members/%email%/lists.xml');
141
+ $request = $this->DoRequest($url, $this->default_options(), $return);
142
+ return $request;
143
+ }
144
+ function NewList($list_name, $return = false) {
145
+ $options = array('name' => $list_name) + $this->default_options();
146
+ $request = $this->DoRequest('/audience_lists', $options, $return, 'POST');
147
+ return $request;
148
+ }
149
+ function DeleteList($list_name, $return = false) {
150
+ $options = array('_method' => 'delete') + $this->default_options();
151
+ $request = $this->DoRequest('/audience_lists/' . rawurlencode($list_name), $options, $return, 'POST');
152
+ return $request;
153
+ }
154
+ function SendMessage($options, $yaml_body = null, $return = false) {
155
+ if (class_exists('Spyc') && $yaml_body != null) {
156
+ $options['body'] = Spyc::YAMLDump($yaml_body);
157
+ }
158
+ $options = $options + $this->default_options();
159
+ if (isset($options['list_name'])) {
160
+ $request = $this->DoRequest('/mailer/to_list', $options, $return, 'POST');
161
+ } else {
162
+ $request = $this->DoRequest('/mailer', $options, $return, 'POST');
163
+ }
164
+ return $request;
165
+ }
166
+ function SendHTML($options, $html, $return = false) {
167
+ if ((!strstr($html, '[[tracking_beacon]]')) && (!strstr($html, '[[peek_image]]'))) {
168
+ die('Please include either the [[tracking_beacon]] or the [[peek_image]] macro in your HTML.');
169
+ }
170
+ $options = $options + $this->default_options();
171
+ $options['raw_html'] = $html;
172
+ if (isset($options['list_name'])) {
173
+ $request = $this->DoRequest('/mailer/to_list', $options, $return, 'POST');
174
+ } else {
175
+ $request = $this->DoRequest('/mailer', $options, $return, 'POST');
176
+ }
177
+ return $request;
178
+ }
179
+ function SendPlainText($options, $message, $return = false) {
180
+ if (!strstr($message, '[[unsubscribe]]')) {
181
+ die('Please include the [[unsubscribe]] macro in your text.');
182
+ }
183
+ $options = $options + $this->default_options();
184
+ $options['raw_plain_text'] = $message;
185
+ if (isset($options['list_name'])) {
186
+ $request = $this->DoRequest('/mailer/to_list', $options, $return, 'POST');
187
+ } else {
188
+ $request = $this->DoRequest('/mailer', $options, $return, 'POST');
189
+ }
190
+ return $request;
191
+ }
192
+ function SuppressedSince($unix_timestamp, $return = false) {
193
+ $request = $this->DoRequest('/audience_members/suppressed_since/' . $unix_timestamp . '.txt', $this->default_options(), $return);
194
+ return $request;
195
+ }
196
+ function Promotions($page = 1, $return = false) {
197
+ $options = array('page' => $page) + $this->default_options();
198
+ $request = $this->DoRequest('/promotions.xml', $options, $return);
199
+ return $request;
200
+ }
201
+ function MailingStats($promotion_id, $mailing_id, $return = false) {
202
+ $url = str_replace("%promotion_id%", $promotion_id, "/promotions/%promotion_id%/mailings/%mailing_id%.xml");
203
+ $url = str_replace("%mailing_id%", $mailing_id, $url);
204
+ $request = $this->DoRequest($url, $this->default_options(), $return);
205
+ return $request;
206
+ }
207
+ function Search($query_string, $raw = false, $return = false) {
208
+ $options = array('query' => $query_string, 'raw' => $raw) + $this->default_options();
209
+ $request = $this->DoRequest('/audience_members/search.xml', $options, $return);
210
+ return $request;
211
+ }
212
+ function Events($unix_timestamp, $return = false) {
213
+ $request = $this->DoRequest('/audience_members/events_since/' . $unix_timestamp . '.xml', $this->default_options(), $return);
214
+ return $request;
215
+ }
216
+ function Status($transaction_id, $return = false) {
217
+ $request = $this->DoRequest('/mailers/status/' . $transaction_id, $this->default_options(), $return);
218
+ return $request;
219
+ }
220
+ function Suppress($email, $return = false) {
221
+ $path = str_replace('%email%', $email, '/audience_members/%email%/suppress_email');
222
+ $request = $this->DoRequest($path, $this->default_options(), $return, 'POST');
223
+ return $request;
224
+ }
225
+ function IsSuppressed($email, $return = false) {
226
+ $path = str_replace('%email%', $email, '/audience_members/%email%/is_suppressed');
227
+ $request = $this->DoRequest($path, $this->default_options(), $return, 'POST');
228
+ return $request;
229
+ }
230
+ function Unsuppress($email, $return = false) {
231
+ $csv_data = "email,opt_out\n{$email},0";
232
+ return $this->Import($csv_data, $return);
233
+ }
234
+ function AddMembership($list_name, $email, $additional = array(), $return = false) {
235
+ $options = array('email' => $email) + $additional + $this->default_options();
236
+ $path = '/audience_lists/' . rawurlencode($list_name) . '/add';
237
+ $request = $this->DoRequest($path, $options, $return, 'POST');
238
+ return $request;
239
+ }
240
+ function RemoveMembership($list_name, $email, $return = false) {
241
+ $options = array('email' => $email) + $this->default_options();
242
+ $path = '/audience_lists/' . rawurlencode($list_name) . '/remove';
243
+ $request = $this->DoRequest($path, $options, $return, 'POST');
244
+ return $request;
245
+ }
246
+ }
includes/vendor/madmimi/Spyc.class.php ADDED
@@ -0,0 +1,1024 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Spyc -- A Simple PHP YAML Class
4
+ * @version 0.4.5
5
+ * @author Vlad Andersen <vlad.andersen@gmail.com>
6
+ * @author Chris Wanstrath <chris@ozmm.org>
7
+ * @link http://code.google.com/p/spyc/
8
+ * @copyright Copyright 2005-2006 Chris Wanstrath, 2006-2009 Vlad Andersen
9
+ * @license http://www.opensource.org/licenses/mit-license.php MIT License
10
+ * @package Spyc
11
+ */
12
+
13
+ if (!function_exists('spyc_load')) {
14
+ /**
15
+ * Parses YAML to array.
16
+ * @param string $string YAML string.
17
+ * @return array
18
+ */
19
+ function spyc_load ($string) {
20
+ return Spyc::YAMLLoadString($string);
21
+ }
22
+ }
23
+
24
+ if (!function_exists('spyc_load_file')) {
25
+ /**
26
+ * Parses YAML to array.
27
+ * @param string $file Path to YAML file.
28
+ * @return array
29
+ */
30
+ function spyc_load_file ($file) {
31
+ return Spyc::YAMLLoad($file);
32
+ }
33
+ }
34
+
35
+ /**
36
+ * The Simple PHP YAML Class.
37
+ *
38
+ * This class can be used to read a YAML file and convert its contents
39
+ * into a PHP array. It currently supports a very limited subsection of
40
+ * the YAML spec.
41
+ *
42
+ * Usage:
43
+ * <code>
44
+ * $Spyc = new Spyc;
45
+ * $array = $Spyc->load($file);
46
+ * </code>
47
+ * or:
48
+ * <code>
49
+ * $array = Spyc::YAMLLoad($file);
50
+ * </code>
51
+ * or:
52
+ * <code>
53
+ * $array = spyc_load_file($file);
54
+ * </code>
55
+ * @package Spyc
56
+ */
57
+ class Spyc {
58
+
59
+ // SETTINGS
60
+
61
+ /**
62
+ * Setting this to true will force YAMLDump to enclose any string value in
63
+ * quotes. False by default.
64
+ *
65
+ * @var bool
66
+ */
67
+ public $setting_dump_force_quotes = false;
68
+
69
+ /**
70
+ * Setting this to true will forse YAMLLoad to use syck_load function when
71
+ * possible. False by default.
72
+ * @var bool
73
+ */
74
+ public $setting_use_syck_is_possible = false;
75
+
76
+
77
+
78
+ /**#@+
79
+ * @access private
80
+ * @var mixed
81
+ */
82
+ private $_dumpIndent;
83
+ private $_dumpWordWrap;
84
+ private $_containsGroupAnchor = false;
85
+ private $_containsGroupAlias = false;
86
+ private $path;
87
+ private $result;
88
+ private $LiteralPlaceHolder = '___YAML_Literal_Block___';
89
+ private $SavedGroups = array();
90
+ private $indent;
91
+ /**
92
+ * Path modifier that should be applied after adding current element.
93
+ * @var array
94
+ */
95
+ private $delayedPath = array();
96
+
97
+ /**#@+
98
+ * @access public
99
+ * @var mixed
100
+ */
101
+ public $_nodeId;
102
+
103
+ /**
104
+ * Load a valid YAML string to Spyc.
105
+ * @param string $input
106
+ * @return array
107
+ */
108
+ public function load ($input) {
109
+ return $this->__loadString($input);
110
+ }
111
+
112
+ /**
113
+ * Load a valid YAML file to Spyc.
114
+ * @param string $file
115
+ * @return array
116
+ */
117
+ public function loadFile ($file) {
118
+ return $this->__load($file);
119
+ }
120
+
121
+ /**
122
+ * Load YAML into a PHP array statically
123
+ *
124
+ * The load method, when supplied with a YAML stream (string or file),
125
+ * will do its best to convert YAML in a file into a PHP array. Pretty
126
+ * simple.
127
+ * Usage:
128
+ * <code>
129
+ * $array = Spyc::YAMLLoad('lucky.yaml');
130
+ * print_r($array);
131
+ * </code>
132
+ * @access public
133
+ * @return array
134
+ * @param string $input Path of YAML file or string containing YAML
135
+ */
136
+ public static function YAMLLoad($input) {
137
+ $Spyc = new Spyc;
138
+ return $Spyc->__load($input);
139
+ }
140
+
141
+ /**
142
+ * Load a string of YAML into a PHP array statically
143
+ *
144
+ * The load method, when supplied with a YAML string, will do its best
145
+ * to convert YAML in a string into a PHP array. Pretty simple.
146
+ *
147
+ * Note: use this function if you don't want files from the file system
148
+ * loaded and processed as YAML. This is of interest to people concerned
149
+ * about security whose input is from a string.
150
+ *
151
+ * Usage:
152
+ * <code>
153
+ * $array = Spyc::YAMLLoadString("---\n0: hello world\n");
154
+ * print_r($array);
155
+ * </code>
156
+ * @access public
157
+ * @return array
158
+ * @param string $input String containing YAML
159
+ */
160
+ public static function YAMLLoadString($input) {
161
+ $Spyc = new Spyc;
162
+ return $Spyc->__loadString($input);
163
+ }
164
+
165
+ /**
166
+ * Dump YAML from PHP array statically
167
+ *
168
+ * The dump method, when supplied with an array, will do its best
169
+ * to convert the array into friendly YAML. Pretty simple. Feel free to
170
+ * save the returned string as nothing.yaml and pass it around.
171
+ *
172
+ * Oh, and you can decide how big the indent is and what the wordwrap
173
+ * for folding is. Pretty cool -- just pass in 'false' for either if
174
+ * you want to use the default.
175
+ *
176
+ * Indent's default is 2 spaces, wordwrap's default is 40 characters. And
177
+ * you can turn off wordwrap by passing in 0.
178
+ *
179
+ * @access public
180
+ * @return string
181
+ * @param array $array PHP array
182
+ * @param int $indent Pass in false to use the default, which is 2
183
+ * @param int $wordwrap Pass in 0 for no wordwrap, false for default (40)
184
+ */
185
+ public static function YAMLDump($array,$indent = false,$wordwrap = false) {
186
+ $spyc = new Spyc;
187
+ return $spyc->dump($array,$indent,$wordwrap);
188
+ }
189
+
190
+
191
+ /**
192
+ * Dump PHP array to YAML
193
+ *
194
+ * The dump method, when supplied with an array, will do its best
195
+ * to convert the array into friendly YAML. Pretty simple. Feel free to
196
+ * save the returned string as tasteful.yaml and pass it around.
197
+ *
198
+ * Oh, and you can decide how big the indent is and what the wordwrap
199
+ * for folding is. Pretty cool -- just pass in 'false' for either if
200
+ * you want to use the default.
201
+ *
202
+ * Indent's default is 2 spaces, wordwrap's default is 40 characters. And
203
+ * you can turn off wordwrap by passing in 0.
204
+ *
205
+ * @access public
206
+ * @return string
207
+ * @param array $array PHP array
208
+ * @param int $indent Pass in false to use the default, which is 2
209
+ * @param int $wordwrap Pass in 0 for no wordwrap, false for default (40)
210
+ */
211
+ public function dump($array,$indent = false,$wordwrap = false) {
212
+ // Dumps to some very clean YAML. We'll have to add some more features
213
+ // and options soon. And better support for folding.
214
+
215
+ // New features and options.
216
+ if ($indent === false or !is_numeric($indent)) {
217
+ $this->_dumpIndent = 2;
218
+ } else {
219
+ $this->_dumpIndent = $indent;
220
+ }
221
+
222
+ if ($wordwrap === false or !is_numeric($wordwrap)) {
223
+ $this->_dumpWordWrap = 40;
224
+ } else {
225
+ $this->_dumpWordWrap = $wordwrap;
226
+ }
227
+
228
+ // New YAML document
229
+ $string = "---\n";
230
+
231
+ // Start at the base of the array and move through it.
232
+ if ($array) {
233
+ $array = (array)$array;
234
+ $first_key = key($array);
235
+
236
+ $previous_key = -1;
237
+ foreach ($array as $key => $value) {
238
+ $string .= $this->_yamlize($key,$value,0,$previous_key, $first_key);
239
+ $previous_key = $key;
240
+ }
241
+ }
242
+ return $string;
243
+ }
244
+
245
+ /**
246
+ * Attempts to convert a key / value array item to YAML
247
+ * @access private
248
+ * @return string
249
+ * @param $key The name of the key
250
+ * @param $value The value of the item
251
+ * @param $indent The indent of the current node
252
+ */
253
+ private function _yamlize($key,$value,$indent, $previous_key = -1, $first_key = 0) {
254
+ if (is_array($value)) {
255
+ if (empty ($value))
256
+ return $this->_dumpNode($key, array(), $indent, $previous_key, $first_key);
257
+ // It has children. What to do?
258
+ // Make it the right kind of item
259
+ $string = $this->_dumpNode($key, NULL, $indent, $previous_key, $first_key);
260
+ // Add the indent
261
+ $indent += $this->_dumpIndent;
262
+ // Yamlize the array
263
+ $string .= $this->_yamlizeArray($value,$indent);
264
+ } elseif (!is_array($value)) {
265
+ // It doesn't have children. Yip.
266
+ $string = $this->_dumpNode($key, $value, $indent, $previous_key, $first_key);
267
+ }
268
+ return $string;
269
+ }
270
+
271
+ /**
272
+ * Attempts to convert an array to YAML
273
+ * @access private
274
+ * @return string
275
+ * @param $array The array you want to convert
276
+ * @param $indent The indent of the current level
277
+ */
278
+ private function _yamlizeArray($array,$indent) {
279
+ if (is_array($array)) {
280
+ $string = '';
281
+ $previous_key = -1;
282
+ $first_key = key($array);
283
+ foreach ($array as $key => $value) {
284
+ $string .= $this->_yamlize($key, $value, $indent, $previous_key, $first_key);
285
+ $previous_key = $key;
286
+ }
287
+ return $string;
288
+ } else {
289
+ return false;
290
+ }
291
+ }
292
+
293
+ /**
294
+ * Returns YAML from a key and a value
295
+ * @access private
296
+ * @return string
297
+ * @param $key The name of the key
298
+ * @param $value The value of the item
299
+ * @param $indent The indent of the current node
300
+ */
301
+ private function _dumpNode($key, $value, $indent, $previous_key = -1, $first_key = 0) {
302
+ // do some folding here, for blocks
303
+ if (is_string ($value) && ((strpos($value,"\n") !== false || strpos($value,": ") !== false || strpos($value,"- ") !== false ||
304
+ strpos($value,"*") !== false || strpos($value,"#") !== false || strpos($value,"<") !== false || strpos($value,">") !== false || strpos($value,"!") !== false ||
305
+ strpos($value,"[") !== false || strpos($value,"]") !== false || strpos($value,"{") !== false || strpos($value,"}") !== false) || substr ($value, -1, 1) == ':')) {
306
+ $value = $this->_doLiteralBlock($value,$indent);
307
+ } else {
308
+ $value = $this->_doFolding($value,$indent);
309
+ if (is_bool($value)) {
310
+ $value = ($value) ? "true" : "false";
311
+ }
312
+ }
313
+
314
+ if ($value === array()) $value = '[ ]';
315
+
316
+ $spaces = str_repeat(' ',$indent);
317
+
318
+ if (is_int($key) && $key - 1 == $previous_key && $first_key===0) {
319
+ // It's a sequence
320
+ $string = $spaces.'- '.$value."\n";
321
+ } else {
322
+ if ($first_key===0) throw new Exception('Keys are all screwy. The first one was zero, now it\'s "'. $key .'"');
323
+ // It's mapped
324
+ if (strpos($key, ":") !== false) { $key = '"' . $key . '"'; }
325
+ $string = $spaces.$key.': '.$value."\n";
326
+ }
327
+ return $string;
328
+ }
329
+
330
+ /**
331
+ * Creates a literal block for dumping
332
+ * @access private
333
+ * @return string
334
+ * @param $value
335
+ * @param $indent int The value of the indent
336
+ */
337
+ private function _doLiteralBlock($value,$indent) {
338
+ if (strpos($value, "\n") === false && strpos($value, "'") === false) {
339
+ return sprintf ("'%s'", $value);
340
+ }
341
+ if (strpos($value, "\n") === false && strpos($value, '"') === false) {
342
+ return sprintf ('"%s"', $value);
343
+ }
344
+ $exploded = explode("\n",$value);
345
+ $newValue = '|';
346
+ $indent += $this->_dumpIndent;
347
+ $spaces = str_repeat(' ',$indent);
348
+ foreach ($exploded as $line) {
349
+ $newValue .= "\n" . $spaces . trim($line);
350
+ }
351
+ return $newValue;
352
+ }
353
+
354
+ /**
355
+ * Folds a string of text, if necessary
356
+ * @access private
357
+ * @return string
358
+ * @param $value The string you wish to fold
359
+ */
360
+ private function _doFolding($value,$indent) {
361
+ // Don't do anything if wordwrap is set to 0
362
+
363
+ if ($this->_dumpWordWrap !== 0 && is_string ($value) && strlen($value) > $this->_dumpWordWrap) {
364
+ $indent += $this->_dumpIndent;
365
+ $indent = str_repeat(' ',$indent);
366
+ $wrapped = wordwrap($value,$this->_dumpWordWrap,"\n$indent");
367
+ $value = ">\n".$indent.$wrapped;
368
+ } else {
369
+ if ($this->setting_dump_force_quotes && is_string ($value))
370
+ $value = '"' . $value . '"';
371
+ }
372
+
373
+
374
+ return $value;
375
+ }
376
+
377
+ // LOADING FUNCTIONS
378
+
379
+ private function __load($input) {
380
+ $Source = $this->loadFromSource($input);
381
+ return $this->loadWithSource($Source);
382
+ }
383
+
384
+ private function __loadString($input) {
385
+ $Source = $this->loadFromString($input);
386
+ return $this->loadWithSource($Source);
387
+ }
388
+
389
+ private function loadWithSource($Source) {
390
+ if (empty ($Source)) return array();
391
+ if ($this->setting_use_syck_is_possible && function_exists ('syck_load')) {
392
+ $array = syck_load (implode ('', $Source));
393
+ return is_array($array) ? $array : array();
394
+ }
395
+
396
+ $this->path = array();
397
+ $this->result = array();
398
+
399
+ $cnt = count($Source);
400
+ for ($i = 0; $i < $cnt; $i++) {
401
+ $line = $Source[$i];
402
+
403
+ $this->indent = strlen($line) - strlen(ltrim($line));
404
+ $tempPath = $this->getParentPathByIndent($this->indent);
405
+ $line = self::stripIndent($line, $this->indent);
406
+ if (self::isComment($line)) continue;
407
+ if (self::isEmpty($line)) continue;
408
+ $this->path = $tempPath;
409
+
410
+ $literalBlockStyle = self::startsLiteralBlock($line);
411
+ if ($literalBlockStyle) {
412
+ $line = rtrim ($line, $literalBlockStyle . " \n");
413
+ $literalBlock = '';
414
+ $line .= $this->LiteralPlaceHolder;
415
+
416
+ while (++$i < $cnt && $this->literalBlockContinues($Source[$i], $this->indent)) {
417
+ $literalBlock = $this->addLiteralLine($literalBlock, $Source[$i], $literalBlockStyle);
418
+ }
419
+ $i--;
420
+ }
421
+
422
+ while (++$i < $cnt && self::greedilyNeedNextLine($line)) {
423
+ $line = rtrim ($line, " \n\t\r") . ' ' . ltrim ($Source[$i], " \t");
424
+ }
425
+ $i--;
426
+
427
+
428
+
429
+ if (strpos ($line, '#')) {
430
+ if (strpos ($line, '"') === false && strpos ($line, "'") === false)
431
+ $line = preg_replace('/\s+#(.+)$/','',$line);
432
+ }
433
+
434
+ $lineArray = $this->_parseLine($line);
435
+
436
+ if ($literalBlockStyle)
437
+ $lineArray = $this->revertLiteralPlaceHolder ($lineArray, $literalBlock);
438
+
439
+ $this->addArray($lineArray, $this->indent);
440
+
441
+ foreach ($this->delayedPath as $indent => $delayedPath)
442
+ $this->path[$indent] = $delayedPath;
443
+
444
+ $this->delayedPath = array();
445
+
446
+ }
447
+ return $this->result;
448
+ }
449
+
450
+ private function loadFromSource ($input) {
451
+ if (!empty($input) && strpos($input, "\n") === false && file_exists($input))
452
+ return file($input);
453
+
454
+ return $this->loadFromString($input);
455
+ }
456
+
457
+ private function loadFromString ($input) {
458
+ $lines = explode("\n",$input);
459
+ foreach ($lines as $k => $_) {
460
+ $lines[$k] = rtrim ($_, "\r");
461
+ }
462
+ return $lines;
463
+ }
464
+
465
+ /**
466
+ * Parses YAML code and returns an array for a node
467
+ * @access private
468
+ * @return array
469
+ * @param string $line A line from the YAML file
470
+ */
471
+ private function _parseLine($line) {
472
+ if (!$line) return array();
473
+ $line = trim($line);
474
+
475
+ if (!$line) return array();
476
+ $array = array();
477
+
478
+ $group = $this->nodeContainsGroup($line);
479
+ if ($group) {
480
+ $this->addGroup($line, $group);
481
+ $line = $this->stripGroup ($line, $group);
482
+ }
483
+
484
+ if ($this->startsMappedSequence($line))
485
+ return $this->returnMappedSequence($line);
486
+
487
+ if ($this->startsMappedValue($line))
488
+ return $this->returnMappedValue($line);
489
+
490
+ if ($this->isArrayElement($line))
491
+ return $this->returnArrayElement($line);
492
+
493
+ if ($this->isPlainArray($line))
494
+ return $this->returnPlainArray($line);
495
+
496
+
497
+ return $this->returnKeyValuePair($line);
498
+
499
+ }
500
+
501
+ /**
502
+ * Finds the type of the passed value, returns the value as the new type.
503
+ * @access private
504
+ * @param string $value
505
+ * @return mixed
506
+ */
507
+ private function _toType($value) {
508
+ if ($value === '') return null;
509
+ $first_character = $value[0];
510
+ $last_character = substr($value, -1, 1);
511
+
512
+ $is_quoted = false;
513
+ do {
514
+ if (!$value) break;
515
+ if ($first_character != '"' && $first_character != "'") break;
516
+ if ($last_character != '"' && $last_character != "'") break;
517
+ $is_quoted = true;
518
+ } while (0);
519
+
520
+ if ($is_quoted)
521
+ return strtr(substr ($value, 1, -1), array ('\\"' => '"', '\'\'' => '\'', '\\\'' => '\''));
522
+
523
+ if (strpos($value, ' #') !== false)
524
+ $value = preg_replace('/\s+#(.+)$/','',$value);
525
+
526
+ if ($first_character == '[' && $last_character == ']') {
527
+ // Take out strings sequences and mappings
528
+ $innerValue = trim(substr ($value, 1, -1));
529
+ if ($innerValue === '') return array();
530
+ $explode = $this->_inlineEscape($innerValue);
531
+ // Propagate value array
532
+ $value = array();
533
+ foreach ($explode as $v) {
534
+ $value[] = $this->_toType($v);
535
+ }
536
+ return $value;
537
+ }
538
+
539
+ if (strpos($value,': ')!==false && $first_character != '{') {
540
+ $array = explode(': ',$value);
541
+ $key = trim($array[0]);
542
+ array_shift($array);
543
+ $value = trim(implode(': ',$array));
544
+ $value = $this->_toType($value);
545
+ return array($key => $value);
546
+ }
547
+
548
+ if ($first_character == '{' && $last_character == '}') {
549
+ $innerValue = trim(substr ($value, 1, -1));
550
+ if ($innerValue === '') return array();
551
+ // Inline Mapping
552
+ // Take out strings sequences and mappings
553
+ $explode = $this->_inlineEscape($innerValue);
554
+ // Propagate value array
555
+ $array = array();
556
+ foreach ($explode as $v) {
557
+ $SubArr = $this->_toType($v);
558
+ if (empty($SubArr)) continue;
559
+ if (is_array ($SubArr)) {
560
+ $array[key($SubArr)] = $SubArr[key($SubArr)]; continue;
561
+ }
562
+ $array[] = $SubArr;
563
+ }
564
+ return $array;
565
+ }
566
+
567
+ if ($value == 'null' || $value == 'NULL' || $value == 'Null' || $value == '' || $value == '~') {
568
+ return null;
569
+ }
570
+
571
+ if (intval($first_character) > 0 && preg_match ('/^[1-9]+[0-9]*$/', $value)) {
572
+ $intvalue = (int)$value;
573
+ if ($intvalue != PHP_INT_MAX)
574
+ $value = $intvalue;
575
+ return $value;
576
+ }
577
+
578
+ if (in_array($value,
579
+ array('true', 'on', '+', 'yes', 'y', 'True', 'TRUE', 'On', 'ON', 'YES', 'Yes', 'Y'))) {
580
+ return true;
581
+ }
582
+
583
+ if (in_array(strtolower($value),
584
+ array('false', 'off', '-', 'no', 'n'))) {
585
+ return false;
586
+ }
587
+
588
+ if (is_numeric($value)) {
589
+ if ($value === '0') return 0;
590
+ if (trim ($value, 0) === $value)
591
+ $value = (float)$value;
592
+ return $value;
593
+ }
594
+
595
+ return $value;
596
+ }
597
+
598
+ /**
599
+ * Used in inlines to check for more inlines or quoted strings
600
+ * @access private
601
+ * @return array
602
+ */
603
+ private function _inlineEscape($inline) {
604
+ // There's gotta be a cleaner way to do this...
605
+ // While pure sequences seem to be nesting just fine,
606
+ // pure mappings and mappings with sequences inside can't go very
607
+ // deep. This needs to be fixed.
608
+
609
+ $seqs = array();
610
+ $maps = array();
611
+ $saved_strings = array();
612
+
613
+ // Check for strings
614
+ $regex = '/(?:(")|(?:\'))((?(1)[^"]+|[^\']+))(?(1)"|\')/';
615
+ if (preg_match_all($regex,$inline,$strings)) {
616
+ $saved_strings = $strings[0];
617
+ $inline = preg_replace($regex,'YAMLString',$inline);
618
+ }
619
+ unset($regex);
620
+
621
+ $i = 0;
622
+ do {
623
+
624
+ // Check for sequences
625
+ while (preg_match('/\[([^{}\[\]]+)\]/U',$inline,$matchseqs)) {
626
+ $seqs[] = $matchseqs[0];
627
+ $inline = preg_replace('/\[([^{}\[\]]+)\]/U', ('YAMLSeq' . (count($seqs) - 1) . 's'), $inline, 1);
628
+ }
629
+
630
+ // Check for mappings
631
+ while (preg_match('/{([^\[\]{}]+)}/U',$inline,$matchmaps)) {
632
+ $maps[] = $matchmaps[0];
633
+ $inline = preg_replace('/{([^\[\]{}]+)}/U', ('YAMLMap' . (count($maps) - 1) . 's'), $inline, 1);
634
+ }
635
+
636
+ if ($i++ >= 10) break;
637
+
638
+ } while (strpos ($inline, '[') !== false || strpos ($inline, '{') !== false);
639
+
640
+ $explode = explode(', ',$inline);
641
+ $stringi = 0; $i = 0;
642
+
643
+ while (1) {
644
+
645
+ // Re-add the sequences
646
+ if (!empty($seqs)) {
647
+ foreach ($explode as $key => $value) {
648
+ if (strpos($value,'YAMLSeq') !== false) {
649
+ foreach ($seqs as $seqk => $seq) {
650
+ $explode[$key] = str_replace(('YAMLSeq'.$seqk.'s'),$seq,$value);
651
+ $value = $explode[$key];
652
+ }
653
+ }
654
+ }
655
+ }
656
+
657
+ // Re-add the mappings
658
+ if (!empty($maps)) {
659
+ foreach ($explode as $key => $value) {
660
+ if (strpos($value,'YAMLMap') !== false) {
661
+ foreach ($maps as $mapk => $map) {
662
+ $explode[$key] = str_replace(('YAMLMap'.$mapk.'s'), $map, $value);
663
+ $value = $explode[$key];
664
+ }
665
+ }
666
+ }
667
+ }
668
+
669
+
670
+ // Re-add the strings
671
+ if (!empty($saved_strings)) {
672
+ foreach ($explode as $key => $value) {
673
+ while (strpos($value,'YAMLString') !== false) {
674
+ $explode[$key] = preg_replace('/YAMLString/',$saved_strings[$stringi],$value, 1);
675
+ unset($saved_strings[$stringi]);
676
+ ++$stringi;
677
+ $value = $explode[$key];
678
+ }
679
+ }
680
+ }
681
+
682
+ $finished = true;
683
+ foreach ($explode as $key => $value) {
684
+ if (strpos($value,'YAMLSeq') !== false) {
685
+ $finished = false; break;
686
+ }
687
+ if (strpos($value,'YAMLMap') !== false) {
688
+ $finished = false; break;
689
+ }
690
+ if (strpos($value,'YAMLString') !== false) {
691
+ $finished = false; break;
692
+ }
693
+ }
694
+ if ($finished) break;
695
+
696
+ $i++;
697
+ if ($i > 10)
698
+ break; // Prevent infinite loops.
699
+ }
700
+
701
+ return $explode;
702
+ }
703
+
704
+ private function literalBlockContinues ($line, $lineIndent) {
705
+ if (!trim($line)) return true;
706
+ if (strlen($line) - strlen(ltrim($line)) > $lineIndent) return true;
707
+ return false;
708
+ }
709
+
710
+ private function referenceContentsByAlias ($alias) {
711
+ do {
712
+ if (!isset($this->SavedGroups[$alias])) { echo "Bad group name: $alias."; break; }
713
+ $groupPath = $this->SavedGroups[$alias];
714
+ $value = $this->result;
715
+ foreach ($groupPath as $k) {
716
+ $value = $value[$k];
717
+ }
718
+ } while (false);
719
+ return $value;
720
+ }
721
+
722
+ private function addArrayInline ($array, $indent) {
723
+ $CommonGroupPath = $this->path;
724
+ if (empty ($array)) return false;
725
+
726
+ foreach ($array as $k => $_) {
727
+ $this->addArray(array($k => $_), $indent);
728
+ $this->path = $CommonGroupPath;
729
+ }
730
+ return true;
731
+ }
732
+
733
+ private function addArray ($incoming_data, $incoming_indent) {
734
+
735
+ // print_r ($incoming_data);
736
+
737
+ if (count ($incoming_data) > 1)
738
+ return $this->addArrayInline ($incoming_data, $incoming_indent);
739
+
740
+ $key = key ($incoming_data);
741
+ $value = isset($incoming_data[$key]) ? $incoming_data[$key] : null;
742
+ if ($key === '__!YAMLZero') $key = '0';
743
+
744
+ if ($incoming_indent == 0 && !$this->_containsGroupAlias && !$this->_containsGroupAnchor) { // Shortcut for root-level values.
745
+ if ($key || $key === '' || $key === '0') {
746
+ $this->result[$key] = $value;
747
+ } else {
748
+ $this->result[] = $value; end ($this->result); $key = key ($this->result);
749
+ }
750
+ $this->path[$incoming_indent] = $key;
751
+ return;
752
+ }
753
+
754
+
755
+
756
+ $history = array();
757
+ // Unfolding inner array tree.
758
+ $history[] = $_arr = $this->result;
759
+ foreach ($this->path as $k) {
760
+ $history[] = $_arr = $_arr[$k];
761
+ }
762
+
763
+ if ($this->_containsGroupAlias) {
764
+ $value = $this->referenceContentsByAlias($this->_containsGroupAlias);
765
+ $this->_containsGroupAlias = false;
766
+ }
767
+
768
+
769
+ // Adding string or numeric key to the innermost level or $this->arr.
770
+ if (is_string($key) && $key == '<<') {
771
+ if (!is_array ($_arr)) { $_arr = array (); }
772
+
773
+ $_arr = array_merge ($_arr, $value);
774
+ } else if ($key || $key === '' || $key === '0') {
775
+ $_arr[$key] = $value;
776
+ } else {
777
+ if (!is_array ($_arr)) { $_arr = array ($value); $key = 0; }
778
+ else { $_arr[] = $value; end ($_arr); $key = key ($_arr); }
779
+ }
780
+
781
+ $reverse_path = array_reverse($this->path);
782
+ $reverse_history = array_reverse ($history);
783
+ $reverse_history[0] = $_arr;
784
+ $cnt = count($reverse_history) - 1;
785
+ for ($i = 0; $i < $cnt; $i++) {
786
+ $reverse_history[$i+1][$reverse_path[$i]] = $reverse_history[$i];
787
+ }
788
+ $this->result = $reverse_history[$cnt];
789
+
790
+ $this->path[$incoming_indent] = $key;
791
+
792
+ if ($this->_containsGroupAnchor) {
793
+ $this->SavedGroups[$this->_containsGroupAnchor] = $this->path;
794
+ if (is_array ($value)) {
795
+ $k = key ($value);
796
+ if (!is_int ($k)) {
797
+ $this->SavedGroups[$this->_containsGroupAnchor][$incoming_indent + 2] = $k;
798
+ }
799
+ }
800
+ $this->_containsGroupAnchor = false;
801
+ }
802
+
803
+ }
804
+
805
+ private static function startsLiteralBlock ($line) {
806
+ $lastChar = substr (trim($line), -1);
807
+ if ($lastChar != '>' && $lastChar != '|') return false;
808
+ if ($lastChar == '|') return $lastChar;
809
+ // HTML tags should not be counted as literal blocks.
810
+ if (preg_match ('#<.*?>$#', $line)) return false;
811
+ return $lastChar;
812
+ }
813
+
814
+ private static function greedilyNeedNextLine($line) {
815
+ $line = trim ($line);
816
+ if (!strlen($line)) return false;
817
+ if (substr ($line, -1, 1) == ']') return false;
818
+ if ($line[0] == '[') return true;
819
+ if (preg_match ('#^[^:]+?:\s*\[#', $line)) return true;
820
+ return false;
821
+ }
822
+
823
+ private function addLiteralLine ($literalBlock, $line, $literalBlockStyle) {
824
+ $line = self::stripIndent($line);
825
+ $line = rtrim ($line, "\r\n\t ") . "\n";
826
+ if ($literalBlockStyle == '|') {
827
+ return $literalBlock . $line;
828
+ }
829
+ if (strlen($line) == 0)
830
+ return rtrim($literalBlock, ' ') . "\n";
831
+ if ($line == "\n" && $literalBlockStyle == '>') {
832
+ return rtrim ($literalBlock, " \t") . "\n";
833
+ }
834
+ if ($line != "\n")
835
+ $line = trim ($line, "\r\n ") . " ";
836
+ return $literalBlock . $line;
837
+ }
838
+
839
+ function revertLiteralPlaceHolder ($lineArray, $literalBlock) {
840
+ foreach ($lineArray as $k => $_) {
841
+ if (is_array($_))
842
+ $lineArray[$k] = $this->revertLiteralPlaceHolder ($_, $literalBlock);
843
+ else if (substr($_, -1 * strlen ($this->LiteralPlaceHolder)) == $this->LiteralPlaceHolder)
844
+ $lineArray[$k] = rtrim ($literalBlock, " \r\n");
845
+ }
846
+ return $lineArray;
847
+ }
848
+
849
+ private static function stripIndent ($line, $indent = -1) {
850
+ if ($indent == -1) $indent = strlen($line) - strlen(ltrim($line));
851
+ return substr ($line, $indent);
852
+ }
853
+
854
+ private function getParentPathByIndent ($indent) {
855
+ if ($indent == 0) return array();
856
+ $linePath = $this->path;
857
+ do {
858
+ end($linePath); $lastIndentInParentPath = key($linePath);
859
+ if ($indent <= $lastIndentInParentPath) array_pop ($linePath);
860
+ } while ($indent <= $lastIndentInParentPath);
861
+ return $linePath;
862
+ }
863
+
864
+
865
+ private function clearBiggerPathValues ($indent) {
866
+
867
+
868
+ if ($indent == 0) $this->path = array();
869
+ if (empty ($this->path)) return true;
870
+
871
+ foreach ($this->path as $k => $_) {
872
+ if ($k > $indent) unset ($this->path[$k]);
873
+ }
874
+
875
+ return true;
876
+ }
877
+
878
+
879
+ private static function isComment ($line) {
880
+ if (!$line) return false;
881
+ if ($line[0] == '#') return true;
882
+ if (trim($line, " \r\n\t") == '---') return true;
883
+ return false;
884
+ }
885
+
886
+ private static function isEmpty ($line) {
887
+ return (trim ($line) === '');
888
+ }
889
+
890
+
891
+ private function isArrayElement ($line) {
892
+ if (!$line) return false;
893
+ if ($line[0] != '-') return false;
894
+ if (strlen ($line) > 3)
895
+ if (substr($line,0,3) == '---') return false;
896
+
897
+ return true;
898
+ }
899
+
900
+ private function isHashElement ($line) {
901
+ return strpos($line, ':');
902
+ }
903
+
904
+ private function isLiteral ($line) {
905
+ if ($this->isArrayElement($line)) return false;
906
+ if ($this->isHashElement($line)) return false;
907
+ return true;
908
+ }
909
+
910
+
911
+ private static function unquote ($value) {
912
+ if (!$value) return $value;
913
+ if (!is_string($value)) return $value;
914
+ if ($value[0] == '\'') return trim ($value, '\'');
915
+ if ($value[0] == '"') return trim ($value, '"');
916
+ return $value;
917
+ }
918
+
919
+ private function startsMappedSequence ($line) {
920
+ return ($line[0] == '-' && substr ($line, -1, 1) == ':');
921
+ }
922
+
923
+ private function returnMappedSequence ($line) {
924
+ $array = array();
925
+ $key = self::unquote(trim(substr($line,1,-1)));
926
+ $array[$key] = array();
927
+ $this->delayedPath = array(strpos ($line, $key) + $this->indent => $key);
928
+ return array($array);
929
+ }
930
+
931
+ private function returnMappedValue ($line) {
932
+ $array = array();
933
+ $key = self::unquote (trim(substr($line,0,-1)));
934
+ $array[$key] = '';
935
+ return $array;
936
+ }
937
+
938
+ private function startsMappedValue ($line) {
939
+ return (substr ($line, -1, 1) == ':');
940
+ }
941
+
942
+ private function isPlainArray ($line) {
943
+ return ($line[0] == '[' && substr ($line, -1, 1) == ']');
944
+ }
945
+
946
+ private function returnPlainArray ($line) {
947
+ return $this->_toType($line);
948
+ }
949
+
950
+ private function returnKeyValuePair ($line) {
951
+ $array = array();
952
+ $key = '';
953
+ if (strpos ($line, ':')) {
954
+ // It's a key/value pair most likely
955
+ // If the key is in double quotes pull it out
956
+ if (($line[0] == '"' || $line[0] == "'") && preg_match('/^(["\'](.*)["\'](\s)*:)/',$line,$matches)) {
957
+ $value = trim(str_replace($matches[1],'',$line));
958
+ $key = $matches[2];
959
+ } else {
960
+ // Do some guesswork as to the key and the value
961
+ $explode = explode(':',$line);
962
+ $key = trim($explode[0]);
963
+ array_shift($explode);
964
+ $value = trim(implode(':',$explode));
965
+ }
966
+ // Set the type of the value. Int, string, etc
967
+ $value = $this->_toType($value);
968
+ if ($key === '0') $key = '__!YAMLZero';
969
+ $array[$key] = $value;
970
+ } else {
971
+ $array = array ($line);
972
+ }
973
+ return $array;
974
+
975
+ }
976
+
977
+
978
+ private function returnArrayElement ($line) {
979
+ if (strlen($line) <= 1) return array(array()); // Weird %)
980
+ $array = array();
981
+ $value = trim(substr($line,1));
982
+ $value = $this->_toType($value);
983
+ $array[] = $value;
984
+ return $array;
985
+ }
986
+
987
+
988
+ private function nodeContainsGroup ($line) {
989
+ $symbolsForReference = 'A-z0-9_\-';
990
+ if (strpos($line, '&') === false && strpos($line, '*') === false) return false; // Please die fast ;-)
991
+ if ($line[0] == '&' && preg_match('/^(&['.$symbolsForReference.']+)/', $line, $matches)) return $matches[1];
992
+ if ($line[0] == '*' && preg_match('/^(\*['.$symbolsForReference.']+)/', $line, $matches)) return $matches[1];
993
+ if (preg_match('/(&['.$symbolsForReference.']+)$/', $line, $matches)) return $matches[1];
994
+ if (preg_match('/(\*['.$symbolsForReference.']+$)/', $line, $matches)) return $matches[1];
995
+ if (preg_match ('#^\s*<<\s*:\s*(\*[^\s]+).*$#', $line, $matches)) return $matches[1];
996
+ return false;
997
+
998
+ }
999
+
1000
+ private function addGroup ($line, $group) {
1001
+ if ($group[0] == '&') $this->_containsGroupAnchor = substr ($group, 1);
1002
+ if ($group[0] == '*') $this->_containsGroupAlias = substr ($group, 1);
1003
+ //print_r ($this->path);
1004
+ }
1005
+
1006
+ private function stripGroup ($line, $group) {
1007
+ $line = trim(str_replace($group, '', $line));
1008
+ return $line;
1009
+ }
1010
+ }
1011
+
1012
+ // Enable use of Spyc from command line
1013
+ // The syntax is the following: php spyc.php spyc.yaml
1014
+
1015
+ define ('SPYC_FROM_COMMAND_LINE', false);
1016
+
1017
+ do {
1018
+ if (!SPYC_FROM_COMMAND_LINE) break;
1019
+ if (empty ($_SERVER['argc']) || $_SERVER['argc'] < 2) break;
1020
+ if (empty ($_SERVER['PHP_SELF']) || $_SERVER['PHP_SELF'] != 'spyc.php') break;
1021
+ $file = $argv[1];
1022
+ printf ("Spyc loading file: %s\n", $file);
1023
+ print_r (spyc_load_file ($file));
1024
+ } while (0);
includes/vendor/mailchimp/Mailchimp/Campaigns.php ADDED
@@ -0,0 +1,378 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Mailchimp_Campaigns {
4
+ public function __construct(Mailchimp $master) {
5
+ $this->master = $master;
6
+ }
7
+
8
+ /**
9
+ * Get the content (both html and text) for a campaign either as it would appear in the campaign archive or as the raw, original content
10
+ * @param string $cid
11
+ * @param associative_array $options
12
+ * - view string optional one of "archive" (default), "preview" (like our popup-preview) or "raw"
13
+ * - email associative_array optional if provided, view is "archive" or "preview", the campaign's list still exists, and the requested record is subscribed to the list. the returned content will be populated with member data populated. a struct with one of the following keys - failing to provide anything will produce an error relating to the email address. If multiple keys are provided, the first one from the following list that we find will be used, the rest will be ignored.
14
+ * - email string an email address
15
+ * - euid string the unique id for an email address (not list related) - the email "id" returned from listMemberInfo, Webhooks, Campaigns, etc.
16
+ * - leid string the list email id (previously called web_id) for a list-member-info type call. this doesn't change when the email address changes
17
+ * @return associative_array containing all content for the campaign
18
+ * - html string The HTML content used for the campaign with merge tags intact
19
+ * - text string The Text content used for the campaign with merge tags intact
20
+ */
21
+ public function content($cid, $options=array()) {
22
+ $_params = array("cid" => $cid, "options" => $options);
23
+ return $this->master->call('campaigns/content', $_params);
24
+ }
25
+
26
+ /**
27
+ * Create a new draft campaign to send. You <strong>can not</strong> have more than 32,000 campaigns in your account.
28
+ * @param string $type
29
+ * @param associative_array $options
30
+ * - list_id string the list to send this campaign to- get lists using lists/list()
31
+ * - subject string the subject line for your campaign message
32
+ * - from_email string the From: email address for your campaign message
33
+ * - from_name string the From: name for your campaign message (not an email address)
34
+ * - to_name string the To: name recipients will see (not email address)
35
+ * - template_id int optional - use this user-created template to generate the HTML content of the campaign (takes precendence over other template options)
36
+ * - gallery_template_id int optional - use a template from the public gallery to generate the HTML content of the campaign (takes precendence over base template options)
37
+ * - base_template_id int optional - use this a base/start-from-scratch template to generate the HTML content of the campaign
38
+ * - folder_id int optional - automatically file the new campaign in the folder_id passed. Get using folders/list() - note that Campaigns and Autoresponders have separate folder setups
39
+ * - tracking associative_array optional - set which recipient actions will be tracked. Click tracking can not be disabled for Free accounts.
40
+ * - opens bool whether to track opens, defaults to true
41
+ * - html_clicks bool whether to track clicks in HTML content, defaults to true
42
+ * - text_clicks bool whether to track clicks in Text content, defaults to false
43
+ * - title string optional - an internal name to use for this campaign. By default, the campaign subject will be used.
44
+ * - authenticate boolean optional - set to true to enable SenderID, DomainKeys, and DKIM authentication, defaults to false.
45
+ * - analytics associative_array optional - one or more of these keys set to the tag to use - that can be any custom text (up to 50 bytes)
46
+ * - google string for Google Analytics tracking
47
+ * - clicktale string for ClickTale tracking
48
+ * - gooal string for Goal tracking (the extra 'o' in the param name is not a typo)
49
+ * - auto_footer boolean optional Whether or not we should auto-generate the footer for your content. Mostly useful for content from URLs or Imports
50
+ * - inline_css boolean optional Whether or not css should be automatically inlined when this campaign is sent, defaults to false.
51
+ * - generate_text boolean optional Whether of not to auto-generate your Text content from the HTML content. Note that this will be ignored if the Text part of the content passed is not empty, defaults to false.
52
+ * - auto_tweet boolean optional If set, this campaign will be auto-tweeted when it is sent - defaults to false. Note that if a Twitter account isn't linked, this will be silently ignored.
53
+ * - auto_fb_post array optional If set, this campaign will be auto-posted to the page_ids contained in the array. If a Facebook account isn't linked or the account does not have permission to post to the page_ids requested, those failures will be silently ignored.
54
+ * - fb_comments boolean optional If true, the Facebook comments (and thus the <a href="http://kb.mailchimp.com/article/i-dont-want-an-archiave-of-my-campaign-can-i-turn-it-off/" target="_blank">archive bar</a> will be displayed. If false, Facebook comments will not be enabled (does not imply no archive bar, see previous link). Defaults to "true".
55
+ * - timewarp boolean optional If set, this campaign must be scheduled 24 hours in advance of sending - default to false. Only valid for "regular" campaigns and "absplit" campaigns that split on schedule_time.
56
+ * - ecomm360 boolean optional If set, our <a href="http://www.mailchimp.com/blog/ecommerce-tracking-plugin/" target="_blank">Ecommerce360 tracking</a> will be enabled for links in the campaign
57
+ * - crm_tracking array optional If set, an array of structs to enable CRM tracking for:
58
+ * - salesforce associative_array optional Enable SalesForce push back
59
+ * - campaign bool optional - if true, create a Campaign object and update it with aggregate stats
60
+ * - notes bool optional - if true, attempt to update Contact notes based on email address
61
+ * - highrise associative_array optional Enable Highrise push back
62
+ * - campaign bool optional - if true, create a Kase object and update it with aggregate stats
63
+ * - notes bool optional - if true, attempt to update Contact notes based on email address
64
+ * - capsule associative_array optional Enable Capsule push back (only notes are supported)
65
+ * - notes bool optional - if true, attempt to update Contact notes based on email address
66
+ * @param associative_array $content
67
+ * - html string for raw/pasted HTML content
68
+ * - sections associative_array when using a template instead of raw HTML, each key should be the unique mc:edit area name from the template.
69
+ * - text string for the plain-text version
70
+ * - url string to have us pull in content from a URL. Note, this will override any other content options - for lists with Email Format options, you'll need to turn on generate_text as well
71
+ * - archive string to send a Base64 encoded archive file for us to import all media from. Note, this will override any other content options - for lists with Email Format options, you'll need to turn on generate_text as well
72
+ * - archive_type string optional - only necessary for the "archive" option. Supported formats are: zip, tar.gz, tar.bz2, tar, tgz, tbz . If not included, we will default to zip
73
+ * @param associative_array $segment_opts
74
+ * @param associative_array $type_opts
75
+ * - rss associative_array For RSS Campaigns this, struct should contain:
76
+ * - url string the URL to pull RSS content from - it will be verified and must exist
77
+ * - schedule string optional one of "daily", "weekly", "monthly" - defaults to "daily"
78
+ * - schedule_hour string optional an hour between 0 and 24 - default to 4 (4am <em>local time</em>) - applies to all schedule types
79
+ * - schedule_weekday string optional for "weekly" only, a number specifying the day of the week to send: 0 (Sunday) - 6 (Saturday) - defaults to 1 (Monday)
80
+ * - schedule_monthday string optional for "monthly" only, a number specifying the day of the month to send (1 - 28) or "last" for the last day of a given month. Defaults to the 1st day of the month
81
+ * - days associative_array optional used for "daily" schedules only, an array of the <a href="http://en.wikipedia.org/wiki/ISO-8601#Week_dates" target="_blank">ISO-8601 weekday numbers</a> to send on
82
+ * - 1 bool optional Monday, defaults to true
83
+ * - 2 bool optional Tuesday, defaults to true
84
+ * - 3 bool optional Wednesday, defaults to true
85
+ * - 4 bool optional Thursday, defaults to true
86
+ * - 5 bool optional Friday, defaults to true
87
+ * - 6 bool optional Saturday, defaults to true
88
+ * - 7 bool optional Sunday, defaults to true
89
+ * - absplit associative_array For A/B Split campaigns, this struct should contain:
90
+ * - split_test string The values to segment based on. Currently, one of: "subject", "from_name", "schedule". NOTE, for "schedule", you will need to call campaigns/schedule() separately!
91
+ * - pick_winner string How the winner will be picked, one of: "opens" (by the open_rate), "clicks" (by the click rate), "manual" (you pick manually)
92
+ * - wait_units int optional the default time unit to wait before auto-selecting a winner - use "3600" for hours, "86400" for days. Defaults to 86400.
93
+ * - wait_time int optional the number of units to wait before auto-selecting a winner - defaults to 1, so if not set, a winner will be selected after 1 Day.
94
+ * - split_size int optional this is a percentage of what size the Campaign's List plus any segmentation options results in. "schedule" type forces 50%, all others default to 10%
95
+ * - from_name_a string optional sort of, required when split_test is "from_name"
96
+ * - from_name_b string optional sort of, required when split_test is "from_name"
97
+ * - from_email_a string optional sort of, required when split_test is "from_name"
98
+ * - from_email_b string optional sort of, required when split_test is "from_name"
99
+ * - subject_a string optional sort of, required when split_test is "subject"
100
+ * - subject_b string optional sort of, required when split_test is "subject"
101
+ * - auto associative_array For AutoResponder campaigns, this struct should contain:
102
+ * - offset-units string one of "hourly", "day", "week", "month", "year" - required
103
+ * - offset-time string optional, sort of - the number of units must be a number greater than 0 for signup based autoresponders, ignored for "hourly"
104
+ * - offset-dir string either "before" or "after", ignored for "hourly"
105
+ * - event string optional "signup" (default) to base this members added to a list, "date", "annual", or "birthday" to base this on merge field in the list, "campaignOpen" or "campaignClicka" to base this on any activity for a campaign, "campaignClicko" to base this on clicks on a specific URL in a campaign, "mergeChanged" to base this on a specific merge field being changed to a specific value
106
+ * - event-datemerge string optional sort of, this is required if the event is "date", "annual", "birthday", or "mergeChanged"
107
+ * - campaign_id string optional sort of, required for "campaignOpen", "campaignClicka", or "campaignClicko"
108
+ * - campaign_url string optional sort of, required for "campaignClicko"
109
+ * - schedule_hour int The hour of the day - 24 hour format in GMT - the autoresponder should be triggered, ignored for "hourly"
110
+ * - use_import_time boolean whether or not imported subscribers (ie, <em>any</em> non-double optin subscribers) will receive
111
+ * - days associative_array optional used for "daily" schedules only, an array of the <a href="http://en.wikipedia.org/wiki/ISO-8601#Week_dates" target="_blank">ISO-8601 weekday numbers</a> to send on<
112
+ * - 1 bool optional Monday, defaults to true
113
+ * - 2 bool optional Tuesday, defaults to true
114
+ * - 3 bool optional Wednesday, defaults to true
115
+ * - 4 bool optional Thursday, defaults to true
116
+ * - 5 bool optional Friday, defaults to true
117
+ * - 6 bool optional Saturday, defaults to true
118
+ * - 7 bool optional Sunday, defaults to true
119
+ * @return associative_array the new campaign's details - will return same data as single campaign from campaigns/list()
120
+ */
121
+ public function create($type, $options, $content, $segment_opts=null, $type_opts=null) {
122
+ $_params = array("type" => $type, "options" => $options, "content" => $content, "segment_opts" => $segment_opts, "type_opts" => $type_opts);
123
+ return $this->master->call('campaigns/create', $_params);
124
+ }
125
+
126
+ /**
127
+ * Delete a campaign. Seriously, "poof, gone!" - be careful! Seriously, no one can undelete these.
128
+ * @param string $cid
129
+ * @return associative_array with a single entry:
130
+ * - complete bool whether the call worked. reallistically this will always be true as errors will be thrown otherwise.
131
+ */
132
+ public function delete($cid) {
133
+ $_params = array("cid" => $cid);
134
+ return $this->master->call('campaigns/delete', $_params);
135
+ }
136
+
137
+ /**
138
+ * Get the list of campaigns and their details matching the specified filters
139
+ * @param associative_array $filters
140
+ * - campaign_id string optional - return the campaign using a know campaign_id. Accepts multiples separated by commas when not using exact matching.
141
+ * - parent_id string optional - return the child campaigns using a known parent campaign_id. Accepts multiples separated by commas when not using exact matching.
142
+ * - list_id string optional - the list to send this campaign to - get lists using lists/list(). Accepts multiples separated by commas when not using exact matching.
143
+ * - folder_id int optional - only show campaigns from this folder id - get folders using folders/list(). Accepts multiples separated by commas when not using exact matching.
144
+ * - template_id int optional - only show campaigns using this template id - get templates using templates/list(). Accepts multiples separated by commas when not using exact matching.
145
+ * - status string optional - return campaigns of a specific status - one of "sent", "save", "paused", "schedule", "sending". Accepts multiples separated by commas when not using exact matching.
146
+ * - type string optional - return campaigns of a specific type - one of "regular", "plaintext", "absplit", "rss", "auto". Accepts multiples separated by commas when not using exact matching.
147
+ * - from_name string optional - only show campaigns that have this "From Name"
148
+ * - from_email string optional - only show campaigns that have this "Reply-to Email"
149
+ * - title string optional - only show campaigns that have this title
150
+ * - subject string optional - only show campaigns that have this subject
151
+ * - sendtime_start string optional - only show campaigns that have been sent since this date/time (in GMT) - - 24 hour format in <strong>GMT</strong>, eg "2013-12-30 20:30:00" - if this is invalid the whole call fails
152
+ * - sendtime_end string optional - only show campaigns that have been sent before this date/time (in GMT) - - 24 hour format in <strong>GMT</strong>, eg "2013-12-30 20:30:00" - if this is invalid the whole call fails
153
+ * - uses_segment boolean - whether to return just campaigns with or without segments
154
+ * - exact boolean optional - flag for whether to filter on exact values when filtering, or search within content for filter values - defaults to true. Using this disables the use of any filters that accept multiples.
155
+ * @param int $start
156
+ * @param int $limit
157
+ * @param string $sort_field
158
+ * @param string $sort_dir
159
+ * @return associative_array containing a count of all matching campaigns, the specific ones for the current page, and any errors from the filters provided
160
+ * - total int the total number of campaigns matching the filters passed in
161
+ * - data array structs for each campaign being returned
162
+ * - id string Campaign Id (used for all other campaign functions)
163
+ * - web_id int The Campaign id used in our web app, allows you to create a link directly to it
164
+ * - list_id string The List used for this campaign
165
+ * - folder_id int The Folder this campaign is in
166
+ * - template_id int The Template this campaign uses
167
+ * - content_type string How the campaign's content is put together - one of 'template', 'html', 'url'
168
+ * - title string Title of the campaign
169
+ * - type string The type of campaign this is (regular,plaintext,absplit,rss,inspection,auto)
170
+ * - create_time string Creation time for the campaign
171
+ * - send_time string Send time for the campaign - also the scheduled time for scheduled campaigns.
172
+ * - emails_sent int Number of emails email was sent to
173
+ * - status string Status of the given campaign (save,paused,schedule,sending,sent)
174
+ * - from_name string From name of the given campaign
175
+ * - from_email string Reply-to email of the given campaign
176
+ * - subject string Subject of the given campaign
177
+ * - to_name string Custom "To:" email string using merge variables
178
+ * - archive_url string Archive link for the given campaign
179
+ * - inline_css boolean Whether or not the campaign content's css was auto-inlined
180
+ * - analytics string Either "google" if enabled or "N" if disabled
181
+ * - analytics_tag string The name/tag the campaign's links were tagged with if analytics were enabled.
182
+ * - authenticate boolean Whether or not the campaign was authenticated
183
+ * - ecomm360 boolean Whether or not ecomm360 tracking was appended to links
184
+ * - auto_tweet boolean Whether or not the campaign was auto tweeted after sending
185
+ * - auto_fb_post string A comma delimited list of Facebook Profile/Page Ids the campaign was posted to after sending. If not used, blank.
186
+ * - auto_footer boolean Whether or not the auto_footer was manually turned on
187
+ * - timewarp boolean Whether or not the campaign used Timewarp
188
+ * - timewarp_schedule string The time, in GMT, that the Timewarp campaign is being sent. For A/B Split campaigns, this is blank and is instead in their schedule_a and schedule_b in the type_opts array
189
+ * - parent_id string the unique id of the parent campaign (currently only valid for rss children). Will be blank for non-rss child campaigns or parent campaign has been deleted.
190
+ * - is_child boolean true if this is an RSS child campaign. Will return true even if the parent campaign has been deleted.
191
+ * - tests_sent string tests sent
192
+ * - tests_remain int test sends remaining
193
+ * - tracking associative_array the various tracking options used
194
+ * - html_clicks boolean whether or not tracking for html clicks was enabled.
195
+ * - text_clicks boolean whether or not tracking for text clicks was enabled.
196
+ * - opens boolean whether or not opens tracking was enabled.
197
+ * - segment_text string a string marked-up with HTML explaining the segment used for the campaign in plain English
198
+ * - segment_opts array the segment used for the campaign - can be passed to campaigns/segment-test or campaigns/create()
199
+ * - saved_segment associative_array if a saved segment was used (match+conditions returned above):
200
+ * - id int the saved segment id
201
+ * - type string the saved segment type
202
+ * - name string the saved segment name
203
+ * - type_opts associative_array the type-specific options for the campaign - can be passed to campaigns/create()
204
+ * - comments_total int total number of comments left on this campaign
205
+ * - comments_unread int total number of unread comments for this campaign based on the login the apikey belongs to
206
+ * - summary associative_array if available, the basic aggregate stats returned by reports/summary
207
+ * - errors array structs of any errors found while loading lists - usually just from providing invalid list ids
208
+ * - filter string the filter that caused the failure
209
+ * - value string the filter value that caused the failure
210
+ * - code int the error code
211
+ * - error string the error message
212
+ */
213
+ public function getList($filters=array(), $start=0, $limit=25, $sort_field='create_time', $sort_dir='DESC') {
214
+ $_params = array("filters" => $filters, "start" => $start, "limit" => $limit, "sort_field" => $sort_field, "sort_dir" => $sort_dir);
215
+ return $this->master->call('campaigns/list', $_params);
216
+ }
217
+
218
+ /**
219
+ * Pause an AutoResponder or RSS campaign from sending
220
+ * @param string $cid
221
+ * @return associative_array with a single entry:
222
+ * - complete bool whether the call worked. reallistically this will always be true as errors will be thrown otherwise.
223
+ */
224
+ public function pause($cid) {
225
+ $_params = array("cid" => $cid);
226
+ return $this->master->call('campaigns/pause', $_params);
227
+ }
228
+
229
+ /**
230
+ * Returns information on whether a campaign is ready to send and possible issues we may have detected with it - very similar to the confirmation step in the app.
231
+ * @param string $cid
232
+ * @return associative_array containing:
233
+ * - is_ready bool whether or not you're going to be able to send this campaign
234
+ * - items array an array of structs explaining basically what the app's confirmation step would
235
+ * - type string the item type - generally success, warning, or error
236
+ * - heading string the item's heading in the app
237
+ * - details string the item's details from the app, sans any html tags/links
238
+ */
239
+ public function ready($cid) {
240
+ $_params = array("cid" => $cid);
241
+ return $this->master->call('campaigns/ready', $_params);
242
+ }
243
+
244
+ /**
245
+ * Replicate a campaign.
246
+ * @param string $cid
247
+ * @return associative_array the matching campaign's details - will return same data as single campaign from campaigns/list()
248
+ */
249
+ public function replicate($cid) {
250
+ $_params = array("cid" => $cid);
251
+ return $this->master->call('campaigns/replicate', $_params);
252
+ }
253
+
254
+ /**
255
+ * Resume sending an AutoResponder or RSS campaign
256
+ * @param string $cid
257
+ * @return associative_array with a single entry:
258
+ * - complete bool whether the call worked. reallistically this will always be true as errors will be thrown otherwise.
259
+ */
260
+ public function resume($cid) {
261
+ $_params = array("cid" => $cid);
262
+ return $this->master->call('campaigns/resume', $_params);
263
+ }
264
+
265
+ /**
266
+ * Schedule a campaign to be sent in the future
267
+ * @param string $cid
268
+ * @param string $schedule_time
269
+ * @param string $schedule_time_b
270
+ * @return associative_array with a single entry:
271
+ * - complete bool whether the call worked. reallistically this will always be true as errors will be thrown otherwise.
272
+ */
273
+ public function schedule($cid, $schedule_time, $schedule_time_b=null) {
274
+ $_params = array("cid" => $cid, "schedule_time" => $schedule_time, "schedule_time_b" => $schedule_time_b);
275
+ return $this->master->call('campaigns/schedule', $_params);
276
+ }
277
+
278
+ /**
279
+ * Schedule a campaign to be sent in batches sometime in the future. Only valid for "regular" campaigns
280
+ * @param string $cid
281
+ * @param string $schedule_time
282
+ * @param int $num_batches
283
+ * @param int $stagger_mins
284
+ * @return associative_array with a single entry:
285
+ * - complete bool whether the call worked. reallistically this will always be true as errors will be thrown otherwise.
286
+ */
287
+ public function scheduleBatch($cid, $schedule_time, $num_batches=2, $stagger_mins=5) {
288
+ $_params = array("cid" => $cid, "schedule_time" => $schedule_time, "num_batches" => $num_batches, "stagger_mins" => $stagger_mins);
289
+ return $this->master->call('campaigns/schedule-batch', $_params);
290
+ }
291
+
292
+ /**
293
+ * Allows one to test their segmentation rules before creating a campaign using them.
294
+ * @param string $list_id
295
+ * @param associative_array $options
296
+ * - saved_segment_id string a saved segment id from lists/segments() - this will take precendence, otherwise the match+conditions are required.
297
+ * - match string controls whether to use AND or OR when applying your options - expects "<strong>any</strong>" (for OR) or "<strong>all</strong>" (for AND)
298
+ * - conditions array of up to 5 structs for different criteria to apply while segmenting. Each criteria row must contain 3 keys - "<strong>field</strong>", "<strong>op</strong>", and "<strong>value</strong>" - and possibly a fourth, "<strong>extra</strong>", based on these definitions:
299
+ * @return associative_array with a single entry:
300
+ * - total int The total number of subscribers matching your segmentation options
301
+ */
302
+ public function segmentTest($list_id, $options) {
303
+ $_params = array("list_id" => $list_id, "options" => $options);
304
+ return $this->master->call('campaigns/segment-test', $_params);
305
+ }
306
+
307
+ /**
308
+ * Send a given campaign immediately. For RSS campaigns, this will "start" them.
309
+ * @param string $cid
310
+ * @return associative_array with a single entry:
311
+ * - complete bool whether the call worked. reallistically this will always be true as errors will be thrown otherwise.
312
+ */
313
+ public function send($cid) {
314
+ $_params = array("cid" => $cid);
315
+ return $this->master->call('campaigns/send', $_params);
316
+ }
317
+
318
+ /**
319
+ * Send a test of this campaign to the provided email addresses
320
+ * @param string $cid
321
+ * @param array $test_emails
322
+ * @param string $send_type
323
+ * @return associative_array with a single entry:
324
+ * - complete bool whether the call worked. reallistically this will always be true as errors will be thrown otherwise.
325
+ */
326
+ public function sendTest($cid, $test_emails=array(), $send_type='html') {
327
+ $_params = array("cid" => $cid, "test_emails" => $test_emails, "send_type" => $send_type);
328
+ return $this->master->call('campaigns/send-test', $_params);
329
+ }
330
+
331
+ /**
332
+ * Get the HTML template content sections for a campaign. Note that this <strong>will</strong> return very jagged, non-standard results based on the template
333
+ a campaign is using. You only want to use this if you want to allow editing template sections in your application.
334
+ * @param string $cid
335
+ * @return associative_array content containing all content section for the campaign - section name are dependent upon the template used and thus can't be documented
336
+ */
337
+ public function templateContent($cid) {
338
+ $_params = array("cid" => $cid);
339
+ return $this->master->call('campaigns/template-content', $_params);
340
+ }
341
+
342
+ /**
343
+ * Unschedule a campaign that is scheduled to be sent in the future
344
+ * @param string $cid
345
+ * @return associative_array with a single entry:
346
+ * - complete bool whether the call worked. reallistically this will always be true as errors will be thrown otherwise.
347
+ */
348
+ public function unschedule($cid) {
349
+ $_params = array("cid" => $cid);
350
+ return $this->master->call('campaigns/unschedule', $_params);
351
+ }
352
+
353
+ /**
354
+ * Update just about any setting besides type for a campaign that has <em>not</em> been sent. See campaigns/create() for details.
355
+ Caveats:<br/><ul class='bullets'>
356
+ <li>If you set a new list_id, all segmentation options will be deleted and must be re-added.</li>
357
+ <li>If you set template_id, you need to follow that up by setting it's 'content'</li>
358
+ <li>If you set segment_opts, you should have tested your options against campaigns/segment-test().</li>
359
+ <li>To clear/unset segment_opts, pass an empty string or array as the value. Various wrappers may require one or the other.</li>
360
+ </ul>
361
+ * @param string $cid
362
+ * @param string $name
363
+ * @param array $value
364
+ * @return associative_array updated campaign details and any errors
365
+ * - data associative_array the update campaign details - will return same data as single campaign from campaigns/list()
366
+ * - errors array for "options" only - structs containing:
367
+ * - code int the error code
368
+ * - message string the full error message
369
+ * - name string the parameter name that failed
370
+ */
371
+ public function update($cid, $name, $value) {
372
+ $_params = array("cid" => $cid, "name" => $name, "value" => $value);
373
+ return $this->master->call('campaigns/update', $_params);
374
+ }
375
+
376
+ }
377
+
378
+
includes/vendor/mailchimp/Mailchimp/Conversations.php ADDED
@@ -0,0 +1,80 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Mailchimp_Conversations {
4
+ public function __construct(Mailchimp $master) {
5
+ $this->master = $master;
6
+ }
7
+
8
+ /**
9
+ * Retrieve conversation metadata, includes message data for the most recent message in the conversation
10
+ * @param string $list_id
11
+ * @param string $leid
12
+ * @param string $campaign_id
13
+ * @param int $start
14
+ * @param int $limit
15
+ * @return associative_array Conversation data and metadata
16
+ * - count int Total number of conversations, irrespective of pagination.
17
+ * - data array An array of structs representing individual conversations
18
+ * - unique_id string A string identifying this particular conversation
19
+ * - message_count int The total number of messages in this conversation
20
+ * - campaign_id string The unique identifier of the campaign this conversation is associated with
21
+ * - list_id string The unique identifier of the list this conversation is associated with
22
+ * - unread_messages int The number of messages in this conversation which have not yet been read.
23
+ * - from_label string A label representing the sender of this message.
24
+ * - from_email string The email address of the sender of this message.
25
+ * - subject string The subject of the message.
26
+ * - timestamp string Date the message was either sent or received.
27
+ * - last_message associative_array The most recent message in the conversation
28
+ * - from_label string A label representing the sender of this message.
29
+ * - from_email string The email address of the sender of this message.
30
+ * - subject string The subject of the message.
31
+ * - message string The plain-text content of the message.
32
+ * - read boolean Whether or not this message has been marked as read.
33
+ * - timestamp string Date the message was either sent or received.
34
+ */
35
+ public function getList($list_id=null, $leid=null, $campaign_id=null, $start=0, $limit=25) {
36
+ $_params = array("list_id" => $list_id, "leid" => $leid, "campaign_id" => $campaign_id, "start" => $start, "limit" => $limit);
37
+ return $this->master->call('conversations/list', $_params);
38
+ }
39
+
40
+ /**
41
+ * Retrieve conversation messages
42
+ * @param string $conversation_id
43
+ * @param boolean $mark_as_read
44
+ * @param int $start
45
+ * @param int $limit
46
+ * @return associative_array Message data and metadata
47
+ * - count int The number of messages in this conversation, irrespective of paging.
48
+ * - data array An array of structs representing each message in a conversation
49
+ * - from_label string A label representing the sender of this message.
50
+ * - from_email string The email address of the sender of this message.
51
+ * - subject string The subject of the message.
52
+ * - message string The plain-text content of the message.
53
+ * - read boolean Whether or not this message has been marked as read.
54
+ * - timestamp string Date the message was either sent or received.
55
+ */
56
+ public function messages($conversation_id, $mark_as_read=false, $start=0, $limit=25) {
57
+ $_params = array("conversation_id" => $conversation_id, "mark_as_read" => $mark_as_read, "start" => $start, "limit" => $limit);
58
+ return $this->master->call('conversations/messages', $_params);
59
+ }
60
+
61
+ /**
62
+ * Retrieve conversation messages
63
+ * @param string $conversation_id
64
+ * @param string $message
65
+ * @return associative_array Message data from the created message
66
+ * - from_label string A label representing the sender of this message.
67
+ * - from_email string The email address of the sender of this message.
68
+ * - subject string The subject of the message.
69
+ * - message string The plain-text content of the message.
70
+ * - read boolean Whether or not this message has been marked as read.
71
+ * - timestamp string Date the message was either sent or received.
72
+ */
73
+ public function reply($conversation_id, $message) {
74
+ $_params = array("conversation_id" => $conversation_id, "message" => $message);
75
+ return $this->master->call('conversations/reply', $_params);
76
+ }
77
+
78
+ }
79
+
80
+
includes/vendor/mailchimp/Mailchimp/Ecomm.php ADDED
@@ -0,0 +1,86 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Mailchimp_Ecomm {
4
+ public function __construct(Mailchimp $master) {
5
+ $this->master = $master;
6
+ }
7
+
8
+ /**
9
+ * Import Ecommerce Order Information to be used for Segmentation. This will generally be used by ecommerce package plugins
10
+ <a href="http://connect.mailchimp.com/category/ecommerce" target="_blank">provided by us or by 3rd part system developers</a>.
11
+ * @param associative_array $order
12
+ * - id string the Order Id
13
+ * - campaign_id string optional the Campaign Id to track this order against (see the "mc_cid" query string variable a campaign passes)
14
+ * - email_id string optional (kind of) the Email Id of the subscriber we should attach this order to (see the "mc_eid" query string variable a campaign passes) - required if campaign_id is passed, otherwise either this or <strong>email</strong> is required. If both are provided, email_id takes precedence
15
+ * - email string optional (kind of) the Email Address we should attach this order to - either this or <strong>email_id</strong> is required. If both are provided, email_id takes precedence
16
+ * - total double The Order Total (ie, the full amount the customer ends up paying)
17
+ * - order_date string optional the date of the order - if this is not provided, we will default the date to now. Should be in the format of 2012-12-30
18
+ * - shipping double optional the total paid for Shipping Fees
19
+ * - tax double optional the total tax paid
20
+ * - store_id string a unique id for the store sending the order in (32 bytes max)
21
+ * - store_name string optional a "nice" name for the store - typically the base web address (ie, "store.mailchimp.com"). We will automatically update this if it changes (based on store_id)
22
+ * - items array structs for each individual line item including:
23
+ * - line_num int optional the line number of the item on the order. We will generate these if they are not passed
24
+ * - product_id int the store's internal Id for the product. Lines that do no contain this will be skipped
25
+ * - sku string optional the store's internal SKU for the product. (max 30 bytes)
26
+ * - product_name string the product name for the product_id associated with this item. We will auto update these as they change (based on product_id)
27
+ * - category_id int (required) the store's internal Id for the (main) category associated with this product. Our testing has found this to be a "best guess" scenario
28
+ * - category_name string (required) the category name for the category_id this product is in. Our testing has found this to be a "best guess" scenario. Our plugins walk the category heirarchy up and send "Root - SubCat1 - SubCat4", etc.
29
+ * - qty double optional the quantity of the item ordered - defaults to 1
30
+ * - cost double optional the cost of a single item (ie, not the extended cost of the line) - defaults to 0
31
+ * @return associative_array with a single entry:
32
+ * - complete bool whether the call worked. reallistically this will always be true as errors will be thrown otherwise.
33
+ */
34
+ public function orderAdd($order) {
35
+ $_params = array("order" => $order);
36
+ return $this->master->call('ecomm/order-add', $_params);
37
+ }
38
+
39
+ /**
40
+ * Delete Ecommerce Order Information used for segmentation. This will generally be used by ecommerce package plugins
41
+ <a href="/plugins/ecomm360.phtml">that we provide</a> or by 3rd part system developers.
42
+ * @param string $store_id
43
+ * @param string $order_id
44
+ * @return associative_array with a single entry:
45
+ * - complete bool whether the call worked. reallistically this will always be true as errors will be thrown otherwise.
46
+ */
47
+ public function orderDel($store_id, $order_id) {
48
+ $_params = array("store_id" => $store_id, "order_id" => $order_id);
49
+ return $this->master->call('ecomm/order-del', $_params);
50
+ }
51
+
52
+ /**
53
+ * Retrieve the Ecommerce Orders for an account
54
+ * @param string $cid
55
+ * @param int $start
56
+ * @param int $limit
57
+ * @param string $since
58
+ * @return associative_array the total matching orders and the specific orders for the requested page
59
+ * - total int the total matching orders
60
+ * - data array structs for each order being returned
61
+ * - store_id string the store id generated by the plugin used to uniquely identify a store
62
+ * - store_name string the store name collected by the plugin - often the domain name
63
+ * - order_id string the internal order id the store tracked this order by
64
+ * - email string the email address that received this campaign and is associated with this order
65
+ * - order_total double the order total
66
+ * - tax_total double the total tax for the order (if collected)
67
+ * - ship_total double the shipping total for the order (if collected)
68
+ * - order_date string the date the order was tracked - from the store if possible, otherwise the GMT time we received it
69
+ * - items array structs for each line item on this order.:
70
+ * - line_num int the line number
71
+ * - product_id int the product id
72
+ * - product_name string the product name
73
+ * - product_sku string the sku for the product
74
+ * - product_category_id int the category id for the product
75
+ * - product_category_name string the category name for the product
76
+ * - qty int the quantity ordered
77
+ * - cost double the cost of the item
78
+ */
79
+ public function orders($cid=null, $start=0, $limit=100, $since=null) {
80
+ $_params = array("cid" => $cid, "start" => $start, "limit" => $limit, "since" => $since);
81
+ return $this->master->call('ecomm/orders', $_params);
82
+ }
83
+
84
+ }
85
+
86
+
includes/vendor/mailchimp/Mailchimp/Exceptions.php ADDED
@@ -0,0 +1,471 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Mailchimp_Error extends Exception {}
4
+ class Mailchimp_HttpError extends Mailchimp_Error {}
5
+
6
+ /**
7
+ * The parameters passed to the API call are invalid or not provided when required
8
+ */
9
+ class Mailchimp_ValidationError extends Mailchimp_Error {}
10
+
11
+ /**
12
+ * None
13
+ */
14
+ class Mailchimp_ServerError_MethodUnknown extends Mailchimp_Error {}
15
+
16
+ /**
17
+ * None
18
+ */
19
+ class Mailchimp_ServerError_InvalidParameters extends Mailchimp_Error {}
20
+
21
+ /**
22
+ * None
23
+ */
24
+ class Mailchimp_Unknown_Exception extends Mailchimp_Error {}
25
+
26
+ /**
27
+ * None
28
+ */
29
+ class Mailchimp_Request_TimedOut extends Mailchimp_Error {}
30
+
31
+ /**
32
+ * None
33
+ */
34
+ class Mailchimp_Zend_Uri_Exception extends Mailchimp_Error {}
35
+
36
+ /**
37
+ * None
38
+ */
39
+ class Mailchimp_PDOException extends Mailchimp_Error {}
40
+
41
+ /**
42
+ * None
43
+ */
44
+ class Mailchimp_Avesta_Db_Exception extends Mailchimp_Error {}
45
+
46
+ /**
47
+ * None
48
+ */
49
+ class Mailchimp_XML_RPC2_Exception extends Mailchimp_Error {}
50
+
51
+ /**
52
+ * None
53
+ */
54
+ class Mailchimp_XML_RPC2_FaultException extends Mailchimp_Error {}
55
+
56
+ /**
57
+ * None
58
+ */
59
+ class Mailchimp_Too_Many_Connections extends Mailchimp_Error {}
60
+
61
+ /**
62
+ * None
63
+ */
64
+ class Mailchimp_Parse_Exception extends Mailchimp_Error {}
65
+
66
+ /**
67
+ * None
68
+ */
69
+ class Mailchimp_User_Unknown extends Mailchimp_Error {}
70
+
71
+ /**
72
+ * None
73
+ */
74
+ class Mailchimp_User_Disabled extends Mailchimp_Error {}
75
+
76
+ /**
77
+ * None
78
+ */
79
+ class Mailchimp_User_DoesNotExist extends Mailchimp_Error {}
80
+
81
+ /**
82
+ * None
83
+ */
84
+ class Mailchimp_User_NotApproved extends Mailchimp_Error {}
85
+
86
+ /**
87
+ * None
88
+ */
89
+ class Mailchimp_Invalid_ApiKey extends Mailchimp_Error {}
90
+
91
+ /**
92
+ * None
93
+ */
94
+ class Mailchimp_User_UnderMaintenance extends Mailchimp_Error {}
95
+
96
+ /**
97
+ * None
98
+ */
99
+ class Mailchimp_Invalid_AppKey extends Mailchimp_Error {}
100
+
101
+ /**
102
+ * None
103
+ */
104
+ class Mailchimp_Invalid_IP extends Mailchimp_Error {}
105
+
106
+ /**
107
+ * None
108
+ */
109
+ class Mailchimp_User_DoesExist extends Mailchimp_Error {}
110
+
111
+ /**
112
+ * None
113
+ */
114
+ class Mailchimp_User_InvalidRole extends Mailchimp_Error {}
115
+
116
+ /**
117
+ * None
118
+ */
119
+ class Mailchimp_User_InvalidAction extends Mailchimp_Error {}
120
+
121
+ /**
122
+ * None
123
+ */
124
+ class Mailchimp_User_MissingEmail extends Mailchimp_Error {}
125
+
126
+ /**
127
+ * None
128
+ */
129
+ class Mailchimp_User_CannotSendCampaign extends Mailchimp_Error {}
130
+
131
+ /**
132
+ * None
133
+ */
134
+ class Mailchimp_User_MissingModuleOutbox extends Mailchimp_Error {}
135
+
136
+ /**
137
+ * None
138
+ */
139
+ class Mailchimp_User_ModuleAlreadyPurchased extends Mailchimp_Error {}
140
+
141
+ /**
142
+ * None
143
+ */
144
+ class Mailchimp_User_ModuleNotPurchased extends Mailchimp_Error {}
145
+
146
+ /**
147
+ * None
148
+ */
149
+ class Mailchimp_User_NotEnoughCredit extends Mailchimp_Error {}
150
+
151
+ /**
152
+ * None
153
+ */
154
+ class Mailchimp_MC_InvalidPayment extends Mailchimp_Error {}
155
+
156
+ /**
157
+ * None
158
+ */
159
+ class Mailchimp_List_DoesNotExist extends Mailchimp_Error {}
160
+
161
+ /**
162
+ * None
163
+ */
164
+ class Mailchimp_List_InvalidInterestFieldType extends Mailchimp_Error {}
165
+
166
+ /**
167
+ * None
168
+ */
169
+ class Mailchimp_List_InvalidOption extends Mailchimp_Error {}
170
+
171
+ /**
172
+ * None
173
+ */
174
+ class Mailchimp_List_InvalidUnsubMember extends Mailchimp_Error {}
175
+
176
+ /**
177
+ * None
178
+ */
179
+ class Mailchimp_List_InvalidBounceMember extends Mailchimp_Error {}
180
+
181
+ /**
182
+ * None
183
+ */
184
+ class Mailchimp_List_AlreadySubscribed extends Mailchimp_Error {}
185
+
186
+ /**
187
+ * None
188
+ */
189
+ class Mailchimp_List_NotSubscribed extends Mailchimp_Error {}
190
+
191
+ /**
192
+ * None
193
+ */
194
+ class Mailchimp_List_InvalidImport extends Mailchimp_Error {}
195
+
196
+ /**
197
+ * None
198
+ */
199
+ class Mailchimp_MC_PastedList_Duplicate extends Mailchimp_Error {}
200
+
201
+ /**
202
+ * None
203
+ */
204
+ class Mailchimp_MC_PastedList_InvalidImport extends Mailchimp_Error {}
205
+
206
+ /**
207
+ * None
208
+ */
209
+ class Mailchimp_Email_AlreadySubscribed extends Mailchimp_Error {}
210
+
211
+ /**
212
+ * None
213
+ */
214
+ class Mailchimp_Email_AlreadyUnsubscribed extends Mailchimp_Error {}
215
+
216
+ /**
217
+ * None
218
+ */
219
+ class Mailchimp_Email_NotExists extends Mailchimp_Error {}
220
+
221
+ /**
222
+ * None
223
+ */
224
+ class Mailchimp_Email_NotSubscribed extends Mailchimp_Error {}
225
+
226
+ /**
227
+ * None
228
+ */
229
+ class Mailchimp_List_MergeFieldRequired extends Mailchimp_Error {}
230
+
231
+ /**
232
+ * None
233
+ */
234
+ class Mailchimp_List_CannotRemoveEmailMerge extends Mailchimp_Error {}
235
+
236
+ /**
237
+ * None
238
+ */
239
+ class Mailchimp_List_Merge_InvalidMergeID extends Mailchimp_Error {}
240
+
241
+ /**
242
+ * None
243
+ */
244
+ class Mailchimp_List_TooManyMergeFields extends Mailchimp_Error {}
245
+
246
+ /**
247
+ * None
248
+ */
249
+ class Mailchimp_List_InvalidMergeField extends Mailchimp_Error {}
250
+
251
+ /**
252
+ * None
253
+ */
254
+ class Mailchimp_List_InvalidInterestGroup extends Mailchimp_Error {}
255
+
256
+ /**
257
+ * None
258
+ */
259
+ class Mailchimp_List_TooManyInterestGroups extends Mailchimp_Error {}
260
+
261
+ /**
262
+ * None
263
+ */
264
+ class Mailchimp_Campaign_DoesNotExist extends Mailchimp_Error {}
265
+
266
+ /**
267
+ * None
268
+ */
269
+ class Mailchimp_Campaign_StatsNotAvailable extends Mailchimp_Error {}
270
+
271
+ /**
272
+ * None
273
+ */
274
+ class Mailchimp_Campaign_InvalidAbsplit extends Mailchimp_Error {}
275
+
276
+ /**
277
+ * None
278
+ */
279
+ class Mailchimp_Campaign_InvalidContent extends Mailchimp_Error {}
280
+
281
+ /**
282
+ * None
283
+ */
284
+ class Mailchimp_Campaign_InvalidOption extends Mailchimp_Error {}
285
+
286
+ /**
287
+ * None
288
+ */
289
+ class Mailchimp_Campaign_InvalidStatus extends Mailchimp_Error {}
290
+
291
+ /**
292
+ * None
293
+ */
294
+ class Mailchimp_Campaign_NotSaved extends Mailchimp_Error {}
295
+
296
+ /**
297
+ * None
298
+ */
299
+ class Mailchimp_Campaign_InvalidSegment extends Mailchimp_Error {}
300
+
301
+ /**
302
+ * None
303
+ */
304
+ class Mailchimp_Campaign_InvalidRss extends Mailchimp_Error {}
305
+
306
+ /**
307
+ * None
308
+ */
309
+ class Mailchimp_Campaign_InvalidAuto extends Mailchimp_Error {}
310
+
311
+ /**
312
+ * None
313
+ */
314
+ class Mailchimp_MC_ContentImport_InvalidArchive extends Mailchimp_Error {}
315
+
316
+ /**
317
+ * None
318
+ */
319
+ class Mailchimp_Campaign_BounceMissing extends Mailchimp_Error {}
320
+
321
+ /**
322
+ * None
323
+ */
324
+ class Mailchimp_Campaign_InvalidTemplate extends Mailchimp_Error {}
325
+
326
+ /**
327
+ * None
328
+ */
329
+ class Mailchimp_Invalid_EcommOrder extends Mailchimp_Error {}
330
+
331
+ /**
332
+ * None
333
+ */
334
+ class Mailchimp_Absplit_UnknownError extends Mailchimp_Error {}
335
+
336
+ /**
337
+ * None
338
+ */
339
+ class Mailchimp_Absplit_UnknownSplitTest extends Mailchimp_Error {}
340
+
341
+ /**
342
+ * None
343
+ */
344
+ class Mailchimp_Absplit_UnknownTestType extends Mailchimp_Error {}
345
+
346
+ /**
347
+ * None
348
+ */
349
+ class Mailchimp_Absplit_UnknownWaitUnit extends Mailchimp_Error {}
350
+
351
+ /**
352
+ * None
353
+ */
354
+ class Mailchimp_Absplit_UnknownWinnerType extends Mailchimp_Error {}
355
+
356
+ /**
357
+ * None
358
+ */
359
+ class Mailchimp_Absplit_WinnerNotSelected extends Mailchimp_Error {}
360
+
361
+ /**
362
+ * None
363
+ */
364
+ class Mailchimp_Invalid_Analytics extends Mailchimp_Error {}
365
+
366
+ /**
367
+ * None
368
+ */
369
+ class Mailchimp_Invalid_DateTime extends Mailchimp_Error {}
370
+
371
+ /**
372
+ * None
373
+ */
374
+ class Mailchimp_Invalid_Email extends Mailchimp_Error {}
375
+
376
+ /**
377
+ * None
378
+ */
379
+ class Mailchimp_Invalid_SendType extends Mailchimp_Error {}
380
+
381
+ /**
382
+ * None
383
+ */
384
+ class Mailchimp_Invalid_Template extends Mailchimp_Error {}
385
+
386
+ /**
387
+ * None
388
+ */
389
+ class Mailchimp_Invalid_TrackingOptions extends Mailchimp_Error {}
390
+
391
+ /**
392
+ * None
393
+ */
394
+ class Mailchimp_Invalid_Options extends Mailchimp_Error {}
395
+
396
+ /**
397
+ * None
398
+ */
399
+ class Mailchimp_Invalid_Folder extends Mailchimp_Error {}
400
+
401
+ /**
402
+ * None
403
+ */
404
+ class Mailchimp_Invalid_URL extends Mailchimp_Error {}
405
+
406
+ /**
407
+ * None
408
+ */
409
+ class Mailchimp_Module_Unknown extends Mailchimp_Error {}
410
+
411
+ /**
412
+ * None
413
+ */
414
+ class Mailchimp_MonthlyPlan_Unknown extends Mailchimp_Error {}
415
+
416
+ /**
417
+ * None
418
+ */
419
+ class Mailchimp_Order_TypeUnknown extends Mailchimp_Error {}
420
+
421
+ /**
422
+ * None
423
+ */
424
+ class Mailchimp_Invalid_PagingLimit extends Mailchimp_Error {}
425
+
426
+ /**
427
+ * None
428
+ */
429
+ class Mailchimp_Invalid_PagingStart extends Mailchimp_Error {}
430
+
431
+ /**
432
+ * None
433
+ */
434
+ class Mailchimp_Max_Size_Reached extends Mailchimp_Error {}
435
+
436
+ /**
437
+ * None
438
+ */
439
+ class Mailchimp_MC_SearchException extends Mailchimp_Error {}
440
+
441
+ /**
442
+ * None
443
+ */
444
+ class Mailchimp_Goal_SaveFailed extends Mailchimp_Error {}
445
+
446
+ /**
447
+ * None
448
+ */
449
+ class Mailchimp_Conversation_DoesNotExist extends Mailchimp_Error {}
450
+
451
+ /**
452
+ * None
453
+ */
454
+ class Mailchimp_Conversation_ReplySaveFailed extends Mailchimp_Error {}
455
+
456
+ /**
457
+ * None
458
+ */
459
+ class Mailchimp_File_Not_Found_Exception extends Mailchimp_Error {}
460
+
461
+ /**
462
+ * None
463
+ */
464
+ class Mailchimp_Folder_Not_Found_Exception extends Mailchimp_Error {}
465
+
466
+ /**
467
+ * None
468
+ */
469
+ class Mailchimp_Folder_Exists_Exception extends Mailchimp_Error {}
470
+
471
+
includes/vendor/mailchimp/Mailchimp/Folders.php ADDED
@@ -0,0 +1,62 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Mailchimp_Folders {
4
+ public function __construct(Mailchimp $master) {
5
+ $this->master = $master;
6
+ }
7
+
8
+ /**
9
+ * Add a new folder to file campaigns, autoresponders, or templates in
10
+ * @param string $name
11
+ * @param string $type
12
+ * @return associative_array with a single value:
13
+ * - folder_id int the folder_id of the newly created folder.
14
+ */
15
+ public function add($name, $type) {
16
+ $_params = array("name" => $name, "type" => $type);
17
+ return $this->master->call('folders/add', $_params);
18
+ }
19
+
20
+ /**
21
+ * Delete a campaign, autoresponder, or template folder. Note that this will simply make whatever was in the folder appear unfiled, no other data is removed
22
+ * @param int $fid
23
+ * @param string $type
24
+ * @return associative_array with a single entry:
25
+ * - complete bool whether the call worked. reallistically this will always be true as errors will be thrown otherwise.
26
+ */
27
+ public function del($fid, $type) {
28
+ $_params = array("fid" => $fid, "type" => $type);
29
+ return $this->master->call('folders/del', $_params);
30
+ }
31
+
32
+ /**
33
+ * List all the folders of a certain type
34
+ * @param string $type
35
+ * @return array structs for each folder, including:
36
+ * - folder_id int Folder Id for the given folder, this can be used in the campaigns/list() function to filter on.
37
+ * - name string Name of the given folder
38
+ * - date_created string The date/time the folder was created
39
+ * - type string The type of the folders being returned, just to make sure you know.
40
+ * - cnt int number of items in the folder.
41
+ */
42
+ public function getList($type) {
43
+ $_params = array("type" => $type);
44
+ return $this->master->call('folders/list', $_params);
45
+ }
46
+
47
+ /**
48
+ * Update the name of a folder for campaigns, autoresponders, or templates
49
+ * @param int $fid
50
+ * @param string $name
51
+ * @param string $type
52
+ * @return associative_array with a single entry:
53
+ * - complete bool whether the call worked. reallistically this will always be true as errors will be thrown otherwise.
54
+ */
55
+ public function update($fid, $name, $type) {
56
+ $_params = array("fid" => $fid, "name" => $name, "type" => $type);
57
+ return $this->master->call('folders/update', $_params);
58
+ }
59
+
60
+ }
61
+
62
+
includes/vendor/mailchimp/Mailchimp/Gallery.php ADDED
@@ -0,0 +1,106 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Mailchimp_Gallery {
4
+ public function __construct(Mailchimp $master) {
5
+ $this->master = $master;
6
+ }
7
+
8
+ /**
9
+ * Return a section of the image gallery
10
+ * @param associative_array $opts
11
+ * - type string optional the gallery type to return - images or files - default to images
12
+ * - start int optional for large data sets, the page number to start at - defaults to 1st page of data (page 0)
13
+ * - limit int optional for large data sets, the number of results to return - defaults to 25, upper limit set at 100
14
+ * - sort_by string optional field to sort by - one of size, time, name - defaults to time
15
+ * - sort_dir string optional field to sort by - one of asc, desc - defaults to desc
16
+ * - search_term string optional a term to search for in names
17
+ * - folder_id int optional to return files that are in a specific folder. id returned by the list-folders call
18
+ * @return associative_array the matching gallery items
19
+ * - total int the total matching items
20
+ * - data array structs for each item included in the set, including:
21
+ * - id int the id of the file
22
+ * - name string the file name
23
+ * - time string the creation date for the item
24
+ * - size int the file size in bytes
25
+ * - full string the url to the actual item in the gallery
26
+ * - thumb string a url for a thumbnail that can be used to represent the item, generally an image thumbnail or an icon for a file type
27
+ */
28
+ public function getList($opts=array()) {
29
+ $_params = array("opts" => $opts);
30
+ return $this->master->call('gallery/list', $_params);
31
+ }
32
+
33
+ /**
34
+ * Return a list of the folders available to the file gallery
35
+ * @param associative_array $opts
36
+ * - start int optional for large data sets, the page number to start at - defaults to 1st page of data (page 0)
37
+ * - limit int optional for large data sets, the number of results to return - defaults to 25, upper limit set at 100
38
+ * - search_term string optional a term to search for in names
39
+ * @return associative_array the matching gallery folders
40
+ * - total int the total matching folders
41
+ * - data array structs for each folder included in the set, including:
42
+ * - id int the id of the folder
43
+ * - name string the file name
44
+ * - file_count int the number of files in the folder
45
+ */
46
+ public function listFolders($opts=array()) {
47
+ $_params = array("opts" => $opts);
48
+ return $this->master->call('gallery/list-folders', $_params);
49
+ }
50
+
51
+ /**
52
+ * Adds a folder to the file gallery
53
+ * @param string $name
54
+ * @return associative_array the new data for the created folder
55
+ * - data.id int the id of the new folder
56
+ */
57
+ public function addFolder($name) {
58
+ $_params = array("name" => $name);
59
+ return $this->master->call('gallery/add-folder', $_params);
60
+ }
61
+
62
+ /**
63
+ * Remove a folder
64
+ * @param int $folder_id
65
+ * @return boolean true/false for success/failure
66
+ */
67
+ public function removeFolder($folder_id) {
68
+ $_params = array("folder_id" => $folder_id);
69
+ return $this->master->call('gallery/remove-folder', $_params);
70
+ }
71
+
72
+ /**
73
+ * Add a file to a folder
74
+ * @param int $file_id
75
+ * @param int $folder_id
76
+ * @return boolean true/false for success/failure
77
+ */
78
+ public function addFileToFolder($file_id, $folder_id) {
79
+ $_params = array("file_id" => $file_id, "folder_id" => $folder_id);
80
+ return $this->master->call('gallery/add-file-to-folder', $_params);
81
+ }
82
+
83
+ /**
84
+ * Remove a file from a folder
85
+ * @param int $file_id
86
+ * @param int $folder_id
87
+ * @return boolean true/false for success/failure
88
+ */
89
+ public function removeFileFromFolder($file_id, $folder_id) {
90
+ $_params = array("file_id" => $file_id, "folder_id" => $folder_id);
91
+ return $this->master->call('gallery/remove-file-from-folder', $_params);
92
+ }
93
+
94
+ /**
95
+ * Remove all files from a folder (Note that the files are not deleted, they are only removed from the folder)
96
+ * @param int $folder_id
97
+ * @return boolean true/false for success/failure
98
+ */
99
+ public function removeAllFilesFromFolder($folder_id) {
100
+ $_params = array("folder_id" => $folder_id);
101
+ return $this->master->call('gallery/remove-all-files-from-folder', $_params);
102
+ }
103
+
104
+ }
105
+
106
+
includes/vendor/mailchimp/Mailchimp/Goal.php ADDED
@@ -0,0 +1,49 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Mailchimp_Goal {
4
+ public function __construct(Mailchimp $master) {
5
+ $this->master = $master;
6
+ }
7
+
8
+ /**
9
+ * Retrieve goal event data for a particular list member. Note: only unique events are returned. If a user triggers
10
+ a particular event multiple times, you will still only receive one entry for that event.
11
+ * @param string $list_id
12
+ * @param associative_array $email
13
+ * - email string an email address
14
+ * - euid string the unique id for an email address (not list related) - the email "id" returned from listMemberInfo, Webhooks, Campaigns, etc.
15
+ * - leid string the list email id (previously called web_id) for a list-member-info type call. this doesn't change when the email address changes
16
+ * @param int $start
17
+ * @param int $limit
18
+ * @return associative_array Event data and metadata
19
+ * - data array An array of goal data structs for the specified list member in the following format
20
+ * - event string The URL or name of the event that was triggered
21
+ * - last_visited_at string A timestamp in the format 'YYYY-MM-DD HH:MM:SS' that represents the last time this event was seen.
22
+ * - total int The total number of events that match your criteria.
23
+ */
24
+ public function events($list_id, $email, $start=0, $limit=25) {
25
+ $_params = array("list_id" => $list_id, "email" => $email, "start" => $start, "limit" => $limit);
26
+ return $this->master->call('goal/events', $_params);
27
+ }
28
+
29
+ /**
30
+ * This allows programmatically trigger goal event collection without the use of front-end code.
31
+ * @param string $list_id
32
+ * @param associative_array $email
33
+ * - email string an email address
34
+ * - euid string the unique id for an email address (not list related) - the email "id" returned from listMemberInfo, Webhooks, Campaigns, etc.
35
+ * - leid string the list email id (previously called web_id) for a list-member-info type call. this doesn't change when the email address changes
36
+ * @param string $campaign_id
37
+ * @param string $event
38
+ * @return associative_array Event data for the submitted event
39
+ * - event string The URL or name of the event that was triggered
40
+ * - last_visited_at string A timestamp in the format 'YYYY-MM-DD HH:MM:SS' that represents the last time this event was seen.
41
+ */
42
+ public function recordEvent($list_id, $email, $campaign_id, $event) {
43
+ $_params = array("list_id" => $list_id, "email" => $email, "campaign_id" => $campaign_id, "event" => $event);
44
+ return $this->master->call('goal/record-event', $_params);
45
+ }
46
+
47
+ }
48
+
49
+
includes/vendor/mailchimp/Mailchimp/Helper.php ADDED
@@ -0,0 +1,237 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Mailchimp_Helper {
4
+ public function __construct(Mailchimp $master) {
5
+ $this->master = $master;
6
+ }
7
+
8
+ /**
9
+ * Retrieve lots of account information including payments made, plan info, some account stats, installed modules,
10
+ contact info, and more. No private information like Credit Card numbers is available.
11
+ * @param array $exclude
12
+ * @return associative_array containing the details for the account tied to this API Key
13
+ * - username string The company name associated with the account
14
+ * - user_id string The Account user unique id (for building some links)
15
+ * - is_trial bool Whether the Account is in Trial mode (can only send campaigns to less than 100 emails)
16
+ * - is_approved bool Whether the Account has been approved for purchases
17
+ * - has_activated bool Whether the Account has been activated
18
+ * - timezone string The timezone for the Account - default is "US/Eastern"
19
+ * - plan_type string Plan Type - "monthly", "payasyougo", or "free"
20
+ * - plan_low int <em>only for Monthly plans</em> - the lower tier for list size
21
+ * - plan_high int <em>only for Monthly plans</em> - the upper tier for list size
22
+ * - plan_start_date string <em>only for Monthly plans</em> - the start date for a monthly plan
23
+ * - emails_left int <em>only for Free and Pay-as-you-go plans</em> emails credits left for the account
24
+ * - pending_monthly bool Whether the account is finishing Pay As You Go credits before switching to a Monthly plan
25
+ * - first_payment string date of first payment
26
+ * - last_payment string date of most recent payment
27
+ * - times_logged_in int total number of times the account has been logged into via the web
28
+ * - last_login string date/time of last login via the web
29
+ * - affiliate_link string Monkey Rewards link for our Affiliate program
30
+ * - industry string the user's selected industry
31
+ * - contact associative_array Contact details for the account
32
+ * - fname string First Name
33
+ * - lname string Last Name
34
+ * - email string Email Address
35
+ * - company string Company Name
36
+ * - address1 string Address Line 1
37
+ * - address2 string Address Line 2
38
+ * - city string City
39
+ * - state string State or Province
40
+ * - zip string Zip or Postal Code
41
+ * - country string Country name
42
+ * - url string Website URL
43
+ * - phone string Phone number
44
+ * - fax string Fax number
45
+ * - modules array a struct for each addon module installed in the account
46
+ * - id string An internal module id
47
+ * - name string The module name
48
+ * - added string The date the module was added
49
+ * - data associative_array Any extra data associated with this module as key=>value pairs
50
+ * - orders array a struct for each order for the account
51
+ * - order_id int The order id
52
+ * - type string The order type - either "monthly" or "credits"
53
+ * - amount double The order amount
54
+ * - date string The order date
55
+ * - credits_used double The total credits used
56
+ * - rewards associative_array Rewards details for the account including credits & inspections earned, number of referrals, referral details, and rewards used
57
+ * - referrals_this_month int the total number of referrals this month
58
+ * - notify_on string whether or not we notify the user when rewards are earned
59
+ * - notify_email string the email address address used for rewards notifications
60
+ * - credits associative_array Email credits earned:
61
+ * - this_month int credits earned this month
62
+ * - total_earned int credits earned all time
63
+ * - remaining int credits remaining
64
+ * - inspections associative_array Inbox Inspections earned:
65
+ * - this_month int credits earned this month
66
+ * - total_earned int credits earned all time
67
+ * - remaining int credits remaining
68
+ * - referrals array a struct for each referral, including:
69
+ * - name string the name of the account
70
+ * - email string the email address associated with the account
71
+ * - signup_date string the signup date for the account
72
+ * - type string the source for the referral
73
+ * - applied array a struct for each applied rewards, including:
74
+ * - value int the number of credits user
75
+ * - date string the date applied
76
+ * - order_id int the order number credits were applied to
77
+ * - order_desc string the order description
78
+ * - integrations array a struct for each connected integrations that can be used with campaigns, including:
79
+ * - id int an internal id for the integration
80
+ * - name string the integration name
81
+ * - list_id string either "_any_" when globally accessible or the list id it's valid for use against
82
+ * - user_id string if applicable, the user id for the integrated system
83
+ * - account string if applicable, the user/account name for the integrated system
84
+ * - profiles array For Facebook, users/page that can be posted to.
85
+ * - id string the user or page id
86
+ * - name string the user or page name
87
+ * - is_page bool whether this is a user or a page
88
+ */
89
+ public function accountDetails($exclude=array()) {
90
+ $_params = array("exclude" => $exclude);
91
+ return $this->master->call('helper/account-details', $_params);
92
+ }
93
+
94
+ /**
95
+ * Retrieve minimal data for all Campaigns a member was sent
96
+ * @param associative_array $email
97
+ * - email string an email address
98
+ * - euid string the unique id for an email address (not list related) - the email "id" returned from listMemberInfo, Webhooks, Campaigns, etc.
99
+ * - leid string the list email id (previously called web_id) for a list-member-info type call. this doesn't change when the email address changes
100
+ * @param associative_array $options
101
+ * - list_id string optional A list_id to limit the campaigns to
102
+ * @return array an array of structs containing campaign data for each matching campaign (ordered by send time ascending), including:
103
+ * - id string the campaign unique id
104
+ * - title string the campaign's title
105
+ * - subject string the campaign's subject
106
+ * - send_time string the time the campaign was sent
107
+ * - type string the campaign type
108
+ */
109
+ public function campaignsForEmail($email, $options=null) {
110
+ $_params = array("email" => $email, "options" => $options);
111
+ return $this->master->call('helper/campaigns-for-email', $_params);
112
+ }
113
+
114
+ /**
115
+ * Return the current Chimp Chatter messages for an account.
116
+ * @return array An array of structs containing data for each chatter message
117
+ * - message string The chatter message
118
+ * - type string The type of the message - one of lists:new-subscriber, lists:unsubscribes, lists:profile-updates, campaigns:facebook-likes, campaigns:facebook-comments, campaigns:forward-to-friend, lists:imports, or campaigns:inbox-inspections
119
+ * - url string a url into the web app that the message could link to, if applicable
120
+ * - list_id string the list_id a message relates to, if applicable. Deleted lists will return -DELETED-
121
+ * - campaign_id string the list_id a message relates to, if applicable. Deleted campaigns will return -DELETED-
122
+ * - update_time string The date/time the message was last updated
123
+ */
124
+ public function chimpChatter() {
125
+ $_params = array();
126
+ return $this->master->call('helper/chimp-chatter', $_params);
127
+ }
128
+
129
+ /**
130
+ * Have HTML content auto-converted to a text-only format. You can send: plain HTML, an existing Campaign Id, or an existing Template Id. Note that this will <strong>not</strong> save anything to or update any of your lists, campaigns, or templates.
131
+ It's also not just Lynx and is very fine tuned for our template layouts - your mileage may vary.
132
+ * @param string $type
133
+ * @param associative_array $content
134
+ * - html string optional a single string value,
135
+ * - cid string a valid Campaign Id
136
+ * - user_template_id string the id of a user template
137
+ * - base_template_id string the id of a built in base/basic template
138
+ * - gallery_template_id string the id of a built in gallery template
139
+ * - url string a valid & public URL to pull html content from
140
+ * @return associative_array the content pass in converted to text.
141
+ * - text string the converted html
142
+ */
143
+ public function generateText($type, $content) {
144
+ $_params = array("type" => $type, "content" => $content);
145
+ return $this->master->call('helper/generate-text', $_params);
146
+ }
147
+
148
+ /**
149
+ * Send your HTML content to have the CSS inlined and optionally remove the original styles.
150
+ * @param string $html
151
+ * @param bool $strip_css
152
+ * @return associative_array with a "html" key
153
+ * - html string Your HTML content with all CSS inlined, just like if we sent it.
154
+ */
155
+ public function inlineCss($html, $strip_css=false) {
156
+ $_params = array("html" => $html, "strip_css" => $strip_css);
157
+ return $this->master->call('helper/inline-css', $_params);
158
+ }
159
+
160
+ /**
161
+ * Retrieve minimal List data for all lists a member is subscribed to.
162
+ * @param associative_array $email
163
+ * - email string an email address
164
+ * - euid string the unique id for an email address (not list related) - the email "id" returned from listMemberInfo, Webhooks, Campaigns, etc.
165
+ * - leid string the list email id (previously called web_id) for a list-member-info type call. this doesn't change when the email address changes
166
+ * @return array An array of structs with info on the list_id the member is subscribed to.
167
+ * - id string the list unique id
168
+ * - web_id int the id referenced in web interface urls
169
+ * - name string the list name
170
+ */
171
+ public function listsForEmail($email) {
172
+ $_params = array("email" => $email);
173
+ return $this->master->call('helper/lists-for-email', $_params);
174
+ }
175
+
176
+ /**
177
+ * "Ping" the MailChimp API - a simple method you can call that will return a constant value as long as everything is good. Note
178
+ than unlike most all of our methods, we don't throw an Exception if we are having issues. You will simply receive a different
179
+ string back that will explain our view on what is going on.
180
+ * @return associative_array a with a "msg" key
181
+ * - msg string containing "Everything's Chimpy!" if everything is chimpy, otherwise returns an error message
182
+ */
183
+ public function ping() {
184
+ $_params = array();
185
+ return $this->master->call('helper/ping', $_params);
186
+ }
187
+
188
+ /**
189
+ * Search all campaigns for the specified query terms
190
+ * @param string $query
191
+ * @param int $offset
192
+ * @param string $snip_start
193
+ * @param string $snip_end
194
+ * @return associative_array containing the total matches and current results
195
+ * - total int total campaigns matching
196
+ * - results array matching campaigns and snippets
197
+ * - snippet string the matching snippet for the campaign
198
+ * - campaign associative_array the matching campaign's details - will return same data as single campaign from campaigns/list()
199
+ */
200
+ public function searchCampaigns($query, $offset=0, $snip_start=null, $snip_end=null) {
201
+ $_params = array("query" => $query, "offset" => $offset, "snip_start" => $snip_start, "snip_end" => $snip_end);
202
+ return $this->master->call('helper/search-campaigns', $_params);
203
+ }
204
+
205
+ /**
206
+ * Search account wide or on a specific list using the specified query terms
207
+ * @param string $query
208
+ * @param string $id
209
+ * @param int $offset
210
+ * @return associative_array An array of both exact matches and partial matches over a full search
211
+ * - exact_matches associative_array containing the exact email address matches and current results
212
+ * - total int total members matching
213
+ * - members array each entry will be struct matching the data format for a single member as returned by lists/member-info()
214
+ * - full_search associative_array containing the total matches and current results
215
+ * - total int total members matching
216
+ * - members array each entry will be struct matching the data format for a single member as returned by lists/member-info()
217
+ */
218
+ public function searchMembers($query, $id=null, $offset=0) {
219
+ $_params = array("query" => $query, "id" => $id, "offset" => $offset);
220
+ return $this->master->call('helper/search-members', $_params);
221
+ }
222
+
223
+ /**
224
+ * Retrieve all domain verification records for an account
225
+ * @return array structs for each domain verification has been attempted for
226
+ * - domain string the verified domain
227
+ * - status string the status of the verification - either "verified" or "pending"
228
+ * - email string the email address used for verification - "pre-existing" if we automatically backfilled it at some point
229
+ */
230
+ public function verifiedDomains() {
231
+ $_params = array();
232
+ return $this->master->call('helper/verified-domains', $_params);
233
+ }
234
+
235
+ }
236
+
237
+
includes/vendor/mailchimp/Mailchimp/Lists.php ADDED
@@ -0,0 +1,904 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Mailchimp_Lists {
4
+ public function __construct(Mailchimp $master) {
5
+ $this->master = $master;
6
+ }
7
+
8
+ /**
9
+ * Get all email addresses that complained about a campaign sent to a list
10
+ * @param string $id
11
+ * @param int $start
12
+ * @param int $limit
13
+ * @param string $since
14
+ * @return associative_array the total of all reports and the specific reports reports this page
15
+ * - total int the total number of matching abuse reports
16
+ * - data array structs for the actual data for each reports, including:
17
+ * - date string date+time the abuse report was received and processed
18
+ * - email string the email address that reported abuse
19
+ * - campaign_id string the unique id for the campaign that report was made against
20
+ * - type string an internal type generally specifying the originating mail provider - may not be useful outside of filling report views
21
+ */
22
+ public function abuseReports($id, $start=0, $limit=500, $since=null) {
23
+ $_params = array("id" => $id, "start" => $start, "limit" => $limit, "since" => $since);
24
+ return $this->master->call('lists/abuse-reports', $_params);
25
+ }
26
+
27
+ /**
28
+ * Access up to the previous 180 days of daily detailed aggregated activity stats for a given list. Does not include AutoResponder activity.
29
+ * @param string $id
30
+ * @return array of structs containing daily values, each containing:
31
+ */
32
+ public function activity($id) {
33
+ $_params = array("id" => $id);
34
+ return $this->master->call('lists/activity', $_params);
35
+ }
36
+
37
+ /**
38
+ * Subscribe a batch of email addresses to a list at once. If you are using a serialized version of the API, we strongly suggest that you
39
+ only run this method as a POST request, and <em>not</em> a GET request. Maximum batch sizes vary based on the amount of data in each record,
40
+ though you should cap them at 5k - 10k records, depending on your experience. These calls are also long, so be sure you increase your timeout values.
41
+ * @param string $id
42
+ * @param array $batch
43
+ * - email associative_array a struct with one of the following keys - failing to provide anything will produce an error relating to the email address. Provide multiples and we'll use the first we see in this same order.
44
+ * - email string an email address
45
+ * - euid string the unique id for an email address (not list related) - the email "id" returned from listMemberInfo, Webhooks, Campaigns, etc.
46
+ * - leid string the list email id (previously called web_id) for a list-member-info type call. this doesn't change when the email address changes
47
+ * - email_type string for the email type option (html or text)
48
+ * - merge_vars associative_array data for the various list specific and special merge vars documented in lists/subscribe
49
+ * @param boolean $double_optin
50
+ * @param boolean $update_existing
51
+ * @param boolean $replace_interests
52
+ * @return associative_array struct of result counts and associated data
53
+ * - add_count int Number of email addresses that were successfully added
54
+ * - adds array array of structs for each add
55
+ * - email string the email address added
56
+ * - euid string the email unique id
57
+ * - leid string the list member's truly unique id
58
+ * - update_count int Number of email addresses that were successfully updated
59
+ * - updates array array of structs for each update
60
+ * - email string the email address added
61
+ * - euid string the email unique id
62
+ * - leid string the list member's truly unique id
63
+ * - error_count int Number of email addresses that failed during addition/updating
64
+ * - errors array array of error structs including:
65
+ * - email string whatever was passed in the batch record's email parameter
66
+ * - email string the email address added
67
+ * - euid string the email unique id
68
+ * - leid string the list member's truly unique id
69
+ * - code int the error code
70
+ * - error string the full error message
71
+ * - row associative_array the row from the batch that caused the error
72
+ */
73
+ public function batchSubscribe($id, $batch, $double_optin=true, $update_existing=false, $replace_interests=true) {
74
+ $_params = array("id" => $id, "batch" => $batch, "double_optin" => $double_optin, "update_existing" => $update_existing, "replace_interests" => $replace_interests);
75
+ return $this->master->call('lists/batch-subscribe', $_params);
76
+ }
77
+
78
+ /**
79
+ * Unsubscribe a batch of email addresses from a list
80
+ * @param string $id
81
+ * @param array $batch
82
+ * - email string an email address
83
+ * - euid string the unique id for an email address (not list related) - the email "id" returned from listMemberInfo, Webhooks, Campaigns, etc.
84
+ * - leid string the list email id (previously called web_id) for a list-member-info type call. this doesn't change when the email address changes
85
+ * @param boolean $delete_member
86
+ * @param boolean $send_goodbye
87
+ * @param boolean $send_notify
88
+ * @return array Array of structs containing results and any errors that occurred
89
+ * - success_count int Number of email addresses that were successfully removed
90
+ * - error_count int Number of email addresses that failed during addition/updating
91
+ * - errors array array of error structs including:
92
+ * - email string whatever was passed in the batch record's email parameter
93
+ * - email string the email address added
94
+ * - euid string the email unique id
95
+ * - leid string the list member's truly unique id
96
+ * - code int the error code
97
+ * - error string the full error message
98
+ */
99
+ public function batchUnsubscribe($id, $batch, $delete_member=false, $send_goodbye=true, $send_notify=false) {
100
+ $_params = array("id" => $id, "batch" => $batch, "delete_member" => $delete_member, "send_goodbye" => $send_goodbye, "send_notify" => $send_notify);
101
+ return $this->master->call('lists/batch-unsubscribe', $_params);
102
+ }
103
+
104
+ /**
105
+ * Retrieve the clients that the list's subscribers have been tagged as being used based on user agents seen. Made possible by <a href="http://user-agent-string.info" target="_blank">user-agent-string.info</a>
106
+ * @param string $id
107
+ * @return associative_array the desktop and mobile user agents in use on the list
108
+ * - desktop associative_array desktop user agents and percentages
109
+ * - penetration double the percent of desktop clients in use
110
+ * - clients array array of structs for each client including:
111
+ * - client string the common name for the client
112
+ * - icon string a url to an image representing this client
113
+ * - percent string percent of list using the client
114
+ * - members string total members using the client
115
+ * - mobile associative_array mobile user agents and percentages
116
+ * - penetration double the percent of mobile clients in use
117
+ * - clients array array of structs for each client including:
118
+ * - client string the common name for the client
119
+ * - icon string a url to an image representing this client
120
+ * - percent string percent of list using the client
121
+ * - members string total members using the client
122
+ */
123
+ public function clients($id) {
124
+ $_params = array("id" => $id);
125
+ return $this->master->call('lists/clients', $_params);
126
+ }
127
+
128
+ /**
129
+ * Access the Growth History by Month in aggregate or for a given list.
130
+ * @param string $id
131
+ * @return array array of structs containing months and growth data
132
+ * - month string The Year and Month in question using YYYY-MM format
133
+ * - existing int number of existing subscribers to start the month
134
+ * - imports int number of subscribers imported during the month
135
+ * - optins int number of subscribers who opted-in during the month
136
+ */
137
+ public function growthHistory($id=null) {
138
+ $_params = array("id" => $id);
139
+ return $this->master->call('lists/growth-history', $_params);
140
+ }
141
+
142
+ /**
143
+ * Get the list of interest groupings for a given list, including the label, form information, and included groups for each
144
+ * @param string $id
145
+ * @param bool $counts
146
+ * @return array array of structs of the interest groupings for the list
147
+ * - id int The id for the Grouping
148
+ * - name string Name for the Interest groups
149
+ * - form_field string Gives the type of interest group: checkbox,radio,select
150
+ * - groups array Array structs of the grouping options (interest groups) including:
151
+ * - bit string the bit value - not really anything to be done with this
152
+ * - name string the name of the group
153
+ * - display_order string the display order of the group, if set
154
+ * - subscribers int total number of subscribers who have this group if "counts" is true. otherwise empty
155
+ */
156
+ public function interestGroupings($id, $counts=false) {
157
+ $_params = array("id" => $id, "counts" => $counts);
158
+ return $this->master->call('lists/interest-groupings', $_params);
159
+ }
160
+
161
+ /**
162
+ * Add a single Interest Group - if interest groups for the List are not yet enabled, adding the first
163
+ group will automatically turn them on.
164
+ * @param string $id
165
+ * @param string $group_name
166
+ * @param int $grouping_id
167
+ * @return associative_array with a single entry:
168
+ * - complete bool whether the call worked. reallistically this will always be true as errors will be thrown otherwise.
169
+ */
170
+ public function interestGroupAdd($id, $group_name, $grouping_id=null) {
171
+ $_params = array("id" => $id, "group_name" => $group_name, "grouping_id" => $grouping_id);
172
+ return $this->master->call('lists/interest-group-add', $_params);
173
+ }
174
+
175
+ /**
176
+ * Delete a single Interest Group - if the last group for a list is deleted, this will also turn groups for the list off.
177
+ * @param string $id
178
+ * @param string $group_name
179
+ * @param int $grouping_id
180
+ * @return associative_array with a single entry:
181
+ * - complete bool whether the call worked. reallistically this will always be true as errors will be thrown otherwise.
182
+ */
183
+ public function interestGroupDel($id, $group_name, $grouping_id=null) {
184
+ $_params = array("id" => $id, "group_name" => $group_name, "grouping_id" => $grouping_id);
185
+ return $this->master->call('lists/interest-group-del', $_params);
186
+ }
187
+
188
+ /**
189
+ * Change the name of an Interest Group
190
+ * @param string $id
191
+ * @param string $old_name
192
+ * @param string $new_name
193
+ * @param int $grouping_id
194
+ * @return associative_array with a single entry:
195
+ * - complete bool whether the call worked. reallistically this will always be true as errors will be thrown otherwise.
196
+ */
197
+ public function interestGroupUpdate($id, $old_name, $new_name, $grouping_id=null) {
198
+ $_params = array("id" => $id, "old_name" => $old_name, "new_name" => $new_name, "grouping_id" => $grouping_id);
199
+ return $this->master->call('lists/interest-group-update', $_params);
200
+ }
201
+
202
+ /**
203
+ * Add a new Interest Grouping - if interest groups for the List are not yet enabled, adding the first
204
+ grouping will automatically turn them on.
205
+ * @param string $id
206
+ * @param string $name
207
+ * @param string $type
208
+ * @param array $groups
209
+ * @return associative_array with a single entry:
210
+ * - id int the new grouping id if the request succeeds, otherwise an error will be thrown
211
+ */
212
+ public function interestGroupingAdd($id, $name, $type, $groups) {
213
+ $_params = array("id" => $id, "name" => $name, "type" => $type, "groups" => $groups);
214
+ return $this->master->call('lists/interest-grouping-add', $_params);
215
+ }
216
+
217
+ /**
218
+ * Delete an existing Interest Grouping - this will permanently delete all contained interest groups and will remove those selections from all list members
219
+ * @param int $grouping_id
220
+ * @return associative_array with a single entry:
221
+ * - complete bool whether the call worked. reallistically this will always be true as errors will be thrown otherwise.
222
+ */
223
+ public function interestGroupingDel($grouping_id) {
224
+ $_params = array("grouping_id" => $grouping_id);
225
+ return $this->master->call('lists/interest-grouping-del', $_params);
226
+ }
227
+
228
+ /**
229
+ * Update an existing Interest Grouping
230
+ * @param int $grouping_id
231
+ * @param string $name
232
+ * @param string $value
233
+ * @return associative_array with a single entry:
234
+ * - complete bool whether the call worked. reallistically this will always be true as errors will be thrown otherwise.
235
+ */
236
+ public function interestGroupingUpdate($grouping_id, $name, $value) {
237
+ $_params = array("grouping_id" => $grouping_id, "name" => $name, "value" => $value);
238
+ return $this->master->call('lists/interest-grouping-update', $_params);
239
+ }
240
+
241
+ /**
242
+ * Retrieve the locations (countries) that the list's subscribers have been tagged to based on geocoding their IP address
243
+ * @param string $id
244
+ * @return array array of locations
245
+ * - country string the country name
246
+ * - cc string the ISO 3166 2 digit country code
247
+ * - percent double the percent of subscribers in the country
248
+ * - total double the total number of subscribers in the country
249
+ */
250
+ public function locations($id) {
251
+ $_params = array("id" => $id);
252
+ return $this->master->call('lists/locations', $_params);
253
+ }
254
+
255
+ /**
256
+ * Get the most recent 100 activities for particular list members (open, click, bounce, unsub, abuse, sent to, etc.)
257
+ * @param string $id
258
+ * @param array $emails
259
+ * - email string an email address - for new subscribers obviously this should be used
260
+ * - euid string the unique id for an email address (not list related) - the email "id" returned from listMemberInfo, Webhooks, Campaigns, etc.
261
+ * - leid string the list email id (previously called web_id) for a list-member-info type call. this doesn't change when the email address changes
262
+ * @return associative_array of data and success/error counts
263
+ * - success_count int the number of subscribers successfully found on the list
264
+ * - error_count int the number of subscribers who were not found on the list
265
+ * - errors array array of error structs including:
266
+ * - email string whatever was passed in the email parameter
267
+ * - email string the email address added
268
+ * - euid string the email unique id
269
+ * - leid string the list member's truly unique id
270
+ * - error string the error message
271
+ * - code string the error code
272
+ * - data array an array of structs where each activity record has:
273
+ * - email string whatever was passed in the email parameter
274
+ * - email string the email address added
275
+ * - euid string the email unique id
276
+ * - leid string the list member's truly unique id
277
+ * - activity array an array of structs containing the activity, including:
278
+ * - action string The action name, one of: open, click, bounce, unsub, abuse, sent, queued, ecomm, mandrill_send, mandrill_hard_bounce, mandrill_soft_bounce, mandrill_open, mandrill_click, mandrill_spam, mandrill_unsub, mandrill_reject
279
+ * - timestamp string The date+time of the action (GMT)
280
+ * - url string For click actions, the url clicked, otherwise this is empty
281
+ * - type string If there's extra bounce, unsub, etc data it will show up here.
282
+ * - campaign_id string The campaign id the action was related to, if it exists - otherwise empty (ie, direct unsub from list)
283
+ * - campaign_data associative_array If not deleted, the campaigns/list data for the campaign
284
+ */
285
+ public function memberActivity($id, $emails) {
286
+ $_params = array("id" => $id, "emails" => $emails);
287
+ return $this->master->call('lists/member-activity', $_params);
288
+ }
289
+
290
+ /**
291
+ * Get all the information for particular members of a list
292
+ * @param string $id
293
+ * @param array $emails
294
+ * - email string an email address - for new subscribers obviously this should be used
295
+ * - euid string the unique id for an email address (not list related) - the email "id" returned from listMemberInfo, Webhooks, Campaigns, etc.
296
+ * - leid string the list email id (previously called web_id) for a list-member-info type call. this doesn't change when the email address changes
297
+ * @return associative_array of data and success/error counts
298
+ * - success_count int the number of subscribers successfully found on the list
299
+ * - error_count int the number of subscribers who were not found on the list
300
+ * - errors array array of error structs including:
301
+ * - email associative_array whatever was passed in the email parameter
302
+ * - email string the email address added
303
+ * - euid string the email unique id
304
+ * - leid string the list member's truly unique id
305
+ * - error string the error message
306
+ * - data array array of structs for each valid list member
307
+ * - id string The unique id (euid) for this email address on an account
308
+ * - email string The email address associated with this record
309
+ * - email_type string The type of emails this customer asked to get: html or text
310
+ * - merges associative_array a struct containing a key for each merge tags and the data for those tags for this email address, plus:
311
+ * - GROUPINGS array if Interest groupings are enabled, this will exist with structs for each grouping:
312
+ * - id int the grouping id
313
+ * - name string the interest group name
314
+ * - groups array structs for each group in the grouping
315
+ * - name string the group name
316
+ * - interested bool whether the member has this group selected
317
+ * - status string The subscription status for this email address, either pending, subscribed, unsubscribed, or cleaned
318
+ * - ip_signup string IP Address this address signed up from. This may be blank if single optin is used.
319
+ * - timestamp_signup string The date+time the double optin was initiated. This may be blank if single optin is used.
320
+ * - ip_opt string IP Address this address opted in from.
321
+ * - timestamp_opt string The date+time the optin completed
322
+ * - member_rating int the rating of the subscriber. This will be 1 - 5 as described <a href="http://eepurl.com/f-2P" target="_blank">here</a>
323
+ * - campaign_id string If the user is unsubscribed and they unsubscribed from a specific campaign, that campaign_id will be listed, otherwise this is not returned.
324
+ * - lists array An array of structs for the other lists this member belongs to
325
+ * - id string the list id
326
+ * - status string the members status on that list
327
+ * - timestamp string The date+time this email address entered it's current status
328
+ * - info_changed string The last time this record was changed. If the record is old enough, this may be blank.
329
+ * - web_id int The Member id used in our web app, allows you to create a link directly to it
330
+ * - leid int The Member id used in our web app, allows you to create a link directly to it
331
+ * - list_id string The list id the for the member record being returned
332
+ * - list_name string The list name the for the member record being returned
333
+ * - language string if set/detected, a language code from <a href="http://kb.mailchimp.com/article/can-i-see-what-languages-my-subscribers-use#code" target="_blank">here</a>
334
+ * - is_gmonkey bool Whether the member is a <a href="http://mailchimp.com/features/golden-monkeys/" target="_blank">Golden Monkey</a> or not.
335
+ * - geo associative_array the geographic information if we have it. including:
336
+ * - latitude string the latitude
337
+ * - longitude string the longitude
338
+ * - gmtoff string GMT offset
339
+ * - dstoff string GMT offset during daylight savings (if DST not observered, will be same as gmtoff)
340
+ * - timezone string the timezone we've place them in
341
+ * - cc string 2 digit ISO-3166 country code
342
+ * - region string generally state, province, or similar
343
+ * - clients associative_array the client we've tracked the address as using with two keys:
344
+ * - name string the common name of the client
345
+ * - icon_url string a url representing a path to an icon representing this client
346
+ * - static_segments array structs for each static segments the member is a part of including:
347
+ * - id int the segment id
348
+ * - name string the name given to the segment
349
+ * - added string the date the member was added
350
+ * - notes array structs for each note entered for this member. For each note:
351
+ * - id int the note id
352
+ * - note string the text entered
353
+ * - created string the date the note was created
354
+ * - updated string the date the note was last updated
355
+ * - created_by_name string the name of the user who created the note. This can change as users update their profile.
356
+ */
357
+ public function memberInfo($id, $emails) {
358
+ $_params = array("id" => $id, "emails" => $emails);
359
+ return $this->master->call('lists/member-info', $_params);
360
+ }
361
+
362
+ /**
363
+ * Get all of the list members for a list that are of a particular status and potentially matching a segment. This will cause locking, so don't run multiples at once. Are you trying to get a dump including lots of merge
364
+ data or specific members of a list? If so, checkout the <a href="/export/1.0/list.func.php">List Export API</a>
365
+ * @param string $id
366
+ * @param string $status
367
+ * @param associative_array $opts
368
+ * - start int optional for large data sets, the page number to start at - defaults to 1st page of data (page 0)
369
+ * - limit int optional for large data sets, the number of results to return - defaults to 25, upper limit set at 100
370
+ * - sort_field string optional the data field to sort by - mergeX (1-30), your custom merge tags, "email", "rating","last_update_time", or "optin_time" - invalid fields will be ignored
371
+ * - sort_dir string optional the direct - ASC or DESC. defaults to ASC (case insensitive)
372
+ * - segment associative_array a properly formatted segment that works with campaigns/segment-test
373
+ * @return associative_array of the total records matched and limited list member data for this page
374
+ * - total int the total matching records
375
+ * - data array structs for each member as returned by member-info
376
+ */
377
+ public function members($id, $status='subscribed', $opts=array()) {
378
+ $_params = array("id" => $id, "status" => $status, "opts" => $opts);
379
+ return $this->master->call('lists/members', $_params);
380
+ }
381
+
382
+ /**
383
+ * Add a new merge tag to a given list
384
+ * @param string $id
385
+ * @param string $tag
386
+ * @param string $name
387
+ * @param associative_array $options
388
+ * - field_type string optional one of: text, number, radio, dropdown, date, address, phone, url, imageurl, zip, birthday - defaults to text
389
+ * - req boolean optional indicates whether the field is required - defaults to false
390
+ * - public boolean optional indicates whether the field is displayed in public - defaults to true
391
+ * - show boolean optional indicates whether the field is displayed in the app's list member view - defaults to true
392
+ * - order int The order this merge tag should be displayed in - this will cause existing values to be reset so this fits
393
+ * - default_value string optional the default value for the field. See lists/subscribe() for formatting info. Defaults to blank - max 255 bytes
394
+ * - helptext string optional the help text to be used with some newer forms. Defaults to blank - max 255 bytes
395
+ * - choices array optional kind of - an array of strings to use as the choices for radio and dropdown type fields
396
+ * - dateformat string optional only valid for birthday and date fields. For birthday type, must be "MM/DD" (default) or "DD/MM". For date type, must be "MM/DD/YYYY" (default) or "DD/MM/YYYY". Any other values will be converted to the default.
397
+ * - phoneformat string optional "US" is the default - any other value will cause them to be unformatted (international)
398
+ * - defaultcountry string optional the <a href="http://www.iso.org/iso/english_country_names_and_code_elements" target="_blank">ISO 3166 2 digit character code</a> for the default country. Defaults to "US". Anything unrecognized will be converted to the default.
399
+ * @return associative_array the full data for the new merge var, just like merge-vars returns
400
+ * - name string Name/description of the merge field
401
+ * - req bool Denotes whether the field is required (true) or not (false)
402
+ * - field_type string The "data type" of this merge var. One of: email, text, number, radio, dropdown, date, address, phone, url, imageurl
403
+ * - public bool Whether or not this field is visible to list subscribers
404
+ * - show bool Whether the field is displayed in thelist dashboard
405
+ * - order string The order this field displays in on forms
406
+ * - default string The default value for this field
407
+ * - helptext string The helptext for this field
408
+ * - size string The width of the field to be used
409
+ * - tag string The merge tag that's used for forms and lists/subscribe() and lists/update-member()
410
+ * - choices array the options available for radio and dropdown field types
411
+ * - id int an unchanging id for the merge var
412
+ */
413
+ public function mergeVarAdd($id, $tag, $name, $options=array()) {
414
+ $_params = array("id" => $id, "tag" => $tag, "name" => $name, "options" => $options);
415
+ return $this->master->call('lists/merge-var-add', $_params);
416
+ }
417
+
418
+ /**
419
+ * Delete a merge tag from a given list and all its members. Seriously - the data is removed from all members as well!
420
+ Note that on large lists this method may seem a bit slower than calls you typically make.
421
+ * @param string $id
422
+ * @param string $tag
423
+ * @return associative_array with a single entry:
424
+ * - complete bool whether the call worked. reallistically this will always be true as errors will be thrown otherwise.
425
+ */
426
+ public function mergeVarDel($id, $tag) {
427
+ $_params = array("id" => $id, "tag" => $tag);
428
+ return $this->master->call('lists/merge-var-del', $_params);
429
+ }
430
+
431
+ /**
432
+ * Completely resets all data stored in a merge var on a list. All data is removed and this action can not be undone.
433
+ * @param string $id
434
+ * @param string $tag
435
+ * @return associative_array with a single entry:
436
+ * - complete bool whether the call worked. reallistically this will always be true as errors will be thrown otherwise.
437
+ */
438
+ public function mergeVarReset($id, $tag) {
439
+ $_params = array("id" => $id, "tag" => $tag);
440
+ return $this->master->call('lists/merge-var-reset', $_params);
441
+ }
442
+
443
+ /**
444
+ * Sets a particular merge var to the specified value for every list member. Only merge var ids 1 - 30 may be modified this way. This is generally a dirty method
445
+ unless you're fixing data since you should probably be using default_values and/or conditional content. as with lists/merge-var-reset(), this can not be undone.
446
+ * @param string $id
447
+ * @param string $tag
448
+ * @param string $value
449
+ * @return associative_array with a single entry:
450
+ * - complete bool whether the call worked. reallistically this will always be true as errors will be thrown otherwise.
451
+ */
452
+ public function mergeVarSet($id, $tag, $value) {
453
+ $_params = array("id" => $id, "tag" => $tag, "value" => $value);
454
+ return $this->master->call('lists/merge-var-set', $_params);
455
+ }
456
+
457
+ /**
458
+ * Update most parameters for a merge tag on a given list. You cannot currently change the merge type
459
+ * @param string $id
460
+ * @param string $tag
461
+ * @param associative_array $options
462
+ * @return associative_array the full data for the new merge var, just like merge-vars returns
463
+ * - name string Name/description of the merge field
464
+ * - req bool Denotes whether the field is required (true) or not (false)
465
+ * - field_type string The "data type" of this merge var. One of: email, text, number, radio, dropdown, date, address, phone, url, imageurl
466
+ * - public bool Whether or not this field is visible to list subscribers
467
+ * - show bool Whether the field is displayed in thelist dashboard
468
+ * - order string The order this field to displays in on forms
469
+ * - default string The default value for this field
470
+ * - helptext string The helptext for this field
471
+ * - size string The width of the field to be used
472
+ * - tag string The merge tag that's used for forms and lists/subscribe() and lists/update-member()
473
+ * - choices array the options available for radio and dropdown field types
474
+ * - id int an unchanging id for the merge var
475
+ */
476
+ public function mergeVarUpdate($id, $tag, $options) {
477
+ $_params = array("id" => $id, "tag" => $tag, "options" => $options);
478
+ return $this->master->call('lists/merge-var-update', $_params);
479
+ }
480
+
481
+ /**
482
+ * Get the list of merge tags for a given list, including their name, tag, and required setting
483
+ * @param array $id
484
+ * @return associative_array of data and success/error counts
485
+ * - success_count int the number of subscribers successfully found on the list
486
+ * - error_count int the number of subscribers who were not found on the list
487
+ * - data array of structs for the merge tags on each list
488
+ * - id string the list id
489
+ * - name string the list name
490
+ * - merge_vars array of structs for each merge var
491
+ * - name string Name of the merge field
492
+ * - req bool Denotes whether the field is required (true) or not (false)
493
+ * - field_type string The "data type" of this merge var. One of the options accepted by field_type in lists/merge-var-add
494
+ * - public bool Whether or not this field is visible to list subscribers
495
+ * - show bool Whether the list owner has this field displayed on their list dashboard
496
+ * - order string The order the list owner has set this field to display in
497
+ * - default string The default value the list owner has set for this field
498
+ * - helptext string The helptext for this field
499
+ * - size string The width of the field to be used
500
+ * - tag string The merge tag that's used for forms and lists/subscribe() and listUpdateMember()
501
+ * - choices array For radio and dropdown field types, an array of the options available
502
+ * - id int an unchanging id for the merge var
503
+ * - errors array of error structs
504
+ * - id string the passed list id that failed
505
+ * - code int the resulting error code
506
+ * - msg string the resulting error message
507
+ */
508
+ public function mergeVars($id) {
509
+ $_params = array("id" => $id);
510
+ return $this->master->call('lists/merge-vars', $_params);
511
+ }
512
+
513
+ /**
514
+ * Retrieve all of Segments for a list.
515
+ * @param string $id
516
+ * @param string $type
517
+ * @return associative_array with 2 keys:
518
+ * - static array of structs with data for each segment
519
+ * - id int the id of the segment
520
+ * - name string the name for the segment
521
+ * - created_date string the date+time the segment was created
522
+ * - last_update string the date+time the segment was last updated (add or del)
523
+ * - last_reset string the date+time the segment was last reset (ie had all members cleared from it)
524
+ * - saved array of structs with data for each segment
525
+ * - id int the id of the segment
526
+ * - name string the name for the segment
527
+ * - segment_opts string same match+conditions struct typically used
528
+ * - segment_text string a textual description of the segment match/conditions
529
+ * - created_date string the date+time the segment was created
530
+ * - last_update string the date+time the segment was last updated (add or del)
531
+ */
532
+ public function segments($id, $type=null) {
533
+ $_params = array("id" => $id, "type" => $type);
534
+ return $this->master->call('lists/segments', $_params);
535
+ }
536
+
537
+ /**
538
+ * Save a segment against a list for later use. There is no limit to the number of segments which can be saved. Static Segments <strong>are not</strong> tied
539
+ to any merge data, interest groups, etc. They essentially allow you to configure an unlimited number of custom segments which will have standard performance.
540
+ When using proper segments, Static Segments are one of the available options for segmentation just as if you used a merge var (and they can be used with other segmentation
541
+ options), though performance may degrade at that point. Saved Segments (called "auto-updating" in the app) are essentially just the match+conditions typically
542
+ used.
543
+ * @param string $id
544
+ * @param associative_array $opts
545
+ * - type string either "static" or "saved"
546
+ * - name string a unique name per list for the segment - 100 byte maximum length, anything longer will throw an error
547
+ * - segment_opts associative_array for "saved" only, the standard segment match+conditions, just like campaigns/segment-test
548
+ * - match string "any" or "all"
549
+ * - conditions array structs for each condition, just like campaigns/segment-test
550
+ * @return associative_array with a single entry:
551
+ * - id int the id of the new segment, otherwise an error will be thrown.
552
+ */
553
+ public function segmentAdd($id, $opts) {
554
+ $_params = array("id" => $id, "opts" => $opts);
555
+ return $this->master->call('lists/segment-add', $_params);
556
+ }
557
+
558
+ /**
559
+ * Delete a segment. Note that this will, of course, remove any member affiliations with any static segments deleted
560
+ * @param string $id
561
+ * @param int $seg_id
562
+ * @return associative_array with a single entry:
563
+ * - complete bool whether the call worked. reallistically this will always be true as errors will be thrown otherwise.
564
+ */
565
+ public function segmentDel($id, $seg_id) {
566
+ $_params = array("id" => $id, "seg_id" => $seg_id);
567
+ return $this->master->call('lists/segment-del', $_params);
568
+ }
569
+
570
+ /**
571
+ * Allows one to test their segmentation rules before creating a campaign using them - this is no different from campaigns/segment-test() and will eventually replace it.
572
+ For the time being, the crazy segmenting condition documentation will continue to live over there.
573
+ * @param string $list_id
574
+ * @param associative_array $options
575
+ * @return associative_array with a single entry:
576
+ * - total int The total number of subscribers matching your segmentation options
577
+ */
578
+ public function segmentTest($list_id, $options) {
579
+ $_params = array("list_id" => $list_id, "options" => $options);
580
+ return $this->master->call('lists/segment-test', $_params);
581
+ }
582
+
583
+ /**
584
+ * Update an existing segment. The list and type can not be changed.
585
+ * @param string $id
586
+ * @param int $seg_id
587
+ * @param associative_array $opts
588
+ * - name string a unique name per list for the segment - 100 byte maximum length, anything longer will throw an error
589
+ * - segment_opts associative_array for "saved" only, the standard segment match+conditions, just like campaigns/segment-test
590
+ * - match string "any" or "all"
591
+ * - conditions array structs for each condition, just like campaigns/segment-test
592
+ * @return associative_array with a single entry:
593
+ * - complete bool whether the call worked. reallistically this will always be true as errors will be thrown otherwise.
594
+ */
595
+ public function segmentUpdate($id, $seg_id, $opts) {
596
+ $_params = array("id" => $id, "seg_id" => $seg_id, "opts" => $opts);
597
+ return $this->master->call('lists/segment-update', $_params);
598
+ }
599
+
600
+ /**
601
+ * Save a segment against a list for later use. There is no limit to the number of segments which can be saved. Static Segments <strong>are not</strong> tied
602
+ to any merge data, interest groups, etc. They essentially allow you to configure an unlimited number of custom segments which will have standard performance.
603
+ When using proper segments, Static Segments are one of the available options for segmentation just as if you used a merge var (and they can be used with other segmentation
604
+ options), though performance may degrade at that point.
605
+ * @param string $id
606
+ * @param string $name
607
+ * @return associative_array with a single entry:
608
+ * - id int the id of the new segment, otherwise an error will be thrown.
609
+ */
610
+ public function staticSegmentAdd($id, $name) {
611
+ $_params = array("id" => $id, "name" => $name);
612
+ return $this->master->call('lists/static-segment-add', $_params);
613
+ }
614
+
615
+ /**
616
+ * Delete a static segment. Note that this will, of course, remove any member affiliations with the segment
617
+ * @param string $id
618
+ * @param int $seg_id
619
+ * @return associative_array with a single entry:
620
+ * - complete bool whether the call worked. reallistically this will always be true as errors will be thrown otherwise.
621
+ */
622
+ public function staticSegmentDel($id, $seg_id) {
623
+ $_params = array("id" => $id, "seg_id" => $seg_id);
624
+ return $this->master->call('lists/static-segment-del', $_params);
625
+ }
626
+
627
+ /**
628
+ * Add list members to a static segment. It is suggested that you limit batch size to no more than 10,000 addresses per call. Email addresses must exist on the list
629
+ in order to be included - this <strong>will not</strong> subscribe them to the list!
630
+ * @param string $id
631
+ * @param int $seg_id
632
+ * @param array $batch
633
+ * - email string an email address
634
+ * - euid string the unique id for an email address (not list related) - the email "id" returned from listMemberInfo, Webhooks, Campaigns, etc.
635
+ * - leid string the list email id (previously called web_id) for a list-member-info type call. this doesn't change when the email address changes
636
+ * @return associative_array an array with the results of the operation
637
+ * - success_count int the total number of successful updates (will include members already in the segment)
638
+ * - errors array structs for each error including:
639
+ * - email string whatever was passed in the email parameter
640
+ * - email string the email address added
641
+ * - euid string the email unique id
642
+ * - leid string the list member's truly unique id
643
+ * - code string the error code
644
+ * - error string the full error message
645
+ */
646
+ public function staticSegmentMembersAdd($id, $seg_id, $batch) {
647
+ $_params = array("id" => $id, "seg_id" => $seg_id, "batch" => $batch);
648
+ return $this->master->call('lists/static-segment-members-add', $_params);
649
+ }
650
+
651
+ /**
652
+ * Remove list members from a static segment. It is suggested that you limit batch size to no more than 10,000 addresses per call. Email addresses must exist on the list
653
+ in order to be removed - this <strong>will not</strong> unsubscribe them from the list!
654
+ * @param string $id
655
+ * @param int $seg_id
656
+ * @param array $batch
657
+ * - email string an email address
658
+ * - euid string the unique id for an email address (not list related) - the email "id" returned from listMemberInfo, Webhooks, Campaigns, etc.
659
+ * - leid string the list email id (previously called web_id) for a list-member-info type call. this doesn't change when the email address changes
660
+ * @return associative_array an array with the results of the operation
661
+ * - success_count int the total number of successful removals
662
+ * - error_count int the total number of unsuccessful removals
663
+ * - errors array structs for each error including:
664
+ * - email string whatever was passed in the email parameter
665
+ * - email string the email address added
666
+ * - euid string the email unique id
667
+ * - leid string the list member's truly unique id
668
+ * - code string the error code
669
+ * - error string the full error message
670
+ */
671
+ public function staticSegmentMembersDel($id, $seg_id, $batch) {
672
+ $_params = array("id" => $id, "seg_id" => $seg_id, "batch" => $batch);
673
+ return $this->master->call('lists/static-segment-members-del', $_params);
674
+ }
675
+
676
+ /**
677
+ * Resets a static segment - removes <strong>all</strong> members from the static segment. Note: does not actually affect list member data
678
+ * @param string $id
679
+ * @param int $seg_id
680
+ * @return associative_array with a single entry:
681
+ * - complete bool whether the call worked. reallistically this will always be true as errors will be thrown otherwise.
682
+ */
683
+ public function staticSegmentReset($id, $seg_id) {
684
+ $_params = array("id" => $id, "seg_id" => $seg_id);
685
+ return $this->master->call('lists/static-segment-reset', $_params);
686
+ }
687
+
688
+ /**
689
+ * Retrieve all of the Static Segments for a list.
690
+ * @param string $id
691
+ * @param boolean $get_counts
692
+ * @param int $start
693
+ * @param int $limit
694
+ * @return array an of structs with data for each static segment
695
+ * - id int the id of the segment
696
+ * - name string the name for the segment
697
+ * - member_count int the total number of subscribed members currently in a segment
698
+ * - created_date string the date+time the segment was created
699
+ * - last_update string the date+time the segment was last updated (add or del)
700
+ * - last_reset string the date+time the segment was last reset (ie had all members cleared from it)
701
+ */
702
+ public function staticSegments($id, $get_counts=true, $start=0, $limit=null) {
703
+ $_params = array("id" => $id, "get_counts" => $get_counts, "start" => $start, "limit" => $limit);
704
+ return $this->master->call('lists/static-segments', $_params);
705
+ }
706
+
707
+ /**
708
+ * Subscribe the provided email to a list. By default this sends a confirmation email - you will not see new members until the link contained in it is clicked!
709
+ * @param string $id
710
+ * @param associative_array $email
711
+ * - email string an email address - for new subscribers obviously this should be used
712
+ * - euid string the unique id for an email address (not list related) - the email "id" returned from listMemberInfo, Webhooks, Campaigns, etc.
713
+ * - leid string the list email id (previously called web_id) for a list-member-info type call. this doesn't change when the email address changes
714
+ * @param associative_array $merge_vars
715
+ * - new-email string set this to change the email address. This is only respected on calls using update_existing or when passed to lists/update.
716
+ * - groupings array of Interest Grouping structs. Each should contain:
717
+ * - id int Grouping "id" from lists/interest-groupings (either this or name must be present) - this id takes precedence and can't change (unlike the name)
718
+ * - name string Grouping "name" from lists/interest-groupings (either this or id must be present)
719
+ * - groups array an array of valid group names for this grouping.
720
+ * - optin_ip string Set the Opt-in IP field. <em>Abusing this may cause your account to be suspended.</em> We do validate this and it must not be a private IP address.
721
+ * - optin_time string Set the Opt-in Time field. <em>Abusing this may cause your account to be suspended.</em> We do validate this and it must be a valid date. Use - 24 hour format in <strong>GMT</strong>, eg "2013-12-30 20:30:00" to be safe. Generally, though, anything strtotime() understands we'll understand - <a href="http://us2.php.net/strtotime" target="_blank">http://us2.php.net/strtotime</a>
722
+ * - mc_location associative_array Set the member's geographic location either by optin_ip or geo data.
723
+ * - latitude string use the specified latitude (longitude must exist for this to work)
724
+ * - longitude string use the specified longitude (latitude must exist for this to work)
725
+ * - anything string if this (or any other key exists here) we'll try to use the optin ip. NOTE - this will slow down each subscribe call a bit, especially for lat/lng pairs in sparsely populated areas. Currently our automated background processes can and will overwrite this based on opens and clicks.
726
+ * - mc_language string Set the member's language preference. Supported codes are fully case-sensitive and can be found <a href="http://kb.mailchimp.com/article/can-i-see-what-languages-my-subscribers-use#code" target="_new">here</a>.
727
+ * - mc_notes array of structs for managing notes - it may contain:
728
+ * - note string the note to set. this is required unless you're deleting a note
729
+ * - id int the note id to operate on. not including this (or using an invalid id) causes a new note to be added
730
+ * - action string if the "id" key exists and is valid, an "update" key may be set to "append" (default), "prepend", "replace", or "delete" to handle how we should update existing notes. "delete", obviously, will only work with a valid "id" - passing that along with "note" and an invalid "id" is wrong and will be ignored.
731
+ * @param string $email_type
732
+ * @param bool $double_optin
733
+ * @param bool $update_existing
734
+ * @param bool $replace_interests
735
+ * @param bool $send_welcome
736
+ * @return associative_array the ids for this subscriber
737
+ * - email string the email address added
738
+ * - euid string the email unique id
739
+ * - leid string the list member's truly unique id
740
+ */
741
+ public function subscribe($id, $email, $merge_vars=null, $email_type='html', $double_optin=true, $update_existing=false, $replace_interests=true, $send_welcome=false) {
742
+ $_params = array("id" => $id, "email" => $email, "merge_vars" => $merge_vars, "email_type" => $email_type, "double_optin" => $double_optin, "update_existing" => $update_existing, "replace_interests" => $replace_interests, "send_welcome" => $send_welcome);
743
+ return $this->master->call('lists/subscribe', $_params);
744
+ }
745
+
746
+ /**
747
+ * Unsubscribe the given email address from the list
748
+ * @param string $id
749
+ * @param associative_array $email
750
+ * - email string an email address
751
+ * - euid string the unique id for an email address (not list related) - the email "id" returned from listMemberInfo, Webhooks, Campaigns, etc.
752
+ * - leid string the list email id (previously called web_id) for a list-member-info type call. this doesn't change when the email address changes
753
+ * @param boolean $delete_member
754
+ * @param boolean $send_goodbye
755
+ * @param boolean $send_notify
756
+ * @return associative_array with a single entry:
757
+ * - complete bool whether the call worked. reallistically this will always be true as errors will be thrown otherwise.
758
+ */
759
+ public function unsubscribe($id, $email, $delete_member=false, $send_goodbye=true, $send_notify=true) {
760
+ $_params = array("id" => $id, "email" => $email, "delete_member" => $delete_member, "send_goodbye" => $send_goodbye, "send_notify" => $send_notify);
761
+ return $this->master->call('lists/unsubscribe', $_params);
762
+ }
763
+
764
+ /**
765
+ * Edit the email address, merge fields, and interest groups for a list member. If you are doing a batch update on lots of users,
766
+ consider using lists/batch-subscribe() with the update_existing and possible replace_interests parameter.
767
+ * @param string $id
768
+ * @param associative_array $email
769
+ * - email string an email address
770
+ * - euid string the unique id for an email address (not list related) - the email "id" returned from listMemberInfo, Webhooks, Campaigns, etc.
771
+ * - leid string the list email id (previously called web_id) for a list-member-info type call. this doesn't change when the email address changes
772
+ * @param array $merge_vars
773
+ * @param string $email_type
774
+ * @param boolean $replace_interests
775
+ * @return associative_array the ids for this subscriber
776
+ * - email string the email address added
777
+ * - euid string the email unique id
778
+ * - leid string the list member's truly unique id
779
+ */
780
+ public function updateMember($id, $email, $merge_vars, $email_type='', $replace_interests=true) {
781
+ $_params = array("id" => $id, "email" => $email, "merge_vars" => $merge_vars, "email_type" => $email_type, "replace_interests" => $replace_interests);
782
+ return $this->master->call('lists/update-member', $_params);
783
+ }
784
+
785
+ /**
786
+ * Add a new Webhook URL for the given list
787
+ * @param string $id
788
+ * @param string $url
789
+ * @param associative_array $actions
790
+ * - subscribe bool optional as subscribes occur, defaults to true
791
+ * - unsubscribe bool optional as subscribes occur, defaults to true
792
+ * - profile bool optional as profile updates occur, defaults to true
793
+ * - cleaned bool optional as emails are cleaned from the list, defaults to true
794
+ * - upemail bool optional when subscribers change their email address, defaults to true
795
+ * - campaign bool option when a campaign is sent or canceled, defaults to true
796
+ * @param associative_array $sources
797
+ * - user bool optional user/subscriber initiated actions, defaults to true
798
+ * - admin bool optional admin actions in our web app, defaults to true
799
+ * - api bool optional actions that happen via API calls, defaults to false
800
+ * @return associative_array with a single entry:
801
+ * - id int the id of the new webhook, otherwise an error will be thrown.
802
+ */
803
+ public function webhookAdd($id, $url, $actions=array(), $sources=array()) {
804
+ $_params = array("id" => $id, "url" => $url, "actions" => $actions, "sources" => $sources);
805
+ return $this->master->call('lists/webhook-add', $_params);
806
+ }
807
+
808
+ /**
809
+ * Delete an existing Webhook URL from a given list
810
+ * @param string $id
811
+ * @param string $url
812
+ * @return associative_array with a single entry:
813
+ * - complete bool whether the call worked. reallistically this will always be true as errors will be thrown otherwise.
814
+ */
815
+ public function webhookDel($id, $url) {
816
+ $_params = array("id" => $id, "url" => $url);
817
+ return $this->master->call('lists/webhook-del', $_params);
818
+ }
819
+
820
+ /**
821
+ * Return the Webhooks configured for the given list
822
+ * @param string $id
823
+ * @return array of structs for each webhook
824
+ * - url string the URL for this Webhook
825
+ * - actions associative_array the possible actions and whether they are enabled
826
+ * - subscribe bool triggered when subscribes happen
827
+ * - unsubscribe bool triggered when unsubscribes happen
828
+ * - profile bool triggered when profile updates happen
829
+ * - cleaned bool triggered when a subscriber is cleaned (bounced) from a list
830
+ * - upemail bool triggered when a subscriber's email address is changed
831
+ * - campaign bool triggered when a campaign is sent or canceled
832
+ * - sources associative_array the possible sources and whether they are enabled
833
+ * - user bool whether user/subscriber triggered actions are returned
834
+ * - admin bool whether admin (manual, in-app) triggered actions are returned
835
+ * - api bool whether api triggered actions are returned
836
+ */
837
+ public function webhooks($id) {
838
+ $_params = array("id" => $id);
839
+ return $this->master->call('lists/webhooks', $_params);
840
+ }
841
+
842
+ /**
843
+ * Retrieve all of the lists defined for your user account
844
+ * @param associative_array $filters
845
+ * - list_id string optional - return a single list using a known list_id. Accepts multiples separated by commas when not using exact matching
846
+ * - list_name string optional - only lists that match this name
847
+ * - from_name string optional - only lists that have a default from name matching this
848
+ * - from_email string optional - only lists that have a default from email matching this
849
+ * - from_subject string optional - only lists that have a default from email matching this
850
+ * - created_before string optional - only show lists that were created before this date+time - 24 hour format in <strong>GMT</strong>, eg "2013-12-30 20:30:00"
851
+ * - created_after string optional - only show lists that were created since this date+time - 24 hour format in <strong>GMT</strong>, eg "2013-12-30 20:30:00"
852
+ * - exact boolean optional - flag for whether to filter on exact values when filtering, or search within content for filter values - defaults to true
853
+ * @param int $start
854
+ * @param int $limit
855
+ * @param string $sort_field
856
+ * @param string $sort_dir
857
+ * @return associative_array result of the operation including valid data and any errors
858
+ * - total int the total number of lists which matched the provided filters
859
+ * - data array structs for the lists which matched the provided filters, including the following
860
+ * - id string The list id for this list. This will be used for all other list management functions.
861
+ * - web_id int The list id used in our web app, allows you to create a link directly to it
862
+ * - name string The name of the list.
863
+ * - date_created string The date that this list was created.
864
+ * - email_type_option boolean Whether or not the List supports multiple formats for emails or just HTML
865
+ * - use_awesomebar boolean Whether or not campaigns for this list use the Awesome Bar in archives by default
866
+ * - default_from_name string Default From Name for campaigns using this list
867
+ * - default_from_email string Default From Email for campaigns using this list
868
+ * - default_subject string Default Subject Line for campaigns using this list
869
+ * - default_language string Default Language for this list's forms
870
+ * - list_rating double An auto-generated activity score for the list (0 - 5)
871
+ * - subscribe_url_short string Our eepurl shortened version of this list's subscribe form (will not change)
872
+ * - subscribe_url_long string The full version of this list's subscribe form (host will vary)
873
+ * - beamer_address string The email address to use for this list's <a href="http://kb.mailchimp.com/article/how-do-i-import-a-campaign-via-email-email-beamer/">Email Beamer</a>
874
+ * - visibility string Whether this list is Public (pub) or Private (prv). Used internally for projects like <a href="http://blog.mailchimp.com/introducing-wavelength/" target="_blank">Wavelength</a>
875
+ * - stats associative_array various stats and counts for the list - many of these are cached for at least 5 minutes
876
+ * - member_count double The number of active members in the given list.
877
+ * - unsubscribe_count double The number of members who have unsubscribed from the given list.
878
+ * - cleaned_count double The number of members cleaned from the given list.
879
+ * - member_count_since_send double The number of active members in the given list since the last campaign was sent
880
+ * - unsubscribe_count_since_send double The number of members who have unsubscribed from the given list since the last campaign was sent
881
+ * - cleaned_count_since_send double The number of members cleaned from the given list since the last campaign was sent
882
+ * - campaign_count double The number of campaigns in any status that use this list
883
+ * - grouping_count double The number of Interest Groupings for this list
884
+ * - group_count double The number of Interest Groups (regardless of grouping) for this list
885
+ * - merge_var_count double The number of merge vars for this list (not including the required EMAIL one)
886
+ * - avg_sub_rate double the average number of subscribe per month for the list (empty value if we haven't calculated this yet)
887
+ * - avg_unsub_rate double the average number of unsubscribe per month for the list (empty value if we haven't calculated this yet)
888
+ * - target_sub_rate double the target subscription rate for the list to keep it growing (empty value if we haven't calculated this yet)
889
+ * - open_rate double the average open rate per campaign for the list (empty value if we haven't calculated this yet)
890
+ * - click_rate double the average click rate per campaign for the list (empty value if we haven't calculated this yet)
891
+ * - modules array Any list specific modules installed for this list (example is SocialPro)
892
+ * - errors array structs of any errors found while loading lists - usually just from providing invalid list ids
893
+ * - param string the data that caused the failure
894
+ * - code int the error code
895
+ * - error string the error message
896
+ */
897
+ public function getList($filters=array(), $start=0, $limit=25, $sort_field='created', $sort_dir='DESC') {
898
+ $_params = array("filters" => $filters, "start" => $start, "limit" => $limit, "sort_field" => $sort_field, "sort_dir" => $sort_dir);
899
+ return $this->master->call('lists/list', $_params);
900
+ }
901
+
902
+ }
903
+
904
+
includes/vendor/mailchimp/Mailchimp/Mobile.php ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Mailchimp_Mobile {
4
+ public function __construct(Mailchimp $master) {
5
+ $this->master = $master;
6
+ }
7
+
8
+ }
9
+
10
+
includes/vendor/mailchimp/Mailchimp/Neapolitan.php ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Mailchimp_Neapolitan {
4
+ public function __construct(Mailchimp $master) {
5
+ $this->master = $master;
6
+ }
7
+
8
+ }
9
+
10
+
includes/vendor/mailchimp/Mailchimp/Reports.php ADDED
@@ -0,0 +1,459 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Mailchimp_Reports {
4
+ public function __construct(Mailchimp $master) {
5
+ $this->master = $master;
6
+ }
7
+
8
+ /**
9
+ * Get all email addresses that complained about a given campaign
10
+ * @param string $cid
11
+ * @param associative_array $opts
12
+ * - start int optional for large data sets, the page number to start at - defaults to 1st page of data (page 0)
13
+ * - limit int optional for large data sets, the number of results to return - defaults to 25, upper limit set at 100
14
+ * - since string optional pull only messages since this time - 24 hour format in <strong>GMT</strong>, eg "2013-12-30 20:30:00"
15
+ * @return associative_array abuse report data for this campaign
16
+ * - total int the total reports matched
17
+ * - data array a struct for the each report, including:
18
+ * - date string date/time the abuse report was received and processed
19
+ * - member string the email address that reported abuse - will only contain email if the list or member has been removed
20
+ * - type string an internal type generally specifying the originating mail provider - may not be useful outside of filling report views
21
+ */
22
+ public function abuse($cid, $opts=array()) {
23
+ $_params = array("cid" => $cid, "opts" => $opts);
24
+ return $this->master->call('reports/abuse', $_params);
25
+ }
26
+
27
+ /**
28
+ * Retrieve the text presented in our app for how a campaign performed and any advice we may have for you - best
29
+ suited for display in customized reports pages. Note: some messages will contain HTML - clean tags as necessary
30
+ * @param string $cid
31
+ * @return array of structs for advice on the campaign's performance, each containing:
32
+ * - msg string the advice message
33
+ * - type string the "type" of the message. one of: negative, positive, or neutral
34
+ */
35
+ public function advice($cid) {
36
+ $_params = array("cid" => $cid);
37
+ return $this->master->call('reports/advice', $_params);
38
+ }
39
+
40
+ /**
41
+ * Retrieve the most recent full bounce message for a specific email address on the given campaign.
42
+ Messages over 30 days old are subject to being removed
43
+ * @param string $cid
44
+ * @param associative_array $email
45
+ * - email string an email address - this is recommended for this method
46
+ * - euid string the unique id for an email address (not list related) - the email "id" returned from listMemberInfo, Webhooks, Campaigns, etc.
47
+ * - leid string the list email id (previously called web_id) for a list-member-info type call. this doesn't change when the email address changes
48
+ * @return associative_array the full bounce message for this email+campaign along with some extra data.
49
+ * - date string date the bounce was received and processed
50
+ * - member associative_array the member record as returned by lists/member-info()
51
+ * - message string the entire bounce message received
52
+ */
53
+ public function bounceMessage($cid, $email) {
54
+ $_params = array("cid" => $cid, "email" => $email);
55
+ return $this->master->call('reports/bounce-message', $_params);
56
+ }
57
+
58
+ /**
59
+ * Retrieve the full bounce messages for the given campaign. Note that this can return very large amounts
60
+ of data depending on how large the campaign was and how much cruft the bounce provider returned. Also,
61
+ messages over 30 days old are subject to being removed
62
+ * @param string $cid
63
+ * @param associative_array $opts
64
+ * - start int optional for large data sets, the page number to start at - defaults to 1st page of data (page 0)
65
+ * - limit int optional for large data sets, the number of results to return - defaults to 25, upper limit set at 100
66
+ * - since string optional pull only messages since this time - 24 hour format in <strong>GMT</strong>, eg "2013-12-30 20:30:00"
67
+ * @return associative_array data for the full bounce messages for this campaign
68
+ * - total int that total number of bounce messages for the campaign
69
+ * - data array structs containing the data for this page
70
+ * - date string date the bounce was received and processed
71
+ * - member associative_array the member record as returned by lists/member-info()
72
+ * - message string the entire bounce message received
73
+ */
74
+ public function bounceMessages($cid, $opts=array()) {
75
+ $_params = array("cid" => $cid, "opts" => $opts);
76
+ return $this->master->call('reports/bounce-messages', $_params);
77
+ }
78
+
79
+ /**
80
+ * Return the list of email addresses that clicked on a given url, and how many times they clicked
81
+ * @param string $cid
82
+ * @param int $tid
83
+ * @param associative_array $opts
84
+ * - start int optional for large data sets, the page number to start at - defaults to 1st page of data (page 0)
85
+ * - limit int optional for large data sets, the number of results to return - defaults to 25, upper limit set at 100
86
+ * - sort_field string optional the data to sort by - "clicked" (order clicks occurred, default) or "clicks" (total number of opens). Invalid fields will fall back on the default.
87
+ * - sort_dir string optional the direct - ASC or DESC. defaults to ASC (case insensitive)
88
+ * @return associative_array containing the total records matched and the specific records for this page
89
+ * - total int the total number of records matched
90
+ * - data array structs for each email addresses that click the requested url
91
+ * - member associative_array the member record as returned by lists/member-info()
92
+ * - clicks int Total number of times the URL was clicked by this email address
93
+ */
94
+ public function clickDetail($cid, $tid, $opts=array()) {
95
+ $_params = array("cid" => $cid, "tid" => $tid, "opts" => $opts);
96
+ return $this->master->call('reports/click-detail', $_params);
97
+ }
98
+
99
+ /**
100
+ * The urls tracked and their click counts for a given campaign.
101
+ * @param string $cid
102
+ * @return associative_array including:
103
+ * - total array structs for each url tracked for the full campaign
104
+ * - url string the url being tracked - urls are tracked individually, so duplicates can exist with vastly different stats
105
+ * - clicks int Number of times the specific link was clicked
106
+ * - clicks_percent double the percentage of total clicks "clicks" represents
107
+ * - unique int Number of unique people who clicked on the specific link
108
+ * - unique_percent double the percentage of unique clicks "unique" represents
109
+ * - tid int the tracking id used in campaign links - used primarily for reports/click-activity. also can be used to order urls by the order they appeared in the campaign to recreate our heat map.
110
+ * - a array if this was an absplit campaign, stat structs for the a group
111
+ * - url string the url being tracked - urls are tracked individually, so duplicates can exist with vastly different stats
112
+ * - clicks int Number of times the specific link was clicked
113
+ * - clicks_percent double the percentage of total clicks "clicks" represents
114
+ * - unique int Number of unique people who clicked on the specific link
115
+ * - unique_percent double the percentage of unique clicks "unique" represents
116
+ * - tid int the tracking id used in campaign links - used primarily for reports/click-activity. also can be used to order urls by the order they appeared in the campaign to recreate our heat map.
117
+ * - b array if this was an absplit campaign, stat structs for the b group
118
+ * - url string the url being tracked - urls are tracked individually, so duplicates can exist with vastly different stats
119
+ * - clicks int Number of times the specific link was clicked
120
+ * - clicks_percent double the percentage of total clicks "clicks" represents
121
+ * - unique int Number of unique people who clicked on the specific link
122
+ * - unique_percent double the percentage of unique clicks "unique" represents
123
+ * - tid int the tracking id used in campaign links - used primarily for reports/click-activity. also can be used to order urls by the order they appeared in the campaign to recreate our heat map.
124
+ */
125
+ public function clicks($cid) {
126
+ $_params = array("cid" => $cid);
127
+ return $this->master->call('reports/clicks', $_params);
128
+ }
129
+
130
+ /**
131
+ * Retrieve the Ecommerce Orders tracked by ecomm/order-add()
132
+ * @param string $cid
133
+ * @param associative_array $opts
134
+ * - start int optional for large data sets, the page number to start at - defaults to 1st page of data (page 0)
135
+ * - limit int optional for large data sets, the number of results to return - defaults to 25, upper limit set at 100
136
+ * - since string optional pull only messages since this time - 24 hour format in <strong>GMT</strong>, eg "2013-12-30 20:30:00"
137
+ * @return associative_array the total matching orders and the specific orders for the requested page
138
+ * - total int the total matching orders
139
+ * - data array structs for the actual data for each order being returned
140
+ * - store_id string the store id generated by the plugin used to uniquely identify a store
141
+ * - store_name string the store name collected by the plugin - often the domain name
142
+ * - order_id string the internal order id the store tracked this order by
143
+ * - member associative_array the member record as returned by lists/member-info() that received this campaign and is associated with this order
144
+ * - order_total double the order total
145
+ * - tax_total double the total tax for the order (if collected)
146
+ * - ship_total double the shipping total for the order (if collected)
147
+ * - order_date string the date the order was tracked - from the store if possible, otherwise the GMT time we received it
148
+ * - lines array structs containing details of the order:
149
+ * - line_num int the line number assigned to this line
150
+ * - product_id int the product id assigned to this item
151
+ * - product_name string the product name
152
+ * - product_sku string the sku for the product
153
+ * - product_category_id int the id for the product category
154
+ * - product_category_name string the product category name
155
+ * - qty double optional the quantity of the item ordered - defaults to 1
156
+ * - cost double optional the cost of a single item (ie, not the extended cost of the line) - defaults to 0
157
+ */
158
+ public function ecommOrders($cid, $opts=array()) {
159
+ $_params = array("cid" => $cid, "opts" => $opts);
160
+ return $this->master->call('reports/ecomm-orders', $_params);
161
+ }
162
+
163
+ /**
164
+ * Retrieve the eepurl stats from the web/Twitter mentions for this campaign
165
+ * @param string $cid
166
+ * @return associative_array containing tweets, retweets, clicks, and referrer related to using the campaign's eepurl
167
+ * - twitter associative_array various Twitter related stats
168
+ * - tweets int Total number of tweets seen
169
+ * - first_tweet string date and time of the first tweet seen
170
+ * - last_tweet string date and time of the last tweet seen
171
+ * - retweets int Total number of retweets seen
172
+ * - first_retweet string date and time of the first retweet seen
173
+ * - last_retweet string date and time of the last retweet seen
174
+ * - statuses array an structs for statuses recorded including:
175
+ * - status string the text of the tweet/update
176
+ * - screen_name string the screen name as recorded when first seen
177
+ * - status_id string the status id of the tweet (they are really unsigned 64 bit ints)
178
+ * - datetime string the date/time of the tweet
179
+ * - is_retweet bool whether or not this was a retweet
180
+ * - clicks associative_array stats related to click-throughs on the eepurl
181
+ * - clicks int Total number of clicks seen
182
+ * - first_click string date and time of the first click seen
183
+ * - last_click string date and time of the first click seen
184
+ * - locations array structs for geographic locations including:
185
+ * - country string the country name the click was tracked to
186
+ * - region string the region in the country the click was tracked to (if available)
187
+ * - referrers array structs for referrers, including
188
+ * - referrer string the referrer, truncated to 100 bytes
189
+ * - clicks int Total number of clicks seen from this referrer
190
+ * - first_click string date and time of the first click seen from this referrer
191
+ * - last_click string date and time of the first click seen from this referrer
192
+ */
193
+ public function eepurl($cid) {
194
+ $_params = array("cid" => $cid);
195
+ return $this->master->call('reports/eepurl', $_params);
196
+ }
197
+
198
+ /**
199
+ * Given a campaign and email address, return the entire click and open history with timestamps, ordered by time. If you need to dump the full activity for a campaign
200
+ and/or get incremental results, you should use the <a href="http://apidocs.mailchimp.com/export/1.0/campaignsubscriberactivity.func.php" targret="_new">campaignSubscriberActivity Export API method</a>,
201
+ <strong>not</strong> this, especially for large campaigns.
202
+ * @param string $cid
203
+ * @param array $emails
204
+ * - email string an email address
205
+ * - euid string the unique id for an email address (not list related) - the email "id" returned from listMemberInfo, Webhooks, Campaigns, etc.
206
+ * - leid string the list email id (previously called web_id) for a list-member-info type call. this doesn't change when the email address changes
207
+ * @return associative_array of data and success/error counts
208
+ * - success_count int the number of subscribers successfully found on the list
209
+ * - error_count int the number of subscribers who were not found on the list
210
+ * - errors array array of error structs including:
211
+ * - email string whatever was passed in the email parameter
212
+ * - email string the email address added
213
+ * - euid string the email unique id
214
+ * - leid string the list member's truly unique id
215
+ * - msg string the error message
216
+ * - data array an array of structs where each activity record has:
217
+ * - email string whatever was passed in the email parameter
218
+ * - email string the email address added
219
+ * - euid string the email unique id
220
+ * - leid string the list member's truly unique id
221
+ * - member associative_array the member record as returned by lists/member-info()
222
+ * - activity array an array of structs containing the activity, including:
223
+ * - action string The action name - either open or click
224
+ * - timestamp string The date/time of the action (GMT)
225
+ * - url string For click actions, the url clicked, otherwise this is empty
226
+ * - ip string The IP address the activity came from
227
+ */
228
+ public function memberActivity($cid, $emails) {
229
+ $_params = array("cid" => $cid, "emails" => $emails);
230
+ return $this->master->call('reports/member-activity', $_params);
231
+ }
232
+
233
+ /**
234
+ * Retrieve the list of email addresses that did not open a given campaign
235
+ * @param string $cid
236
+ * @param associative_array $opts
237
+ * - start int optional for large data sets, the page number to start at - defaults to 1st page of data (page 0)
238
+ * - limit int optional for large data sets, the number of results to return - defaults to 25, upper limit set at 100
239
+ * @return associative_array a total of all matching emails and the specific emails for this page
240
+ * - total int the total number of members who didn't open the campaign
241
+ * - data array structs for each campaign member matching as returned by lists/member-info()
242
+ */
243
+ public function notOpened($cid, $opts=array()) {
244
+ $_params = array("cid" => $cid, "opts" => $opts);
245
+ return $this->master->call('reports/not-opened', $_params);
246
+ }
247
+
248
+ /**
249
+ * Retrieve the list of email addresses that opened a given campaign with how many times they opened
250
+ * @param string $cid
251
+ * @param associative_array $opts
252
+ * - start int optional for large data sets, the page number to start at - defaults to 1st page of data (page 0)
253
+ * - limit int optional for large data sets, the number of results to return - defaults to 25, upper limit set at 100
254
+ * - sort_field string optional the data to sort by - "opened" (order opens occurred, default) or "opens" (total number of opens). Invalid fields will fall back on the default.
255
+ * - sort_dir string optional the direct - ASC or DESC. defaults to ASC (case insensitive)
256
+ * @return associative_array containing the total records matched and the specific records for this page
257
+ * - total int the total number of records matched
258
+ * - data array structs for the actual opens data, including:
259
+ * - member associative_array the member record as returned by lists/member-info()
260
+ * - opens int Total number of times the campaign was opened by this email address
261
+ */
262
+ public function opened($cid, $opts=array()) {
263
+ $_params = array("cid" => $cid, "opts" => $opts);
264
+ return $this->master->call('reports/opened', $_params);
265
+ }
266
+
267
+ /**
268
+ * Get the top 5 performing email domains for this campaign. Users wanting more than 5 should use campaign reports/member-activity()
269
+ or campaignEmailStatsAIMAll() and generate any additional stats they require.
270
+ * @param string $cid
271
+ * @return array domains structs for each email domains and their associated stats
272
+ * - domain string Domain name or special "Other" to roll-up stats past 5 domains
273
+ * - total_sent int Total Email across all domains - this will be the same in every row
274
+ * - emails int Number of emails sent to this domain
275
+ * - bounces int Number of bounces
276
+ * - opens int Number of opens
277
+ * - clicks int Number of clicks
278
+ * - unsubs int Number of unsubs
279
+ * - delivered int Number of deliveries
280
+ * - emails_pct int Percentage of emails that went to this domain (whole number)
281
+ * - bounces_pct int Percentage of bounces from this domain (whole number)
282
+ * - opens_pct int Percentage of opens from this domain (whole number)
283
+ * - clicks_pct int Percentage of clicks from this domain (whole number)
284
+ * - unsubs_pct int Percentage of unsubs from this domain (whole number)
285
+ */
286
+ public function domainPerformance($cid) {
287
+ $_params = array("cid" => $cid);
288
+ return $this->master->call('reports/domain-performance', $_params);
289
+ }
290
+
291
+ /**
292
+ * Retrieve the countries/regions and number of opens tracked for each. Email address are not returned.
293
+ * @param string $cid
294
+ * @return array an array of country structs where opens occurred
295
+ * - code string The ISO3166 2 digit country code
296
+ * - name string A version of the country name, if we have it
297
+ * - opens int The total number of opens that occurred in the country
298
+ * - regions array structs of data for each sub-region in the country
299
+ * - code string An internal code for the region. When this is blank, it indicates we know the country, but not the region
300
+ * - name string The name of the region, if we have one. For blank "code" values, this will be "Rest of Country"
301
+ * - opens int The total number of opens that occurred in the country
302
+ */
303
+ public function geoOpens($cid) {
304
+ $_params = array("cid" => $cid);
305
+ return $this->master->call('reports/geo-opens', $_params);
306
+ }
307
+
308
+ /**
309
+ * Retrieve the Google Analytics data we've collected for this campaign. Note, requires Google Analytics Add-on to be installed and configured.
310
+ * @param string $cid
311
+ * @return array of structs for analytics we've collected for the passed campaign.
312
+ * - visits int number of visits
313
+ * - pages int number of page views
314
+ * - new_visits int new visits recorded
315
+ * - bounces int vistors who "bounced" from your site
316
+ * - time_on_site double the total time visitors spent on your sites
317
+ * - goal_conversions int number of goals converted
318
+ * - goal_value double value of conversion in dollars
319
+ * - revenue double revenue generated by campaign
320
+ * - transactions int number of transactions tracked
321
+ * - ecomm_conversions int number Ecommerce transactions tracked
322
+ * - goals array structs containing goal names and number of conversions
323
+ * - name string the name of the goal
324
+ * - conversions int the number of conversions for the goal
325
+ */
326
+ public function googleAnalytics($cid) {
327
+ $_params = array("cid" => $cid);
328
+ return $this->master->call('reports/google-analytics', $_params);
329
+ }
330
+
331
+ /**
332
+ * Get email addresses the campaign was sent to
333
+ * @param string $cid
334
+ * @param associative_array $opts
335
+ * - status string optional the status to pull - one of 'sent', 'hard' (bounce), or 'soft' (bounce). By default, all records are returned
336
+ * - start int optional for large data sets, the page number to start at - defaults to 1st page of data (page 0)
337
+ * - limit int optional for large data sets, the number of results to return - defaults to 25, upper limit set at 100
338
+ * @return associative_array a total of all matching emails and the specific emails for this page
339
+ * - total int the total number of members for the campaign and status
340
+ * - data array structs for each campaign member matching
341
+ * - member associative_array the member record as returned by lists/member-info()
342
+ * - status string the status of the send - one of 'sent', 'hard', 'soft'
343
+ * - absplit_group string if this was an absplit campaign, one of 'a','b', or 'winner'
344
+ * - tz_group string if this was an timewarp campaign the timezone GMT offset the member was included in
345
+ */
346
+ public function sentTo($cid, $opts=array()) {
347
+ $_params = array("cid" => $cid, "opts" => $opts);
348
+ return $this->master->call('reports/sent-to', $_params);
349
+ }
350
+
351
+ /**
352
+ * Get the URL to a customized <a href="http://eepurl.com/gKmL" target="_blank">VIP Report</a> for the specified campaign and optionally send an email to someone with links to it. Note subsequent calls will overwrite anything already set for the same campign (eg, the password)
353
+ * @param string $cid
354
+ * @param array $opts
355
+ * - to_email string optional - optional, comma delimited list of email addresses to share the report with - no value means an email will not be sent
356
+ * - theme_id int optional - either a global or a user-specific theme id. Currently this needs to be pulled out of either the Share Report or Cobranding web views by grabbing the "theme" attribute from the list presented.
357
+ * - css_url string optional - a link to an external CSS file to be included after our default CSS (http://vip-reports.net/css/vip.css) <strong>only if</strong> loaded via the "secure_url" - max 255 bytes
358
+ * @return associative_array details for the shared report, including:
359
+ * - title string The Title of the Campaign being shared
360
+ * - url string The URL to the shared report
361
+ * - secure_url string The URL to the shared report, including the password (good for loading in an IFRAME). For non-secure reports, this will not be returned
362
+ * - password string If secured, the password for the report, otherwise this field will not be returned
363
+ */
364
+ public function share($cid, $opts=array()) {
365
+ $_params = array("cid" => $cid, "opts" => $opts);
366
+ return $this->master->call('reports/share', $_params);
367
+ }
368
+
369
+ /**
370
+ * Retrieve relevant aggregate campaign statistics (opens, bounces, clicks, etc.)
371
+ * @param string $cid
372
+ * @return associative_array the statistics for this campaign
373
+ * - syntax_errors int Number of email addresses in campaign that had syntactical errors.
374
+ * - hard_bounces int Number of email addresses in campaign that hard bounced.
375
+ * - soft_bounces int Number of email addresses in campaign that soft bounced.
376
+ * - unsubscribes int Number of email addresses in campaign that unsubscribed.
377
+ * - abuse_reports int Number of email addresses in campaign that reported campaign for abuse.
378
+ * - forwards int Number of times email was forwarded to a friend.
379
+ * - forwards_opens int Number of times a forwarded email was opened.
380
+ * - opens int Number of times the campaign was opened.
381
+ * - last_open string Date of the last time the email was opened.
382
+ * - unique_opens int Number of people who opened the campaign.
383
+ * - clicks int Number of times a link in the campaign was clicked.
384
+ * - unique_clicks int Number of unique recipient/click pairs for the campaign.
385
+ * - last_click string Date of the last time a link in the email was clicked.
386
+ * - users_who_clicked int Number of unique recipients who clicked on a link in the campaign.
387
+ * - emails_sent int Number of email addresses campaign was sent to.
388
+ * - unique_likes int total number of unique likes (Facebook)
389
+ * - recipient_likes int total number of recipients who liked (Facebook) the campaign
390
+ * - facebook_likes int total number of likes (Facebook) that came from Facebook
391
+ * - industry associative_array Various rates/percentages for the account's selected industry - empty otherwise. These will vary across calls, do not use them for anything important.
392
+ * - type string the selected industry
393
+ * - open_rate float industry open rate
394
+ * - click_rate float industry click rate
395
+ * - bounce_rate float industry bounce rate
396
+ * - unopen_rate float industry unopen rate
397
+ * - unsub_rate float industry unsub rate
398
+ * - abuse_rate float industry abuse rate
399
+ * - absplit associative_array If this was an absplit campaign, stats for the A and B groups will be returned - otherwise this is empty
400
+ * - bounces_a int bounces for the A group
401
+ * - bounces_b int bounces for the B group
402
+ * - forwards_a int forwards for the A group
403
+ * - forwards_b int forwards for the B group
404
+ * - abuse_reports_a int abuse reports for the A group
405
+ * - abuse_reports_b int abuse reports for the B group
406
+ * - unsubs_a int unsubs for the A group
407
+ * - unsubs_b int unsubs for the B group
408
+ * - recipients_click_a int clicks for the A group
409
+ * - recipients_click_b int clicks for the B group
410
+ * - forwards_opens_a int opened forwards for the A group
411
+ * - forwards_opens_b int opened forwards for the B group
412
+ * - opens_a int total opens for the A group
413
+ * - opens_b int total opens for the B group
414
+ * - last_open_a string date/time of last open for the A group
415
+ * - last_open_b string date/time of last open for the BG group
416
+ * - unique_opens_a int unique opens for the A group
417
+ * - unique_opens_b int unique opens for the B group
418
+ * - timewarp array If this campaign was a Timewarp campaign, an array of structs from each timezone stats exist for. Each will contain:
419
+ * - opens int opens for this timezone
420
+ * - last_open string the date/time of the last open for this timezone
421
+ * - unique_opens int the unique opens for this timezone
422
+ * - clicks int the total clicks for this timezone
423
+ * - last_click string the date/time of the last click for this timezone
424
+ * - unique_opens int the unique clicks for this timezone
425
+ * - bounces int the total bounces for this timezone
426
+ * - total int the total number of members sent to in this timezone
427
+ * - sent int the total number of members delivered to in this timezone
428
+ * - timeseries array structs for the first 24 hours of the campaign, per-hour stats:
429
+ * - timestamp string The timestemp in Y-m-d H:00:00 format
430
+ * - emails_sent int the total emails sent during the hour
431
+ * - unique_opens int unique opens seen during the hour
432
+ * - recipients_click int unique clicks seen during the hour
433
+ */
434
+ public function summary($cid) {
435
+ $_params = array("cid" => $cid);
436
+ return $this->master->call('reports/summary', $_params);
437
+ }
438
+
439
+ /**
440
+ * Get all unsubscribed email addresses for a given campaign
441
+ * @param string $cid
442
+ * @param associative_array $opts
443
+ * - start int optional for large data sets, the page number to start at - defaults to 1st page of data (page 0)
444
+ * - limit int optional for large data sets, the number of results to return - defaults to 25, upper limit set at 100
445
+ * @return associative_array a total of all unsubscribed emails and the specific members for this page
446
+ * - total int the total number of unsubscribes for the campaign
447
+ * - data array structs for the email addresses that unsubscribed
448
+ * - member string the member that unsubscribed as returned by lists/member-info()
449
+ * - reason string the reason collected for the unsubscribe. If populated, one of 'NORMAL','NOSIGNUP','INAPPROPRIATE','SPAM','OTHER'
450
+ * - reason_text string if the reason is OTHER, the text entered.
451
+ */
452
+ public function unsubscribes($cid, $opts=array()) {
453
+ $_params = array("cid" => $cid, "opts" => $opts);
454
+ return $this->master->call('reports/unsubscribes', $_params);
455
+ }
456
+
457
+ }
458
+
459
+
includes/vendor/mailchimp/Mailchimp/Templates.php ADDED
@@ -0,0 +1,114 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Mailchimp_Templates {
4
+ public function __construct(Mailchimp $master) {
5
+ $this->master = $master;
6
+ }
7
+
8
+ /**
9
+ * Create a new user template, <strong>NOT</strong> campaign content. These templates can then be applied while creating campaigns.
10
+ * @param string $name
11
+ * @param string $html
12
+ * @param int $folder_id
13
+ * @return associative_array with a single element:
14
+ * - template_id int the new template id, otherwise an error is thrown.
15
+ */
16
+ public function add($name, $html, $folder_id=null) {
17
+ $_params = array("name" => $name, "html" => $html, "folder_id" => $folder_id);
18
+ return $this->master->call('templates/add', $_params);
19
+ }
20
+
21
+ /**
22
+ * Delete (deactivate) a user template
23
+ * @param int $template_id
24
+ * @return associative_array with a single entry:
25
+ * - complete bool whether the call worked. reallistically this will always be true as errors will be thrown otherwise.
26
+ */
27
+ public function del($template_id) {
28
+ $_params = array("template_id" => $template_id);
29
+ return $this->master->call('templates/del', $_params);
30
+ }
31
+
32
+ /**
33
+ * Pull details for a specific template to help support editing
34
+ * @param int $template_id
35
+ * @param string $type
36
+ * @return associative_array info to be used when editing
37
+ * - default_content associative_array the default content broken down into the named editable sections for the template - dependant upon template, so not documented
38
+ * - sections associative_array the valid editable section names - dependant upon template, so not documented
39
+ * - source string the full source of the template as if you exported it via our template editor
40
+ * - preview string similar to the source, but the rendered version of the source from our popup preview
41
+ */
42
+ public function info($template_id, $type='user') {
43
+ $_params = array("template_id" => $template_id, "type" => $type);
44
+ return $this->master->call('templates/info', $_params);
45
+ }
46
+
47
+ /**
48
+ * Retrieve various templates available in the system, allowing some thing similar to our template gallery to be created.
49
+ * @param associative_array $types
50
+ * - user boolean Custom templates for this user account. Defaults to true.
51
+ * - gallery boolean Templates from our Gallery. Note that some templates that require extra configuration are withheld. (eg, the Etsy template). Defaults to false.
52
+ * - base boolean Our "start from scratch" extremely basic templates. Defaults to false. As of the 9.0 update, "base" templates are no longer available via the API because they are now all saved Drag & Drop templates.
53
+ * @param associative_array $filters
54
+ * - category string optional for Gallery templates only, limit to a specific template category
55
+ * - folder_id string user templates, limit to this folder_id
56
+ * - include_inactive boolean user templates are not deleted, only set inactive. defaults to false.
57
+ * - inactive_only boolean only include inactive user templates. defaults to false.
58
+ * - include_drag_and_drop boolean Include templates created and saved using the new Drag & Drop editor. <strong>Note:</strong> You will not be able to edit or create new drag & drop templates via this API. This is useful only for creating a new campaign based on a drag & drop template.
59
+ * @return associative_array for each type
60
+ * - user array matching user templates, if requested.
61
+ * - id int Id of the template
62
+ * - name string Name of the template
63
+ * - layout string General description of the layout of the template
64
+ * - category string The category for the template, if there is one.
65
+ * - preview_image string If we've generated it, the url of the preview image for the template. We do out best to keep these up to date, but Preview image urls are not guaranteed to be available
66
+ * - date_created string The date/time the template was created
67
+ * - active boolean whether or not the template is active and available for use.
68
+ * - edit_source boolean Whether or not you are able to edit the source of a template.
69
+ * - folder_id boolean if it's in one, the folder id
70
+ * - gallery array matching gallery templates, if requested.
71
+ * - id int Id of the template
72
+ * - name string Name of the template
73
+ * - layout string General description of the layout of the template
74
+ * - category string The category for the template, if there is one.
75
+ * - preview_image string If we've generated it, the url of the preview image for the template. We do out best to keep these up to date, but Preview image urls are not guaranteed to be available
76
+ * - date_created string The date/time the template was created
77
+ * - active boolean whether or not the template is active and available for use.
78
+ * - edit_source boolean Whether or not you are able to edit the source of a template.
79
+ * - base array matching base templates, if requested. (Will always be empty as of 9.0)
80
+ */
81
+ public function getList($types=array(), $filters=array()) {
82
+ $_params = array("types" => $types, "filters" => $filters);
83
+ return $this->master->call('templates/list', $_params);
84
+ }
85
+
86
+ /**
87
+ * Undelete (reactivate) a user template
88
+ * @param int $template_id
89
+ * @return associative_array with a single entry:
90
+ * - complete bool whether the call worked. reallistically this will always be true as errors will be thrown otherwise.
91
+ */
92
+ public function undel($template_id) {
93
+ $_params = array("template_id" => $template_id);
94
+ return $this->master->call('templates/undel', $_params);
95
+ }
96
+
97
+ /**
98
+ * Replace the content of a user template, <strong>NOT</strong> campaign content.
99
+ * @param int $template_id
100
+ * @param associative_array $values
101
+ * - name string the name for the template - names must be unique and a max of 50 bytes
102
+ * - html string a string specifying the entire template to be created. This is <strong>NOT</strong> campaign content. They are intended to utilize our <a href="http://www.mailchimp.com/resources/email-template-language/" target="_blank">template language</a>.
103
+ * - folder_id int the folder to put this template in - 0 or a blank values will remove it from a folder.
104
+ * @return associative_array with a single entry:
105
+ * - complete bool whether the call worked. reallistically this will always be true as errors will be thrown otherwise.
106
+ */
107
+ public function update($template_id, $values) {
108
+ $_params = array("template_id" => $template_id, "values" => $values);
109
+ return $this->master->call('templates/update', $_params);
110
+ }
111
+
112
+ }
113
+
114
+
includes/vendor/mailchimp/Mailchimp/Users.php ADDED
@@ -0,0 +1,105 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Mailchimp_Users {
4
+ public function __construct(Mailchimp $master) {
5
+ $this->master = $master;
6
+ }
7
+
8
+ /**
9
+ * Invite a user to your account
10
+ * @param string $email
11
+ * @param string $role
12
+ * @param string $msg
13
+ * @return associative_array the method completion status
14
+ * - status string The status (success) of the call if it completed. Otherwise an error is thrown.
15
+ */
16
+ public function invite($email, $role='viewer', $msg='') {
17
+ $_params = array("email" => $email, "role" => $role, "msg" => $msg);
18
+ return $this->master->call('users/invite', $_params);
19
+ }
20
+
21
+ /**
22
+ * Resend an invite a user to your account. Note, if the same address has been invited multiple times, this will simpy re-send the most recent invite
23
+ * @param string $email
24
+ * @return associative_array the method completion status
25
+ * - status string The status (success) of the call if it completed. Otherwise an error is thrown.
26
+ */
27
+ public function inviteResend($email) {
28
+ $_params = array("email" => $email);
29
+ return $this->master->call('users/invite-resend', $_params);
30
+ }
31
+
32
+ /**
33
+ * Revoke an invitation sent to a user to your account. Note, if the same address has been invited multiple times, this will simpy revoke the most recent invite
34
+ * @param string $email
35
+ * @return associative_array the method completion status
36
+ * - status string The status (success) of the call if it completed. Otherwise an error is thrown.
37
+ */
38
+ public function inviteRevoke($email) {
39
+ $_params = array("email" => $email);
40
+ return $this->master->call('users/invite-revoke', $_params);
41
+ }
42
+
43
+ /**
44
+ * Retrieve the list of pending users invitations have been sent for.
45
+ * @return array structs for each invitation, including:
46
+ * - email string the email address the invitation was sent to
47
+ * - role string the role that will be assigned if they accept
48
+ * - sent_at string the time the invitation was sent. this will change if it's resent.
49
+ * - expiration string the expiration time for the invitation. this will change if it's resent.
50
+ * - msg string the welcome message included with the invitation
51
+ */
52
+ public function invites() {
53
+ $_params = array();
54
+ return $this->master->call('users/invites', $_params);
55
+ }
56
+
57
+ /**
58
+ * Revoke access for a specified login
59
+ * @param string $username
60
+ * @return associative_array the method completion status
61
+ * - status string The status (success) of the call if it completed. Otherwise an error is thrown.
62
+ */
63
+ public function loginRevoke($username) {
64
+ $_params = array("username" => $username);
65
+ return $this->master->call('users/login-revoke', $_params);
66
+ }
67
+
68
+ /**
69
+ * Retrieve the list of active logins.
70
+ * @return array structs for each user, including:
71
+ * - id int the login id for this login
72
+ * - username string the username used to log in
73
+ * - name string a display name for the account - empty first/last names will return the username
74
+ * - email string the email tied to the account used for passwords resets and the ilk
75
+ * - role string the role assigned to the account
76
+ * - avatar string if available, the url for the login's avatar
77
+ * - global_user_id int the globally unique user id for the user account connected to
78
+ * - dc_unique_id string the datacenter unique id for the user account connected to, like helper/account-details
79
+ */
80
+ public function logins() {
81
+ $_params = array();
82
+ return $this->master->call('users/logins', $_params);
83
+ }
84
+
85
+ /**
86
+ * Retrieve the profile for the login owning the provided API Key
87
+ * @return associative_array the current user's details, including:
88
+ * - id int the login id for this login
89
+ * - username string the username used to log in
90
+ * - name string a display name for the account - empty first/last names will return the username
91
+ * - email string the email tied to the account used for passwords resets and the ilk
92
+ * - role string the role assigned to the account
93
+ * - avatar string if available, the url for the login's avatar
94
+ * - global_user_id int the globally unique user id for the user account connected to
95
+ * - dc_unique_id string the datacenter unique id for the user account connected to, like helper/account-details
96
+ * - account_name string The name of the account to which the API key belongs
97
+ */
98
+ public function profile() {
99
+ $_params = array();
100
+ return $this->master->call('users/profile', $_params);
101
+ }
102
+
103
+ }
104
+
105
+
includes/vendor/mailchimp/Mailchimp/Vip.php ADDED
@@ -0,0 +1,111 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Mailchimp_Vip {
4
+ public function __construct(Mailchimp $master) {
5
+ $this->master = $master;
6
+ }
7
+
8
+ /**
9
+ * Retrieve all Activity (opens/clicks) for VIPs over the past 10 days
10
+ * @return array structs for each activity recorded.
11
+ * - action string The action taken - either "open" or "click"
12
+ * - timestamp string The datetime the action occurred in GMT
13
+ * - url string IF the action is a click, the url that was clicked
14
+ * - unique_id string The campaign_id of the List the Member appears on
15
+ * - title string The campaign title
16
+ * - list_name string The name of the List the Member appears on
17
+ * - list_id string The id of the List the Member appears on
18
+ * - email string The email address of the member
19
+ * - fname string IF a FNAME merge field exists on the list, that value for the member
20
+ * - lname string IF a LNAME merge field exists on the list, that value for the member
21
+ * - member_rating int the rating of the subscriber. This will be 1 - 5 as described <a href="http://eepurl.com/f-2P" target="_blank">here</a>
22
+ * - member_since string the datetime the member was added and/or confirmed
23
+ * - geo associative_array the geographic information if we have it. including:
24
+ * - latitude string the latitude
25
+ * - longitude string the longitude
26
+ * - gmtoff string GMT offset
27
+ * - dstoff string GMT offset during daylight savings (if DST not observered, will be same as gmtoff
28
+ * - timezone string the timezone we've place them in
29
+ * - cc string 2 digit ISO-3166 country code
30
+ * - region string generally state, province, or similar
31
+ */
32
+ public function activity() {
33
+ $_params = array();
34
+ return $this->master->call('vip/activity', $_params);
35
+ }
36
+
37
+ /**
38
+ * Add VIPs (previously called Golden Monkeys)
39
+ * @param string $id
40
+ * @param array $emails
41
+ * - email string an email address - for new subscribers obviously this should be used
42
+ * - euid string the unique id for an email address (not list related) - the email "id" returned from listMemberInfo, Webhooks, Campaigns, etc.
43
+ * - leid string the list email id (previously called web_id) for a list-member-info type call. this doesn't change when the email address changes
44
+ * @return associative_array of data and success/error counts
45
+ * - success_count int the number of successful adds
46
+ * - error_count int the number of unsuccessful adds
47
+ * - errors array array of error structs including:
48
+ * - email associative_array whatever was passed in the email parameter
49
+ * - email string the email address added
50
+ * - euid string the email unique id
51
+ * - leid string the list member's truly unique id
52
+ * - code string the error code
53
+ * - error string the error message
54
+ * - data array array of structs for each member added
55
+ * - email associative_array whatever was passed in the email parameter
56
+ * - email string the email address added
57
+ * - euid string the email unique id
58
+ * - leid string the list member's truly unique id
59
+ */
60
+ public function add($id, $emails) {
61
+ $_params = array("id" => $id, "emails" => $emails);
62
+ return $this->master->call('vip/add', $_params);
63
+ }
64
+
65
+ /**
66
+ * Remove VIPs - this does not affect list membership
67
+ * @param string $id
68
+ * @param array $emails
69
+ * - email string an email address - for new subscribers obviously this should be used
70
+ * - euid string the unique id for an email address (not list related) - the email "id" returned from listMemberInfo, Webhooks, Campaigns, etc.
71
+ * - leid string the list email id (previously called web_id) for a list-member-info type call. this doesn't change when the email address changes
72
+ * @return associative_array of data and success/error counts
73
+ * - success_count int the number of successful deletions
74
+ * - error_count int the number of unsuccessful deletions
75
+ * - errors array array of error structs including:
76
+ * - email associative_array whatever was passed in the email parameter
77
+ * - email string the email address
78
+ * - euid string the email unique id
79
+ * - leid string the list member's truly unique id
80
+ * - code string the error code
81
+ * - msg string the error message
82
+ * - data array array of structs for each member deleted
83
+ * - email associative_array whatever was passed in the email parameter
84
+ * - email string the email address
85
+ * - euid string the email unique id
86
+ * - leid string the list member's truly unique id
87
+ */
88
+ public function del($id, $emails) {
89
+ $_params = array("id" => $id, "emails" => $emails);
90
+ return $this->master->call('vip/del', $_params);
91
+ }
92
+
93
+ /**
94
+ * Retrieve all Golden Monkey(s) for an account
95
+ * @return array structs for each Golden Monkey, including:
96
+ * - list_id string The id of the List the Member appears on
97
+ * - list_name string The name of the List the Member appears on
98
+ * - email string The email address of the member
99
+ * - fname string IF a FNAME merge field exists on the list, that value for the member
100
+ * - lname string IF a LNAME merge field exists on the list, that value for the member
101
+ * - member_rating int the rating of the subscriber. This will be 1 - 5 as described <a href="http://eepurl.com/f-2P" target="_blank">here</a>
102
+ * - member_since string the datetime the member was added and/or confirmed
103
+ */
104
+ public function members() {
105
+ $_params = array();
106
+ return $this->master->call('vip/members', $_params);
107
+ }
108
+
109
+ }
110
+
111
+
includes/vendor/mailchimp/mailchimp.php ADDED
@@ -0,0 +1,261 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ require_once 'Mailchimp/Folders.php';
4
+ require_once 'Mailchimp/Templates.php';
5
+ require_once 'Mailchimp/Users.php';
6
+ require_once 'Mailchimp/Helper.php';
7
+ require_once 'Mailchimp/Mobile.php';
8
+ require_once 'Mailchimp/Conversations.php';
9
+ require_once 'Mailchimp/Ecomm.php';
10
+ require_once 'Mailchimp/Neapolitan.php';
11
+ require_once 'Mailchimp/Lists.php';
12
+ require_once 'Mailchimp/Campaigns.php';
13
+ require_once 'Mailchimp/Vip.php';
14
+ require_once 'Mailchimp/Reports.php';
15
+ require_once 'Mailchimp/Gallery.php';
16
+ require_once 'Mailchimp/Goal.php';
17
+ require_once 'Mailchimp/Exceptions.php';
18
+
19
+ class Mailchimp {
20
+
21
+ public $apikey;
22
+ public $ch;
23
+ public $root = 'https://api.mailchimp.com/2.0';
24
+ public $debug = false;
25
+
26
+ public static $error_map = array(
27
+ "ValidationError" => "Mailchimp_ValidationError",
28
+ "ServerError_MethodUnknown" => "Mailchimp_ServerError_MethodUnknown",
29
+ "ServerError_InvalidParameters" => "Mailchimp_ServerError_InvalidParameters",
30
+ "Unknown_Exception" => "Mailchimp_Unknown_Exception",
31
+ "Request_TimedOut" => "Mailchimp_Request_TimedOut",
32
+ "Zend_Uri_Exception" => "Mailchimp_Zend_Uri_Exception",
33
+ "PDOException" => "Mailchimp_PDOException",
34
+ "Avesta_Db_Exception" => "Mailchimp_Avesta_Db_Exception",
35
+ "XML_RPC2_Exception" => "Mailchimp_XML_RPC2_Exception",
36
+ "XML_RPC2_FaultException" => "Mailchimp_XML_RPC2_FaultException",
37
+ "Too_Many_Connections" => "Mailchimp_Too_Many_Connections",
38
+ "Parse_Exception" => "Mailchimp_Parse_Exception",
39
+ "User_Unknown" => "Mailchimp_User_Unknown",
40
+ "User_Disabled" => "Mailchimp_User_Disabled",
41
+ "User_DoesNotExist" => "Mailchimp_User_DoesNotExist",
42
+ "User_NotApproved" => "Mailchimp_User_NotApproved",
43
+ "Invalid_ApiKey" => "Mailchimp_Invalid_ApiKey",
44
+ "User_UnderMaintenance" => "Mailchimp_User_UnderMaintenance",
45
+ "Invalid_AppKey" => "Mailchimp_Invalid_AppKey",
46
+ "Invalid_IP" => "Mailchimp_Invalid_IP",
47
+ "User_DoesExist" => "Mailchimp_User_DoesExist",
48
+ "User_InvalidRole" => "Mailchimp_User_InvalidRole",
49
+ "User_InvalidAction" => "Mailchimp_User_InvalidAction",
50
+ "User_MissingEmail" => "Mailchimp_User_MissingEmail",
51
+ "User_CannotSendCampaign" => "Mailchimp_User_CannotSendCampaign",
52
+ "User_MissingModuleOutbox" => "Mailchimp_User_MissingModuleOutbox",
53
+ "User_ModuleAlreadyPurchased" => "Mailchimp_User_ModuleAlreadyPurchased",
54
+ "User_ModuleNotPurchased" => "Mailchimp_User_ModuleNotPurchased",
55
+ "User_NotEnoughCredit" => "Mailchimp_User_NotEnoughCredit",
56
+ "MC_InvalidPayment" => "Mailchimp_MC_InvalidPayment",
57
+ "List_DoesNotExist" => "Mailchimp_List_DoesNotExist",
58
+ "List_InvalidInterestFieldType" => "Mailchimp_List_InvalidInterestFieldType",
59
+ "List_InvalidOption" => "Mailchimp_List_InvalidOption",
60
+ "List_InvalidUnsubMember" => "Mailchimp_List_InvalidUnsubMember",
61
+ "List_InvalidBounceMember" => "Mailchimp_List_InvalidBounceMember",
62
+ "List_AlreadySubscribed" => "Mailchimp_List_AlreadySubscribed",
63
+ "List_NotSubscribed" => "Mailchimp_List_NotSubscribed",
64
+ "List_InvalidImport" => "Mailchimp_List_InvalidImport",
65
+ "MC_PastedList_Duplicate" => "Mailchimp_MC_PastedList_Duplicate",
66
+ "MC_PastedList_InvalidImport" => "Mailchimp_MC_PastedList_InvalidImport",
67
+ "Email_AlreadySubscribed" => "Mailchimp_Email_AlreadySubscribed",
68
+ "Email_AlreadyUnsubscribed" => "Mailchimp_Email_AlreadyUnsubscribed",
69
+ "Email_NotExists" => "Mailchimp_Email_NotExists",
70
+ "Email_NotSubscribed" => "Mailchimp_Email_NotSubscribed",
71
+ "List_MergeFieldRequired" => "Mailchimp_List_MergeFieldRequired",
72
+ "List_CannotRemoveEmailMerge" => "Mailchimp_List_CannotRemoveEmailMerge",
73
+ "List_Merge_InvalidMergeID" => "Mailchimp_List_Merge_InvalidMergeID",
74
+ "List_TooManyMergeFields" => "Mailchimp_List_TooManyMergeFields",
75
+ "List_InvalidMergeField" => "Mailchimp_List_InvalidMergeField",
76
+ "List_InvalidInterestGroup" => "Mailchimp_List_InvalidInterestGroup",
77
+ "List_TooManyInterestGroups" => "Mailchimp_List_TooManyInterestGroups",
78
+ "Campaign_DoesNotExist" => "Mailchimp_Campaign_DoesNotExist",
79
+ "Campaign_StatsNotAvailable" => "Mailchimp_Campaign_StatsNotAvailable",
80
+ "Campaign_InvalidAbsplit" => "Mailchimp_Campaign_InvalidAbsplit",
81
+ "Campaign_InvalidContent" => "Mailchimp_Campaign_InvalidContent",
82
+ "Campaign_InvalidOption" => "Mailchimp_Campaign_InvalidOption",
83
+ "Campaign_InvalidStatus" => "Mailchimp_Campaign_InvalidStatus",
84
+ "Campaign_NotSaved" => "Mailchimp_Campaign_NotSaved",
85
+ "Campaign_InvalidSegment" => "Mailchimp_Campaign_InvalidSegment",
86
+ "Campaign_InvalidRss" => "Mailchimp_Campaign_InvalidRss",
87
+ "Campaign_InvalidAuto" => "Mailchimp_Campaign_InvalidAuto",
88
+ "MC_ContentImport_InvalidArchive" => "Mailchimp_MC_ContentImport_InvalidArchive",
89
+ "Campaign_BounceMissing" => "Mailchimp_Campaign_BounceMissing",
90
+ "Campaign_InvalidTemplate" => "Mailchimp_Campaign_InvalidTemplate",
91
+ "Invalid_EcommOrder" => "Mailchimp_Invalid_EcommOrder",
92
+ "Absplit_UnknownError" => "Mailchimp_Absplit_UnknownError",
93
+ "Absplit_UnknownSplitTest" => "Mailchimp_Absplit_UnknownSplitTest",
94
+ "Absplit_UnknownTestType" => "Mailchimp_Absplit_UnknownTestType",
95
+ "Absplit_UnknownWaitUnit" => "Mailchimp_Absplit_UnknownWaitUnit",
96
+ "Absplit_UnknownWinnerType" => "Mailchimp_Absplit_UnknownWinnerType",
97
+ "Absplit_WinnerNotSelected" => "Mailchimp_Absplit_WinnerNotSelected",
98
+ "Invalid_Analytics" => "Mailchimp_Invalid_Analytics",
99
+ "Invalid_DateTime" => "Mailchimp_Invalid_DateTime",
100
+ "Invalid_Email" => "Mailchimp_Invalid_Email",
101
+ "Invalid_SendType" => "Mailchimp_Invalid_SendType",
102
+ "Invalid_Template" => "Mailchimp_Invalid_Template",
103
+ "Invalid_TrackingOptions" => "Mailchimp_Invalid_TrackingOptions",
104
+ "Invalid_Options" => "Mailchimp_Invalid_Options",
105
+ "Invalid_Folder" => "Mailchimp_Invalid_Folder",
106
+ "Invalid_URL" => "Mailchimp_Invalid_URL",
107
+ "Module_Unknown" => "Mailchimp_Module_Unknown",
108
+ "MonthlyPlan_Unknown" => "Mailchimp_MonthlyPlan_Unknown",
109
+ "Order_TypeUnknown" => "Mailchimp_Order_TypeUnknown",
110
+ "Invalid_PagingLimit" => "Mailchimp_Invalid_PagingLimit",
111
+ "Invalid_PagingStart" => "Mailchimp_Invalid_PagingStart",
112
+ "Max_Size_Reached" => "Mailchimp_Max_Size_Reached",
113
+ "MC_SearchException" => "Mailchimp_MC_SearchException",
114
+ "Goal_SaveFailed" => "Mailchimp_Goal_SaveFailed",
115
+ "Conversation_DoesNotExist" => "Mailchimp_Conversation_DoesNotExist",
116
+ "Conversation_ReplySaveFailed" => "Mailchimp_Conversation_ReplySaveFailed",
117
+ "File_Not_Found_Exception" => "Mailchimp_File_Not_Found_Exception",
118
+ "Folder_Not_Found_Exception" => "Mailchimp_Folder_Not_Found_Exception",
119
+ "Folder_Exists_Exception" => "Mailchimp_Folder_Exists_Exception"
120
+ );
121
+
122
+ public function __construct($apikey=null, $opts=array()) {
123
+ if (!$apikey) {
124
+ $apikey = getenv('MAILCHIMP_APIKEY');
125
+ }
126
+
127
+ if (!$apikey) {
128
+ $apikey = $this->readConfigs();
129
+ }
130
+
131
+ if (!$apikey) {
132
+ throw new Mailchimp_Error('You must provide a MailChimp API key');
133
+ }
134
+
135
+ $this->apikey = $apikey;
136
+ $dc = "us1";
137
+
138
+ if (strstr($this->apikey, "-")){
139
+ list($key, $dc) = explode("-", $this->apikey, 2);
140
+ if (!$dc) {
141
+ $dc = "us1";
142
+ }
143
+ }
144
+
145
+ $this->root = str_replace('https://api', 'https://' . $dc . '.api', $this->root);
146
+ $this->root = rtrim($this->root, '/') . '/';
147
+
148
+ if (!isset($opts['timeout']) || !is_int($opts['timeout'])){
149
+ $opts['timeout'] = 600;
150
+ }
151
+ if (isset($opts['debug'])){
152
+ $this->debug = true;
153
+ }
154
+
155
+
156
+ $this->ch = curl_init();
157
+
158
+ if (isset($opts['CURLOPT_FOLLOWLOCATION']) && $opts['CURLOPT_FOLLOWLOCATION'] === true) {
159
+ curl_setopt($this->ch, CURLOPT_FOLLOWLOCATION, true);
160
+ }
161
+
162
+ curl_setopt($this->ch, CURLOPT_USERAGENT, 'MailChimp-PHP/2.0.5');
163
+ curl_setopt($this->ch, CURLOPT_POST, true);
164
+ curl_setopt($this->ch, CURLOPT_HEADER, false);
165
+ curl_setopt($this->ch, CURLOPT_RETURNTRANSFER, true);
166
+ curl_setopt($this->ch, CURLOPT_CONNECTTIMEOUT, 30);
167
+ curl_setopt($this->ch, CURLOPT_TIMEOUT, $opts['timeout']);
168
+
169
+
170
+ $this->folders = new Mailchimp_Folders($this);
171
+ $this->templates = new Mailchimp_Templates($this);
172
+ $this->users = new Mailchimp_Users($this);
173
+ $this->helper = new Mailchimp_Helper($this);
174
+ $this->mobile = new Mailchimp_Mobile($this);
175
+ $this->conversations = new Mailchimp_Conversations($this);
176
+ $this->ecomm = new Mailchimp_Ecomm($this);
177
+ $this->neapolitan = new Mailchimp_Neapolitan($this);
178
+ $this->lists = new Mailchimp_Lists($this);
179
+ $this->campaigns = new Mailchimp_Campaigns($this);
180
+ $this->vip = new Mailchimp_Vip($this);
181
+ $this->reports = new Mailchimp_Reports($this);
182
+ $this->gallery = new Mailchimp_Gallery($this);
183
+ $this->goal = new Mailchimp_Goal($this);
184
+ }
185
+
186
+ public function __destruct() {
187
+ curl_close($this->ch);
188
+ }
189
+
190
+ public function call($url, $params) {
191
+ $params['apikey'] = $this->apikey;
192
+
193
+ $params = json_encode($params);
194
+ $ch = $this->ch;
195
+
196
+ curl_setopt($ch, CURLOPT_URL, $this->root . $url . '.json');
197
+ curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json'));
198
+ curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
199
+ curl_setopt($ch, CURLOPT_VERBOSE, $this->debug);
200
+
201
+ $start = microtime(true);
202
+ $this->log('Call to ' . $this->root . $url . '.json: ' . $params);
203
+ if($this->debug) {
204
+ $curl_buffer = fopen('php://memory', 'w+');
205
+ curl_setopt($ch, CURLOPT_STDERR, $curl_buffer);
206
+ }
207
+
208
+ $response_body = curl_exec($ch);
209
+
210
+ $info = curl_getinfo($ch);
211
+ $time = microtime(true) - $start;
212
+ if($this->debug) {
213
+ rewind($curl_buffer);
214
+ $this->log(stream_get_contents($curl_buffer));
215
+ fclose($curl_buffer);
216
+ }
217
+ $this->log('Completed in ' . number_format($time * 1000, 2) . 'ms');
218
+ $this->log('Got response: ' . $response_body);
219
+
220
+ if(curl_error($ch)) {
221
+ throw new Mailchimp_HttpError("API call to $url failed: " . curl_error($ch));
222
+ }
223
+ $result = json_decode($response_body, true);
224
+
225
+ if(floor($info['http_code'] / 100) >= 4) {
226
+ throw $this->castError($result);
227
+ }
228
+
229
+ return $result;
230
+ }
231
+
232
+ public function readConfigs() {
233
+ $paths = array('~/.mailchimp.key', '/etc/mailchimp.key');
234
+ foreach($paths as $path) {
235
+ if(file_exists($path)) {
236
+ $apikey = trim(file_get_contents($path));
237
+ if ($apikey) {
238
+ return $apikey;
239
+ }
240
+ }
241
+ }
242
+ return false;
243
+ }
244
+
245
+ public function castError($result) {
246
+ if ($result['status'] !== 'error' || !$result['name']) {
247
+ throw new Mailchimp_Error('We received an unexpected error: ' . json_encode($result));
248
+ }
249
+
250
+ $class = (isset(self::$error_map[$result['name']])) ? self::$error_map[$result['name']] : 'Mailchimp_Error';
251
+ return new $class($result['error'], $result['code']);
252
+ }
253
+
254
+ public function log($msg) {
255
+ if ($this->debug) {
256
+ error_log($msg);
257
+ }
258
+ }
259
+ }
260
+
261
+
js/fl-builder-layout.js CHANGED
@@ -8,39 +8,23 @@
8
 
9
  init: function()
10
  {
11
- var win = $(window);
12
-
13
  // Destroy existing layout events.
14
  FLBuilderLayout._destroy();
15
 
16
- // Add the builder body class.
17
- $('body').addClass('fl-builder');
18
 
19
- // Add the builder touch body class.
20
- if(FLBuilderLayout._isTouch()) {
21
- $('body').addClass('fl-builder-touch');
22
- }
23
 
24
- // Init parallax backgrounds.
25
- if($('.fl-row-bg-parallax').length > 0 && !FLBuilderLayout._isTouch()) {
26
- FLBuilderLayout._scrollParallaxBackgrounds();
27
- FLBuilderLayout._initParallaxBackgrounds();
28
- win.on('scroll.fl-bg-parallax', FLBuilderLayout._scrollParallaxBackgrounds);
29
- }
30
-
31
- // Init video backgrounds.
32
- if($('.fl-bg-video').length > 0) {
33
- FLBuilderLayout._resizeBgVideos();
34
- win.on('resize.fl-bg-video', FLBuilderLayout._resizeBgVideos);
35
- }
36
 
37
  // Init module animations.
38
- if($('.fl-builder-edit').length === 0 && typeof jQuery.fn.waypoint !== 'undefined' && !FLBuilderLayout._isTouch()) {
39
- FLBuilderLayout._initModuleAnimations();
40
- }
41
 
42
- // Init anchor links.
43
- FLBuilderLayout._initAnchorLinks();
44
  },
45
 
46
  _destroy: function()
@@ -60,6 +44,35 @@
60
  return false;
61
  },
62
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
63
  _initParallaxBackgrounds: function()
64
  {
65
  $('.fl-row-bg-parallax').each(FLBuilderLayout._initParallaxBackground);
@@ -151,10 +164,12 @@
151
 
152
  _initModuleAnimations: function()
153
  {
154
- $('.fl-animation').waypoint({
155
- offset: '80%',
156
- handler: FLBuilderLayout._doModuleAnimation
157
- });
 
 
158
  },
159
 
160
  _doModuleAnimation: function()
@@ -224,6 +239,65 @@
224
  }
225
 
226
  e.preventDefault();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
227
  }
228
  };
229
 
8
 
9
  init: function()
10
  {
 
 
11
  // Destroy existing layout events.
12
  FLBuilderLayout._destroy();
13
 
14
+ // Init CSS classes.
15
+ FLBuilderLayout._initClasses();
16
 
17
+ // Init anchor links.
18
+ FLBuilderLayout._initAnchorLinks();
 
 
19
 
20
+ // Init backgrounds.
21
+ FLBuilderLayout._initBackgrounds();
 
 
 
 
 
 
 
 
 
 
22
 
23
  // Init module animations.
24
+ FLBuilderLayout._initModuleAnimations();
 
 
25
 
26
+ // Init forms.
27
+ FLBuilderLayout._initForms();
28
  },
29
 
30
  _destroy: function()
44
  return false;
45
  },
46
 
47
+ _initClasses: function()
48
+ {
49
+ // Add the builder body class.
50
+ $('body').addClass('fl-builder');
51
+
52
+ // Add the builder touch body class.
53
+ if(FLBuilderLayout._isTouch()) {
54
+ $('body').addClass('fl-builder-touch');
55
+ }
56
+ },
57
+
58
+ _initBackgrounds: function()
59
+ {
60
+ var win = $(window);
61
+
62
+ // Init parallax backgrounds.
63
+ if($('.fl-row-bg-parallax').length > 0 && !FLBuilderLayout._isTouch()) {
64
+ FLBuilderLayout._scrollParallaxBackgrounds();
65
+ FLBuilderLayout._initParallaxBackgrounds();
66
+ win.on('scroll.fl-bg-parallax', FLBuilderLayout._scrollParallaxBackgrounds);
67
+ }
68
+
69
+ // Init video backgrounds.
70
+ if($('.fl-bg-video').length > 0) {
71
+ FLBuilderLayout._resizeBgVideos();
72
+ win.on('resize.fl-bg-video', FLBuilderLayout._resizeBgVideos);
73
+ }
74
+ },
75
+
76
  _initParallaxBackgrounds: function()
77
  {
78
  $('.fl-row-bg-parallax').each(FLBuilderLayout._initParallaxBackground);
164
 
165
  _initModuleAnimations: function()
166
  {
167
+ if($('.fl-builder-edit').length === 0 && typeof jQuery.fn.waypoint !== 'undefined' && !FLBuilderLayout._isTouch()) {
168
+ $('.fl-animation').waypoint({
169
+ offset: '80%',
170
+ handler: FLBuilderLayout._doModuleAnimation
171
+ });
172
+ }
173
  },
174
 
175
  _doModuleAnimation: function()
239
  }
240
 
241
  e.preventDefault();
242
+ },
243
+
244
+ _initForms: function()
245
+ {
246
+ if ( ! FLBuilderLayout._hasPlaceholderSupport ) {
247
+ $( '.fl-form-field input' ).each( FLBuilderLayout._initFormFieldPlaceholderFallback );
248
+ }
249
+
250
+ $( '.fl-form-field input' ).on( 'focus', FLBuilderLayout._clearFormFieldError );
251
+ },
252
+
253
+ _hasPlaceholderSupport: function()
254
+ {
255
+ var input = document.createElement( 'input' );
256
+
257
+ return 'undefined' != input.placeholder;
258
+ },
259
+
260
+ _initFormFieldPlaceholderFallback: function()
261
+ {
262
+ var field = $( this ),
263
+ val = field.val(),
264
+ placeholder = field.attr( 'placeholder' );
265
+
266
+ if ( 'undefined' != placeholder && '' == val ) {
267
+ field.val( placeholder );
268
+ field.on( 'focus', FLBuilderLayout._hideFormFieldPlaceholderFallback );
269
+ field.on( 'blur', FLBuilderLayout._showFormFieldPlaceholderFallback );
270
+ }
271
+ },
272
+
273
+ _hideFormFieldPlaceholderFallback: function()
274
+ {
275
+ var field = $( this ),
276
+ val = field.val(),
277
+ placeholder = field.attr( 'placeholder' );
278
+
279
+ if ( val == placeholder ) {
280
+ field.val( '' );
281
+ }
282
+ },
283
+
284
+ _showFormFieldPlaceholderFallback: function()
285
+ {
286
+ var field = $( this ),
287
+ val = field.val(),
288
+ placeholder = field.attr( 'placeholder' );
289
+
290
+ if ( '' == val ) {
291
+ field.val( placeholder );
292
+ }
293
+ },
294
+
295
+ _clearFormFieldError: function()
296
+ {
297
+ var field = $( this );
298
+
299
+ field.removeClass( 'fl-form-error' );
300
+ field.siblings( '.fl-form-error-message' ).hide();
301
  }
302
  };
303
 
js/fl-builder-preview.js CHANGED
@@ -358,14 +358,28 @@ var FLBuilderPreview;
358
  */
359
  _textColorChange: function(e)
360
  {
361
- if(this.elements.textColor.val() == '') {
 
 
362
  this.updateCSSRule(this.classes.node, 'color', 'inherit');
363
- this.updateCSSRule(this.classes.node + ' *', 'color', 'inherit');
 
 
 
 
 
 
364
  }
365
  else {
366
  this.delay(100, $.proxy(function(){
367
- this.updateCSSRule(this.classes.node, 'color', '#' + this.elements.textColor.val());
368
- this.updateCSSRule(this.classes.node + ' *', 'color', '#' + this.elements.textColor.val());
 
 
 
 
 
 
369
  }, this));
370
  }
371
  },
358
  */
359
  _textColorChange: function(e)
360
  {
361
+ var val = this.elements.textColor.val();
362
+
363
+ if(val == '') {
364
  this.updateCSSRule(this.classes.node, 'color', 'inherit');
365
+ this.updateCSSRule(this.classes.node + ' a', 'color', 'inherit');
366
+ this.updateCSSRule(this.classes.node + ' h1', 'color', 'inherit');
367
+ this.updateCSSRule(this.classes.node + ' h2', 'color', 'inherit');
368
+ this.updateCSSRule(this.classes.node + ' h3', 'color', 'inherit');
369
+ this.updateCSSRule(this.classes.node + ' h4', 'color', 'inherit');
370
+ this.updateCSSRule(this.classes.node + ' h5', 'color', 'inherit');
371
+ this.updateCSSRule(this.classes.node + ' h6', 'color', 'inherit');
372
  }
373
  else {
374
  this.delay(100, $.proxy(function(){
375
+ this.updateCSSRule(this.classes.node, 'color', '#' + val);
376
+ this.updateCSSRule(this.classes.node + ' a', 'color', '#' + val);
377
+ this.updateCSSRule(this.classes.node + ' h1', 'color', '#' + val);
378
+ this.updateCSSRule(this.classes.node + ' h2', 'color', '#' + val);
379
+ this.updateCSSRule(this.classes.node + ' h3', 'color', '#' + val);
380
+ this.updateCSSRule(this.classes.node + ' h4', 'color', '#' + val);
381
+ this.updateCSSRule(this.classes.node + ' h5', 'color', '#' + val);
382
+ this.updateCSSRule(this.classes.node + ' h6', 'color', '#' + val);
383
  }, this));
384
  }
385
  },
js/fl-builder-services.js ADDED
@@ -0,0 +1,368 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ (function( $ ) {
2
+
3
+ /**
4
+ * JavaScript class for working with third party services.
5
+ *
6
+ * @since 1.5.4
7
+ */
8
+ var FLBuilderServices = {
9
+
10
+ /**
11
+ * Initializes the services logic.
12
+ *
13
+ * @return void
14
+ * @since 1.5.4
15
+ */
16
+ init: function()
17
+ {
18
+ var body = $('body');
19
+
20
+ // Standard Events
21
+ body.delegate( '.fl-builder-service-select', 'change', this._serviceChange );
22
+ body.delegate( '.fl-builder-service-connect-button', 'click', this._connectClicked );
23
+ body.delegate( '.fl-builder-service-account-select', 'change', this._accountChange );
24
+ body.delegate( '.fl-builder-service-account-delete', 'click', this._accountDeleteClicked );
25
+
26
+ // Campaign Monitor Events
27
+ body.delegate( '.fl-builder-campaign-monitor-client-select', 'change', this._campaignMonitorClientChange );
28
+ },
29
+
30
+ /**
31
+ * Show the lightbox loading graphic and remove errors.
32
+ *
33
+ * @param {Object} ele An element within the lightbox.
34
+ * @return void
35
+ * @since 1.5.4
36
+ */
37
+ _startSettingsLoading: function( ele )
38
+ {
39
+ var lightbox = $( '.fl-builder-settings' ),
40
+ wrap = ele.closest( '.fl-builder-service-settings' ),
41
+ error = $( '.fl-builder-service-error' );
42
+
43
+ lightbox.append( '<div class="fl-builder-loading"></div>' );
44
+ wrap.addClass( 'fl-builder-service-settings-loading' );
45
+ error.remove();
46
+ },
47
+
48
+ /**
49
+ * Remove the lightbox loading graphic.
50
+ *
51
+ * @return void
52
+ * @since 1.5.4
53
+ */
54
+ _finishSettingsLoading: function()
55
+ {
56
+ var lightbox = $( '.fl-builder-settings' ),
57
+ wrap = $( '.fl-builder-service-settings-loading' );
58
+
59
+ lightbox.find( '.fl-builder-loading' ).remove();
60
+ wrap.removeClass( 'fl-builder-service-settings-loading' );
61
+ },
62
+
63
+ /**
64
+ * Fires when the service select changes.
65
+ *
66
+ * @return void
67
+ * @since 1.5.4
68
+ */
69
+ _serviceChange: function()
70
+ {
71
+ var nodeId = $( '.fl-builder-settings' ).data( 'node' ),
72
+ select = $( this ),
73
+ selectRow = select.closest( 'tr' ),
74
+ service = select.val();
75
+
76
+ selectRow.siblings( 'tr.fl-builder-service-account-row' ).remove();
77
+ selectRow.siblings( 'tr.fl-builder-service-connect-row' ).remove();
78
+ selectRow.siblings( 'tr.fl-builder-service-field-row' ).remove();
79
+ $( '.fl-builder-service-error' ).remove();
80
+
81
+ if ( '' == service ) {
82
+ return;
83
+ }
84
+
85
+ FLBuilderServices._startSettingsLoading( select );
86
+
87
+ FLBuilder.ajax( {
88
+ action : 'fl_builder_render_service_settings',
89
+ node_id : nodeId,
90
+ service : service
91
+ }, FLBuilderServices._serviceChangeComplete );
92
+ },
93
+
94
+ /**
95
+ * AJAX callback for when the service select changes.
96
+ *
97
+ * @param {String} response The JSON response.
98
+ * @return void
99
+ * @since 1.5.4
100
+ */
101
+ _serviceChangeComplete: function( response )
102
+ {
103
+ var data = JSON.parse( response ),
104
+ wrap = $( '.fl-builder-service-settings-loading' ),
105
+ selectRow = wrap.find( '.fl-builder-service-select-row' );
106
+
107
+ selectRow.after( data.html );
108
+ FLBuilderServices._addAccountDelete( wrap );
109
+ FLBuilderServices._finishSettingsLoading();
110
+ },
111
+
112
+ /**
113
+ * Fires when the service connect button is clicked.
114
+ *
115
+ * @return void
116
+ * @since 1.5.4
117
+ */
118
+ _connectClicked: function()
119
+ {
120
+ var nodeId = $( '.fl-builder-settings' ).data( 'node' ),
121
+ wrap = $( this ).closest( '.fl-builder-service-settings' ),
122
+ select = wrap.find( '.fl-builder-service-select' ),
123
+ connectRows = wrap.find( '.fl-builder-service-connect-row' ),
124
+ connectInputs = wrap.find( '.fl-builder-service-connect-input' ),
125
+ input = null,
126
+ name = null,
127
+ i = 0,
128
+ data = {
129
+ action : 'fl_builder_connect_service',
130
+ node_id : nodeId,
131
+ service : select.val(),
132
+ fields : {}
133
+ };
134
+
135
+ for ( ; i < connectInputs.length; i++ ) {
136
+ input = connectInputs.eq( i );
137
+ name = input.attr( 'name' );
138
+ data['fields'][ name ] = input.val();
139
+ }
140
+
141
+ connectRows.hide();
142
+ FLBuilderServices._startSettingsLoading( select );
143
+ FLBuilder.ajax( data, FLBuilderServices._connectComplete );
144
+ },
145
+
146
+ /**
147
+ * AJAX callback for when the service connect button is clicked.
148
+ *
149
+ * @param {String} response The JSON response.
150
+ * @return void
151
+ * @since 1.5.4
152
+ */
153
+ _connectComplete: function( response )
154
+ {
155
+ var data = JSON.parse( response ),
156
+ wrap = $( '.fl-builder-service-settings-loading' ),
157
+ selectRow = wrap.find( '.fl-builder-service-select-row' ),
158
+ select = wrap.find( '.fl-builder-service-select' ),
159
+ accountRow = wrap.find( '.fl-builder-service-account-row' ),
160
+ account = wrap.find( '.fl-builder-service-account-select' ),
161
+ connectRows = wrap.find( '.fl-builder-service-connect-row' );
162
+
163
+ if ( data.error ) {
164
+
165
+ connectRows.show();
166
+
167
+ if ( 0 === account.length ) {
168
+ select.after( '<div class="fl-builder-service-error">' + data.error + '</div>' );
169
+ }
170
+ else {
171
+ account.after( '<div class="fl-builder-service-error">' + data.error + '</div>' );
172
+ }
173
+ }
174
+ else {
175
+ connectRows.remove();
176
+ accountRow.remove();
177
+ selectRow.after( data.html );
178
+ }
179
+
180
+ FLBuilderServices._addAccountDelete( wrap );
181
+ FLBuilderServices._finishSettingsLoading();
182
+ },
183
+
184
+ /**
185
+ * Fires when the service account select changes.
186
+ *
187
+ * @return void
188
+ * @since 1.5.4
189
+ */
190
+ _accountChange: function()
191
+ {
192
+ var nodeId = $( '.fl-builder-settings' ).data( 'node' ),
193
+ wrap = $( this ).closest( '.fl-builder-service-settings' ),
194
+ select = wrap.find( '.fl-builder-service-select' ),
195
+ account = wrap.find( '.fl-builder-service-account-select' ),
196
+ connectRows = wrap.find( '.fl-builder-service-connect-row' ),
197
+ fieldRows = wrap.find( 'tr.fl-builder-service-field-row' ),
198
+ error = $( '.fl-builder-service-error' ),
199
+ value = account.val(),
200
+ data = null;
201
+
202
+ connectRows.remove();
203
+ fieldRows.remove();
204
+ error.remove();
205
+
206
+ if ( 'add_new_account' == value ) {
207
+ data = {
208
+ action : 'fl_builder_render_service_settings',
209
+ node_id : nodeId,
210
+ service : select.val(),
211
+ add_new : true
212
+ };
213
+ }
214
+ else if ( '' != value ) {
215
+ data = {
216
+ action : 'fl_builder_render_service_fields',
217
+ node_id : nodeId,
218
+ service : select.val(),
219
+ account : value
220
+ };
221
+ }
222
+
223
+ if ( data ) {
224
+ FLBuilderServices._startSettingsLoading( select );
225
+ FLBuilder.ajax( data, FLBuilderServices._accountChangeComplete );
226
+ }
227
+
228
+ FLBuilderServices._addAccountDelete( wrap );
229
+ },
230
+
231
+ /**
232
+ * AJAX callback for when the service account select changes.
233
+ *
234
+ * @param {String} response The JSON response.
235
+ * @return void
236
+ * @since 1.5.4
237
+ */
238
+ _accountChangeComplete: function( response )
239
+ {
240
+ var data = JSON.parse( response ),
241
+ wrap = $( '.fl-builder-service-settings-loading' ),
242
+ accountRow = wrap.find( '.fl-builder-service-account-row' );
243
+
244
+ accountRow.after( data.html );
245
+ FLBuilderServices._finishSettingsLoading();
246
+ },
247
+
248
+ /**
249
+ * Adds an account delete link.
250
+ *
251
+ * @param {Object} wrap An element within the lightbox.
252
+ * @return void
253
+ * @since 1.5.4
254
+ */
255
+ _addAccountDelete: function( wrap )
256
+ {
257
+ var account = wrap.find( '.fl-builder-service-account-select' );
258
+
259
+ if ( account.length > 0 ) {
260
+
261
+ wrap.find( '.fl-builder-service-account-delete' ).remove();
262
+
263
+ if ( '' != account.val() && 'add_new_account' != account.val() ) {
264
+ account.after( '<a href="javascript:void(0);" class="fl-builder-service-account-delete">' + FLBuilderStrings.deleteAccount + '</a>' );
265
+ }
266
+ }
267
+ },
268
+
269
+ /**
270
+ * Fires when the account delete link is clicked.
271
+ *
272
+ * @return void
273
+ * @since 1.5.4
274
+ */
275
+ _accountDeleteClicked: function()
276
+ {
277
+ var wrap = $( this ).closest( '.fl-builder-service-settings' ),
278
+ select = wrap.find( '.fl-builder-service-select' ),
279
+ account = wrap.find( '.fl-builder-service-account-select' );
280
+
281
+ if ( confirm( FLBuilderStrings.deleteAccountWarning ) ) {
282
+
283
+ FLBuilder.ajax( {
284
+ action : 'fl_builder_delete_service_account',
285
+ service : select.val(),
286
+ account : account.val()
287
+ }, FLBuilderServices._accountDeleteComplete );
288
+
289
+ FLBuilderServices._startSettingsLoading( account );
290
+ }
291
+ },
292
+
293
+ /**
294
+ * AJAX callback for when the account delete link is clicked.
295
+ *
296
+ * @return void
297
+ * @since 1.5.4
298
+ */
299
+ _accountDeleteComplete: function()
300
+ {
301
+ var wrap = $( '.fl-builder-service-settings-loading' ),
302
+ select = wrap.find( '.fl-builder-service-select' );
303
+
304
+ FLBuilderServices._finishSettingsLoading();
305
+
306
+ select.trigger( 'change' );
307
+ },
308
+
309
+ /* Campaign Monitor
310
+ ----------------------------------------------------------*/
311
+
312
+ /**
313
+ * Fires when the Campaign Monitor client select is changed.
314
+ *
315
+ * @return void
316
+ * @since 1.5.4
317
+ */
318
+ _campaignMonitorClientChange: function()
319
+ {
320
+ var nodeId = $( '.fl-builder-settings' ).data( 'node' ),
321
+ wrap = $( this ).closest( '.fl-builder-service-settings' ),
322
+ select = wrap.find( '.fl-builder-service-select' ),
323
+ account = wrap.find( '.fl-builder-service-account-select' ),
324
+ client = $( this ),
325
+ list = wrap.find( '.fl-builder-service-list-select' ),
326
+ value = client.val();
327
+
328
+ if ( 0 != list.length ) {
329
+ list.closest( 'tr' ).remove();
330
+ }
331
+ if ( '' == value ) {
332
+ return;
333
+ }
334
+
335
+ FLBuilderServices._startSettingsLoading( select );
336
+
337
+ FLBuilder.ajax( {
338
+ action : 'fl_builder_render_service_fields',
339
+ node_id : nodeId,
340
+ service : select.val(),
341
+ account : account.val(),
342
+ client : value
343
+ }, FLBuilderServices._campaignMonitorClientChangeComplete );
344
+ },
345
+
346
+ /**
347
+ * AJAX callback for when the Campaign Monitor client select is changed.
348
+ *
349
+ * @param {String} response The JSON response.
350
+ * @return void
351
+ * @since 1.5.4
352
+ */
353
+ _campaignMonitorClientChangeComplete: function( response )
354
+ {
355
+ var data = JSON.parse( response ),
356
+ wrap = $( '.fl-builder-service-settings-loading' ),
357
+ client = wrap.find( '.fl-builder-campaign-monitor-client-select' );
358
+
359
+ client.closest( 'tr' ).after( data.html );
360
+ FLBuilderServices._finishSettingsLoading();
361
+ }
362
+ };
363
+
364
+ $ ( function() {
365
+ FLBuilderServices.init();
366
+ });
367
+
368
+ })( jQuery );
js/fl-builder.js CHANGED
@@ -434,6 +434,9 @@ var FLBuilder;
434
  $('body').delegate('.fl-builder-no-tour-button', 'click', FLBuilder._noTourButtonClicked);
435
  $('body').delegate('.fl-builder-yes-tour-button', 'click', FLBuilder._yesTourButtonClicked);
436
 
 
 
 
437
  /* Rows */
438
  $('body').delegate('.fl-row-overlay .fl-block-remove', 'click', FLBuilder._deleteRowClicked);
439
  $('body').delegate('.fl-row-overlay .fl-block-copy', 'click', FLBuilder._rowCopyClicked);
@@ -502,7 +505,7 @@ var FLBuilder;
502
  $('body').delegate('.fl-link-field-select', 'click', FLBuilder._linkFieldSelectClicked);
503
  $('body').delegate('.fl-link-field-search-cancel', 'click', FLBuilder._linkFieldSelectCancelClicked);
504
 
505
- /* Loop Builder */
506
  $('body').delegate('.fl-loop-builder select[name=post_type]', 'change', FLBuilder._loopBuilderPostTypeChange);
507
  },
508
 
@@ -808,7 +811,14 @@ var FLBuilder;
808
  */
809
  _exit: function()
810
  {
811
- var href = FLBuilder._exitUrl ? FLBuilder._exitUrl : window.location.href.replace('fl_builder', '');
 
 
 
 
 
 
 
812
 
813
  window.location.href = href;
814
  },
@@ -1224,7 +1234,7 @@ var FLBuilder;
1224
  */
1225
  _saveUserTemplateSettingsComplete: function()
1226
  {
1227
- FLBuilder._alert(FLBuilderStrings.templateSaved);
1228
  },
1229
 
1230
  /* Edit User Template
@@ -2716,7 +2726,6 @@ var FLBuilder;
2716
  }
2717
  }
2718
 
2719
- FLBuilder._updateEditorFields();
2720
  FLLightbox.closeParent(this);
2721
 
2722
  if(FLBuilder.preview) {
@@ -3269,15 +3278,9 @@ var FLBuilder;
3269
  preview.attr('src', FLBuilder._getPhotoSrc(photo));
3270
  wrap.removeClass('fl-photo-empty');
3271
  wrap.find('label.error').remove();
3272
-
3273
- if(typeof photo.sizes !== 'undefined') {
3274
- srcSelect.show();
3275
- srcSelect.html(FLBuilder._getPhotoSizeOptions(photo));
3276
- srcSelect.trigger('change');
3277
- }
3278
- else {
3279
- srcSelect.hide();
3280
- }
3281
  },
3282
 
3283
  /**
@@ -3313,10 +3316,16 @@ var FLBuilder;
3313
  thumbnail : FLBuilderStrings.thumbnail
3314
  };
3315
 
3316
- for(size in photo.sizes) {
3317
- selected = size == 'full' ? ' selected="selected"' : '';
3318
- html += '<option value="' + photo.sizes[size].url + '"' + selected + '>' + titles[size] + ' - ' + photo.sizes[size].width + ' x ' + photo.sizes[size].height + '</option>';
3319
  }
 
 
 
 
 
 
 
3320
 
3321
  return html;
3322
  },
@@ -3755,21 +3764,6 @@ var FLBuilder;
3755
  $(this).parent().hide();
3756
  },
3757
 
3758
- /* Loop Builder
3759
- ----------------------------------------------------------*/
3760
-
3761
- /**
3762
- * @method _loopBuilderPostTypeChange
3763
- * @private
3764
- */
3765
- _loopBuilderPostTypeChange: function()
3766
- {
3767
- var val = $(this).val();
3768
-
3769
- $('.fl-loop-builder-filter').hide();
3770
- $('.fl-loop-builder-' + val + '-filter').show();
3771
- },
3772
-
3773
  /* Editor Fields
3774
  ----------------------------------------------------------*/
3775
 
@@ -3798,6 +3792,9 @@ var FLBuilder;
3798
  },
3799
 
3800
  /**
 
 
 
3801
  * @method _updateEditorField
3802
  * @private
3803
  */
@@ -3807,16 +3804,40 @@ var FLBuilder;
3807
  wrap = textarea.closest( '.wp-editor-wrap' ),
3808
  id = textarea.attr( 'id' ),
3809
  setting = textarea.closest( '.fl-editor-field' ).attr( 'id' ),
3810
- editor = typeof tinyMCE == 'undefined' ? false : tinyMCE.get( id );
 
 
 
 
 
 
 
3811
 
3812
- // Update the textarea content if tinymce is active.
3813
  if ( editor && wrap.hasClass( 'tmce-active' ) ) {
3814
- textarea.val( editor.getContent() );
 
 
 
 
 
 
3815
  }
 
 
 
 
 
 
 
 
 
 
 
 
3816
 
3817
- // Set the textarea name to our setting name so
3818
- // it can be referenced in the settings object.
3819
- textarea.attr( 'name', setting );
3820
  },
3821
 
3822
  /* AJAX
@@ -4009,20 +4030,29 @@ var FLBuilder;
4009
  ----------------------------------------------------------*/
4010
 
4011
  /**
4012
- * @method _alert
4013
  * @private
4014
  */
4015
- _alert: function(message)
4016
  {
4017
  var alert = new FLLightbox({
4018
  className: 'fl-builder-lightbox fl-builder-alert-lightbox',
4019
  destroyOnClose: true
4020
  }),
4021
- html = '<div class="fl-lightbox-message">' + message + '</div><div class="fl-lightbox-footer"><span class="fl-builder-settings-cancel fl-builder-button fl-builder-button-large fl-builder-button-primary" href="javascript:void(0);">' + FLBuilderStrings.ok + '</span></div>';
4022
 
4023
  alert.open(html);
4024
  },
4025
 
 
 
 
 
 
 
 
 
 
4026
  /* Console Logging
4027
  ----------------------------------------------------------*/
4028
 
434
  $('body').delegate('.fl-builder-no-tour-button', 'click', FLBuilder._noTourButtonClicked);
435
  $('body').delegate('.fl-builder-yes-tour-button', 'click', FLBuilder._yesTourButtonClicked);
436
 
437
+ /* Alert Lightbox */
438
+ $('body').delegate('.fl-builder-alert-close', 'click', FLBuilder._alertClose);
439
+
440
  /* Rows */
441
  $('body').delegate('.fl-row-overlay .fl-block-remove', 'click', FLBuilder._deleteRowClicked);
442
  $('body').delegate('.fl-row-overlay .fl-block-copy', 'click', FLBuilder._rowCopyClicked);
505
  $('body').delegate('.fl-link-field-select', 'click', FLBuilder._linkFieldSelectClicked);
506
  $('body').delegate('.fl-link-field-search-cancel', 'click', FLBuilder._linkFieldSelectCancelClicked);
507
 
508
+ /* Loop Builder Fields */
509
  $('body').delegate('.fl-loop-builder select[name=post_type]', 'change', FLBuilder._loopBuilderPostTypeChange);
510
  },
511
 
811
  */
812
  _exit: function()
813
  {
814
+ var href = window.location.href;
815
+
816
+ if ( FLBuilder._exitUrl ) {
817
+ href = FLBuilder._exitUrl;
818
+ }
819
+ else {
820
+ href = href.replace('?fl_builder', '').replace('&fl_builder', '');
821
+ }
822
 
823
  window.location.href = href;
824
  },
1234
  */
1235
  _saveUserTemplateSettingsComplete: function()
1236
  {
1237
+ FLBuilder.alert(FLBuilderStrings.templateSaved);
1238
  },
1239
 
1240
  /* Edit User Template
2726
  }
2727
  }
2728
 
 
2729
  FLLightbox.closeParent(this);
2730
 
2731
  if(FLBuilder.preview) {
3278
  preview.attr('src', FLBuilder._getPhotoSrc(photo));
3279
  wrap.removeClass('fl-photo-empty');
3280
  wrap.find('label.error').remove();
3281
+ srcSelect.show();
3282
+ srcSelect.html(FLBuilder._getPhotoSizeOptions(photo));
3283
+ srcSelect.trigger('change');
 
 
 
 
 
 
3284
  },
3285
 
3286
  /**
3316
  thumbnail : FLBuilderStrings.thumbnail
3317
  };
3318
 
3319
+ if(typeof photo.sizes === 'undefined') {
3320
+ html += '<option value="' + photo.url + '">' + FLBuilderStrings.fullSize + '</option>';
 
3321
  }
3322
+ else {
3323
+
3324
+ for(size in photo.sizes) {
3325
+ selected = size == 'full' ? ' selected="selected"' : '';
3326
+ html += '<option value="' + photo.sizes[size].url + '"' + selected + '>' + titles[size] + ' - ' + photo.sizes[size].width + ' x ' + photo.sizes[size].height + '</option>';
3327
+ }
3328
+ }
3329
 
3330
  return html;
3331
  },
3764
  $(this).parent().hide();
3765
  },
3766
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3767
  /* Editor Fields
3768
  ----------------------------------------------------------*/
3769
 
3792
  },
3793
 
3794
  /**
3795
+ * Create a hidden textarea with the editor content so
3796
+ * this field can be saved.
3797
+ *
3798
  * @method _updateEditorField
3799
  * @private
3800
  */
3804
  wrap = textarea.closest( '.wp-editor-wrap' ),
3805
  id = textarea.attr( 'id' ),
3806
  setting = textarea.closest( '.fl-editor-field' ).attr( 'id' ),
3807
+ editor = typeof tinyMCE == 'undefined' ? false : tinyMCE.get( id ),
3808
+ hidden = textarea.siblings( 'textarea[name="' + setting + '"]' );
3809
+
3810
+ // Add a hidden textarea if we don't have one.
3811
+ if ( 0 === hidden.length ) {
3812
+ hidden = $( '<textarea name="' + setting + '"></textarea>' ).hide();
3813
+ textarea.after( hidden );
3814
+ }
3815
 
3816
+ // Update the hidden textarea content.
3817
  if ( editor && wrap.hasClass( 'tmce-active' ) ) {
3818
+ hidden.val( editor.getContent() );
3819
+ }
3820
+ else if ( 'undefined' != typeof switchEditors ) {
3821
+ hidden.val( switchEditors.wpautop( textarea.val() ) );
3822
+ }
3823
+ else {
3824
+ hidden.val( textarea.val() );
3825
  }
3826
+ },
3827
+
3828
+ /* Loop Builder Fields
3829
+ ----------------------------------------------------------*/
3830
+
3831
+ /**
3832
+ * @method _loopBuilderPostTypeChange
3833
+ * @private
3834
+ */
3835
+ _loopBuilderPostTypeChange: function()
3836
+ {
3837
+ var val = $(this).val();
3838
 
3839
+ $('.fl-loop-builder-filter').hide();
3840
+ $('.fl-loop-builder-' + val + '-filter').show();
 
3841
  },
3842
 
3843
  /* AJAX
4030
  ----------------------------------------------------------*/
4031
 
4032
  /**
4033
+ * @method alert
4034
  * @private
4035
  */
4036
+ alert: function(message)
4037
  {
4038
  var alert = new FLLightbox({
4039
  className: 'fl-builder-lightbox fl-builder-alert-lightbox',
4040
  destroyOnClose: true
4041
  }),
4042
+ html = '<div class="fl-lightbox-message">' + message + '</div><div class="fl-lightbox-footer"><span class="fl-builder-alert-close fl-builder-button fl-builder-button-large fl-builder-button-primary" href="javascript:void(0);">' + FLBuilderStrings.ok + '</span></div>';
4043
 
4044
  alert.open(html);
4045
  },
4046
 
4047
+ /**
4048
+ * @method _alertClose
4049
+ * @private
4050
+ */
4051
+ _alertClose: function()
4052
+ {
4053
+ FLLightbox.closeParent(this);
4054
+ },
4055
+
4056
  /* Console Logging
4057
  ----------------------------------------------------------*/
4058