Version Description
(2015.03.17) =
Download this release
Release Info
Developer | AndyGCook |
Plugin | HubSpot – Free Marketing Plugin for WordPress |
Version | 3.1.4 |
Comparing to | |
See all releases |
Code changes from version 2.2.11 to 3.1.4
- admin/inc/class-leadin-contact.php +335 -4
- admin/inc/class-leadin-list-table.php +15 -3
- admin/inc/class-leadin-tag-editor.php +1 -2
- admin/inc/class-stats-dashboard.php +1 -1
- admin/leadin-admin.php +405 -176
- assets/css/build/leadin-admin.css +1 -1
- assets/css/build/leadin-lead-notifcation.css +1 -1
- assets/css/build/leadin-subscribe-premium.css +0 -3
- assets/js/build/leadin-admin.js +177 -0
- assets/js/build/leadin-admin.min.js +8 -8
- assets/js/build/leadin-subscribe.js +7 -8
- assets/js/build/leadin-subscribe.min.js +1 -1
- images/power-up-icon-aweber-connect.png +0 -0
- images/power-up-icon-aweber-connect@2x.png +0 -0
- images/power-up-icon-aweber-connect_small.png +0 -0
- images/power-up-icon-aweber-connect_small@2x.png +0 -0
- images/power-up-icon-campaign-monitor-connect.png +0 -0
- images/power-up-icon-campaign-monitor-connect@2x.png +0 -0
- images/power-up-icon-campaign-monitor-connect_small.png +0 -0
- images/power-up-icon-campaign-monitor-connect_small@2x.png +0 -0
- images/power-up-icon-getresponse-connect.png +0 -0
- images/power-up-icon-getresponse-connect@2x.png +0 -0
- images/power-up-icon-getresponse-connect_small.png +0 -0
- images/power-up-icon-getresponse-connect_small@2x.png +0 -0
- images/power-up-icon-getresponse-list-sync_small.png +0 -0
- images/power-up-icon-getresponse-list-sync_small@2x.png +0 -0
- images/powerup-icon-lookups.png +0 -0
- images/powerup-icon-lookups@2x.png +0 -0
- inc/class-emailer.php +269 -22
- inc/class-leadin-updater.php +1 -3
- inc/class-leadin.php +19 -65
- inc/leadin-ajax-functions.php +69 -8
- inc/leadin-constants.php +15 -0
- inc/leadin-functions.php +248 -15
- leadin.php +65 -8
- lib/mixpanel/Base/LI_MixpanelBase.php +68 -0
- lib/mixpanel/ConsumerStrategies/LI_AbstractConsumer.php +58 -0
- lib/mixpanel/ConsumerStrategies/LI_CurlConsumer.php +222 -0
- lib/mixpanel/ConsumerStrategies/LI_FileConsumer.php +39 -0
- lib/mixpanel/ConsumerStrategies/LI_SocketConsumer.php +309 -0
- lib/mixpanel/LI_Mixpanel.php +305 -0
- lib/mixpanel/Producers/LI_MixpanelBaseProducer.php +230 -0
- lib/mixpanel/Producers/LI_MixpanelEvents.php +165 -0
- lib/mixpanel/Producers/LI_MixpanelPeople.php +139 -0
- lib/segment/lib/Segment.php +145 -0
- lib/segment/lib/Segment/Client.php +201 -0
- lib/segment/lib/Segment/Consumer.php +104 -0
- lib/segment/lib/Segment/Consumer/File.php +111 -0
- lib/segment/lib/Segment/Consumer/ForkCurl.php +59 -0
- lib/segment/lib/Segment/Consumer/Socket.php +174 -0
- lib/segment/lib/Segment/QueueConsumer.php +138 -0
- lib/segment/send.php +106 -0
- power-ups/aweber-connect.php +168 -0
- power-ups/aweber-connect/admin/aweber-connect-admin.php +323 -0
- power-ups/aweber-connect/inc/aweber_api/li_aweber.php +292 -0
- power-ups/aweber-connect/inc/aweber_api/li_aweber_api.php +8 -0
- power-ups/aweber-connect/inc/aweber_api/li_aweber_collection.php +268 -0
- power-ups/aweber-connect/inc/aweber_api/li_aweber_entry.php +343 -0
- power-ups/aweber-connect/inc/aweber_api/li_aweber_entry_data_array.php +68 -0
- power-ups/aweber-connect/inc/aweber_api/li_aweber_response.php +73 -0
- power-ups/aweber-connect/inc/aweber_api/li_curl_object.php +103 -0
- power-ups/aweber-connect/inc/aweber_api/li_curl_response.php +51 -0
- power-ups/aweber-connect/inc/aweber_api/li_exceptions.php +130 -0
- power-ups/aweber-connect/inc/aweber_api/li_oauth_adapter.php +11 -0
- power-ups/aweber-connect/inc/aweber_api/li_oauth_application.php +681 -0
- power-ups/campaign-monitor-connect.php +141 -0
- power-ups/campaign-monitor-connect/admin/campaign-monitor-connect-admin.php +225 -0
- power-ups/campaign-monitor-connect/inc/li_campaign_monitor.php +123 -0
- power-ups/campaign-monitor-connect/inc/test.php +35 -0
- power-ups/constant-contact-connect.php +9 -2
- power-ups/constant-contact-connect/admin/constant-contact-connect-admin.php +11 -50
- power-ups/contacts.php +1 -1
- power-ups/contacts/admin/contacts-admin.php +220 -9
- power-ups/getresponse-connect.php +133 -0
- power-ups/getresponse-connect/admin/getresponse-connect-admin.php +206 -0
- power-ups/getresponse-connect/inc/LI_GetResponseAPI.php +558 -0
- power-ups/lookups.php +78 -0
- power-ups/lookups/admin/inc/blacklist_domains.php +3025 -0
- power-ups/lookups/admin/lookups-admin.php +44 -0
- power-ups/mailchimp-connect.php +7 -28
- power-ups/mailchimp-connect/admin/mailchimp-connect-admin.php +15 -48
- power-ups/subscribe-widget.php +0 -11
- power-ups/subscribe-widget/admin/subscribe-widget-admin.php +5 -5
- readme.txt +102 -76
admin/inc/class-leadin-contact.php
CHANGED
@@ -1,4 +1,11 @@
|
|
1 |
<?php
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2 |
//=============================================
|
3 |
// LI_Contact Class
|
4 |
//=============================================
|
@@ -49,6 +56,12 @@ class LI_Contact {
|
|
49 |
$submissions = $this->get_contact_submissions($this->hashkey, 'ARRAY_A');
|
50 |
$tags = $this->get_contact_tags($this->hashkey);
|
51 |
|
|
|
|
|
|
|
|
|
|
|
|
|
52 |
// Merge the page views array and submissions array and reorder by date
|
53 |
$events_array = array_merge($pageviews, $submissions);
|
54 |
usort($events_array, array('LI_Contact','sort_by_event_date'));
|
@@ -119,8 +132,7 @@ class LI_Contact {
|
|
119 |
}
|
120 |
else
|
121 |
{
|
122 |
-
|
123 |
-
// Always overwrite the first_submission date which will end as last submission date
|
124 |
$lead->first_submission = $event['event_date'];
|
125 |
|
126 |
$event['form_name'] = 'form';
|
@@ -264,7 +276,10 @@ class LI_Contact {
|
|
264 |
lead_ip,
|
265 |
lead_email,
|
266 |
lead_first_name,
|
267 |
-
lead_last_name
|
|
|
|
|
|
|
268 |
FROM
|
269 |
$wpdb->li_leads
|
270 |
WHERE hashkey LIKE %s", $wpdb->db_hour_offset, '%b %D %l:%i%p', $hashkey);
|
@@ -274,6 +289,173 @@ class LI_Contact {
|
|
274 |
return $contact_details;
|
275 |
}
|
276 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
277 |
/**
|
278 |
* Gets all the tags for a contact
|
279 |
*
|
@@ -365,6 +547,8 @@ class LI_Contact {
|
|
365 |
);
|
366 |
|
367 |
$safe_tags .= $wpdb->insert_id . ',';
|
|
|
|
|
368 |
}
|
369 |
else
|
370 |
{
|
@@ -393,7 +577,7 @@ class LI_Contact {
|
|
393 |
if ( ! ${$power_up_global}->activated )
|
394 |
continue;
|
395 |
|
396 |
-
${$power_up_global}->push_contact_to_list($list['list_id'], $this->history->lead->lead_email);
|
397 |
}
|
398 |
|
399 |
array_push($synced_lists, $list['list_id']);
|
@@ -405,10 +589,17 @@ class LI_Contact {
|
|
405 |
{
|
406 |
$q = $wpdb->prepare("UPDATE $wpdb->li_tag_relationships SET tag_relationship_deleted = 0 WHERE contact_hashkey = %s AND tag_relationship_id IN ( " . rtrim($tags_to_update, ',') . " ) ", $this->hashkey);
|
407 |
$tag_updated = $wpdb->query($q);
|
|
|
|
|
408 |
}
|
409 |
|
410 |
$q = $wpdb->prepare("UPDATE $wpdb->li_tag_relationships SET tag_relationship_deleted = 1 WHERE contact_hashkey = %s " . ( $safe_tags ? "AND tag_relationship_id NOT IN ( " . rtrim($safe_tags, ',') . " ) " : '' ) . " AND tag_relationship_deleted = 0 ", $this->hashkey);
|
411 |
$deleted_tags = $wpdb->query($q);
|
|
|
|
|
|
|
|
|
|
|
412 |
}
|
413 |
|
414 |
/**
|
@@ -424,5 +615,145 @@ class LI_Contact {
|
|
424 |
|
425 |
return $val_a < $val_b;
|
426 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
427 |
}
|
428 |
?>
|
1 |
<?php
|
2 |
+
|
3 |
+
//=============================================
|
4 |
+
// Include Needed Files
|
5 |
+
//=============================================
|
6 |
+
|
7 |
+
require_once(LEADIN_PLUGIN_DIR . '/power-ups/lookups/admin/inc/blacklist_domains.php');
|
8 |
+
|
9 |
//=============================================
|
10 |
// LI_Contact Class
|
11 |
//=============================================
|
56 |
$submissions = $this->get_contact_submissions($this->hashkey, 'ARRAY_A');
|
57 |
$tags = $this->get_contact_tags($this->hashkey);
|
58 |
|
59 |
+
if ( WPLeadIn::is_power_up_active('lookups') )
|
60 |
+
{
|
61 |
+
$lead->social_data = $this->get_social_details($lead);
|
62 |
+
$lead->company_data = $this->get_company_details($lead);
|
63 |
+
}
|
64 |
+
|
65 |
// Merge the page views array and submissions array and reorder by date
|
66 |
$events_array = array_merge($pageviews, $submissions);
|
67 |
usort($events_array, array('LI_Contact','sort_by_event_date'));
|
132 |
}
|
133 |
else
|
134 |
{
|
135 |
+
// Always overwrite the last_submission date which will end as last submission date
|
|
|
136 |
$lead->first_submission = $event['event_date'];
|
137 |
|
138 |
$event['form_name'] = 'form';
|
276 |
lead_ip,
|
277 |
lead_email,
|
278 |
lead_first_name,
|
279 |
+
lead_last_name,
|
280 |
+
social_data,
|
281 |
+
company_data,
|
282 |
+
lead_deleted
|
283 |
FROM
|
284 |
$wpdb->li_leads
|
285 |
WHERE hashkey LIKE %s", $wpdb->db_hour_offset, '%b %D %l:%i%p', $hashkey);
|
289 |
return $contact_details;
|
290 |
}
|
291 |
|
292 |
+
/**
|
293 |
+
* Sets the social_data on a contact
|
294 |
+
*
|
295 |
+
* @param object
|
296 |
+
* @return object
|
297 |
+
*/
|
298 |
+
function get_social_details ( $lead )
|
299 |
+
{
|
300 |
+
$site_url = site_url();
|
301 |
+
$social_data = '';
|
302 |
+
|
303 |
+
if ( ! $lead->social_data )
|
304 |
+
{
|
305 |
+
// Grab the social intel lookup
|
306 |
+
$social_data = json_decode($this->query_social_lookup_endpoint(strtolower($lead->lead_email), $site_url));
|
307 |
+
|
308 |
+
if ( ! isset($social_data->status) )
|
309 |
+
{
|
310 |
+
$this->update_social_lookup_data($this->hashkey, serialize($social_data));
|
311 |
+
|
312 |
+
// Update the first and last names if one of them isn't set, and the respected name part is present or the full name is present the full name is present or the correspond
|
313 |
+
$first_name = '';
|
314 |
+
$last_name = '';
|
315 |
+
$update_name = FALSE;
|
316 |
+
|
317 |
+
if ( ! $lead->lead_first_name )
|
318 |
+
{
|
319 |
+
if ( isset($social_data->fullcontactDetails->contactinfo->givenname) )
|
320 |
+
{
|
321 |
+
$first_name = $social_data->fullcontactDetails->contactinfo->givenname;
|
322 |
+
$update_name = TRUE;
|
323 |
+
}
|
324 |
+
else if ( isset($social_data->fullcontactDetails->contactinfo->fullname) )
|
325 |
+
{
|
326 |
+
$first_name = reset(explode(' ', $social_data->fullcontactDetails->contactinfo->fullname));
|
327 |
+
$update_name = TRUE;
|
328 |
+
}
|
329 |
+
}
|
330 |
+
else
|
331 |
+
$first_name = $lead->lead_first_name;
|
332 |
+
|
333 |
+
if ( ! $lead->lead_last_name )
|
334 |
+
{
|
335 |
+
if ( isset($social_data->fullcontactDetails->contactinfo->familyname) )
|
336 |
+
{
|
337 |
+
$last_name = $social_data->fullcontactDetails->contactinfo->familyname;
|
338 |
+
$update_name = TRUE;
|
339 |
+
}
|
340 |
+
else if ( isset($social_data->fullcontactDetails->contactinfo->fullname) )
|
341 |
+
{
|
342 |
+
$last_name = end(explode(' ', $social_data->fullcontactDetails->contactinfo->fullname));
|
343 |
+
$update_name = TRUE;
|
344 |
+
}
|
345 |
+
}
|
346 |
+
else
|
347 |
+
$last_name = $lead->lead_first_name;
|
348 |
+
|
349 |
+
if ( $update_name )
|
350 |
+
$this->update_contact_full_name($this->hashkey, $first_name, $last_name);
|
351 |
+
|
352 |
+
}
|
353 |
+
else if ( isset($social_data->status) && $social_data->status == 'error' )
|
354 |
+
{
|
355 |
+
$social_data = '';
|
356 |
+
}
|
357 |
+
}
|
358 |
+
else
|
359 |
+
$social_data = unserialize($lead->social_data);
|
360 |
+
|
361 |
+
if ( isset($social_data->fullcontactDetails) )
|
362 |
+
{
|
363 |
+
$fullcontactDetails = $social_data->fullcontactDetails;
|
364 |
+
|
365 |
+
if ( count($fullcontactDetails->organizations) )
|
366 |
+
{
|
367 |
+
foreach ( $fullcontactDetails->organizations as $org )
|
368 |
+
{
|
369 |
+
if ( isset($org->isprimary) )
|
370 |
+
{
|
371 |
+
$social_data->properties->primary->company_name = ( isset($org->name) ? $org->name : '' );
|
372 |
+
$social_data->properties->primary->title = ( isset($org->title) ? $org->title : '' );
|
373 |
+
break;
|
374 |
+
}
|
375 |
+
}
|
376 |
+
}
|
377 |
+
|
378 |
+
if ( isset($social_data->twitterDetails->description) )
|
379 |
+
{
|
380 |
+
if ( $social_data->twitterDetails->description )
|
381 |
+
$social_data->properties->description = $social_data->twitterDetails->description;
|
382 |
+
}
|
383 |
+
|
384 |
+
if ( count($fullcontactDetails->socialprofiles) )
|
385 |
+
{
|
386 |
+
$social_profiles = array();
|
387 |
+
|
388 |
+
foreach ( $fullcontactDetails->socialprofiles as $key => $profile )
|
389 |
+
{
|
390 |
+
$whitelisted_profiles = array('twitter', 'facebook', 'linkedin', 'googleplus');
|
391 |
+
if ( in_array($profile->typeid, $whitelisted_profiles) && ! empty($profile->username) )
|
392 |
+
{
|
393 |
+
$social_profile = (object)NULL;
|
394 |
+
$social_profile->typename = $profile->typename;
|
395 |
+
$social_profile->url = leadin_safe_social_profile_url($profile->url);
|
396 |
+
$social_profile->typeid = $profile->typeid;
|
397 |
+
$social_profile->username = $profile->username;
|
398 |
+
|
399 |
+
$social_profiles[] = $social_profile;
|
400 |
+
}
|
401 |
+
}
|
402 |
+
|
403 |
+
if ( count($social_profiles) )
|
404 |
+
{
|
405 |
+
if ( isset($social_data->properties->social_profiles) )
|
406 |
+
$social_data->properties->social_profiles = $social_profiles;
|
407 |
+
}
|
408 |
+
}
|
409 |
+
}
|
410 |
+
|
411 |
+
return $social_data;
|
412 |
+
}
|
413 |
+
|
414 |
+
/**
|
415 |
+
* Sets the company_data on a contact
|
416 |
+
*
|
417 |
+
* @param object
|
418 |
+
* @return object
|
419 |
+
*/
|
420 |
+
function get_company_details ( $lead )
|
421 |
+
{
|
422 |
+
global $blacklist_freemail_domains;
|
423 |
+
global $blacklist_nonmail_domains;
|
424 |
+
|
425 |
+
$site_url = site_url();
|
426 |
+
$email_domain = end(explode('@', $lead->lead_email));
|
427 |
+
$leadin_user = leadin_get_current_user();
|
428 |
+
$company_data = '';
|
429 |
+
|
430 |
+
if ( strstr($leadin_user['email'], ',') )
|
431 |
+
$leadin_user_email = reset(explode(',', $leadin_user['email']));
|
432 |
+
else
|
433 |
+
$leadin_user_email = $leadin_user['email'];
|
434 |
+
|
435 |
+
if ( ! in_array($email_domain, $blacklist_nonmail_domains) && ! in_array($email_domain, $blacklist_freemail_domains) )
|
436 |
+
{
|
437 |
+
if ( ! $lead->company_data )
|
438 |
+
{
|
439 |
+
// Grab the company intel lookup
|
440 |
+
$company_data = json_decode($this->query_company_lookup_endpoint($email_domain, $leadin_user_email, $site_url));
|
441 |
+
|
442 |
+
if ( isset($company_data->status) && $company_data->status != 'error' )
|
443 |
+
{
|
444 |
+
$this->update_company_lookup_data($this->hashkey, serialize($company_data));
|
445 |
+
}
|
446 |
+
else
|
447 |
+
{
|
448 |
+
}
|
449 |
+
}
|
450 |
+
else
|
451 |
+
{
|
452 |
+
$company_data = unserialize($lead->company_data);
|
453 |
+
}
|
454 |
+
}
|
455 |
+
|
456 |
+
return $company_data;
|
457 |
+
}
|
458 |
+
|
459 |
/**
|
460 |
* Gets all the tags for a contact
|
461 |
*
|
547 |
);
|
548 |
|
549 |
$safe_tags .= $wpdb->insert_id . ',';
|
550 |
+
|
551 |
+
leadin_track_plugin_activity('Tag Added - Contact Timeline');
|
552 |
}
|
553 |
else
|
554 |
{
|
577 |
if ( ! ${$power_up_global}->activated )
|
578 |
continue;
|
579 |
|
580 |
+
${$power_up_global}->push_contact_to_list($list['list_id'], $this->history->lead->lead_email, $this->history->lead->lead_first_name, $this->history->lead->lead_last_name);
|
581 |
}
|
582 |
|
583 |
array_push($synced_lists, $list['list_id']);
|
589 |
{
|
590 |
$q = $wpdb->prepare("UPDATE $wpdb->li_tag_relationships SET tag_relationship_deleted = 0 WHERE contact_hashkey = %s AND tag_relationship_id IN ( " . rtrim($tags_to_update, ',') . " ) ", $this->hashkey);
|
591 |
$tag_updated = $wpdb->query($q);
|
592 |
+
|
593 |
+
leadin_track_plugin_activity('Tag Restored - Contact Timeline');
|
594 |
}
|
595 |
|
596 |
$q = $wpdb->prepare("UPDATE $wpdb->li_tag_relationships SET tag_relationship_deleted = 1 WHERE contact_hashkey = %s " . ( $safe_tags ? "AND tag_relationship_id NOT IN ( " . rtrim($safe_tags, ',') . " ) " : '' ) . " AND tag_relationship_deleted = 0 ", $this->hashkey);
|
597 |
$deleted_tags = $wpdb->query($q);
|
598 |
+
|
599 |
+
if ( $deleted_tags )
|
600 |
+
{
|
601 |
+
leadin_track_plugin_activity('Tag Removed - Contact Timeline');
|
602 |
+
}
|
603 |
}
|
604 |
|
605 |
/**
|
615 |
|
616 |
return $val_a < $val_b;
|
617 |
}
|
618 |
+
|
619 |
+
/**
|
620 |
+
* Query the social lookup endpoint on Leadin.com
|
621 |
+
*
|
622 |
+
* @param string
|
623 |
+
* @param string
|
624 |
+
* @return array
|
625 |
+
*/
|
626 |
+
function query_social_lookup_endpoint ( $lookup_email, $caller_domain )
|
627 |
+
{
|
628 |
+
$api_endpoint = 'http://leadin.com/enrichment/v1/profile/email/email_lookup.php';
|
629 |
+
$params = '?lookup_email=' . $lookup_email . '&caller_domain=' . $caller_domain;
|
630 |
+
|
631 |
+
$curl_handle = curl_init();
|
632 |
+
curl_setopt($curl_handle,CURLOPT_URL, $api_endpoint . $params);
|
633 |
+
curl_setopt($curl_handle,CURLOPT_CONNECTTIMEOUT,2);
|
634 |
+
curl_setopt($curl_handle,CURLOPT_RETURNTRANSFER,1);
|
635 |
+
$data = curl_exec($curl_handle);
|
636 |
+
curl_close($curl_handle);
|
637 |
+
|
638 |
+
|
639 |
+
return htmlspecialchars_decode($data);
|
640 |
+
|
641 |
+
}
|
642 |
+
|
643 |
+
/**
|
644 |
+
* Query the company lookup endpoint on Leadin.com
|
645 |
+
*
|
646 |
+
* @param string
|
647 |
+
* @param string
|
648 |
+
* @param string
|
649 |
+
* @return array
|
650 |
+
*/
|
651 |
+
function query_company_lookup_endpoint ( $lookup_company_url, $caller_email, $caller_domain )
|
652 |
+
{
|
653 |
+
$caller_domain = str_replace(array('http://', 'https://'), '', $caller_domain);
|
654 |
+
$caller_domain = 'leadin.com';
|
655 |
+
|
656 |
+
$api_endpoint = 'http://leadin.com/enrichment/v1/company/company_lookup.php';
|
657 |
+
$params = '?lookup_company_url=' . $lookup_company_url . '&caller_email=' . $caller_email . '&caller_domain=' . $caller_domain;
|
658 |
+
|
659 |
+
$curl_handle = curl_init();
|
660 |
+
curl_setopt($curl_handle,CURLOPT_URL, $api_endpoint . $params);
|
661 |
+
curl_setopt($curl_handle,CURLOPT_CONNECTTIMEOUT,2);
|
662 |
+
curl_setopt($curl_handle,CURLOPT_RETURNTRANSFER,1);
|
663 |
+
$data = curl_exec($curl_handle);
|
664 |
+
curl_close($curl_handle);
|
665 |
+
|
666 |
+
|
667 |
+
return htmlspecialchars_decode($data);
|
668 |
+
}
|
669 |
+
|
670 |
+
/**
|
671 |
+
* Queries for the company_data and social_data fields on the contact in li_leads
|
672 |
+
*
|
673 |
+
* @param string
|
674 |
+
* @return object
|
675 |
+
*/
|
676 |
+
function get_cached_lookup_data ( $hashkey )
|
677 |
+
{
|
678 |
+
global $wpdb;
|
679 |
+
|
680 |
+
$q = $wpdb->prepare("SELECT social_data, company_data FROM $wpdb->li_leads WHERE hashkey = %s", $hashkey);
|
681 |
+
$result = $wpdb->get_row($q);
|
682 |
+
|
683 |
+
return $result;
|
684 |
+
}
|
685 |
+
|
686 |
+
/**
|
687 |
+
* Cache the social lookup data in the database
|
688 |
+
*
|
689 |
+
* @param string
|
690 |
+
* @param string serialized array
|
691 |
+
* @param string
|
692 |
+
* @return bool
|
693 |
+
*/
|
694 |
+
function update_social_lookup_data ( $hashkey, $social_data )
|
695 |
+
{
|
696 |
+
global $wpdb;
|
697 |
+
|
698 |
+
$q = $wpdb->prepare("UPDATE $wpdb->li_leads SET social_data = %s WHERE hashkey = %s", $social_data, $hashkey);
|
699 |
+
$result = $wpdb->query($q);
|
700 |
+
|
701 |
+
return $result;
|
702 |
+
}
|
703 |
+
|
704 |
+
/**
|
705 |
+
* Cache the company lookup data in the database
|
706 |
+
*
|
707 |
+
* @param string
|
708 |
+
* @param string serialized array
|
709 |
+
* @param string
|
710 |
+
* @return bool
|
711 |
+
*/
|
712 |
+
function update_company_lookup_data ( $hashkey, $company_data )
|
713 |
+
{
|
714 |
+
global $wpdb;
|
715 |
+
|
716 |
+
$q = $wpdb->prepare("UPDATE $wpdb->li_leads SET company_data = %s WHERE hashkey = %s", $company_data, $hashkey);
|
717 |
+
$result = $wpdb->query($q);
|
718 |
+
|
719 |
+
return $result;
|
720 |
+
}
|
721 |
+
|
722 |
+
/**
|
723 |
+
* Update the first + last name on a contact row in li_leads
|
724 |
+
*
|
725 |
+
* @param string
|
726 |
+
* @param string
|
727 |
+
* @param string
|
728 |
+
* @return bool
|
729 |
+
*/
|
730 |
+
function update_contact_full_name ( $hashkey, $first_name, $last_name )
|
731 |
+
{
|
732 |
+
global $wpdb;
|
733 |
+
|
734 |
+
$q = $wpdb->prepare("UPDATE $wpdb->li_leads SET lead_first_name = %s, lead_last_name = %s WHERE hashkey = %s", $first_name, $last_name, $hashkey);
|
735 |
+
$result = $wpdb->query($q);
|
736 |
+
|
737 |
+
return $result;
|
738 |
+
}
|
739 |
+
|
740 |
+
/**
|
741 |
+
* Redirects the user to a merged contact when the current contact has been deleted
|
742 |
+
*
|
743 |
+
* @param string
|
744 |
+
*
|
745 |
+
*/
|
746 |
+
function display_error_message_for_merged_contact ( $lead_email )
|
747 |
+
{
|
748 |
+
global $wpdb;
|
749 |
+
|
750 |
+
$q = $wpdb->prepare("SELECT lead_id FROM $wpdb->li_leads WHERE lead_email = %s AND lead_deleted = 0 ORDER BY lead_date DESC LIMIT 1", $lead_email);
|
751 |
+
$lead_id = $wpdb->get_var($q);
|
752 |
+
|
753 |
+
if ( $lead_id )
|
754 |
+
{
|
755 |
+
echo '<div style="background: #fff; border-left: 4px solid #dd3d36; padding: 1px 12px; margin-bottom: 20px;" ><p>This contact record was merged with a more recent entry and is out of date... <br/><br/> <a class="button" href="' . get_admin_url() . 'admin.php?page=leadin_contacts&action=view&lead=' . $lead_id . '">View the latest timeline</a></p></div>';
|
756 |
+
}
|
757 |
+
}
|
758 |
}
|
759 |
?>
|
admin/inc/class-leadin-list-table.php
CHANGED
@@ -189,7 +189,6 @@ class LI_List_Table extends WP_List_Table {
|
|
189 |
$ids_for_action = '';
|
190 |
$hashes_for_action = '';
|
191 |
|
192 |
-
// @TODO Fix the delete logic
|
193 |
if ( strstr($this->current_action(), 'delete') )
|
194 |
{
|
195 |
if ( 'delete_selected' === $this->current_action() )
|
@@ -201,6 +200,8 @@ class LI_List_Table extends WP_List_Table {
|
|
201 |
if ( $i != (count($_GET['contact'])-1) )
|
202 |
$ids_for_action .= ',';
|
203 |
}
|
|
|
|
|
204 |
}
|
205 |
else if ( 'delete_all' === $this->current_action() )
|
206 |
{
|
@@ -209,11 +210,12 @@ class LI_List_Table extends WP_List_Table {
|
|
209 |
$ids_for_action .= $contact['ID'] . ',';
|
210 |
|
211 |
$ids_for_action = rtrim($ids_for_action, ',');
|
|
|
|
|
212 |
}
|
213 |
else // default case for when it's not actually processing a bulk action
|
214 |
return FALSE;
|
215 |
|
216 |
-
|
217 |
$q = $wpdb->prepare("SELECT hashkey FROM $wpdb->li_leads WHERE lead_id IN ( " . $ids_for_action . " ) ", "");
|
218 |
$hashes = $wpdb->get_results($q);
|
219 |
|
@@ -294,6 +296,8 @@ class LI_List_Table extends WP_List_Table {
|
|
294 |
$wpdb->query($q);
|
295 |
}
|
296 |
|
|
|
|
|
297 |
// Bulk push all the email addresses for the tag to the MailChimp API
|
298 |
$tagger = new LI_Tag_Editor($tag_id);
|
299 |
$tagger->push_contacts_to_tagged_list($tag_id);
|
@@ -305,6 +309,8 @@ class LI_List_Table extends WP_List_Table {
|
|
305 |
// "Delete" the existing tags only
|
306 |
$q = $wpdb->prepare("UPDATE $wpdb->li_tag_relationships SET tag_relationship_deleted = 1 WHERE tag_id = %d AND contact_hashkey IN ( " . rtrim($contacts_to_update, ',') . ") ", $tag_id);
|
307 |
$wpdb->query($q);
|
|
|
|
|
308 |
}
|
309 |
}
|
310 |
}
|
@@ -345,6 +351,8 @@ class LI_List_Table extends WP_List_Table {
|
|
345 |
|
346 |
$search_query = $_GET['s'];
|
347 |
$mysql_search_filter = $wpdb->prepare(" AND ( l.lead_email LIKE '%%%s%%' OR l.lead_source LIKE '%%%s%%' ) ", $escaped_query, $escaped_query);
|
|
|
|
|
348 |
}
|
349 |
|
350 |
$filtered_contacts = array();
|
@@ -374,6 +382,8 @@ class LI_List_Table extends WP_List_Table {
|
|
374 |
$q = $wpdb->prepare("SELECT lead_hashkey FROM $wpdb->li_pageviews WHERE pageview_title LIKE '%%%s%%' GROUP BY lead_hashkey", htmlspecialchars(urldecode($_GET['filter_content'])));
|
375 |
$filtered_contacts = leadin_merge_filtered_contacts($wpdb->get_results($q, 'ARRAY_A'), $filtered_contacts);
|
376 |
$filter_action_set = TRUE;
|
|
|
|
|
377 |
}
|
378 |
}
|
379 |
|
@@ -385,6 +395,8 @@ class LI_List_Table extends WP_List_Table {
|
|
385 |
{
|
386 |
$filter_form = str_replace(array('#', '.'), '', htmlspecialchars(urldecode($_GET['filter_form'])));
|
387 |
$filter_form_query = $wpdb->prepare(" AND ( form_selector_id LIKE '%%%s%%' OR form_selector_classes LIKE '%%%s%%' )", $filter_form, $filter_form);
|
|
|
|
|
388 |
}
|
389 |
|
390 |
$q = $wpdb->prepare("SELECT lead_hashkey FROM $wpdb->li_submissions WHERE form_page_title LIKE '%%%s%%' ", ( $_GET['filter_content'] != 'any page' ? htmlspecialchars(urldecode($_GET['filter_content'])): '' ));
|
@@ -549,7 +561,7 @@ class LI_List_Table extends WP_List_Table {
|
|
549 |
function views ()
|
550 |
{
|
551 |
$this->tags = stripslashes_deep($this->get_tags());
|
552 |
-
|
553 |
$current = ( !empty($_GET['contact_type']) ? html_entity_decode($_GET['contact_type']) : 'all' );
|
554 |
$all_params = array( 'contact_type', 's', 'paged', '_wpnonce', '_wpreferrer', '_wp_http_referer', 'action', 'action2', 'filter_form', 'filter_action', 'filter_content', 'contact');
|
555 |
|
189 |
$ids_for_action = '';
|
190 |
$hashes_for_action = '';
|
191 |
|
|
|
192 |
if ( strstr($this->current_action(), 'delete') )
|
193 |
{
|
194 |
if ( 'delete_selected' === $this->current_action() )
|
200 |
if ( $i != (count($_GET['contact'])-1) )
|
201 |
$ids_for_action .= ',';
|
202 |
}
|
203 |
+
|
204 |
+
leadin_track_plugin_activity('Bulk Contacts Deleted', array( "contact_type" => 'selected'));
|
205 |
}
|
206 |
else if ( 'delete_all' === $this->current_action() )
|
207 |
{
|
210 |
$ids_for_action .= $contact['ID'] . ',';
|
211 |
|
212 |
$ids_for_action = rtrim($ids_for_action, ',');
|
213 |
+
|
214 |
+
leadin_track_plugin_activity('Bulk Contacts Deleted', array( "contact_type" => 'all'));
|
215 |
}
|
216 |
else // default case for when it's not actually processing a bulk action
|
217 |
return FALSE;
|
218 |
|
|
|
219 |
$q = $wpdb->prepare("SELECT hashkey FROM $wpdb->li_leads WHERE lead_id IN ( " . $ids_for_action . " ) ", "");
|
220 |
$hashes = $wpdb->get_results($q);
|
221 |
|
296 |
$wpdb->query($q);
|
297 |
}
|
298 |
|
299 |
+
leadin_track_plugin_activity('Bulk Tag Added', array( "contact_type" => ( empty($_POST['leadin_selected_contacts']) ? 'all' : 'selected' )));
|
300 |
+
|
301 |
// Bulk push all the email addresses for the tag to the MailChimp API
|
302 |
$tagger = new LI_Tag_Editor($tag_id);
|
303 |
$tagger->push_contacts_to_tagged_list($tag_id);
|
309 |
// "Delete" the existing tags only
|
310 |
$q = $wpdb->prepare("UPDATE $wpdb->li_tag_relationships SET tag_relationship_deleted = 1 WHERE tag_id = %d AND contact_hashkey IN ( " . rtrim($contacts_to_update, ',') . ") ", $tag_id);
|
311 |
$wpdb->query($q);
|
312 |
+
|
313 |
+
leadin_track_plugin_activity('Bulk Tag Removed', array( "contact_type" => ( empty($_POST['leadin_selected_contacts']) ? 'all' : 'selected' )));
|
314 |
}
|
315 |
}
|
316 |
}
|
351 |
|
352 |
$search_query = $_GET['s'];
|
353 |
$mysql_search_filter = $wpdb->prepare(" AND ( l.lead_email LIKE '%%%s%%' OR l.lead_source LIKE '%%%s%%' ) ", $escaped_query, $escaped_query);
|
354 |
+
|
355 |
+
leadin_track_plugin_activity('Filtered List', array ( "filter_type" => "search" ));
|
356 |
}
|
357 |
|
358 |
$filtered_contacts = array();
|
382 |
$q = $wpdb->prepare("SELECT lead_hashkey FROM $wpdb->li_pageviews WHERE pageview_title LIKE '%%%s%%' GROUP BY lead_hashkey", htmlspecialchars(urldecode($_GET['filter_content'])));
|
383 |
$filtered_contacts = leadin_merge_filtered_contacts($wpdb->get_results($q, 'ARRAY_A'), $filtered_contacts);
|
384 |
$filter_action_set = TRUE;
|
385 |
+
|
386 |
+
leadin_track_plugin_activity('Filtered List', array ( "filter_type" => "page" ));
|
387 |
}
|
388 |
}
|
389 |
|
395 |
{
|
396 |
$filter_form = str_replace(array('#', '.'), '', htmlspecialchars(urldecode($_GET['filter_form'])));
|
397 |
$filter_form_query = $wpdb->prepare(" AND ( form_selector_id LIKE '%%%s%%' OR form_selector_classes LIKE '%%%s%%' )", $filter_form, $filter_form);
|
398 |
+
|
399 |
+
leadin_track_plugin_activity('Filtered List', array ( "filter_type" => "form" ));
|
400 |
}
|
401 |
|
402 |
$q = $wpdb->prepare("SELECT lead_hashkey FROM $wpdb->li_submissions WHERE form_page_title LIKE '%%%s%%' ", ( $_GET['filter_content'] != 'any page' ? htmlspecialchars(urldecode($_GET['filter_content'])): '' ));
|
561 |
function views ()
|
562 |
{
|
563 |
$this->tags = stripslashes_deep($this->get_tags());
|
564 |
+
|
565 |
$current = ( !empty($_GET['contact_type']) ? html_entity_decode($_GET['contact_type']) : 'all' );
|
566 |
$all_params = array( 'contact_type', 's', 'paged', '_wpnonce', '_wpreferrer', '_wp_http_referer', 'action', 'action2', 'filter_form', 'filter_action', 'filter_content', 'contact');
|
567 |
|
admin/inc/class-leadin-tag-editor.php
CHANGED
@@ -88,7 +88,7 @@ class LI_Tag_Editor {
|
|
88 |
{
|
89 |
global $wpdb;
|
90 |
|
91 |
-
$q =
|
92 |
$tag_order = $wpdb->get_var($q);
|
93 |
$tag_order = ( $tag_order ? $tag_order + 1 : 1 );
|
94 |
$tag_slug = $this->generate_slug($tag_text);
|
@@ -113,7 +113,6 @@ class LI_Tag_Editor {
|
|
113 |
function save_tag ( $tag_id, $tag_text, $tag_form_selectors, $tag_synced_lists )
|
114 |
{
|
115 |
global $wpdb;
|
116 |
-
global $leadin_mailchimp_connect_wp;
|
117 |
|
118 |
$tag_slug = $this->generate_slug($tag_text, $tag_id);
|
119 |
|
88 |
{
|
89 |
global $wpdb;
|
90 |
|
91 |
+
$q = "SELECT MAX(tag_order) FROM $wpdb->li_tags";
|
92 |
$tag_order = $wpdb->get_var($q);
|
93 |
$tag_order = ( $tag_order ? $tag_order + 1 : 1 );
|
94 |
$tag_slug = $this->generate_slug($tag_text);
|
113 |
function save_tag ( $tag_id, $tag_text, $tag_form_selectors, $tag_synced_lists )
|
114 |
{
|
115 |
global $wpdb;
|
|
|
116 |
|
117 |
$tag_slug = $this->generate_slug($tag_text, $tag_id);
|
118 |
|
admin/inc/class-stats-dashboard.php
CHANGED
@@ -157,7 +157,7 @@ class LI_StatsDashboard {
|
|
157 |
( SELECT MIN(pageview_source) AS pageview_source FROM $wpdb->li_pageviews WHERE lead_hashkey = lh AND pageview_session_start = 1 AND pageview_deleted = 0 ) AS lead_source,
|
158 |
( SELECT MIN(pageview_url) AS pageview_url FROM $wpdb->li_pageviews WHERE lead_hashkey = lh AND pageview_session_start = 1 AND pageview_deleted = 0 ) AS lead_origin_url
|
159 |
FROM
|
160 |
-
$wpdb->li_leads ll, li_pageviews lpv
|
161 |
WHERE
|
162 |
lead_date >= CURRENT_DATE() AND
|
163 |
ll.hashkey = lpv.lead_hashkey AND
|
157 |
( SELECT MIN(pageview_source) AS pageview_source FROM $wpdb->li_pageviews WHERE lead_hashkey = lh AND pageview_session_start = 1 AND pageview_deleted = 0 ) AS lead_source,
|
158 |
( SELECT MIN(pageview_url) AS pageview_url FROM $wpdb->li_pageviews WHERE lead_hashkey = lh AND pageview_session_start = 1 AND pageview_deleted = 0 ) AS lead_origin_url
|
159 |
FROM
|
160 |
+
$wpdb->li_leads ll, $wpdb->li_pageviews lpv
|
161 |
WHERE
|
162 |
lead_date >= CURRENT_DATE() AND
|
163 |
ll.hashkey = lpv.lead_hashkey AND
|
admin/leadin-admin.php
CHANGED
@@ -56,16 +56,12 @@ class WPLeadInAdmin {
|
|
56 |
*/
|
57 |
function __construct ( $power_ups )
|
58 |
{
|
59 |
-
//echo get_bloginfo('wpurl');
|
60 |
//=============================================
|
61 |
// Hooks & Filters
|
62 |
//=============================================
|
63 |
|
64 |
$options = get_option('leadin_options');
|
65 |
|
66 |
-
if ( is_multisite() )
|
67 |
-
$options = leadin_check_multisite_missing_options($options);
|
68 |
-
|
69 |
$this->action = $this->leadin_current_action();
|
70 |
|
71 |
// If the plugin version matches the latest version escape the update function
|
@@ -83,19 +79,28 @@ class WPLeadInAdmin {
|
|
83 |
{
|
84 |
add_action('admin_footer', array($this, 'build_contacts_chart'));
|
85 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
86 |
}
|
87 |
|
88 |
-
function leadin_update_check (
|
89 |
{
|
90 |
$options = get_option('leadin_options');
|
91 |
|
92 |
// 0.5.1 upgrade - Create active power-ups option if it doesn't exist
|
93 |
$leadin_active_power_ups = get_option('leadin_active_power_ups');
|
94 |
|
95 |
-
if (
|
96 |
{
|
97 |
$auto_activate = array(
|
98 |
-
'contacts'
|
|
|
99 |
);
|
100 |
|
101 |
update_option('leadin_active_power_ups', serialize($auto_activate));
|
@@ -104,11 +109,13 @@ class WPLeadInAdmin {
|
|
104 |
{
|
105 |
// 0.9.2 upgrade - set beta program power-up to auto-activate
|
106 |
$activated_power_ups = unserialize($leadin_active_power_ups);
|
|
|
107 |
|
108 |
// 0.9.3 bug fix for duplicate beta_program values being stored in the active power-ups array
|
109 |
if ( !in_array('beta_program', $activated_power_ups) )
|
110 |
{
|
111 |
$activated_power_ups[] = 'beta_program';
|
|
|
112 |
}
|
113 |
else
|
114 |
{
|
@@ -116,7 +123,10 @@ class WPLeadInAdmin {
|
|
116 |
$count = $tmp['beta_program'];
|
117 |
|
118 |
if ( $count > 1 )
|
|
|
119 |
$activated_power_ups = array_unique($activated_power_ups);
|
|
|
|
|
120 |
}
|
121 |
|
122 |
// 2.0.1 upgrade - [plugin_slug]_list_sync changed to [plugin_slug]_connect
|
@@ -125,6 +135,7 @@ class WPLeadInAdmin {
|
|
125 |
{
|
126 |
unset($activated_power_ups[$mailchimp_list_sync_key]);
|
127 |
$activated_power_ups[] = 'mailchimp_connect';
|
|
|
128 |
}
|
129 |
|
130 |
$constant_contact_list_sync_key = array_search('constant_contact_list_sync', $activated_power_ups);
|
@@ -132,13 +143,11 @@ class WPLeadInAdmin {
|
|
132 |
{
|
133 |
unset($activated_power_ups[$constant_contact_list_sync_key]);
|
134 |
$activated_power_ups[] = 'constant_contact_connect';
|
|
|
135 |
}
|
136 |
|
137 |
-
|
138 |
-
|
139 |
-
$activated_power_ups[] = 'contacts';
|
140 |
-
|
141 |
-
update_option('leadin_active_power_ups', serialize($activated_power_ups));
|
142 |
}
|
143 |
|
144 |
// 0.7.2 bug fix - data recovery algorithm for deleted contacts
|
@@ -147,6 +156,28 @@ class WPLeadInAdmin {
|
|
147 |
leadin_recover_contact_data();
|
148 |
}
|
149 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
150 |
// Set the database version if it doesn't exist
|
151 |
if ( isset($options['li_db_version']) )
|
152 |
{
|
@@ -180,6 +211,19 @@ class WPLeadInAdmin {
|
|
180 |
|
181 |
// Set the plugin version
|
182 |
leadin_update_option('leadin_options', 'leadin_version', LEADIN_PLUGIN_VERSION);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
183 |
}
|
184 |
|
185 |
//=============================================
|
@@ -217,10 +261,11 @@ class WPLeadInAdmin {
|
|
217 |
|
218 |
}
|
219 |
}
|
220 |
-
|
221 |
self::check_admin_action();
|
222 |
|
223 |
-
|
|
|
224 |
|
225 |
foreach ( $this->admin_power_ups as $power_up )
|
226 |
{
|
@@ -237,6 +282,10 @@ class WPLeadInAdmin {
|
|
237 |
add_submenu_page('leadin_stats', 'Tags', 'Tags', $capability, 'leadin_tags', array(&$this, 'leadin_build_tag_page'));
|
238 |
add_submenu_page('leadin_stats', 'Settings', 'Settings', 'activate_plugins', 'leadin_settings', array(&$this, 'leadin_plugin_options'));
|
239 |
add_submenu_page('leadin_stats', 'Power-ups', 'Power-ups', 'activate_plugins', 'leadin_power_ups', array(&$this, 'leadin_power_ups_page'));
|
|
|
|
|
|
|
|
|
240 |
$submenu['leadin_stats'][0][0] = 'Stats';
|
241 |
|
242 |
if ( !isset($_GET['page']) || $_GET['page'] != 'leadin_settings' )
|
@@ -249,6 +298,64 @@ class WPLeadInAdmin {
|
|
249 |
|
250 |
}
|
251 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
252 |
//=============================================
|
253 |
// Settings Page
|
254 |
//=============================================
|
@@ -277,7 +384,7 @@ class WPLeadInAdmin {
|
|
277 |
|
278 |
echo '<div id="leadin" class="li-stats wrap '. ( $wp_version < 3.8 && !is_plugin_active('mp6/mp6.php') ? 'pre-mp6' : ''). '">';
|
279 |
|
280 |
-
$this->leadin_header('Leadin Stats: ' . date('F j Y, g:ia', current_time('timestamp')), 'leadin-stats__header');
|
281 |
|
282 |
echo '<div class="leadin-stats__top-container">';
|
283 |
echo $this->leadin_postbox('leadin-stats__chart', leadin_single_plural_label(number_format($this->stats_dashboard->total_contacts_last_30_days), 'new contact', 'new contacts') . ' last 30 days', $this->leadin_build_contacts_chart_stats());
|
@@ -293,6 +400,8 @@ class WPLeadInAdmin {
|
|
293 |
echo '<div class="leadin-stats__postbox_containter">';
|
294 |
echo $this->leadin_postbox('leadin-stats__sources', 'New contact sources last 30 days', $this->leadin_build_sources_postbox());
|
295 |
echo '</div>';
|
|
|
|
|
296 |
}
|
297 |
|
298 |
|
@@ -331,11 +440,17 @@ class WPLeadInAdmin {
|
|
331 |
} // Create a comma deliniated list of synced lists for tag_synced_lists
|
332 |
else if ( strstr($name, 'email_connect_') )
|
333 |
{
|
334 |
-
|
335 |
if ( strstr($name, '_mailchimp') )
|
336 |
$synced_list = array('esp' => 'mailchimp', 'list_id' => str_replace('email_connect_mailchimp_', '', $name), 'list_name' => $value);
|
337 |
else if ( strstr($name, '_constant_contact') )
|
338 |
$synced_list = array('esp' => 'constant_contact', 'list_id' => str_replace('email_connect_constant_contact_', '', $name), 'list_name' => $value);
|
|
|
|
|
|
|
|
|
|
|
|
|
339 |
|
340 |
array_push($tag_synced_lists, $synced_list);
|
341 |
}
|
@@ -415,7 +530,12 @@ class WPLeadInAdmin {
|
|
415 |
$tagger->get_tag_details($tagger->tag_id);
|
416 |
|
417 |
echo '<a href="' . get_bloginfo('wpurl') . '/wp-admin/admin.php?page=leadin_tags">← Manage tags</a>';
|
418 |
-
|
|
|
|
|
|
|
|
|
|
|
419 |
?>
|
420 |
|
421 |
<div class="">
|
@@ -495,6 +615,8 @@ class WPLeadInAdmin {
|
|
495 |
case 'mailchimp' :
|
496 |
$esp_list_url = 'http://admin.mailchimp.com/lists/new-list/';
|
497 |
$settings_page_anchor_id = '#li_mls_api_key';
|
|
|
|
|
498 |
break;
|
499 |
|
500 |
case 'constant_contact' :
|
@@ -502,6 +624,27 @@ class WPLeadInAdmin {
|
|
502 |
$settings_page_anchor_id = '#li_cc_email';
|
503 |
break;
|
504 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
505 |
default:
|
506 |
$esp_list_url = '';
|
507 |
$settings_page_anchor_id = '';
|
@@ -511,12 +654,12 @@ class WPLeadInAdmin {
|
|
511 |
if ( ! ${'leadin_' . $power_up_slug . '_wp'}->admin->authed )
|
512 |
{
|
513 |
echo 'It looks like you haven\'t set up your ' . $esp_name_readable . ' integration yet...<br/><br/>';
|
514 |
-
echo '<a href="' . get_bloginfo('wpurl') . '/wp-admin/admin.php?page=leadin_settings' . $settings_page_anchor_id . '">
|
515 |
}
|
516 |
else if ( ${'leadin_' . $power_up_slug . '_wp'}->admin->invalid_key )
|
517 |
{
|
518 |
-
echo
|
519 |
-
echo '<p
|
520 |
}
|
521 |
else if ( count($lists) )
|
522 |
{
|
@@ -533,15 +676,18 @@ class WPLeadInAdmin {
|
|
533 |
|
534 |
if ( $synced_lists )
|
535 |
{
|
|
|
|
|
536 |
$key = leadin_array_search_deep($list_id, $synced_lists, 'list_id');
|
537 |
|
538 |
if ( isset($key) )
|
539 |
{
|
|
|
540 |
if ( $synced_lists[$key]['esp'] == $esp_name )
|
541 |
$synced = TRUE;
|
542 |
}
|
543 |
}
|
544 |
-
|
545 |
echo '<label for="' . $html_id . '">';
|
546 |
echo '<input name="' . $html_id . '" type="checkbox" id="' . $html_id . '" value="' . $list->name . '" ' . ( $synced ? 'checked' : '' ) . '>';
|
547 |
echo $list->name;
|
@@ -551,7 +697,7 @@ class WPLeadInAdmin {
|
|
551 |
else
|
552 |
{
|
553 |
echo 'It looks like you don\'t have any ' . $esp_name_readable . ' lists yet...<br/><br/>';
|
554 |
-
echo '<a href="' . $esp_list_url . '" target="_blank">Create a list on ' . $esp_url . '
|
555 |
}
|
556 |
echo '</fieldset>';
|
557 |
echo '</td>';
|
@@ -602,7 +748,7 @@ class WPLeadInAdmin {
|
|
602 |
<div class="leadin-contacts">
|
603 |
|
604 |
<?php
|
605 |
-
$this->leadin_header('Manage Leadin Tags <a href="' . get_bloginfo('wpurl') . '/wp-admin/admin.php?page=leadin_tags&action=add_tag" class="add-new-h2">Add New</a>', '');
|
606 |
?>
|
607 |
|
608 |
<div class="">
|
@@ -871,7 +1017,7 @@ class WPLeadInAdmin {
|
|
871 |
function leadin_options_section_heading ( )
|
872 |
{
|
873 |
$this->print_hidden_settings_fields();
|
874 |
-
|
875 |
if ( $this->has_leads() )
|
876 |
{
|
877 |
echo '<div class="leadin-section">';
|
@@ -885,7 +1031,7 @@ class WPLeadInAdmin {
|
|
885 |
echo '<p style="color: #f67d42; font-weight: bold;">Leadin is set up and waiting for a form submission...</p>';
|
886 |
echo '<p>Can\'t wait to see Leadin in action? Go fill out a form on your site to see your first contact.</p>';
|
887 |
echo '</div>';
|
888 |
-
}
|
889 |
}
|
890 |
|
891 |
function print_hidden_settings_fields ()
|
@@ -903,6 +1049,8 @@ class WPLeadInAdmin {
|
|
903 |
$converted_to_tags = ( isset($options['converted_to_tags']) ? $options['converted_to_tags'] : 0 );
|
904 |
$names_added_to_contacts = ( isset($options['names_added_to_contacts']) ? $options['names_added_to_contacts'] : 0 );
|
905 |
$leadin_version = ( isset($options['leadin_version']) ? $options['leadin_version'] : LEADIN_PLUGIN_VERSION );
|
|
|
|
|
906 |
|
907 |
printf(
|
908 |
'<input id="li_installed" type="hidden" name="leadin_options[li_installed]" value="%d"/>',
|
@@ -953,6 +1101,16 @@ class WPLeadInAdmin {
|
|
953 |
'<input id="leadin_version" type="hidden" name="leadin_options[leadin_version]" value="%s"/>',
|
954 |
$leadin_version
|
955 |
);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
956 |
}
|
957 |
|
958 |
function has_leads ( )
|
@@ -963,21 +1121,13 @@ class WPLeadInAdmin {
|
|
963 |
$num_contacts = $wpdb->get_var($q);
|
964 |
|
965 |
if ( $num_contacts > 0 )
|
966 |
-
|
967 |
-
return true;
|
968 |
-
}
|
969 |
else
|
970 |
-
|
971 |
-
return false;
|
972 |
-
}
|
973 |
}
|
974 |
|
975 |
function update_option_leadin_options_callback ( $old_value, $new_value )
|
976 |
{
|
977 |
-
$user_email = $new_value["li_email"];
|
978 |
-
|
979 |
-
if ( isset( $_POST['li_updates_subscription'] ) && $_POST['li_updates_subscription'] )
|
980 |
-
leadin_subscribe_user_updates();
|
981 |
}
|
982 |
|
983 |
/**
|
@@ -1004,73 +1154,90 @@ class WPLeadInAdmin {
|
|
1004 |
global $wp_version;
|
1005 |
|
1006 |
$li_options = get_option('leadin_options');
|
1007 |
-
|
1008 |
echo '<div id="leadin" class="li-onboarding wrap '. ( $wp_version < 3.8 && !is_plugin_active('mp6/mp6.php') ? 'pre-mp6' : ''). '">';
|
1009 |
|
1010 |
-
$this->leadin_header('Leadin Setup');
|
1011 |
|
1012 |
?>
|
1013 |
|
1014 |
-
<div class="oboarding-steps">
|
1015 |
-
|
1016 |
<?php if ( ! isset($_GET['activate_popup']) ) : ?>
|
1017 |
|
1018 |
<?php if ( $li_options['onboarding_step'] == 1 ) : ?>
|
1019 |
|
1020 |
-
|
1021 |
-
|
1022 |
-
|
1023 |
-
<
|
1024 |
-
|
1025 |
-
|
1026 |
-
|
1027 |
-
|
1028 |
-
|
1029 |
-
<
|
1030 |
-
|
1031 |
-
|
1032 |
-
|
1033 |
-
|
1034 |
-
|
1035 |
-
|
1036 |
-
|
1037 |
-
|
1038 |
-
|
1039 |
-
|
1040 |
-
|
1041 |
-
</
|
1042 |
</div>
|
1043 |
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1044 |
|
1045 |
<?php elseif ( $li_options['onboarding_step'] == 2 ) : ?>
|
1046 |
|
1047 |
-
|
1048 |
-
|
1049 |
-
|
1050 |
-
<
|
1051 |
-
|
1052 |
-
|
1053 |
-
|
1054 |
-
|
1055 |
-
|
1056 |
-
<
|
1057 |
-
|
1058 |
-
|
1059 |
-
|
1060 |
-
|
1061 |
-
|
1062 |
-
|
1063 |
-
|
1064 |
-
|
1065 |
-
|
1066 |
-
|
1067 |
-
|
1068 |
-
|
1069 |
-
|
1070 |
-
|
1071 |
-
|
1072 |
-
|
1073 |
-
|
|
|
|
|
|
|
|
|
1074 |
</div>
|
1075 |
|
1076 |
<?php endif; ?>
|
@@ -1099,7 +1266,10 @@ class WPLeadInAdmin {
|
|
1099 |
}
|
1100 |
|
1101 |
leadin_update_option('leadin_subscribe_options', 'li_subscribe_vex_class', $vex_class_option);
|
|
|
1102 |
}
|
|
|
|
|
1103 |
|
1104 |
// Update the onboarding settings
|
1105 |
if ( ! isset($options['onboarding_complete']) || ! $options['onboarding_complete'] )
|
@@ -1107,39 +1277,28 @@ class WPLeadInAdmin {
|
|
1107 |
leadin_update_option('leadin_options', 'onboarding_complete', 1);
|
1108 |
}
|
1109 |
?>
|
|
|
|
|
1110 |
|
1111 |
-
<
|
1112 |
-
<
|
1113 |
-
|
1114 |
-
|
1115 |
-
|
1116 |
-
|
1117 |
-
<
|
1118 |
-
|
1119 |
-
<
|
1120 |
-
|
1121 |
-
|
1122 |
-
|
1123 |
-
|
|
|
|
|
1124 |
</div>
|
1125 |
</div>
|
1126 |
|
1127 |
<?php endif; ?>
|
1128 |
-
|
1129 |
-
</div>
|
1130 |
-
|
1131 |
-
|
1132 |
-
<div class="oboarding-steps-help">
|
1133 |
-
<h4>Any questions?</h4>
|
1134 |
-
<?php if ( isset($li_options['premium']) && $li_options['premium'] ) : ?>
|
1135 |
-
<p>Send us a message and we’re happy to help you get set up.</p>
|
1136 |
-
<a class="button" href="#" onclick="return SnapEngage.startLink();">Chat with us</a>
|
1137 |
-
<?php else : ?>
|
1138 |
-
<p>Leave us a message in the WordPress support forums. We're always happy to help you get set up and can answer any questions there.</p>
|
1139 |
-
<a class="button" href="http://wordpress.org/support/plugin/leadin" target="_blank">Go to Forums</a>
|
1140 |
-
<?php endif; ?>
|
1141 |
-
</div>
|
1142 |
-
|
1143 |
|
1144 |
<?php
|
1145 |
|
@@ -1158,7 +1317,7 @@ class WPLeadInAdmin {
|
|
1158 |
|
1159 |
echo '<div id="leadin" class="li-settings wrap '. ( $wp_version < 3.8 && !is_plugin_active('mp6/mp6.php') ? 'pre-mp6' : ''). '">';
|
1160 |
|
1161 |
-
$this->leadin_header('Leadin Settings');
|
1162 |
|
1163 |
?>
|
1164 |
<div class="leadin-settings__content">
|
@@ -1170,9 +1329,11 @@ class WPLeadInAdmin {
|
|
1170 |
?>
|
1171 |
</form>
|
1172 |
</div>
|
1173 |
-
|
1174 |
-
<
|
1175 |
-
|
|
|
|
|
1176 |
<?php
|
1177 |
|
1178 |
$this->leadin_footer();
|
@@ -1190,42 +1351,45 @@ class WPLeadInAdmin {
|
|
1190 |
{
|
1191 |
$new_input = array();
|
1192 |
|
1193 |
-
if( isset(
|
1194 |
$new_input['li_email'] = sanitize_text_field( $input['li_email'] );
|
1195 |
|
1196 |
-
if( isset(
|
1197 |
$new_input['li_installed'] = $input['li_installed'];
|
1198 |
|
1199 |
-
if( isset(
|
1200 |
$new_input['li_db_version'] = $input['li_db_version'];
|
1201 |
|
1202 |
-
if( isset(
|
1203 |
$new_input['onboarding_step'] = ( $input['onboarding_step'] + 1 );
|
1204 |
|
1205 |
-
if( isset(
|
1206 |
$new_input['onboarding_complete'] = $input['onboarding_complete'];
|
1207 |
|
1208 |
-
if( isset(
|
1209 |
$new_input['ignore_settings_popup'] = $input['ignore_settings_popup'];
|
1210 |
|
1211 |
-
if( isset(
|
1212 |
$new_input['data_recovered'] = $input['data_recovered'];
|
1213 |
|
1214 |
-
if( isset(
|
1215 |
$new_input['converted_to_tags'] = $input['converted_to_tags'];
|
1216 |
|
1217 |
-
if( isset(
|
1218 |
$new_input['names_added_to_contacts'] = $input['names_added_to_contacts'];
|
1219 |
|
1220 |
-
if( isset(
|
1221 |
$new_input['delete_flags_fixed'] = $input['delete_flags_fixed'];
|
1222 |
|
1223 |
-
if( isset(
|
1224 |
$new_input['leadin_version'] = $input['leadin_version'];
|
1225 |
|
1226 |
-
if( isset(
|
1227 |
$new_input['li_updates_subscription'] = $input['li_updates_subscription'];
|
1228 |
|
|
|
|
|
|
|
1229 |
$user_roles = get_editable_roles();
|
1230 |
if ( count($user_roles) )
|
1231 |
{
|
@@ -1327,7 +1491,7 @@ class WPLeadInAdmin {
|
|
1327 |
|
1328 |
echo '<div id="leadin" class="li-settings wrap '. ( $wp_version < 3.8 && !is_plugin_active('mp6/mp6.php') ? 'pre-mp6' : ''). '">';
|
1329 |
|
1330 |
-
$this->leadin_header('Leadin Power-ups');
|
1331 |
|
1332 |
?>
|
1333 |
|
@@ -1343,7 +1507,7 @@ class WPLeadInAdmin {
|
|
1343 |
continue;
|
1344 |
?>
|
1345 |
|
1346 |
-
<?php if ( $power_up_count ==
|
1347 |
<!-- static content stats power-up - not a real powerup and this is a hack to put it second in the order -->
|
1348 |
<li class="powerup activated">
|
1349 |
<div class="img-containter">
|
@@ -1366,23 +1530,37 @@ class WPLeadInAdmin {
|
|
1366 |
</div>
|
1367 |
<h2><?php echo $power_up->power_up_name; ?></h2>
|
1368 |
<p><?php echo $power_up->description; ?></p>
|
|
|
1369 |
<?php if ( $power_up->activated ) : ?>
|
1370 |
<?php if ( ! $power_up->permanent ) : ?>
|
|
|
1371 |
<a href="<?php echo get_bloginfo('wpurl') . '/wp-admin/admin.php?page=leadin_power_ups&leadin_action=deactivate&power_up=' . $power_up->slug; ?>" class="button button-secondary button-large">Deactivate</a>
|
1372 |
<?php endif; ?>
|
1373 |
<?php else : ?>
|
1374 |
-
<?php
|
1375 |
-
|
|
|
|
|
|
|
1376 |
<?php else : ?>
|
1377 |
-
|
1378 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
1379 |
<?php endif; ?>
|
|
|
|
|
1380 |
|
1381 |
-
|
1382 |
-
|
1383 |
-
<a href="<?php echo get_bloginfo('wpurl') . '/wp-admin/admin.php?page=
|
1384 |
<a href="<?php echo get_bloginfo('wpurl') . '/wp-admin/admin.php?page=leadin_settings'; ?>" class="button button-secondary button-large">Configure</a>
|
1385 |
<?php else : ?>
|
|
|
1386 |
<a href="<?php echo get_bloginfo('wpurl') . '/wp-admin/admin.php?page=leadin_' . $power_up->menu_link; ?>" class="button button-secondary button-large">Configure</a>
|
1387 |
<?php endif; ?>
|
1388 |
<?php endif; ?>
|
@@ -1404,9 +1582,8 @@ class WPLeadInAdmin {
|
|
1404 |
<img src="<?php echo LEADIN_PATH; ?>/images/powerup-icon-vip@2x.png" height="80px" width="80px">
|
1405 |
</div>
|
1406 |
<h2>Leadin VIP Program</h2>
|
1407 |
-
|
1408 |
<p>Exclusive features and offers for consultants and agencies.</p>
|
1409 |
-
|
1410 |
<a href="http://leadin.com/vip" target="_blank" class="button button-primary button-large">Become a VIP</a>
|
1411 |
</li>
|
1412 |
|
@@ -1434,6 +1611,7 @@ class WPLeadInAdmin {
|
|
1434 |
|
1435 |
WPLeadIn::activate_power_up( $power_up, FALSE );
|
1436 |
//ob_end_clean();
|
|
|
1437 |
|
1438 |
if ( isset($_GET['redirect_to']) )
|
1439 |
wp_redirect($_GET['redirect_to']);
|
@@ -1448,6 +1626,7 @@ class WPLeadInAdmin {
|
|
1448 |
$power_up = stripslashes( $_GET['power_up'] );
|
1449 |
|
1450 |
WPLeadIn::deactivate_power_up( $power_up, FALSE );
|
|
|
1451 |
wp_redirect(get_bloginfo('wpurl') . '/wp-admin/admin.php?page=leadin_power_ups');
|
1452 |
exit;
|
1453 |
|
@@ -1502,27 +1681,97 @@ class WPLeadInAdmin {
|
|
1502 |
*
|
1503 |
* @param string
|
1504 |
*/
|
1505 |
-
function leadin_header ( $page_title = '', $css_class = '' )
|
1506 |
{
|
|
|
|
|
1507 |
?>
|
1508 |
-
|
1509 |
-
<?php if (
|
1510 |
-
|
1511 |
-
|
1512 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1513 |
<?php endif; ?>
|
1514 |
|
1515 |
<?php screen_icon('leadin'); ?>
|
1516 |
-
|
1517 |
<h2 class="<?php echo $css_class ?>"><?php echo $page_title; ?></h2>
|
1518 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1519 |
<?php $options = get_option('leadin_options'); ?>
|
1520 |
|
1521 |
<?php if ( isset($_GET['settings-updated']) && $options['onboarding_complete'] ) : ?>
|
1522 |
<div id="message" class="updated">
|
1523 |
<p><strong><?php _e('Settings saved.') ?></strong></p>
|
1524 |
</div>
|
1525 |
-
<?php endif;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1526 |
}
|
1527 |
|
1528 |
function leadin_footer ()
|
@@ -1531,37 +1780,17 @@ class WPLeadInAdmin {
|
|
1531 |
|
1532 |
?>
|
1533 |
<div id="leadin-footer">
|
1534 |
-
<p class="support">
|
1535 |
-
<a href="http://leadin.com">Leadin</a> <?php echo LEADIN_PLUGIN_VERSION?>
|
1536 |
-
|
1537 |
-
<span style="padding: 0px 5px;">|</span>Need help? <a href="#" onclick="return SnapEngage.startLink();">Contact us</a>
|
1538 |
-
<?php else : ?>
|
1539 |
-
<span style="padding: 0px 5px;">|</span><a href="https://wordpress.org/support/plugin/leadin" target="_blank">Support forums</a>
|
1540 |
-
<?php endif; ?>
|
1541 |
<span style="padding: 0px 5px;">|</span><a href="http://leadin.com/dev-updates/">Get product & security updates</a>
|
1542 |
<span style="padding: 0px 5px;">|</span><a href="http://wordpress.org/support/view/plugin-reviews/leadin?rate=5#postform">Leave us a review</a>
|
1543 |
</p>
|
1544 |
-
<p class="sharing"><a href="https://twitter.com/leadinapp" class="twitter-follow-button" data-show-count="false">Follow @leadinapp</a>
|
1545 |
|
|
|
1546 |
<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+'://platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js,fjs);}}(document, 'script', 'twitter-wjs');</script></p>
|
1547 |
</div>
|
1548 |
-
|
1549 |
-
<script type="text/javascript">
|
1550 |
-
(function() {
|
1551 |
-
var se = document.createElement('script'); se.type = 'text/javascript'; se.async = true;
|
1552 |
-
se.src = '//commondatastorage.googleapis.com/code.snapengage.com/js/b7667cce-a26d-4440-a716-7c4b9f086705.js';
|
1553 |
-
var done = false;
|
1554 |
-
se.onload = se.onreadystatechange = function() {
|
1555 |
-
if (!done&&(!this.readyState||this.readyState==='loaded'||this.readyState==='complete')) {
|
1556 |
-
done = true;
|
1557 |
-
// Place your SnapEngage JS API code below
|
1558 |
-
// SnapEngage.allowChatSound(true); // Example JS API: Enable sounds for Visitors.
|
1559 |
-
}
|
1560 |
-
};
|
1561 |
-
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(se, s);
|
1562 |
-
})();
|
1563 |
-
</script>
|
1564 |
-
<!-- end SnapEngage code -->
|
1565 |
<?php
|
1566 |
}
|
1567 |
|
56 |
*/
|
57 |
function __construct ( $power_ups )
|
58 |
{
|
|
|
59 |
//=============================================
|
60 |
// Hooks & Filters
|
61 |
//=============================================
|
62 |
|
63 |
$options = get_option('leadin_options');
|
64 |
|
|
|
|
|
|
|
65 |
$this->action = $this->leadin_current_action();
|
66 |
|
67 |
// If the plugin version matches the latest version escape the update function
|
79 |
{
|
80 |
add_action('admin_footer', array($this, 'build_contacts_chart'));
|
81 |
}
|
82 |
+
|
83 |
+
$updater_type = '';
|
84 |
+
|
85 |
+
if ( isset($options['pro']) && $options['pro'] )
|
86 |
+
$updater_type = 'pro';
|
87 |
+
|
88 |
+
if ( $updater_type )
|
89 |
+
$li_wp_updater = new WPLeadInUpdater($updater_type);
|
90 |
}
|
91 |
|
92 |
+
function leadin_update_check ()
|
93 |
{
|
94 |
$options = get_option('leadin_options');
|
95 |
|
96 |
// 0.5.1 upgrade - Create active power-ups option if it doesn't exist
|
97 |
$leadin_active_power_ups = get_option('leadin_active_power_ups');
|
98 |
|
99 |
+
if ( ! $leadin_active_power_ups )
|
100 |
{
|
101 |
$auto_activate = array(
|
102 |
+
'contacts',
|
103 |
+
'lookups'
|
104 |
);
|
105 |
|
106 |
update_option('leadin_active_power_ups', serialize($auto_activate));
|
109 |
{
|
110 |
// 0.9.2 upgrade - set beta program power-up to auto-activate
|
111 |
$activated_power_ups = unserialize($leadin_active_power_ups);
|
112 |
+
$update_active_power_ups = FALSE;
|
113 |
|
114 |
// 0.9.3 bug fix for duplicate beta_program values being stored in the active power-ups array
|
115 |
if ( !in_array('beta_program', $activated_power_ups) )
|
116 |
{
|
117 |
$activated_power_ups[] = 'beta_program';
|
118 |
+
$update_active_power_ups = TRUE;
|
119 |
}
|
120 |
else
|
121 |
{
|
123 |
$count = $tmp['beta_program'];
|
124 |
|
125 |
if ( $count > 1 )
|
126 |
+
{
|
127 |
$activated_power_ups = array_unique($activated_power_ups);
|
128 |
+
$update_active_power_ups = TRUE;
|
129 |
+
}
|
130 |
}
|
131 |
|
132 |
// 2.0.1 upgrade - [plugin_slug]_list_sync changed to [plugin_slug]_connect
|
135 |
{
|
136 |
unset($activated_power_ups[$mailchimp_list_sync_key]);
|
137 |
$activated_power_ups[] = 'mailchimp_connect';
|
138 |
+
$update_active_power_ups = TRUE;
|
139 |
}
|
140 |
|
141 |
$constant_contact_list_sync_key = array_search('constant_contact_list_sync', $activated_power_ups);
|
143 |
{
|
144 |
unset($activated_power_ups[$constant_contact_list_sync_key]);
|
145 |
$activated_power_ups[] = 'constant_contact_connect';
|
146 |
+
$update_active_power_ups = TRUE;
|
147 |
}
|
148 |
|
149 |
+
if ( $update_active_power_ups )
|
150 |
+
update_option('leadin_active_power_ups', serialize($activated_power_ups));
|
|
|
|
|
|
|
151 |
}
|
152 |
|
153 |
// 0.7.2 bug fix - data recovery algorithm for deleted contacts
|
156 |
leadin_recover_contact_data();
|
157 |
}
|
158 |
|
159 |
+
// Check if the pro flag is not set and version > 3.0 and if yes, set the pro flag. This resets the Pro flag and takes care of the settings bug from Pro 3.1.3
|
160 |
+
if ( ! isset($options['pro']) )
|
161 |
+
{
|
162 |
+
if ( isset($options['leadin_version']) && version_compare($options['leadin_version'], '3.0.0', '>=') && version_compare($options['leadin_version'], '3.1.4', '<') )
|
163 |
+
{
|
164 |
+
leadin_update_option('leadin_options', 'pro', 1);
|
165 |
+
|
166 |
+
// Check to make sure the lookups power-up is activate for Pro users
|
167 |
+
if ( ! in_array('lookups', $activated_power_ups) )
|
168 |
+
WPLeadIn::activate_power_up('lookups', FALSE);
|
169 |
+
}
|
170 |
+
}
|
171 |
+
else
|
172 |
+
{
|
173 |
+
if ( $options['pro'] )
|
174 |
+
{
|
175 |
+
// Check to make sure the lookups power-up is activate for Pro users
|
176 |
+
if ( ! in_array('lookups', $activated_power_ups) )
|
177 |
+
WPLeadIn::activate_power_up('lookups', FALSE);
|
178 |
+
}
|
179 |
+
}
|
180 |
+
|
181 |
// Set the database version if it doesn't exist
|
182 |
if ( isset($options['li_db_version']) )
|
183 |
{
|
211 |
|
212 |
// Set the plugin version
|
213 |
leadin_update_option('leadin_options', 'leadin_version', LEADIN_PLUGIN_VERSION);
|
214 |
+
|
215 |
+
if ( leadin_check_pro_user() )
|
216 |
+
{
|
217 |
+
$leadin_user = leadin_get_current_user();
|
218 |
+
leadin_set_user_properties(array(
|
219 |
+
'$wp-url' => get_bloginfo('wpurl'),
|
220 |
+
'$wp-version' => $leadin_user['wp_version'],
|
221 |
+
'$li-version' => $leadin_user['li_version']
|
222 |
+
));
|
223 |
+
}
|
224 |
+
|
225 |
+
// Catch all for installs that get their options nixed for whatever reason
|
226 |
+
leadin_check_missing_options($options);
|
227 |
}
|
228 |
|
229 |
//=============================================
|
261 |
|
262 |
}
|
263 |
}
|
264 |
+
|
265 |
self::check_admin_action();
|
266 |
|
267 |
+
$leadin_icon = ($wp_version < 3.8 && !is_plugin_active('mp6/mp6.php') ? LEADIN_PATH . '/images/leadin-icon-32x32.png' : 'data:image/svg+xml;base64,' . base64_encode(file_get_contents(LEADIN_PATH . '/images/leadin-svg-icon.svg')));
|
268 |
+
add_menu_page('Leadin', 'Leadin', $capability, 'leadin_stats', array($this, 'leadin_build_stats_page'), $leadin_icon , '25.100713');
|
269 |
|
270 |
foreach ( $this->admin_power_ups as $power_up )
|
271 |
{
|
282 |
add_submenu_page('leadin_stats', 'Tags', 'Tags', $capability, 'leadin_tags', array(&$this, 'leadin_build_tag_page'));
|
283 |
add_submenu_page('leadin_stats', 'Settings', 'Settings', 'activate_plugins', 'leadin_settings', array(&$this, 'leadin_plugin_options'));
|
284 |
add_submenu_page('leadin_stats', 'Power-ups', 'Power-ups', 'activate_plugins', 'leadin_power_ups', array(&$this, 'leadin_power_ups_page'));
|
285 |
+
|
286 |
+
if ( ! leadin_check_pro_user() )
|
287 |
+
add_submenu_page('leadin_stats', 'Pro Upgrade', 'Pro Upgrade', 'activate_plugins', 'leadin_pro_upgrade', array(&$this, 'leadin_pro_upgrade_page'));
|
288 |
+
|
289 |
$submenu['leadin_stats'][0][0] = 'Stats';
|
290 |
|
291 |
if ( !isset($_GET['page']) || $_GET['page'] != 'leadin_settings' )
|
298 |
|
299 |
}
|
300 |
|
301 |
+
function leadin_pro_upgrade_page ()
|
302 |
+
{
|
303 |
+
global $wp_version;
|
304 |
+
|
305 |
+
echo '<div id="leadin" class=" wrap '. ( $wp_version < 3.8 && !is_plugin_active('mp6/mp6.php') ? 'pre-mp6' : ''). '">';
|
306 |
+
|
307 |
+
$this->leadin_header('Upgrade to Leadin Pro for free');
|
308 |
+
|
309 |
+
?>
|
310 |
+
<p>Leadin Pro is the best version of Leadin to date. </p>
|
311 |
+
<div class="compare">
|
312 |
+
<div class="title">
|
313 |
+
<h2>Leadin (current version)</h2>
|
314 |
+
</div>
|
315 |
+
<div class="content">
|
316 |
+
<ul class="features">
|
317 |
+
<li>Contacts Tracking</li>
|
318 |
+
<p>Learn more about your visitors.</p>
|
319 |
+
<li>Contacts Analytics</li>
|
320 |
+
<p>Find out what content and traffic sources convert the best.</p>
|
321 |
+
<li>Popup Form</li>
|
322 |
+
<p>Convert more visitors to contacts, faster.</p>
|
323 |
+
<li>Email Connectors</li>
|
324 |
+
<p>Push contacts to MailChimp, Constant Contact, Campaign Monitor, GetResponse and AWeber without replacing any of your forms.</p>
|
325 |
+
</ul>
|
326 |
+
</div>
|
327 |
+
</div>
|
328 |
+
<div class="compare">
|
329 |
+
<div class="title teal">
|
330 |
+
<h2>Leadin Pro</h2>
|
331 |
+
</div>
|
332 |
+
<div class="content">
|
333 |
+
<p>All the features you're enjoying now, plus:</p>
|
334 |
+
<ul class="features plus">
|
335 |
+
<li>Contact Enrichment</li>
|
336 |
+
<p>In addition to seeing the pages your contacts have visited, you'll now be able to see publicly available information about your contacts and their businesses. Info like social accounts, job role, and company location all in your contact reports. </p>
|
337 |
+
</ul>
|
338 |
+
<?php
|
339 |
+
echo '<p id="agree-pp-error" style="display: none; border-left: 4px solid #dd3d36; padding-left: 12px; margin-bottom: 25px;">Before you can unlock the awesomeness of Leadin Pro, we need you to agree to our Privacy Policy, because lawyers.</p>';
|
340 |
+
echo '<label for="agree-pp">';
|
341 |
+
echo '<input type="checkbox" id="agree-pp" name="agree-pp"/>';
|
342 |
+
echo 'I agree to Leadin\'s <a href="http://leadin.com/legal/privacy-policy" target="_blank">Privacy Policy</a></label>';
|
343 |
+
|
344 |
+
echo '<a id="pro-upgrade-button" class="big-button--orange">Upgrade to Leadin Pro</a>';
|
345 |
+
?>
|
346 |
+
</div>
|
347 |
+
</div>
|
348 |
+
|
349 |
+
|
350 |
+
<?php
|
351 |
+
|
352 |
+
$this->leadin_footer();
|
353 |
+
|
354 |
+
//end wrap
|
355 |
+
echo '</div>';
|
356 |
+
|
357 |
+
}
|
358 |
+
|
359 |
//=============================================
|
360 |
// Settings Page
|
361 |
//=============================================
|
384 |
|
385 |
echo '<div id="leadin" class="li-stats wrap '. ( $wp_version < 3.8 && !is_plugin_active('mp6/mp6.php') ? 'pre-mp6' : ''). '">';
|
386 |
|
387 |
+
$this->leadin_header('Leadin Stats: ' . date('F j Y, g:ia', current_time('timestamp')), 'leadin-stats__header', 'Loaded Stats Page');
|
388 |
|
389 |
echo '<div class="leadin-stats__top-container">';
|
390 |
echo $this->leadin_postbox('leadin-stats__chart', leadin_single_plural_label(number_format($this->stats_dashboard->total_contacts_last_30_days), 'new contact', 'new contacts') . ' last 30 days', $this->leadin_build_contacts_chart_stats());
|
400 |
echo '<div class="leadin-stats__postbox_containter">';
|
401 |
echo $this->leadin_postbox('leadin-stats__sources', 'New contact sources last 30 days', $this->leadin_build_sources_postbox());
|
402 |
echo '</div>';
|
403 |
+
|
404 |
+
$this->leadin_footer();
|
405 |
}
|
406 |
|
407 |
|
440 |
} // Create a comma deliniated list of synced lists for tag_synced_lists
|
441 |
else if ( strstr($name, 'email_connect_') )
|
442 |
{
|
443 |
+
// Name comes through as email_connect_espslug_listid, so replace the beginning of each one with corresponding esp slug, which leaves just the list id
|
444 |
if ( strstr($name, '_mailchimp') )
|
445 |
$synced_list = array('esp' => 'mailchimp', 'list_id' => str_replace('email_connect_mailchimp_', '', $name), 'list_name' => $value);
|
446 |
else if ( strstr($name, '_constant_contact') )
|
447 |
$synced_list = array('esp' => 'constant_contact', 'list_id' => str_replace('email_connect_constant_contact_', '', $name), 'list_name' => $value);
|
448 |
+
else if ( strstr($name, '_aweber') )
|
449 |
+
$synced_list = array('esp' => 'aweber', 'list_id' => str_replace('email_connect_aweber_', '', $name), 'list_name' => $value);
|
450 |
+
else if ( strstr($name, '_campaign_monitor') )
|
451 |
+
$synced_list = array('esp' => 'campaign_monitor', 'list_id' => str_replace('email_connect_campaign_monitor_', '', $name), 'list_name' => $value);
|
452 |
+
else if ( strstr($name, '_getresponse') )
|
453 |
+
$synced_list = array('esp' => 'getresponse', 'list_id' => str_replace('email_connect_getresponse_', '', $name), 'list_name' => $value);
|
454 |
|
455 |
array_push($tag_synced_lists, $synced_list);
|
456 |
}
|
530 |
$tagger->get_tag_details($tagger->tag_id);
|
531 |
|
532 |
echo '<a href="' . get_bloginfo('wpurl') . '/wp-admin/admin.php?page=leadin_tags">← Manage tags</a>';
|
533 |
+
|
534 |
+
if ( $this->action == 'edit_tag' ) {
|
535 |
+
$this->leadin_header('Edit a tag', 'leadin-contacts__header', 'Loaded Tag Editor');
|
536 |
+
} else {
|
537 |
+
$this->leadin_header('Add a tag', 'leadin-contacts__header', 'Loaded Add Tag');
|
538 |
+
}
|
539 |
?>
|
540 |
|
541 |
<div class="">
|
615 |
case 'mailchimp' :
|
616 |
$esp_list_url = 'http://admin.mailchimp.com/lists/new-list/';
|
617 |
$settings_page_anchor_id = '#li_mls_api_key';
|
618 |
+
$invalid_key_message = 'It looks like your ' . $esp_name_readable . ' API key is invalid...<br/><br/>';
|
619 |
+
$invalid_key_link = '<a target="_blank" href="http://kb.mailchimp.com/accounts/management/about-api-keys#Find-or-Generate-Your-API-Key">Get your API key</a> from <a href="http://admin.mailchimp.com/account/api/" target="_blank">MailChimp.com</a>';
|
620 |
break;
|
621 |
|
622 |
case 'constant_contact' :
|
624 |
$settings_page_anchor_id = '#li_cc_email';
|
625 |
break;
|
626 |
|
627 |
+
case 'aweber' :
|
628 |
+
$esp_list_url = 'https://www.aweber.com/users/newlist#about';
|
629 |
+
$settings_page_anchor_id = '#li_ac_auth_code';
|
630 |
+
$invalid_key_message = 'It looks like your ' . $esp_name_readable . ' Authorization Code is invalid...<br/><br/>';
|
631 |
+
$invalid_key_link = '<a target="_blank" href="https://help.aweber.com/hc/en-us/articles/204031226-How-Do-I-Authorize-an-App-">Get your Authorization Code</a> from <a href="https://auth.aweber.com/1.0/oauth/authorize_app/156b03fb" target="_blank">AWeber.com</a>';
|
632 |
+
break;
|
633 |
+
|
634 |
+
case 'campaign_monitor' :
|
635 |
+
$esp_list_url = 'https://login.createsend.com/l';
|
636 |
+
$settings_page_anchor_id = '#li_cm_api_key';
|
637 |
+
$invalid_key_message = 'It looks like your ' . $esp_name_readable . ' API key is invalid...<br/><br/>';
|
638 |
+
$invalid_key_link = '<a target="_blank" href="http://help.campaignmonitor.com/topic.aspx?t=206">Get your API key</a> from <a href="https://login.createsend.com/l" target="_blank">CampaignMonitor.com</a>';
|
639 |
+
break;
|
640 |
+
|
641 |
+
case 'getresponse' :
|
642 |
+
$esp_list_url = 'https://app.getresponse.com/create_campaign.html';
|
643 |
+
$settings_page_anchor_id = '#li_gr_api_key';
|
644 |
+
$invalid_key_message = 'It looks like your ' . $esp_name_readable . ' API key is invalid...<br/><br/>';
|
645 |
+
$invalid_key_link = '<a target="_blank" href="http://support.getresponse.com/faq/where-i-find-api-key">Get your API key</a> from <a href="https://app.getresponse.com/account.html#api" target="_blank">GetResponse.com</a>';
|
646 |
+
break;
|
647 |
+
|
648 |
default:
|
649 |
$esp_list_url = '';
|
650 |
$settings_page_anchor_id = '';
|
654 |
if ( ! ${'leadin_' . $power_up_slug . '_wp'}->admin->authed )
|
655 |
{
|
656 |
echo 'It looks like you haven\'t set up your ' . $esp_name_readable . ' integration yet...<br/><br/>';
|
657 |
+
echo '<a href="' . get_bloginfo('wpurl') . '/wp-admin/admin.php?page=leadin_settings' . $settings_page_anchor_id . '">Set up your ' . $esp_name_readable . ' integration</a>';
|
658 |
}
|
659 |
else if ( ${'leadin_' . $power_up_slug . '_wp'}->admin->invalid_key )
|
660 |
{
|
661 |
+
echo $invalid_key_message;
|
662 |
+
echo '<p>' . $invalid_key_link . ' then try copying and pasting it again in <a href="' . get_bloginfo('wpurl') . '/wp-admin/admin.php?page=leadin_settings' . $settings_page_anchor_id . '">Leadin → Settings</a></p>';
|
663 |
}
|
664 |
else if ( count($lists) )
|
665 |
{
|
676 |
|
677 |
if ( $synced_lists )
|
678 |
{
|
679 |
+
|
680 |
+
// Search the synched lists for this tag for the list_id
|
681 |
$key = leadin_array_search_deep($list_id, $synced_lists, 'list_id');
|
682 |
|
683 |
if ( isset($key) )
|
684 |
{
|
685 |
+
// Double check that the list is synced with the actual ESP
|
686 |
if ( $synced_lists[$key]['esp'] == $esp_name )
|
687 |
$synced = TRUE;
|
688 |
}
|
689 |
}
|
690 |
+
|
691 |
echo '<label for="' . $html_id . '">';
|
692 |
echo '<input name="' . $html_id . '" type="checkbox" id="' . $html_id . '" value="' . $list->name . '" ' . ( $synced ? 'checked' : '' ) . '>';
|
693 |
echo $list->name;
|
697 |
else
|
698 |
{
|
699 |
echo 'It looks like you don\'t have any ' . $esp_name_readable . ' lists yet...<br/><br/>';
|
700 |
+
echo '<a href="' . $esp_list_url . '" target="_blank">Create a list on ' . $esp_url . '</a>';
|
701 |
}
|
702 |
echo '</fieldset>';
|
703 |
echo '</td>';
|
748 |
<div class="leadin-contacts">
|
749 |
|
750 |
<?php
|
751 |
+
$this->leadin_header('Manage Leadin Tags <a href="' . get_bloginfo('wpurl') . '/wp-admin/admin.php?page=leadin_tags&action=add_tag" class="add-new-h2">Add New</a>', 'leadin-contacts__header', 'Loaded Tag List');
|
752 |
?>
|
753 |
|
754 |
<div class="">
|
1017 |
function leadin_options_section_heading ( )
|
1018 |
{
|
1019 |
$this->print_hidden_settings_fields();
|
1020 |
+
|
1021 |
if ( $this->has_leads() )
|
1022 |
{
|
1023 |
echo '<div class="leadin-section">';
|
1031 |
echo '<p style="color: #f67d42; font-weight: bold;">Leadin is set up and waiting for a form submission...</p>';
|
1032 |
echo '<p>Can\'t wait to see Leadin in action? Go fill out a form on your site to see your first contact.</p>';
|
1033 |
echo '</div>';
|
1034 |
+
}
|
1035 |
}
|
1036 |
|
1037 |
function print_hidden_settings_fields ()
|
1049 |
$converted_to_tags = ( isset($options['converted_to_tags']) ? $options['converted_to_tags'] : 0 );
|
1050 |
$names_added_to_contacts = ( isset($options['names_added_to_contacts']) ? $options['names_added_to_contacts'] : 0 );
|
1051 |
$leadin_version = ( isset($options['leadin_version']) ? $options['leadin_version'] : LEADIN_PLUGIN_VERSION );
|
1052 |
+
$pro = ( isset($options['pro']) ? $options['pro'] : 0 );
|
1053 |
+
$li_updates_subscription = ( isset($options['li_updates_subscription']) ? $options['li_updates_subscription'] : 0 );
|
1054 |
|
1055 |
printf(
|
1056 |
'<input id="li_installed" type="hidden" name="leadin_options[li_installed]" value="%d"/>',
|
1101 |
'<input id="leadin_version" type="hidden" name="leadin_options[leadin_version]" value="%s"/>',
|
1102 |
$leadin_version
|
1103 |
);
|
1104 |
+
|
1105 |
+
printf(
|
1106 |
+
'<input id="pro" type="hidden" name="leadin_options[pro]" value="%d"/>',
|
1107 |
+
$pro
|
1108 |
+
);
|
1109 |
+
|
1110 |
+
printf(
|
1111 |
+
'<input id="li_updates_subscription" type="hidden" name="leadin_options[li_updates_subscription]" value="%d"/>',
|
1112 |
+
$li_updates_subscription
|
1113 |
+
);
|
1114 |
}
|
1115 |
|
1116 |
function has_leads ( )
|
1121 |
$num_contacts = $wpdb->get_var($q);
|
1122 |
|
1123 |
if ( $num_contacts > 0 )
|
1124 |
+
return TRUE;
|
|
|
|
|
1125 |
else
|
1126 |
+
return FALSE;
|
|
|
|
|
1127 |
}
|
1128 |
|
1129 |
function update_option_leadin_options_callback ( $old_value, $new_value )
|
1130 |
{
|
|
|
|
|
|
|
|
|
1131 |
}
|
1132 |
|
1133 |
/**
|
1154 |
global $wp_version;
|
1155 |
|
1156 |
$li_options = get_option('leadin_options');
|
1157 |
+
|
1158 |
echo '<div id="leadin" class="li-onboarding wrap '. ( $wp_version < 3.8 && !is_plugin_active('mp6/mp6.php') ? 'pre-mp6' : ''). '">';
|
1159 |
|
|
|
1160 |
|
1161 |
?>
|
1162 |
|
|
|
|
|
1163 |
<?php if ( ! isset($_GET['activate_popup']) ) : ?>
|
1164 |
|
1165 |
<?php if ( $li_options['onboarding_step'] == 1 ) : ?>
|
1166 |
|
1167 |
+
<?php $this->leadin_header('Leadin Setup', 'li_setup', 'Onboarding Step 2 - Get Contact Reports'); ?>
|
1168 |
+
|
1169 |
+
<div class="oboarding-steps">
|
1170 |
+
<ol class="oboarding-steps-names">
|
1171 |
+
<li class="oboarding-step-name completed">Activate Leadin</li>
|
1172 |
+
<li class="oboarding-step-name active">Get Contact Reports</li>
|
1173 |
+
<li class="oboarding-step-name">Grow Your Contacts List</li>
|
1174 |
+
</ol>
|
1175 |
+
<div class="oboarding-step">
|
1176 |
+
<h2 class="oboarding-step-title">Where should we send your contact reports?</h2>
|
1177 |
+
<div class="oboarding-step-content">
|
1178 |
+
<p class="oboarding-step-description">Leadin will help you get to know your website visitors by sending you a report including traffic source and pageview history each time a visitor fills out a form.</p>
|
1179 |
+
<form id="li-onboarding-form" method="post" action="options.php">
|
1180 |
+
<div>
|
1181 |
+
<?php settings_fields('leadin_settings_options'); ?>
|
1182 |
+
<?php $this->li_email_callback(); ?>
|
1183 |
+
</div>
|
1184 |
+
<?php $this->print_hidden_settings_fields(); ?>
|
1185 |
+
<input type="hidden" id="next_onboarding_step" name="next_onboarding_step" value="2">
|
1186 |
+
<input type="submit" name="submit" id="submit" class="button button-primary button-big" value="<?php esc_attr_e('Save Email'); ?>">
|
1187 |
+
</form>
|
1188 |
+
</div>
|
1189 |
</div>
|
1190 |
</div>
|
1191 |
+
<!-- Facebook Conversion Code for Installed plugin -->
|
1192 |
+
<script>(function() {
|
1193 |
+
var _fbq = window._fbq || (window._fbq = []);
|
1194 |
+
if (!_fbq.loaded) {
|
1195 |
+
var fbds = document.createElement('script');
|
1196 |
+
fbds.async = true;
|
1197 |
+
fbds.src = '//connect.facebook.net/en_US/fbds.js';
|
1198 |
+
var s = document.getElementsByTagName('script')[0];
|
1199 |
+
s.parentNode.insertBefore(fbds, s);
|
1200 |
+
_fbq.loaded = true;
|
1201 |
+
}
|
1202 |
+
})();
|
1203 |
+
window._fbq = window._fbq || [];
|
1204 |
+
window._fbq.push(['track', '6024677413664', {'value':'0.00','currency':'USD'}]);
|
1205 |
+
</script>
|
1206 |
+
<noscript><img height="1" width="1" alt="" style="display:none" src="https://www.facebook.com/tr?ev=6024677413664&cd[value]=0.00&cd[currency]=USD&noscript=1" /></noscript>
|
1207 |
|
1208 |
<?php elseif ( $li_options['onboarding_step'] == 2 ) : ?>
|
1209 |
|
1210 |
+
<?php $this->leadin_header('Leadin Setup', 'li_setup', 'Onboarding Step 3 - Grow Your Contact List'); ?>
|
1211 |
+
|
1212 |
+
<div class="oboarding-steps">
|
1213 |
+
<ol class="oboarding-steps-names">
|
1214 |
+
<li class="oboarding-step-name completed">Activate Leadin</li>
|
1215 |
+
<li class="oboarding-step-name completed">Get Contact Reports</li>
|
1216 |
+
<li class="oboarding-step-name active">Grow Your Contacts List</li>
|
1217 |
+
</ol>
|
1218 |
+
<div class="oboarding-step">
|
1219 |
+
<h2 class="oboarding-step-title">Grow your contacts list with our popup form<br><small>and start converting visitors on <?php echo get_bloginfo('wpurl') ?></small></h2>
|
1220 |
+
<form id="li-onboarding-form" method="post" action="options.php">
|
1221 |
+
<?php $this->print_hidden_settings_fields(); ?>
|
1222 |
+
<div class="popup-options">
|
1223 |
+
<label class="popup-option">
|
1224 |
+
<input type="radio" name="popup-position" value="slide_in" checked="checked" >Slide in
|
1225 |
+
<img src="<?php echo LEADIN_PATH ?>/images/popup-bottom.png">
|
1226 |
+
</label>
|
1227 |
+
<label class="popup-option">
|
1228 |
+
<input type="radio" name="popup-position" value="popup">Popup
|
1229 |
+
<img src="<?php echo LEADIN_PATH ?>/images/popup-over.png">
|
1230 |
+
</label>
|
1231 |
+
<label class="popup-option">
|
1232 |
+
<input type="radio" name="popup-position" value="top">Top
|
1233 |
+
<img src="<?php echo LEADIN_PATH ?>/images/popup-top.png">
|
1234 |
+
</label>
|
1235 |
+
</div>
|
1236 |
+
<input type="hidden" id="next_onboarding_step" name="next_onboarding_step" value="3">
|
1237 |
+
<a id="btn-activate-subscribe" href="<?php echo get_admin_url() .'admin.php?page=leadin_settings&leadin_action=activate&power_up=subscribe_widget&redirect_to=' . get_admin_url() . urlencode('admin.php?page=leadin_settings&activate_popup=true&popup_position=slide_in'); ?>" class="button button-primary button-big"><?php esc_attr_e('Activate the popup form');?></a>
|
1238 |
+
<p><a href="<?php echo get_admin_url() .'admin.php?page=leadin_settings&activate_popup=false'; ?>">Don't activate the popup form right now</a></p>
|
1239 |
+
</form>
|
1240 |
+
</div>
|
1241 |
</div>
|
1242 |
|
1243 |
<?php endif; ?>
|
1266 |
}
|
1267 |
|
1268 |
leadin_update_option('leadin_subscribe_options', 'li_subscribe_vex_class', $vex_class_option);
|
1269 |
+
leadin_track_plugin_activity('Onboarding Popup Activated');
|
1270 |
}
|
1271 |
+
else
|
1272 |
+
leadin_track_plugin_activity('Onboarding Popup Not Activated');
|
1273 |
|
1274 |
// Update the onboarding settings
|
1275 |
if ( ! isset($options['onboarding_complete']) || ! $options['onboarding_complete'] )
|
1277 |
leadin_update_option('leadin_options', 'onboarding_complete', 1);
|
1278 |
}
|
1279 |
?>
|
1280 |
+
|
1281 |
+
<?php $this->leadin_header('Leadin Setup', 'li_setup', 'Onboarding Complete'); ?>
|
1282 |
|
1283 |
+
<div class="oboarding-steps">
|
1284 |
+
<ol class="oboarding-steps-names">
|
1285 |
+
<li class="oboarding-step-name completed">Activate Leadin</li>
|
1286 |
+
<li class="oboarding-step-name completed">Get Contact Reports</li>
|
1287 |
+
<li class="oboarding-step-name completed">Grow Your Contacts List</li>
|
1288 |
+
</ol>
|
1289 |
+
<div class="oboarding-step">
|
1290 |
+
<h2 class="oboarding-step-title">Setup Complete!<br>Leadin is waiting for your first form submission.</h2>
|
1291 |
+
<div class="oboarding-step-content">
|
1292 |
+
<p class="oboarding-step-description">Leadin is set up and waiting for a form submission. Once Leadin detects a form submission, a new contact will be added to your contacts list. We recommend filling out a form on your site to test that Leadin is working correctly.</p>
|
1293 |
+
<form id="li-onboarding-form" method="post" action="options.php">
|
1294 |
+
<?php $this->print_hidden_settings_fields(); ?>
|
1295 |
+
<a href="<?php echo get_admin_url() . 'admin.php?page=leadin_settings'; ?>" class="button button-primary button-big"><?php esc_attr_e('Complete Setup'); ?></a>
|
1296 |
+
</form>
|
1297 |
+
</div>
|
1298 |
</div>
|
1299 |
</div>
|
1300 |
|
1301 |
<?php endif; ?>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1302 |
|
1303 |
<?php
|
1304 |
|
1317 |
|
1318 |
echo '<div id="leadin" class="li-settings wrap '. ( $wp_version < 3.8 && !is_plugin_active('mp6/mp6.php') ? 'pre-mp6' : ''). '">';
|
1319 |
|
1320 |
+
$this->leadin_header('Leadin Settings', 'li_settings', 'Loaded Settings Page');
|
1321 |
|
1322 |
?>
|
1323 |
<div class="leadin-settings__content">
|
1329 |
?>
|
1330 |
</form>
|
1331 |
</div>
|
1332 |
+
<?php if ( ! leadin_check_pro_user() ) : ?>
|
1333 |
+
<div class="leadin-settings__sidebar">
|
1334 |
+
<a href="<?php echo admin_url(); ?>admin.php?page=leadin_pro_upgrade"><img class="pro-upgrade-cta" src="<?php echo LEADIN_PATH; ?>/images/pro-upgrade-cta.png"></a>
|
1335 |
+
</div>
|
1336 |
+
<?php endif; ?>
|
1337 |
<?php
|
1338 |
|
1339 |
$this->leadin_footer();
|
1351 |
{
|
1352 |
$new_input = array();
|
1353 |
|
1354 |
+
if ( isset($input['li_email']) )
|
1355 |
$new_input['li_email'] = sanitize_text_field( $input['li_email'] );
|
1356 |
|
1357 |
+
if ( isset($input['li_installed']) )
|
1358 |
$new_input['li_installed'] = $input['li_installed'];
|
1359 |
|
1360 |
+
if ( isset($input['li_db_version']) )
|
1361 |
$new_input['li_db_version'] = $input['li_db_version'];
|
1362 |
|
1363 |
+
if ( isset($input['onboarding_step']) )
|
1364 |
$new_input['onboarding_step'] = ( $input['onboarding_step'] + 1 );
|
1365 |
|
1366 |
+
if ( isset($input['onboarding_complete']) )
|
1367 |
$new_input['onboarding_complete'] = $input['onboarding_complete'];
|
1368 |
|
1369 |
+
if ( isset($input['ignore_settings_popup']) )
|
1370 |
$new_input['ignore_settings_popup'] = $input['ignore_settings_popup'];
|
1371 |
|
1372 |
+
if ( isset($input['data_recovered']) )
|
1373 |
$new_input['data_recovered'] = $input['data_recovered'];
|
1374 |
|
1375 |
+
if ( isset($input['converted_to_tags']) )
|
1376 |
$new_input['converted_to_tags'] = $input['converted_to_tags'];
|
1377 |
|
1378 |
+
if ( isset($input['names_added_to_contacts']) )
|
1379 |
$new_input['names_added_to_contacts'] = $input['names_added_to_contacts'];
|
1380 |
|
1381 |
+
if ( isset($input['delete_flags_fixed']) )
|
1382 |
$new_input['delete_flags_fixed'] = $input['delete_flags_fixed'];
|
1383 |
|
1384 |
+
if ( isset($input['leadin_version']) )
|
1385 |
$new_input['leadin_version'] = $input['leadin_version'];
|
1386 |
|
1387 |
+
if ( isset($input['li_updates_subscription']) )
|
1388 |
$new_input['li_updates_subscription'] = $input['li_updates_subscription'];
|
1389 |
|
1390 |
+
if ( isset($input['pro']) )
|
1391 |
+
$new_input['pro'] = $input['pro'];
|
1392 |
+
|
1393 |
$user_roles = get_editable_roles();
|
1394 |
if ( count($user_roles) )
|
1395 |
{
|
1491 |
|
1492 |
echo '<div id="leadin" class="li-settings wrap '. ( $wp_version < 3.8 && !is_plugin_active('mp6/mp6.php') ? 'pre-mp6' : ''). '">';
|
1493 |
|
1494 |
+
$this->leadin_header('Leadin Power-ups', 'li_powerups', 'Loaded Power-ups Page');
|
1495 |
|
1496 |
?>
|
1497 |
|
1507 |
continue;
|
1508 |
?>
|
1509 |
|
1510 |
+
<?php if ( $power_up_count == 2 ) : ?>
|
1511 |
<!-- static content stats power-up - not a real powerup and this is a hack to put it second in the order -->
|
1512 |
<li class="powerup activated">
|
1513 |
<div class="img-containter">
|
1530 |
</div>
|
1531 |
<h2><?php echo $power_up->power_up_name; ?></h2>
|
1532 |
<p><?php echo $power_up->description; ?></p>
|
1533 |
+
|
1534 |
<?php if ( $power_up->activated ) : ?>
|
1535 |
<?php if ( ! $power_up->permanent ) : ?>
|
1536 |
+
<?php // SHOW DEACTIVATE POWER-UP BUTTON ?>
|
1537 |
<a href="<?php echo get_bloginfo('wpurl') . '/wp-admin/admin.php?page=leadin_power_ups&leadin_action=deactivate&power_up=' . $power_up->slug; ?>" class="button button-secondary button-large">Deactivate</a>
|
1538 |
<?php endif; ?>
|
1539 |
<?php else : ?>
|
1540 |
+
<?php // SHOW DEACTIVATE POWER-UP BUTTON ?>
|
1541 |
+
<?php if ( $power_up->pro_only ) : ?>
|
1542 |
+
<?php if ( ! leadin_check_pro_user() ) : ?>
|
1543 |
+
<a href="<?php echo admin_url(); ?>admin.php?page=leadin_pro_upgrade">Upgrade to Pro</a> for free to unlock
|
1544 |
+
<?php endif; ?>
|
1545 |
<?php else : ?>
|
1546 |
+
<?php if ( ( $power_up->curl_required && function_exists('curl_init') && function_exists('curl_setopt') ) || ! $power_up->curl_required ) : ?>
|
1547 |
+
<?php // SHOW ACTIVATE POWER-UP BUTTON ?>
|
1548 |
+
<a href="<?php echo get_bloginfo('wpurl') . '/wp-admin/admin.php?page=leadin_power_ups&leadin_action=activate&power_up=' . $power_up->slug; ?>" class="button button-primary button-large">Activate</a>
|
1549 |
+
<?php else : ?>
|
1550 |
+
<?php // SHOW CURL REQUIRED MESSAGE ?>
|
1551 |
+
<p><a href="http://stackoverflow.com/questions/2939820/how-to-enable-curl-installed-ubuntu-lamp-stack" target="_blank">Install cURL</a> to use this power-up.</p>
|
1552 |
+
<?php endif; ?>
|
1553 |
+
<?php endif; ?>
|
1554 |
<?php endif; ?>
|
1555 |
+
|
1556 |
+
<?php if ( $power_up->activated || ( $power_up->permanent && $power_up->activated ) ) : ?>
|
1557 |
|
1558 |
+
<?php if ( $power_up->slug == 'contacts' || $power_up->slug == 'lookups' ) : ?>
|
1559 |
+
<?php // SHOW VIEW CONTACTS / CONFIGURE BUTTON ?>
|
1560 |
+
<a href="<?php echo get_bloginfo('wpurl') . '/wp-admin/admin.php?page=leadin_contacts'; ?>" class="button button-secondary button-large">View Contacts</a>
|
1561 |
<a href="<?php echo get_bloginfo('wpurl') . '/wp-admin/admin.php?page=leadin_settings'; ?>" class="button button-secondary button-large">Configure</a>
|
1562 |
<?php else : ?>
|
1563 |
+
<?php // SHOW CONFIGURE BUTTON ?>
|
1564 |
<a href="<?php echo get_bloginfo('wpurl') . '/wp-admin/admin.php?page=leadin_' . $power_up->menu_link; ?>" class="button button-secondary button-large">Configure</a>
|
1565 |
<?php endif; ?>
|
1566 |
<?php endif; ?>
|
1582 |
<img src="<?php echo LEADIN_PATH; ?>/images/powerup-icon-vip@2x.png" height="80px" width="80px">
|
1583 |
</div>
|
1584 |
<h2>Leadin VIP Program</h2>
|
|
|
1585 |
<p>Exclusive features and offers for consultants and agencies.</p>
|
1586 |
+
|
1587 |
<a href="http://leadin.com/vip" target="_blank" class="button button-primary button-large">Become a VIP</a>
|
1588 |
</li>
|
1589 |
|
1611 |
|
1612 |
WPLeadIn::activate_power_up( $power_up, FALSE );
|
1613 |
//ob_end_clean();
|
1614 |
+
leadin_track_plugin_activity($power_up . " power-up activated");
|
1615 |
|
1616 |
if ( isset($_GET['redirect_to']) )
|
1617 |
wp_redirect($_GET['redirect_to']);
|
1626 |
$power_up = stripslashes( $_GET['power_up'] );
|
1627 |
|
1628 |
WPLeadIn::deactivate_power_up( $power_up, FALSE );
|
1629 |
+
leadin_track_plugin_activity($power_up . " power-up deactivated");
|
1630 |
wp_redirect(get_bloginfo('wpurl') . '/wp-admin/admin.php?page=leadin_power_ups');
|
1631 |
exit;
|
1632 |
|
1681 |
*
|
1682 |
* @param string
|
1683 |
*/
|
1684 |
+
function leadin_header ( $page_title = '', $css_class = '', $event_name = '' )
|
1685 |
{
|
1686 |
+
$options = get_option('li_options');
|
1687 |
+
$leadin_user = leadin_get_current_user();
|
1688 |
?>
|
1689 |
+
|
1690 |
+
<?php if ( leadin_check_pro_user() ) : ?>
|
1691 |
+
<?php // @TODO - we should really move this logic to the leadin-admin.js file... ?>
|
1692 |
+
<script type="text/javascript">
|
1693 |
+
!function(){var analytics=window.analytics=window.analytics||[];if(!analytics.initialize)if(analytics.invoked)window.console&&console.error&&console.error("Segment snippet included twice.");else{analytics.invoked=!0;analytics.methods=["trackSubmit","trackClick","trackLink","trackForm","pageview","identify","group","track","ready","alias","page","once","off","on"];analytics.factory=function(t){return function(){var e=Array.prototype.slice.call(arguments);e.unshift(t);analytics.push(e);return analytics}};for(var t=0;t<analytics.methods.length;t++){var e=analytics.methods[t];analytics[e]=analytics.factory(e)}analytics.load=function(t){var e=document.createElement("script");e.type="text/javascript";e.async=!0;e.src=("https:"===document.location.protocol?"https://":"http://")+"cdn.segment.com/analytics.js/v1/"+t+"/analytics.min.js";var n=document.getElementsByTagName("script")[0];n.parentNode.insertBefore(e,n)};analytics.SNIPPET_VERSION="3.0.1";
|
1694 |
+
analytics.load("<?php echo SEGMENT_WRITE_KEY ?>");
|
1695 |
+
analytics.identify("<?php echo $leadin_user['user_id']; ?>", {
|
1696 |
+
"name" : "<?php echo $leadin_user['alias']; ?>",
|
1697 |
+
"email" : "<?php echo $leadin_user['email']; ?>",
|
1698 |
+
"wp-url" : "<?php echo $leadin_user['wp_url']; ?>",
|
1699 |
+
"wp-version" : "<?php echo $leadin_user['wp_version']; ?>",
|
1700 |
+
"li-version" : "<?php echo $leadin_user['li_version']; ?>",
|
1701 |
+
"li-source" : "<?php echo LEADIN_SOURCE; ?>",
|
1702 |
+
"createdAt" : "<?php echo date('Y-m-d H:i:s'); ?>",
|
1703 |
+
"website" : "<?php echo $leadin_user['wp_url']; ?>",
|
1704 |
+
"company" : "<?php echo $leadin_user['wp_url']; ?>",
|
1705 |
+
"contacts" : "<?php echo $leadin_user['total_contacts']; ?>",
|
1706 |
+
"utm_source" : "<?php echo $leadin_user['utm_source']; ?>",
|
1707 |
+
"utm_medium" : "<?php echo $leadin_user['utm_medium']; ?>",
|
1708 |
+
"utm_term" : "<?php echo $leadin_user['utm_term']; ?>",
|
1709 |
+
"utm_content" : "<?php echo $leadin_user['utm_content']; ?>",
|
1710 |
+
"utm_campaign" : "<?php echo $leadin_user['utm_campaign']; ?>",
|
1711 |
+
"referral_source" : "<?php echo $leadin_user['referral_source']; ?>"
|
1712 |
+
});
|
1713 |
+
|
1714 |
+
jQuery(document).ready( function ( $ ) {
|
1715 |
+
<?php if ( $event_name == 'Loaded Contact List Page' ) : ?>
|
1716 |
+
var num_tags = jQuery('.icon-tag').length;
|
1717 |
+
analytics.track(<?php echo "'$event_name', { num_tags: num_tags }"; ?>);
|
1718 |
+
<?php else : ?>
|
1719 |
+
analytics.track(<?php echo "'$event_name'"; ?>);
|
1720 |
+
<?php endif; ?>
|
1721 |
+
});
|
1722 |
+
}}();
|
1723 |
+
</script>
|
1724 |
<?php endif; ?>
|
1725 |
|
1726 |
<?php screen_icon('leadin'); ?>
|
1727 |
+
|
1728 |
<h2 class="<?php echo $css_class ?>"><?php echo $page_title; ?></h2>
|
1729 |
|
1730 |
+
<?php if ( $options['onboarding_complete'] ) : ?>
|
1731 |
+
<?php if ( $this->has_leads() == FALSE ) : ?>
|
1732 |
+
<div id="message" class="updated">
|
1733 |
+
<p>Leadin is set up and waiting for a form submission... Need help? <a href="http://wordpress.org/support/plugin/leadin">Contact Us</a>.</p>
|
1734 |
+
</div>
|
1735 |
+
<?php endif; ?>
|
1736 |
+
<?php endif; ?>
|
1737 |
+
|
1738 |
<?php $options = get_option('leadin_options'); ?>
|
1739 |
|
1740 |
<?php if ( isset($_GET['settings-updated']) && $options['onboarding_complete'] ) : ?>
|
1741 |
<div id="message" class="updated">
|
1742 |
<p><strong><?php _e('Settings saved.') ?></strong></p>
|
1743 |
</div>
|
1744 |
+
<?php endif; ?>
|
1745 |
+
<?php if ( isset($options['onboarding_complete']) && $options['onboarding_complete'] && ! isset($_COOKIE['ignore_social_share']) ) : ?>
|
1746 |
+
<?php if ( leadin_check_first_pageview_data() ) : ?>
|
1747 |
+
<div class="dialog-bottom-right">
|
1748 |
+
<h1>Hey, do you like Leadin?</h1>
|
1749 |
+
<a href="javscript:void(0);" id="close-share" class="close"></a>
|
1750 |
+
<p>Looks like you've been using Leadin for at least 30 days. Want to help support us by spreading the word?</p>
|
1751 |
+
<p>We'd love it if you could tell your friends about us or leave us a review on WordPress.org.</p>
|
1752 |
+
<a class="big-button--share fb" href="https://www.facebook.com/sharer/sharer.php?u=http://leadin.com/facebook-share" target="_blank"></a>
|
1753 |
+
<a class="big-button--share tw" href="https://twitter.com/home?status=I've%20been%20using%20%40LeadinApp%20to%20track%20visitors%20on%20my%20Wordpress%20site.%20Try%20it%20for%20free!%20http://leadin.com/twitter-share" target="_blank"></a>
|
1754 |
+
<a class="big-button--share wp" href="https://wordpress.org/support/view/plugin-reviews/leadin?rate=5#postform" target="_blank"></a>
|
1755 |
+
</div>
|
1756 |
+
<script type="text/javascript">
|
1757 |
+
jQuery(document).ready(function($){
|
1758 |
+
var BR = $(".dialog-bottom-right");
|
1759 |
+
var close = $(".close");
|
1760 |
+
BR.animate({
|
1761 |
+
"bottom" : 0
|
1762 |
+
},
|
1763 |
+
1000);
|
1764 |
+
close.click(function(){
|
1765 |
+
BR.animate({
|
1766 |
+
"bottom" : -400
|
1767 |
+
},
|
1768 |
+
1000);
|
1769 |
+
});
|
1770 |
+
});
|
1771 |
+
</script>
|
1772 |
+
<?php endif; ?>
|
1773 |
+
<?php endif; ?>
|
1774 |
+
<?php
|
1775 |
}
|
1776 |
|
1777 |
function leadin_footer ()
|
1780 |
|
1781 |
?>
|
1782 |
<div id="leadin-footer">
|
1783 |
+
<p class="support">
|
1784 |
+
<a href="http://leadin.com">Leadin</a> <?php echo LEADIN_PLUGIN_VERSION; ?>
|
1785 |
+
<span style="padding: 0px 5px;">|</span><a href="http://support.leadin.com" target="_blank">Support Docs</a>
|
|
|
|
|
|
|
|
|
1786 |
<span style="padding: 0px 5px;">|</span><a href="http://leadin.com/dev-updates/">Get product & security updates</a>
|
1787 |
<span style="padding: 0px 5px;">|</span><a href="http://wordpress.org/support/view/plugin-reviews/leadin?rate=5#postform">Leave us a review</a>
|
1788 |
</p>
|
|
|
1789 |
|
1790 |
+
<p class="sharing"><a href="https://twitter.com/leadinapp" class="twitter-follow-button" data-show-count="false">Follow @leadinapp</a><p>
|
1791 |
<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+'://platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js,fjs);}}(document, 'script', 'twitter-wjs');</script></p>
|
1792 |
</div>
|
1793 |
+
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1794 |
<?php
|
1795 |
}
|
1796 |
|
assets/css/build/leadin-admin.css
CHANGED
@@ -1 +1 @@
|
|
1 |
-
#leadin label{cursor:default}#leadin .col-wrap{padding:0}#leadin .col-left .col-wrap{padding-right:10px}#leadin .metabox-holder{*zoom:1}#leadin .metabox-holder:after{content:"";display:table;clear:both}#wp-admin-bar-leadin-admin-menu img{height:16px;width:16px;opacity:0.6}@media (min-width: 1200px){#leadin{*zoom:1;max-width:1420px;max-width:88.75rem;padding-left:20px;padding-left:1.25rem;padding-right:20px;padding-right:1.25rem;margin-left:auto;margin-right:auto;margin:10px 20px 0 0;padding:0}#leadin:after{content:"";display:table;clear:both}#leadin *{box-sizing:border-box}}#li_analytics-meta .li-analytics-link{float:left}#li_analytics-meta .li-analytics-link .li-analytics__face{height:35px;width:35px;margin-right:5px;margin-bottom:5px}#li_analytics-meta .hidden_face{display:none}#li_analytics-meta .show-all-faces-container{clear:both}.leadin-postbox,.powerup-list .powerup{background-color:#fff;border:1px solid #e5e5e5;-moz-box-shadow:0 1px 1px rgba(0,0,0,0.04);-webkit-box-shadow:0 1px 1px rgba(0,0,0,0.04);box-shadow:0 1px 1px rgba(0,0,0,0.04)}.leadin-postbox__header{margin:0;padding:8px 12px;font-size:14px;border-bottom:1px solid #eee}.leadin-postbox__content{margin:11px 0;padding:0 12px;*zoom:1}.leadin-postbox__content:after{content:"";display:table;clear:both}.leadin-postbox__table{margin:0;width:100%}.leadin-postbox__table th{padding:6px 0;text-align:left;text-transform:uppercase;letter-spacing:0.05em}.leadin-postbox__table td{padding:6px 0}.leadin-postbox__table tr,.leadin-postbox__table td,.leadin-postbox__table th{vertical-align:middle !important}.leadin-dynamic-avatar_0{background-color:#F88E4B}.leadin-dynamic-avatar_1{background-color:#64AADA}.leadin-dynamic-avatar_2{background-color:#64C2B6}.leadin-dynamic-avatar_3{background-color:#CF7BAA}.leadin-dynamic-avatar_4{background-color:#E7C24B}.leadin-dynamic-avatar_5{background-color:#9387DA}.leadin-dynamic-avatar_6{background-color:#D6DD99}.leadin-dynamic-avatar_7{background-color:#FF4C4C}.leadin-dynamic-avatar_8{background-color:#99583D}.leadin-dynamic-avatar_9{background-color:#54CC14}@font-face{font-family:"icomoon";src:url("../../fonts/icomoon.eot?-lejfm6");src:url("../../fonts/icomoon.eot?#iefix-lejfm6") format("embedded-opentype"),url("../../fonts/icomoon.woff?-lejfm6") format("woff"),url("../../fonts/icomoon.ttf?-lejfm6") format("truetype"),url("../../fonts/icomoon.svg?-lejfm6#icomoon") format("svg");font-weight:normal;font-style:normal}.icon,.icon-profile,.icon-tag,.icon-tags,.icon-envelope,.icon-user,.icon-cog,.icon-bars,.icon-lab,.icon-bulb,.icon-mover{font-family:"icomoon";speak:none;font-style:normal;font-weight:normal;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.icon-profile:before{content:""}.icon-tag:before{content:""}.icon-tags:before{content:""}.icon-envelope:before{content:""}.icon-user:before{content:""}.icon-cog:before{content:""}.icon-bars:before{content:""}.icon-lab:before{content:""}.icon-bulb:before{content:""}.icon-mover:before{content:""}#leadin-footer{*zoom:1;clear:both;margin-top:48px;color:#999;border-top:1px solid #dedede}#leadin-footer:after{content:"";display:table;clear:both}#leadin-footer .support .sharing{height:18px;text-align:left}@media screen and (min-width: 500px){#leadin-footer .support,#leadin-footer .version,#leadin-footer .sharing{width:50%;float:left}#leadin-footer .sharing{text-align:right}}.button-big{padding:6px 36px !important;font-size:14px !important;height:auto !important}.oboarding-steps-names{*zoom:1;margin:0}.oboarding-steps-names:after{content:"";display:table;clear:both}.oboarding-step-name{float:left;margin:0;padding-bottom:24px;list-style:decimal inside none;font-size:18px;color:#bbb}.oboarding-step-name.active{color:#1F7D71;background-image:url(../../../images/triangle.png);background-position:bottom center;background-repeat:no-repeat}.oboarding-step-name.completed{list-style-image:url(../../../images/checkmark.png)}.oboarding-step-name+.oboarding-step-name{margin-left:72px}.oboarding-steps{margin:18px 0}@media (min-width: 1200px){.oboarding-steps{width:66.19718%;float:left;margin-right:1.40845%}}.oboarding-step-content{margin:0 auto;max-width:500px}.oboarding-step-content .description{margin:12px 0;display:block;display:none}.oboarding-step{text-align:center;display:block;padding:36px;background-color:#D3EEEB;border:2px solid #2a9;-moz-border-radius:5px;-webkit-border-radius:5px;border-radius:5px;color:#1F7D71}.oboarding-step .form-table th{display:none}.oboarding-step .form-table td{width:auto;display:block}.oboarding-step .form-table input{width:100%;font-size:16px;line-height:1.5;padding:7px 10px;display:block}.oboarding-step .oboarding-step-title,.oboarding-step .oboarding-step-description{color:#1F7D71;padding:0;margin-bottom:36px}.oboarding-step .button-primary{margin-top:36px}.oboarding-step .oboarding-step-description{font-size:16px;text-align:left}.oboarding-step .popup-option{width:31%;float:left;text-align:left;cursor:pointer !important}.oboarding-step .popup-option img{max-width:100%;margin-top:6px;-moz-box-shadow:0 1px 2px rgba(0,0,0,0.15);-webkit-box-shadow:0 1px 2px rgba(0,0,0,0.15);box-shadow:0 1px 2px rgba(0,0,0,0.15);-moz-border-radius:6px;-webkit-border-radius:6px;border-radius:6px}.oboarding-step .popup-option:hover img{-moz-box-shadow:0 2px 4px rgba(0,0,0,0.25);-webkit-box-shadow:0 2px 4px rgba(0,0,0,0.25);box-shadow:0 2px 4px rgba(0,0,0,0.25)}.oboarding-step .popup-option input{margin-right:8px !important}.oboarding-step .popup-option input:checked ~ img{border:2px solid #2ea2cc}.oboarding-step .popup-option+.popup-option{margin-left:3%}.oboarding-step .popup-options{*zoom:1}.oboarding-step .popup-options:after{content:"";display:table;clear:both}.oboarding-steps-help{margin-top:24px;color:#999}@media (min-width: 1200px){.oboarding-steps-help{width:15.49296%;float:left;margin-right:1.40845%;margin-top:60px}}@media (min-width: 1200px){.leadin-settings__content{width:74.64789%;float:left;margin-right:1.40845%}.leadin-settings__sidebar{width:23.94366%;float:right;margin-right:0}}.li-settings h3{border-left:1px solid #e5e5e5;border-right:1px solid #e5e5e5;border-top:1px solid #e5e5e5;border-bottom:1px solid #e5e5e5;margin-bottom:0px;background:#fff;padding:8px 12px;font-size:15px}.li-settings .form-table{margin-top:0px;border-left:1px solid #e5e5e5;border-right:1px solid #e5e5e5;border-bottom:1px solid #e5e5e5;background-color:#fff;-moz-box-shadow:0 1px 1px rgba(0,0,0,0.04);-webkit-box-shadow:0 1px 1px rgba(0,0,0,0.04);box-shadow:0 1px 1px rgba(0,0,0,0.04)}.li-settings .form-table th{padding-left:12px}.li-settings .leadin-section{background-color:#fff;border-left:1px solid #e5e5e5;border-right:1px solid #e5e5e5;font-size:14px;padding:15px 12px 5px 12px}.li-settings .leadin-section p{margin:0;padding:0}.li-settings.pre-mp6 h3{font-family:Georgia}.li-settings.pre-mp6 select,.li-settings.pre-mp6 input{font-family:sans-serif;font-size:12px}.li-settings.pre-mp6 .form-table,.li-settings.pre-mp6 .leadin-section,.li-settings.pre-mp6 h3{background-color:#f9f9f9 !important}.li-settings.pre-mp6 .form-table{-moz-border-radius-bottomleft:3px;-webkit-border-bottom-left-radius:3px;border-bottom-left-radius:3px;-moz-border-radius-bottomright:3px;-webkit-border-bottom-right-radius:3px;border-bottom-right-radius:3px}.li-settings.pre-mp6 h3{background-color:#f9f9f9 !important;-moz-border-radius-topleft:3px;-webkit-border-top-left-radius:3px;border-top-left-radius:3px;-moz-border-radius-topright:3px;-webkit-border-top-right-radius:3px;border-top-right-radius:3px}.li-settings.pre-mp6 .leadin-section{font-size:12px;padding-left:6px}.li-settings.pre-mp6 h3{padding-left:6px;font-weight:normal;color:#464646;text-shadow:#fff 0px 1px 0px}.li-settings.pre-mp6 label{font-size:12px}.li-settings.pre-mp6 input[type="checkbox"],.li-settings.pre-mp6 input[type="radio"]{margin-right:2px}#icon-leadin{background:url("../../images/leadin-icon-32x32.png") top center no-repeat}.help-notification{background:#d9edf7;border:1px solid #bce8f1;padding:10px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.toplevel_page_leadin_stats .wp-menu-image img{width:16px;height:16px}.leadin-contact-avatar{margin-right:10px;float:left}.power-up-settings-icon{padding-right:10px;float:left;max-height:20px;margin-top:-1px}.dashicons{margin-right:10px;float:left;margin-top:-1px}tr.synced-list-row td.synced-list-cell{padding:3px 0px 10px 0px}tr.synced-list-row td.synced-list-cell .icon-tag{font-size:12px}tr.synced-list-row span.synced-list-arrow{padding:0px 10px}tr.synced-list-row td.synced-list-edit{padding:3px 0px 10px 20px}.leadin-settings__sidebar .pro-upgrade-cta{max-width:100%}.leadin-contacts .button{transition:background-color 0.2s}@media (min-width: 1200px){.leadin-contacts__nav{width:15.49296%;float:left;margin-right:1.40845%;margin-top:30px}.leadin-contacts__content{width:83.09859%;float:right;margin-right:0;margin-bottom:18px;margin-top:30px}.leadin-contacts__export-form{width:83.09859%;float:left;margin-right:1.40845%;padding-left:16.90141%;margin-bottom:18px}}.leadin-contacts__search{float:right;padding:10px 0;padding-bottom:9px}.leadin-contacts__type-picker{margin:0 0 30px;*zoom:1}.leadin-contacts__type-picker:after{content:"";display:table;clear:both}.leadin-contacts__type-picker li{margin:0;padding:0 1em 0 0;float:left}@media (min-width: 1200px){.leadin-contacts__type-picker li{float:none;padding:0}.leadin-contacts__type-picker li+li{padding:18px 0 0}}.leadin-contacts__type-picker li a{display:block;line-height:24px;font-weight:400;font-size:16px;text-decoration:none}.leadin-contacts__type-picker li a.current{font-weight:bold}.leadin-contacts__type-picker li a.current,.leadin-contacts__type-picker li a:hover,.leadin-contacts__type-picker li a:active{color:#F67D42}.leadin-contacts__type-picker li a .icon-tag,.leadin-contacts__type-picker li a .icon-user{padding-right:1em;font-size:0.85em}.leadin-contacts__tags-header{margin:30px 0 18px;font-size:14px;text-transform:uppercase;letter-spacing:0.1em;color:#999}.leadin-contacts__filter-text{margin:0 0 18px}.leadin-contacts__filter-count{color:#F67D42}#clear-filter{font-size:0.8em;margin-left:10px}.leadin-contacts__table table th#source{width:20%}.leadin-contacts__table table th#visits,.leadin-contacts__table table th#submissions{width:8%}.leadin-contacts__table table th#status,.leadin-contacts__table table th#last_visit,.leadin-contacts__table table th#date,.leadin-contacts__table table th#pageviews{width:10%}.leadin-contacts__table table th,.leadin-contacts__table table td{display:none}.leadin-contacts__table table th:nth-child(-n+3),.leadin-contacts__table table td:nth-child(-n+3){display:table-cell}@media (min-width: 1200px){.leadin-contacts__table table th,.leadin-contacts__table table td{display:table-cell}}.leadin-contacts.pre-mp6 .table_search{float:right;padding:12px 0;padding-bottom:11px}.leadin-contacts.pre-mp6 table{background-color:#fff;border-color:#dedede}.leadin-contacts.pre-mp6 table tr.alternate{background-color:#fff}.leadin-contacts.pre-mp6 table th,.leadin-contacts.pre-mp6 table td{border-top:0;padding:12px 6px 11px}.leadin-contacts.pre-mp6 table th a,.leadin-contacts.pre-mp6 table td a{padding:0}.leadin-contacts.pre-mp6 table th[scope="col"]{background:#eee;font-family:sans-serif;font-size:12px;text-shadow:none}.leadin-contacts.pre-mp6 table td{border-color:#dedede;line-height:18px;font-size:14px}.leadin-contacts.pre-mp6 table td .row-actions{float:left}#leadin .contact-header-wrap{*zoom:1;padding:18px 0 24px}#leadin .contact-header-wrap:after{content:"";display:table;clear:both}#leadin .contact-header-wrap .contact-header-avatar,#leadin .contact-header-wrap .contact-header-info{float:left}#leadin .contact-header-info{padding-left:15px}#leadin .contact-name{line-height:30px;padding:0;margin:0}#leadin .contact-tags{margin-top:15px}#leadin .contact-tag{padding:4px 10px;color:#fff;background-color:#F67D42;text-decoration:none;font-weight:600;text-transform:uppercase;letter-spacing:0.1em;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px}#leadin .contact-tag:hover{opacity:0.9}#leadin .contact-tag+.contact-tag,#leadin .contact-tag+.contact-edit-tags{margin-left:10px}#leadin .contact-tag .icon-tag{padding-right:10px}#leadin .contact-info h3{margin:0}#leadin .contact-info label{font-weight:bold;line-height:1;cursor:default}#leadin .leadin-meta-section+.leadin-meta-section{margin-top:24px}#leadin .leadin-meta-table{width:100%;text-align:left}#leadin .leadin-meta-table th{color:#666;padding-bottom:6px}#leadin .leain-meta-header,#leadin .contact-history .session-date{margin:0 0 12px;text-transform:uppercase;letter-spacing:0.05em;color:#444}#leadin .leadin-premium-tag:after{content:"Pro";margin-left:10px;font-size:10px;color:#fff;background-color:#93C054;padding:2px 6px;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px}#leadin .contact-history{margin-left:20px}@media (min-width: 1200px){#leadin .contact-history{padding-left:20px;border-left:2px solid #dedede}}#leadin .contact-history .sessions{margin:0}#leadin .contact-history .session+.session{margin-top:30px}#leadin .contact-history .session-date{position:relative}@media (min-width: 1200px){#leadin .contact-history .session-date:before{content:"•";font-size:32px;line-height:0;height:31px;width:31px;position:absolute;left:-27px;top:9px;color:#dedede}}#leadin .contact-history .session-time-range{color:#999;font-weight:400}#leadin .contact-history .events{background-color:#fff;border:1px solid #dedede;-moz-box-shadow:0 1px 1px rgba(0,0,0,0.04);-webkit-box-shadow:0 1px 1px rgba(0,0,0,0.04);box-shadow:0 1px 1px rgba(0,0,0,0.04)}#leadin .contact-history .event{margin:0;padding:10px 20px;border-bottom:1px solid #dedede;border-left:4px solid;*zoom:1}#leadin .contact-history .event:after{content:"";display:table;clear:both}#leadin .contact-history .event:first-child{border-top:0}#leadin .contact-history .event.pageview{border-left-color:#28c;color:#28c}#leadin .contact-history .event.form-submission{border-left-color:#F67D42;color:#F67D42}#leadin .contact-history .event.source{border-left-color:#99AA1F;color:#99AA1F}#leadin .contact-history .event-title{margin:0;font-size:13px;font-weight:600}#leadin .contact-history .event-time{float:left;font-weight:400;width:75px}#leadin .contact-history .event-content{margin-left:75px}#leadin .contact-history .event-detail{margin-top:20px;color:#444}#leadin .contact-history .event-detail li+li{padding-top:6px;border-top:1px solid #eee}#leadin .contact-history .event-detail.pageview-url{color:#ccc}#leadin .contact-history .visit-source p{margin:0;color:#1F6696}#leadin .contact-history .field-label{text-transform:uppercase;letter-spacing:0.05em;color:#999;margin-bottom:6px;font-size:0.9em}#leadin .contact-history .field-value{margin:0}#leadin.pre-mp6 .events{background-color:#f9f9f9}.powerup-list{margin:0}.powerup-list .powerup{width:20%;min-width:250px;float:left;margin:20px;padding:15px}.powerup-list .powerup h2,.powerup-list .powerup p{margin:0;padding:0;color:#666;margin-bottom:15px}.powerup-list .powerup .img-containter{text-align:center;padding:30px 15px;margin-bottom:15px;background-color:#f1f1f1;color:red}.powerup-list .powerup .img-containter h2{font-size:20px}.powerup-list .powerup.activated h2,.powerup-list .powerup.activated p{color:#1F7D71}.powerup-list .powerup.activated .img-containter{background-color:#D3EEEB}@media (min-width: 1200px){.leadin-stats__top-container,.leadin-stats__chart-container,.leadin-stats__big-numbers-container{width:100%;float:right;margin-right:0}.leadin-stats__postbox_containter{width:49.29577%;float:left;margin-right:1.40845%}.leadin-stats__postbox_containter:nth-child(2n+2){width:49.29577%;float:right;margin-right:0}}h2.leadin-stats__header{margin-bottom:12px}.leadin-stats__postbox_containter .leadin-postbox,.leadin-stats__postbox_containter .powerup-list .powerup,.powerup-list .leadin-stats__postbox_containter .powerup{margin-bottom:12px}.leadin-stats__big-number{text-align:center;width:42%;float:left;padding:4%}@media (min-width: 1200px){.leadin-stats__big-number{width:25%;padding:10px}}.big-number--average .leadin-stats__big-number-top-label,.big-number--average .leadin-stats__big-number-content,.big-number--average .leadin-stats__big-number-bottom-label{color:#4CA6CF}.leadin-stats__top-container,.leadin-stats__big-number-top-label,.leadin-stats__big-number-content,.leadin-stats__big-number-bottom-label{color:#666;margin-bottom:12px}.leadin-stats__big-number-top-label{text-transform:uppercase;letter-spacing:0.05em}
|
1 |
+
#leadin label{cursor:default}#leadin .col-wrap{padding:0}#leadin .col-left .col-wrap{padding-right:10px}#leadin .metabox-holder{*zoom:1}#leadin .metabox-holder:after{content:"";display:table;clear:both}#wp-admin-bar-leadin-admin-menu img{height:16px;width:16px;opacity:0.6}@media (min-width: 1200px){#leadin{*zoom:1;max-width:1420px;max-width:88.75rem;padding-left:20px;padding-left:1.25rem;padding-right:20px;padding-right:1.25rem;margin-left:auto;margin-right:auto;margin:10px 20px 0 0;padding:0}#leadin:after{content:"";display:table;clear:both}#leadin *{box-sizing:border-box}}#li_analytics-meta .li-analytics-link{float:left}#li_analytics-meta .li-analytics-link .li-analytics__face{height:35px;width:35px;margin-right:5px;margin-bottom:5px}#li_analytics-meta .hidden_face{display:none}#li_analytics-meta .show-all-faces-container{clear:both}.leadin-postbox,.powerup-list .powerup{background-color:#fff;border:1px solid #e5e5e5;-moz-box-shadow:0 1px 1px rgba(0,0,0,0.04);-webkit-box-shadow:0 1px 1px rgba(0,0,0,0.04);box-shadow:0 1px 1px rgba(0,0,0,0.04)}.leadin-postbox__header{margin:0;padding:8px 12px;font-size:14px;border-bottom:1px solid #eee}.leadin-postbox__content{margin:11px 0;padding:0 12px;*zoom:1}.leadin-postbox__content:after{content:"";display:table;clear:both}.leadin-postbox__table{margin:0;width:100%}.leadin-postbox__table th{padding:6px 0;text-align:left;text-transform:uppercase;letter-spacing:0.05em}.leadin-postbox__table td{padding:6px 0}.leadin-postbox__table tr,.leadin-postbox__table td,.leadin-postbox__table th{vertical-align:middle !important}.leadin-dynamic-avatar_0{background-color:#F88E4B}.leadin-dynamic-avatar_1{background-color:#64AADA}.leadin-dynamic-avatar_2{background-color:#64C2B6}.leadin-dynamic-avatar_3{background-color:#CF7BAA}.leadin-dynamic-avatar_4{background-color:#E7C24B}.leadin-dynamic-avatar_5{background-color:#9387DA}.leadin-dynamic-avatar_6{background-color:#D6DD99}.leadin-dynamic-avatar_7{background-color:#FF4C4C}.leadin-dynamic-avatar_8{background-color:#99583D}.leadin-dynamic-avatar_9{background-color:#54CC14}@font-face{font-family:"icomoon";src:url("../../fonts/icomoon.eot?-lejfm6");src:url("../../fonts/icomoon.eot?#iefix-lejfm6") format("embedded-opentype"),url("../../fonts/icomoon.woff?-lejfm6") format("woff"),url("../../fonts/icomoon.ttf?-lejfm6") format("truetype"),url("../../fonts/icomoon.svg?-lejfm6#icomoon") format("svg");font-weight:normal;font-style:normal}.icon,.icon-profile,.icon-tag,.icon-tags,.icon-envelope,.icon-user,.icon-cog,.icon-bars,.icon-lab,.icon-bulb,.icon-mover{font-family:"icomoon";speak:none;font-style:normal;font-weight:normal;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.icon-profile:before{content:""}.icon-tag:before{content:""}.icon-tags:before{content:""}.icon-envelope:before{content:""}.icon-user:before{content:""}.icon-cog:before{content:""}.icon-bars:before{content:""}.icon-lab:before{content:""}.icon-bulb:before{content:""}.icon-mover:before{content:""}#leadin-footer{*zoom:1;clear:both;margin-top:48px;color:#999;border-top:1px solid #dedede}#leadin-footer:after{content:"";display:table;clear:both}#leadin-footer .support .sharing{height:18px;text-align:left}@media screen and (min-width: 500px){#leadin-footer .support,#leadin-footer .version,#leadin-footer .sharing{width:50%;float:left}#leadin-footer .sharing{text-align:right}}.button-big{padding:6px 36px !important;font-size:14px !important;height:auto !important}.oboarding-steps-names{*zoom:1;margin:0}.oboarding-steps-names:after{content:"";display:table;clear:both}.oboarding-step-name{float:left;margin:0;padding-bottom:24px;list-style:decimal inside none;font-size:18px;color:#bbb}.oboarding-step-name.active{color:#1F7D71;background-image:url(../../../images/triangle.png);background-position:bottom center;background-repeat:no-repeat}.oboarding-step-name.completed{list-style-image:url(../../../images/checkmark.png)}.oboarding-step-name+.oboarding-step-name{margin-left:72px}.oboarding-steps{margin:18px 0}@media (min-width: 1200px){.oboarding-steps{width:66.19718%;float:left;margin-right:1.40845%}}.oboarding-step-content{margin:0 auto;max-width:500px}.oboarding-step-content .description{margin:12px 0;display:block;display:none}.oboarding-step{text-align:center;display:block;padding:36px;background-color:#D3EEEB;border:2px solid #2a9;-moz-border-radius:5px;-webkit-border-radius:5px;border-radius:5px;color:#1F7D71}.oboarding-step .form-table th{display:none}.oboarding-step .form-table td{width:auto;display:block}.oboarding-step .form-table input{width:100%;font-size:16px;line-height:1.5;padding:7px 10px;display:block}.oboarding-step .oboarding-step-title,.oboarding-step .oboarding-step-description{color:#1F7D71;padding:0;margin-bottom:36px}.oboarding-step .button-primary{margin-top:36px}.oboarding-step .oboarding-step-description{font-size:16px;text-align:left}.oboarding-step .popup-option{width:31%;float:left;text-align:left;cursor:pointer !important}.oboarding-step .popup-option img{max-width:100%;margin-top:6px;-moz-box-shadow:0 1px 2px rgba(0,0,0,0.15);-webkit-box-shadow:0 1px 2px rgba(0,0,0,0.15);box-shadow:0 1px 2px rgba(0,0,0,0.15);-moz-border-radius:6px;-webkit-border-radius:6px;border-radius:6px}.oboarding-step .popup-option:hover img{-moz-box-shadow:0 2px 4px rgba(0,0,0,0.25);-webkit-box-shadow:0 2px 4px rgba(0,0,0,0.25);box-shadow:0 2px 4px rgba(0,0,0,0.25)}.oboarding-step .popup-option input{margin-right:8px !important}.oboarding-step .popup-option input:checked ~ img{border:2px solid #2ea2cc}.oboarding-step .popup-option+.popup-option{margin-left:3%}.oboarding-step .popup-options{*zoom:1}.oboarding-step .popup-options:after{content:"";display:table;clear:both}.oboarding-steps-help{margin-top:24px;color:#999}@media (min-width: 1200px){.oboarding-steps-help{width:15.49296%;float:left;margin-right:1.40845%;margin-top:60px}}@media (min-width: 1200px){.leadin-settings__content{width:74.64789%;float:left;margin-right:1.40845%}.leadin-settings__sidebar{width:23.94366%;float:right;margin-right:0}}.li-settings h3{border-left:1px solid #e5e5e5;border-right:1px solid #e5e5e5;border-top:1px solid #e5e5e5;border-bottom:1px solid #e5e5e5;margin-bottom:0px;background:#fff;padding:8px 12px;font-size:15px}.li-settings .form-table{margin-top:0px;border-left:1px solid #e5e5e5;border-right:1px solid #e5e5e5;border-bottom:1px solid #e5e5e5;background-color:#fff;-moz-box-shadow:0 1px 1px rgba(0,0,0,0.04);-webkit-box-shadow:0 1px 1px rgba(0,0,0,0.04);box-shadow:0 1px 1px rgba(0,0,0,0.04)}.li-settings .form-table th{padding-left:12px}.li-settings .leadin-section{background-color:#fff;border-left:1px solid #e5e5e5;border-right:1px solid #e5e5e5;font-size:14px;padding:15px 12px 5px 12px}.li-settings .leadin-section p{margin:0;padding:0}.li-settings.pre-mp6 h3{font-family:Georgia}.li-settings.pre-mp6 select,.li-settings.pre-mp6 input{font-family:sans-serif;font-size:12px}.li-settings.pre-mp6 .form-table,.li-settings.pre-mp6 .leadin-section,.li-settings.pre-mp6 h3{background-color:#f9f9f9 !important}.li-settings.pre-mp6 .form-table{-moz-border-radius-bottomleft:3px;-webkit-border-bottom-left-radius:3px;border-bottom-left-radius:3px;-moz-border-radius-bottomright:3px;-webkit-border-bottom-right-radius:3px;border-bottom-right-radius:3px}.li-settings.pre-mp6 h3{background-color:#f9f9f9 !important;-moz-border-radius-topleft:3px;-webkit-border-top-left-radius:3px;border-top-left-radius:3px;-moz-border-radius-topright:3px;-webkit-border-top-right-radius:3px;border-top-right-radius:3px}.li-settings.pre-mp6 .leadin-section{font-size:12px;padding-left:6px}.li-settings.pre-mp6 h3{padding-left:6px;font-weight:normal;color:#464646;text-shadow:#fff 0px 1px 0px}.li-settings.pre-mp6 label{font-size:12px}.li-settings.pre-mp6 input[type="checkbox"],.li-settings.pre-mp6 input[type="radio"]{margin-right:2px}#icon-leadin{background:url("../../images/leadin-icon-32x32.png") top center no-repeat}.help-notification{background:#d9edf7;border:1px solid #bce8f1;padding:10px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.toplevel_page_leadin_stats .wp-menu-image img{width:16px;height:16px}.leadin-contact-avatar{margin-right:10px;float:left}.power-up-settings-icon{padding-right:10px;float:left;max-height:20px;margin-top:-1px}.dashicons{margin-right:10px;float:left;margin-top:-1px}tr.synced-list-row td.synced-list-cell{padding:3px 0px 10px 0px}tr.synced-list-row td.synced-list-cell .icon-tag{font-size:12px}tr.synced-list-row span.synced-list-arrow{padding:0px 10px}tr.synced-list-row td.synced-list-edit{padding:3px 0px 10px 20px}.leadin-settings__sidebar .pro-upgrade-cta{max-width:100%}.leadin-contacts .button{transition:background-color 0.2s}@media (min-width: 1200px){.leadin-contacts__nav{width:15.49296%;float:left;margin-right:1.40845%;margin-top:30px}.leadin-contacts__content{width:83.09859%;float:right;margin-right:0;margin-bottom:18px;margin-top:30px}.leadin-contacts__export-form{width:83.09859%;float:left;margin-right:1.40845%;padding-left:16.90141%;margin-bottom:18px}}.leadin-contacts__search{float:right;padding:10px 0;padding-bottom:9px}.leadin-contacts__type-picker{margin:0 0 30px;*zoom:1}.leadin-contacts__type-picker:after{content:"";display:table;clear:both}.leadin-contacts__type-picker li{margin:0;padding:0 1em 0 0;float:left}@media (min-width: 1200px){.leadin-contacts__type-picker li{float:none;padding:0}.leadin-contacts__type-picker li+li{padding:18px 0 0}}.leadin-contacts__type-picker li a{display:block;line-height:24px;font-weight:400;font-size:16px;text-decoration:none}.leadin-contacts__type-picker li a.current{font-weight:bold}.leadin-contacts__type-picker li a.current,.leadin-contacts__type-picker li a:hover,.leadin-contacts__type-picker li a:active{color:#F67D42}.leadin-contacts__type-picker li a .icon-tag,.leadin-contacts__type-picker li a .icon-user{padding-right:1em;font-size:0.85em}.leadin-contacts__tags-header{margin:30px 0 18px;font-size:14px;text-transform:uppercase;letter-spacing:0.1em;color:#999}.leadin-contacts__filter-text{margin:0 0 18px}.leadin-contacts__filter-count{color:#F67D42}#clear-filter{font-size:0.8em;margin-left:10px}.leadin-contacts__table table th#source{width:20%}.leadin-contacts__table table th#visits,.leadin-contacts__table table th#submissions{width:8%}.leadin-contacts__table table th#status,.leadin-contacts__table table th#last_visit,.leadin-contacts__table table th#date,.leadin-contacts__table table th#pageviews{width:10%}.leadin-contacts__table table th,.leadin-contacts__table table td{display:none}.leadin-contacts__table table th:nth-child(-n+3),.leadin-contacts__table table td:nth-child(-n+3){display:table-cell}@media (min-width: 1200px){.leadin-contacts__table table th,.leadin-contacts__table table td{display:table-cell}}.leadin-contacts.pre-mp6 .table_search{float:right;padding:12px 0;padding-bottom:11px}.leadin-contacts.pre-mp6 table{background-color:#fff;border-color:#dedede}.leadin-contacts.pre-mp6 table tr.alternate{background-color:#fff}.leadin-contacts.pre-mp6 table th,.leadin-contacts.pre-mp6 table td{border-top:0;padding:12px 6px 11px}.leadin-contacts.pre-mp6 table th a,.leadin-contacts.pre-mp6 table td a{padding:0}.leadin-contacts.pre-mp6 table th[scope="col"]{background:#eee;font-family:sans-serif;font-size:12px;text-shadow:none}.leadin-contacts.pre-mp6 table td{border-color:#dedede;line-height:18px;font-size:14px}.leadin-contacts.pre-mp6 table td .row-actions{float:left}#leadin .contact-header-wrap{*zoom:1;padding:18px 0 24px}#leadin .contact-header-wrap:after{content:"";display:table;clear:both}#leadin .contact-header-wrap .contact-header-avatar,#leadin .contact-header-wrap .contact-header-info{float:left}#leadin .contact-header-info{padding-left:15px}#leadin .contact-name{line-height:30px;padding:0;margin:0}#leadin .contact-tags{margin-top:15px}#leadin .contact-tag{padding:4px 10px;color:#fff;background-color:#F67D42;text-decoration:none;font-weight:600;text-transform:uppercase;letter-spacing:0.1em;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px}#leadin .contact-tag:hover{opacity:0.9}#leadin .contact-tag+.contact-tag,#leadin .contact-tag+.contact-edit-tags{margin-left:10px}#leadin .contact-tag .icon-tag{padding-right:10px}#leadin .contact-info h3{margin:0}#leadin .contact-info label{font-weight:bold;line-height:1;cursor:default}#leadin .leadin-meta-section+.leadin-meta-section{margin-top:24px}#leadin .leadin-meta-table{width:100%;text-align:left}#leadin .leadin-meta-table th{color:#666;padding-bottom:6px}#leadin .leain-meta-header,#leadin .contact-history .session-date{margin:0 0 12px;text-transform:uppercase;letter-spacing:0.05em;color:#444}#leadin .leadin-premium-tag:after{content:"Pro";margin-left:10px;font-size:10px;color:#fff;background-color:#93C054;padding:2px 6px;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px}#leadin .contact-history{margin-left:20px}@media (min-width: 1200px){#leadin .contact-history{padding-left:20px;border-left:2px solid #dedede}}#leadin .contact-history .sessions{margin:0}#leadin .contact-history .session+.session{margin-top:30px}#leadin .contact-history .session-date{position:relative}@media (min-width: 1200px){#leadin .contact-history .session-date:before{content:"•";font-size:32px;line-height:0;height:31px;width:31px;position:absolute;left:-27px;top:9px;color:#dedede}}#leadin .contact-history .session-time-range{color:#999;font-weight:400}#leadin .contact-history .events{background-color:#fff;border:1px solid #dedede;-moz-box-shadow:0 1px 1px rgba(0,0,0,0.04);-webkit-box-shadow:0 1px 1px rgba(0,0,0,0.04);box-shadow:0 1px 1px rgba(0,0,0,0.04)}#leadin .contact-history .event{margin:0;padding:10px 20px;border-bottom:1px solid #dedede;border-left:4px solid;*zoom:1}#leadin .contact-history .event:after{content:"";display:table;clear:both}#leadin .contact-history .event:first-child{border-top:0}#leadin .contact-history .event.pageview{border-left-color:#28c;color:#28c}#leadin .contact-history .event.form-submission{border-left-color:#F67D42;color:#F67D42}#leadin .contact-history .event.source{border-left-color:#99AA1F;color:#99AA1F}#leadin .contact-history .event-title{margin:0;font-size:13px;font-weight:600}#leadin .contact-history .event-time{float:left;font-weight:400;width:75px}#leadin .contact-history .event-content{margin-left:75px}#leadin .contact-history .event-detail{margin-top:20px;color:#444}#leadin .contact-history .event-detail li+li{padding-top:6px;border-top:1px solid #eee}#leadin .contact-history .event-detail.pageview-url{color:#ccc}#leadin .contact-history .visit-source p{margin:0;color:#1F6696}#leadin .contact-history .field-label{text-transform:uppercase;letter-spacing:0.05em;color:#999;margin-bottom:6px;font-size:0.9em}#leadin .contact-history .field-value{margin:0}#leadin.pre-mp6 .events{background-color:#f9f9f9}.powerup-list{margin:0}.powerup-list .powerup{width:20%;min-width:250px;float:left;margin:20px;padding:15px}.powerup-list .powerup h2,.powerup-list .powerup p{margin:0;padding:0;color:#666;margin-bottom:15px}.powerup-list .powerup .img-containter{text-align:center;padding:30px 15px;margin-bottom:15px;background-color:#f1f1f1;color:red}.powerup-list .powerup .img-containter h2{font-size:20px}.powerup-list .powerup.activated h2,.powerup-list .powerup.activated p{color:#1F7D71}.powerup-list .powerup.activated .img-containter{background-color:#D3EEEB}@media (min-width: 1200px){.leadin-stats__top-container,.leadin-stats__chart-container,.leadin-stats__big-numbers-container{width:100%;float:right;margin-right:0}.leadin-stats__postbox_containter{width:49.29577%;float:left;margin-right:1.40845%}.leadin-stats__postbox_containter:nth-child(2n+2){width:49.29577%;float:right;margin-right:0}}h2.leadin-stats__header{margin-bottom:12px}.leadin-stats__postbox_containter .leadin-postbox,.leadin-stats__postbox_containter .powerup-list .powerup,.powerup-list .leadin-stats__postbox_containter .powerup{margin-bottom:12px}.leadin-stats__big-number{text-align:center;width:42%;float:left;padding:4%}@media (min-width: 1200px){.leadin-stats__big-number{width:25%;padding:10px}}.big-number--average .leadin-stats__big-number-top-label,.big-number--average .leadin-stats__big-number-content,.big-number--average .leadin-stats__big-number-bottom-label{color:#4CA6CF}.leadin-stats__top-container,.leadin-stats__big-number-top-label,.leadin-stats__big-number-content,.leadin-stats__big-number-bottom-label{color:#666;margin-bottom:12px}.leadin-stats__big-number-top-label{text-transform:uppercase;letter-spacing:0.05em}.big-button,.big-button--orange,.big-button--share{display:block;text-align:center;color:#fff;text-decoration:none;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;padding:10px;font-size:16px;margin-top:15px}.big-button:hover,.big-button--orange:hover,.big-button--share:hover,.big-button:active,.big-button--orange:active,.big-button--share:active,.big-button:focus,.big-button--orange:focus,.big-button--share:focus,.big-button:visited,.big-button--orange:visited,.big-button--share:visited{color:#fff}.big-button--orange{background-color:#F67D42;border:1px solid #E75913;-webkit-box-shadow:inset 0 1px 0 rgba(255,195,166,0.5),0 1px 0 rgba(0,0,0,0.08);box-shadow:inset 0 1px 0 rgba(255,195,166,0.5),0 1px 0 rgba(0,0,0,0.08)}.big-button--orange:hover{color:#fff;background-color:#f56c2a}.big-button--orange:active{color:#f1f1f1;background-color:#f45c11;-moz-box-shadow:none;-webkit-box-shadow:none;box-shadow:none}.btn-submitting{background-color:#979797;cursor:not-allowed;border-color:grey;box-shadow:none}.btn-submitting:hover,.btn-submitting:active,.btn-submitting:focus,.btn-submitting:visited{background-color:#979797;color:#fff;box-shadow:none}.compare{width:100%;float:left;margin-right:1.40845%;display:inline;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;background-color:#fff;position:relative;margin-bottom:20px}.compare:first-of-type{margin-bottom:60px}.compare:first-of-type:after{width:100%;float:left;margin-right:1.40845%;display:inline;content:"";display:inline-block;-webkit-font-smoothing:antialiased;font:normal 48px/1 "dashicons";position:absolute;bottom:-55px;text-align:center}@media (min-width: 1200px){.compare:first-of-type:after{width:7.04225%;float:left;margin-right:1.40845%;content:"";display:inline-block;-webkit-font-smoothing:antialiased;font:normal 48px/1 "dashicons";position:absolute;right:-40px;top:4em}}@media (min-width: 1200px){.compare{width:32.39437%;float:left;margin-right:1.40845%;margin-right:60px}}.compare .title{width:100%;height:72px;background-color:#979797;position:absolute;text-align:center;padding-top:15px;-moz-border-radius-topleft:3px;-webkit-border-top-left-radius:3px;border-top-left-radius:3px;-moz-border-radius-topright:3px;-webkit-border-top-right-radius:3px;border-top-right-radius:3px}.compare .title h2{color:#fff;font-size:20px}.compare .title.teal{background-color:#6EC8C7}.compare .content{margin-top:50px;padding:30px}.compare .features{text-transform:uppercase;font-weight:bold;font-size:18px;padding-left:15px}.compare .features li{list-style-position:outside;text-indent:-10px}.compare .features li:before{content:"";display:inline-block;-webkit-font-smoothing:antialiased;font:normal 20px/1 "dashicons";vertical-align:top}.compare .features.plus li:before{content:"";display:inline-block;-webkit-font-smoothing:antialiased;font:normal 20px/1.1 "dashicons";vertical-align:top}.compare .features p{margin-left:2px;margin-top:-5px}.compare p{text-transform:none;font-weight:normal;line-height:27px}*{box-sizing:border-box}.big-button--share{display:inline-block;margin-right:2px;width:82px;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.5),0 1px 0 rgba(0,0,0,0.08);box-shadow:inset 0 1px 0 rgba(255,255,255,0.5),0 1px 0 rgba(0,0,0,0.08)}@media (min-width: 1200px){.big-button--share{margin-right:7px;width:200px}}.big-button--share.fb{background-color:#3B579D;border:1px solid #344d8a}.big-button--share.fb:after{content:""}@media (min-width: 1200px){.big-button--share.fb:after{content:"Share on Facebook"}}.big-button--share.fb:hover{background-color:#4261b0}.big-button--share.fb:before{content:"";display:inline-block;-webkit-font-smoothing:antialiased;font:normal 20px/1.4 "dashicons";vertical-align:top;margin-right:5px}.big-button--share.tw{background-color:#1DB1EB;border:1px solid #13a3db}.big-button--share.tw:after{content:""}@media (min-width: 1200px){.big-button--share.tw:after{content:"Share on Twitter"}}.big-button--share.tw:hover{background-color:#34b9ed}.big-button--share.tw:before{content:"";display:inline-block;-webkit-font-smoothing:antialiased;font:normal 20px/1.4 "dashicons";vertical-align:top;margin-right:5px}.big-button--share.wp{background-color:#1585B6;border:1px solid #12749f}.big-button--share.wp:after{content:""}@media (min-width: 1200px){.big-button--share.wp:after{content:"Write a Review"}}.big-button--share.wp:hover{background-color:#1896cd}.big-button--share.wp:before{content:"";display:inline-block;-webkit-font-smoothing:antialiased;font:normal 20px/1.4 "dashicons";vertical-align:top;margin-right:5px}.dialog-bottom-right{line-height:28px;background-color:#6EC8C7;color:#fff;position:fixed;z-index:1111;right:0;bottom:-400px;-moz-border-radius-topleft:3px;-webkit-border-top-left-radius:3px;border-top-left-radius:3px;width:300px;padding:20px;-moz-box-shadow:grey -1px 0 7px;-webkit-box-shadow:grey -1px 0 7px;box-shadow:grey -1px 0 7px}@media (min-width: 1200px){.dialog-bottom-right{width:668px}}.dialog-bottom-right h1{color:#1B6F6C;font-size:20px;font-weight:600;margin:0px}.dialog-bottom-right p{color:#fff;font-size:14px}.close:before{content:"";display:inline-block;-webkit-font-smoothing:antialiased;font:normal 24px/1.4 "dashicons";vertical-align:top;float:right;margin-top:-30px;color:grey}
|
assets/css/build/leadin-lead-notifcation.css
CHANGED
@@ -1 +1 @@
|
|
1 |
-
body,.body{background-color:#f1f1f1}h1{font-size:26px;line-height:60px}h2{font-size:23px}h3{font-size:18px}h4{font-size:14px;font-weight:bold}.submission-detail h3{color:#666}.lead-timeline__pageview-url a{color:#999}.lead-timeline__submission-label{text-transform:uppercase;font-size:12px;color:#999;letter-spacing:0.05em}.lead-timeline__previous-activity h2{margin-top:15px}.lead-timeline__event{background-color:#fff;border-top:1px solid #dedede;border-right:1px solid #dedede}.lead-timeline__event.pageview{border-left:4px solid #28c}.lead-timeline__event.pageview .lead-timeline__event-title,.lead-timeline__event.pageview .lead-timeline__event-time{color:#1f6696}.lead-timeline__event.submission{border-left:4px solid #f6601d}.lead-timeline__event.submission .lead-timeline__event-title,.lead-timeline__event.submission .lead-timeline__event-time{color:#b34a12}.lead-timeline__event.traffic-source{border-left:4px solid #99aa1f;border-bottom:1px solid #dedede;margin-bottom:20px}.lead-timeline__event.traffic-source .lead-timeline__event-title,.lead-timeline__event.traffic-source .lead-timeline__event-time{color:#727e14}.footer{margin-bottom:20px}
|
1 |
+
body,.body{background-color:#f1f1f1}h1{font-size:26px;line-height:60px}h2{font-size:23px}h3{font-size:18px}h4{font-size:14px;font-weight:bold}.submission-detail h3{color:#666}.lead-timeline__pageview-url a{color:#999}.lead-timeline__submission-label{text-transform:uppercase;font-size:12px;color:#999;letter-spacing:0.05em}.lead-timeline__previous-activity h2{margin-top:15px}.lead-timeline__event{background-color:#fff;border-top:1px solid #dedede;border-right:1px solid #dedede}.lead-timeline__event.pageview{border-left:4px solid #28c}.lead-timeline__event.pageview .lead-timeline__event-title,.lead-timeline__event.pageview .lead-timeline__event-time{color:#1f6696}.lead-timeline__event.submission{border-left:4px solid #f6601d}.lead-timeline__event.submission .lead-timeline__event-title,.lead-timeline__event.submission .lead-timeline__event-time{color:#b34a12}.lead-timeline__event.traffic-source{border-left:4px solid #99aa1f;border-bottom:1px solid #dedede;margin-bottom:20px}.lead-timeline__event.traffic-source .lead-timeline__event-title,.lead-timeline__event.traffic-source .lead-timeline__event-time{color:#727e14}.data-lookup-header{font-size:20px;margin-bottom:15px}.data-lookup-limit .green,.data-lookup-limit .yellow,.data-lookup-limit .red{font-weight:bold}.data-lookup-limit .green{color:green}.data-lookup-limit .yellow{color:#ff0}.data-lookup-limit .red{color:red}.contact-name,.company-name{font-size:14px;font-weight:bold;color:#444}.contact-name-subhead,.company-name-subhead{font-size:14px;font-weight:400;margin-bottom:15px;color:#444}.contact-description,.company-description{color:#666}.footer{margin-bottom:20px}
|
assets/css/build/leadin-subscribe-premium.css
DELETED
@@ -1,3 +0,0 @@
|
|
1 |
-
#powered-by-leadin-thank-you, #leadin-subscribe-powered-by {
|
2 |
-
display: none;
|
3 |
-
}
|
|
|
|
|
|
assets/js/build/leadin-admin.js
CHANGED
@@ -1,3 +1,116 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
/*
|
2 |
Highcharts JS v4.0.1 (2014-04-24)
|
3 |
|
@@ -310,6 +423,17 @@ hasBidiBug:Nb,isTouchDevice:Jb,numberFormat:Ga,seriesTypes:F,setOptions:function
|
|
310 |
}
|
311 |
jQuery(document).ready( function ( $ ) {
|
312 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
313 |
$("#filter_action").select2(
|
314 |
|
315 |
);
|
@@ -434,7 +558,50 @@ jQuery(document).ready( function ( $ ) {
|
|
434 |
|
435 |
$('#preview-popup-link').attr('href', preview_link);
|
436 |
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
437 |
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
438 |
jQuery(document).ready( function ( $ ) {
|
439 |
|
440 |
var $bulk_opt_selected = $('.bulkactions select option[value="add_tag_to_selected"], .bulkactions select option[value="remove_tag_from_selected"], .bulkactions select option[value="delete_selected"]');
|
@@ -549,6 +716,16 @@ jQuery(document).ready( function ( $ ) {
|
|
549 |
$('.bulkactions select').val('-1');
|
550 |
}
|
551 |
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
552 |
});
|
553 |
/*
|
554 |
Copyright 2012 Igor Vaynberg
|
1 |
+
/*!
|
2 |
+
* jQuery Cookie Plugin v1.4.0
|
3 |
+
* https://github.com/carhartl/jquery-cookie
|
4 |
+
*
|
5 |
+
* Copyright 2013 Klaus Hartl
|
6 |
+
* Released under the MIT license
|
7 |
+
*/
|
8 |
+
(function (factory) {
|
9 |
+
if (typeof define === 'function' && define.amd) {
|
10 |
+
// AMD. Register as anonymous module.
|
11 |
+
define(['jquery'], factory);
|
12 |
+
} else {
|
13 |
+
// Browser globals.
|
14 |
+
factory(jQuery);
|
15 |
+
}
|
16 |
+
}(function ($) {
|
17 |
+
|
18 |
+
var pluses = /\+/g;
|
19 |
+
|
20 |
+
function encode(s) {
|
21 |
+
return config.raw ? s : encodeURIComponent(s);
|
22 |
+
}
|
23 |
+
|
24 |
+
function decode(s) {
|
25 |
+
return config.raw ? s : decodeURIComponent(s);
|
26 |
+
}
|
27 |
+
|
28 |
+
function stringifyCookieValue(value) {
|
29 |
+
return encode(config.json ? JSON.stringify(value) : String(value));
|
30 |
+
}
|
31 |
+
|
32 |
+
function parseCookieValue(s) {
|
33 |
+
if (s.indexOf('"') === 0) {
|
34 |
+
// This is a quoted cookie as according to RFC2068, unescape...
|
35 |
+
s = s.slice(1, -1).replace(/\\"/g, '"').replace(/\\\\/g, '\\');
|
36 |
+
}
|
37 |
+
|
38 |
+
try {
|
39 |
+
// Replace server-side written pluses with spaces.
|
40 |
+
// If we can't decode the cookie, ignore it, it's unusable.
|
41 |
+
// If we can't parse the cookie, ignore it, it's unusable.
|
42 |
+
s = decodeURIComponent(s.replace(pluses, ' '));
|
43 |
+
return config.json ? JSON.parse(s) : s;
|
44 |
+
} catch(e) {}
|
45 |
+
}
|
46 |
+
|
47 |
+
function read(s, converter) {
|
48 |
+
var value = config.raw ? s : parseCookieValue(s);
|
49 |
+
return $.isFunction(converter) ? converter(value) : value;
|
50 |
+
}
|
51 |
+
|
52 |
+
var config = $.cookie = function (key, value, options) {
|
53 |
+
|
54 |
+
// Write
|
55 |
+
if (value !== undefined && !$.isFunction(value)) {
|
56 |
+
options = $.extend({}, config.defaults, options);
|
57 |
+
|
58 |
+
if (typeof options.expires === 'number') {
|
59 |
+
var days = options.expires, t = options.expires = new Date();
|
60 |
+
t.setDate(t.getDate() + days);
|
61 |
+
}
|
62 |
+
|
63 |
+
return (document.cookie = [
|
64 |
+
encode(key), '=', stringifyCookieValue(value),
|
65 |
+
options.expires ? '; expires=' + options.expires.toUTCString() : '', // use expires attribute, max-age is not supported by IE
|
66 |
+
options.path ? '; path=' + options.path : '',
|
67 |
+
options.domain ? '; domain=' + options.domain : '',
|
68 |
+
options.secure ? '; secure' : ''
|
69 |
+
].join(''));
|
70 |
+
}
|
71 |
+
|
72 |
+
// Read
|
73 |
+
|
74 |
+
var result = key ? undefined : {};
|
75 |
+
|
76 |
+
// To prevent the for loop in the first place assign an empty array
|
77 |
+
// in case there are no cookies at all. Also prevents odd result when
|
78 |
+
// calling $.cookie().
|
79 |
+
var cookies = document.cookie ? document.cookie.split('; ') : [];
|
80 |
+
|
81 |
+
for (var i = 0, l = cookies.length; i < l; i++) {
|
82 |
+
var parts = cookies[i].split('=');
|
83 |
+
var name = decode(parts.shift());
|
84 |
+
var cookie = parts.join('=');
|
85 |
+
|
86 |
+
if (key && key === name) {
|
87 |
+
// If second argument (value) is a function it's a converter...
|
88 |
+
result = read(cookie, value);
|
89 |
+
break;
|
90 |
+
}
|
91 |
+
|
92 |
+
// Prevent storing a cookie that we couldn't decode.
|
93 |
+
if (!key && (cookie = read(cookie)) !== undefined) {
|
94 |
+
result[name] = cookie;
|
95 |
+
}
|
96 |
+
}
|
97 |
+
|
98 |
+
return result;
|
99 |
+
};
|
100 |
+
|
101 |
+
config.defaults = {};
|
102 |
+
|
103 |
+
$.removeCookie = function (key, options) {
|
104 |
+
if ($.cookie(key) === undefined) {
|
105 |
+
return false;
|
106 |
+
}
|
107 |
+
|
108 |
+
// Must not alter options, thus extending a fresh object...
|
109 |
+
$.cookie(key, '', $.extend({}, options, { expires: -1 }));
|
110 |
+
return !$.cookie(key);
|
111 |
+
};
|
112 |
+
|
113 |
+
}));
|
114 |
/*
|
115 |
Highcharts JS v4.0.1 (2014-04-24)
|
116 |
|
423 |
}
|
424 |
jQuery(document).ready( function ( $ ) {
|
425 |
|
426 |
+
$('#close-share').click( function( e ) {
|
427 |
+
$.cookie('ignore_social_share', 1, { expires: 30 });
|
428 |
+
});
|
429 |
+
|
430 |
+
$('.big-button--share').click( function( e ) {
|
431 |
+
$.cookie('ignore_social_share', 1);
|
432 |
+
});
|
433 |
+
|
434 |
+
if ( ! $.cookie('ignore_social_share') )
|
435 |
+
leadin_check_social_share_popup();
|
436 |
+
|
437 |
$("#filter_action").select2(
|
438 |
|
439 |
);
|
558 |
|
559 |
$('#preview-popup-link').attr('href', preview_link);
|
560 |
});
|
561 |
+
|
562 |
+
$('#pro-upgrade-button').click( function ( e ) {
|
563 |
+
e.preventDefault();
|
564 |
+
|
565 |
+
if ( ! $('#agree-pp').is(":checked") )
|
566 |
+
{
|
567 |
+
$('#agree-pp-error').show();
|
568 |
+
return false;
|
569 |
+
}
|
570 |
+
else
|
571 |
+
{
|
572 |
+
$('#agree-pp-error').hide();
|
573 |
+
$(this).addClass('btn-submitting').text('Upgrading...');
|
574 |
+
}
|
575 |
+
|
576 |
+
$.ajax({
|
577 |
+
type: 'POST',
|
578 |
+
url: li_admin_ajax.ajax_url,
|
579 |
+
data: {
|
580 |
+
"action": "leadin_upgrade_to_pro"
|
581 |
+
},
|
582 |
+
success: function( redirect_to ) {
|
583 |
+
|
584 |
+
if ( redirect_to )
|
585 |
+
window.location.href = redirect_to + "&pro_upgrade=1";
|
586 |
+
}
|
587 |
+
});
|
588 |
+
});
|
589 |
});
|
590 |
+
|
591 |
+
function leadin_check_social_share_popup ()
|
592 |
+
{
|
593 |
+
jQuery.ajax({
|
594 |
+
type: 'POST',
|
595 |
+
url: li_admin_ajax.ajax_url,
|
596 |
+
data: {
|
597 |
+
"action": "leadin_check_installation_date"
|
598 |
+
},
|
599 |
+
success: function( data ) {
|
600 |
+
if ( ! data )
|
601 |
+
$.cookie('ignore_social_share', 1);
|
602 |
+
}
|
603 |
+
});
|
604 |
+
}
|
605 |
jQuery(document).ready( function ( $ ) {
|
606 |
|
607 |
var $bulk_opt_selected = $('.bulkactions select option[value="add_tag_to_selected"], .bulkactions select option[value="remove_tag_from_selected"], .bulkactions select option[value="delete_selected"]');
|
716 |
$('.bulkactions select').val('-1');
|
717 |
}
|
718 |
});
|
719 |
+
|
720 |
+
$('#contact-detail-read-more').click( function ( e ) {
|
721 |
+
$('#company-detail-overview-short').hide();
|
722 |
+
$('#company-detail-overview-full').show();
|
723 |
+
});
|
724 |
+
|
725 |
+
$('#contact-detail-read-less').click( function ( e ) {
|
726 |
+
$('#company-detail-overview-full').hide();
|
727 |
+
$('#company-detail-overview-short').show();
|
728 |
+
});
|
729 |
});
|
730 |
/*
|
731 |
Copyright 2012 Igor Vaynberg
|
assets/js/build/leadin-admin.min.js
CHANGED
@@ -1,8 +1,8 @@
|
|
1 |
-
window.Highcharts||!function(){function q(a,b){var c;a||(a={});for(c in b)a[c]=b[c];return a}function w(){var a,c,b=arguments,d={},e=function(a,b){var c,d;"object"!=typeof a&&(a={});for(d in b)b.hasOwnProperty(d)&&(c=b[d],a[d]=c&&"object"==typeof c&&"[object Array]"!==Object.prototype.toString.call(c)&&"renderTo"!==d&&"number"!=typeof c.nodeType?e(a[d]||{},c):b[d]);return a};for(b[0]===!0&&(d=b[1],b=Array.prototype.slice.call(b,2)),c=b.length,a=0;c>a;a++)d=e(d,b[a]);return d}function z(a,b){return parseInt(a,b||10)}function Fa(a){return"string"==typeof a}function ca(a){return"object"==typeof a}function La(a){return"[object Array]"===Object.prototype.toString.call(a)}function ha(a){return"number"==typeof a}function za(a){return U.log(a)/U.LN10}function ia(a){return U.pow(10,a)}function ja(a,b){for(var c=a.length;c--;)if(a[c]===b){a.splice(c,1);break}}function r(a){return a!==t&&null!==a}function H(a,b,c){var d,e;if(Fa(b))r(c)?a.setAttribute(b,c):a&&a.getAttribute&&(e=a.getAttribute(b));else if(r(b)&&ca(b))for(d in b)a.setAttribute(d,b[d]);return e}function qa(a){return La(a)?a:[a]}function m(){var b,c,a=arguments,d=a.length;for(b=0;d>b;b++)if(c=a[b],"undefined"!=typeof c&&null!==c)return c}function G(a,b){Aa&&!aa&&b&&b.opacity!==t&&(b.filter="alpha(opacity="+100*b.opacity+")"),q(a.style,b)}function Y(a,b,c,d,e){return a=y.createElement(a),b&&q(a,b),e&&G(a,{padding:0,border:Q,margin:0}),c&&G(a,c),d&&d.appendChild(a),a}function ka(a,b){var c=function(){};return c.prototype=new a,q(c.prototype,b),c}function Ga(a,b,c,d){var e=E.lang,a=+a||0,f=-1===b?(a.toString().split(".")[1]||"").length:isNaN(b=M(b))?2:b,b=void 0===c?e.decimalPoint:c,d=void 0===d?e.thousandsSep:d,e=0>a?"-":"",c=String(z(a=M(a).toFixed(f))),g=c.length>3?c.length%3:0;return e+(g?c.substr(0,g)+d:"")+c.substr(g).replace(/(\d{3})(?=\d)/g,"$1"+d)+(f?b+M(a-c).toFixed(f).slice(2):"")}function Ha(a,b){return Array((b||2)+1-String(a).length).join(0)+a}function Ma(a,b,c){var d=a[b];a[b]=function(){var a=Array.prototype.slice.call(arguments);return a.unshift(d),c.apply(this,a)}}function Ia(a,b){for(var e,f,g,h,i,c="{",d=!1,j=[];-1!==(c=a.indexOf(c));){if(e=a.slice(0,c),d){for(f=e.split(":"),g=f.shift().split("."),i=g.length,e=b,h=0;i>h;h++)e=e[g[h]];f.length&&(f=f.join(":"),g=/\.([0-9])/,h=E.lang,i=void 0,/f$/.test(f)?(i=(i=f.match(g))?i[1]:-1,null!==e&&(e=Ga(e,i,h.decimalPoint,f.indexOf(",")>-1?h.thousandsSep:""))):e=cb(f,e))}j.push(e),a=a.slice(c+1),c=(d=!d)?"}":"{"}return j.push(a),j.join("")}function mb(a){return U.pow(10,T(U.log(a)/U.LN10))}function nb(a,b,c,d){var e,c=m(c,1);for(e=a/c,b||(b=[1,2,2.5,5,10],d&&d.allowDecimals===!1&&(1===c?b=[1,2,5,10]:.1>=c&&(b=[1/c]))),d=0;d<b.length&&(a=b[d],!(e<=(b[d]+(b[d+1]||b[d]))/2));d++);return a*=c}function Bb(){this.symbol=this.color=0}function ob(a,b){var d,e,c=a.length;for(e=0;c>e;e++)a[e].ss_i=e;for(a.sort(function(a,c){return d=b(a,c),0===d?a.ss_i-c.ss_i:d}),e=0;c>e;e++)delete a[e].ss_i}function Na(a){for(var b=a.length,c=a[0];b--;)a[b]<c&&(c=a[b]);return c}function Ba(a){for(var b=a.length,c=a[0];b--;)a[b]>c&&(c=a[b]);return c}function Oa(a,b){for(var c in a)a[c]&&a[c]!==b&&a[c].destroy&&a[c].destroy(),delete a[c]}function Pa(a){db||(db=Y(Ja)),a&&db.appendChild(a),db.innerHTML=""}function ra(a,b){var c="Highcharts error #"+a+": www.highcharts.com/errors/"+a;if(b)throw c;I.console&&console.log(c)}function da(a){return parseFloat(a.toPrecision(14))}function Qa(a,b){va=m(a,b.animation)}function Cb(){var a=E.global.useUTC,b=a?"getUTC":"get",c=a?"setUTC":"set";Ra=6e4*(a&&E.global.timezoneOffset||0),eb=a?Date.UTC:function(a,b,c,g,h,i){return new Date(a,b,m(c,1),m(g,0),m(h,0),m(i,0)).getTime()},pb=b+"Minutes",qb=b+"Hours",rb=b+"Day",Xa=b+"Date",fb=b+"Month",gb=b+"FullYear",Db=c+"Minutes",Eb=c+"Hours",sb=c+"Date",Fb=c+"Month",Gb=c+"FullYear"}function P(){}function Sa(a,b,c,d){this.axis=a,this.pos=b,this.type=c||"",this.isNew=!0,!c&&!d&&this.addLabel()}function la(){this.init.apply(this,arguments)}function Ya(){this.init.apply(this,arguments)}function Hb(a,b,c,d,e){var f=a.chart.inverted;this.axis=a,this.isNegative=c,this.options=b,this.x=d,this.total=null,this.points={},this.stack=e,this.alignOptions={align:b.align||(f?c?"left":"right":"center"),verticalAlign:b.verticalAlign||(f?"middle":c?"bottom":"top"),y:m(b.y,f?4:c?14:-6),x:m(b.x,f?c?-6:6:0)},this.textAlign=b.textAlign||(f?c?"right":"left":"center")}var t,Za,$a,db,E,cb,va,ub,A,eb,Ra,pb,qb,rb,Xa,fb,gb,Db,Eb,sb,Fb,Gb,y=document,I=window,U=Math,u=U.round,T=U.floor,Ka=U.ceil,v=U.max,C=U.min,M=U.abs,Z=U.cos,ea=U.sin,ma=U.PI,Ca=2*ma/360,wa=navigator.userAgent,Ib=I.opera,Aa=/msie/i.test(wa)&&!Ib,hb=8===y.documentMode,ib=/AppleWebKit/.test(wa),Ta=/Firefox/.test(wa),Jb=/(Mobile|Android|Windows Phone)/.test(wa),xa="http://www.w3.org/2000/svg",aa=!!y.createElementNS&&!!y.createElementNS(xa,"svg").createSVGRect,Nb=Ta&&parseInt(wa.split("Firefox/")[1],10)<4,fa=!aa&&!Aa&&!!y.createElement("canvas").getContext,Kb={},tb=0,sa=function(){},V=[],ab=0,Ja="div",Q="none",Ob=/^[0-9]+$/,Pb="stroke-width",F={},R=I.Highcharts=I.Highcharts?ra(16,!0):{};cb=function(a,b,c){if(!r(b)||isNaN(b))return"Invalid date";var e,a=m(a,"%Y-%m-%d %H:%M:%S"),d=new Date(b-Ra),f=d[qb](),g=d[rb](),h=d[Xa](),i=d[fb](),j=d[gb](),k=E.lang,l=k.weekdays,d=q({a:l[g].substr(0,3),A:l[g],d:Ha(h),e:h,b:k.shortMonths[i],B:k.months[i],m:Ha(i+1),y:j.toString().substr(2,2),Y:j,H:Ha(f),I:Ha(f%12||12),l:f%12||12,M:Ha(d[pb]()),p:12>f?"AM":"PM",P:12>f?"am":"pm",S:Ha(d.getSeconds()),L:Ha(u(b%1e3),3)},R.dateFormats);for(e in d)for(;-1!==a.indexOf("%"+e);)a=a.replace("%"+e,"function"==typeof d[e]?d[e](b):d[e]);return c?a.substr(0,1).toUpperCase()+a.substr(1):a},Bb.prototype={wrapColor:function(a){this.color>=a&&(this.color=0)},wrapSymbol:function(a){this.symbol>=a&&(this.symbol=0)}},A=function(){for(var a=0,b=arguments,c=b.length,d={};c>a;a++)d[b[a++]]=b[a];return d}("millisecond",1,"second",1e3,"minute",6e4,"hour",36e5,"day",864e5,"week",6048e5,"month",26784e5,"year",31556952e3),ub={init:function(a,b,c){var g,h,i,b=b||"",d=a.shift,e=b.indexOf("C")>-1,f=e?7:3,b=b.split(" "),c=[].concat(c),j=function(a){for(g=a.length;g--;)"M"===a[g]&&a.splice(g+1,0,a[g+1],a[g+2],a[g+1],a[g+2])};if(e&&(j(b),j(c)),a.isArea&&(h=b.splice(b.length-6,6),i=c.splice(c.length-6,6)),d<=c.length/f&&b.length===c.length)for(;d--;)c=[].concat(c).splice(0,f).concat(c);if(a.shift=0,b.length)for(a=c.length;b.length<a;)d=[].concat(b).splice(b.length-f,f),e&&(d[f-6]=d[f-2],d[f-5]=d[f-1]),b=b.concat(d);return h&&(b=b.concat(h),c=c.concat(i)),[b,c]},step:function(a,b,c,d){var e=[],f=a.length;if(1===c)e=d;else if(f===b.length&&1>c)for(;f--;)d=parseFloat(a[f]),e[f]=isNaN(d)?a[f]:c*parseFloat(b[f]-d)+d;else e=b;return e}},function(a){I.HighchartsAdapter=I.HighchartsAdapter||a&&{init:function(b){var e,c=a.fx,d=c.step,f=a.Tween,g=f&&f.propHooks;e=a.cssHooks.opacity,a.extend(a.easing,{easeOutQuad:function(a,b,c,d,e){return-d*(b/=e)*(b-2)+c}}),a.each(["cur","_default","width","height","opacity"],function(a,b){var k,e=d;"cur"===b?e=c.prototype:"_default"===b&&f&&(e=g[b],b="set"),(k=e[b])&&(e[b]=function(c){var d,c=a?c:this;return"align"!==c.prop?(d=c.elem,d.attr?d.attr(c.prop,"cur"===b?t:c.now):k.apply(this,arguments)):void 0})}),Ma(e,"get",function(a,b,c){return b.attr?b.opacity||0:a.call(this,b,c)}),e=function(a){var d,c=a.elem;a.started||(d=b.init(c,c.d,c.toD),a.start=d[0],a.end=d[1],a.started=!0),c.attr("d",b.step(a.start,a.end,a.pos,c.toD))},f?g.d={set:e}:d.d=e,this.each=Array.prototype.forEach?function(a,b){return Array.prototype.forEach.call(a,b)}:function(a,b){for(var c=0,d=a.length;d>c;c++)if(b.call(a[c],a[c],c,a)===!1)return c},a.fn.highcharts=function(){var c,d,a="Chart",b=arguments;return this[0]&&(Fa(b[0])&&(a=b[0],b=Array.prototype.slice.call(b,1)),c=b[0],c!==t&&(c.chart=c.chart||{},c.chart.renderTo=this[0],new R[a](c,b[1]),d=this),c===t&&(d=V[H(this[0],"data-highcharts-chart")])),d}},getScript:a.getScript,inArray:a.inArray,adapterRun:function(b,c){return a(b)[c]()},grep:a.grep,map:function(a,c){for(var d=[],e=0,f=a.length;f>e;e++)d[e]=c.call(a[e],a[e],e,a);return d},offset:function(b){return a(b).offset()},addEvent:function(b,c,d){a(b).bind(c,d)},removeEvent:function(b,c,d){var e=y.removeEventListener?"removeEventListener":"detachEvent";y[e]&&b&&!b[e]&&(b[e]=function(){}),a(b).unbind(c,d)},fireEvent:function(b,c,d,e){var h,f=a.Event(c),g="detached"+c;!Aa&&d&&(delete d.layerX,delete d.layerY,delete d.returnValue),q(f,d),b[c]&&(b[g]=b[c],b[c]=null),a.each(["preventDefault","stopPropagation"],function(a,b){var c=f[b];f[b]=function(){try{c.call(f)}catch(a){"preventDefault"===b&&(h=!0)}}}),a(b).trigger(f),b[g]&&(b[c]=b[g],b[g]=null),e&&!f.isDefaultPrevented()&&!h&&e(f)},washMouseEvent:function(a){var c=a.originalEvent||a;return c.pageX===t&&(c.pageX=a.pageX,c.pageY=a.pageY),c},animate:function(b,c,d){var e=a(b);b.style||(b.style={}),c.d&&(b.toD=c.d,c.d=1),e.stop(),c.opacity!==t&&b.attr&&(c.opacity+="px"),e.animate(c,d)},stop:function(b){a(b).stop()}}}(I.jQuery);var S=I.HighchartsAdapter,N=S||{};S&&S.init.call(S,ub);var jb=N.adapterRun,Qb=N.getScript,Da=N.inArray,p=N.each,vb=N.grep,Rb=N.offset,Ua=N.map,K=N.addEvent,W=N.removeEvent,D=N.fireEvent,Sb=N.washMouseEvent,kb=N.animate,bb=N.stop,N={enabled:!0,x:0,y:15,style:{color:"#606060",cursor:"default",fontSize:"11px"}};E={colors:"#7cb5ec,#434348,#90ed7d,#f7a35c,#8085e9,#f15c80,#e4d354,#8085e8,#8d4653,#91e8e1".split(","),symbols:["circle","diamond","square","triangle","triangle-down"],lang:{loading:"Loading...",months:"January,February,March,April,May,June,July,August,September,October,November,December".split(","),shortMonths:"Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec".split(","),weekdays:"Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday".split(","),decimalPoint:".",numericSymbols:"k,M,G,T,P,E".split(","),resetZoom:"Reset zoom",resetZoomTitle:"Reset zoom level 1:1",thousandsSep:","},global:{useUTC:!0,canvasToolsURL:"http://code.highcharts.com/4.0.1/modules/canvas-tools.js",VMLRadialGradientURL:"http://code.highcharts.com/4.0.1/gfx/vml-radial-gradient.png"},chart:{borderColor:"#4572A7",borderRadius:0,defaultSeriesType:"line",ignoreHiddenSeries:!0,spacing:[10,10,15,10],backgroundColor:"#FFFFFF",plotBorderColor:"#C0C0C0",resetZoomButton:{theme:{zIndex:20},position:{align:"right",x:-10,y:10}}},title:{text:"Chart title",align:"center",margin:15,style:{color:"#333333",fontSize:"18px"}},subtitle:{text:"",align:"center",style:{color:"#555555"}},plotOptions:{line:{allowPointSelect:!1,showCheckbox:!1,animation:{duration:1e3},events:{},lineWidth:2,marker:{lineWidth:0,radius:4,lineColor:"#FFFFFF",states:{hover:{enabled:!0},select:{fillColor:"#FFFFFF",lineColor:"#000000",lineWidth:2}}},point:{events:{}},dataLabels:w(N,{align:"center",enabled:!1,formatter:function(){return null===this.y?"":Ga(this.y,-1)},verticalAlign:"bottom",y:0}),cropThreshold:300,pointRange:0,states:{hover:{marker:{},halo:{size:10,opacity:.25}},select:{marker:{}}},stickyTracking:!0,turboThreshold:1e3}},labels:{style:{position:"absolute",color:"#3E576F"}},legend:{enabled:!0,align:"center",layout:"horizontal",labelFormatter:function(){return this.name},borderColor:"#909090",borderRadius:0,navigation:{activeColor:"#274b6d",inactiveColor:"#CCC"},shadow:!1,itemStyle:{color:"#333333",fontSize:"12px",fontWeight:"bold"},itemHoverStyle:{color:"#000"},itemHiddenStyle:{color:"#CCC"},itemCheckboxStyle:{position:"absolute",width:"13px",height:"13px"},symbolPadding:5,verticalAlign:"bottom",x:0,y:0,title:{style:{fontWeight:"bold"}}},loading:{labelStyle:{fontWeight:"bold",position:"relative",top:"1em"},style:{position:"absolute",backgroundColor:"white",opacity:.5,textAlign:"center"}},tooltip:{enabled:!0,animation:aa,backgroundColor:"rgba(249, 249, 249, .85)",borderWidth:1,borderRadius:3,dateTimeLabelFormats:{millisecond:"%A, %b %e, %H:%M:%S.%L",second:"%A, %b %e, %H:%M:%S",minute:"%A, %b %e, %H:%M",hour:"%A, %b %e, %H:%M",day:"%A, %b %e, %Y",week:"Week from %A, %b %e, %Y",month:"%B %Y",year:"%Y"},headerFormat:'<span style="font-size: 10px">{point.key}</span><br/>',pointFormat:'<span style="color:{series.color}">â—</span> {series.name}: <b>{point.y}</b><br/>',shadow:!0,snap:Jb?25:10,style:{color:"#333333",cursor:"default",fontSize:"12px",padding:"8px",whiteSpace:"nowrap"}},credits:{enabled:!0,text:"Highcharts.com",href:"http://www.highcharts.com",position:{align:"right",x:-10,verticalAlign:"bottom",y:-5},style:{cursor:"pointer",color:"#909090",fontSize:"9px"}}};var ba=E.plotOptions,S=ba.line;Cb();var Tb=/rgba\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]?(?:\.[0-9]+)?)\s*\)/,Ub=/#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/,Vb=/rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/,ya=function(a){var c,d,b=[];return function(a){a&&a.stops?d=Ua(a.stops,function(a){return ya(a[1])}):(c=Tb.exec(a))?b=[z(c[1]),z(c[2]),z(c[3]),parseFloat(c[4],10)]:(c=Ub.exec(a))?b=[z(c[1],16),z(c[2],16),z(c[3],16),1]:(c=Vb.exec(a))&&(b=[z(c[1]),z(c[2]),z(c[3]),1])}(a),{get:function(c){var f;return d?(f=w(a),f.stops=[].concat(f.stops),p(d,function(a,b){f.stops[b]=[f.stops[b][0],a.get(c)]})):f=b&&!isNaN(b[0])?"rgb"===c?"rgb("+b[0]+","+b[1]+","+b[2]+")":"a"===c?b[3]:"rgba("+b.join(",")+")":a,f},brighten:function(a){if(d)p(d,function(b){b.brighten(a)});else if(ha(a)&&0!==a){var c;for(c=0;3>c;c++)b[c]+=z(255*a),b[c]<0&&(b[c]=0),b[c]>255&&(b[c]=255)}return this},rgba:b,setOpacity:function(a){return b[3]=a,this}}};P.prototype={init:function(a,b){this.element="span"===b?Y(b):y.createElementNS(xa,b),this.renderer=a},opacity:1,animate:function(a,b,c){b=m(b,va,!0),bb(this),b?(b=w(b,{}),c&&(b.complete=c),kb(this,a,b)):(this.attr(a),c&&c())},colorGradient:function(a,b,c){var e,f,g,h,i,j,k,l,o,n,d=this.renderer,s=[];if(a.linearGradient?f="linearGradient":a.radialGradient&&(f="radialGradient"),f){g=a[f],h=d.gradients,j=a.stops,o=c.radialReference,La(g)&&(a[f]=g={x1:g[0],y1:g[1],x2:g[2],y2:g[3],gradientUnits:"userSpaceOnUse"}),"radialGradient"===f&&o&&!r(g.gradientUnits)&&(g=w(g,{cx:o[0]-o[2]/2+g.cx*o[2],cy:o[1]-o[2]/2+g.cy*o[2],r:g.r*o[2],gradientUnits:"userSpaceOnUse"}));for(n in g)"id"!==n&&s.push(n,g[n]);for(n in j)s.push(j[n]);s=s.join(","),h[s]?a=h[s].attr("id"):(g.id=a="highcharts-"+tb++,h[s]=i=d.createElement(f).attr(g).add(d.defs),i.stops=[],p(j,function(a){0===a[1].indexOf("rgba")?(e=ya(a[1]),k=e.get("rgb"),l=e.get("a")):(k=a[1],l=1),a=d.createElement("stop").attr({offset:a[0],"stop-color":k,"stop-opacity":l}).add(i),i.stops.push(a)})),c.setAttribute(b,"url("+d.url+"#"+a+")")}},attr:function(a,b){var c,d,f,h,e=this.element,g=this;if("string"==typeof a&&b!==t&&(c=a,a={},a[c]=b),"string"==typeof a)g=(this[a+"Getter"]||this._defaultGetter).call(this,a,e);else{for(c in a)d=a[c],h=!1,this.symbolName&&/^(x|y|width|height|r|start|end|innerR|anchorX|anchorY)/.test(c)&&(f||(this.symbolAttr(a),f=!0),h=!0),!this.rotation||"x"!==c&&"y"!==c||(this.doTransform=!0),h||(this[c+"Setter"]||this._defaultSetter).call(this,d,c,e),this.shadows&&/^(width|height|visibility|x|y|d|transform|cx|cy|r)$/.test(c)&&this.updateShadows(c,d);this.doTransform&&(this.updateTransform(),this.doTransform=!1)}return g},updateShadows:function(a,b){for(var c=this.shadows,d=c.length;d--;)c[d].setAttribute(a,"height"===a?v(b-(c[d].cutHeight||0),0):"d"===a?this.d:b)},addClass:function(a){var b=this.element,c=H(b,"class")||"";return-1===c.indexOf(a)&&H(b,"class",c+" "+a),this},symbolAttr:function(a){var b=this;p("x,y,r,start,end,width,height,innerR,anchorX,anchorY".split(","),function(c){b[c]=m(a[c],b[c])}),b.attr({d:b.renderer.symbols[b.symbolName](b.x,b.y,b.width,b.height,b)})},clip:function(a){return this.attr("clip-path",a?"url("+this.renderer.url+"#"+a.id+")":Q)},crisp:function(a){var b,d,c={},e=a.strokeWidth||this.strokeWidth||this.attr&&this.attr("stroke-width")||0;d=u(e)%2/2,a.x=T(a.x||this.x||0)+d,a.y=T(a.y||this.y||0)+d,a.width=T((a.width||this.width||0)-2*d),a.height=T((a.height||this.height||0)-2*d),a.strokeWidth=e;for(b in a)this[b]!==a[b]&&(this[b]=c[b]=a[b]);return c},css:function(a){var e,f,b=this.styles,c={},d=this.element,g="";if(e=!b,a&&a.color&&(a.fill=a.color),b)for(f in a)a[f]!==b[f]&&(c[f]=a[f],e=!0);if(e){if(e=this.textWidth=a&&a.width&&"text"===d.nodeName.toLowerCase()&&z(a.width),b&&(a=q(b,c)),this.styles=a,e&&(fa||!aa&&this.renderer.forExport)&&delete a.width,Aa&&!aa)G(this.element,a);else{b=function(a,b){return"-"+b.toLowerCase()};for(f in a)g+=f.replace(/([A-Z])/g,b)+":"+a[f]+";";H(d,"style",g)}e&&this.added&&this.renderer.buildText(this)}return this},on:function(a,b){var c=this,d=c.element;return $a&&"click"===a?(d.ontouchstart=function(a){c.touchEventFired=Date.now(),a.preventDefault(),b.call(d,a)},d.onclick=function(a){(-1===wa.indexOf("Android")||Date.now()-(c.touchEventFired||0)>1100)&&b.call(d,a)}):d["on"+a]=b,this},setRadialReference:function(a){return this.element.radialReference=a,this},translate:function(a,b){return this.attr({translateX:a,translateY:b})},invert:function(){return this.inverted=!0,this.updateTransform(),this},updateTransform:function(){var a=this.translateX||0,b=this.translateY||0,c=this.scaleX,d=this.scaleY,e=this.inverted,f=this.rotation,g=this.element;e&&(a+=this.attr("width"),b+=this.attr("height")),a=["translate("+a+","+b+")"],e?a.push("rotate(90) scale(-1,1)"):f&&a.push("rotate("+f+" "+(g.getAttribute("x")||0)+" "+(g.getAttribute("y")||0)+")"),(r(c)||r(d))&&a.push("scale("+m(c,1)+" "+m(d,1)+")"),a.length&&g.setAttribute("transform",a.join(" "))},toFront:function(){var a=this.element;return a.parentNode.appendChild(a),this},align:function(a,b,c){var d,e,f,g,h={};return e=this.renderer,f=e.alignedObjects,a?(this.alignOptions=a,this.alignByTranslate=b,(!c||Fa(c))&&(this.alignTo=d=c||"renderer",ja(f,this),f.push(this),c=null)):(a=this.alignOptions,b=this.alignByTranslate,d=this.alignTo),c=m(c,e[d],e),d=a.align,e=a.verticalAlign,f=(c.x||0)+(a.x||0),g=(c.y||0)+(a.y||0),("right"===d||"center"===d)&&(f+=(c.width-(a.width||0))/{right:1,center:2}[d]),h[b?"translateX":"x"]=u(f),("bottom"===e||"middle"===e)&&(g+=(c.height-(a.height||0))/({bottom:1,middle:2}[e]||1)),h[b?"translateY":"y"]=u(g),this[this.placed?"animate":"attr"](h),this.placed=!0,this.alignAttr=h,this},getBBox:function(){var c,d,a=this.bBox,b=this.renderer,e=this.rotation;c=this.element;var f=this.styles,g=e*Ca;d=this.textStr;var h;if((""===d||Ob.test(d))&&(h="num."+d.toString().length+(f?"|"+f.fontSize+"|"+f.fontFamily:"")),h&&(a=b.cache[h]),!a){if(c.namespaceURI===xa||b.forExport){try{a=c.getBBox?q({},c.getBBox()):{width:c.offsetWidth,height:c.offsetHeight}}catch(i){}(!a||a.width<0)&&(a={width:0,height:0})}else a=this.htmlGetBBox();b.isSVG&&(c=a.width,d=a.height,Aa&&f&&"11px"===f.fontSize&&"16.9"===d.toPrecision(3)&&(a.height=d=14),e&&(a.width=M(d*ea(g))+M(c*Z(g)),a.height=M(d*Z(g))+M(c*ea(g)))),this.bBox=a,h&&(b.cache[h]=a)}return a},show:function(a){return a&&this.element.namespaceURI===xa?(this.element.removeAttribute("visibility"),this):this.attr({visibility:a?"inherit":"visible"})},hide:function(){return this.attr({visibility:"hidden"})},fadeOut:function(a){var b=this;b.animate({opacity:0},{duration:a||150,complete:function(){b.hide()}})},add:function(a){var g,h,b=this.renderer,c=a||b,d=c.element||b.box,e=this.element,f=this.zIndex;if(a&&(this.parentGroup=a),this.parentInverted=a&&a.inverted,void 0!==this.textStr&&b.buildText(this),f&&(c.handleZ=!0,f=z(f)),c.handleZ)for(a=d.childNodes,g=0;g<a.length;g++)if(b=a[g],c=H(b,"zIndex"),b!==e&&(z(c)>f||!r(f)&&r(c))){d.insertBefore(e,b),h=!0;break}return h||d.appendChild(e),this.added=!0,this.onAdd&&this.onAdd(),this},safeRemoveChild:function(a){var b=a.parentNode;b&&b.removeChild(a)},destroy:function(){var e,f,a=this,b=a.element||{},c=a.shadows,d=a.renderer.isSVG&&"SPAN"===b.nodeName&&a.parentGroup;if(b.onclick=b.onmouseout=b.onmouseover=b.onmousemove=b.point=null,bb(a),a.clipPath&&(a.clipPath=a.clipPath.destroy()),a.stops){for(f=0;f<a.stops.length;f++)a.stops[f]=a.stops[f].destroy();a.stops=null}for(a.safeRemoveChild(b),c&&p(c,function(b){a.safeRemoveChild(b)});d&&0===d.div.childNodes.length;)b=d.parentGroup,a.safeRemoveChild(d.div),delete d.div,d=b;a.alignTo&&ja(a.renderer.alignedObjects,a);for(e in a)delete a[e];return null},shadow:function(a,b,c){var e,f,h,i,j,k,d=[],g=this.element;if(a){for(i=m(a.width,3),j=(a.opacity||.15)/i,k=this.parentInverted?"(-1,-1)":"("+m(a.offsetX,1)+", "+m(a.offsetY,1)+")",e=1;i>=e;e++)f=g.cloneNode(0),h=2*i+1-2*e,H(f,{isShadow:"true",stroke:a.color||"black","stroke-opacity":j*e,"stroke-width":h,transform:"translate"+k,fill:Q}),c&&(H(f,"height",v(H(f,"height")-h,0)),f.cutHeight=h),b?b.element.appendChild(f):g.parentNode.insertBefore(f,g),d.push(f);this.shadows=d}return this},xGetter:function(a){return"circle"===this.element.nodeName&&(a={x:"cx",y:"cy"}[a]||a),this._defaultGetter(a)},_defaultGetter:function(a){return a=m(this[a],this.element?this.element.getAttribute(a):null,0),/^[0-9\.]+$/.test(a)&&(a=parseFloat(a)),a},dSetter:function(a,b,c){a&&a.join&&(a=a.join(" ")),/(NaN| {2}|^$)/.test(a)&&(a="M 0 0"),c.setAttribute(b,a),this[b]=a},dashstyleSetter:function(a){var b;if(a=a&&a.toLowerCase()){for(a=a.replace("shortdashdotdot","3,1,1,1,1,1,").replace("shortdashdot","3,1,1,1").replace("shortdot","1,1,").replace("shortdash","3,1,").replace("longdash","8,3,").replace(/dot/g,"1,3,").replace("dash","4,3,").replace(/,$/,"").split(","),b=a.length;b--;)a[b]=z(a[b])*this.element.getAttribute("stroke-width");a=a.join(","),this.element.setAttribute("stroke-dasharray",a)}},alignSetter:function(a){this.element.setAttribute("text-anchor",{left:"start",center:"middle",right:"end"}[a])},opacitySetter:function(a,b,c){this[b]=a,c.setAttribute(b,a)},"stroke-widthSetter":function(a,b,c){0===a&&(a=1e-5),this.strokeWidth=a,c.setAttribute(b,a)},titleSetter:function(a){var b=this.element.getElementsByTagName("title")[0];b||(b=y.createElementNS(xa,"title"),this.element.appendChild(b)),b.textContent=a},textSetter:function(a){a!==this.textStr&&(delete this.bBox,this.textStr=a,this.added&&this.renderer.buildText(this))},fillSetter:function(a,b,c){"string"==typeof a?c.setAttribute(b,a):a&&this.colorGradient(a,b,c)},zIndexSetter:function(a,b,c){c.setAttribute(b,a),this[b]=a},_defaultSetter:function(a,b,c){c.setAttribute(b,a)}},P.prototype.yGetter=P.prototype.xGetter,P.prototype.translateXSetter=P.prototype.translateYSetter=P.prototype.rotationSetter=P.prototype.verticalAlignSetter=P.prototype.scaleXSetter=P.prototype.scaleYSetter=function(a,b){this[b]=a,this.doTransform=!0},P.prototype.strokeSetter=P.prototype.fillSetter;var ta=function(){this.init.apply(this,arguments)};ta.prototype={Element:P,init:function(a,b,c,d,e){var g,f=location,d=this.createElement("svg").attr({version:"1.1"}).css(this.getStyle(d));g=d.element,a.appendChild(g),-1===a.innerHTML.indexOf("xmlns")&&H(g,"xmlns",xa),this.isSVG=!0,this.box=g,this.boxWrapper=d,this.alignedObjects=[],this.url=(Ta||ib)&&y.getElementsByTagName("base").length?f.href.replace(/#.*?$/,"").replace(/([\('\)])/g,"\\$1").replace(/ /g,"%20"):"",this.createElement("desc").add().element.appendChild(y.createTextNode("Created with Highcharts 4.0.1")),this.defs=this.createElement("defs").add(),this.forExport=e,this.gradients={},this.cache={},this.setSize(b,c,!1);var h;Ta&&a.getBoundingClientRect&&(this.subPixelFix=b=function(){G(a,{left:0,top:0}),h=a.getBoundingClientRect(),G(a,{left:Ka(h.left)-h.left+"px",top:Ka(h.top)-h.top+"px"})},b(),K(I,"resize",b))},getStyle:function(a){return this.style=q({fontFamily:'"Lucida Grande", "Lucida Sans Unicode", Arial, Helvetica, sans-serif',fontSize:"12px"},a)},isHidden:function(){return!this.boxWrapper.getBBox().width},destroy:function(){var a=this.defs;return this.box=null,this.boxWrapper=this.boxWrapper.destroy(),Oa(this.gradients||{}),this.gradients=null,a&&(this.defs=a.destroy()),this.subPixelFix&&W(I,"resize",this.subPixelFix),this.alignedObjects=null},createElement:function(a){var b=new this.Element;return b.init(this,a),b},draw:function(){},buildText:function(a){for(var h,i,b=a.element,c=this,d=c.forExport,e=m(a.textStr,"").toString(),f=-1!==e.indexOf("<"),g=b.childNodes,j=H(b,"x"),k=a.styles,l=a.textWidth,o=k&&k.lineHeight,n=g.length,s=function(a){return o?z(o):c.fontMetrics(/(px|em)$/.test(a&&a.style.fontSize)?a.style.fontSize:k&&k.fontSize||c.style.fontSize||12).h};n--;)b.removeChild(g[n]);f||-1!==e.indexOf(" ")?(h=/<.*style="([^"]+)".*>/,i=/<.*href="(http[^"]+)".*>/,l&&!a.added&&this.box.appendChild(b),e=f?e.replace(/<(b|strong)>/g,'<span style="font-weight:bold">').replace(/<(i|em)>/g,'<span style="font-style:italic">').replace(/<a/g,"<span").replace(/<\/(b|strong|i|em|a)>/g,"</span>").split(/<br.*?>/g):[e],""===e[e.length-1]&&e.pop(),p(e,function(e,f){var g,n=0,e=e.replace(/<span/g,"|||<span").replace(/<\/span>/g,"</span>|||");g=e.split("|||"),p(g,function(e){if(""!==e||1===g.length){var p,o={},m=y.createElementNS(xa,"tspan");if(h.test(e)&&(p=e.match(h)[1].replace(/(;| |^)color([ :])/,"$1fill$2"),H(m,"style",p)),i.test(e)&&!d&&(H(m,"onclick",'location.href="'+e.match(i)[1]+'"'),G(m,{cursor:"pointer"})),e=(e.replace(/<(.|\n)*?>/g,"")||" ").replace(/</g,"<").replace(/>/g,">")," "!==e&&(m.appendChild(y.createTextNode(e)),n?o.dx=0:f&&null!==j&&(o.x=j),H(m,o),!n&&f&&(!aa&&d&&G(m,{display:"block"}),H(m,"dy",s(m),ib&&m.offsetHeight)),b.appendChild(m),n++,l))for(var $,r,e=e.replace(/([^\^])-/g,"$1- ").split(" "),o=e.length>1&&"nowrap"!==k.whiteSpace,B=a._clipHeight,q=[],v=s(),t=1;o&&(e.length||q.length);)delete a.bBox,$=a.getBBox(),r=$.width,!aa&&c.forExport&&(r=c.measureSpanWidth(m.firstChild.data,a.styles)),$=r>l,$&&1!==e.length?(m.removeChild(m.firstChild),q.unshift(e.pop())):(e=q,q=[],e.length&&(t++,B&&t*v>B?(e=["..."],a.attr("title",a.textStr)):(m=y.createElementNS(xa,"tspan"),H(m,{dy:v,x:j}),p&&H(m,"style",p),b.appendChild(m),r>l&&(l=r)))),e.length&&m.appendChild(y.createTextNode(e.join(" ").replace(/- /g,"-")))}})})):b.appendChild(y.createTextNode(e))},button:function(a,b,c,d,e,f,g,h,i){var l,o,n,s,m,p,j=this.label(a,b,c,i,null,null,null,null,"button"),k=0,a={x1:0,y1:0,x2:0,y2:1},e=w({"stroke-width":1,stroke:"#CCCCCC",fill:{linearGradient:a,stops:[[0,"#FEFEFE"],[1,"#F6F6F6"]]},r:2,padding:5,style:{color:"black"}},e);return n=e.style,delete e.style,f=w(e,{stroke:"#68A",fill:{linearGradient:a,stops:[[0,"#FFF"],[1,"#ACF"]]}},f),s=f.style,delete f.style,g=w(e,{stroke:"#68A",fill:{linearGradient:a,stops:[[0,"#9BD"],[1,"#CDF"]]}},g),m=g.style,delete g.style,h=w(e,{style:{color:"#CCC"}},h),p=h.style,delete h.style,K(j.element,Aa?"mouseover":"mouseenter",function(){3!==k&&j.attr(f).css(s)}),K(j.element,Aa?"mouseout":"mouseleave",function(){3!==k&&(l=[e,f,g][k],o=[n,s,m][k],j.attr(l).css(o))}),j.setState=function(a){(j.state=k=a)?2===a?j.attr(g).css(m):3===a&&j.attr(h).css(p):j.attr(e).css(n)},j.on("click",function(){3!==k&&d.call(j)}).attr(e).css(q({cursor:"default"},n))},crispLine:function(a,b){return a[1]===a[4]&&(a[1]=a[4]=u(a[1])-b%2/2),a[2]===a[5]&&(a[2]=a[5]=u(a[2])+b%2/2),a},path:function(a){var b={fill:Q};return La(a)?b.d=a:ca(a)&&q(b,a),this.createElement("path").attr(b)},circle:function(a,b,c){return a=ca(a)?a:{x:a,y:b,r:c},b=this.createElement("circle"),b.xSetter=function(a){this.element.setAttribute("cx",a)},b.ySetter=function(a){this.element.setAttribute("cy",a)},b.attr(a)},arc:function(a,b,c,d,e,f){return ca(a)&&(b=a.y,c=a.r,d=a.innerR,e=a.start,f=a.end,a=a.x),a=this.symbol("arc",a||0,b||0,c||0,c||0,{innerR:d||0,start:e||0,end:f||0}),a.r=c,a},rect:function(a,b,c,d,e,f){var e=ca(a)?a.r:e,g=this.createElement("rect"),a=ca(a)?a:a===t?{}:{x:a,y:b,width:v(c,0),height:v(d,0)};return f!==t&&(a.strokeWidth=f,a=g.crisp(a)),e&&(a.r=e),g.rSetter=function(a){H(this.element,{rx:a,ry:a})},g.attr(a)},setSize:function(a,b,c){var d=this.alignedObjects,e=d.length;for(this.width=a,this.height=b,this.boxWrapper[m(c,!0)?"animate":"attr"]({width:a,height:b});e--;)d[e].align()},g:function(a){var b=this.createElement("g");return r(a)?b.attr({"class":"highcharts-"+a}):b},image:function(a,b,c,d,e){var f={preserveAspectRatio:Q};return arguments.length>1&&q(f,{x:b,y:c,width:d,height:e}),f=this.createElement("image").attr(f),f.element.setAttributeNS?f.element.setAttributeNS("http://www.w3.org/1999/xlink","href",a):f.element.setAttribute("hc-svg-href",a),f},symbol:function(a,b,c,d,e,f){var g,j,k,h=this.symbols[a],h=h&&h(u(b),u(c),d,e,f),i=/^url\((.*?)\)$/;return h?(g=this.path(h),q(g,{symbolName:a,x:b,y:c,width:d,height:e}),f&&q(g,f)):i.test(a)&&(k=function(a,b){a.element&&(a.attr({width:b[0],height:b[1]}),a.alignByTranslate||a.translate(u((d-b[0])/2),u((e-b[1])/2)))},j=a.match(i)[1],a=Kb[j],g=this.image(j).attr({x:b,y:c}),g.isImg=!0,a?k(g,a):(g.attr({width:0,height:0}),Y("img",{onload:function(){k(g,Kb[j]=[this.width,this.height])},src:j}))),g},symbols:{circle:function(a,b,c,d){var e=.166*c;return["M",a+c/2,b,"C",a+c+e,b,a+c+e,b+d,a+c/2,b+d,"C",a-e,b+d,a-e,b,a+c/2,b,"Z"]},square:function(a,b,c,d){return["M",a,b,"L",a+c,b,a+c,b+d,a,b+d,"Z"]},triangle:function(a,b,c,d){return["M",a+c/2,b,"L",a+c,b+d,a,b+d,"Z"]},"triangle-down":function(a,b,c,d){return["M",a,b,"L",a+c,b,a+c/2,b+d,"Z"]},diamond:function(a,b,c,d){return["M",a+c/2,b,"L",a+c,b+d/2,a+c/2,b+d,a,b+d/2,"Z"]},arc:function(a,b,c,d,e){var f=e.start,c=e.r||c||d,g=e.end-.001,d=e.innerR,h=e.open,i=Z(f),j=ea(f),k=Z(g),g=ea(g),e=e.end-f<ma?0:1;return["M",a+c*i,b+c*j,"A",c,c,0,e,1,a+c*k,b+c*g,h?"M":"L",a+d*k,b+d*g,"A",d,d,0,e,0,a+d*i,b+d*j,h?"":"Z"]},callout:function(a,b,c,d,e){var f=C(e&&e.r||0,c,d),g=f+6,h=e&&e.anchorX,i=e&&e.anchorY,e=u(e.strokeWidth||0)%2/2;return a+=e,b+=e,e=["M",a+f,b,"L",a+c-f,b,"C",a+c,b,a+c,b,a+c,b+f,"L",a+c,b+d-f,"C",a+c,b+d,a+c,b+d,a+c-f,b+d,"L",a+f,b+d,"C",a,b+d,a,b+d,a,b+d-f,"L",a,b+f,"C",a,b,a,b,a+f,b],h&&h>c&&i>b+g&&b+d-g>i?e.splice(13,3,"L",a+c,i-6,a+c+6,i,a+c,i+6,a+c,b+d-f):h&&0>h&&i>b+g&&b+d-g>i?e.splice(33,3,"L",a,i+6,a-6,i,a,i-6,a,b+f):i&&i>d&&h>a+g&&a+c-g>h?e.splice(23,3,"L",h+6,b+d,h,b+d+6,h-6,b+d,a+f,b+d):i&&0>i&&h>a+g&&a+c-g>h&&e.splice(3,3,"L",h-6,b,h,b-6,h+6,b,c-f,b),e}},clipRect:function(a,b,c,d){var e="highcharts-"+tb++,f=this.createElement("clipPath").attr({id:e}).add(this.defs),a=this.rect(a,b,c,d,0).add(f);return a.id=e,a.clipPath=f,a},text:function(a,b,c,d){var e=fa||!aa&&this.forExport,f={};return d&&!this.forExport?this.html(a,b,c):(f.x=Math.round(b||0),c&&(f.y=Math.round(c)),(a||0===a)&&(f.text=a),a=this.createElement("text").attr(f),e&&a.css({position:"absolute"}),d||(a.xSetter=function(a,b,c){var e,f,d=c.childNodes;for(f=1;f<d.length;f++)e=d[f],e.getAttribute("x")===c.getAttribute("x")&&e.setAttribute("x",a);c.setAttribute(b,a)}),a)},fontMetrics:function(a){var a=a||this.style.fontSize,a=/px/.test(a)?z(a):/em/.test(a)?12*parseFloat(a):12,a=24>a?a+4:u(1.2*a),b=u(.8*a);return{h:a,b:b}},label:function(a,b,c,d,e,f,g,h,i){function j(){var a,b;a=s.element.style,J=(void 0===Va||void 0===wb||n.styles.textAlign)&&s.textStr&&s.getBBox(),n.width=(Va||J.width||0)+2*x+v,n.height=(wb||J.height||0)+2*x,na=x+o.fontMetrics(a&&a.fontSize).b,z&&(m||(a=u(-L*x),b=h?-na:0,n.box=m=d?o.symbol(d,a,b,n.width,n.height,B):o.rect(a,b,n.width,n.height,0,B[Pb]),m.attr("fill",Q).add(n)),m.isImg||m.attr(q({width:u(n.width),height:u(n.height)},B)),B=null)}function k(){var c,a=n.styles,a=a&&a.textAlign,b=v+x*(1-L);c=h?0:na,r(Va)&&J&&("center"===a||"right"===a)&&(b+={center:.5,right:1}[a]*(Va-J.width)),(b!==s.x||c!==s.y)&&(s.attr("x",b),c!==t&&s.attr("y",c)),s.x=b,s.y=c}function l(a,b){m?m.attr(a,b):B[a]=b}var m,J,Va,wb,xb,yb,na,z,o=this,n=o.g(i),s=o.text("",0,0,g).attr({zIndex:1}),L=0,x=3,v=0,y=0,B={};n.onAdd=function(){s.add(n),n.attr({text:a||"",x:b,y:c}),m&&r(e)&&n.attr({anchorX:e,anchorY:f})},n.widthSetter=function(a){Va=a},n.heightSetter=function(a){wb=a},n.paddingSetter=function(a){r(a)&&a!==x&&(x=a,k())},n.paddingLeftSetter=function(a){r(a)&&a!==v&&(v=a,k())},n.alignSetter=function(a){L={left:0,center:.5,right:1}[a]},n.textSetter=function(a){a!==t&&s.textSetter(a),j(),k()},n["stroke-widthSetter"]=function(a,b){a&&(z=!0),y=a%2/2,l(b,a)},n.strokeSetter=n.fillSetter=n.rSetter=function(a,b){"fill"===b&&a&&(z=!0),l(b,a)
|
2 |
-
},n.anchorXSetter=function(a,b){e=a,l(b,a+y-xb)},n.anchorYSetter=function(a,b){f=a,l(b,a-yb)},n.xSetter=function(a){n.x=a,L&&(a-=L*((Va||J.width)+x)),xb=u(a),n.attr("translateX",xb)},n.ySetter=function(a){yb=n.y=u(a),n.attr("translateY",yb)};var A=n.css;return q(n,{css:function(a){if(a){var b={},a=w(a);p("fontSize,fontWeight,fontFamily,color,lineHeight,width,textDecoration,textShadow".split(","),function(c){a[c]!==t&&(b[c]=a[c],delete a[c])}),s.css(b)}return A.call(n,a)},getBBox:function(){return{width:J.width+2*x,height:J.height+2*x,x:J.x-x,y:J.y-x}},shadow:function(a){return m&&m.shadow(a),n},destroy:function(){W(n.element,"mouseenter"),W(n.element,"mouseleave"),s&&(s=s.destroy()),m&&(m=m.destroy()),P.prototype.destroy.call(n),n=o=j=k=l=null}})}},Za=ta,q(P.prototype,{htmlCss:function(a){var b=this.element;return(b=a&&"SPAN"===b.tagName&&a.width)&&(delete a.width,this.textWidth=b,this.updateTransform()),this.styles=q(this.styles,a),G(this.element,a),this},htmlGetBBox:function(){var a=this.element,b=this.bBox;return b||("text"===a.nodeName&&(a.style.position="absolute"),b=this.bBox={x:a.offsetLeft,y:a.offsetTop,width:a.offsetWidth,height:a.offsetHeight}),b},htmlUpdateTransform:function(){if(this.added){var a=this.renderer,b=this.element,c=this.translateX||0,d=this.translateY||0,e=this.x||0,f=this.y||0,g=this.textAlign||"left",h={left:0,center:.5,right:1}[g],i=this.shadows;if(G(b,{marginLeft:c,marginTop:d}),i&&p(i,function(a){G(a,{marginLeft:c+1,marginTop:d+1})}),this.inverted&&p(b.childNodes,function(c){a.invertChild(c,b)}),"SPAN"===b.tagName){var k,j=this.rotation,l=z(this.textWidth),o=[j,g,b.innerHTML,this.textWidth].join(",");o!==this.cTT&&(k=a.fontMetrics(b.style.fontSize).b,r(j)&&this.setSpanRotation(j,h,k),i=m(this.elemWidth,b.offsetWidth),i>l&&/[ \-]/.test(b.textContent||b.innerText)&&(G(b,{width:l+"px",display:"block",whiteSpace:"normal"}),i=l),this.getSpanCorrection(i,k,h,j,g)),G(b,{left:e+(this.xCorr||0)+"px",top:f+(this.yCorr||0)+"px"}),ib&&(k=b.offsetHeight),this.cTT=o}}else this.alignOnAdd=!0},setSpanRotation:function(a,b,c){var d={},e=Aa?"-ms-transform":ib?"-webkit-transform":Ta?"MozTransform":Ib?"-o-transform":"";d[e]=d.transform="rotate("+a+"deg)",d[e+(Ta?"Origin":"-origin")]=d.transformOrigin=100*b+"% "+c+"px",G(this.element,d)},getSpanCorrection:function(a,b,c){this.xCorr=-a*c,this.yCorr=-b}}),q(ta.prototype,{html:function(a,b,c){var d=this.createElement("span"),e=d.element,f=d.renderer;return d.textSetter=function(a){a!==e.innerHTML&&delete this.bBox,e.innerHTML=this.textStr=a},d.xSetter=d.ySetter=d.alignSetter=d.rotationSetter=function(a,b){"align"===b&&(b="textAlign"),d[b]=a,d.htmlUpdateTransform()},d.attr({text:a,x:u(b),y:u(c)}).css({position:"absolute",whiteSpace:"nowrap",fontFamily:this.style.fontFamily,fontSize:this.style.fontSize}),d.css=d.htmlCss,f.isSVG&&(d.add=function(a){var b,c=f.box.parentNode,j=[];if(this.parentGroup=a){if(b=a.div,!b){for(;a;)j.push(a),a=a.parentGroup;p(j.reverse(),function(a){var d;b=a.div=a.div||Y(Ja,{className:H(a.element,"class")},{position:"absolute",left:(a.translateX||0)+"px",top:(a.translateY||0)+"px"},b||c),d=b.style,q(a,{translateXSetter:function(b,c){d.left=b+"px",a[c]=b,a.doTransform=!0},translateYSetter:function(b,c){d.top=b+"px",a[c]=b,a.doTransform=!0},visibilitySetter:function(a,b){d[b]=a}})})}}else b=c;return b.appendChild(e),d.added=!0,d.alignOnAdd&&d.htmlUpdateTransform(),d}),d}});var X;if(!aa&&!fa){R.VMLElement=X={init:function(a,b){var c=["<",b,' filled="f" stroked="f"'],d=["position: ","absolute",";"],e=b===Ja;("shape"===b||e)&&d.push("left:0;top:0;width:1px;height:1px;"),d.push("visibility: ",e?"hidden":"visible"),c.push(' style="',d.join(""),'"/>'),b&&(c=e||"span"===b||"img"===b?c.join(""):a.prepVML(c),this.element=Y(c)),this.renderer=a},add:function(a){var b=this.renderer,c=this.element,d=b.box,d=a?a.element||a:d;return a&&a.inverted&&b.invertChild(c,d),d.appendChild(c),this.added=!0,this.alignOnAdd&&!this.deferUpdateTransform&&this.updateTransform(),this.onAdd&&this.onAdd(),this},updateTransform:P.prototype.htmlUpdateTransform,setSpanRotation:function(){var a=this.rotation,b=Z(a*Ca),c=ea(a*Ca);G(this.element,{filter:a?["progid:DXImageTransform.Microsoft.Matrix(M11=",b,", M12=",-c,", M21=",c,", M22=",b,", sizingMethod='auto expand')"].join(""):Q})},getSpanCorrection:function(a,b,c,d,e){var i,f=d?Z(d*Ca):1,g=d?ea(d*Ca):0,h=m(this.elemHeight,this.element.offsetHeight);this.xCorr=0>f&&-a,this.yCorr=0>g&&-h,i=0>f*g,this.xCorr+=g*b*(i?1-c:c),this.yCorr-=f*b*(d?i?c:1-c:1),e&&"left"!==e&&(this.xCorr-=a*c*(0>f?-1:1),d&&(this.yCorr-=h*c*(0>g?-1:1)),G(this.element,{textAlign:e}))},pathToVML:function(a){for(var b=a.length,c=[];b--;)ha(a[b])?c[b]=u(10*a[b])-5:"Z"===a[b]?c[b]="x":(c[b]=a[b],!a.isArc||"wa"!==a[b]&&"at"!==a[b]||(c[b+5]===c[b+7]&&(c[b+7]+=a[b+7]>a[b+5]?1:-1),c[b+6]===c[b+8]&&(c[b+8]+=a[b+8]>a[b+6]?1:-1)));return c.join(" ")||"x"},clip:function(a){var c,b=this;return a?(c=a.members,ja(c,b),c.push(b),b.destroyClip=function(){ja(c,b)},a=a.getCSS(b)):(b.destroyClip&&b.destroyClip(),a={clip:hb?"inherit":"rect(auto)"}),b.css(a)},css:P.prototype.htmlCss,safeRemoveChild:function(a){a.parentNode&&Pa(a)},destroy:function(){return this.destroyClip&&this.destroyClip(),P.prototype.destroy.apply(this)},on:function(a,b){return this.element["on"+a]=function(){var a=I.event;a.target=a.srcElement,b(a)},this},cutOffPath:function(a,b){var c,a=a.split(/[ ,]/);return c=a.length,(9===c||11===c)&&(a[c-4]=a[c-2]=z(a[c-2])-10*b),a.join(" ")},shadow:function(a,b,c){var e,h,j,l,o,n,s,d=[],f=this.element,g=this.renderer,i=f.style,k=f.path;if(k&&"string"!=typeof k.value&&(k="x"),o=k,a){for(n=m(a.width,3),s=(a.opacity||.15)/n,e=1;3>=e;e++)l=2*n+1-2*e,c&&(o=this.cutOffPath(k.value,l+.5)),j=['<shape isShadow="true" strokeweight="',l,'" filled="false" path="',o,'" coordsize="10 10" style="',f.style.cssText,'" />'],h=Y(g.prepVML(j),null,{left:z(i.left)+m(a.offsetX,1),top:z(i.top)+m(a.offsetY,1)}),c&&(h.cutOff=l+1),j=['<stroke color="',a.color||"black",'" opacity="',s*e,'"/>'],Y(g.prepVML(j),null,null,h),b?b.element.appendChild(h):f.parentNode.insertBefore(h,f),d.push(h);this.shadows=d}return this},updateShadows:sa,setAttr:function(a,b){hb?this.element[a]=b:this.element.setAttribute(a,b)},classSetter:function(a){this.element.className=a},dashstyleSetter:function(a,b,c){(c.getElementsByTagName("stroke")[0]||Y(this.renderer.prepVML(["<stroke/>"]),null,null,c))[b]=a||"solid",this[b]=a},dSetter:function(a,b,c){var d=this.shadows,a=a||[];if(this.d=a.join(" "),c.path=a=this.pathToVML(a),d)for(c=d.length;c--;)d[c].path=d[c].cutOff?this.cutOffPath(a,d[c].cutOff):a;this.setAttr(b,a)},fillSetter:function(a,b,c){var d=c.nodeName;"SPAN"===d?c.style.color=a:"IMG"!==d&&(c.filled=a!==Q,this.setAttr("fillcolor",this.renderer.color(a,c,b,this)))},opacitySetter:sa,rotationSetter:function(a,b,c){c=c.style,this[b]=c[b]=a,c.left=-u(ea(a*Ca)+1)+"px",c.top=u(Z(a*Ca))+"px"},strokeSetter:function(a,b,c){this.setAttr("strokecolor",this.renderer.color(a,c,b))},"stroke-widthSetter":function(a,b,c){c.stroked=!!a,this[b]=a,ha(a)&&(a+="px"),this.setAttr("strokeweight",a)},titleSetter:function(a,b){this.setAttr(b,a)},visibilitySetter:function(a,b,c){"inherit"===a&&(a="visible"),this.shadows&&p(this.shadows,function(c){c.style[b]=a}),"DIV"===c.nodeName&&(a="hidden"===a?"-999em":0,hb||(c.style[b]=a?"visible":"hidden"),b="top"),c.style[b]=a},xSetter:function(a,b,c){this[b]=a,"x"===b?b="left":"y"===b&&(b="top"),this.updateClipping?(this[b]=a,this.updateClipping()):c.style[b]=a},zIndexSetter:function(a,b,c){c.style[b]=a}},X=ka(P,X),X.prototype.ySetter=X.prototype.widthSetter=X.prototype.heightSetter=X.prototype.xSetter;var ga={Element:X,isIE8:wa.indexOf("MSIE 8.0")>-1,init:function(a,b,c,d){var e;if(this.alignedObjects=[],d=this.createElement(Ja).css(q(this.getStyle(d),{position:"relative"})),e=d.element,a.appendChild(d.element),this.isVML=!0,this.box=e,this.boxWrapper=d,this.cache={},this.setSize(b,c,!1),!y.namespaces.hcv){y.namespaces.add("hcv","urn:schemas-microsoft-com:vml");try{y.createStyleSheet().cssText="hcv\\:fill, hcv\\:path, hcv\\:shape, hcv\\:stroke{ behavior:url(#default#VML); display: inline-block; } "}catch(f){y.styleSheets[0].cssText+="hcv\\:fill, hcv\\:path, hcv\\:shape, hcv\\:stroke{ behavior:url(#default#VML); display: inline-block; } "}}},isHidden:function(){return!this.box.offsetWidth},clipRect:function(a,b,c,d){var e=this.createElement(),f=ca(a);return q(e,{members:[],left:(f?a.x:a)+1,top:(f?a.y:b)+1,width:(f?a.width:c)-1,height:(f?a.height:d)-1,getCSS:function(a){var b=a.element,c=b.nodeName,a=a.inverted,d=this.top-("shape"===c?b.offsetTop:0),e=this.left,b=e+this.width,f=d+this.height,d={clip:"rect("+u(a?e:d)+"px,"+u(a?f:b)+"px,"+u(a?b:f)+"px,"+u(a?d:e)+"px)"};return!a&&hb&&"DIV"===c&&q(d,{width:b+"px",height:f+"px"}),d},updateClipping:function(){p(e.members,function(a){a.element&&a.css(e.getCSS(a))})}})},color:function(a,b,c,d){var f,h,i,e=this,g=/^rgba/,j=Q;if(a&&a.linearGradient?i="gradient":a&&a.radialGradient&&(i="pattern"),i){var k,l,n,s,m,J,L,r,o=a.linearGradient||a.radialGradient,x="",a=a.stops,v=[],q=function(){h=['<fill colors="'+v.join(",")+'" opacity="',m,'" o:opacity2="',s,'" type="',i,'" ',x,'focus="100%" method="any" />'],Y(e.prepVML(h),null,null,b)};if(n=a[0],r=a[a.length-1],n[0]>0&&a.unshift([0,n[1]]),r[0]<1&&a.push([1,r[1]]),p(a,function(a,b){g.test(a[1])?(f=ya(a[1]),k=f.get("rgb"),l=f.get("a")):(k=a[1],l=1),v.push(100*a[0]+"% "+k),b?(m=l,J=k):(s=l,L=k)}),"fill"===c)if("gradient"===i)c=o.x1||o[0]||0,a=o.y1||o[1]||0,n=o.x2||o[2]||0,o=o.y2||o[3]||0,x='angle="'+(90-180*U.atan((o-a)/(n-c))/ma)+'"',q();else{var w,j=o.r,t=2*j,u=2*j,y=o.cx,B=o.cy,na=b.radialReference,j=function(){na&&(w=d.getBBox(),y+=(na[0]-w.x)/w.width-.5,B+=(na[1]-w.y)/w.height-.5,t*=na[2]/w.width,u*=na[2]/w.height),x='src="'+E.global.VMLRadialGradientURL+'" size="'+t+","+u+'" origin="0.5,0.5" position="'+y+","+B+'" color2="'+L+'" ',q()};d.added?j():d.onAdd=j,j=J}else j=k}else g.test(a)&&"IMG"!==b.tagName?(f=ya(a),h=["<",c,' opacity="',f.get("a"),'"/>'],Y(this.prepVML(h),null,null,b),j=f.get("rgb")):(j=b.getElementsByTagName(c),j.length&&(j[0].opacity=1,j[0].type="solid"),j=a);return j},prepVML:function(a){var b=this.isIE8,a=a.join("");return b?(a=a.replace("/>",' xmlns="urn:schemas-microsoft-com:vml" />'),a=-1===a.indexOf('style="')?a.replace("/>",' style="display:inline-block;behavior:url(#default#VML);" />'):a.replace('style="','style="display:inline-block;behavior:url(#default#VML);')):a=a.replace("<","<hcv:"),a},text:ta.prototype.html,path:function(a){var b={coordsize:"10 10"};return La(a)?b.d=a:ca(a)&&q(b,a),this.createElement("shape").attr(b)},circle:function(a,b,c){var d=this.symbol("circle");return ca(a)&&(c=a.r,b=a.y,a=a.x),d.isCircle=!0,d.r=c,d.attr({x:a,y:b})},g:function(a){var b;return a&&(b={className:"highcharts-"+a,"class":"highcharts-"+a}),this.createElement(Ja).attr(b)},image:function(a,b,c,d,e){var f=this.createElement("img").attr({src:a});return arguments.length>1&&f.attr({x:b,y:c,width:d,height:e}),f},createElement:function(a){return"rect"===a?this.symbol(a):ta.prototype.createElement.call(this,a)},invertChild:function(a,b){var c=this,d=b.style,e="IMG"===a.tagName&&a.style;G(a,{flip:"x",left:z(d.width)-(e?z(e.top):1),top:z(d.height)-(e?z(e.left):1),rotation:-90}),p(a.childNodes,function(b){c.invertChild(b,a)})},symbols:{arc:function(a,b,c,d,e){var f=e.start,g=e.end,h=e.r||c||d,c=e.innerR,d=Z(f),i=ea(f),j=Z(g),k=ea(g);return g-f===0?["x"]:(f=["wa",a-h,b-h,a+h,b+h,a+h*d,b+h*i,a+h*j,b+h*k],e.open&&!c&&f.push("e","M",a,b),f.push("at",a-c,b-c,a+c,b+c,a+c*j,b+c*k,a+c*d,b+c*i,"x","e"),f.isArc=!0,f)},circle:function(a,b,c,d,e){return e&&(c=d=2*e.r),e&&e.isCircle&&(a-=c/2,b-=d/2),["wa",a,b,a+c,b+d,a+c,b+d/2,a+c,b+d/2,"e"]},rect:function(a,b,c,d,e){return ta.prototype.symbols[r(e)&&e.r?"callout":"square"].call(0,a,b,c,d,e)}}};R.VMLRenderer=X=function(){this.init.apply(this,arguments)},X.prototype=w(ta.prototype,ga),Za=X}ta.prototype.measureSpanWidth=function(a,b){var d,c=y.createElement("span");return d=y.createTextNode(a),c.appendChild(d),G(c,b),this.box.appendChild(c),d=c.offsetWidth,Pa(c),d};var Lb;fa&&(R.CanVGRenderer=X=function(){xa="http://www.w3.org/1999/xhtml"},X.prototype.symbols={},Lb=function(){function a(){var d,a=b.length;for(d=0;a>d;d++)b[d]();b=[]}var b=[];return{push:function(c,d){0===b.length&&Qb(d,a),b.push(c)}}}(),Za=X),Sa.prototype={addLabel:function(){var l,a=this.axis,b=a.options,c=a.chart,d=a.horiz,e=a.categories,f=a.names,g=this.pos,h=b.labels,i=a.tickPositions,d=d&&e&&!h.step&&!h.staggerLines&&!h.rotation&&c.plotWidth/i.length||!d&&(c.margin[3]||.33*c.chartWidth),j=g===i[0],k=g===i[i.length-1],f=e?m(e[g],f[g],g):g,e=this.label,o=i.info;a.isDatetimeAxis&&o&&(l=b.dateTimeLabelFormats[o.higherRanks[g]||o.unitName]),this.isFirst=j,this.isLast=k,b=a.labelFormatter.call({axis:a,chart:c,isFirst:j,isLast:k,dateTimeLabelFormat:l,value:a.isLog?da(ia(f)):f}),g=d&&{width:v(1,u(d-2*(h.padding||10)))+"px"},g=q(g,h.style),r(e)?e&&e.attr({text:b}).css(g):(l={align:a.labelAlign},ha(h.rotation)&&(l.rotation=h.rotation),d&&h.ellipsis&&(l._clipHeight=a.len/i.length),this.label=r(b)&&h.enabled?c.renderer.text(b,0,0,h.useHTML).attr(l).css(g).add(a.labelGroup):null)},getLabelSize:function(){var a=this.label,b=this.axis;return a?a.getBBox()[b.horiz?"height":"width"]:0},getLabelSides:function(){var a=this.label.getBBox(),b=this.axis,c=b.horiz,d=b.options.labels,a=c?a.width:a.height,b=c?d.x-a*{left:0,center:.5,right:1}[b.labelAlign]:0;return[b,c?a+b:a]},handleOverflow:function(a,b){var l,o,n,c=!0,d=this.axis,e=this.isFirst,f=this.isLast,g=d.horiz?b.x:b.y,h=d.reversed,i=d.tickPositions,j=this.getLabelSides(),k=j[0],j=j[1],s=this.label.line||0;if(l=d.labelEdge,o=d.justifyLabels&&(e||f),l[s]===t||g+k>l[s]?l[s]=g+j:o||(c=!1),o){l=(o=d.justifyToPlot)?d.pos:0,o=o?l+d.len:d.chart.chartWidth;do a+=e?1:-1,n=d.ticks[i[a]];while(i[a]&&(!n||n.label.line!==s));d=n&&n.label.xy&&n.label.xy.x+n.getLabelSides()[e?0:1],e&&!h||f&&h?l>g+k&&(g=l-k,n&&g+j>d&&(c=!1)):g+j>o&&(g=o-j,n&&d>g+k&&(c=!1)),b.x=g}return c},getPosition:function(a,b,c,d){var e=this.axis,f=e.chart,g=d&&f.oldChartHeight||f.chartHeight;return{x:a?e.translate(b+c,null,null,d)+e.transB:e.left+e.offset+(e.opposite?(d&&f.oldChartWidth||f.chartWidth)-e.right-e.left:0),y:a?g-e.bottom+e.offset-(e.opposite?e.height:0):g-e.translate(b+c,null,null,d)-e.transB}},getLabelPosition:function(a,b,c,d,e,f,g,h){var i=this.axis,j=i.transA,k=i.reversed,l=i.staggerLines,o=i.chart.renderer.fontMetrics(e.style.fontSize).b,n=e.rotation,a=a+e.x-(f&&d?f*j*(k?-1:1):0),b=b+e.y-(f&&!d?f*j*(k?1:-1):0);return n&&2===i.side&&(b-=o-o*Z(n*Ca)),!r(e.y)&&!n&&(b+=o-c.getBBox().height/2),l&&(c.line=g/(h||1)%l,b+=c.line*(i.labelOffset/l)),{x:a,y:b}},getMarkPath:function(a,b,c,d,e,f){return f.crispLine(["M",a,b,"L",a+(e?0:-c),b+(e?c:0)],d)},render:function(a,b,c){var d=this.axis,e=d.options,f=d.chart.renderer,g=d.horiz,h=this.type,i=this.label,j=this.pos,k=e.labels,l=this.gridLine,o=h?h+"Grid":"grid",n=h?h+"Tick":"tick",s=e[o+"LineWidth"],p=e[o+"LineColor"],J=e[o+"LineDashStyle"],L=e[n+"Length"],o=e[n+"Width"]||0,x=e[n+"Color"],r=e[n+"Position"],n=this.mark,v=k.step,q=!0,u=d.tickmarkOffset,w=this.getPosition(g,j,u,b),y=w.x,w=w.y,B=g&&y===d.pos+d.len||!g&&w===d.pos?-1:1;this.isActive=!0,s&&(j=d.getPlotLinePath(j+u,s*B,b,!0),l===t&&(l={stroke:p,"stroke-width":s},J&&(l.dashstyle=J),h||(l.zIndex=1),b&&(l.opacity=0),this.gridLine=l=s?f.path(j).attr(l).add(d.gridGroup):null),!b&&l&&j&&l[this.isNew?"attr":"animate"]({d:j,opacity:c})),o&&L&&("inside"===r&&(L=-L),d.opposite&&(L=-L),h=this.getMarkPath(y,w,L,o*B,g,f),n?n.animate({d:h,opacity:c}):this.mark=f.path(h).attr({stroke:x,"stroke-width":o,opacity:c}).add(d.axisGroup)),i&&!isNaN(y)&&(i.xy=w=this.getLabelPosition(y,w,i,g,k,u,a,v),this.isFirst&&!this.isLast&&!m(e.showFirstLabel,1)||this.isLast&&!this.isFirst&&!m(e.showLastLabel,1)?q=!1:!d.isRadial&&!k.step&&!k.rotation&&!b&&0!==c&&(q=this.handleOverflow(a,w)),v&&a%v&&(q=!1),q&&!isNaN(w.y)?(w.opacity=c,i[this.isNew?"attr":"animate"](w),this.isNew=!1):i.attr("y",-9999))},destroy:function(){Oa(this,this.axis)}},R.PlotLineOrBand=function(a,b){this.axis=a,b&&(this.options=b,this.id=b.id)},R.PlotLineOrBand.prototype={render:function(){var p,a=this,b=a.axis,c=b.horiz,d=(b.pointRange||0)/2,e=a.options,f=e.label,g=a.label,h=e.width,i=e.to,j=e.from,k=r(j)&&r(i),l=e.value,o=e.dashStyle,n=a.svgElem,s=[],J=e.color,L=e.zIndex,x=e.events,q={},t=b.chart.renderer;if(b.isLog&&(j=za(j),i=za(i),l=za(l)),h)s=b.getPlotLinePath(l,h),q={stroke:J,"stroke-width":h},o&&(q.dashstyle=o);else{if(!k)return;j=v(j,b.min-d),i=C(i,b.max+d),s=b.getPlotBandPath(j,i,e),J&&(q.fill=J),e.borderWidth&&(q.stroke=e.borderColor,q["stroke-width"]=e.borderWidth)}if(r(L)&&(q.zIndex=L),n)s?n.animate({d:s},null,n.onGetPath):(n.hide(),n.onGetPath=function(){n.show()},g&&(a.label=g=g.destroy()));else if(s&&s.length&&(a.svgElem=n=t.path(s).attr(q).add(),x))for(p in d=function(b){n.on(b,function(c){x[b].apply(a,[c])})},x)d(p);return f&&r(f.text)&&s&&s.length&&b.width>0&&b.height>0?(f=w({align:c&&k&&"center",x:c?!k&&4:10,verticalAlign:!c&&k&&"middle",y:c?k?16:10:k?6:-4,rotation:c&&!k&&90},f),g||(q={align:f.textAlign||f.align,rotation:f.rotation},r(L)&&(q.zIndex=L),a.label=g=t.text(f.text,0,0,f.useHTML).attr(q).css(f.style).add()),b=[s[1],s[4],m(s[6],s[1])],s=[s[2],s[5],m(s[7],s[2])],c=Na(b),k=Na(s),g.align(f,!1,{x:c,y:k,width:Ba(b)-c,height:Ba(s)-k}),g.show()):g&&g.hide(),a},destroy:function(){ja(this.axis.plotLinesAndBands,this),delete this.axis,Oa(this)}},la.prototype={defaultOptions:{dateTimeLabelFormats:{millisecond:"%H:%M:%S.%L",second:"%H:%M:%S",minute:"%H:%M",hour:"%H:%M",day:"%e. %b",week:"%e. %b",month:"%b '%y",year:"%Y"},endOnTick:!1,gridLineColor:"#C0C0C0",labels:N,lineColor:"#C0D0E0",lineWidth:1,minPadding:.01,maxPadding:.01,minorGridLineColor:"#E0E0E0",minorGridLineWidth:1,minorTickColor:"#A0A0A0",minorTickLength:2,minorTickPosition:"outside",startOfWeek:1,startOnTick:!1,tickColor:"#C0D0E0",tickLength:10,tickmarkPlacement:"between",tickPixelInterval:100,tickPosition:"outside",tickWidth:1,title:{align:"middle",style:{color:"#707070"}},type:"linear"},defaultYAxisOptions:{endOnTick:!0,gridLineWidth:1,tickPixelInterval:72,showLastLabel:!0,labels:{x:-8,y:3},lineWidth:0,maxPadding:.05,minPadding:.05,startOnTick:!0,tickWidth:0,title:{rotation:270,text:"Values"},stackLabels:{enabled:!1,formatter:function(){return Ga(this.total,-1)},style:N.style}},defaultLeftAxisOptions:{labels:{x:-15,y:null},title:{rotation:270}},defaultRightAxisOptions:{labels:{x:15,y:null},title:{rotation:90}},defaultBottomAxisOptions:{labels:{x:0,y:20},title:{rotation:0}},defaultTopAxisOptions:{labels:{x:0,y:-15},title:{rotation:0}},init:function(a,b){var c=b.isX;this.horiz=a.inverted?!c:c,this.coll=(this.isXAxis=c)?"xAxis":"yAxis",this.opposite=b.opposite,this.side=b.side||(this.horiz?this.opposite?0:2:this.opposite?1:3),this.setOptions(b);var d=this.options,e=d.type;this.labelFormatter=d.labels.formatter||this.defaultLabelFormatter,this.userOptions=b,this.minPixelPadding=0,this.chart=a,this.reversed=d.reversed,this.zoomEnabled=d.zoomEnabled!==!1,this.categories=d.categories||"category"===e,this.names=[],this.isLog="logarithmic"===e,this.isDatetimeAxis="datetime"===e,this.isLinked=r(d.linkedTo),this.tickmarkOffset=this.categories&&"between"===d.tickmarkPlacement?.5:0,this.ticks={},this.labelEdge=[],this.minorTicks={},this.plotLinesAndBands=[],this.alternateBands={},this.len=0,this.minRange=this.userMinRange=d.minRange||d.maxZoom,this.range=d.range,this.offset=d.offset||0,this.stacks={},this.oldStacks={},this.min=this.max=null,this.crosshair=m(d.crosshair,qa(a.options.tooltip.crosshairs)[c?0:1],!1);var f,d=this.options.events;-1===Da(this,a.axes)&&(c&&!this.isColorAxis?a.axes.splice(a.xAxis.length,0,this):a.axes.push(this),a[this.coll].push(this)),this.series=this.series||[],a.inverted&&c&&this.reversed===t&&(this.reversed=!0),this.removePlotLine=this.removePlotBand=this.removePlotBandOrLine;for(f in d)K(this,f,d[f]);this.isLog&&(this.val2lin=za,this.lin2val=ia)},setOptions:function(a){this.options=w(this.defaultOptions,this.isXAxis?{}:this.defaultYAxisOptions,[this.defaultTopAxisOptions,this.defaultRightAxisOptions,this.defaultBottomAxisOptions,this.defaultLeftAxisOptions][this.side],w(E[this.coll],a))},defaultLabelFormatter:function(){var g,a=this.axis,b=this.value,c=a.categories,d=this.dateTimeLabelFormat,e=E.lang.numericSymbols,f=e&&e.length,h=a.options.labels.format,a=a.isLog?b:a.tickInterval;if(h)g=Ia(h,this);else if(c)g=b;else if(d)g=cb(d,b);else if(f&&a>=1e3)for(;f--&&g===t;)c=Math.pow(1e3,f+1),a>=c&&null!==e[f]&&(g=Ga(b/c,-1)+e[f]);return g===t&&(g=M(b)>=1e4?Ga(b,0):Ga(b,-1,t,"")),g},getSeriesExtremes:function(){var a=this,b=a.chart;a.hasVisibleSeries=!1,a.dataMin=a.dataMax=null,a.buildStacks&&a.buildStacks(),p(a.series,function(c){if(c.visible||!b.options.chart.ignoreHiddenSeries){var d;d=c.options.threshold;var e;a.hasVisibleSeries=!0,a.isLog&&0>=d&&(d=null),a.isXAxis?(d=c.xData,d.length&&(a.dataMin=C(m(a.dataMin,d[0]),Na(d)),a.dataMax=v(m(a.dataMax,d[0]),Ba(d)))):(c.getExtremes(),e=c.dataMax,c=c.dataMin,r(c)&&r(e)&&(a.dataMin=C(m(a.dataMin,c),c),a.dataMax=v(m(a.dataMax,e),e)),r(d)&&(a.dataMin>=d?(a.dataMin=d,a.ignoreMinPadding=!0):a.dataMax<d&&(a.dataMax=d,a.ignoreMaxPadding=!0)))}})},translate:function(a,b,c,d,e,f){var g=1,h=0,i=d?this.oldTransA:this.transA,d=d?this.oldMin:this.min,j=this.minPixelPadding,e=(this.options.ordinal||this.isLog&&e)&&this.lin2val;return i||(i=this.transA),c&&(g*=-1,h=this.len),this.reversed&&(g*=-1,h-=g*(this.sector||this.len)),b?(a=a*g+h,a-=j,a=a/i+d,e&&(a=this.lin2val(a))):(e&&(a=this.val2lin(a)),"between"===f&&(f=.5),a=g*(a-d)*i+h+g*j+(ha(f)?i*f*this.pointRange:0)),a},toPixels:function(a,b){return this.translate(a,!1,!this.horiz,null,!0)+(b?0:this.pos)},toValue:function(a,b){return this.translate(a-(b?0:this.pos),!0,!this.horiz,null,!0)},getPlotLinePath:function(a,b,c,d,e){var i,j,o,f=this.chart,g=this.left,h=this.top,k=c&&f.oldChartHeight||f.chartHeight,l=c&&f.oldChartWidth||f.chartWidth;return i=this.transB,e=m(e,this.translate(a,null,null,c)),a=c=u(e+i),i=j=u(k-e-i),isNaN(e)?o=!0:this.horiz?(i=h,j=k-this.bottom,(g>a||a>g+this.width)&&(o=!0)):(a=g,c=l-this.right,(h>i||i>h+this.height)&&(o=!0)),o&&!d?null:f.renderer.crispLine(["M",a,i,"L",c,j],b||1)},getLinearTickPositions:function(a,b,c){var d,e=da(T(b/a)*a),f=da(Ka(c/a)*a),g=[];if(b===c&&ha(b))return[b];for(b=e;f>=b&&(g.push(b),b=da(b+a),b!==d);)d=b;return g},getMinorTickPositions:function(){var e,a=this.options,b=this.tickPositions,c=this.minorTickInterval,d=[];if(this.isLog)for(e=b.length,a=1;e>a;a++)d=d.concat(this.getLogTickPositions(c,b[a-1],b[a],!0));else if(this.isDatetimeAxis&&"auto"===a.minorTickInterval)d=d.concat(this.getTimeTicks(this.normalizeTimeTickInterval(c),this.min,this.max,a.startOfWeek)),d[0]<this.min&&d.shift();else for(b=this.min+(b[0]-this.min)%c;b<=this.max;b+=c)d.push(b);return d},adjustForMinRange:function(){var d,f,g,h,i,j,a=this.options,b=this.min,c=this.max,e=this.dataMax-this.dataMin>=this.minRange;if(this.isXAxis&&this.minRange===t&&!this.isLog&&(r(a.min)||r(a.max)?this.minRange=null:(p(this.series,function(a){for(i=a.xData,g=j=a.xIncrement?1:i.length-1;g>0;g--)h=i[g]-i[g-1],(f===t||f>h)&&(f=h)}),this.minRange=C(5*f,this.dataMax-this.dataMin))),c-b<this.minRange){var k=this.minRange;d=(k-c+b)/2,d=[b-d,m(a.min,b-d)],e&&(d[2]=this.dataMin),b=Ba(d),c=[b+k,m(a.max,b+k)],e&&(c[2]=this.dataMax),c=Na(c),k>c-b&&(d[0]=c-k,d[1]=m(a.min,c-k),b=Ba(d))}this.min=b,this.max=c},setAxisTranslation:function(a){var e,b=this,c=b.max-b.min,d=b.axisPointRange||0,f=0,g=0,h=b.linkedParent,i=!!b.categories,j=b.transA;(b.isXAxis||i||d)&&(h?(f=h.minPointOffset,g=h.pointRangePadding):p(b.series,function(a){var h=i?1:b.isXAxis?a.pointRange:b.axisPointRange||0,j=a.options.pointPlacement,n=a.closestPointRange;h>c&&(h=0),d=v(d,h),f=v(f,Fa(j)?0:h/2),g=v(g,"on"===j?0:h),!a.noSharedTooltip&&r(n)&&(e=r(e)?C(e,n):n)}),h=b.ordinalSlope&&e?b.ordinalSlope/e:1,b.minPointOffset=f*=h,b.pointRangePadding=g*=h,b.pointRange=C(d,c),b.closestPointRange=e),a&&(b.oldTransA=j),b.translationSlope=b.transA=j=b.len/(c+g||1),b.transB=b.horiz?b.left:b.bottom,b.minPixelPadding=j*f},setTickPositions:function(a){var s,b=this,c=b.chart,d=b.options,e=b.isLog,f=b.isDatetimeAxis,g=b.isXAxis,h=b.isLinked,i=b.options.tickPositioner,j=d.maxPadding,k=d.minPadding,l=d.tickInterval,o=d.minTickInterval,n=d.tickPixelInterval,$=b.categories;h?(b.linkedParent=c[b.coll][d.linkedTo],c=b.linkedParent.getExtremes(),b.min=m(c.min,c.dataMin),b.max=m(c.max,c.dataMax),d.type!==b.linkedParent.options.type&&ra(11,1)):(b.min=m(b.userMin,d.min,b.dataMin),b.max=m(b.userMax,d.max,b.dataMax)),e&&(!a&&C(b.min,m(b.dataMin,b.min))<=0&&ra(10,1),b.min=da(za(b.min)),b.max=da(za(b.max))),b.range&&r(b.max)&&(b.userMin=b.min=v(b.min,b.max-b.range),b.userMax=b.max,b.range=null),b.beforePadding&&b.beforePadding(),b.adjustForMinRange(),$||b.axisPointRange||b.usePercentage||h||!r(b.min)||!r(b.max)||!(c=b.max-b.min)||(r(d.min)||r(b.userMin)||!k||!(b.dataMin<0)&&b.ignoreMinPadding||(b.min-=c*k),r(d.max)||r(b.userMax)||!j||!(b.dataMax>0)&&b.ignoreMaxPadding||(b.max+=c*j)),ha(d.floor)&&(b.min=v(b.min,d.floor)),ha(d.ceiling)&&(b.max=C(b.max,d.ceiling)),b.min===b.max||void 0===b.min||void 0===b.max?b.tickInterval=1:h&&!l&&n===b.linkedParent.options.tickPixelInterval?b.tickInterval=b.linkedParent.tickInterval:(b.tickInterval=m(l,$?1:(b.max-b.min)*n/v(b.len,n)),!r(l)&&b.len<n&&!this.isRadial&&!this.isLog&&!$&&d.startOnTick&&d.endOnTick&&(s=!0,b.tickInterval/=4)),g&&!a&&p(b.series,function(a){a.processData(b.min!==b.oldMin||b.max!==b.oldMax)}),b.setAxisTranslation(!0),b.beforeSetTickPositions&&b.beforeSetTickPositions(),b.postProcessTickInterval&&(b.tickInterval=b.postProcessTickInterval(b.tickInterval)),b.pointRange&&(b.tickInterval=v(b.pointRange,b.tickInterval)),!l&&b.tickInterval<o&&(b.tickInterval=o),f||e||l||(b.tickInterval=nb(b.tickInterval,null,mb(b.tickInterval),d)),b.minorTickInterval="auto"===d.minorTickInterval&&b.tickInterval?b.tickInterval/5:d.minorTickInterval,b.tickPositions=a=d.tickPositions?[].concat(d.tickPositions):i&&i.apply(b,[b.min,b.max]),a||(!b.ordinalPositions&&(b.max-b.min)/b.tickInterval>v(2*b.len,200)&&ra(19,!0),a=f?b.getTimeTicks(b.normalizeTimeTickInterval(b.tickInterval,d.units),b.min,b.max,d.startOfWeek,b.ordinalPositions,b.closestPointRange,!0):e?b.getLogTickPositions(b.tickInterval,b.min,b.max):b.getLinearTickPositions(b.tickInterval,b.min,b.max),s&&a.splice(1,a.length-2),b.tickPositions=a),h||(e=a[0],f=a[a.length-1],h=b.minPointOffset||0,d.startOnTick?b.min=e:b.min-h>e&&a.shift(),d.endOnTick?b.max=f:b.max+h<f&&a.pop(),1===a.length&&(d=M(b.max)>1e13?1:.001,b.min-=d,b.max+=d))},setMaxTicks:function(){var a=this.chart,b=a.maxTicks||{},c=this.tickPositions,d=this._maxTicksKey=[this.coll,this.pos,this.len].join("-");!this.isLinked&&!this.isDatetimeAxis&&c&&c.length>(b[d]||0)&&this.options.alignTicks!==!1&&(b[d]=c.length),a.maxTicks=b},adjustTickAmount:function(){var a=this._maxTicksKey,b=this.tickPositions,c=this.chart.maxTicks;if(c&&c[a]&&!this.isDatetimeAxis&&!this.categories&&!this.isLinked&&this.options.alignTicks!==!1&&this.min!==t){var d=this.tickAmount,e=b.length;if(this.tickAmount=a=c[a],a>e){for(;b.length<a;)b.push(da(b[b.length-1]+this.tickInterval));this.transA*=(e-1)/(a-1),this.max=b[b.length-1]}r(d)&&a!==d&&(this.isDirty=!0)}},setScale:function(){var b,c,d,e,a=this.stacks;if(this.oldMin=this.min,this.oldMax=this.max,this.oldAxisLength=this.len,this.setAxisSize(),e=this.len!==this.oldAxisLength,p(this.series,function(a){(a.isDirtyData||a.isDirty||a.xAxis.isDirty)&&(d=!0)}),e||d||this.isLinked||this.forceRedraw||this.userMin!==this.oldUserMin||this.userMax!==this.oldUserMax){if(!this.isXAxis)for(b in a)for(c in a[b])a[b][c].total=null,a[b][c].cum=0;this.forceRedraw=!1,this.getSeriesExtremes(),this.setTickPositions(),this.oldUserMin=this.userMin,this.oldUserMax=this.userMax,this.isDirty||(this.isDirty=e||this.min!==this.oldMin||this.max!==this.oldMax)}else if(!this.isXAxis){this.oldStacks&&(a=this.stacks=this.oldStacks);for(b in a)for(c in a[b])a[b][c].cum=a[b][c].total}this.setMaxTicks()},setExtremes:function(a,b,c,d,e){var f=this,g=f.chart,c=m(c,!0),e=q(e,{min:a,max:b});D(f,"setExtremes",e,function(){f.userMin=a,f.userMax=b,f.eventArgs=e,f.isDirtyExtremes=!0,c&&g.redraw(d)})},zoom:function(a,b){var c=this.dataMin,d=this.dataMax,e=this.options;return this.allowZoomOutside||(r(c)&&a<=C(c,m(e.min,c))&&(a=t),r(d)&&b>=v(d,m(e.max,d))&&(b=t)),this.displayBtn=a!==t||b!==t,this.setExtremes(a,b,!1,t,{trigger:"zoom"}),!0},setAxisSize:function(){var a=this.chart,b=this.options,c=b.offsetLeft||0,d=this.horiz,e=m(b.width,a.plotWidth-c+(b.offsetRight||0)),f=m(b.height,a.plotHeight),g=m(b.top,a.plotTop),b=m(b.left,a.plotLeft+c),c=/%$/;c.test(f)&&(f=parseInt(f,10)/100*a.plotHeight),c.test(g)&&(g=parseInt(g,10)/100*a.plotHeight+a.plotTop),this.left=b,this.top=g,this.width=e,this.height=f,this.bottom=a.chartHeight-f-g,this.right=a.chartWidth-e-b,this.len=v(d?e:f,0),this.pos=d?b:g},getExtremes:function(){var a=this.isLog;return{min:a?da(ia(this.min)):this.min,max:a?da(ia(this.max)):this.max,dataMin:this.dataMin,dataMax:this.dataMax,userMin:this.userMin,userMax:this.userMax}},getThreshold:function(a){var b=this.isLog,c=b?ia(this.min):this.min,b=b?ia(this.max):this.max;return c>a||null===a?a=c:a>b&&(a=b),this.translate(a,0,1,0,1)},autoLabelAlign:function(a){return a=(m(a,0)-90*this.side+720)%360,a>15&&165>a?"right":a>195&&345>a?"left":"center"},getOffset:function(){var j,l,q,y,z,A,B,a=this,b=a.chart,c=b.renderer,d=a.options,e=a.tickPositions,f=a.ticks,g=a.horiz,h=a.side,i=b.inverted?[1,0,3,2][h]:h,k=0,o=0,n=d.title,s=d.labels,$=0,J=b.axisOffset,L=b.clipOffset,x=[-1,1,1,-1][h],u=1,w=m(s.maxStaggerLines,5),na=2===h?c.fontMetrics(s.style.fontSize).b:0;if(a.hasData=j=a.hasVisibleSeries||r(a.min)&&r(a.max)&&!!e,a.showAxis=b=j||m(d.showEmpty,!0),a.staggerLines=a.horiz&&s.staggerLines,a.axisGroup||(a.gridGroup=c.g("grid").attr({zIndex:d.gridZIndex||1}).add(),a.axisGroup=c.g("axis").attr({zIndex:d.zIndex||2}).add(),a.labelGroup=c.g("axis-labels").attr({zIndex:s.zIndex||7}).addClass("highcharts-"+a.coll.toLowerCase()+"-labels").add()),j||a.isLinked){if(a.labelAlign=m(s.align||a.autoLabelAlign(s.rotation)),p(e,function(b){f[b]?f[b].addLabel():f[b]=new Sa(a,b)}),a.horiz&&!a.staggerLines&&w&&!s.rotation){for(q=a.reversed?[].concat(e).reverse():e;w>u;){for(j=[],y=!1,s=0;s<q.length;s++)z=q[s],A=(A=f[z].label&&f[z].label.getBBox())?A.width:0,B=s%u,A&&(z=a.translate(z),j[B]!==t&&z<j[B]&&(y=!0),j[B]=z+A);if(!y)break;u++}u>1&&(a.staggerLines=u)}p(e,function(b){(0===h||2===h||{1:"left",3:"right"}[h]===a.labelAlign)&&($=v(f[b].getLabelSize(),$))}),a.staggerLines&&($*=a.staggerLines,a.labelOffset=$)}else for(q in f)f[q].destroy(),delete f[q];n&&n.text&&n.enabled!==!1&&(a.axisTitle||(a.axisTitle=c.text(n.text,0,0,n.useHTML).attr({zIndex:7,rotation:n.rotation||0,align:n.textAlign||{low:"left",middle:"center",high:"right"}[n.align]}).addClass("highcharts-"+this.coll.toLowerCase()+"-title").css(n.style).add(a.axisGroup),a.axisTitle.isNew=!0),b&&(k=a.axisTitle.getBBox()[g?"height":"width"],o=m(n.margin,g?5:10),l=n.offset),a.axisTitle[b?"show":"hide"]()),a.offset=x*m(d.offset,J[h]),a.axisTitleMargin=m(l,$+o+($&&x*d.labels[g?"y":"x"]-na)),J[h]=v(J[h],a.axisTitleMargin+k+x*a.offset),L[i]=v(L[i],2*T(d.lineWidth/2))},getLinePath:function(a){var b=this.chart,c=this.opposite,d=this.offset,e=this.horiz,f=this.left+(c?this.width:0)+d,d=b.chartHeight-this.bottom-(c?this.height:0)+d;return c&&(a*=-1),b.renderer.crispLine(["M",e?this.left:f,e?d:this.top,"L",e?b.chartWidth-this.right:f,e?d:b.chartHeight-this.bottom],a)},getTitlePosition:function(){var a=this.horiz,b=this.left,c=this.top,d=this.len,e=this.options.title,f=a?b:c,g=this.opposite,h=this.offset,i=z(e.style.fontSize||12),d={low:f+(a?0:d),middle:f+d/2,high:f+(a?d:0)}[e.align],b=(a?c+this.height:b)+(a?1:-1)*(g?-1:1)*this.axisTitleMargin+(2===this.side?i:0);
|
3 |
-
return{x:a?d:b+(g?this.width:0)+h+(e.x||0),y:a?b-(g?this.height:0)+h:d+(e.y||0)}},render:function(){var j,u,z,a=this,b=a.horiz,c=a.reversed,d=a.chart,e=d.renderer,f=a.options,g=a.isLog,h=a.isLinked,i=a.tickPositions,k=a.axisTitle,l=a.ticks,o=a.minorTicks,n=a.alternateBands,s=f.stackLabels,m=f.alternateGridColor,J=a.tickmarkOffset,L=f.lineWidth,x=d.hasRendered&&r(a.oldMin)&&!isNaN(a.oldMin),q=a.hasData,v=a.showAxis,w=f.labels.overflow,y=a.justifyLabels=b&&w!==!1;a.labelEdge.length=0,a.justifyToPlot="justify"===w,p([l,o,n],function(a){for(var b in a)a[b].isActive=!1}),(q||h)&&(a.minorTickInterval&&!a.categories&&p(a.getMinorTickPositions(),function(b){o[b]||(o[b]=new Sa(a,b,"minor")),x&&o[b].isNew&&o[b].render(null,!0),o[b].render(null,!1,1)}),i.length&&(j=i.slice(),(b&&c||!b&&!c)&&j.reverse(),y&&(j=j.slice(1).concat([j[0]])),p(j,function(b,c){y&&(c=c===j.length-1?0:c+1),(!h||b>=a.min&&b<=a.max)&&(l[b]||(l[b]=new Sa(a,b)),x&&l[b].isNew&&l[b].render(c,!0,.1),l[b].render(c,!1,1))}),J&&0===a.min&&(l[-1]||(l[-1]=new Sa(a,-1,null,!0)),l[-1].render(-1))),m&&p(i,function(b,c){c%2===0&&b<a.max&&(n[b]||(n[b]=new R.PlotLineOrBand(a)),u=b+J,z=i[c+1]!==t?i[c+1]+J:a.max,n[b].options={from:g?ia(u):u,to:g?ia(z):z,color:m},n[b].render(),n[b].isActive=!0)}),a._addedPlotLB||(p((f.plotLines||[]).concat(f.plotBands||[]),function(b){a.addPlotBandOrLine(b)}),a._addedPlotLB=!0)),p([l,o,n],function(a){var b,c,e=[],f=va?va.duration||500:0,g=function(){for(c=e.length;c--;)a[e[c]]&&!a[e[c]].isActive&&(a[e[c]].destroy(),delete a[e[c]])};for(b in a)a[b].isActive||(a[b].render(b,!1,0),a[b].isActive=!1,e.push(b));a!==n&&d.hasRendered&&f?f&&setTimeout(g,f):g()}),L&&(b=a.getLinePath(L),a.axisLine?a.axisLine.animate({d:b}):a.axisLine=e.path(b).attr({stroke:f.lineColor,"stroke-width":L,zIndex:7}).add(a.axisGroup),a.axisLine[v?"show":"hide"]()),k&&v&&(k[k.isNew?"attr":"animate"](a.getTitlePosition()),k.isNew=!1),s&&s.enabled&&a.renderStackTotals(),a.isDirty=!1},redraw:function(){var a=this.chart.pointer;a&&a.reset(!0),this.render(),p(this.plotLinesAndBands,function(a){a.render()}),p(this.series,function(a){a.isDirty=!0})},destroy:function(a){var d,b=this,c=b.stacks,e=b.plotLinesAndBands;a||W(b);for(d in c)Oa(c[d]),c[d]=null;for(p([b.ticks,b.minorTicks,b.alternateBands],function(a){Oa(a)}),a=e.length;a--;)e[a].destroy();p("stackTotalGroup,axisLine,axisTitle,axisGroup,cross,gridGroup,labelGroup".split(","),function(a){b[a]&&(b[a]=b[a].destroy())}),this.cross&&this.cross.destroy()},drawCrosshair:function(a,b){if(this.crosshair)if((r(b)||!m(this.crosshair.snap,!0))===!1)this.hideCrosshair();else{var c,d=this.crosshair,e=d.animation;m(d.snap,!0)?r(b)&&(c=this.chart.inverted!=this.horiz?b.plotX:this.len-b.plotY):c=this.horiz?a.chartX-this.pos:this.len-a.chartY+this.pos,c=this.isRadial?this.getPlotLinePath(this.isXAxis?b.x:m(b.stackY,b.y)):this.getPlotLinePath(null,null,null,null,c),null===c?this.hideCrosshair():this.cross?this.cross.attr({visibility:"visible"})[e?"animate":"attr"]({d:c},e):(e={"stroke-width":d.width||1,stroke:d.color||"#C0C0C0",zIndex:d.zIndex||2},d.dashStyle&&(e.dashstyle=d.dashStyle),this.cross=this.chart.renderer.path(c).attr(e).add())}},hideCrosshair:function(){this.cross&&this.cross.hide()}},q(la.prototype,{getPlotBandPath:function(a,b){var c=this.getPlotLinePath(b),d=this.getPlotLinePath(a);return d&&c?d.push(c[4],c[5],c[1],c[2]):d=null,d},addPlotBand:function(a){this.addPlotBandOrLine(a,"plotBands")},addPlotLine:function(a){this.addPlotBandOrLine(a,"plotLines")},addPlotBandOrLine:function(a,b){var c=new R.PlotLineOrBand(this,a).render(),d=this.userOptions;return c&&(b&&(d[b]=d[b]||[],d[b].push(a)),this.plotLinesAndBands.push(c)),c},removePlotBandOrLine:function(a){for(var b=this.plotLinesAndBands,c=this.options,d=this.userOptions,e=b.length;e--;)b[e].id===a&&b[e].destroy();p([c.plotLines||[],d.plotLines||[],c.plotBands||[],d.plotBands||[]],function(b){for(e=b.length;e--;)b[e].id===a&&ja(b,b[e])})}}),la.prototype.getTimeTicks=function(a,b,c,d){var h,e=[],f={},g=E.global.useUTC,i=new Date(b-Ra),j=a.unitRange,k=a.count;if(r(b)){j>=A.second&&(i.setMilliseconds(0),i.setSeconds(j>=A.minute?0:k*T(i.getSeconds()/k))),j>=A.minute&&i[Db](j>=A.hour?0:k*T(i[pb]()/k)),j>=A.hour&&i[Eb](j>=A.day?0:k*T(i[qb]()/k)),j>=A.day&&i[sb](j>=A.month?1:k*T(i[Xa]()/k)),j>=A.month&&(i[Fb](j>=A.year?0:k*T(i[fb]()/k)),h=i[gb]()),j>=A.year&&(h-=h%k,i[Gb](h)),j===A.week&&i[sb](i[Xa]()-i[rb]()+m(d,1)),b=1,Ra&&(i=new Date(i.getTime()+Ra)),h=i[gb]();for(var d=i.getTime(),l=i[fb](),o=i[Xa](),n=g?Ra:(864e5+6e4*i.getTimezoneOffset())%864e5;c>d;)e.push(d),j===A.year?d=eb(h+b*k,0):j===A.month?d=eb(h,l+b*k):g||j!==A.day&&j!==A.week?d+=j*k:d=eb(h,l,o+b*k*(j===A.day?1:7)),b++;e.push(d),p(vb(e,function(a){return j<=A.hour&&a%A.day===n}),function(a){f[a]="day"})}return e.info=q(a,{higherRanks:f,totalRange:j*k}),e},la.prototype.normalizeTimeTickInterval=function(a,b){var g,c=b||[["millisecond",[1,2,5,10,20,25,50,100,200,500]],["second",[1,2,5,10,15,30]],["minute",[1,2,5,10,15,30]],["hour",[1,2,3,4,6,8,12]],["day",[1,2]],["week",[1,2]],["month",[1,2,3,4,6]],["year",null]],d=c[c.length-1],e=A[d[0]],f=d[1];for(g=0;g<c.length&&(d=c[g],e=A[d[0]],f=d[1],!(c[g+1]&&a<=(e*f[f.length-1]+A[c[g+1][0]])/2));g++);return e===A.year&&5*e>a&&(f=[1,2,5]),c=nb(a/e,f,"year"===d[0]?v(mb(a/e),1):1),{unitRange:e,count:c,unitName:d[0]}},la.prototype.getLogTickPositions=function(a,b,c,d){var e=this.options,f=this.len,g=[];if(d||(this._minorAutoInterval=null),a>=.5)a=u(a),g=this.getLinearTickPositions(a,b,c);else if(a>=.08)for(var h,i,j,k,l,f=T(b),e=a>.3?[1,2,4]:a>.15?[1,2,4,6,8]:[1,2,3,4,5,6,7,8,9];c+1>f&&!l;f++)for(i=e.length,h=0;i>h&&!l;h++)j=za(ia(f)*e[h]),j>b&&(!d||c>=k)&&g.push(k),k>c&&(l=!0),k=j;else b=ia(b),c=ia(c),a=e[d?"minorTickInterval":"tickInterval"],a=m("auto"===a?null:a,this._minorAutoInterval,(c-b)*(e.tickPixelInterval/(d?5:1))/((d?f/this.tickPositions.length:f)||1)),a=nb(a,null,mb(a)),g=Ua(this.getLinearTickPositions(a,b,c),za),d||(this._minorAutoInterval=a/5);return d||(this.tickInterval=a),g};var Mb=R.Tooltip=function(){this.init.apply(this,arguments)};Mb.prototype={init:function(a,b){var c=b.borderWidth,d=b.style,e=z(d.padding);this.chart=a,this.options=b,this.crosshairs=[],this.now={x:0,y:0},this.isHidden=!0,this.label=a.renderer.label("",0,0,b.shape||"callout",null,null,b.useHTML,null,"tooltip").attr({padding:e,fill:b.backgroundColor,"stroke-width":c,r:b.borderRadius,zIndex:8}).css(d).css({padding:0}).add().attr({y:-9999}),fa||this.label.shadow(b.shadow),this.shared=b.shared},destroy:function(){this.label&&(this.label=this.label.destroy()),clearTimeout(this.hideTimer),clearTimeout(this.tooltipTimeout)},move:function(a,b,c,d){var e=this,f=e.now,g=e.options.animation!==!1&&!e.isHidden,h=e.followPointer||e.len>1;q(f,{x:g?(2*f.x+a)/3:a,y:g?(f.y+b)/2:b,anchorX:h?t:g?(2*f.anchorX+c)/3:c,anchorY:h?t:g?(f.anchorY+d)/2:d}),e.label.attr(f),g&&(M(a-f.x)>1||M(b-f.y)>1)&&(clearTimeout(this.tooltipTimeout),this.tooltipTimeout=setTimeout(function(){e&&e.move(a,b,c,d)},32))},hide:function(){var b,a=this;clearTimeout(this.hideTimer),this.isHidden||(b=this.chart.hoverPoints,this.hideTimer=setTimeout(function(){a.label.fadeOut(),a.isHidden=!0},m(this.options.hideDelay,500)),b&&p(b,function(a){a.setState()}),this.chart.hoverPoints=null)},getAnchor:function(a,b){var c,i,d=this.chart,e=d.inverted,f=d.plotTop,g=0,h=0,a=qa(a);return c=a[0].tooltipPos,this.followPointer&&b&&(b.chartX===t&&(b=d.pointer.normalize(b)),c=[b.chartX-d.plotLeft,b.chartY-f]),c||(p(a,function(a){i=a.series.yAxis,g+=a.plotX,h+=(a.plotLow?(a.plotLow+a.plotHigh)/2:a.plotY)+(!e&&i?i.top-f:0)}),g/=a.length,h/=a.length,c=[e?d.plotWidth-h:g,this.shared&&!e&&a.length>1&&b?b.chartY-f:e?d.plotHeight-g:h]),Ua(c,u)},getPosition:function(a,b,c){var g,d=this.chart,e=this.distance,f={},h=["y",d.chartHeight,b,c.plotY+d.plotTop],i=["x",d.chartWidth,a,c.plotX+d.plotLeft],j=c.ttBelow||d.inverted&&!c.negative||!d.inverted&&c.negative,k=function(a,b,c,d){var g=d-e>c,b=b>d+e+c,c=d-e-c;if(d+=e,j&&b)f[a]=d;else if(!j&&g)f[a]=c;else if(g)f[a]=c;else{if(!b)return!1;f[a]=d}},l=function(a,b,c,d){return e>d||d>b-e?!1:void(f[a]=c/2>d?1:d>b-c/2?b-c-2:d-c/2)},o=function(a){var b=h;h=i,i=b,g=a},n=function(){k.apply(0,h)!==!1?l.apply(0,i)===!1&&!g&&(o(!0),n()):g?f.x=f.y=0:(o(!0),n())};return(d.inverted||this.len>1)&&o(),n(),f},defaultFormatter:function(a){var d,b=this.points||qa(this),c=b[0].series;return d=[a.tooltipHeaderFormatter(b[0])],p(b,function(a){c=a.series,d.push(c.tooltipFormatter&&c.tooltipFormatter(a)||a.point.tooltipFormatter(c.tooltipOptions.pointFormat))}),d.push(a.options.footerFormat||""),d.join("")},refresh:function(a,b){var f,g,i,c=this.chart,d=this.label,e=this.options,h={},j=[];i=e.formatter||this.defaultFormatter;var k,h=c.hoverPoints,l=this.shared;clearTimeout(this.hideTimer),this.followPointer=qa(a)[0].series.tooltipOptions.followPointer,g=this.getAnchor(a,b),f=g[0],g=g[1],!l||a.series&&a.series.noSharedTooltip?h=a.getLabelConfig():(c.hoverPoints=a,h&&p(h,function(a){a.setState()}),p(a,function(a){a.setState("hover"),j.push(a.getLabelConfig())}),h={x:a[0].category,y:a[0].y},h.points=j,this.len=j.length,a=a[0]),i=i.call(h,this),h=a.series,this.distance=m(h.tooltipOptions.distance,16),i===!1?this.hide():(this.isHidden&&(bb(d),d.attr("opacity",1).show()),d.attr({text:i}),k=e.borderColor||a.color||h.color||"#606060",d.attr({stroke:k}),this.updatePosition({plotX:f,plotY:g,negative:a.negative,ttBelow:a.ttBelow}),this.isHidden=!1),D(c,"tooltipRefresh",{text:i,x:f+c.plotLeft,y:g+c.plotTop,borderColor:k})},updatePosition:function(a){var b=this.chart,c=this.label,c=(this.options.positioner||this.getPosition).call(this,c.width,c.height,a);this.move(u(c.x),u(c.y),a.plotX+b.plotLeft,a.plotY+b.plotTop)},tooltipHeaderFormatter:function(a){var h,b=a.series,c=b.tooltipOptions,d=c.dateTimeLabelFormats,e=c.xDateFormat,f=b.xAxis,g=f&&"datetime"===f.options.type&&ha(a.key),c=c.headerFormat,f=f&&f.closestPointRange;if(g&&!e){if(f){for(h in A)if(A[h]>=f||A[h]<=A.day&&a.key%A[h]>0){e=d[h];break}}else e=d.day;e=e||d.year}return g&&e&&(c=c.replace("{point.key}","{point.key:"+e+"}")),Ia(c,{point:a,series:b})}};var oa;$a=y.documentElement.ontouchstart!==t;var Wa=R.Pointer=function(a,b){this.init(a,b)};if(Wa.prototype={init:function(a,b){var f,c=b.chart,d=c.events,e=fa?"":c.zoomType,c=a.inverted;this.options=b,this.chart=a,this.zoomX=f=/x/.test(e),this.zoomY=e=/y/.test(e),this.zoomHor=f&&!c||e&&c,this.zoomVert=e&&!c||f&&c,this.hasZoom=f||e,this.runChartClick=d&&!!d.click,this.pinchDown=[],this.lastValidTouch={},R.Tooltip&&b.tooltip.enabled&&(a.tooltip=new Mb(a,b.tooltip),this.followTouchMove=b.tooltip.followTouchMove),this.setDOMEvents()},normalize:function(a,b){var c,d,a=a||window.event,a=Sb(a);return a.target||(a.target=a.srcElement),d=a.touches?a.touches.length?a.touches.item(0):a.changedTouches[0]:a,b||(this.chartPosition=b=Rb(this.chart.container)),d.pageX===t?(c=v(a.x,a.clientX-b.left),d=a.y):(c=d.pageX-b.left,d=d.pageY-b.top),q(a,{chartX:u(c),chartY:u(d)})},getCoordinates:function(a){var b={xAxis:[],yAxis:[]};return p(this.chart.axes,function(c){b[c.isXAxis?"xAxis":"yAxis"].push({axis:c,value:c.toValue(a[c.horiz?"chartX":"chartY"])})}),b},getIndex:function(a){var b=this.chart;return b.inverted?b.plotHeight+b.plotTop-a.chartY:a.chartX-b.plotLeft},runPointActions:function(a){var e,f,i,j,b=this.chart,c=b.series,d=b.tooltip,g=b.hoverPoint,h=b.hoverSeries,k=b.chartWidth,l=this.getIndex(a);if(d&&this.options.tooltip.shared&&(!h||!h.noSharedTooltip)){for(f=[],i=c.length,j=0;i>j;j++)c[j].visible&&c[j].options.enableMouseTracking!==!1&&!c[j].noSharedTooltip&&c[j].singularTooltips!==!0&&c[j].tooltipPoints.length&&(e=c[j].tooltipPoints[l])&&e.series&&(e._dist=M(l-e.clientX),k=C(k,e._dist),f.push(e));for(i=f.length;i--;)f[i]._dist>k&&f.splice(i,1);f.length&&f[0].clientX!==this.hoverX&&(d.refresh(f,a),this.hoverX=f[0].clientX)}c=h&&h.tooltipOptions.followPointer,h&&h.tracker&&!c?(e=h.tooltipPoints[l])&&e!==g&&e.onMouseOver(a):d&&c&&!d.isHidden&&(h=d.getAnchor([{}],a),d.updatePosition({plotX:h[0],plotY:h[1]})),d&&!this._onDocumentMouseMove&&(this._onDocumentMouseMove=function(a){V[oa]&&V[oa].pointer.onDocumentMouseMove(a)},K(y,"mousemove",this._onDocumentMouseMove)),p(b.axes,function(b){b.drawCrosshair(a,m(e,g))})},reset:function(a){var b=this.chart,c=b.hoverSeries,d=b.hoverPoint,e=b.tooltip,f=e&&e.shared?b.hoverPoints:d;(a=a&&e&&f)&&qa(f)[0].plotX===t&&(a=!1),a?(e.refresh(f),d&&d.setState(d.state,!0)):(d&&d.onMouseOut(),c&&c.onMouseOut(),e&&e.hide(),this._onDocumentMouseMove&&(W(y,"mousemove",this._onDocumentMouseMove),this._onDocumentMouseMove=null),p(b.axes,function(a){a.hideCrosshair()}),this.hoverX=null)},scaleGroups:function(a,b){var d,c=this.chart;p(c.series,function(e){d=a||e.getPlotBox(),e.xAxis&&e.xAxis.zoomEnabled&&(e.group.attr(d),e.markerGroup&&(e.markerGroup.attr(d),e.markerGroup.clip(b?c.clipRect:null)),e.dataLabelsGroup&&e.dataLabelsGroup.attr(d))}),c.clipRect.attr(b||c.clipBox)},dragStart:function(a){var b=this.chart;b.mouseIsDown=a.type,b.cancelClick=!1,b.mouseDownX=this.mouseDownX=a.chartX,b.mouseDownY=this.mouseDownY=a.chartY},drag:function(a){var l,b=this.chart,c=b.options.chart,d=a.chartX,e=a.chartY,f=this.zoomHor,g=this.zoomVert,h=b.plotLeft,i=b.plotTop,j=b.plotWidth,k=b.plotHeight,o=this.mouseDownX,n=this.mouseDownY;h>d?d=h:d>h+j&&(d=h+j),i>e?e=i:e>i+k&&(e=i+k),this.hasDragged=Math.sqrt(Math.pow(o-d,2)+Math.pow(n-e,2)),this.hasDragged>10&&(l=b.isInsidePlot(o-h,n-i),b.hasCartesianSeries&&(this.zoomX||this.zoomY)&&l&&!this.selectionMarker&&(this.selectionMarker=b.renderer.rect(h,i,f?1:j,g?1:k,0).attr({fill:c.selectionMarkerFill||"rgba(69,114,167,0.25)",zIndex:7}).add()),this.selectionMarker&&f&&(d-=o,this.selectionMarker.attr({width:M(d),x:(d>0?0:d)+o})),this.selectionMarker&&g&&(d=e-n,this.selectionMarker.attr({height:M(d),y:(d>0?0:d)+n})),l&&!this.selectionMarker&&c.panning&&b.pan(a,c.panning))},drop:function(a){var b=this.chart,c=this.hasPinched;if(this.selectionMarker){var i,d={xAxis:[],yAxis:[],originalEvent:a.originalEvent||a},a=this.selectionMarker,e=a.attr?a.attr("x"):a.x,f=a.attr?a.attr("y"):a.y,g=a.attr?a.attr("width"):a.width,h=a.attr?a.attr("height"):a.height;(this.hasDragged||c)&&(p(b.axes,function(a){if(a.zoomEnabled){var b=a.horiz,c=a.toValue(b?e:f),b=a.toValue(b?e+g:f+h);!isNaN(c)&&!isNaN(b)&&(d[a.coll].push({axis:a,min:C(c,b),max:v(c,b)}),i=!0)}}),i&&D(b,"selection",d,function(a){b.zoom(q(a,c?{animation:!1}:null))})),this.selectionMarker=this.selectionMarker.destroy(),c&&this.scaleGroups()}b&&(G(b.container,{cursor:b._cursor}),b.cancelClick=this.hasDragged>10,b.mouseIsDown=this.hasDragged=this.hasPinched=!1,this.pinchDown=[])},onContainerMouseDown:function(a){a=this.normalize(a),a.preventDefault&&a.preventDefault(),this.dragStart(a)},onDocumentMouseUp:function(a){V[oa]&&V[oa].pointer.drop(a)},onDocumentMouseMove:function(a){var b=this.chart,c=this.chartPosition,d=b.hoverSeries,a=this.normalize(a,c);c&&d&&!this.inClass(a.target,"highcharts-tracker")&&!b.isInsidePlot(a.chartX-b.plotLeft,a.chartY-b.plotTop)&&this.reset()},onContainerMouseLeave:function(){var a=V[oa];a&&(a.pointer.reset(),a.pointer.chartPosition=null)},onContainerMouseMove:function(a){var b=this.chart;oa=b.index,a=this.normalize(a),"mousedown"===b.mouseIsDown&&this.drag(a),(this.inClass(a.target,"highcharts-tracker")||b.isInsidePlot(a.chartX-b.plotLeft,a.chartY-b.plotTop))&&!b.openMenu&&this.runPointActions(a)},inClass:function(a,b){for(var c;a;){if(c=H(a,"class")){if(-1!==c.indexOf(b))return!0;if(-1!==c.indexOf("highcharts-container"))return!1}a=a.parentNode}},onTrackerMouseOut:function(a){var b=this.chart.hoverSeries,c=(a=a.relatedTarget||a.toElement)&&a.point&&a.point.series;!b||b.options.stickyTracking||this.inClass(a,"highcharts-tooltip")||c===b||b.onMouseOut()},onContainerClick:function(a){var b=this.chart,c=b.hoverPoint,d=b.plotLeft,e=b.plotTop,a=this.normalize(a);a.cancelBubble=!0,b.cancelClick||(c&&this.inClass(a.target,"highcharts-tracker")?(D(c.series,"click",q(a,{point:c})),b.hoverPoint&&c.firePointEvent("click",a)):(q(a,this.getCoordinates(a)),b.isInsidePlot(a.chartX-d,a.chartY-e)&&D(b,"click",a)))},setDOMEvents:function(){var a=this,b=a.chart.container;b.onmousedown=function(b){a.onContainerMouseDown(b)},b.onmousemove=function(b){a.onContainerMouseMove(b)},b.onclick=function(b){a.onContainerClick(b)},K(b,"mouseleave",a.onContainerMouseLeave),1===ab&&K(y,"mouseup",a.onDocumentMouseUp),$a&&(b.ontouchstart=function(b){a.onContainerTouchStart(b)},b.ontouchmove=function(b){a.onContainerTouchMove(b)},1===ab&&K(y,"touchend",a.onDocumentTouchEnd))},destroy:function(){var a;W(this.chart.container,"mouseleave",this.onContainerMouseLeave),ab||(W(y,"mouseup",this.onDocumentMouseUp),W(y,"touchend",this.onDocumentTouchEnd)),clearInterval(this.tooltipTimeout);for(a in this)this[a]=null}},q(R.Pointer.prototype,{pinchTranslate:function(a,b,c,d,e,f){(this.zoomHor||this.pinchHor)&&this.pinchTranslateDirection(!0,a,b,c,d,e,f),(this.zoomVert||this.pinchVert)&&this.pinchTranslateDirection(!1,a,b,c,d,e,f)},pinchTranslateDirection:function(a,b,c,d,e,f,g,h){var s,m,y,i=this.chart,j=a?"x":"y",k=a?"X":"Y",l="chart"+k,o=a?"width":"height",n=i["plot"+(a?"Left":"Top")],p=h||1,q=i.inverted,x=i.bounds[a?"h":"v"],r=1===b.length,v=b[0][l],u=c[0][l],t=!r&&b[1][l],w=!r&&c[1][l],c=function(){!r&&M(v-t)>20&&(p=h||M(u-w)/M(v-t)),m=(n-u)/p+v,s=i["plot"+(a?"Width":"Height")]/p};c(),b=m,b<x.min?(b=x.min,y=!0):b+s>x.max&&(b=x.max-s,y=!0),y?(u-=.8*(u-g[j][0]),r||(w-=.8*(w-g[j][1])),c()):g[j]=[u,w],q||(f[j]=m-n,f[o]=s),f=q?1/p:p,e[o]=s,e[j]=b,d[q?a?"scaleY":"scaleX":"scale"+k]=p,d["translate"+k]=f*n+(u-f*v)},pinch:function(a){var b=this,c=b.chart,d=b.pinchDown,e=b.followTouchMove,f=a.touches,g=f.length,h=b.lastValidTouch,i=b.hasZoom,j=b.selectionMarker,k={},l=1===g&&(b.inClass(a.target,"highcharts-tracker")&&c.runTrackerClick||c.runChartClick),o={};(i||e)&&!l&&a.preventDefault(),Ua(f,function(a){return b.normalize(a)}),"touchstart"===a.type?(p(f,function(a,b){d[b]={chartX:a.chartX,chartY:a.chartY}}),h.x=[d[0].chartX,d[1]&&d[1].chartX],h.y=[d[0].chartY,d[1]&&d[1].chartY],p(c.axes,function(a){if(a.zoomEnabled){var b=c.bounds[a.horiz?"h":"v"],d=a.minPixelPadding,e=a.toPixels(a.dataMin),f=a.toPixels(a.dataMax),g=C(e,f),e=v(e,f);b.min=C(a.pos,g-d),b.max=v(a.pos+a.len,e+d)}})):d.length&&(j||(b.selectionMarker=j=q({destroy:sa},c.plotBox)),b.pinchTranslate(d,f,k,j,o,h),b.hasPinched=i,b.scaleGroups(k,o),!i&&e&&1===g&&this.runPointActions(b.normalize(a)))},onContainerTouchStart:function(a){var b=this.chart;oa=b.index,1===a.touches.length?(a=this.normalize(a),b.isInsidePlot(a.chartX-b.plotLeft,a.chartY-b.plotTop)?(this.runPointActions(a),this.pinch(a)):this.reset()):2===a.touches.length&&this.pinch(a)},onContainerTouchMove:function(a){(1===a.touches.length||2===a.touches.length)&&this.pinch(a)},onDocumentTouchEnd:function(a){V[oa]&&V[oa].pointer.drop(a)}}),I.PointerEvent||I.MSPointerEvent){var ua={},zb=!!I.PointerEvent,Wb=function(){var a,b=[];b.item=function(a){return this[a]};for(a in ua)ua.hasOwnProperty(a)&&b.push({pageX:ua[a].pageX,pageY:ua[a].pageY,target:ua[a].target});return b},Ab=function(a,b,c,d){a=a.originalEvent||a,"touch"!==a.pointerType&&a.pointerType!==a.MSPOINTER_TYPE_TOUCH||!V[oa]||(d(a),d=V[oa].pointer,d[b]({type:c,target:a.currentTarget,preventDefault:sa,touches:Wb()}))};q(Wa.prototype,{onContainerPointerDown:function(a){Ab(a,"onContainerTouchStart","touchstart",function(a){ua[a.pointerId]={pageX:a.pageX,pageY:a.pageY,target:a.currentTarget}})},onContainerPointerMove:function(a){Ab(a,"onContainerTouchMove","touchmove",function(a){ua[a.pointerId]={pageX:a.pageX,pageY:a.pageY},ua[a.pointerId].target||(ua[a.pointerId].target=a.currentTarget)})},onDocumentPointerUp:function(a){Ab(a,"onContainerTouchEnd","touchend",function(a){delete ua[a.pointerId]})},batchMSEvents:function(a){a(this.chart.container,zb?"pointerdown":"MSPointerDown",this.onContainerPointerDown),a(this.chart.container,zb?"pointermove":"MSPointerMove",this.onContainerPointerMove),a(y,zb?"pointerup":"MSPointerUp",this.onDocumentPointerUp)}}),Ma(Wa.prototype,"init",function(a,b,c){a.call(this,b,c),(this.hasZoom||this.followTouchMove)&&G(b.container,{"-ms-touch-action":Q,"touch-action":Q})}),Ma(Wa.prototype,"setDOMEvents",function(a){a.apply(this),(this.hasZoom||this.followTouchMove)&&this.batchMSEvents(K)}),Ma(Wa.prototype,"destroy",function(a){this.batchMSEvents(W),a.call(this)})}var lb=R.Legend=function(a,b){this.init(a,b)};lb.prototype={init:function(a,b){var c=this,d=b.itemStyle,e=m(b.padding,8),f=b.itemMarginTop||0;this.options=b,b.enabled&&(c.baseline=z(d.fontSize)+3+f,c.itemStyle=d,c.itemHiddenStyle=w(d,b.itemHiddenStyle),c.itemMarginTop=f,c.padding=e,c.initialItemX=e,c.initialItemY=e-5,c.maxItemWidth=0,c.chart=a,c.itemHeight=0,c.lastLineHeight=0,c.symbolWidth=m(b.symbolWidth,16),c.pages=[],c.render(),K(c.chart,"endResize",function(){c.positionCheckboxes()}))},colorizeItem:function(a,b){var j,c=this.options,d=a.legendItem,e=a.legendLine,f=a.legendSymbol,g=this.itemHiddenStyle.color,c=b?c.itemStyle.color:g,h=b?a.legendColor||a.color||"#CCC":g,g=a.options&&a.options.marker,i={fill:h};if(d&&d.css({fill:c,color:c}),e&&e.attr({stroke:h}),f){if(g&&f.isMarker)for(j in i.stroke=h,g=a.convertAttribs(g))d=g[j],d!==t&&(i[j]=d);f.attr(i)}},positionItem:function(a){var b=this.options,c=b.symbolPadding,b=!b.rtl,d=a._legendItemPos,e=d[0],d=d[1],f=a.checkbox;a.legendGroup&&a.legendGroup.translate(b?e:this.legendWidth-e-2*c-4,d),f&&(f.x=e,f.y=d)},destroyItem:function(a){var b=a.checkbox;p(["legendItem","legendLine","legendSymbol","legendGroup"],function(b){a[b]&&(a[b]=a[b].destroy())}),b&&Pa(a.checkbox)},destroy:function(){var a=this.group,b=this.box;b&&(this.box=b.destroy()),a&&(this.group=a.destroy())},positionCheckboxes:function(a){var c,b=this.group.alignAttr,d=this.clipHeight||this.legendHeight;b&&(c=b.translateY,p(this.allItems,function(e){var g,f=e.checkbox;f&&(g=c+f.y+(a||0)+3,G(f,{left:b.translateX+e.checkboxOffset+f.x-20+"px",top:g+"px",display:g>c-6&&c+d-6>g?"":Q}))}))},renderTitle:function(){var a=this.padding,b=this.options.title,c=0;b.text&&(this.title||(this.title=this.chart.renderer.label(b.text,a-3,a-4,null,null,null,null,null,"legend-title").attr({zIndex:1}).css(b.style).add(this.group)),a=this.title.getBBox(),c=a.height,this.offsetWidth=a.width,this.contentGroup.attr({translateY:c})),this.titleHeight=c},renderItem:function(a){var b=this.chart,c=b.renderer,d=this.options,e="horizontal"===d.layout,f=this.symbolWidth,g=d.symbolPadding,h=this.itemStyle,i=this.itemHiddenStyle,j=this.padding,k=e?m(d.itemDistance,20):0,l=!d.rtl,o=d.width,n=d.itemMarginBottom||0,s=this.itemMarginTop,p=this.initialItemX,q=a.legendItem,r=a.series&&a.series.drawLegendSymbol?a.series:a,x=r.options,x=this.createCheckboxForItem&&x&&x.showCheckbox,t=d.useHTML;q||(a.legendGroup=c.g("legend-item").attr({zIndex:1}).add(this.scrollGroup),r.drawLegendSymbol(this,a),a.legendItem=q=c.text(d.labelFormat?Ia(d.labelFormat,a):d.labelFormatter.call(a),l?f+g:-g,this.baseline,t).css(w(a.visible?h:i)).attr({align:l?"left":"right",zIndex:2}).add(a.legendGroup),this.setItemEvents&&this.setItemEvents(a,q,t,h,i),this.colorizeItem(a,a.visible),x&&this.createCheckboxForItem(a)),c=q.getBBox(),f=a.checkboxOffset=d.itemWidth||a.legendItemWidth||f+g+c.width+k+(x?20:0),this.itemHeight=g=u(a.legendItemHeight||c.height),e&&this.itemX-p+f>(o||b.chartWidth-2*j-p-d.x)&&(this.itemX=p,this.itemY+=s+this.lastLineHeight+n,this.lastLineHeight=0),this.maxItemWidth=v(this.maxItemWidth,f),this.lastItemY=s+this.itemY+n,this.lastLineHeight=v(g,this.lastLineHeight),a._legendItemPos=[this.itemX,this.itemY],e?this.itemX+=f:(this.itemY+=s+g+n,this.lastLineHeight=g),this.offsetWidth=o||v((e?this.itemX-p-k:f)+j,this.offsetWidth)},getAllItems:function(){var a=[];return p(this.chart.series,function(b){var c=b.options;m(c.showInLegend,r(c.linkedTo)?!1:t,!0)&&(a=a.concat(b.legendItems||("point"===c.legendType?b.data:b)))}),a},render:function(){var e,f,g,h,a=this,b=a.chart,c=b.renderer,d=a.group,i=a.box,j=a.options,k=a.padding,l=j.borderWidth,o=j.backgroundColor;a.itemX=a.initialItemX,a.itemY=a.initialItemY,a.offsetWidth=0,a.lastItemY=0,d||(a.group=d=c.g("legend").attr({zIndex:7}).add(),a.contentGroup=c.g().attr({zIndex:1}).add(d),a.scrollGroup=c.g().add(a.contentGroup)),a.renderTitle(),e=a.getAllItems(),ob(e,function(a,b){return(a.options&&a.options.legendIndex||0)-(b.options&&b.options.legendIndex||0)}),j.reversed&&e.reverse(),a.allItems=e,a.display=f=!!e.length,p(e,function(b){a.renderItem(b)}),g=j.width||a.offsetWidth,h=a.lastItemY+a.lastLineHeight+a.titleHeight,h=a.handleOverflow(h),(l||o)&&(g+=k,h+=k,i?g>0&&h>0&&(i[i.isNew?"attr":"animate"](i.crisp({width:g,height:h})),i.isNew=!1):(a.box=i=c.rect(0,0,g,h,j.borderRadius,l||0).attr({stroke:j.borderColor,"stroke-width":l||0,fill:o||Q}).add(d).shadow(j.shadow),i.isNew=!0),i[f?"show":"hide"]()),a.legendWidth=g,a.legendHeight=h,p(e,function(b){a.positionItem(b)}),f&&d.align(q({width:g,height:h},j),!0,"spacingBox"),b.isResizing||this.positionCheckboxes()},handleOverflow:function(a){var h,s,b=this,c=this.chart,d=c.renderer,e=this.options,f=e.y,f=c.spacingBox.height+("top"===e.verticalAlign?-f:f)-this.padding,g=e.maxHeight,i=this.clipRect,j=e.navigation,k=m(j.animation,!0),l=j.arrowSize||12,o=this.nav,n=this.pages,q=this.allItems;return"horizontal"===e.layout&&(f/=2),g&&(f=C(f,g)),n.length=0,a>f&&!e.useHTML?(this.clipHeight=h=f-20-this.titleHeight-this.padding,this.currentPage=m(this.currentPage,1),this.fullHeight=a,p(q,function(a,b){var c=a._legendItemPos[1],d=u(a.legendItem.getBBox().height),e=n.length;(!e||c-n[e-1]>h&&(s||c)!==n[e-1])&&(n.push(s||c),e++),b===q.length-1&&c+d-n[e-1]>h&&n.push(c),c!==s&&(s=c)}),i||(i=b.clipRect=d.clipRect(0,this.padding,9999,0),b.contentGroup.clip(i)),i.attr({height:h}),o||(this.nav=o=d.g().attr({zIndex:1}).add(this.group),this.up=d.symbol("triangle",0,0,l,l).on("click",function(){b.scroll(-1,k)}).add(o),this.pager=d.text("",15,10).css(j.style).add(o),this.down=d.symbol("triangle-down",0,0,l,l).on("click",function(){b.scroll(1,k)}).add(o)),b.scroll(0),a=f):o&&(i.attr({height:c.chartHeight}),o.hide(),this.scrollGroup.attr({translateY:1}),this.clipHeight=0),a},scroll:function(a,b){var c=this.pages,d=c.length,e=this.currentPage+a,f=this.clipHeight,g=this.options.navigation,h=g.activeColor,g=g.inactiveColor,i=this.pager,j=this.padding;e>d&&(e=d),e>0&&(b!==t&&Qa(b,this.chart),this.nav.attr({translateX:j,translateY:f+this.padding+7+this.titleHeight,visibility:"visible"}),this.up.attr({fill:1===e?g:h}).css({cursor:1===e?"default":"pointer"}),i.attr({text:e+"/"+d}),this.down.attr({x:18+this.pager.getBBox().width,fill:e===d?g:h}).css({cursor:e===d?"default":"pointer"}),c=-c[e-1]+this.initialItemY,this.scrollGroup.animate({translateY:c}),this.currentPage=e,this.positionCheckboxes(c))}},N=R.LegendSymbolMixin={drawRectangle:function(a,b){var c=a.options.symbolHeight||12;b.legendSymbol=this.chart.renderer.rect(0,a.baseline-5-c/2,a.symbolWidth,c,a.options.symbolRadius||0).attr({zIndex:3}).add(b.legendGroup)},drawLineMarker:function(a){var d,b=this.options,c=b.marker;d=a.symbolWidth;var g,e=this.chart.renderer,f=this.legendGroup,a=a.baseline-u(.3*e.fontMetrics(a.options.itemStyle.fontSize).b);b.lineWidth&&(g={"stroke-width":b.lineWidth},b.dashStyle&&(g.dashstyle=b.dashStyle),this.legendLine=e.path(["M",0,a,"L",d,a]).attr(g).add(f)),c&&c.enabled!==!1&&(b=c.radius,this.legendSymbol=d=e.symbol(this.symbol,d/2-b,a-b,2*b,2*b).add(f),d.isMarker=!0)}},(/Trident\/7\.0/.test(wa)||Ta)&&Ma(lb.prototype,"positionItem",function(a,b){var c=this,d=function(){b._legendItemPos&&a.call(c,b)};d(),setTimeout(d)}),Ya.prototype={init:function(a,b){var c,d=a.series;a.series=null,c=w(E,a),c.series=a.series=d,this.userOptions=a,d=c.chart,this.margin=this.splashArray("margin",d),this.spacing=this.splashArray("spacing",d);var e=d.events;this.bounds={h:{},v:{}},this.callback=b,this.isResizing=0,this.options=c,this.axes=[],this.series=[],this.hasCartesianSeries=d.showAxes;var g,f=this;if(f.index=V.length,V.push(f),ab++,d.reflow!==!1&&K(f,"load",function(){f.initReflow()}),e)for(g in e)K(f,g,e[g]);f.xAxis=[],f.yAxis=[],f.animation=fa?!1:m(d.animation,!0),f.pointCount=0,f.counters=new Bb,f.firstRender()},initSeries:function(a){var b=this.options.chart;return(b=F[a.type||b.type||b.defaultSeriesType])||ra(17,!0),b=new b,b.init(this,a),b},isInsidePlot:function(a,b,c){var d=c?b:a,a=c?a:b;return d>=0&&d<=this.plotWidth&&a>=0&&a<=this.plotHeight},adjustTickAmounts:function(){this.options.chart.alignTicks!==!1&&p(this.axes,function(a){a.adjustTickAmount()}),this.maxTicks=null},redraw:function(a){var g,h,b=this.axes,c=this.series,d=this.pointer,e=this.legend,f=this.isDirtyLegend,i=this.isDirtyBox,j=c.length,k=j,l=this.renderer,o=l.isHidden(),n=[];for(Qa(a,this),o&&this.cloneRenderTo(),this.layOutTitles();k--;)if(a=c[k],a.options.stacking&&(g=!0,a.isDirty)){h=!0;break}if(h)for(k=j;k--;)a=c[k],a.options.stacking&&(a.isDirty=!0);p(c,function(a){a.isDirty&&"point"===a.options.legendType&&(f=!0)}),f&&e.options.enabled&&(e.render(),this.isDirtyLegend=!1),g&&this.getStacks(),this.hasCartesianSeries&&(this.isResizing||(this.maxTicks=null,p(b,function(a){a.setScale()})),this.adjustTickAmounts(),this.getMargins(),p(b,function(a){a.isDirty&&(i=!0)}),p(b,function(a){a.isDirtyExtremes&&(a.isDirtyExtremes=!1,n.push(function(){D(a,"afterSetExtremes",q(a.eventArgs,a.getExtremes())),delete a.eventArgs})),(i||g)&&a.redraw()})),i&&this.drawChartBox(),p(c,function(a){a.isDirty&&a.visible&&(!a.isCartesian||a.xAxis)&&a.redraw()}),d&&d.reset(!0),l.draw(),D(this,"redraw"),o&&this.cloneRenderTo(!0),p(n,function(a){a.call()})},get:function(a){var d,e,b=this.axes,c=this.series;for(d=0;d<b.length;d++)if(b[d].options.id===a)return b[d];for(d=0;d<c.length;d++)if(c[d].options.id===a)return c[d];for(d=0;d<c.length;d++)for(e=c[d].points||[],b=0;b<e.length;b++)if(e[b].id===a)return e[b];return null},getAxes:function(){var a=this,b=this.options,c=b.xAxis=qa(b.xAxis||{}),b=b.yAxis=qa(b.yAxis||{});p(c,function(a,b){a.index=b,a.isX=!0}),p(b,function(a,b){a.index=b}),c=c.concat(b),p(c,function(b){new la(a,b)}),a.adjustTickAmounts()},getSelectedPoints:function(){var a=[];return p(this.series,function(b){a=a.concat(vb(b.points||[],function(a){return a.selected}))}),a},getSelectedSeries:function(){return vb(this.series,function(a){return a.selected})},getStacks:function(){var a=this;p(a.yAxis,function(a){a.stacks&&a.hasVisibleSeries&&(a.oldStacks=a.stacks)}),p(a.series,function(b){!b.options.stacking||b.visible!==!0&&a.options.chart.ignoreHiddenSeries!==!1||(b.stackKey=b.type+m(b.options.stack,""))})},setTitle:function(a,b,c){var g,f,d=this,e=d.options;f=e.title=w(e.title,a),g=e.subtitle=w(e.subtitle,b),e=g,p([["title",a,f],["subtitle",b,e]],function(a){var b=a[0],c=d[b],e=a[1],a=a[2];c&&e&&(d[b]=c=c.destroy()),a&&a.text&&!c&&(d[b]=d.renderer.text(a.text,0,0,a.useHTML).attr({align:a.align,"class":"highcharts-"+b,zIndex:a.zIndex||4}).css(a.style).add())}),d.layOutTitles(c)},layOutTitles:function(a){var b=0,c=this.title,d=this.subtitle,e=this.options,f=e.title,e=e.subtitle,g=this.spacingBox.width-44;!c||(c.css({width:(f.width||g)+"px"}).align(q({y:15},f),!1,"spacingBox"),f.floating||f.verticalAlign)||(b=c.getBBox().height),d&&(d.css({width:(e.width||g)+"px"}).align(q({y:b+f.margin},e),!1,"spacingBox"),!e.floating&&!e.verticalAlign&&(b=Ka(b+d.getBBox().height))),c=this.titleOffset!==b,this.titleOffset=b,!this.isDirtyBox&&c&&(this.isDirtyBox=c,this.hasRendered&&m(a,!0)&&this.isDirtyBox&&this.redraw())},getChartSize:function(){var a=this.options.chart,b=a.width,a=a.height,c=this.renderToClone||this.renderTo;r(b)||(this.containerWidth=jb(c,"width")),r(a)||(this.containerHeight=jb(c,"height")),this.chartWidth=v(0,b||this.containerWidth||600),this.chartHeight=v(0,m(a,this.containerHeight>19?this.containerHeight:400))},cloneRenderTo:function(a){var b=this.renderToClone,c=this.container;a?b&&(this.renderTo.appendChild(c),Pa(b),delete this.renderToClone):(c&&c.parentNode===this.renderTo&&this.renderTo.removeChild(c),this.renderToClone=b=this.renderTo.cloneNode(0),G(b,{position:"absolute",top:"-9999px",display:"block"}),b.style.setProperty&&b.style.setProperty("display","block","important"),y.body.appendChild(b),c&&b.appendChild(c))
|
4 |
-
},getContainer:function(){var a,c,d,e,b=this.options.chart;this.renderTo=a=b.renderTo,e="highcharts-"+tb++,Fa(a)&&(this.renderTo=a=y.getElementById(a)),a||ra(13,!0),c=z(H(a,"data-highcharts-chart")),!isNaN(c)&&V[c]&&V[c].hasRendered&&V[c].destroy(),H(a,"data-highcharts-chart",this.index),a.innerHTML="",!b.skipClone&&!a.offsetWidth&&this.cloneRenderTo(),this.getChartSize(),c=this.chartWidth,d=this.chartHeight,this.container=a=Y(Ja,{className:"highcharts-container"+(b.className?" "+b.className:""),id:e},q({position:"relative",overflow:"hidden",width:c+"px",height:d+"px",textAlign:"left",lineHeight:"normal",zIndex:0,"-webkit-tap-highlight-color":"rgba(0,0,0,0)"},b.style),this.renderToClone||a),this._cursor=a.style.cursor,this.renderer=b.forExport?new ta(a,c,d,b.style,!0):new Za(a,c,d,b.style),fa&&this.renderer.create(this,a,c,d)},getMargins:function(){var b,a=this.spacing,c=this.legend,d=this.margin,e=this.options.legend,f=m(e.margin,20),g=e.x,h=e.y,i=e.align,j=e.verticalAlign,k=this.titleOffset;this.resetMargins(),b=this.axisOffset,k&&!r(d[0])&&(this.plotTop=v(this.plotTop,k+this.options.title.margin+a[0])),c.display&&!e.floating&&("right"===i?r(d[1])||(this.marginRight=v(this.marginRight,c.legendWidth-g+f+a[1])):"left"===i?r(d[3])||(this.plotLeft=v(this.plotLeft,c.legendWidth+g+f+a[3])):"top"===j?r(d[0])||(this.plotTop=v(this.plotTop,c.legendHeight+h+f+a[0])):"bottom"!==j||r(d[2])||(this.marginBottom=v(this.marginBottom,c.legendHeight-h+f+a[2]))),this.extraBottomMargin&&(this.marginBottom+=this.extraBottomMargin),this.extraTopMargin&&(this.plotTop+=this.extraTopMargin),this.hasCartesianSeries&&p(this.axes,function(a){a.getOffset()}),r(d[3])||(this.plotLeft+=b[3]),r(d[0])||(this.plotTop+=b[0]),r(d[2])||(this.marginBottom+=b[2]),r(d[1])||(this.marginRight+=b[1]),this.setChartSize()},reflow:function(a){var b=this,c=b.options.chart,d=b.renderTo,e=c.width||jb(d,"width"),f=c.height||jb(d,"height"),c=a?a.target:I,d=function(){b.container&&(b.setSize(e,f,!1),b.hasUserSize=null)};b.hasUserSize||!e||!f||c!==I&&c!==y||((e!==b.containerWidth||f!==b.containerHeight)&&(clearTimeout(b.reflowTimeout),a?b.reflowTimeout=setTimeout(d,100):d()),b.containerWidth=e,b.containerHeight=f)},initReflow:function(){var a=this,b=function(b){a.reflow(b)};K(I,"resize",b),K(a,"destroy",function(){W(I,"resize",b)})},setSize:function(a,b,c){var e,f,g,d=this;d.isResizing+=1,g=function(){d&&D(d,"endResize",null,function(){d.isResizing-=1})},Qa(c,d),d.oldChartHeight=d.chartHeight,d.oldChartWidth=d.chartWidth,r(a)&&(d.chartWidth=e=v(0,u(a)),d.hasUserSize=!!e),r(b)&&(d.chartHeight=f=v(0,u(b))),(va?kb:G)(d.container,{width:e+"px",height:f+"px"},va),d.setChartSize(!0),d.renderer.setSize(e,f,c),d.maxTicks=null,p(d.axes,function(a){a.isDirty=!0,a.setScale()}),p(d.series,function(a){a.isDirty=!0}),d.isDirtyLegend=!0,d.isDirtyBox=!0,d.layOutTitles(),d.getMargins(),d.redraw(c),d.oldChartHeight=null,D(d,"resize"),va===!1?g():setTimeout(g,va&&va.duration||500)},setChartSize:function(a){var i,j,k,l,b=this.inverted,c=this.renderer,d=this.chartWidth,e=this.chartHeight,f=this.options.chart,g=this.spacing,h=this.clipOffset;this.plotLeft=i=u(this.plotLeft),this.plotTop=j=u(this.plotTop),this.plotWidth=k=v(0,u(d-i-this.marginRight)),this.plotHeight=l=v(0,u(e-j-this.marginBottom)),this.plotSizeX=b?l:k,this.plotSizeY=b?k:l,this.plotBorderWidth=f.plotBorderWidth||0,this.spacingBox=c.spacingBox={x:g[3],y:g[0],width:d-g[3]-g[1],height:e-g[0]-g[2]},this.plotBox=c.plotBox={x:i,y:j,width:k,height:l},d=2*T(this.plotBorderWidth/2),b=Ka(v(d,h[3])/2),c=Ka(v(d,h[0])/2),this.clipBox={x:b,y:c,width:T(this.plotSizeX-v(d,h[1])/2-b),height:T(this.plotSizeY-v(d,h[2])/2-c)},a||p(this.axes,function(a){a.setAxisSize(),a.setAxisTranslation()})},resetMargins:function(){var a=this.spacing,b=this.margin;this.plotTop=m(b[0],a[0]),this.marginRight=m(b[1],a[1]),this.marginBottom=m(b[2],a[2]),this.plotLeft=m(b[3],a[3]),this.axisOffset=[0,0,0,0],this.clipOffset=[0,0,0,0]},drawChartBox:function(){var n,a=this.options.chart,b=this.renderer,c=this.chartWidth,d=this.chartHeight,e=this.chartBackground,f=this.plotBackground,g=this.plotBorder,h=this.plotBGImage,i=a.borderWidth||0,j=a.backgroundColor,k=a.plotBackgroundColor,l=a.plotBackgroundImage,o=a.plotBorderWidth||0,s=this.plotLeft,m=this.plotTop,p=this.plotWidth,q=this.plotHeight,r=this.plotBox,v=this.clipRect,u=this.clipBox;n=i+(a.shadow?8:0),(i||j)&&(e?e.animate(e.crisp({width:c-n,height:d-n})):(e={fill:j||Q},i&&(e.stroke=a.borderColor,e["stroke-width"]=i),this.chartBackground=b.rect(n/2,n/2,c-n,d-n,a.borderRadius,i).attr(e).addClass("highcharts-background").add().shadow(a.shadow))),k&&(f?f.animate(r):this.plotBackground=b.rect(s,m,p,q,0).attr({fill:k}).add().shadow(a.plotShadow)),l&&(h?h.animate(r):this.plotBGImage=b.image(l,s,m,p,q).add()),v?v.animate({width:u.width,height:u.height}):this.clipRect=b.clipRect(u),o&&(g?g.animate(g.crisp({x:s,y:m,width:p,height:q})):this.plotBorder=b.rect(s,m,p,q,0,-o).attr({stroke:a.plotBorderColor,"stroke-width":o,fill:Q,zIndex:1}).add()),this.isDirtyBox=!1},propFromSeries:function(){var c,e,f,a=this,b=a.options.chart,d=a.options.series;p(["inverted","angular","polar"],function(g){for(c=F[b.type||b.defaultSeriesType],f=a[g]||b[g]||c&&c.prototype[g],e=d&&d.length;!f&&e--;)(c=F[d[e].type])&&c.prototype[g]&&(f=!0);a[g]=f})},linkSeries:function(){var a=this,b=a.series;p(b,function(a){a.linkedSeries.length=0}),p(b,function(b){var d=b.options.linkedTo;Fa(d)&&(d=":previous"===d?a.series[b.index-1]:a.get(d))&&(d.linkedSeries.push(b),b.linkedParent=d)})},renderSeries:function(){p(this.series,function(a){a.translate(),a.setTooltipPoints&&a.setTooltipPoints(),a.render()})},render:function(){var g,a=this,b=a.axes,c=a.renderer,d=a.options,e=d.labels,f=d.credits;a.setTitle(),a.legend=new lb(a,d.legend),a.getStacks(),p(b,function(a){a.setScale()}),a.getMargins(),a.maxTicks=null,p(b,function(a){a.setTickPositions(!0),a.setMaxTicks()}),a.adjustTickAmounts(),a.getMargins(),a.drawChartBox(),a.hasCartesianSeries&&p(b,function(a){a.render()}),a.seriesGroup||(a.seriesGroup=c.g("series-group").attr({zIndex:3}).add()),a.renderSeries(),e.items&&p(e.items,function(b){var d=q(e.style,b.style),f=z(d.left)+a.plotLeft,g=z(d.top)+a.plotTop+12;delete d.left,delete d.top,c.text(b.html,f,g).attr({zIndex:2}).css(d).add()}),f.enabled&&!a.credits&&(g=f.href,a.credits=c.text(f.text,0,0).on("click",function(){g&&(location.href=g)}).attr({align:f.position.align,zIndex:8}).css(f.style).add().align(f.position)),a.hasRendered=!0},destroy:function(){var e,a=this,b=a.axes,c=a.series,d=a.container,f=d&&d.parentNode;for(D(a,"destroy"),V[a.index]=t,ab--,a.renderTo.removeAttribute("data-highcharts-chart"),W(a),e=b.length;e--;)b[e]=b[e].destroy();for(e=c.length;e--;)c[e]=c[e].destroy();p("title,subtitle,chartBackground,plotBackground,plotBGImage,plotBorder,seriesGroup,clipRect,credits,pointer,scroller,rangeSelector,legend,resetZoomButton,tooltip,renderer".split(","),function(b){var c=a[b];c&&c.destroy&&(a[b]=c.destroy())}),d&&(d.innerHTML="",W(d),f&&Pa(d));for(e in a)delete a[e]},isReadyToRender:function(){var a=this;return!aa&&I==I.top&&"complete"!==y.readyState||fa&&!I.canvg?(fa?Lb.push(function(){a.firstRender()},a.options.global.canvasToolsURL):y.attachEvent("onreadystatechange",function(){y.detachEvent("onreadystatechange",a.firstRender),"complete"===y.readyState&&a.firstRender()}),!1):!0},firstRender:function(){var a=this,b=a.options,c=a.callback;a.isReadyToRender()&&(a.getContainer(),D(a,"init"),a.resetMargins(),a.setChartSize(),a.propFromSeries(),a.getAxes(),p(b.series||[],function(b){a.initSeries(b)}),a.linkSeries(),D(a,"beforeRender"),R.Pointer&&(a.pointer=new Wa(a,b)),a.render(),a.renderer.draw(),c&&c.apply(a,[a]),p(a.callbacks,function(b){b.apply(a,[a])}),a.cloneRenderTo(!0),D(a,"load"))},splashArray:function(a,b){var c=b[a],c=ca(c)?c:[c,c,c,c];return[m(b[a+"Top"],c[0]),m(b[a+"Right"],c[1]),m(b[a+"Bottom"],c[2]),m(b[a+"Left"],c[3])]}},Ya.prototype.callbacks=[],X=R.CenteredSeriesMixin={getCenter:function(){var d,h,a=this.options,b=this.chart,c=2*(a.slicedOffset||0),e=b.plotWidth-2*c,f=b.plotHeight-2*c,b=a.center,a=[m(b[0],"50%"),m(b[1],"50%"),a.size||"100%",a.innerSize||0],g=C(e,f);return Ua(a,function(a,b){return h=/%$/.test(a),d=2>b||2===b&&h,(h?[e,f,g,g][b]*z(a)/100:a)+(d?c:0)})}};var Ea=function(){};Ea.prototype={init:function(a,b,c){return this.series=a,this.applyOptions(b,c),this.pointAttr={},a.options.colorByPoint&&(b=a.options.colors||a.chart.options.colors,this.color=this.color||b[a.colorCounter++],a.colorCounter===b.length)&&(a.colorCounter=0),a.chart.pointCount++,this},applyOptions:function(a,b){var c=this.series,d=c.pointValKey,a=Ea.prototype.optionsToObject.call(this,a);return q(this,a),this.options=this.options?q(this.options,a):a,d&&(this.y=this[d]),this.x===t&&c&&(this.x=b===t?c.autoIncrement():b),this},optionsToObject:function(a){var b={},c=this.series,d=c.pointArrayMap||["y"],e=d.length,f=0,g=0;if("number"==typeof a||null===a)b[d[0]]=a;else if(La(a))for(a.length>e&&(c=typeof a[0],"string"===c?b.name=a[0]:"number"===c&&(b.x=a[0]),f++);e>g;)b[d[g++]]=a[f++];else"object"==typeof a&&(b=a,a.dataLabels&&(c._hasPointLabels=!0),a.marker&&(c._hasPointMarkers=!0));return b},destroy:function(){var c,a=this.series.chart,b=a.hoverPoints;a.pointCount--,b&&(this.setState(),ja(b,this),!b.length)&&(a.hoverPoints=null),this===a.hoverPoint&&this.onMouseOut(),(this.graphic||this.dataLabel)&&(W(this),this.destroyElements()),this.legendItem&&a.legend.destroyItem(this);for(c in this)this[c]=null},destroyElements:function(){for(var b,a="graphic,dataLabel,dataLabelUpper,group,connector,shadowGroup".split(","),c=6;c--;)b=a[c],this[b]&&(this[b]=this[b].destroy())},getLabelConfig:function(){return{x:this.category,y:this.y,key:this.name||this.category,series:this.series,point:this,percentage:this.percentage,total:this.total||this.stackTotal}},tooltipFormatter:function(a){var b=this.series,c=b.tooltipOptions,d=m(c.valueDecimals,""),e=c.valuePrefix||"",f=c.valueSuffix||"";return p(b.pointArrayMap||["y"],function(b){b="{point."+b,(e||f)&&(a=a.replace(b+"}",e+b+"}"+f)),a=a.replace(b+"}",b+":,."+d+"f}")}),Ia(a,{point:this,series:this.series})},firePointEvent:function(a,b,c){var d=this,e=this.series.options;(e.point.events[a]||d.options&&d.options.events&&d.options.events[a])&&this.importEvents(),"click"===a&&e.allowPointSelect&&(c=function(a){d.select(null,a.ctrlKey||a.metaKey||a.shiftKey)}),D(this,a,b,c)}};var O=function(){};O.prototype={isCartesian:!0,type:"line",pointClass:Ea,sorted:!0,requireSorting:!0,pointAttrToOptions:{stroke:"lineColor","stroke-width":"lineWidth",fill:"fillColor",r:"radius"},axisTypes:["xAxis","yAxis"],colorCounter:0,parallelArrays:["x","y"],init:function(a,b){var d,e,c=this,f=a.series,g=function(a,b){return m(a.options.index,a._i)-m(b.options.index,b._i)};c.chart=a,c.options=b=c.setOptions(b),c.linkedSeries=[],c.bindAxes(),q(c,{name:b.name,state:"",pointAttr:{},visible:b.visible!==!1,selected:b.selected===!0}),fa&&(b.animation=!1),e=b.events;for(d in e)K(c,d,e[d]);(e&&e.click||b.point&&b.point.events&&b.point.events.click||b.allowPointSelect)&&(a.runTrackerClick=!0),c.getColor(),c.getSymbol(),p(c.parallelArrays,function(a){c[a+"Data"]=[]}),c.setData(b.data,!1),c.isCartesian&&(a.hasCartesianSeries=!0),f.push(c),c._i=f.length-1,ob(f,g),this.yAxis&&ob(this.yAxis.series,g),p(f,function(a,b){a.index=b,a.name=a.name||"Series "+(b+1)})},bindAxes:function(){var d,a=this,b=a.options,c=a.chart;p(a.axisTypes||[],function(e){p(c[e],function(c){d=c.options,(b[e]===d.index||b[e]!==t&&b[e]===d.id||b[e]===t&&0===d.index)&&(c.series.push(a),a[e]=c,c.isDirty=!0)}),!a[e]&&a.optionalAxis!==e&&ra(18,!0)})},updateParallelArrays:function(a,b){var c=a.series,d=arguments;p(c.parallelArrays,"number"==typeof b?function(d){var f="y"===d&&c.toYData?c.toYData(a):a[d];c[d+"Data"][b]=f}:function(a){Array.prototype[b].apply(c[a+"Data"],Array.prototype.slice.call(d,2))})},autoIncrement:function(){var a=this.options,b=this.xIncrement,b=m(b,a.pointStart,0);return this.pointInterval=m(this.pointInterval,a.pointInterval,1),this.xIncrement=b+this.pointInterval,b},getSegments:function(){var c,a=-1,b=[],d=this.points,e=d.length;if(e)if(this.options.connectNulls){for(c=e;c--;)null===d[c].y&&d.splice(c,1);d.length&&(b=[d])}else p(d,function(c,g){null===c.y?(g>a+1&&b.push(d.slice(a+1,g)),a=g):g===e-1&&b.push(d.slice(a+1,g+1))});this.segments=b},setOptions:function(a){var b=this.chart,c=b.options.plotOptions,b=b.userOptions||{},d=b.plotOptions||{},e=c[this.type];return this.userOptions=a,c=w(e,c.series,a),this.tooltipOptions=w(E.tooltip,E.plotOptions[this.type].tooltip,b.tooltip,d.series&&d.series.tooltip,d[this.type]&&d[this.type].tooltip,a.tooltip),null===e.marker&&delete c.marker,c},getColor:function(){var e,a=this.options,b=this.userOptions,c=this.chart.options.colors,d=this.chart.counters;e=a.color||ba[this.type].color,e||a.colorByPoint||(r(b._colorIndex)?a=b._colorIndex:(b._colorIndex=d.color,a=d.color++),e=c[a]),this.color=e,d.wrapColor(c.length)},getSymbol:function(){var a=this.userOptions,b=this.options.marker,c=this.chart,d=c.options.symbols,c=c.counters;this.symbol=b.symbol,this.symbol||(r(a._symbolIndex)?a=a._symbolIndex:(a._symbolIndex=c.symbol,a=c.symbol++),this.symbol=d[a]),/^url/.test(this.symbol)&&(b.radius=0),c.wrapSymbol(d.length)},drawLegendSymbol:N.drawLineMarker,setData:function(a,b,c,d){var h,e=this,f=e.points,g=f&&f.length||0,i=e.options,j=e.chart,k=null,l=e.xAxis,o=l&&!!l.categories,n=e.tooltipPoints,s=i.turboThreshold,q=this.xData,r=this.yData,v=(h=e.pointArrayMap)&&h.length,a=a||[];if(h=a.length,b=m(b,!0),d===!1||!h||g!==h||e.cropped||e.hasGroupedData){if(e.xIncrement=null,e.pointRange=o?1:i.pointRange,e.colorCounter=0,p(this.parallelArrays,function(a){e[a+"Data"].length=0}),s&&h>s){for(c=0;null===k&&h>c;)k=a[c],c++;if(ha(k)){for(o=m(i.pointStart,0),i=m(i.pointInterval,1),c=0;h>c;c++)q[c]=o,r[c]=a[c],o+=i;e.xIncrement=o}else if(La(k))if(v)for(c=0;h>c;c++)i=a[c],q[c]=i[0],r[c]=i.slice(1,v+1);else for(c=0;h>c;c++)i=a[c],q[c]=i[0],r[c]=i[1];else ra(12)}else for(c=0;h>c;c++)a[c]!==t&&(i={series:e},e.pointClass.prototype.applyOptions.apply(i,[a[c]]),e.updateParallelArrays(i,c),o&&i.name)&&(l.names[i.x]=i.name);for(Fa(r[0])&&ra(14,!0),e.data=[],e.options.data=a,c=g;c--;)f[c]&&f[c].destroy&&f[c].destroy();n&&(n.length=0),l&&(l.minRange=l.userMinRange),e.isDirty=e.isDirtyData=j.isDirtyBox=!0,c=!1}else p(a,function(a,b){f[b].update(a,!1)});b&&j.redraw(c)},processData:function(a){var e,b=this.xData,c=this.yData,d=b.length;e=0;var f,g,o,n,h=this.xAxis,i=this.options,j=i.cropThreshold,k=0,l=this.isCartesian;if(l&&!this.isDirty&&!h.isDirty&&!this.yAxis.isDirty&&!a)return!1;for(l&&this.sorted&&(!j||d>j||this.forceCrop)&&(o=h.min,n=h.max,b[d-1]<o||b[0]>n?(b=[],c=[]):(b[0]<o||b[d-1]>n)&&(e=this.cropData(this.xData,this.yData,o,n),b=e.xData,c=e.yData,e=e.start,f=!0,k=b.length)),d=b.length-1;d>=0;d--)a=b[d]-b[d-1],!f&&b[d]>o&&b[d]<n&&k++,a>0&&(g===t||g>a)?g=a:0>a&&this.requireSorting&&ra(15);this.cropped=f,this.cropStart=e,this.processedXData=b,this.processedYData=c,this.activePointCount=k,null===i.pointRange&&(this.pointRange=g||1),this.closestPointRange=g},cropData:function(a,b,c,d){var i,e=a.length,f=0,g=e,h=m(this.cropShoulder,1);for(i=0;e>i;i++)if(a[i]>=c){f=v(0,i-h);break}for(;e>i;i++)if(a[i]>d){g=i+h;break}return{xData:a.slice(f,g),yData:b.slice(f,g),start:f,end:g}},generatePoints:function(){var c,i,k,o,a=this.options.data,b=this.data,d=this.processedXData,e=this.processedYData,f=this.pointClass,g=d.length,h=this.cropStart||0,j=this.hasGroupedData,l=[];for(b||j||(b=[],b.length=a.length,b=this.data=b),o=0;g>o;o++)i=h+o,j?l[o]=(new f).init(this,[d[o]].concat(qa(e[o]))):(b[i]?k=b[i]:a[i]!==t&&(b[i]=k=(new f).init(this,a[i],d[o])),l[o]=k);if(b&&(g!==(c=b.length)||j))for(o=0;c>o;o++)o===h&&!j&&(o+=g),b[o]&&(b[o].destroyElements(),b[o].plotX=t);this.data=b,this.points=l},getExtremes:function(a){var d,b=this.yAxis,c=this.processedXData,e=[],f=0;d=this.xAxis.getExtremes();var i,j,k,l,g=d.min,h=d.max,a=a||this.stackedYData||this.processedYData;for(d=a.length,l=0;d>l;l++)if(j=c[l],k=a[l],i=null!==k&&k!==t&&(!b.isLog||k.length||k>0),j=this.getExtremesFromAll||this.cropped||(c[l+1]||j)>=g&&(c[l-1]||j)<=h,i&&j)if(i=k.length)for(;i--;)null!==k[i]&&(e[f++]=k[i]);else e[f++]=k;this.dataMin=m(void 0,Na(e)),this.dataMax=m(void 0,Ba(e))},translate:function(){this.processedXData||this.processData(),this.generatePoints();for(var a=this.options,b=a.stacking,c=this.xAxis,d=c.categories,e=this.yAxis,f=this.points,g=f.length,h=!!this.modifyValue,i=a.pointPlacement,j="between"===i||ha(i),k=a.threshold,a=0;g>a;a++){var l=f[a],o=l.x,n=l.y,s=l.low,p=b&&e.stacks[(this.negStacks&&k>n?"-":"")+this.stackKey];e.isLog&&0>=n&&(l.y=n=null),l.plotX=c.translate(o,0,0,0,1,i,"flags"===this.type),b&&this.visible&&p&&p[o]&&(p=p[o],n=p.points[this.index+","+a],s=n[0],n=n[1],0===s&&(s=m(k,e.min)),e.isLog&&0>=s&&(s=null),l.total=l.stackTotal=p.total,l.percentage=p.total&&l.y/p.total*100,l.stackY=n,p.setOffset(this.pointXOffset||0,this.barW||0)),l.yBottom=r(s)?e.translate(s,0,1,0,1):null,h&&(n=this.modifyValue(n,l)),l.plotY="number"==typeof n&&1/0!==n?e.translate(n,0,1,0,1):t,l.clientX=j?c.translate(o,0,0,0,1):l.plotX,l.negative=l.y<(k||0),l.category=d&&d[l.x]!==t?d[l.x]:l.x}this.getSegments()},animate:function(a){var d,b=this.chart,c=b.renderer;d=this.options.animation;var g,e=this.clipBox||b.clipBox,f=b.inverted;d&&!ca(d)&&(d=ba[this.type].animation),g=["_sharedClip",d.duration,d.easing,e.height].join(","),a?(a=b[g],d=b[g+"m"],a||(b[g]=a=c.clipRect(q(e,{width:0})),b[g+"m"]=d=c.clipRect(-99,f?-b.plotLeft:-b.plotTop,99,f?b.chartWidth:b.chartHeight)),this.group.clip(a),this.markerGroup.clip(d),this.sharedClipKey=g):((a=b[g])&&a.animate({width:b.plotSizeX},d),b[g+"m"]&&b[g+"m"].animate({width:b.plotSizeX+99},d),this.animate=null)},afterAnimate:function(){var a=this.chart,b=this.sharedClipKey,c=this.group,d=this.clipBox;c&&this.options.clip!==!1&&(b&&d||c.clip(d?a.renderer.clipRect(d):a.clipRect),this.markerGroup.clip()),D(this,"afterAnimate"),setTimeout(function(){b&&a[b]&&(d||(a[b]=a[b].destroy()),a[b+"m"]&&(a[b+"m"]=a[b+"m"].destroy()))},100)},drawPoints:function(){var a,d,e,f,g,h,i,j,k,b=this.points,c=this.chart;d=this.options.marker;var o,l=this.pointAttr[""],n=this.markerGroup,s=m(d.enabled,this.activePointCount<.5*this.xAxis.len/d.radius);if(d.enabled!==!1||this._hasPointMarkers)for(f=b.length;f--;)g=b[f],d=T(g.plotX),e=g.plotY,k=g.graphic,i=g.marker||{},a=s&&i.enabled===t||i.enabled,o=c.isInsidePlot(u(d),e,c.inverted),a&&e!==t&&!isNaN(e)&&null!==g.y?(a=g.pointAttr[g.selected?"select":""]||l,h=a.r,i=m(i.symbol,this.symbol),j=0===i.indexOf("url"),k?k[o?"show":"hide"](!0).animate(q({x:d-h,y:e-h},k.symbolName?{width:2*h,height:2*h}:{})):o&&(h>0||j)&&(g.graphic=c.renderer.symbol(i,d-h,e-h,2*h,2*h).attr(a).add(n))):k&&(g.graphic=k.destroy())},convertAttribs:function(a,b,c,d){var f,g,e=this.pointAttrToOptions,h={},a=a||{},b=b||{},c=c||{},d=d||{};for(f in e)g=e[f],h[f]=m(a[g],b[f],c[f],d[f]);return h},getAttribs:function(){var f,a=this,b=a.options,c=ba[a.type].marker?b.marker:b,d=c.states,e=d.hover,g=a.color;f={stroke:g,fill:g};var i,k,h=a.points||[],j=[],l=a.pointAttrToOptions;k=a.hasPointSpecificOptions;var o=b.negativeColor,n=c.lineColor,s=c.fillColor;i=b.turboThreshold;var m;if(b.marker?(e.radius=e.radius||c.radius+2,e.lineWidth=e.lineWidth||c.lineWidth+1):e.color=e.color||ya(e.color||g).brighten(e.brightness).get(),j[""]=a.convertAttribs(c,f),p(["hover","select"],function(b){j[b]=a.convertAttribs(d[b],j[""])}),a.pointAttr=j,g=h.length,!i||i>g||k)for(;g--;){if(i=h[g],(c=i.options&&i.options.marker||i.options)&&c.enabled===!1&&(c.radius=0),i.negative&&o&&(i.color=i.fillColor=o),k=b.colorByPoint||i.color,i.options)for(m in l)r(c[l[m]])&&(k=!0);k?(c=c||{},k=[],d=c.states||{},f=d.hover=d.hover||{},b.marker||(f.color=f.color||!i.options.color&&e.color||ya(i.color).brighten(f.brightness||e.brightness).get()),f={color:i.color},s||(f.fillColor=i.color),n||(f.lineColor=i.color),k[""]=a.convertAttribs(q(f,c),j[""]),k.hover=a.convertAttribs(d.hover,j.hover,k[""]),k.select=a.convertAttribs(d.select,j.select,k[""])):k=j,i.pointAttr=k}},destroy:function(){var d,e,g,h,i,a=this,b=a.chart,c=/AppleWebKit\/533/.test(wa),f=a.data||[];for(D(a,"destroy"),W(a),p(a.axisTypes||[],function(b){(i=a[b])&&(ja(i.series,a),i.isDirty=i.forceRedraw=!0)}),a.legendItem&&a.chart.legend.destroyItem(a),e=f.length;e--;)(g=f[e])&&g.destroy&&g.destroy();a.points=null,clearTimeout(a.animationTimeout),p("area,graph,dataLabelsGroup,group,markerGroup,tracker,graphNeg,areaNeg,posClip,negClip".split(","),function(b){a[b]&&(d=c&&"group"===b?"hide":"destroy",a[b][d]())}),b.hoverSeries===a&&(b.hoverSeries=null),ja(b.series,a);for(h in a)delete a[h]},getSegmentPath:function(a){var b=this,c=[],d=b.options.step;return p(a,function(e,f){var i,g=e.plotX,h=e.plotY;b.getPointSpline?c.push.apply(c,b.getPointSpline(a,e,f)):(c.push(f?"L":"M"),d&&f&&(i=a[f-1],"right"===d?c.push(i.plotX,h):"center"===d?c.push((i.plotX+g)/2,i.plotY,(i.plotX+g)/2,h):c.push(g,i.plotY)),c.push(e.plotX,e.plotY))}),c},getGraphPath:function(){var c,a=this,b=[],d=[];return p(a.segments,function(e){c=a.getSegmentPath(e),e.length>1?b=b.concat(c):d.push(e[0])}),a.singlePoints=d,a.graphPath=b},drawGraph:function(){var a=this,b=this.options,c=[["graph",b.lineColor||this.color]],d=b.lineWidth,e=b.dashStyle,f="square"!==b.linecap,g=this.getGraphPath(),h=b.negativeColor;h&&c.push(["graphNeg",h]),p(c,function(c,h){var k=c[0],l=a[k];l?(bb(l),l.animate({d:g})):d&&g.length&&(l={stroke:c[1],"stroke-width":d,fill:Q,zIndex:1},e?l.dashstyle=e:f&&(l["stroke-linecap"]=l["stroke-linejoin"]="round"),a[k]=a.chart.renderer.path(g).attr(l).add(a.group).shadow(!h&&b.shadow))})},clipNeg:function(){var e,a=this.options,b=this.chart,c=b.renderer,d=a.negativeColor||a.negativeFillColor,f=this.graph,g=this.area,h=this.posClip,i=this.negClip;e=b.chartWidth;var j=b.chartHeight,k=v(e,j),l=this.yAxis;d&&(f||g)&&(d=u(l.toPixels(a.threshold||0,!0)),0>d&&(k-=d),a={x:0,y:0,width:k,height:d},k={x:0,y:d,width:k,height:k},b.inverted&&(a.height=k.y=b.plotWidth-d,c.isVML&&(a={x:b.plotWidth-d-b.plotLeft,y:0,width:e,height:j},k={x:d+b.plotLeft-e,y:0,width:b.plotLeft+d,height:e})),l.reversed?(b=k,e=a):(b=a,e=k),h?(h.animate(b),i.animate(e)):(this.posClip=h=c.clipRect(b),this.negClip=i=c.clipRect(e),f&&this.graphNeg&&(f.clip(h),this.graphNeg.clip(i)),g&&(g.clip(h),this.areaNeg.clip(i))))},invertGroups:function(){function a(){var a={width:b.yAxis.len,height:b.xAxis.len};p(["group","markerGroup"],function(c){b[c]&&b[c].attr(a).invert()})}var b=this,c=b.chart;b.xAxis&&(K(c,"resize",a),K(b,"destroy",function(){W(c,"resize",a)}),a(),b.invertGroups=a)},plotGroup:function(a,b,c,d,e){var f=this[a],g=!f;return g&&(this[a]=f=this.chart.renderer.g(b).attr({visibility:c,zIndex:d||.1}).add(e)),f[g?"attr":"animate"](this.getPlotBox()),f},getPlotBox:function(){var a=this.chart,b=this.xAxis,c=this.yAxis;return a.inverted&&(b=c,c=this.xAxis),{translateX:b?b.left:a.plotLeft,translateY:c?c.top:a.plotTop,scaleX:1,scaleY:1}},render:function(){var c,a=this,b=a.chart,d=a.options,e=(c=d.animation)&&!!a.animate&&b.renderer.isSVG&&m(c.duration,500)||0,f=a.visible?"visible":"hidden",g=d.zIndex,h=a.hasRendered,i=b.seriesGroup;c=a.plotGroup("group","series",f,g,i),a.markerGroup=a.plotGroup("markerGroup","markers",f,g,i),e&&a.animate(!0),a.getAttribs(),c.inverted=a.isCartesian?b.inverted:!1,a.drawGraph&&(a.drawGraph(),a.clipNeg()),a.drawDataLabels&&a.drawDataLabels(),a.visible&&a.drawPoints(),a.drawTracker&&a.options.enableMouseTracking!==!1&&a.drawTracker(),b.inverted&&a.invertGroups(),d.clip!==!1&&!a.sharedClipKey&&!h&&c.clip(b.clipRect),e&&a.animate(),h||(e?a.animationTimeout=setTimeout(function(){a.afterAnimate()},e):a.afterAnimate()),a.isDirty=a.isDirtyData=!1,a.hasRendered=!0},redraw:function(){var a=this.chart,b=this.isDirtyData,c=this.group,d=this.xAxis,e=this.yAxis;c&&(a.inverted&&c.attr({width:a.plotWidth,height:a.plotHeight}),c.animate({translateX:m(d&&d.left,a.plotLeft),translateY:m(e&&e.top,a.plotTop)})),this.translate(),this.setTooltipPoints&&this.setTooltipPoints(!0),this.render(),b&&D(this,"updatedData")}},Hb.prototype={destroy:function(){Oa(this,this.axis)},render:function(a){var b=this.options,c=b.format,c=c?Ia(c,this):b.formatter.call(this);this.label?this.label.attr({text:c,visibility:"hidden"}):this.label=this.axis.chart.renderer.text(c,null,null,b.useHTML).css(b.style).attr({align:this.textAlign,rotation:b.rotation,visibility:"hidden"}).add(a)},setOffset:function(a,b){var c=this.axis,d=c.chart,e=d.inverted,f=this.isNegative,g=c.translate(c.usePercentage?100:this.total,0,0,0,1),c=c.translate(0),c=M(g-c),h=d.xAxis[0].translate(this.x)+a,i=d.plotHeight,f={x:e?f?g:g-c:h,y:e?i-h-b:f?i-g-c:i-g,width:e?c:b,height:e?b:c};(e=this.label)&&(e.align(this.alignOptions,null,f),f=e.alignAttr,e[this.options.crop===!1||d.isInsidePlot(f.x,f.y)?"show":"hide"](!0))}},la.prototype.buildStacks=function(){var a=this.series,b=m(this.options.reversedStacks,!0),c=a.length;if(!this.isXAxis){for(this.usePercentage=!1;c--;)a[b?c:a.length-c-1].setStackedPoints();if(this.usePercentage)for(c=0;c<a.length;c++)a[c].setPercentStacks()}},la.prototype.renderStackTotals=function(){var d,e,a=this.chart,b=a.renderer,c=this.stacks,f=this.stackTotalGroup;f||(this.stackTotalGroup=f=b.g("stack-labels").attr({visibility:"visible",zIndex:6}).add()),f.translate(a.plotLeft,a.plotTop);for(d in c)for(e in a=c[d])a[e].render(f)},O.prototype.setStackedPoints=function(){if(this.options.stacking&&(this.visible===!0||this.chart.options.chart.ignoreHiddenSeries===!1)){var n,m,p,q,r,u,a=this.processedXData,b=this.processedYData,c=[],d=b.length,e=this.options,f=e.threshold,g=e.stack,e=e.stacking,h=this.stackKey,i="-"+h,j=this.negStacks,k=this.yAxis,l=k.stacks,o=k.oldStacks;for(q=0;d>q;q++)r=a[q],u=b[q],p=this.index+","+q,m=(n=j&&f>u)?i:h,l[m]||(l[m]={}),l[m][r]||(o[m]&&o[m][r]?(l[m][r]=o[m][r],l[m][r].total=null):l[m][r]=new Hb(k,k.options.stackLabels,n,r,g)),m=l[m][r],m.points[p]=[m.cum||0],"percent"===e?(n=n?h:i,j&&l[n]&&l[n][r]?(n=l[n][r],m.total=n.total=v(n.total,m.total)+M(u)||0):m.total=da(m.total+(M(u)||0))):m.total=da(m.total+(u||0)),m.cum=(m.cum||0)+(u||0),m.points[p].push(m.cum),c[q]=m.cum;"percent"===e&&(k.usePercentage=!0),this.stackedYData=c,k.oldStacks={}}},O.prototype.setPercentStacks=function(){var a=this,b=a.stackKey,c=a.yAxis.stacks,d=a.processedXData;p([b,"-"+b],function(b){for(var e,g,h,f=d.length;f--;)g=d[f],e=(h=c[b]&&c[b][g])&&h.points[a.index+","+f],(g=e)&&(h=h.total?100/h.total:0,g[0]=da(g[0]*h),g[1]=da(g[1]*h),a.stackedYData[f]=g[1])})},q(Ya.prototype,{addSeries:function(a,b,c){var d,e=this;return a&&(b=m(b,!0),D(e,"addSeries",{options:a},function(){d=e.initSeries(a),e.isDirtyLegend=!0,e.linkSeries(),b&&e.redraw(c)})),d},addAxis:function(a,b,c,d){var e=b?"xAxis":"yAxis",f=this.options;new la(this,w(a,{index:this[e].length,isX:b})),f[e]=qa(f[e]||{}),f[e].push(a),m(c,!0)&&this.redraw(d)},showLoading:function(a){var b=this.options,c=this.loadingDiv,d=b.loading;c||(this.loadingDiv=c=Y(Ja,{className:"highcharts-loading"},q(d.style,{zIndex:10,display:Q}),this.container),this.loadingSpan=Y("span",null,d.labelStyle,c)),this.loadingSpan.innerHTML=a||b.lang.loading,this.loadingShown||(G(c,{opacity:0,display:"",left:this.plotLeft+"px",top:this.plotTop+"px",width:this.plotWidth+"px",height:this.plotHeight+"px"}),kb(c,{opacity:d.style.opacity},{duration:d.showDuration||0}),this.loadingShown=!0)},hideLoading:function(){var a=this.options,b=this.loadingDiv;b&&kb(b,{opacity:0},{duration:a.loading.hideDuration||100,complete:function(){G(b,{display:Q})}}),this.loadingShown=!1}}),q(Ea.prototype,{update:function(a,b,c){var g,d=this,e=d.series,f=d.graphic,h=e.data,i=e.chart,j=e.options,b=m(b,!0);d.firePointEvent("update",{options:a},function(){d.applyOptions(a),ca(a)&&(e.getAttribs(),f&&(a&&a.marker&&a.marker.symbol?d.graphic=f.destroy():f.attr(d.pointAttr[d.state||""])),a&&a.dataLabels&&d.dataLabel&&(d.dataLabel=d.dataLabel.destroy())),g=Da(d,h),e.updateParallelArrays(d,g),j.data[g]=d.options,e.isDirty=e.isDirtyData=!0,!e.fixedBox&&e.hasCartesianSeries&&(i.isDirtyBox=!0),"point"===j.legendType&&i.legend.destroyItem(d),b&&i.redraw(c)})},remove:function(a,b){var g,c=this,d=c.series,e=d.points,f=d.chart,h=d.data;Qa(b,f),a=m(a,!0),c.firePointEvent("remove",null,function(){g=Da(c,h),h.length===e.length&&e.splice(g,1),h.splice(g,1),d.options.data.splice(g,1),d.updateParallelArrays(c,"splice",g,1),c.destroy(),d.isDirty=!0,d.isDirtyData=!0,a&&f.redraw()})}}),q(O.prototype,{addPoint:function(a,b,c,d){var o,e=this.options,f=this.data,g=this.graph,h=this.area,i=this.chart,j=this.xAxis&&this.xAxis.names,k=g&&g.shift||0,l=e.data,n=this.xData;if(Qa(d,i),c&&p([g,h,this.graphNeg,this.areaNeg],function(a){a&&(a.shift=k+1)}),h&&(h.isArea=!0),b=m(b,!0),d={series:this},this.pointClass.prototype.applyOptions.apply(d,[a]),g=d.x,h=n.length,this.requireSorting&&g<n[h-1])for(o=!0;h&&n[h-1]>g;)h--;this.updateParallelArrays(d,"splice",h,0,0),this.updateParallelArrays(d,h),j&&(j[g]=d.name),l.splice(h,0,a),o&&(this.data.splice(h,0,null),this.processData()),"point"===e.legendType&&this.generatePoints(),c&&(f[0]&&f[0].remove?f[0].remove(!1):(f.shift(),this.updateParallelArrays(d,"shift"),l.shift())),this.isDirtyData=this.isDirty=!0,b&&(this.getAttribs(),i.redraw())},remove:function(a,b){var c=this,d=c.chart,a=m(a,!0);c.isRemoving||(c.isRemoving=!0,D(c,"remove",null,function(){c.destroy(),d.isDirtyLegend=d.isDirtyBox=!0,d.linkSeries(),a&&d.redraw(b)})),c.isRemoving=!1},update:function(a,b){var f,c=this.chart,d=this.type,e=F[d].prototype,a=w(this.userOptions,{animation:!1,index:this.index,pointStart:this.xData[0]},{data:this.options.data},a);this.remove(!1);for(f in e)e.hasOwnProperty(f)&&(this[f]=t);q(this,F[a.type||d].prototype),this.init(c,a),m(b,!0)&&c.redraw(!1)}}),q(la.prototype,{update:function(a,b){var c=this.chart,a=c.options[this.coll][this.options.index]=w(this.userOptions,a);this.destroy(!0),this._addedPlotLB=t,this.init(c,q(a,{events:t})),c.isDirtyBox=!0,m(b,!0)&&c.redraw()},remove:function(a){for(var b=this.chart,c=this.coll,d=this.series,e=d.length;e--;)d[e]&&d[e].remove(!1);ja(b.axes,this),ja(b[c],this),b.options[c].splice(this.options.index,1),p(b[c],function(a,b){a.options.index=b}),this.destroy(),b.isDirtyBox=!0,m(a,!0)&&b.redraw()},setTitle:function(a,b){this.update({title:a},b)},setCategories:function(a,b){this.update({categories:a},b)}}),ga=ka(O),F.line=ga,ba.area=w(S,{threshold:0});var pa=ka(O,{type:"area",getSegments:function(){var h,i,l,o,n,a=[],b=[],c=[],d=this.xAxis,e=this.yAxis,f=e.stacks[this.stackKey],g={},j=this.points,k=this.options.connectNulls;if(this.options.stacking&&!this.cropped){for(o=0;o<j.length;o++)g[j[o].x]=j[o];for(n in f)null!==f[n].total&&c.push(+n);c.sort(function(a,b){return a-b}),p(c,function(a){(!k||g[a]&&null!==g[a].y)&&(g[a]?b.push(g[a]):(h=d.translate(a),l=f[a].percent?f[a].total?100*f[a].cum/f[a].total:0:f[a].cum,i=e.toPixels(l,!0),b.push({y:null,plotX:h,clientX:h,plotY:i,yBottom:i,onMouseOver:sa})))}),b.length&&a.push(b)}else O.prototype.getSegments.call(this),a=this.segments;this.segments=a},getSegmentPath:function(a){var d,b=O.prototype.getSegmentPath.call(this,a),c=[].concat(b),e=this.options;d=b.length;var g,f=this.yAxis.getThreshold(e.threshold);if(3===d&&c.push("L",b[1],b[2]),e.stacking&&!this.closedStacks)for(d=a.length-1;d>=0;d--)g=m(a[d].yBottom,f),d<a.length-1&&e.step&&c.push(a[d+1].plotX,g),c.push(a[d].plotX,g);else this.closeSegment(c,a,f);return this.areaPath=this.areaPath.concat(c),b},closeSegment:function(a,b,c){a.push("L",b[b.length-1].plotX,c,"L",b[0].plotX,c)},drawGraph:function(){this.areaPath=[],O.prototype.drawGraph.apply(this);var a=this,b=this.areaPath,c=this.options,d=c.negativeColor,e=c.negativeFillColor,f=[["area",this.color,c.fillColor]];(d||e)&&f.push(["areaNeg",d,e]),p(f,function(d){var e=d[0],f=a[e];f?f.animate({d:b}):a[e]=a.chart.renderer.path(b).attr({fill:m(d[2],ya(d[1]).setOpacity(m(c.fillOpacity,.75)).get()),zIndex:0}).add(a.group)
|
5 |
-
})},drawLegendSymbol:N.drawRectangle});F.area=pa,ba.spline=w(S),ga=ka(O,{type:"spline",getPointSpline:function(a,b,c){var h,i,j,k,d=b.plotX,e=b.plotY,f=a[c-1],g=a[c+1];if(f&&g){a=f.plotY,j=g.plotX;var l,g=g.plotY;h=(1.5*d+f.plotX)/2.5,i=(1.5*e+a)/2.5,j=(1.5*d+j)/2.5,k=(1.5*e+g)/2.5,l=(k-i)*(j-d)/(j-h)+e-k,i+=l,k+=l,i>a&&i>e?(i=v(a,e),k=2*e-i):a>i&&e>i&&(i=C(a,e),k=2*e-i),k>g&&k>e?(k=v(g,e),i=2*e-k):g>k&&e>k&&(k=C(g,e),i=2*e-k),b.rightContX=j,b.rightContY=k}return c?(b=["C",f.rightContX||f.plotX,f.rightContY||f.plotY,h||d,i||e,d,e],f.rightContX=f.rightContY=null):b=["M",d,e],b}}),F.spline=ga,ba.areaspline=w(ba.area),pa=pa.prototype,ga=ka(ga,{type:"areaspline",closedStacks:!0,getSegmentPath:pa.getSegmentPath,closeSegment:pa.closeSegment,drawGraph:pa.drawGraph,drawLegendSymbol:N.drawRectangle}),F.areaspline=ga,ba.column=w(S,{borderColor:"#FFFFFF",borderRadius:0,groupPadding:.2,marker:null,pointPadding:.1,minPointLength:0,cropThreshold:50,pointRange:null,states:{hover:{brightness:.1,shadow:!1,halo:!1},select:{color:"#C0C0C0",borderColor:"#000000",shadow:!1}},dataLabels:{align:null,verticalAlign:null,y:null},stickyTracking:!1,tooltip:{distance:6},threshold:0}),ga=ka(O,{type:"column",pointAttrToOptions:{stroke:"borderColor",fill:"color",r:"borderRadius"},cropShoulder:0,trackerGroups:["group","dataLabelsGroup"],negStacks:!0,init:function(){O.prototype.init.apply(this,arguments);var a=this,b=a.chart;b.hasRendered&&p(b.series,function(b){b.type===a.type&&(b.isDirty=!0)})},getColumnMetrics:function(){var f,h,a=this,b=a.options,c=a.xAxis,d=a.yAxis,e=c.reversed,g={},i=0;b.grouping===!1?i=1:p(a.chart.series,function(b){var c=b.options,e=b.yAxis;b.type===a.type&&b.visible&&d.len===e.len&&d.pos===e.pos&&(c.stacking?(f=b.stackKey,g[f]===t&&(g[f]=i++),h=g[f]):c.grouping!==!1&&(h=i++),b.columnIndex=h)});var c=C(M(c.transA)*(c.ordinalSlope||b.pointRange||c.closestPointRange||c.tickInterval||1),c.len),j=c*b.groupPadding,k=(c-2*j)/i,l=b.pointWidth,b=r(l)?(k-l)/2:k*b.pointPadding,l=m(l,k-2*b);return a.columnMetrics={width:l,offset:b+(j+((e?i-(a.columnIndex||0):a.columnIndex)||0)*k-c/2)*(e?-1:1)}},translate:function(){var a=this,b=a.chart,c=a.options,d=a.borderWidth=m(c.borderWidth,a.activePointCount>.5*a.xAxis.len?0:1),e=a.yAxis,f=a.translatedThreshold=e.getThreshold(c.threshold),g=m(c.minPointLength,5),c=a.getColumnMetrics(),h=c.width,i=a.barW=Ka(v(h,1+2*d)),j=a.pointXOffset=c.offset,k=-(d%2?.5:0),l=d%2?.5:1;b.renderer.isVML&&b.inverted&&(l+=1),O.prototype.translate.apply(a),p(a.points,function(c){var x,d=m(c.yBottom,f),p=C(v(-999-d,c.plotY),e.len+999+d),q=c.plotX+j,r=i,t=C(p,d);x=v(p,d)-t,M(x)<g&&g&&(x=g,t=u(M(t-f)>g?d-g:f-(e.translate(c.y,0,1,0,1)<=f?g:0))),c.barX=q,c.pointWidth=h,c.tooltipPos=b.inverted?[e.len-p,a.xAxis.len-q-r/2]:[q+r/2,p],d=M(q)<.5,r=u(q+r)+k,q=u(q)+k,r-=q,p=M(t)<.5,x=u(t+x)+l,t=u(t)+l,x-=t,d&&(q+=1,r-=1),p&&(t-=1,x+=1),c.shapeType="rect",c.shapeArgs={x:q,y:t,width:r,height:x}})},getSymbol:sa,drawLegendSymbol:N.drawRectangle,drawGraph:sa,drawPoints:function(){var f,g,h,a=this,b=this.chart,c=a.options,d=b.renderer,e=c.animationLimit||250;p(a.points,function(i){var j=i.plotY,k=i.graphic;j===t||isNaN(j)||null===i.y?k&&(i.graphic=k.destroy()):(f=i.shapeArgs,h=r(a.borderWidth)?{"stroke-width":a.borderWidth}:{},g=i.pointAttr[i.selected?"select":""]||a.pointAttr[""],k?(bb(k),k.attr(h)[b.pointCount<e?"animate":"attr"](w(f))):i.graphic=d[i.shapeType](f).attr(g).attr(h).add(a.group).shadow(c.shadow,null,c.stacking&&!c.borderRadius))})},animate:function(a){var b=this.yAxis,c=this.options,d=this.chart.inverted,e={};aa&&(a?(e.scaleY=.001,a=C(b.pos+b.len,v(b.pos,b.toPixels(c.threshold))),d?e.translateX=a-b.len:e.translateY=a,this.group.attr(e)):(e.scaleY=1,e[d?"translateX":"translateY"]=b.pos,this.group.animate(e,this.options.animation),this.animate=null))},remove:function(){var a=this,b=a.chart;b.hasRendered&&p(b.series,function(b){b.type===a.type&&(b.isDirty=!0)}),O.prototype.remove.apply(a,arguments)}}),F.column=ga,ba.bar=w(ba.column),pa=ka(ga,{type:"bar",inverted:!0}),F.bar=pa,ba.scatter=w(S,{lineWidth:0,tooltip:{headerFormat:'<span style="color:{series.color}">â—</span> <span style="font-size: 10px;"> {series.name}</span><br/>',pointFormat:"x: <b>{point.x}</b><br/>y: <b>{point.y}</b><br/>"},stickyTracking:!1}),pa=ka(O,{type:"scatter",sorted:!1,requireSorting:!1,noSharedTooltip:!0,trackerGroups:["markerGroup"],takeOrdinalPosition:!1,singularTooltips:!0,drawGraph:function(){this.options.lineWidth&&O.prototype.drawGraph.call(this)}}),F.scatter=pa,ba.pie=w(S,{borderColor:"#FFFFFF",borderWidth:1,center:[null,null],clip:!1,colorByPoint:!0,dataLabels:{distance:30,enabled:!0,formatter:function(){return this.point.name}},ignoreHiddenPoint:!0,legendType:"point",marker:null,size:null,showInLegend:!1,slicedOffset:10,states:{hover:{brightness:.1,shadow:!1}},stickyTracking:!1,tooltip:{followPointer:!0}}),S={type:"pie",isCartesian:!1,pointClass:ka(Ea,{init:function(){Ea.prototype.init.apply(this,arguments);var b,a=this;return a.y<0&&(a.y=null),q(a,{visible:a.visible!==!1,name:m(a.name,"Slice")}),b=function(b){a.slice("select"===b.type)},K(a,"select",b),K(a,"unselect",b),a},setVisible:function(a){var b=this,c=b.series,d=c.chart;b.visible=b.options.visible=a=a===t?!b.visible:a,c.options.data[Da(b,c.data)]=b.options,p(["graphic","dataLabel","connector","shadowGroup"],function(c){b[c]&&b[c][a?"show":"hide"](!0)}),b.legendItem&&d.legend.colorizeItem(b,a),!c.isDirty&&c.options.ignoreHiddenPoint&&(c.isDirty=!0,d.redraw())},slice:function(a,b,c){var d=this.series;Qa(c,d.chart),m(b,!0),this.sliced=this.options.sliced=a=r(a)?a:!this.sliced,d.options.data[Da(this,d.data)]=this.options,a=a?this.slicedTranslation:{translateX:0,translateY:0},this.graphic.animate(a),this.shadowGroup&&this.shadowGroup.animate(a)},haloPath:function(a){var b=this.shapeArgs,c=this.series.chart;return this.series.chart.renderer.symbols.arc(c.plotLeft+b.x,c.plotTop+b.y,b.r+a,b.r+a,{innerR:this.shapeArgs.r,start:b.start,end:b.end})}}),requireSorting:!1,noSharedTooltip:!0,trackerGroups:["group","dataLabelsGroup"],axisTypes:[],pointAttrToOptions:{stroke:"borderColor","stroke-width":"borderWidth",fill:"color"},singularTooltips:!0,getColor:sa,animate:function(a){var b=this,c=b.points,d=b.startAngleRad;a||(p(c,function(a){var c=a.graphic,a=a.shapeArgs;c&&(c.attr({r:b.center[3]/2,start:d,end:d}),c.animate({r:a.r,start:a.start,end:a.end},b.options.animation))}),b.animate=null)},setData:function(a,b,c,d){O.prototype.setData.call(this,a,!1,c,d),this.processData(),this.generatePoints(),m(b,!0)&&this.chart.redraw(c)},generatePoints:function(){var a,c,d,e,b=0,f=this.options.ignoreHiddenPoint;for(O.prototype.generatePoints.call(this),c=this.points,d=c.length,a=0;d>a;a++)e=c[a],b+=f&&!e.visible?0:e.y;for(this.total=b,a=0;d>a;a++)e=c[a],e.percentage=b>0?e.y/b*100:0,e.total=b},translate:function(a){this.generatePoints();var f,g,h,o,p,b=0,c=this.options,d=c.slicedOffset,e=d+c.borderWidth,i=c.startAngle||0,j=this.startAngleRad=ma/180*(i-90),i=(this.endAngleRad=ma/180*(m(c.endAngle,i+360)-90))-j,k=this.points,l=c.dataLabels.distance,c=c.ignoreHiddenPoint,n=k.length;for(a||(this.center=a=this.getCenter()),this.getX=function(b,c){return h=U.asin(C((b-a[1])/(a[2]/2+l),1)),a[0]+(c?-1:1)*Z(h)*(a[2]/2+l)},o=0;n>o;o++)p=k[o],f=j+b*i,(!c||p.visible)&&(b+=p.percentage/100),g=j+b*i,p.shapeType="arc",p.shapeArgs={x:a[0],y:a[1],r:a[2]/2,innerR:a[3]/2,start:u(1e3*f)/1e3,end:u(1e3*g)/1e3},h=(g+f)/2,h>1.5*ma?h-=2*ma:-ma/2>h&&(h+=2*ma),p.slicedTranslation={translateX:u(Z(h)*d),translateY:u(ea(h)*d)},f=Z(h)*a[2]/2,g=ea(h)*a[2]/2,p.tooltipPos=[a[0]+.7*f,a[1]+.7*g],p.half=-ma/2>h||h>ma/2?1:0,p.angle=h,e=C(e,l/2),p.labelPos=[a[0]+f+Z(h)*l,a[1]+g+ea(h)*l,a[0]+f+Z(h)*e,a[1]+g+ea(h)*e,a[0]+f,a[1]+g,0>l?"center":p.half?"right":"left",h]},drawGraph:null,drawPoints:function(){var c,d,f,g,a=this,b=a.chart.renderer,e=a.options.shadow;e&&!a.shadowGroup&&(a.shadowGroup=b.g("shadow").add(a.group)),p(a.points,function(h){d=h.graphic,g=h.shapeArgs,f=h.shadowGroup,e&&!f&&(f=h.shadowGroup=b.g("shadow").add(a.shadowGroup)),c=h.sliced?h.slicedTranslation:{translateX:0,translateY:0},f&&f.attr(c),d?d.animate(q(g,c)):h.graphic=d=b[h.shapeType](g).setRadialReference(a.center).attr(h.pointAttr[h.selected?"select":""]).attr({"stroke-linejoin":"round"}).attr(c).add(a.group).shadow(e,f),void 0!==h.visible&&h.setVisible(h.visible)})},sortByAngle:function(a,b){a.sort(function(a,d){return void 0!==a.angle&&(d.angle-a.angle)*b})},drawLegendSymbol:N.drawRectangle,getCenter:X.getCenter,getSymbol:sa},S=ka(O,S),F.pie=S,O.prototype.drawDataLabels=function(){var f,g,h,i,a=this,b=a.options,c=b.cursor,d=b.dataLabels,e=a.points;(d.enabled||a._hasPointLabels)&&(a.dlProcessOptions&&a.dlProcessOptions(d),i=a.plotGroup("dataLabelsGroup","data-labels","hidden",d.zIndex||6),!a.hasRendered&&m(d.defer,!0)&&(i.attr({opacity:0}),K(a,"afterAnimate",function(){a.dataLabelsGroup.show()[b.animation?"animate":"attr"]({opacity:1},{duration:200})})),g=d,p(e,function(b){var e,o,n,l=b.dataLabel,p=b.connector,u=!0;if(f=b.options&&b.options.dataLabels,e=m(f&&f.enabled,g.enabled),l&&!e)b.dataLabel=l.destroy();else if(e){if(d=w(g,f),e=d.rotation,o=b.getLabelConfig(),h=d.format?Ia(d.format,o):d.formatter.call(o,d),d.style.color=m(d.color,d.style.color,a.color,"black"),l)r(h)?(l.attr({text:h}),u=!1):(b.dataLabel=l=l.destroy(),p&&(b.connector=p.destroy()));else if(r(h)){l={fill:d.backgroundColor,stroke:d.borderColor,"stroke-width":d.borderWidth,r:d.borderRadius||0,rotation:e,padding:d.padding,zIndex:1};for(n in l)l[n]===t&&delete l[n];l=b.dataLabel=a.chart.renderer[e?"text":"label"](h,0,-999,null,null,null,d.useHTML).attr(l).css(q(d.style,c&&{cursor:c})).add(i).shadow(d.shadow)}l&&a.alignDataLabel(b,l,d,null,u)}}))},O.prototype.alignDataLabel=function(a,b,c,d,e){var f=this.chart,g=f.inverted,h=m(a.plotX,-999),i=m(a.plotY,-999),j=b.getBBox();(a=this.visible&&(a.series.forceDL||f.isInsidePlot(h,u(i),g)||d&&f.isInsidePlot(h,g?d.x+1:d.y+d.height-1,g)))&&(d=q({x:g?f.plotWidth-i:h,y:u(g?f.plotHeight-h:i),width:0,height:0},d),q(c,{width:j.width,height:j.height}),c.rotation?(g={align:c.align,x:d.x+c.x+d.width/2,y:d.y+c.y+d.height/2},b[e?"attr":"animate"](g)):(b.align(c,null,d),g=b.alignAttr,"justify"===m(c.overflow,"justify")?this.justifyDataLabel(b,c,g,j,d,e):m(c.crop,!0)&&(a=f.isInsidePlot(g.x,g.y)&&f.isInsidePlot(g.x+j.width,g.y+j.height)))),a||(b.attr({y:-999}),b.placed=!1)},O.prototype.justifyDataLabel=function(a,b,c,d,e,f){var j,k,g=this.chart,h=b.align,i=b.verticalAlign;j=c.x,0>j&&("right"===h?b.align="left":b.x=-j,k=!0),j=c.x+d.width,j>g.plotWidth&&("left"===h?b.align="right":b.x=g.plotWidth-j,k=!0),j=c.y,0>j&&("bottom"===i?b.verticalAlign="top":b.y=-j,k=!0),j=c.y+d.height,j>g.plotHeight&&("top"===i?b.verticalAlign="bottom":b.y=g.plotHeight-j,k=!0),k&&(a.placed=!f,a.align(b,null,e))},F.pie&&(F.pie.prototype.drawDataLabels=function(){var c,i,j,t,w,x,y,A,C,G,D,B,a=this,b=a.data,d=a.chart,e=a.options.dataLabels,f=m(e.connectorPadding,10),g=m(e.connectorWidth,1),h=d.plotWidth,d=d.plotHeight,k=m(e.softConnector,!0),l=e.distance,o=a.center,n=o[2]/2,q=o[1],r=l>0,z=[[],[]],F=[0,0,0,0],N=function(a,b){return b.y-a.y};if(a.visible&&(e.enabled||a._hasPointLabels)){for(O.prototype.drawDataLabels.apply(a),p(b,function(a){a.dataLabel&&a.visible&&z[a.half].push(a)}),D=0;!y&&b[D];)y=b[D]&&b[D].dataLabel&&(b[D].dataLabel.getBBox().height||21),D++;for(D=2;D--;){var E,b=[],K=[],H=z[D],I=H.length;if(a.sortByAngle(H,D-.5),l>0){for(B=q-n-l;q+n+l>=B;B+=y)b.push(B);if(w=b.length,I>w){for(c=[].concat(H),c.sort(N),B=I;B--;)c[B].rank=B;for(B=I;B--;)H[B].rank>=w&&H.splice(B,1);I=H.length}for(B=0;I>B;B++){c=H[B],x=c.labelPos,c=9999;var Q,P;for(P=0;w>P;P++)Q=M(b[P]-x[1]),c>Q&&(c=Q,E=P);if(B>E&&null!==b[B])E=B;else for(I-B+E>w&&null!==b[B]&&(E=w-I+B);null===b[E];)E++;K.push({i:E,y:b[E]}),b[E]=null}K.sort(N)}for(B=0;I>B;B++)c=H[B],x=c.labelPos,t=c.dataLabel,G=c.visible===!1?"hidden":"visible",c=x[1],l>0?(w=K.pop(),E=w.i,C=w.y,(c>C&&null!==b[E+1]||C>c&&null!==b[E-1])&&(C=c)):C=c,A=e.justify?o[0]+(D?-1:1)*(n+l):a.getX(0===E||E===b.length-1?c:C,D),t._attr={visibility:G,align:x[6]},t._pos={x:A+e.x+({left:f,right:-f}[x[6]]||0),y:C+e.y-10},t.connX=A,t.connY=C,null===this.options.size&&(w=t.width,f>A-w?F[3]=v(u(w-A+f),F[3]):A+w>h-f&&(F[1]=v(u(A+w-h+f),F[1])),0>C-y/2?F[0]=v(u(-C+y/2),F[0]):C+y/2>d&&(F[2]=v(u(C+y/2-d),F[2])))}(0===Ba(F)||this.verifyDataLabelOverflow(F))&&(this.placeDataLabels(),r&&g&&p(this.points,function(b){i=b.connector,x=b.labelPos,(t=b.dataLabel)&&t._pos?(G=t._attr.visibility,A=t.connX,C=t.connY,j=k?["M",A+("left"===x[6]?5:-5),C,"C",A,C,2*x[2]-x[4],2*x[3]-x[5],x[2],x[3],"L",x[4],x[5]]:["M",A+("left"===x[6]?5:-5),C,"L",x[2],x[3],"L",x[4],x[5]],i?(i.animate({d:j}),i.attr("visibility",G)):b.connector=i=a.chart.renderer.path(j).attr({"stroke-width":g,stroke:e.connectorColor||b.color||"#606060",visibility:G}).add(a.dataLabelsGroup)):i&&(b.connector=i.destroy())}))}},F.pie.prototype.placeDataLabels=function(){p(this.points,function(a){var b,a=a.dataLabel;a&&((b=a._pos)?(a.attr(a._attr),a[a.moved?"animate":"attr"](b),a.moved=!0):a&&a.attr({y:-999}))})},F.pie.prototype.alignDataLabel=sa,F.pie.prototype.verifyDataLabelOverflow=function(a){var f,b=this.center,c=this.options,d=c.center,e=c=c.minSize||80;return null!==d[0]?e=v(b[2]-v(a[1],a[3]),c):(e=v(b[2]-a[1]-a[3],c),b[0]+=(a[3]-a[1])/2),null!==d[1]?e=v(C(e,b[2]-v(a[0],a[2])),c):(e=v(C(e,b[2]-a[0]-a[2]),c),b[1]+=(a[0]-a[2])/2),e<b[2]?(b[2]=e,this.translate(b),p(this.points,function(a){a.dataLabel&&(a.dataLabel._pos=null)}),this.drawDataLabels&&this.drawDataLabels()):f=!0,f}),F.column&&(F.column.prototype.alignDataLabel=function(a,b,c,d,e){var f=this.chart,g=f.inverted,h=a.dlBox||a.shapeArgs,i=a.below||a.plotY>m(this.translatedThreshold,f.plotSizeY),j=m(c.inside,!!this.options.stacking);h&&(d=w(h),g&&(d={x:f.plotWidth-d.y-d.height,y:f.plotHeight-d.x-d.width,width:d.height,height:d.width}),!j)&&(g?(d.x+=i?0:d.width,d.width=0):(d.y+=i?d.height:0,d.height=0)),c.align=m(c.align,!g||j?"center":i?"right":"left"),c.verticalAlign=m(c.verticalAlign,g||j?"middle":i?"top":"bottom"),O.prototype.alignDataLabel.call(this,a,b,c,d,e)}),S=R.TrackerMixin={drawTrackerPoint:function(){var a=this,b=a.chart,c=b.pointer,d=a.options.cursor,e=d&&{cursor:d},f=function(c){var e,d=c.target;for(b.hoverSeries!==a&&a.onMouseOver();d&&!e;)e=d.point,d=d.parentNode;e!==t&&e!==b.hoverPoint&&e.onMouseOver(c)};p(a.points,function(a){a.graphic&&(a.graphic.element.point=a),a.dataLabel&&(a.dataLabel.element.point=a)}),a._hasTracking||(p(a.trackerGroups,function(b){a[b]&&(a[b].addClass("highcharts-tracker").on("mouseover",f).on("mouseout",function(a){c.onTrackerMouseOut(a)}).css(e),$a)&&a[b].on("touchstart",f)}),a._hasTracking=!0)},drawTrackerGraph:function(){var m,a=this,b=a.options,c=b.trackByArea,d=[].concat(c?a.areaPath:a.graphPath),e=d.length,f=a.chart,g=f.pointer,h=f.renderer,i=f.options.tooltip.snap,j=a.tracker,k=b.cursor,l=k&&{cursor:k},k=a.singlePoints,n=function(){f.hoverSeries!==a&&a.onMouseOver()},q="rgba(192,192,192,"+(aa?1e-4:.002)+")";if(e&&!c)for(m=e+1;m--;)"M"===d[m]&&d.splice(m+1,0,d[m+1]-i,d[m+2],"L"),(m&&"M"===d[m]||m===e)&&d.splice(m,0,"L",d[m-2]+i,d[m-1]);for(m=0;m<k.length;m++)e=k[m],d.push("M",e.plotX-i,e.plotY,"L",e.plotX+i,e.plotY);j?j.attr({d:d}):(a.tracker=h.path(d).attr({"stroke-linejoin":"round",visibility:a.visible?"visible":"hidden",stroke:q,fill:c?q:Q,"stroke-width":b.lineWidth+(c?0:2*i),zIndex:2}).add(a.group),p([a.tracker,a.markerGroup],function(a){a.addClass("highcharts-tracker").on("mouseover",n).on("mouseout",function(a){g.onTrackerMouseOut(a)}).css(l),$a&&a.on("touchstart",n)}))}},F.column&&(ga.prototype.drawTracker=S.drawTrackerPoint),F.pie&&(F.pie.prototype.drawTracker=S.drawTrackerPoint),F.scatter&&(pa.prototype.drawTracker=S.drawTrackerPoint),q(lb.prototype,{setItemEvents:function(a,b,c,d,e){var f=this;(c?b:a.legendGroup).on("mouseover",function(){a.setState("hover"),b.css(f.options.itemHoverStyle)}).on("mouseout",function(){b.css(a.visible?d:e),a.setState()}).on("click",function(b){var c=function(){a.setVisible()},b={browserEvent:b};a.firePointEvent?a.firePointEvent("legendItemClick",b,c):D(a,"legendItemClick",b,c)})},createCheckboxForItem:function(a){a.checkbox=Y("input",{type:"checkbox",checked:a.selected,defaultChecked:a.selected},this.options.itemCheckboxStyle,this.chart.container),K(a.checkbox,"click",function(b){D(a,"checkboxClick",{checked:b.target.checked},function(){a.select()})})}}),E.legend.itemStyle.cursor="pointer",q(Ya.prototype,{showResetZoom:function(){var a=this,b=E.lang,c=a.options.chart.resetZoomButton,d=c.theme,e=d.states,f="chart"===c.relativeTo?null:"plotBox";this.resetZoomButton=a.renderer.button(b.resetZoom,null,null,function(){a.zoomOut()},d,e&&e.hover).attr({align:c.position.align,title:b.resetZoomTitle}).add().align(c.position,!1,f)},zoomOut:function(){var a=this;D(a,"selection",{resetSelection:!0},function(){a.zoom()})},zoom:function(a){var b,e,c=this.pointer,d=!1;!a||a.resetSelection?p(this.axes,function(a){b=a.zoom()}):p(a.xAxis.concat(a.yAxis),function(a){var e=a.axis,h=e.isXAxis;(c[h?"zoomX":"zoomY"]||c[h?"pinchX":"pinchY"])&&(b=e.zoom(a.min,a.max),e.displayBtn&&(d=!0))}),e=this.resetZoomButton,d&&!e?this.showResetZoom():!d&&ca(e)&&(this.resetZoomButton=e.destroy()),b&&this.redraw(m(this.options.chart.animation,a&&a.animation,this.pointCount<100))},pan:function(a,b){var e,c=this,d=c.hoverPoints;d&&p(d,function(a){a.setState()}),p("xy"===b?[1,0]:[1],function(b){var d=a[b?"chartX":"chartY"],h=c[b?"xAxis":"yAxis"][0],i=c[b?"mouseDownX":"mouseDownY"],j=(h.pointRange||0)/2,k=h.getExtremes(),l=h.toValue(i-d,!0)+j,i=h.toValue(i+c[b?"plotWidth":"plotHeight"]-d,!0)-j;h.series.length&&l>C(k.dataMin,k.min)&&i<v(k.dataMax,k.max)&&(h.setExtremes(l,i,!1,!1,{trigger:"pan"}),e=!0),c[b?"mouseDownX":"mouseDownY"]=d}),e&&c.redraw(!1),G(c.container,{cursor:"move"})}}),q(Ea.prototype,{select:function(a,b){var c=this,d=c.series,e=d.chart,a=m(a,!c.selected);c.firePointEvent(a?"select":"unselect",{accumulate:b},function(){c.selected=c.options.selected=a,d.options.data[Da(c,d.data)]=c.options,c.setState(a&&"select"),b||p(e.getSelectedPoints(),function(a){a.selected&&a!==c&&(a.selected=a.options.selected=!1,d.options.data[Da(a,d.data)]=a.options,a.setState(""),a.firePointEvent("unselect"))})})},onMouseOver:function(a){var b=this.series,c=b.chart,d=c.tooltip,e=c.hoverPoint;e&&e!==this&&e.onMouseOut(),this.firePointEvent("mouseOver"),d&&(!d.shared||b.noSharedTooltip)&&d.refresh(this,a),this.setState("hover"),c.hoverPoint=this},onMouseOut:function(){var a=this.series.chart,b=a.hoverPoints;b&&-1!==Da(this,b)||(this.firePointEvent("mouseOut"),this.setState(),a.hoverPoint=null)},importEvents:function(){if(!this.hasImportedEvents){var b,a=w(this.series.options.point,this.options).events;this.events=a;for(b in a)K(this,b,a[b]);this.hasImportedEvents=!0}},setState:function(a,b){var p,c=this.plotX,d=this.plotY,e=this.series,f=e.options.states,g=ba[e.type].marker&&e.options.marker,h=g&&!g.enabled,i=g&&g.states[a],j=i&&i.enabled===!1,k=e.stateMarkerGraphic,l=this.marker||{},m=e.chart,n=e.halo,a=a||"";p=this.pointAttr[a]||e.pointAttr[a],a===this.state&&!b||this.selected&&"select"!==a||f[a]&&f[a].enabled===!1||a&&(j||h&&i.enabled===!1)||a&&l.states&&l.states[a]&&l.states[a].enabled===!1||(this.graphic?(g=g&&this.graphic.symbolName&&p.r,this.graphic.attr(w(p,g?{x:c-g,y:d-g,width:2*g,height:2*g}:{})),k&&k.hide()):(a&&i&&(g=i.radius,l=l.symbol||e.symbol,k&&k.currentSymbol!==l&&(k=k.destroy()),k?k[b?"animate":"attr"]({x:c-g,y:d-g}):l&&(e.stateMarkerGraphic=k=m.renderer.symbol(l,c-g,d-g,2*g,2*g).attr(p).add(e.markerGroup),k.currentSymbol=l)),k&&k[a&&m.isInsidePlot(c,d,m.inverted)?"show":"hide"]()),(c=f[a]&&f[a].halo)&&c.size?(n||(e.halo=n=m.renderer.path().add(e.seriesGroup)),n.attr(q({fill:ya(this.color||e.color).setOpacity(c.opacity).get()},c.attributes))[b?"animate":"attr"]({d:this.haloPath(c.size)})):n&&n.attr({d:[]}),this.state=a)},haloPath:function(a){var b=this.series,c=b.chart,d=b.getPlotBox(),e=c.inverted;return c.renderer.symbols.circle(d.translateX+(e?b.yAxis.len-this.plotY:this.plotX)-a,d.translateY+(e?b.xAxis.len-this.plotX:this.plotY)-a,2*a,2*a)}}),q(O.prototype,{onMouseOver:function(){var a=this.chart,b=a.hoverSeries;b&&b!==this&&b.onMouseOut(),this.options.events.mouseOver&&D(this,"mouseOver"),this.setState("hover"),a.hoverSeries=this},onMouseOut:function(){var a=this.options,b=this.chart,c=b.tooltip,d=b.hoverPoint;d&&d.onMouseOut(),this&&a.events.mouseOut&&D(this,"mouseOut"),c&&!a.stickyTracking&&(!c.shared||this.noSharedTooltip)&&c.hide(),this.setState(),b.hoverSeries=null},setState:function(a){var b=this.options,c=this.graph,d=this.graphNeg,e=b.states,b=b.lineWidth,a=a||"";this.state!==a&&(this.state=a,e[a]&&e[a].enabled===!1||(a&&(b=e[a].lineWidth||b+1),c&&!c.dashstyle&&(a={"stroke-width":b},c.attr(a),d&&d.attr(a))))},setVisible:function(a,b){var f,c=this,d=c.chart,e=c.legendItem,g=d.options.chart.ignoreHiddenSeries,h=c.visible;f=(c.visible=a=c.userOptions.visible=a===t?!h:a)?"show":"hide",p(["group","dataLabelsGroup","markerGroup","tracker"],function(a){c[a]&&c[a][f]()}),d.hoverSeries===c&&c.onMouseOut(),e&&d.legend.colorizeItem(c,a),c.isDirty=!0,c.options.stacking&&p(d.series,function(a){a.options.stacking&&a.visible&&(a.isDirty=!0)}),p(c.linkedSeries,function(b){b.setVisible(a,!1)}),g&&(d.isDirtyBox=!0),b!==!1&&d.redraw(),D(c,f)},setTooltipPoints:function(a){var c,d,h,i,b=[],e=this.xAxis,f=e&&e.getExtremes(),g=e?e.tooltipLen||e.len:this.chart.plotSizeX,j=[];if(this.options.enableMouseTracking!==!1&&!this.singularTooltips){for(a&&(this.tooltipPoints=null),p(this.segments||this.points,function(a){b=b.concat(a)}),e&&e.reversed&&(b=b.reverse()),this.orderTooltipPoints&&this.orderTooltipPoints(b),a=b.length,i=0;a>i;i++)if(e=b[i],c=e.x,c>=f.min&&c<=f.max)for(h=b[i+1],c=d===t?0:d+1,d=b[i+1]?C(v(0,T((e.clientX+(h?h.wrappedClientX||h.clientX:g))/2)),g):g;c>=0&&d>=c;)j[c++]=e;this.tooltipPoints=j}},show:function(){this.setVisible(!0)},hide:function(){this.setVisible(!1)},select:function(a){this.selected=a=a===t?!this.selected:a,this.checkbox&&(this.checkbox.checked=a),D(this,a?"select":"unselect")},drawTracker:S.drawTrackerGraph}),q(R,{Axis:la,Chart:Ya,Color:ya,Point:Ea,Tick:Sa,Renderer:Za,Series:O,SVGElement:P,SVGRenderer:ta,arrayMin:Na,arrayMax:Ba,charts:V,dateFormat:cb,format:Ia,pathAnim:ub,getOptions:function(){return E},hasBidiBug:Nb,isTouchDevice:Jb,numberFormat:Ga,seriesTypes:F,setOptions:function(a){return E=w(!0,E,a),Cb(),E},addEvent:K,removeEvent:W,createElement:Y,discardElement:Pa,css:G,each:p,extend:q,map:Ua,merge:w,pick:m,splat:qa,extendClass:ka,pInt:z,wrap:Ma,svg:aa,canvas:fa,vml:!aa&&!fa,product:"Highcharts",version:"4.0.1"})}(),jQuery(document).ready(function($){$("#filter_action").select2(),$("#filter_action").change(function(){var $this=$(this);"submitted"==$this.val()?$("#form-filter-input").show():($("#form-filter-input").hide(),$("#filter_form").select2("val","any form"))}),$("#view-all-do-not-track-selectors").click(function(){$(".form-do-not-track, #view-less-do-not-track-selectors").not(".do-not-track-always-show").show(),$("#view-all-do-not-track-selectors").hide()}),$("#view-less-do-not-track-selectors").click(function(){$(".form-do-not-track, #view-less-do-not-track-selectors").not(".do-not-track-always-show").hide(),$("#view-all-do-not-track-selectors").show()}),$("#filter_content").select2({query:function(query){var key=query.term;$.ajax({type:"POST",url:li_admin_ajax.ajax_url,data:{action:"leadin_get_posts_and_pages",search_term:key},success:function(data){var i,json_data=jQuery.parseJSON(data),data_test={results:[]};for(i=0;i<json_data.length;i++)data_test.results.push({id:json_data[i].post_title,text:json_data[i].post_title});query.callback(data_test)}})},initSelection:function(){$("#filter_content").val()?$("#filter_content").select2("data",{id:$("#filter_content").val(),text:$("#filter_content").val()}):$("#filter_content").select2("data",{id:"any page",text:"any page"})}}),$("#filter_form").select2({query:function(query){var key=query.term;$.ajax({type:"POST",url:li_admin_ajax.ajax_url,data:{action:"leadin_get_form_selectors",search_term:key},success:function(data){var i,json_data=jQuery.parseJSON(data),data_test={results:[]};for(i=0;i<json_data.length;i++)data_test.results.push({id:json_data[i],text:json_data[i]});query.callback(data_test)}})},initSelection:function(){$("#filter_form").val()?$("#filter_form").select2("data",{id:$("#filter_form").val(),text:$("#filter_form").val()}):$("#filter_form").select2("data",{id:"any form",text:"any form"})}}),$("#leadin-contact-status").change(function(){$("#leadin-contact-status-button").addClass("button-primary")}),$("input[name=popup-position]:radio").change(function(){$("#btn-activate-subscribe").attr("href",window.location.href+"&leadin_action=activate&power_up=subscribe_widget&redirect_to="+encodeURIComponent(window.location.href+"&activate_popup=true&popup_position="+$("input:radio[name='popup-position']:checked").val()))}),$("#li_subscribe_vex_class, #li_subscribe_heading, #li_subscribe_text, #li_subscribe_btn_label, #li_subscribe_name_fields:checkbox, #li_subscribe_phone_field:checkbox").change(function(){var preview_link=$("#wp-admin-bar-view-site a.ab-item").attr("href")+"?preview-subscribe=1";preview_link+="&lis_heading="+$("#li_subscribe_heading").val(),preview_link+="&lis_desc="+$("#li_subscribe_text").val(),preview_link+="&lis_show_names="+($("#li_subscribe_name_fields").is(":checked")?1:0),preview_link+="&lis_show_phone="+($("#li_subscribe_phone_field").is(":checked")?1:0),preview_link+="&lis_btn_label="+$("#li_subscribe_btn_label").val(),preview_link+="&lis_vex_class="+$("#li_subscribe_vex_class option:selected").val(),$("#preview-popup-link").attr("href",preview_link)})}),jQuery(document).ready(function($){var $bulk_opt_selected=$('.bulkactions select option[value="add_tag_to_selected"], .bulkactions select option[value="remove_tag_from_selected"], .bulkactions select option[value="delete_selected"]');$("#leadin-contacts input:checkbox").not("thead input:checkbox, tfoot input:checkbox").bind("change",function(){var cb_count=0,selected_vals="",$btn_selected=$("#leadin-export-selected-leads"),$input_selected_vals=$(".leadin-selected-contacts"),$cb_selected=$("#leadin-contacts input:checkbox:checked").not("thead input:checkbox, tfoot input:checkbox");$cb_selected.length>0?($btn_selected.attr("disabled",!1),$bulk_opt_selected.attr("disabled",!1)):($btn_selected.attr("disabled",!0),$bulk_opt_selected.attr("disabled",!0)),$cb_selected.each(function(){selected_vals+=$(this).val(),cb_count!=$cb_selected.length-1&&(selected_vals+=","),cb_count++}),$input_selected_vals.val(selected_vals),$(".selected-contacts-count").text(cb_count)}),$("#cb-select-all-1, #cb-select-all-2").bind("change",function(){var cb_count=0,selected_vals="",$this=$(this),$btn_selected=$("#leadin-export-selected-leads"),$cb_selected=$("#leadin-contacts input:checkbox").not("thead input:checkbox, tfoot input:checkbox"),$input_selected_vals=$(".leadin-selected-contacts");$cb_selected.each(function(){selected_vals+=$(this).val(),cb_count!=$cb_selected.length-1&&(selected_vals+=","),cb_count++}),$input_selected_vals.val(selected_vals),$this.is(":checked")?($btn_selected.attr("disabled",!1),$bulk_opt_selected.attr("disabled",!1)):($btn_selected.attr("disabled",!0),$bulk_opt_selected.attr("disabled",!0),$(".selected-contacts-count").text($("#contact-count").text())),$(".selected-contacts-count").text(cb_count)}),$(".postbox .handlediv").bind("click",function(){var $postbox=$(this).parent();$postbox.hasClass("closed")?$postbox.removeClass("closed"):$postbox.addClass("closed")}),$(".selected-contacts-count").text($("#contact-count").text()),$bulk_opt_selected.attr("disabled",!0),$(".bulkactions select").change(function(){{var $this=$(this);$("#contact-count").text()}"add_tag_to_all"==$this.val()||"add_tag_to_selected"==$this.val()?($("#bulk-edit-tags h2").html($("#bulk-edit-tags h2").html().replace("remove from","add to")),$("#bulk-edit-button").val("Add Tag"),$("#bulk-edit-tag-action").val("add_tag"),tb_show("","#TB_inline?width=400&height=175&inlineId=bulk-edit-tags"),$(".bulkactions select").val("-1")):("remove_tag_from_all"==$this.val()||"remove_tag_from_selected"==$this.val())&&($("#bulk-edit-tags h2").html($("#bulk-edit-tags h2").html().replace("add to","remove from")),$("#bulk-edit-button").val("Remove Tag"),$("#bulk-edit-tag-action").val("remove_tag"),tb_show("","#TB_inline?width=400&height=175&inlineId=bulk-edit-tags"),$(".bulkactions select").val("-1"))})}),function($){"undefined"==typeof $.fn.each2&&$.extend($.fn,{each2:function(c){for(var j=$([0]),i=-1,l=this.length;++i<l&&(j.context=j[0]=this[i])&&c.call(j[0],i,j)!==!1;);return this}})}(jQuery),function($,undefined){"use strict";function reinsertElement(element){var placeholder=$(document.createTextNode(""));element.before(placeholder),placeholder.before(element),placeholder.remove()}function stripDiacritics(str){function match(a){return DIACRITICS[a]||a}return str.replace(/[^\u0000-\u007E]/g,match)}function indexOf(value,array){for(var i=0,l=array.length;l>i;i+=1)if(equal(value,array[i]))return i;return-1}function measureScrollbar(){var $template=$(MEASURE_SCROLLBAR_TEMPLATE);$template.appendTo("body");var dim={width:$template.width()-$template[0].clientWidth,height:$template.height()-$template[0].clientHeight};return $template.remove(),dim}function equal(a,b){return a===b?!0:a===undefined||b===undefined?!1:null===a||null===b?!1:a.constructor===String?a+""==b+"":b.constructor===String?b+""==a+"":!1}function splitVal(string,separator){var val,i,l;if(null===string||string.length<1)return[];for(val=string.split(separator),i=0,l=val.length;l>i;i+=1)val[i]=$.trim(val[i]);return val}function getSideBorderPadding(element){return element.outerWidth(!1)-element.width()}function installKeyUpChangeEvent(element){var key="keyup-change-value";element.on("keydown",function(){$.data(element,key)===undefined&&$.data(element,key,element.val())}),element.on("keyup",function(){var val=$.data(element,key);val!==undefined&&element.val()!==val&&($.removeData(element,key),element.trigger("keyup-change"))})}function installFilteredMouseMove(element){element.on("mousemove",function(e){var lastpos=lastMousePosition;(lastpos===undefined||lastpos.x!==e.pageX||lastpos.y!==e.pageY)&&$(e.target).trigger("mousemove-filtered",e)})}function debounce(quietMillis,fn,ctx){ctx=ctx||undefined;var timeout;return function(){var args=arguments;window.clearTimeout(timeout),timeout=window.setTimeout(function(){fn.apply(ctx,args)},quietMillis)}}function installDebouncedScroll(threshold,element){var notify=debounce(threshold,function(e){element.trigger("scroll-debounced",e)});element.on("scroll",function(e){indexOf(e.target,element.get())>=0&¬ify(e)})}function focus($el){$el[0]!==document.activeElement&&window.setTimeout(function(){var range,el=$el[0],pos=$el.val().length;$el.focus();var isVisible=el.offsetWidth>0||el.offsetHeight>0;isVisible&&el===document.activeElement&&(el.setSelectionRange?el.setSelectionRange(pos,pos):el.createTextRange&&(range=el.createTextRange(),range.collapse(!1),range.select()))},0)}function getCursorInfo(el){el=$(el)[0];var offset=0,length=0;if("selectionStart"in el)offset=el.selectionStart,length=el.selectionEnd-offset;else if("selection"in document){el.focus();var sel=document.selection.createRange();length=document.selection.createRange().text.length,sel.moveStart("character",-el.value.length),offset=sel.text.length-length}return{offset:offset,length:length}}function killEvent(event){event.preventDefault(),event.stopPropagation()}function killEventImmediately(event){event.preventDefault(),event.stopImmediatePropagation()}function measureTextWidth(e){if(!sizer){var style=e[0].currentStyle||window.getComputedStyle(e[0],null);sizer=$(document.createElement("div")).css({position:"absolute",left:"-10000px",top:"-10000px",display:"none",fontSize:style.fontSize,fontFamily:style.fontFamily,fontStyle:style.fontStyle,fontWeight:style.fontWeight,letterSpacing:style.letterSpacing,textTransform:style.textTransform,whiteSpace:"nowrap"}),sizer.attr("class","select2-sizer"),$("body").append(sizer)
|
6 |
-
}return sizer.text(e.val()),sizer.width()}function syncCssClasses(dest,src,adapter){var classes,adapted,replacements=[];classes=dest.attr("class"),classes&&(classes=""+classes,$(classes.split(" ")).each2(function(){0===this.indexOf("select2-")&&replacements.push(this)})),classes=src.attr("class"),classes&&(classes=""+classes,$(classes.split(" ")).each2(function(){0!==this.indexOf("select2-")&&(adapted=adapter(this),adapted&&replacements.push(adapted))})),dest.attr("class",replacements.join(" "))}function markMatch(text,term,markup,escapeMarkup){var match=stripDiacritics(text.toUpperCase()).indexOf(stripDiacritics(term.toUpperCase())),tl=term.length;return 0>match?void markup.push(escapeMarkup(text)):(markup.push(escapeMarkup(text.substring(0,match))),markup.push("<span class='select2-match'>"),markup.push(escapeMarkup(text.substring(match,match+tl))),markup.push("</span>"),void markup.push(escapeMarkup(text.substring(match+tl,text.length))))}function defaultEscapeMarkup(markup){var replace_map={"\\":"\","&":"&","<":"<",">":">",'"':""","'":"'","/":"/"};return String(markup).replace(/[&<>"'\/\\]/g,function(match){return replace_map[match]})}function ajax(options){var timeout,handler=null,quietMillis=options.quietMillis||100,ajaxUrl=options.url,self=this;return function(query){window.clearTimeout(timeout),timeout=window.setTimeout(function(){var data=options.data,url=ajaxUrl,transport=options.transport||$.fn.select2.ajaxDefaults.transport,deprecated={type:options.type||"GET",cache:options.cache||!1,jsonpCallback:options.jsonpCallback||undefined,dataType:options.dataType||"json"},params=$.extend({},$.fn.select2.ajaxDefaults.params,deprecated);data=data?data.call(self,query.term,query.page,query.context):null,url="function"==typeof url?url.call(self,query.term,query.page,query.context):url,handler&&"function"==typeof handler.abort&&handler.abort(),options.params&&($.isFunction(options.params)?$.extend(params,options.params.call(self)):$.extend(params,options.params)),$.extend(params,{url:url,dataType:options.dataType,data:data,success:function(data){var results=options.results(data,query.page);query.callback(results)}}),handler=transport.call(self,params)},quietMillis)}}function local(options){var dataText,tmp,data=options,text=function(item){return""+item.text};$.isArray(data)&&(tmp=data,data={results:tmp}),$.isFunction(data)===!1&&(tmp=data,data=function(){return tmp});var dataItem=data();return dataItem.text&&(text=dataItem.text,$.isFunction(text)||(dataText=dataItem.text,text=function(item){return item[dataText]})),function(query){var process,t=query.term,filtered={results:[]};return""===t?void query.callback(data()):(process=function(datum,collection){var group,attr;if(datum=datum[0],datum.children){group={};for(attr in datum)datum.hasOwnProperty(attr)&&(group[attr]=datum[attr]);group.children=[],$(datum.children).each2(function(i,childDatum){process(childDatum,group.children)}),(group.children.length||query.matcher(t,text(group),datum))&&collection.push(group)}else query.matcher(t,text(datum),datum)&&collection.push(datum)},$(data().results).each2(function(i,datum){process(datum,filtered.results)}),void query.callback(filtered))}}function tags(data){var isFunc=$.isFunction(data);return function(query){var t=query.term,filtered={results:[]},result=isFunc?data(query):data;$.isArray(result)&&($(result).each(function(){var isObject=this.text!==undefined,text=isObject?this.text:this;(""===t||query.matcher(t,text))&&filtered.results.push(isObject?this:{id:this,text:this})}),query.callback(filtered))}}function checkFormatter(formatter,formatterName){if($.isFunction(formatter))return!0;if(!formatter)return!1;if("string"==typeof formatter)return!0;throw new Error(formatterName+" must be a string, function, or falsy value")}function evaluate(val){if($.isFunction(val)){var args=Array.prototype.slice.call(arguments,1);return val.apply(null,args)}return val}function countResults(results){var count=0;return $.each(results,function(i,item){item.children?count+=countResults(item.children):count++}),count}function defaultTokenizer(input,selection,selectCallback,opts){var token,index,i,l,separator,original=input,dupe=!1;if(!opts.createSearchChoice||!opts.tokenSeparators||opts.tokenSeparators.length<1)return undefined;for(;;){for(index=-1,i=0,l=opts.tokenSeparators.length;l>i&&(separator=opts.tokenSeparators[i],index=input.indexOf(separator),!(index>=0));i++);if(0>index)break;if(token=input.substring(0,index),input=input.substring(index+separator.length),token.length>0&&(token=opts.createSearchChoice.call(this,token,selection),token!==undefined&&null!==token&&opts.id(token)!==undefined&&null!==opts.id(token))){for(dupe=!1,i=0,l=selection.length;l>i;i++)if(equal(opts.id(token),opts.id(selection[i]))){dupe=!0;break}dupe||selectCallback(token)}}return original!==input?input:void 0}function cleanupJQueryElements(){var self=this;Array.prototype.forEach.call(arguments,function(element){self[element].remove(),self[element]=null})}function clazz(SuperClass,methods){var constructor=function(){};return constructor.prototype=new SuperClass,constructor.prototype.constructor=constructor,constructor.prototype.parent=SuperClass.prototype,constructor.prototype=$.extend(constructor.prototype,methods),constructor}if(window.Select2===undefined){var KEY,AbstractSelect2,SingleSelect2,MultiSelect2,nextUid,sizer,$document,scrollBarDimensions,lastMousePosition={x:0,y:0},KEY={TAB:9,ENTER:13,ESC:27,SPACE:32,LEFT:37,UP:38,RIGHT:39,DOWN:40,SHIFT:16,CTRL:17,ALT:18,PAGE_UP:33,PAGE_DOWN:34,HOME:36,END:35,BACKSPACE:8,DELETE:46,isArrow:function(k){switch(k=k.which?k.which:k){case KEY.LEFT:case KEY.RIGHT:case KEY.UP:case KEY.DOWN:return!0}return!1},isControl:function(e){var k=e.which;switch(k){case KEY.SHIFT:case KEY.CTRL:case KEY.ALT:return!0}return e.metaKey?!0:!1},isFunctionKey:function(k){return k=k.which?k.which:k,k>=112&&123>=k}},MEASURE_SCROLLBAR_TEMPLATE="<div class='select2-measure-scrollbar'></div>",DIACRITICS={"Ⓐ":"A","A":"A","À":"A","Á":"A","Â":"A","Ầ":"A","Ấ":"A","Ẫ":"A","Ẩ":"A","Ã":"A","Ā":"A","Ă":"A","Ằ":"A","Ắ":"A","Ẵ":"A","Ẳ":"A","Ȧ":"A","Ǡ":"A","Ä":"A","Ǟ":"A","Ả":"A","Å":"A","Ǻ":"A","Ǎ":"A","Ȁ":"A","Ȃ":"A","Ạ":"A","Ậ":"A","Ặ":"A","Ḁ":"A","Ą":"A","Ⱥ":"A","Ɐ":"A","Ꜳ":"AA","Æ":"AE","Ǽ":"AE","Ǣ":"AE","Ꜵ":"AO","Ꜷ":"AU","Ꜹ":"AV","Ꜻ":"AV","Ꜽ":"AY","Ⓑ":"B","B":"B","Ḃ":"B","Ḅ":"B","Ḇ":"B","Ƀ":"B","Ƃ":"B","Ɓ":"B","Ⓒ":"C","C":"C","Ć":"C","Ĉ":"C","Ċ":"C","Č":"C","Ç":"C","Ḉ":"C","Ƈ":"C","Ȼ":"C","Ꜿ":"C","Ⓓ":"D","D":"D","Ḋ":"D","Ď":"D","Ḍ":"D","Ḑ":"D","Ḓ":"D","Ḏ":"D","Đ":"D","Ƌ":"D","Ɗ":"D","Ɖ":"D","Ꝺ":"D","DZ":"DZ","DŽ":"DZ","Dz":"Dz","Dž":"Dz","Ⓔ":"E","E":"E","È":"E","É":"E","Ê":"E","Ề":"E","Ế":"E","Ễ":"E","Ể":"E","Ẽ":"E","Ē":"E","Ḕ":"E","Ḗ":"E","Ĕ":"E","Ė":"E","Ë":"E","Ẻ":"E","Ě":"E","Ȅ":"E","Ȇ":"E","Ẹ":"E","Ệ":"E","Ȩ":"E","Ḝ":"E","Ę":"E","Ḙ":"E","Ḛ":"E","Ɛ":"E","Ǝ":"E","Ⓕ":"F","F":"F","Ḟ":"F","Ƒ":"F","Ꝼ":"F","Ⓖ":"G","G":"G","Ǵ":"G","Ĝ":"G","Ḡ":"G","Ğ":"G","Ġ":"G","Ǧ":"G","Ģ":"G","Ǥ":"G","Ɠ":"G","Ꞡ":"G","Ᵹ":"G","Ꝿ":"G","Ⓗ":"H","H":"H","Ĥ":"H","Ḣ":"H","Ḧ":"H","Ȟ":"H","Ḥ":"H","Ḩ":"H","Ḫ":"H","Ħ":"H","Ⱨ":"H","Ⱶ":"H","Ɥ":"H","Ⓘ":"I","I":"I","Ì":"I","Í":"I","Î":"I","Ĩ":"I","Ī":"I","Ĭ":"I","İ":"I","Ï":"I","Ḯ":"I","Ỉ":"I","Ǐ":"I","Ȉ":"I","Ȋ":"I","Ị":"I","Į":"I","Ḭ":"I","Ɨ":"I","Ⓙ":"J","J":"J","Ĵ":"J","Ɉ":"J","Ⓚ":"K","K":"K","Ḱ":"K","Ǩ":"K","Ḳ":"K","Ķ":"K","Ḵ":"K","Ƙ":"K","Ⱪ":"K","Ꝁ":"K","Ꝃ":"K","Ꝅ":"K","Ꞣ":"K","Ⓛ":"L","L":"L","Ŀ":"L","Ĺ":"L","Ľ":"L","Ḷ":"L","Ḹ":"L","Ļ":"L","Ḽ":"L","Ḻ":"L","Ł":"L","Ƚ":"L","Ɫ":"L","Ⱡ":"L","Ꝉ":"L","Ꝇ":"L","Ꞁ":"L","LJ":"LJ","Lj":"Lj","Ⓜ":"M","M":"M","Ḿ":"M","Ṁ":"M","Ṃ":"M","Ɱ":"M","Ɯ":"M","Ⓝ":"N","N":"N","Ǹ":"N","Ń":"N","Ñ":"N","Ṅ":"N","Ň":"N","Ṇ":"N","Ņ":"N","Ṋ":"N","Ṉ":"N","Ƞ":"N","Ɲ":"N","Ꞑ":"N","Ꞥ":"N","NJ":"NJ","Nj":"Nj","Ⓞ":"O","O":"O","Ò":"O","Ó":"O","Ô":"O","Ồ":"O","Ố":"O","Ỗ":"O","Ổ":"O","Õ":"O","Ṍ":"O","Ȭ":"O","Ṏ":"O","Ō":"O","Ṑ":"O","Ṓ":"O","Ŏ":"O","Ȯ":"O","Ȱ":"O","Ö":"O","Ȫ":"O","Ỏ":"O","Ő":"O","Ǒ":"O","Ȍ":"O","Ȏ":"O","Ơ":"O","Ờ":"O","Ớ":"O","Ỡ":"O","Ở":"O","Ợ":"O","Ọ":"O","Ộ":"O","Ǫ":"O","Ǭ":"O","Ø":"O","Ǿ":"O","Ɔ":"O","Ɵ":"O","Ꝋ":"O","Ꝍ":"O","Ƣ":"OI","Ꝏ":"OO","Ȣ":"OU","Ⓟ":"P","P":"P","Ṕ":"P","Ṗ":"P","Ƥ":"P","Ᵽ":"P","Ꝑ":"P","Ꝓ":"P","Ꝕ":"P","Ⓠ":"Q","Q":"Q","Ꝗ":"Q","Ꝙ":"Q","Ɋ":"Q","Ⓡ":"R","R":"R","Ŕ":"R","Ṙ":"R","Ř":"R","Ȑ":"R","Ȓ":"R","Ṛ":"R","Ṝ":"R","Ŗ":"R","Ṟ":"R","Ɍ":"R","Ɽ":"R","Ꝛ":"R","Ꞧ":"R","Ꞃ":"R","Ⓢ":"S","S":"S","ẞ":"S","Ś":"S","Ṥ":"S","Ŝ":"S","Ṡ":"S","Š":"S","Ṧ":"S","Ṣ":"S","Ṩ":"S","Ș":"S","Ş":"S","Ȿ":"S","Ꞩ":"S","Ꞅ":"S","Ⓣ":"T","T":"T","Ṫ":"T","Ť":"T","Ṭ":"T","Ț":"T","Ţ":"T","Ṱ":"T","Ṯ":"T","Ŧ":"T","Ƭ":"T","Ʈ":"T","Ⱦ":"T","Ꞇ":"T","Ꜩ":"TZ","Ⓤ":"U","U":"U","Ù":"U","Ú":"U","Û":"U","Ũ":"U","Ṹ":"U","Ū":"U","Ṻ":"U","Ŭ":"U","Ü":"U","Ǜ":"U","Ǘ":"U","Ǖ":"U","Ǚ":"U","Ủ":"U","Ů":"U","Ű":"U","Ǔ":"U","Ȕ":"U","Ȗ":"U","Ư":"U","Ừ":"U","Ứ":"U","Ữ":"U","Ử":"U","Ự":"U","Ụ":"U","Ṳ":"U","Ų":"U","Ṷ":"U","Ṵ":"U","Ʉ":"U","Ⓥ":"V","V":"V","Ṽ":"V","Ṿ":"V","Ʋ":"V","Ꝟ":"V","Ʌ":"V","Ꝡ":"VY","Ⓦ":"W","W":"W","Ẁ":"W","Ẃ":"W","Ŵ":"W","Ẇ":"W","Ẅ":"W","Ẉ":"W","Ⱳ":"W","Ⓧ":"X","X":"X","Ẋ":"X","Ẍ":"X","Ⓨ":"Y","Y":"Y","Ỳ":"Y","Ý":"Y","Ŷ":"Y","Ỹ":"Y","Ȳ":"Y","Ẏ":"Y","Ÿ":"Y","Ỷ":"Y","Ỵ":"Y","Ƴ":"Y","Ɏ":"Y","Ỿ":"Y","Ⓩ":"Z","Z":"Z","Ź":"Z","Ẑ":"Z","Ż":"Z","Ž":"Z","Ẓ":"Z","Ẕ":"Z","Ƶ":"Z","Ȥ":"Z","Ɀ":"Z","Ⱬ":"Z","Ꝣ":"Z","ⓐ":"a","a":"a","ẚ":"a","à":"a","á":"a","â":"a","ầ":"a","ấ":"a","ẫ":"a","ẩ":"a","ã":"a","ā":"a","ă":"a","ằ":"a","ắ":"a","ẵ":"a","ẳ":"a","ȧ":"a","ǡ":"a","ä":"a","ǟ":"a","ả":"a","å":"a","ǻ":"a","ǎ":"a","ȁ":"a","ȃ":"a","ạ":"a","ậ":"a","ặ":"a","ḁ":"a","ą":"a","ⱥ":"a","ɐ":"a","ꜳ":"aa","æ":"ae","ǽ":"ae","ǣ":"ae","ꜵ":"ao","ꜷ":"au","ꜹ":"av","ꜻ":"av","ꜽ":"ay","ⓑ":"b","b":"b","ḃ":"b","ḅ":"b","ḇ":"b","ƀ":"b","ƃ":"b","ɓ":"b","ⓒ":"c","c":"c","ć":"c","ĉ":"c","ċ":"c","č":"c","ç":"c","ḉ":"c","ƈ":"c","ȼ":"c","ꜿ":"c","ↄ":"c","ⓓ":"d","d":"d","ḋ":"d","ď":"d","ḍ":"d","ḑ":"d","ḓ":"d","ḏ":"d","đ":"d","ƌ":"d","ɖ":"d","ɗ":"d","ꝺ":"d","dz":"dz","dž":"dz","ⓔ":"e","e":"e","è":"e","é":"e","ê":"e","ề":"e","ế":"e","ễ":"e","ể":"e","ẽ":"e","ē":"e","ḕ":"e","ḗ":"e","ĕ":"e","ė":"e","ë":"e","ẻ":"e","ě":"e","ȅ":"e","ȇ":"e","ẹ":"e","ệ":"e","ȩ":"e","ḝ":"e","ę":"e","ḙ":"e","ḛ":"e","ɇ":"e","ɛ":"e","ǝ":"e","ⓕ":"f","f":"f","ḟ":"f","ƒ":"f","ꝼ":"f","ⓖ":"g","g":"g","ǵ":"g","ĝ":"g","ḡ":"g","ğ":"g","ġ":"g","ǧ":"g","ģ":"g","ǥ":"g","ɠ":"g","ꞡ":"g","ᵹ":"g","ꝿ":"g","ⓗ":"h","h":"h","ĥ":"h","ḣ":"h","ḧ":"h","ȟ":"h","ḥ":"h","ḩ":"h","ḫ":"h","ẖ":"h","ħ":"h","ⱨ":"h","ⱶ":"h","ɥ":"h","ƕ":"hv","ⓘ":"i","i":"i","ì":"i","í":"i","î":"i","ĩ":"i","ī":"i","ĭ":"i","ï":"i","ḯ":"i","ỉ":"i","ǐ":"i","ȉ":"i","ȋ":"i","ị":"i","į":"i","ḭ":"i","ɨ":"i","ı":"i","ⓙ":"j","j":"j","ĵ":"j","ǰ":"j","ɉ":"j","ⓚ":"k","k":"k","ḱ":"k","ǩ":"k","ḳ":"k","ķ":"k","ḵ":"k","ƙ":"k","ⱪ":"k","ꝁ":"k","ꝃ":"k","ꝅ":"k","ꞣ":"k","ⓛ":"l","l":"l","ŀ":"l","ĺ":"l","ľ":"l","ḷ":"l","ḹ":"l","ļ":"l","ḽ":"l","ḻ":"l","ſ":"l","ł":"l","ƚ":"l","ɫ":"l","ⱡ":"l","ꝉ":"l","ꞁ":"l","ꝇ":"l","lj":"lj","ⓜ":"m","m":"m","ḿ":"m","ṁ":"m","ṃ":"m","ɱ":"m","ɯ":"m","ⓝ":"n","n":"n","ǹ":"n","ń":"n","ñ":"n","ṅ":"n","ň":"n","ṇ":"n","ņ":"n","ṋ":"n","ṉ":"n","ƞ":"n","ɲ":"n","ʼn":"n","ꞑ":"n","ꞥ":"n","nj":"nj","ⓞ":"o","o":"o","ò":"o","ó":"o","ô":"o","ồ":"o","ố":"o","ỗ":"o","ổ":"o","õ":"o","ṍ":"o","ȭ":"o","ṏ":"o","ō":"o","ṑ":"o","ṓ":"o","ŏ":"o","ȯ":"o","ȱ":"o","ö":"o","ȫ":"o","ỏ":"o","ő":"o","ǒ":"o","ȍ":"o","ȏ":"o","ơ":"o","ờ":"o","ớ":"o","ỡ":"o","ở":"o","ợ":"o","ọ":"o","ộ":"o","ǫ":"o","ǭ":"o","ø":"o","ǿ":"o","ɔ":"o","ꝋ":"o","ꝍ":"o","ɵ":"o","ƣ":"oi","ȣ":"ou","ꝏ":"oo","ⓟ":"p","p":"p","ṕ":"p","ṗ":"p","ƥ":"p","ᵽ":"p","ꝑ":"p","ꝓ":"p","ꝕ":"p","ⓠ":"q","q":"q","ɋ":"q","ꝗ":"q","ꝙ":"q","ⓡ":"r","r":"r","ŕ":"r","ṙ":"r","ř":"r","ȑ":"r","ȓ":"r","ṛ":"r","ṝ":"r","ŗ":"r","ṟ":"r","ɍ":"r","ɽ":"r","ꝛ":"r","ꞧ":"r","ꞃ":"r","ⓢ":"s","s":"s","ß":"s","ś":"s","ṥ":"s","ŝ":"s","ṡ":"s","š":"s","ṧ":"s","ṣ":"s","ṩ":"s","ș":"s","ş":"s","ȿ":"s","ꞩ":"s","ꞅ":"s","ẛ":"s","ⓣ":"t","t":"t","ṫ":"t","ẗ":"t","ť":"t","ṭ":"t","ț":"t","ţ":"t","ṱ":"t","ṯ":"t","ŧ":"t","ƭ":"t","ʈ":"t","ⱦ":"t","ꞇ":"t","ꜩ":"tz","ⓤ":"u","u":"u","ù":"u","ú":"u","û":"u","ũ":"u","ṹ":"u","ū":"u","ṻ":"u","ŭ":"u","ü":"u","ǜ":"u","ǘ":"u","ǖ":"u","ǚ":"u","ủ":"u","ů":"u","ű":"u","ǔ":"u","ȕ":"u","ȗ":"u","ư":"u","ừ":"u","ứ":"u","ữ":"u","ử":"u","ự":"u","ụ":"u","ṳ":"u","ų":"u","ṷ":"u","ṵ":"u","ʉ":"u","ⓥ":"v","v":"v","ṽ":"v","ṿ":"v","ʋ":"v","ꝟ":"v","ʌ":"v","ꝡ":"vy","ⓦ":"w","w":"w","ẁ":"w","ẃ":"w","ŵ":"w","ẇ":"w","ẅ":"w","ẘ":"w","ẉ":"w","ⱳ":"w","ⓧ":"x","x":"x","ẋ":"x","ẍ":"x","ⓨ":"y","y":"y","ỳ":"y","ý":"y","ŷ":"y","ỹ":"y","ȳ":"y","ẏ":"y","ÿ":"y","ỷ":"y","ẙ":"y","ỵ":"y","ƴ":"y","ɏ":"y","ỿ":"y","ⓩ":"z","z":"z","ź":"z","ẑ":"z","ż":"z","ž":"z","ẓ":"z","ẕ":"z","ƶ":"z","ȥ":"z","ɀ":"z","ⱬ":"z","ꝣ":"z"};$document=$(document),nextUid=function(){var counter=1;return function(){return counter++}}(),$document.on("mousemove",function(e){lastMousePosition.x=e.pageX,lastMousePosition.y=e.pageY}),AbstractSelect2=clazz(Object,{bind:function(func){var self=this;return function(){func.apply(self,arguments)}},init:function(opts){var results,search,resultsSelector=".select2-results";this.opts=opts=this.prepareOpts(opts),this.id=opts.id,opts.element.data("select2")!==undefined&&null!==opts.element.data("select2")&&opts.element.data("select2").destroy(),this.container=this.createContainer(),this.liveRegion=$("<span>",{role:"status","aria-live":"polite"}).addClass("select2-hidden-accessible").appendTo(document.body),this.containerId="s2id_"+(opts.element.attr("id")||"autogen"+nextUid()),this.containerEventName=this.containerId.replace(/([.])/g,"_").replace(/([;&,\-\.\+\*\~':"\!\^#$%@\[\]\(\)=>\|])/g,"\\$1"),this.container.attr("id",this.containerId),this.container.attr("title",opts.element.attr("title")),this.body=$("body"),syncCssClasses(this.container,this.opts.element,this.opts.adaptContainerCssClass),this.container.attr("style",opts.element.attr("style")),this.container.css(evaluate(opts.containerCss)),this.container.addClass(evaluate(opts.containerCssClass)),this.elementTabIndex=this.opts.element.attr("tabindex"),this.opts.element.data("select2",this).attr("tabindex","-1").before(this.container).on("click.select2",killEvent),this.container.data("select2",this),this.dropdown=this.container.find(".select2-drop"),syncCssClasses(this.dropdown,this.opts.element,this.opts.adaptDropdownCssClass),this.dropdown.addClass(evaluate(opts.dropdownCssClass)),this.dropdown.data("select2",this),this.dropdown.on("click",killEvent),this.results=results=this.container.find(resultsSelector),this.search=search=this.container.find("input.select2-input"),this.queryCount=0,this.resultsPage=0,this.context=null,this.initContainer(),this.container.on("click",killEvent),installFilteredMouseMove(this.results),this.dropdown.on("mousemove-filtered",resultsSelector,this.bind(this.highlightUnderEvent)),this.dropdown.on("touchstart touchmove touchend",resultsSelector,this.bind(function(event){this._touchEvent=!0,this.highlightUnderEvent(event)})),this.dropdown.on("touchmove",resultsSelector,this.bind(this.touchMoved)),this.dropdown.on("touchstart touchend",resultsSelector,this.bind(this.clearTouchMoved)),this.dropdown.on("click",this.bind(function(){this._touchEvent&&(this._touchEvent=!1,this.selectHighlighted())})),installDebouncedScroll(80,this.results),this.dropdown.on("scroll-debounced",resultsSelector,this.bind(this.loadMoreIfNeeded)),$(this.container).on("change",".select2-input",function(e){e.stopPropagation()}),$(this.dropdown).on("change",".select2-input",function(e){e.stopPropagation()}),$.fn.mousewheel&&results.mousewheel(function(e,delta,deltaX,deltaY){var top=results.scrollTop();deltaY>0&&0>=top-deltaY?(results.scrollTop(0),killEvent(e)):0>deltaY&&results.get(0).scrollHeight-results.scrollTop()+deltaY<=results.height()&&(results.scrollTop(results.get(0).scrollHeight-results.height()),killEvent(e))}),installKeyUpChangeEvent(search),search.on("keyup-change input paste",this.bind(this.updateResults)),search.on("focus",function(){search.addClass("select2-focused")}),search.on("blur",function(){search.removeClass("select2-focused")}),this.dropdown.on("mouseup",resultsSelector,this.bind(function(e){$(e.target).closest(".select2-result-selectable").length>0&&(this.highlightUnderEvent(e),this.selectHighlighted(e))})),this.dropdown.on("click mouseup mousedown touchstart touchend focusin",function(e){e.stopPropagation()}),this.nextSearchTerm=undefined,$.isFunction(this.opts.initSelection)&&(this.initSelection(),this.monitorSource()),null!==opts.maximumInputLength&&this.search.attr("maxlength",opts.maximumInputLength);var disabled=opts.element.prop("disabled");disabled===undefined&&(disabled=!1),this.enable(!disabled);var readonly=opts.element.prop("readonly");readonly===undefined&&(readonly=!1),this.readonly(readonly),scrollBarDimensions=scrollBarDimensions||measureScrollbar(),this.autofocus=opts.element.prop("autofocus"),opts.element.prop("autofocus",!1),this.autofocus&&this.focus(),this.search.attr("placeholder",opts.searchInputPlaceholder)},destroy:function(){var element=this.opts.element,select2=element.data("select2");this.close(),this.propertyObserver&&(this.propertyObserver.disconnect(),this.propertyObserver=null),select2!==undefined&&(select2.container.remove(),select2.liveRegion.remove(),select2.dropdown.remove(),element.removeClass("select2-offscreen").removeData("select2").off(".select2").prop("autofocus",this.autofocus||!1),this.elementTabIndex?element.attr({tabindex:this.elementTabIndex}):element.removeAttr("tabindex"),element.show()),cleanupJQueryElements.call(this,"container","liveRegion","dropdown","results","search")},optionToData:function(element){return element.is("option")?{id:element.prop("value"),text:element.text(),element:element.get(),css:element.attr("class"),disabled:element.prop("disabled"),locked:equal(element.attr("locked"),"locked")||equal(element.data("locked"),!0)}:element.is("optgroup")?{text:element.attr("label"),children:[],element:element.get(),css:element.attr("class")}:void 0},prepareOpts:function(opts){var element,select,idKey,ajaxUrl,self=this;if(element=opts.element,"select"===element.get(0).tagName.toLowerCase()&&(this.select=select=opts.element),select&&$.each(["id","multiple","ajax","query","createSearchChoice","initSelection","data","tags"],function(){if(this in opts)throw new Error("Option '"+this+"' is not allowed for Select2 when attached to a <select> element.")}),opts=$.extend({},{populateResults:function(container,results,query){var populate,id=this.opts.id,liveRegion=this.liveRegion;(populate=function(results,container,depth){var i,l,result,selectable,disabled,compound,node,label,innerContainer,formatted;for(results=opts.sortResults(results,container,query),i=0,l=results.length;l>i;i+=1)result=results[i],disabled=result.disabled===!0,selectable=!disabled&&id(result)!==undefined,compound=result.children&&result.children.length>0,node=$("<li></li>"),node.addClass("select2-results-dept-"+depth),node.addClass("select2-result"),node.addClass(selectable?"select2-result-selectable":"select2-result-unselectable"),disabled&&node.addClass("select2-disabled"),compound&&node.addClass("select2-result-with-children"),node.addClass(self.opts.formatResultCssClass(result)),node.attr("role","presentation"),label=$(document.createElement("div")),label.addClass("select2-result-label"),label.attr("id","select2-result-label-"+nextUid()),label.attr("role","option"),formatted=opts.formatResult(result,label,query,self.opts.escapeMarkup),formatted!==undefined&&(label.html(formatted),node.append(label)),compound&&(innerContainer=$("<ul></ul>"),innerContainer.addClass("select2-result-sub"),populate(result.children,innerContainer,depth+1),node.append(innerContainer)),node.data("select2-data",result),container.append(node);liveRegion.text(opts.formatMatches(results.length))})(results,container,0)}},$.fn.select2.defaults,opts),"function"!=typeof opts.id&&(idKey=opts.id,opts.id=function(e){return e[idKey]}),$.isArray(opts.element.data("select2Tags"))){if("tags"in opts)throw"tags specified as both an attribute 'data-select2-tags' and in options of Select2 "+opts.element.attr("id");opts.tags=opts.element.data("select2Tags")}if(select?(opts.query=this.bind(function(query){var children,placeholderOption,process,data={results:[],more:!1},term=query.term;process=function(element,collection){var group;element.is("option")?query.matcher(term,element.text(),element)&&collection.push(self.optionToData(element)):element.is("optgroup")&&(group=self.optionToData(element),element.children().each2(function(i,elm){process(elm,group.children)}),group.children.length>0&&collection.push(group))},children=element.children(),this.getPlaceholder()!==undefined&&children.length>0&&(placeholderOption=this.getPlaceholderOption(),placeholderOption&&(children=children.not(placeholderOption))),children.each2(function(i,elm){process(elm,data.results)}),query.callback(data)}),opts.id=function(e){return e.id}):"query"in opts||("ajax"in opts?(ajaxUrl=opts.element.data("ajax-url"),ajaxUrl&&ajaxUrl.length>0&&(opts.ajax.url=ajaxUrl),opts.query=ajax.call(opts.element,opts.ajax)):"data"in opts?opts.query=local(opts.data):"tags"in opts&&(opts.query=tags(opts.tags),opts.createSearchChoice===undefined&&(opts.createSearchChoice=function(term){return{id:$.trim(term),text:$.trim(term)}}),opts.initSelection===undefined&&(opts.initSelection=function(element,callback){var data=[];$(splitVal(element.val(),opts.separator)).each(function(){var obj={id:this,text:this},tags=opts.tags;$.isFunction(tags)&&(tags=tags()),$(tags).each(function(){return equal(this.id,obj.id)?(obj=this,!1):void 0}),data.push(obj)}),callback(data)}))),"function"!=typeof opts.query)throw"query function not defined for Select2 "+opts.element.attr("id");if("top"===opts.createSearchChoicePosition)opts.createSearchChoicePosition=function(list,item){list.unshift(item)};else if("bottom"===opts.createSearchChoicePosition)opts.createSearchChoicePosition=function(list,item){list.push(item)};else if("function"!=typeof opts.createSearchChoicePosition)throw"invalid createSearchChoicePosition option must be 'top', 'bottom' or a custom function";return opts},monitorSource:function(){var sync,observer,el=this.opts.element;el.on("change.select2",this.bind(function(){this.opts.element.data("select2-change-triggered")!==!0&&this.initSelection()})),sync=this.bind(function(){var disabled=el.prop("disabled");disabled===undefined&&(disabled=!1),this.enable(!disabled);var readonly=el.prop("readonly");readonly===undefined&&(readonly=!1),this.readonly(readonly),syncCssClasses(this.container,this.opts.element,this.opts.adaptContainerCssClass),this.container.addClass(evaluate(this.opts.containerCssClass)),syncCssClasses(this.dropdown,this.opts.element,this.opts.adaptDropdownCssClass),this.dropdown.addClass(evaluate(this.opts.dropdownCssClass))}),el.length&&el[0].attachEvent&&el.each(function(){this.attachEvent("onpropertychange",sync)}),observer=window.MutationObserver||window.WebKitMutationObserver||window.MozMutationObserver,observer!==undefined&&(this.propertyObserver&&(delete this.propertyObserver,this.propertyObserver=null),this.propertyObserver=new observer(function(mutations){mutations.forEach(sync)}),this.propertyObserver.observe(el.get(0),{attributes:!0,subtree:!1}))},triggerSelect:function(data){var evt=$.Event("select2-selecting",{val:this.id(data),object:data});return this.opts.element.trigger(evt),!evt.isDefaultPrevented()},triggerChange:function(details){details=details||{},details=$.extend({},details,{type:"change",val:this.val()}),this.opts.element.data("select2-change-triggered",!0),this.opts.element.trigger(details),this.opts.element.data("select2-change-triggered",!1),this.opts.element.click(),this.opts.blurOnChange&&this.opts.element.blur()},isInterfaceEnabled:function(){return this.enabledInterface===!0},enableInterface:function(){var enabled=this._enabled&&!this._readonly,disabled=!enabled;return enabled===this.enabledInterface?!1:(this.container.toggleClass("select2-container-disabled",disabled),this.close(),this.enabledInterface=enabled,!0)},enable:function(enabled){enabled===undefined&&(enabled=!0),this._enabled!==enabled&&(this._enabled=enabled,this.opts.element.prop("disabled",!enabled),this.enableInterface())},disable:function(){this.enable(!1)},readonly:function(enabled){enabled===undefined&&(enabled=!1),this._readonly!==enabled&&(this._readonly=enabled,this.opts.element.prop("readonly",enabled),this.enableInterface())},opened:function(){return this.container.hasClass("select2-dropdown-open")},positionDropdown:function(){var bodyOffset,above,changeDirection,css,resultsListNode,$dropdown=this.dropdown,offset=this.container.offset(),height=this.container.outerHeight(!1),width=this.container.outerWidth(!1),dropHeight=$dropdown.outerHeight(!1),$window=$(window),windowWidth=$window.width(),windowHeight=$window.height(),viewPortRight=$window.scrollLeft()+windowWidth,viewportBottom=$window.scrollTop()+windowHeight,dropTop=offset.top+height,dropLeft=offset.left,enoughRoomBelow=viewportBottom>=dropTop+dropHeight,enoughRoomAbove=offset.top-dropHeight>=$window.scrollTop(),dropWidth=$dropdown.outerWidth(!1),enoughRoomOnRight=viewPortRight>=dropLeft+dropWidth,aboveNow=$dropdown.hasClass("select2-drop-above");aboveNow?(above=!0,!enoughRoomAbove&&enoughRoomBelow&&(changeDirection=!0,above=!1)):(above=!1,!enoughRoomBelow&&enoughRoomAbove&&(changeDirection=!0,above=!0)),changeDirection&&($dropdown.hide(),offset=this.container.offset(),height=this.container.outerHeight(!1),width=this.container.outerWidth(!1),dropHeight=$dropdown.outerHeight(!1),viewPortRight=$window.scrollLeft()+windowWidth,viewportBottom=$window.scrollTop()+windowHeight,dropTop=offset.top+height,dropLeft=offset.left,dropWidth=$dropdown.outerWidth(!1),enoughRoomOnRight=viewPortRight>=dropLeft+dropWidth,$dropdown.show(),this.focusSearch()),this.opts.dropdownAutoWidth?(resultsListNode=$(".select2-results",$dropdown)[0],$dropdown.addClass("select2-drop-auto-width"),$dropdown.css("width",""),dropWidth=$dropdown.outerWidth(!1)+(resultsListNode.scrollHeight===resultsListNode.clientHeight?0:scrollBarDimensions.width),dropWidth>width?width=dropWidth:dropWidth=width,dropHeight=$dropdown.outerHeight(!1),enoughRoomOnRight=viewPortRight>=dropLeft+dropWidth):this.container.removeClass("select2-drop-auto-width"),"static"!==this.body.css("position")&&(bodyOffset=this.body.offset(),dropTop-=bodyOffset.top,dropLeft-=bodyOffset.left),enoughRoomOnRight||(dropLeft=offset.left+this.container.outerWidth(!1)-dropWidth),css={left:dropLeft,width:width},above?(css.top=offset.top-dropHeight,css.bottom="auto",this.container.addClass("select2-drop-above"),$dropdown.addClass("select2-drop-above")):(css.top=dropTop,css.bottom="auto",this.container.removeClass("select2-drop-above"),$dropdown.removeClass("select2-drop-above")),css=$.extend(css,evaluate(this.opts.dropdownCss)),$dropdown.css(css)},shouldOpen:function(){var event;return this.opened()?!1:this._enabled===!1||this._readonly===!0?!1:(event=$.Event("select2-opening"),this.opts.element.trigger(event),!event.isDefaultPrevented())},clearDropdownAlignmentPreference:function(){this.container.removeClass("select2-drop-above"),this.dropdown.removeClass("select2-drop-above")},open:function(){return this.shouldOpen()?(this.opening(),!0):!1},opening:function(){var mask,cid=this.containerEventName,scroll="scroll."+cid,resize="resize."+cid,orient="orientationchange."+cid;this.container.addClass("select2-dropdown-open").addClass("select2-container-active"),this.clearDropdownAlignmentPreference(),this.dropdown[0]!==this.body.children().last()[0]&&this.dropdown.detach().appendTo(this.body),mask=$("#select2-drop-mask"),0==mask.length&&(mask=$(document.createElement("div")),mask.attr("id","select2-drop-mask").attr("class","select2-drop-mask"),mask.hide(),mask.appendTo(this.body),mask.on("mousedown touchstart click",function(e){reinsertElement(mask);var self,dropdown=$("#select2-drop");dropdown.length>0&&(self=dropdown.data("select2"),self.opts.selectOnBlur&&self.selectHighlighted({noFocus:!0}),self.close(),e.preventDefault(),e.stopPropagation())})),this.dropdown.prev()[0]!==mask[0]&&this.dropdown.before(mask),$("#select2-drop").removeAttr("id"),this.dropdown.attr("id","select2-drop"),mask.show(),this.positionDropdown(),this.dropdown.show(),this.positionDropdown(),this.dropdown.addClass("select2-drop-active");var that=this;this.container.parents().add(window).each(function(){$(this).on(resize+" "+scroll+" "+orient,function(){that.opened()&&that.positionDropdown()})})},close:function(){if(this.opened()){var cid=this.containerEventName,scroll="scroll."+cid,resize="resize."+cid,orient="orientationchange."+cid;this.container.parents().add(window).each(function(){$(this).off(scroll).off(resize).off(orient)}),this.clearDropdownAlignmentPreference(),$("#select2-drop-mask").hide(),this.dropdown.removeAttr("id"),this.dropdown.hide(),this.container.removeClass("select2-dropdown-open").removeClass("select2-container-active"),this.results.empty(),this.clearSearch(),this.search.removeClass("select2-active"),this.opts.element.trigger($.Event("select2-close"))}},externalSearch:function(term){this.open(),this.search.val(term),this.updateResults(!1)},clearSearch:function(){},getMaximumSelectionSize:function(){return evaluate(this.opts.maximumSelectionSize)},ensureHighlightVisible:function(){var children,index,child,hb,rb,y,more,results=this.results;if(index=this.highlight(),!(0>index)){if(0==index)return void results.scrollTop(0);children=this.findHighlightableChoices().find(".select2-result-label"),child=$(children[index]),hb=child.offset().top+child.outerHeight(!0),index===children.length-1&&(more=results.find("li.select2-more-results"),more.length>0&&(hb=more.offset().top+more.outerHeight(!0))),rb=results.offset().top+results.outerHeight(!0),hb>rb&&results.scrollTop(results.scrollTop()+(hb-rb)),y=child.offset().top-results.offset().top,0>y&&"none"!=child.css("display")&&results.scrollTop(results.scrollTop()+y)}},findHighlightableChoices:function(){return this.results.find(".select2-result-selectable:not(.select2-disabled):not(.select2-selected)")},moveHighlight:function(delta){for(var choices=this.findHighlightableChoices(),index=this.highlight();index>-1&&index<choices.length;){index+=delta;var choice=$(choices[index]);if(choice.hasClass("select2-result-selectable")&&!choice.hasClass("select2-disabled")&&!choice.hasClass("select2-selected")){this.highlight(index);break}}},highlight:function(index){var choice,data,choices=this.findHighlightableChoices();return 0===arguments.length?indexOf(choices.filter(".select2-highlighted")[0],choices.get()):(index>=choices.length&&(index=choices.length-1),0>index&&(index=0),this.removeHighlight(),choice=$(choices[index]),choice.addClass("select2-highlighted"),this.search.attr("aria-activedescendant",choice.find(".select2-result-label").attr("id")),this.ensureHighlightVisible(),this.liveRegion.text(choice.text()),data=choice.data("select2-data"),void(data&&this.opts.element.trigger({type:"select2-highlight",val:this.id(data),choice:data})))},removeHighlight:function(){this.results.find(".select2-highlighted").removeClass("select2-highlighted")},touchMoved:function(){this._touchMoved=!0},clearTouchMoved:function(){this._touchMoved=!1},countSelectableResults:function(){return this.findHighlightableChoices().length},highlightUnderEvent:function(event){var el=$(event.target).closest(".select2-result-selectable");if(el.length>0&&!el.is(".select2-highlighted")){var choices=this.findHighlightableChoices();this.highlight(choices.index(el))}else 0==el.length&&this.removeHighlight()},loadMoreIfNeeded:function(){var below,results=this.results,more=results.find("li.select2-more-results"),page=this.resultsPage+1,self=this,term=this.search.val(),context=this.context;0!==more.length&&(below=more.offset().top-results.offset().top-results.height(),below<=this.opts.loadMorePadding&&(more.addClass("select2-active"),this.opts.query({element:this.opts.element,term:term,page:page,context:context,matcher:this.opts.matcher,callback:this.bind(function(data){self.opened()&&(self.opts.populateResults.call(this,results,data.results,{term:term,page:page,context:context}),self.postprocessResults(data,!1,!1),data.more===!0?(more.detach().appendTo(results).text(evaluate(self.opts.formatLoadMore,page+1)),window.setTimeout(function(){self.loadMoreIfNeeded()
|
7 |
-
},10)):more.remove(),self.positionDropdown(),self.resultsPage=page,self.context=data.context,this.opts.element.trigger({type:"select2-loaded",items:data}))})})))},tokenize:function(){},updateResults:function(initial){function postRender(){search.removeClass("select2-active"),self.positionDropdown(),self.liveRegion.text(results.find(".select2-no-results,.select2-selection-limit,.select2-searching").length?results.text():self.opts.formatMatches(results.find(".select2-result-selectable").length))}function render(html){results.html(html),postRender()}var data,input,queryNumber,search=this.search,results=this.results,opts=this.opts,self=this,term=search.val(),lastTerm=$.data(this.container,"select2-last-term");if((initial===!0||!lastTerm||!equal(term,lastTerm))&&($.data(this.container,"select2-last-term",term),initial===!0||this.showSearchInput!==!1&&this.opened())){queryNumber=++this.queryCount;var maxSelSize=this.getMaximumSelectionSize();if(maxSelSize>=1&&(data=this.data(),$.isArray(data)&&data.length>=maxSelSize&&checkFormatter(opts.formatSelectionTooBig,"formatSelectionTooBig")))return void render("<li class='select2-selection-limit'>"+evaluate(opts.formatSelectionTooBig,maxSelSize)+"</li>");if(search.val().length<opts.minimumInputLength)return render(checkFormatter(opts.formatInputTooShort,"formatInputTooShort")?"<li class='select2-no-results'>"+evaluate(opts.formatInputTooShort,search.val(),opts.minimumInputLength)+"</li>":""),void(initial&&this.showSearch&&this.showSearch(!0));if(opts.maximumInputLength&&search.val().length>opts.maximumInputLength)return void render(checkFormatter(opts.formatInputTooLong,"formatInputTooLong")?"<li class='select2-no-results'>"+evaluate(opts.formatInputTooLong,search.val(),opts.maximumInputLength)+"</li>":"");opts.formatSearching&&0===this.findHighlightableChoices().length&&render("<li class='select2-searching'>"+evaluate(opts.formatSearching)+"</li>"),search.addClass("select2-active"),this.removeHighlight(),input=this.tokenize(),input!=undefined&&null!=input&&search.val(input),this.resultsPage=1,opts.query({element:opts.element,term:search.val(),page:this.resultsPage,context:null,matcher:opts.matcher,callback:this.bind(function(data){var def;if(queryNumber==this.queryCount){if(!this.opened())return void this.search.removeClass("select2-active");if(this.context=data.context===undefined?null:data.context,this.opts.createSearchChoice&&""!==search.val()&&(def=this.opts.createSearchChoice.call(self,search.val(),data.results),def!==undefined&&null!==def&&self.id(def)!==undefined&&null!==self.id(def)&&0===$(data.results).filter(function(){return equal(self.id(this),self.id(def))}).length&&this.opts.createSearchChoicePosition(data.results,def)),0===data.results.length&&checkFormatter(opts.formatNoMatches,"formatNoMatches"))return void render("<li class='select2-no-results'>"+evaluate(opts.formatNoMatches,search.val())+"</li>");results.empty(),self.opts.populateResults.call(this,results,data.results,{term:search.val(),page:this.resultsPage,context:null}),data.more===!0&&checkFormatter(opts.formatLoadMore,"formatLoadMore")&&(results.append("<li class='select2-more-results'>"+self.opts.escapeMarkup(evaluate(opts.formatLoadMore,this.resultsPage))+"</li>"),window.setTimeout(function(){self.loadMoreIfNeeded()},10)),this.postprocessResults(data,initial),postRender(),this.opts.element.trigger({type:"select2-loaded",items:data})}})})}},cancel:function(){this.close()},blur:function(){this.opts.selectOnBlur&&this.selectHighlighted({noFocus:!0}),this.close(),this.container.removeClass("select2-container-active"),this.search[0]===document.activeElement&&this.search.blur(),this.clearSearch(),this.selection.find(".select2-search-choice-focus").removeClass("select2-search-choice-focus")},focusSearch:function(){focus(this.search)},selectHighlighted:function(options){if(this._touchMoved)return void this.clearTouchMoved();var index=this.highlight(),highlighted=this.results.find(".select2-highlighted"),data=highlighted.closest(".select2-result").data("select2-data");data?(this.highlight(index),this.onSelect(data,options)):options&&options.noFocus&&this.close()},getPlaceholder:function(){var placeholderOption;return this.opts.element.attr("placeholder")||this.opts.element.attr("data-placeholder")||this.opts.element.data("placeholder")||this.opts.placeholder||((placeholderOption=this.getPlaceholderOption())!==undefined?placeholderOption.text():undefined)},getPlaceholderOption:function(){if(this.select){var firstOption=this.select.children("option").first();if(this.opts.placeholderOption!==undefined)return"first"===this.opts.placeholderOption&&firstOption||"function"==typeof this.opts.placeholderOption&&this.opts.placeholderOption(this.select);if(""===$.trim(firstOption.text())&&""===firstOption.val())return firstOption}},initContainerWidth:function(){function resolveContainerWidth(){var style,attrs,matches,i,l,attr;if("off"===this.opts.width)return null;if("element"===this.opts.width)return 0===this.opts.element.outerWidth(!1)?"auto":this.opts.element.outerWidth(!1)+"px";if("copy"===this.opts.width||"resolve"===this.opts.width){if(style=this.opts.element.attr("style"),style!==undefined)for(attrs=style.split(";"),i=0,l=attrs.length;l>i;i+=1)if(attr=attrs[i].replace(/\s/g,""),matches=attr.match(/^width:(([-+]?([0-9]*\.)?[0-9]+)(px|em|ex|%|in|cm|mm|pt|pc))/i),null!==matches&&matches.length>=1)return matches[1];return"resolve"===this.opts.width?(style=this.opts.element.css("width"),style.indexOf("%")>0?style:0===this.opts.element.outerWidth(!1)?"auto":this.opts.element.outerWidth(!1)+"px"):null}return $.isFunction(this.opts.width)?this.opts.width():this.opts.width}var width=resolveContainerWidth.call(this);null!==width&&this.container.css("width",width)}}),SingleSelect2=clazz(AbstractSelect2,{createContainer:function(){var container=$(document.createElement("div")).attr({"class":"select2-container"}).html(["<a href='javascript:void(0)' class='select2-choice' tabindex='-1'>"," <span class='select2-chosen'> </span><abbr class='select2-search-choice-close'></abbr>"," <span class='select2-arrow' role='presentation'><b role='presentation'></b></span>","</a>","<label for='' class='select2-offscreen'></label>","<input class='select2-focusser select2-offscreen' type='text' aria-haspopup='true' role='button' />","<div class='select2-drop select2-display-none'>"," <div class='select2-search'>"," <label for='' class='select2-offscreen'></label>"," <input type='text' autocomplete='off' autocorrect='off' autocapitalize='off' spellcheck='false' class='select2-input' role='combobox' aria-expanded='true'"," aria-autocomplete='list' />"," </div>"," <ul class='select2-results' role='listbox'>"," </ul>","</div>"].join(""));return container},enableInterface:function(){this.parent.enableInterface.apply(this,arguments)&&this.focusser.prop("disabled",!this.isInterfaceEnabled())},opening:function(){var el,range,len;this.opts.minimumResultsForSearch>=0&&this.showSearch(!0),this.parent.opening.apply(this,arguments),this.showSearchInput!==!1&&this.search.val(this.focusser.val()),this.opts.shouldFocusInput(this)&&(this.search.focus(),el=this.search.get(0),el.createTextRange?(range=el.createTextRange(),range.collapse(!1),range.select()):el.setSelectionRange&&(len=this.search.val().length,el.setSelectionRange(len,len))),""===this.search.val()&&this.nextSearchTerm!=undefined&&(this.search.val(this.nextSearchTerm),this.search.select()),this.focusser.prop("disabled",!0).val(""),this.updateResults(!0),this.opts.element.trigger($.Event("select2-open"))},close:function(){this.opened()&&(this.parent.close.apply(this,arguments),this.focusser.prop("disabled",!1),this.opts.shouldFocusInput(this)&&this.focusser.focus())},focus:function(){this.opened()?this.close():(this.focusser.prop("disabled",!1),this.opts.shouldFocusInput(this)&&this.focusser.focus())},isFocused:function(){return this.container.hasClass("select2-container-active")},cancel:function(){this.parent.cancel.apply(this,arguments),this.focusser.prop("disabled",!1),this.opts.shouldFocusInput(this)&&this.focusser.focus()},destroy:function(){$("label[for='"+this.focusser.attr("id")+"']").attr("for",this.opts.element.attr("id")),this.parent.destroy.apply(this,arguments),cleanupJQueryElements.call(this,"selection","focusser")},initContainer:function(){var selection,elementLabel,container=this.container,dropdown=this.dropdown,idSuffix=nextUid();this.showSearch(this.opts.minimumResultsForSearch<0?!1:!0),this.selection=selection=container.find(".select2-choice"),this.focusser=container.find(".select2-focusser"),selection.find(".select2-chosen").attr("id","select2-chosen-"+idSuffix),this.focusser.attr("aria-labelledby","select2-chosen-"+idSuffix),this.results.attr("id","select2-results-"+idSuffix),this.search.attr("aria-owns","select2-results-"+idSuffix),this.focusser.attr("id","s2id_autogen"+idSuffix),elementLabel=$("label[for='"+this.opts.element.attr("id")+"']"),this.focusser.prev().text(elementLabel.text()).attr("for",this.focusser.attr("id"));var originalTitle=this.opts.element.attr("title");this.opts.element.attr("title",originalTitle||elementLabel.text()),this.focusser.attr("tabindex",this.elementTabIndex),this.search.attr("id",this.focusser.attr("id")+"_search"),this.search.prev().text($("label[for='"+this.focusser.attr("id")+"']").text()).attr("for",this.search.attr("id")),this.search.on("keydown",this.bind(function(e){if(this.isInterfaceEnabled()){if(e.which===KEY.PAGE_UP||e.which===KEY.PAGE_DOWN)return void killEvent(e);switch(e.which){case KEY.UP:case KEY.DOWN:return this.moveHighlight(e.which===KEY.UP?-1:1),void killEvent(e);case KEY.ENTER:return this.selectHighlighted(),void killEvent(e);case KEY.TAB:return void this.selectHighlighted({noFocus:!0});case KEY.ESC:return this.cancel(e),void killEvent(e)}}})),this.search.on("blur",this.bind(function(){document.activeElement===this.body.get(0)&&window.setTimeout(this.bind(function(){this.opened()&&this.search.focus()}),0)})),this.focusser.on("keydown",this.bind(function(e){if(this.isInterfaceEnabled()&&e.which!==KEY.TAB&&!KEY.isControl(e)&&!KEY.isFunctionKey(e)&&e.which!==KEY.ESC){if(this.opts.openOnEnter===!1&&e.which===KEY.ENTER)return void killEvent(e);if(e.which==KEY.DOWN||e.which==KEY.UP||e.which==KEY.ENTER&&this.opts.openOnEnter){if(e.altKey||e.ctrlKey||e.shiftKey||e.metaKey)return;return this.open(),void killEvent(e)}return e.which==KEY.DELETE||e.which==KEY.BACKSPACE?(this.opts.allowClear&&this.clear(),void killEvent(e)):void 0}})),installKeyUpChangeEvent(this.focusser),this.focusser.on("keyup-change input",this.bind(function(e){if(this.opts.minimumResultsForSearch>=0){if(e.stopPropagation(),this.opened())return;this.open()}})),selection.on("mousedown touchstart","abbr",this.bind(function(e){this.isInterfaceEnabled()&&(this.clear(),killEventImmediately(e),this.close(),this.selection.focus())})),selection.on("mousedown touchstart",this.bind(function(e){reinsertElement(selection),this.container.hasClass("select2-container-active")||this.opts.element.trigger($.Event("select2-focus")),this.opened()?this.close():this.isInterfaceEnabled()&&this.open(),killEvent(e)})),dropdown.on("mousedown touchstart",this.bind(function(){this.opts.shouldFocusInput(this)&&this.search.focus()})),selection.on("focus",this.bind(function(e){killEvent(e)})),this.focusser.on("focus",this.bind(function(){this.container.hasClass("select2-container-active")||this.opts.element.trigger($.Event("select2-focus")),this.container.addClass("select2-container-active")})).on("blur",this.bind(function(){this.opened()||(this.container.removeClass("select2-container-active"),this.opts.element.trigger($.Event("select2-blur")))})),this.search.on("focus",this.bind(function(){this.container.hasClass("select2-container-active")||this.opts.element.trigger($.Event("select2-focus")),this.container.addClass("select2-container-active")})),this.initContainerWidth(),this.opts.element.addClass("select2-offscreen"),this.setPlaceholder()},clear:function(triggerChange){var data=this.selection.data("select2-data");if(data){var evt=$.Event("select2-clearing");if(this.opts.element.trigger(evt),evt.isDefaultPrevented())return;var placeholderOption=this.getPlaceholderOption();this.opts.element.val(placeholderOption?placeholderOption.val():""),this.selection.find(".select2-chosen").empty(),this.selection.removeData("select2-data"),this.setPlaceholder(),triggerChange!==!1&&(this.opts.element.trigger({type:"select2-removed",val:this.id(data),choice:data}),this.triggerChange({removed:data}))}},initSelection:function(){if(this.isPlaceholderOptionSelected())this.updateSelection(null),this.close(),this.setPlaceholder();else{var self=this;this.opts.initSelection.call(null,this.opts.element,function(selected){selected!==undefined&&null!==selected&&(self.updateSelection(selected),self.close(),self.setPlaceholder(),self.nextSearchTerm=self.opts.nextSearchTerm(selected,self.search.val()))})}},isPlaceholderOptionSelected:function(){var placeholderOption;return this.getPlaceholder()===undefined?!1:(placeholderOption=this.getPlaceholderOption())!==undefined&&placeholderOption.prop("selected")||""===this.opts.element.val()||this.opts.element.val()===undefined||null===this.opts.element.val()},prepareOpts:function(){var opts=this.parent.prepareOpts.apply(this,arguments),self=this;return"select"===opts.element.get(0).tagName.toLowerCase()?opts.initSelection=function(element,callback){var selected=element.find("option").filter(function(){return this.selected&&!this.disabled});callback(self.optionToData(selected))}:"data"in opts&&(opts.initSelection=opts.initSelection||function(element,callback){var id=element.val(),match=null;opts.query({matcher:function(term,text,el){var is_match=equal(id,opts.id(el));return is_match&&(match=el),is_match},callback:$.isFunction(callback)?function(){callback(match)}:$.noop})}),opts},getPlaceholder:function(){return this.select&&this.getPlaceholderOption()===undefined?undefined:this.parent.getPlaceholder.apply(this,arguments)},setPlaceholder:function(){var placeholder=this.getPlaceholder();if(this.isPlaceholderOptionSelected()&&placeholder!==undefined){if(this.select&&this.getPlaceholderOption()===undefined)return;this.selection.find(".select2-chosen").html(this.opts.escapeMarkup(placeholder)),this.selection.addClass("select2-default"),this.container.removeClass("select2-allowclear")}},postprocessResults:function(data,initial,noHighlightUpdate){var selected=0,self=this;if(this.findHighlightableChoices().each2(function(i,elm){return equal(self.id(elm.data("select2-data")),self.opts.element.val())?(selected=i,!1):void 0}),noHighlightUpdate!==!1&&this.highlight(initial===!0&&selected>=0?selected:0),initial===!0){var min=this.opts.minimumResultsForSearch;min>=0&&this.showSearch(countResults(data.results)>=min)}},showSearch:function(showSearchInput){this.showSearchInput!==showSearchInput&&(this.showSearchInput=showSearchInput,this.dropdown.find(".select2-search").toggleClass("select2-search-hidden",!showSearchInput),this.dropdown.find(".select2-search").toggleClass("select2-offscreen",!showSearchInput),$(this.dropdown,this.container).toggleClass("select2-with-searchbox",showSearchInput))},onSelect:function(data,options){if(this.triggerSelect(data)){var old=this.opts.element.val(),oldData=this.data();this.opts.element.val(this.id(data)),this.updateSelection(data),this.opts.element.trigger({type:"select2-selected",val:this.id(data),choice:data}),this.nextSearchTerm=this.opts.nextSearchTerm(data,this.search.val()),this.close(),options&&options.noFocus||!this.opts.shouldFocusInput(this)||this.focusser.focus(),equal(old,this.id(data))||this.triggerChange({added:data,removed:oldData})}},updateSelection:function(data){var formatted,cssClass,container=this.selection.find(".select2-chosen");this.selection.data("select2-data",data),container.empty(),null!==data&&(formatted=this.opts.formatSelection(data,container,this.opts.escapeMarkup)),formatted!==undefined&&container.append(formatted),cssClass=this.opts.formatSelectionCssClass(data,container),cssClass!==undefined&&container.addClass(cssClass),this.selection.removeClass("select2-default"),this.opts.allowClear&&this.getPlaceholder()!==undefined&&this.container.addClass("select2-allowclear")},val:function(){var val,triggerChange=!1,data=null,self=this,oldData=this.data();if(0===arguments.length)return this.opts.element.val();if(val=arguments[0],arguments.length>1&&(triggerChange=arguments[1]),this.select)this.select.val(val).find("option").filter(function(){return this.selected}).each2(function(i,elm){return data=self.optionToData(elm),!1}),this.updateSelection(data),this.setPlaceholder(),triggerChange&&this.triggerChange({added:data,removed:oldData});else{if(!val&&0!==val)return void this.clear(triggerChange);if(this.opts.initSelection===undefined)throw new Error("cannot call val() if initSelection() is not defined");this.opts.element.val(val),this.opts.initSelection(this.opts.element,function(data){self.opts.element.val(data?self.id(data):""),self.updateSelection(data),self.setPlaceholder(),triggerChange&&self.triggerChange({added:data,removed:oldData})})}},clearSearch:function(){this.search.val(""),this.focusser.val("")},data:function(value){var data,triggerChange=!1;return 0===arguments.length?(data=this.selection.data("select2-data"),data==undefined&&(data=null),data):(arguments.length>1&&(triggerChange=arguments[1]),void(value?(data=this.data(),this.opts.element.val(value?this.id(value):""),this.updateSelection(value),triggerChange&&this.triggerChange({added:value,removed:data})):this.clear(triggerChange)))}}),MultiSelect2=clazz(AbstractSelect2,{createContainer:function(){var container=$(document.createElement("div")).attr({"class":"select2-container select2-container-multi"}).html(["<ul class='select2-choices'>"," <li class='select2-search-field'>"," <label for='' class='select2-offscreen'></label>"," <input type='text' autocomplete='off' autocorrect='off' autocapitalize='off' spellcheck='false' class='select2-input'>"," </li>","</ul>","<div class='select2-drop select2-drop-multi select2-display-none'>"," <ul class='select2-results'>"," </ul>","</div>"].join(""));return container},prepareOpts:function(){var opts=this.parent.prepareOpts.apply(this,arguments),self=this;return"select"===opts.element.get(0).tagName.toLowerCase()?opts.initSelection=function(element,callback){var data=[];element.find("option").filter(function(){return this.selected&&!this.disabled}).each2(function(i,elm){data.push(self.optionToData(elm))}),callback(data)}:"data"in opts&&(opts.initSelection=opts.initSelection||function(element,callback){var ids=splitVal(element.val(),opts.separator),matches=[];opts.query({matcher:function(term,text,el){var is_match=$.grep(ids,function(id){return equal(id,opts.id(el))}).length;return is_match&&matches.push(el),is_match},callback:$.isFunction(callback)?function(){for(var ordered=[],i=0;i<ids.length;i++)for(var id=ids[i],j=0;j<matches.length;j++){var match=matches[j];if(equal(id,opts.id(match))){ordered.push(match),matches.splice(j,1);break}}callback(ordered)}:$.noop})}),opts},selectChoice:function(choice){var selected=this.container.find(".select2-search-choice-focus");selected.length&&choice&&choice[0]==selected[0]||(selected.length&&this.opts.element.trigger("choice-deselected",selected),selected.removeClass("select2-search-choice-focus"),choice&&choice.length&&(this.close(),choice.addClass("select2-search-choice-focus"),this.opts.element.trigger("choice-selected",choice)))},destroy:function(){$("label[for='"+this.search.attr("id")+"']").attr("for",this.opts.element.attr("id")),this.parent.destroy.apply(this,arguments),cleanupJQueryElements.call(this,"searchContainer","selection")},initContainer:function(){var selection,selector=".select2-choices";this.searchContainer=this.container.find(".select2-search-field"),this.selection=selection=this.container.find(selector);var _this=this;this.selection.on("click",".select2-search-choice:not(.select2-locked)",function(){_this.search[0].focus(),_this.selectChoice($(this))}),this.search.attr("id","s2id_autogen"+nextUid()),this.search.prev().text($("label[for='"+this.opts.element.attr("id")+"']").text()).attr("for",this.search.attr("id")),this.search.on("input paste",this.bind(function(){this.isInterfaceEnabled()&&(this.opened()||this.open())})),this.search.attr("tabindex",this.elementTabIndex),this.keydowns=0,this.search.on("keydown",this.bind(function(e){if(this.isInterfaceEnabled()){++this.keydowns;var selected=selection.find(".select2-search-choice-focus"),prev=selected.prev(".select2-search-choice:not(.select2-locked)"),next=selected.next(".select2-search-choice:not(.select2-locked)"),pos=getCursorInfo(this.search);if(selected.length&&(e.which==KEY.LEFT||e.which==KEY.RIGHT||e.which==KEY.BACKSPACE||e.which==KEY.DELETE||e.which==KEY.ENTER)){var selectedChoice=selected;return e.which==KEY.LEFT&&prev.length?selectedChoice=prev:e.which==KEY.RIGHT?selectedChoice=next.length?next:null:e.which===KEY.BACKSPACE?this.unselect(selected.first())&&(this.search.width(10),selectedChoice=prev.length?prev:next):e.which==KEY.DELETE?this.unselect(selected.first())&&(this.search.width(10),selectedChoice=next.length?next:null):e.which==KEY.ENTER&&(selectedChoice=null),this.selectChoice(selectedChoice),killEvent(e),void(selectedChoice&&selectedChoice.length||this.open())}if((e.which===KEY.BACKSPACE&&1==this.keydowns||e.which==KEY.LEFT)&&0==pos.offset&&!pos.length)return this.selectChoice(selection.find(".select2-search-choice:not(.select2-locked)").last()),void killEvent(e);if(this.selectChoice(null),this.opened())switch(e.which){case KEY.UP:case KEY.DOWN:return this.moveHighlight(e.which===KEY.UP?-1:1),void killEvent(e);case KEY.ENTER:return this.selectHighlighted(),void killEvent(e);case KEY.TAB:return this.selectHighlighted({noFocus:!0}),void this.close();case KEY.ESC:return this.cancel(e),void killEvent(e)}if(e.which!==KEY.TAB&&!KEY.isControl(e)&&!KEY.isFunctionKey(e)&&e.which!==KEY.BACKSPACE&&e.which!==KEY.ESC){if(e.which===KEY.ENTER){if(this.opts.openOnEnter===!1)return;if(e.altKey||e.ctrlKey||e.shiftKey||e.metaKey)return}this.open(),(e.which===KEY.PAGE_UP||e.which===KEY.PAGE_DOWN)&&killEvent(e),e.which===KEY.ENTER&&killEvent(e)}}})),this.search.on("keyup",this.bind(function(){this.keydowns=0,this.resizeSearch()})),this.search.on("blur",this.bind(function(e){this.container.removeClass("select2-container-active"),this.search.removeClass("select2-focused"),this.selectChoice(null),this.opened()||this.clearSearch(),e.stopImmediatePropagation(),this.opts.element.trigger($.Event("select2-blur"))})),this.container.on("click",selector,this.bind(function(e){this.isInterfaceEnabled()&&($(e.target).closest(".select2-search-choice").length>0||(this.selectChoice(null),this.clearPlaceholder(),this.container.hasClass("select2-container-active")||this.opts.element.trigger($.Event("select2-focus")),this.open(),this.focusSearch(),e.preventDefault()))})),this.container.on("focus",selector,this.bind(function(){this.isInterfaceEnabled()&&(this.container.hasClass("select2-container-active")||this.opts.element.trigger($.Event("select2-focus")),this.container.addClass("select2-container-active"),this.dropdown.addClass("select2-drop-active"),this.clearPlaceholder())})),this.initContainerWidth(),this.opts.element.addClass("select2-offscreen"),this.clearSearch()},enableInterface:function(){this.parent.enableInterface.apply(this,arguments)&&this.search.prop("disabled",!this.isInterfaceEnabled())},initSelection:function(){if(""===this.opts.element.val()&&""===this.opts.element.text()&&(this.updateSelection([]),this.close(),this.clearSearch()),this.select||""!==this.opts.element.val()){var self=this;this.opts.initSelection.call(null,this.opts.element,function(data){data!==undefined&&null!==data&&(self.updateSelection(data),self.close(),self.clearSearch())})}},clearSearch:function(){var placeholder=this.getPlaceholder(),maxWidth=this.getMaxSearchWidth();placeholder!==undefined&&0===this.getVal().length&&this.search.hasClass("select2-focused")===!1?(this.search.val(placeholder).addClass("select2-default"),this.search.width(maxWidth>0?maxWidth:this.container.css("width"))):this.search.val("").width(10)},clearPlaceholder:function(){this.search.hasClass("select2-default")&&this.search.val("").removeClass("select2-default")},opening:function(){this.clearPlaceholder(),this.resizeSearch(),this.parent.opening.apply(this,arguments),this.focusSearch(),""===this.search.val()&&this.nextSearchTerm!=undefined&&(this.search.val(this.nextSearchTerm),this.search.select()),this.updateResults(!0),this.opts.shouldFocusInput(this)&&this.search.focus(),this.opts.element.trigger($.Event("select2-open"))},close:function(){this.opened()&&this.parent.close.apply(this,arguments)},focus:function(){this.close(),this.search.focus()},isFocused:function(){return this.search.hasClass("select2-focused")},updateSelection:function(data){var ids=[],filtered=[],self=this;$(data).each(function(){indexOf(self.id(this),ids)<0&&(ids.push(self.id(this)),filtered.push(this))}),data=filtered,this.selection.find(".select2-search-choice").remove(),$(data).each(function(){self.addSelectedChoice(this)}),self.postprocessResults()},tokenize:function(){var input=this.search.val();input=this.opts.tokenizer.call(this,input,this.data(),this.bind(this.onSelect),this.opts),null!=input&&input!=undefined&&(this.search.val(input),input.length>0&&this.open())},onSelect:function(data,options){this.triggerSelect(data)&&(this.addSelectedChoice(data),this.opts.element.trigger({type:"selected",val:this.id(data),choice:data}),this.nextSearchTerm=this.opts.nextSearchTerm(data,this.search.val()),this.clearSearch(),this.updateResults(),(this.select||!this.opts.closeOnSelect)&&this.postprocessResults(data,!1,this.opts.closeOnSelect===!0),this.opts.closeOnSelect?(this.close(),this.search.width(10)):this.countSelectableResults()>0?(this.search.width(10),this.resizeSearch(),this.getMaximumSelectionSize()>0&&this.val().length>=this.getMaximumSelectionSize()?this.updateResults(!0):this.nextSearchTerm!=undefined&&(this.search.val(this.nextSearchTerm),this.updateResults(),this.search.select()),this.positionDropdown()):(this.close(),this.search.width(10)),this.triggerChange({added:data}),options&&options.noFocus||this.focusSearch())},cancel:function(){this.close(),this.focusSearch()},addSelectedChoice:function(data){var formatted,cssClass,enableChoice=!data.locked,enabledItem=$("<li class='select2-search-choice'> <div></div> <a href='#' class='select2-search-choice-close' tabindex='-1'></a></li>"),disabledItem=$("<li class='select2-search-choice select2-locked'><div></div></li>"),choice=enableChoice?enabledItem:disabledItem,id=this.id(data),val=this.getVal();formatted=this.opts.formatSelection(data,choice.find("div"),this.opts.escapeMarkup),formatted!=undefined&&choice.find("div").replaceWith("<div>"+formatted+"</div>"),cssClass=this.opts.formatSelectionCssClass(data,choice.find("div")),cssClass!=undefined&&choice.addClass(cssClass),enableChoice&&choice.find(".select2-search-choice-close").on("mousedown",killEvent).on("click dblclick",this.bind(function(e){this.isInterfaceEnabled()&&(this.unselect($(e.target)),this.selection.find(".select2-search-choice-focus").removeClass("select2-search-choice-focus"),killEvent(e),this.close(),this.focusSearch())})).on("focus",this.bind(function(){this.isInterfaceEnabled()&&(this.container.addClass("select2-container-active"),this.dropdown.addClass("select2-drop-active"))})),choice.data("select2-data",data),choice.insertBefore(this.searchContainer),val.push(id),this.setVal(val)},unselect:function(selected){var data,index,val=this.getVal();if(selected=selected.closest(".select2-search-choice"),0===selected.length)throw"Invalid argument: "+selected+". Must be .select2-search-choice";if(data=selected.data("select2-data")){var evt=$.Event("select2-removing");if(evt.val=this.id(data),evt.choice=data,this.opts.element.trigger(evt),evt.isDefaultPrevented())return!1;for(;(index=indexOf(this.id(data),val))>=0;)val.splice(index,1),this.setVal(val),this.select&&this.postprocessResults();return selected.remove(),this.opts.element.trigger({type:"select2-removed",val:this.id(data),choice:data}),this.triggerChange({removed:data}),!0}},postprocessResults:function(data,initial,noHighlightUpdate){var val=this.getVal(),choices=this.results.find(".select2-result"),compound=this.results.find(".select2-result-with-children"),self=this;choices.each2(function(i,choice){var id=self.id(choice.data("select2-data"));indexOf(id,val)>=0&&(choice.addClass("select2-selected"),choice.find(".select2-result-selectable").addClass("select2-selected"))}),compound.each2(function(i,choice){choice.is(".select2-result-selectable")||0!==choice.find(".select2-result-selectable:not(.select2-selected)").length||choice.addClass("select2-selected")}),-1==this.highlight()&&noHighlightUpdate!==!1&&self.highlight(0),!this.opts.createSearchChoice&&!choices.filter(".select2-result:not(.select2-selected)").length>0&&(!data||data&&!data.more&&0===this.results.find(".select2-no-results").length)&&checkFormatter(self.opts.formatNoMatches,"formatNoMatches")&&this.results.append("<li class='select2-no-results'>"+evaluate(self.opts.formatNoMatches,self.search.val())+"</li>")},getMaxSearchWidth:function(){return this.selection.width()-getSideBorderPadding(this.search)},resizeSearch:function(){var minimumWidth,left,maxWidth,containerLeft,searchWidth,sideBorderPadding=getSideBorderPadding(this.search);minimumWidth=measureTextWidth(this.search)+10,left=this.search.offset().left,maxWidth=this.selection.width(),containerLeft=this.selection.offset().left,searchWidth=maxWidth-(left-containerLeft)-sideBorderPadding,minimumWidth>searchWidth&&(searchWidth=maxWidth-sideBorderPadding),40>searchWidth&&(searchWidth=maxWidth-sideBorderPadding),0>=searchWidth&&(searchWidth=minimumWidth),this.search.width(Math.floor(searchWidth))},getVal:function(){var val;return this.select?(val=this.select.val(),null===val?[]:val):(val=this.opts.element.val(),splitVal(val,this.opts.separator))},setVal:function(val){var unique;this.select?this.select.val(val):(unique=[],$(val).each(function(){indexOf(this,unique)<0&&unique.push(this)}),this.opts.element.val(0===unique.length?"":unique.join(this.opts.separator)))},buildChangeDetails:function(old,current){for(var current=current.slice(0),old=old.slice(0),i=0;i<current.length;i++)for(var j=0;j<old.length;j++)equal(this.opts.id(current[i]),this.opts.id(old[j]))&&(current.splice(i,1),i>0&&i--,old.splice(j,1),j--);return{added:current,removed:old}},val:function(val,triggerChange){var oldData,self=this;if(0===arguments.length)return this.getVal();if(oldData=this.data(),oldData.length||(oldData=[]),!val&&0!==val)return this.opts.element.val(""),this.updateSelection([]),this.clearSearch(),void(triggerChange&&this.triggerChange({added:this.data(),removed:oldData}));if(this.setVal(val),this.select)this.opts.initSelection(this.select,this.bind(this.updateSelection)),triggerChange&&this.triggerChange(this.buildChangeDetails(oldData,this.data()));else{if(this.opts.initSelection===undefined)throw new Error("val() cannot be called if initSelection() is not defined");this.opts.initSelection(this.opts.element,function(data){var ids=$.map(data,self.id);self.setVal(ids),self.updateSelection(data),self.clearSearch(),triggerChange&&self.triggerChange(self.buildChangeDetails(oldData,self.data()))})}this.clearSearch()},onSortStart:function(){if(this.select)throw new Error("Sorting of elements is not supported when attached to <select>. Attach to <input type='hidden'/> instead.");this.search.width(0),this.searchContainer.hide()},onSortEnd:function(){var val=[],self=this;this.searchContainer.show(),this.searchContainer.appendTo(this.searchContainer.parent()),this.resizeSearch(),this.selection.find(".select2-search-choice").each(function(){val.push(self.opts.id($(this).data("select2-data")))
|
8 |
-
}),this.setVal(val),this.triggerChange()},data:function(values,triggerChange){var ids,old,self=this;return 0===arguments.length?this.selection.children(".select2-search-choice").map(function(){return $(this).data("select2-data")}).get():(old=this.data(),values||(values=[]),ids=$.map(values,function(e){return self.opts.id(e)}),this.setVal(ids),this.updateSelection(values),this.clearSearch(),triggerChange&&this.triggerChange(this.buildChangeDetails(old,this.data())),void 0)}}),$.fn.select2=function(){var opts,select2,method,value,multiple,args=Array.prototype.slice.call(arguments,0),allowedMethods=["val","destroy","opened","open","close","focus","isFocused","container","dropdown","onSortStart","onSortEnd","enable","disable","readonly","positionDropdown","data","search"],valueMethods=["opened","isFocused","container","dropdown"],propertyMethods=["val","data"],methodsMap={search:"externalSearch"};return this.each(function(){if(0===args.length||"object"==typeof args[0])opts=0===args.length?{}:$.extend({},args[0]),opts.element=$(this),"select"===opts.element.get(0).tagName.toLowerCase()?multiple=opts.element.prop("multiple"):(multiple=opts.multiple||!1,"tags"in opts&&(opts.multiple=multiple=!0)),select2=multiple?new window.Select2["class"].multi:new window.Select2["class"].single,select2.init(opts);else{if("string"!=typeof args[0])throw"Invalid arguments to select2 plugin: "+args;if(indexOf(args[0],allowedMethods)<0)throw"Unknown method: "+args[0];if(value=undefined,select2=$(this).data("select2"),select2===undefined)return;if(method=args[0],"container"===method?value=select2.container:"dropdown"===method?value=select2.dropdown:(methodsMap[method]&&(method=methodsMap[method]),value=select2[method].apply(select2,args.slice(1))),indexOf(args[0],valueMethods)>=0||indexOf(args[0],propertyMethods)>=0&&1==args.length)return!1}}),value===undefined?this:value},$.fn.select2.defaults={width:"copy",loadMorePadding:0,closeOnSelect:!0,openOnEnter:!0,containerCss:{},dropdownCss:{},containerCssClass:"",dropdownCssClass:"",formatResult:function(result,container,query,escapeMarkup){var markup=[];return markMatch(result.text,query.term,markup,escapeMarkup),markup.join("")},formatSelection:function(data,container,escapeMarkup){return data?escapeMarkup(data.text):undefined},sortResults:function(results){return results},formatResultCssClass:function(data){return data.css},formatSelectionCssClass:function(){return undefined},formatMatches:function(matches){return matches+" results are available, use up and down arrow keys to navigate."},formatNoMatches:function(){return"No matches found"},formatInputTooShort:function(input,min){var n=min-input.length;return"Please enter "+n+" or more character"+(1==n?"":"s")},formatInputTooLong:function(input,max){var n=input.length-max;return"Please delete "+n+" character"+(1==n?"":"s")},formatSelectionTooBig:function(limit){return"You can only select "+limit+" item"+(1==limit?"":"s")},formatLoadMore:function(){return"Loading more results…"},formatSearching:function(){return"Searching…"},minimumResultsForSearch:0,minimumInputLength:0,maximumInputLength:null,maximumSelectionSize:0,id:function(e){return e==undefined?null:e.id},matcher:function(term,text){return stripDiacritics(""+text).toUpperCase().indexOf(stripDiacritics(""+term).toUpperCase())>=0},separator:",",tokenSeparators:[],tokenizer:defaultTokenizer,escapeMarkup:defaultEscapeMarkup,blurOnChange:!1,selectOnBlur:!1,adaptContainerCssClass:function(c){return c},adaptDropdownCssClass:function(){return null},nextSearchTerm:function(){return undefined},searchInputPlaceholder:"",createSearchChoicePosition:"top",shouldFocusInput:function(instance){var supportsTouchEvents="ontouchstart"in window||navigator.msMaxTouchPoints>0;return supportsTouchEvents&&instance.opts.minimumResultsForSearch<0?!1:!0}},$.fn.select2.ajaxDefaults={transport:$.ajax,params:{type:"GET",cache:!1,dataType:"json"}},window.Select2={query:{ajax:ajax,local:local,tags:tags},util:{debounce:debounce,markMatch:markMatch,escapeMarkup:defaultEscapeMarkup,stripDiacritics:stripDiacritics},"class":{"abstract":AbstractSelect2,single:SingleSelect2,multi:MultiSelect2}}}}(jQuery),jQuery(document).ready(function($){$("#filter_action, #filter_content, #filter_form").change(function(){$("#leadin-contacts-filter-button").addClass("button-primary")})});
|
1 |
+
function leadin_check_social_share_popup(){jQuery.ajax({type:"POST",url:li_admin_ajax.ajax_url,data:{action:"leadin_check_installation_date"},success:function(data){data||$.cookie("ignore_social_share",1)}})}!function(factory){"function"==typeof define&&define.amd?define(["jquery"],factory):factory(jQuery)}(function($){function encode(s){return config.raw?s:encodeURIComponent(s)}function decode(s){return config.raw?s:decodeURIComponent(s)}function stringifyCookieValue(value){return encode(config.json?JSON.stringify(value):String(value))}function parseCookieValue(s){0===s.indexOf('"')&&(s=s.slice(1,-1).replace(/\\"/g,'"').replace(/\\\\/g,"\\"));try{return s=decodeURIComponent(s.replace(pluses," ")),config.json?JSON.parse(s):s}catch(e){}}function read(s,converter){var value=config.raw?s:parseCookieValue(s);return $.isFunction(converter)?converter(value):value}var pluses=/\+/g,config=$.cookie=function(key,value,options){if(void 0!==value&&!$.isFunction(value)){if(options=$.extend({},config.defaults,options),"number"==typeof options.expires){var days=options.expires,t=options.expires=new Date;t.setDate(t.getDate()+days)}return document.cookie=[encode(key),"=",stringifyCookieValue(value),options.expires?"; expires="+options.expires.toUTCString():"",options.path?"; path="+options.path:"",options.domain?"; domain="+options.domain:"",options.secure?"; secure":""].join("")}for(var result=key?void 0:{},cookies=document.cookie?document.cookie.split("; "):[],i=0,l=cookies.length;l>i;i++){var parts=cookies[i].split("="),name=decode(parts.shift()),cookie=parts.join("=");if(key&&key===name){result=read(cookie,value);break}key||void 0===(cookie=read(cookie))||(result[name]=cookie)}return result};config.defaults={},$.removeCookie=function(key,options){return void 0===$.cookie(key)?!1:($.cookie(key,"",$.extend({},options,{expires:-1})),!$.cookie(key))}}),window.Highcharts||!function(){function q(a,b){var c;a||(a={});for(c in b)a[c]=b[c];return a}function w(){var a,c,b=arguments,d={},e=function(a,b){var c,d;"object"!=typeof a&&(a={});for(d in b)b.hasOwnProperty(d)&&(c=b[d],a[d]=c&&"object"==typeof c&&"[object Array]"!==Object.prototype.toString.call(c)&&"renderTo"!==d&&"number"!=typeof c.nodeType?e(a[d]||{},c):b[d]);return a};for(b[0]===!0&&(d=b[1],b=Array.prototype.slice.call(b,2)),c=b.length,a=0;c>a;a++)d=e(d,b[a]);return d}function z(a,b){return parseInt(a,b||10)}function Fa(a){return"string"==typeof a}function ca(a){return"object"==typeof a}function La(a){return"[object Array]"===Object.prototype.toString.call(a)}function ha(a){return"number"==typeof a}function za(a){return U.log(a)/U.LN10}function ia(a){return U.pow(10,a)}function ja(a,b){for(var c=a.length;c--;)if(a[c]===b){a.splice(c,1);break}}function r(a){return a!==t&&null!==a}function H(a,b,c){var d,e;if(Fa(b))r(c)?a.setAttribute(b,c):a&&a.getAttribute&&(e=a.getAttribute(b));else if(r(b)&&ca(b))for(d in b)a.setAttribute(d,b[d]);return e}function qa(a){return La(a)?a:[a]}function m(){var b,c,a=arguments,d=a.length;for(b=0;d>b;b++)if(c=a[b],"undefined"!=typeof c&&null!==c)return c}function G(a,b){Aa&&!aa&&b&&b.opacity!==t&&(b.filter="alpha(opacity="+100*b.opacity+")"),q(a.style,b)}function Y(a,b,c,d,e){return a=y.createElement(a),b&&q(a,b),e&&G(a,{padding:0,border:Q,margin:0}),c&&G(a,c),d&&d.appendChild(a),a}function ka(a,b){var c=function(){};return c.prototype=new a,q(c.prototype,b),c}function Ga(a,b,c,d){var e=E.lang,a=+a||0,f=-1===b?(a.toString().split(".")[1]||"").length:isNaN(b=M(b))?2:b,b=void 0===c?e.decimalPoint:c,d=void 0===d?e.thousandsSep:d,e=0>a?"-":"",c=String(z(a=M(a).toFixed(f))),g=c.length>3?c.length%3:0;return e+(g?c.substr(0,g)+d:"")+c.substr(g).replace(/(\d{3})(?=\d)/g,"$1"+d)+(f?b+M(a-c).toFixed(f).slice(2):"")}function Ha(a,b){return Array((b||2)+1-String(a).length).join(0)+a}function Ma(a,b,c){var d=a[b];a[b]=function(){var a=Array.prototype.slice.call(arguments);return a.unshift(d),c.apply(this,a)}}function Ia(a,b){for(var e,f,g,h,i,c="{",d=!1,j=[];-1!==(c=a.indexOf(c));){if(e=a.slice(0,c),d){for(f=e.split(":"),g=f.shift().split("."),i=g.length,e=b,h=0;i>h;h++)e=e[g[h]];f.length&&(f=f.join(":"),g=/\.([0-9])/,h=E.lang,i=void 0,/f$/.test(f)?(i=(i=f.match(g))?i[1]:-1,null!==e&&(e=Ga(e,i,h.decimalPoint,f.indexOf(",")>-1?h.thousandsSep:""))):e=cb(f,e))}j.push(e),a=a.slice(c+1),c=(d=!d)?"}":"{"}return j.push(a),j.join("")}function mb(a){return U.pow(10,T(U.log(a)/U.LN10))}function nb(a,b,c,d){var e,c=m(c,1);for(e=a/c,b||(b=[1,2,2.5,5,10],d&&d.allowDecimals===!1&&(1===c?b=[1,2,5,10]:.1>=c&&(b=[1/c]))),d=0;d<b.length&&(a=b[d],!(e<=(b[d]+(b[d+1]||b[d]))/2));d++);return a*=c}function Bb(){this.symbol=this.color=0}function ob(a,b){var d,e,c=a.length;for(e=0;c>e;e++)a[e].ss_i=e;for(a.sort(function(a,c){return d=b(a,c),0===d?a.ss_i-c.ss_i:d}),e=0;c>e;e++)delete a[e].ss_i}function Na(a){for(var b=a.length,c=a[0];b--;)a[b]<c&&(c=a[b]);return c}function Ba(a){for(var b=a.length,c=a[0];b--;)a[b]>c&&(c=a[b]);return c}function Oa(a,b){for(var c in a)a[c]&&a[c]!==b&&a[c].destroy&&a[c].destroy(),delete a[c]}function Pa(a){db||(db=Y(Ja)),a&&db.appendChild(a),db.innerHTML=""}function ra(a,b){var c="Highcharts error #"+a+": www.highcharts.com/errors/"+a;if(b)throw c;I.console&&console.log(c)}function da(a){return parseFloat(a.toPrecision(14))}function Qa(a,b){va=m(a,b.animation)}function Cb(){var a=E.global.useUTC,b=a?"getUTC":"get",c=a?"setUTC":"set";Ra=6e4*(a&&E.global.timezoneOffset||0),eb=a?Date.UTC:function(a,b,c,g,h,i){return new Date(a,b,m(c,1),m(g,0),m(h,0),m(i,0)).getTime()},pb=b+"Minutes",qb=b+"Hours",rb=b+"Day",Xa=b+"Date",fb=b+"Month",gb=b+"FullYear",Db=c+"Minutes",Eb=c+"Hours",sb=c+"Date",Fb=c+"Month",Gb=c+"FullYear"}function P(){}function Sa(a,b,c,d){this.axis=a,this.pos=b,this.type=c||"",this.isNew=!0,!c&&!d&&this.addLabel()}function la(){this.init.apply(this,arguments)}function Ya(){this.init.apply(this,arguments)}function Hb(a,b,c,d,e){var f=a.chart.inverted;this.axis=a,this.isNegative=c,this.options=b,this.x=d,this.total=null,this.points={},this.stack=e,this.alignOptions={align:b.align||(f?c?"left":"right":"center"),verticalAlign:b.verticalAlign||(f?"middle":c?"bottom":"top"),y:m(b.y,f?4:c?14:-6),x:m(b.x,f?c?-6:6:0)},this.textAlign=b.textAlign||(f?c?"right":"left":"center")}var t,Za,$a,db,E,cb,va,ub,A,eb,Ra,pb,qb,rb,Xa,fb,gb,Db,Eb,sb,Fb,Gb,y=document,I=window,U=Math,u=U.round,T=U.floor,Ka=U.ceil,v=U.max,C=U.min,M=U.abs,Z=U.cos,ea=U.sin,ma=U.PI,Ca=2*ma/360,wa=navigator.userAgent,Ib=I.opera,Aa=/msie/i.test(wa)&&!Ib,hb=8===y.documentMode,ib=/AppleWebKit/.test(wa),Ta=/Firefox/.test(wa),Jb=/(Mobile|Android|Windows Phone)/.test(wa),xa="http://www.w3.org/2000/svg",aa=!!y.createElementNS&&!!y.createElementNS(xa,"svg").createSVGRect,Nb=Ta&&parseInt(wa.split("Firefox/")[1],10)<4,fa=!aa&&!Aa&&!!y.createElement("canvas").getContext,Kb={},tb=0,sa=function(){},V=[],ab=0,Ja="div",Q="none",Ob=/^[0-9]+$/,Pb="stroke-width",F={},R=I.Highcharts=I.Highcharts?ra(16,!0):{};cb=function(a,b,c){if(!r(b)||isNaN(b))return"Invalid date";var e,a=m(a,"%Y-%m-%d %H:%M:%S"),d=new Date(b-Ra),f=d[qb](),g=d[rb](),h=d[Xa](),i=d[fb](),j=d[gb](),k=E.lang,l=k.weekdays,d=q({a:l[g].substr(0,3),A:l[g],d:Ha(h),e:h,b:k.shortMonths[i],B:k.months[i],m:Ha(i+1),y:j.toString().substr(2,2),Y:j,H:Ha(f),I:Ha(f%12||12),l:f%12||12,M:Ha(d[pb]()),p:12>f?"AM":"PM",P:12>f?"am":"pm",S:Ha(d.getSeconds()),L:Ha(u(b%1e3),3)},R.dateFormats);for(e in d)for(;-1!==a.indexOf("%"+e);)a=a.replace("%"+e,"function"==typeof d[e]?d[e](b):d[e]);return c?a.substr(0,1).toUpperCase()+a.substr(1):a},Bb.prototype={wrapColor:function(a){this.color>=a&&(this.color=0)},wrapSymbol:function(a){this.symbol>=a&&(this.symbol=0)}},A=function(){for(var a=0,b=arguments,c=b.length,d={};c>a;a++)d[b[a++]]=b[a];return d}("millisecond",1,"second",1e3,"minute",6e4,"hour",36e5,"day",864e5,"week",6048e5,"month",26784e5,"year",31556952e3),ub={init:function(a,b,c){var g,h,i,b=b||"",d=a.shift,e=b.indexOf("C")>-1,f=e?7:3,b=b.split(" "),c=[].concat(c),j=function(a){for(g=a.length;g--;)"M"===a[g]&&a.splice(g+1,0,a[g+1],a[g+2],a[g+1],a[g+2])};if(e&&(j(b),j(c)),a.isArea&&(h=b.splice(b.length-6,6),i=c.splice(c.length-6,6)),d<=c.length/f&&b.length===c.length)for(;d--;)c=[].concat(c).splice(0,f).concat(c);if(a.shift=0,b.length)for(a=c.length;b.length<a;)d=[].concat(b).splice(b.length-f,f),e&&(d[f-6]=d[f-2],d[f-5]=d[f-1]),b=b.concat(d);return h&&(b=b.concat(h),c=c.concat(i)),[b,c]},step:function(a,b,c,d){var e=[],f=a.length;if(1===c)e=d;else if(f===b.length&&1>c)for(;f--;)d=parseFloat(a[f]),e[f]=isNaN(d)?a[f]:c*parseFloat(b[f]-d)+d;else e=b;return e}},function(a){I.HighchartsAdapter=I.HighchartsAdapter||a&&{init:function(b){var e,c=a.fx,d=c.step,f=a.Tween,g=f&&f.propHooks;e=a.cssHooks.opacity,a.extend(a.easing,{easeOutQuad:function(a,b,c,d,e){return-d*(b/=e)*(b-2)+c}}),a.each(["cur","_default","width","height","opacity"],function(a,b){var k,e=d;"cur"===b?e=c.prototype:"_default"===b&&f&&(e=g[b],b="set"),(k=e[b])&&(e[b]=function(c){var d,c=a?c:this;return"align"!==c.prop?(d=c.elem,d.attr?d.attr(c.prop,"cur"===b?t:c.now):k.apply(this,arguments)):void 0})}),Ma(e,"get",function(a,b,c){return b.attr?b.opacity||0:a.call(this,b,c)}),e=function(a){var d,c=a.elem;a.started||(d=b.init(c,c.d,c.toD),a.start=d[0],a.end=d[1],a.started=!0),c.attr("d",b.step(a.start,a.end,a.pos,c.toD))},f?g.d={set:e}:d.d=e,this.each=Array.prototype.forEach?function(a,b){return Array.prototype.forEach.call(a,b)}:function(a,b){for(var c=0,d=a.length;d>c;c++)if(b.call(a[c],a[c],c,a)===!1)return c},a.fn.highcharts=function(){var c,d,a="Chart",b=arguments;return this[0]&&(Fa(b[0])&&(a=b[0],b=Array.prototype.slice.call(b,1)),c=b[0],c!==t&&(c.chart=c.chart||{},c.chart.renderTo=this[0],new R[a](c,b[1]),d=this),c===t&&(d=V[H(this[0],"data-highcharts-chart")])),d}},getScript:a.getScript,inArray:a.inArray,adapterRun:function(b,c){return a(b)[c]()},grep:a.grep,map:function(a,c){for(var d=[],e=0,f=a.length;f>e;e++)d[e]=c.call(a[e],a[e],e,a);return d},offset:function(b){return a(b).offset()},addEvent:function(b,c,d){a(b).bind(c,d)},removeEvent:function(b,c,d){var e=y.removeEventListener?"removeEventListener":"detachEvent";y[e]&&b&&!b[e]&&(b[e]=function(){}),a(b).unbind(c,d)},fireEvent:function(b,c,d,e){var h,f=a.Event(c),g="detached"+c;!Aa&&d&&(delete d.layerX,delete d.layerY,delete d.returnValue),q(f,d),b[c]&&(b[g]=b[c],b[c]=null),a.each(["preventDefault","stopPropagation"],function(a,b){var c=f[b];f[b]=function(){try{c.call(f)}catch(a){"preventDefault"===b&&(h=!0)}}}),a(b).trigger(f),b[g]&&(b[c]=b[g],b[g]=null),e&&!f.isDefaultPrevented()&&!h&&e(f)},washMouseEvent:function(a){var c=a.originalEvent||a;return c.pageX===t&&(c.pageX=a.pageX,c.pageY=a.pageY),c},animate:function(b,c,d){var e=a(b);b.style||(b.style={}),c.d&&(b.toD=c.d,c.d=1),e.stop(),c.opacity!==t&&b.attr&&(c.opacity+="px"),e.animate(c,d)},stop:function(b){a(b).stop()}}}(I.jQuery);var S=I.HighchartsAdapter,N=S||{};S&&S.init.call(S,ub);var jb=N.adapterRun,Qb=N.getScript,Da=N.inArray,p=N.each,vb=N.grep,Rb=N.offset,Ua=N.map,K=N.addEvent,W=N.removeEvent,D=N.fireEvent,Sb=N.washMouseEvent,kb=N.animate,bb=N.stop,N={enabled:!0,x:0,y:15,style:{color:"#606060",cursor:"default",fontSize:"11px"}};E={colors:"#7cb5ec,#434348,#90ed7d,#f7a35c,#8085e9,#f15c80,#e4d354,#8085e8,#8d4653,#91e8e1".split(","),symbols:["circle","diamond","square","triangle","triangle-down"],lang:{loading:"Loading...",months:"January,February,March,April,May,June,July,August,September,October,November,December".split(","),shortMonths:"Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec".split(","),weekdays:"Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday".split(","),decimalPoint:".",numericSymbols:"k,M,G,T,P,E".split(","),resetZoom:"Reset zoom",resetZoomTitle:"Reset zoom level 1:1",thousandsSep:","},global:{useUTC:!0,canvasToolsURL:"http://code.highcharts.com/4.0.1/modules/canvas-tools.js",VMLRadialGradientURL:"http://code.highcharts.com/4.0.1/gfx/vml-radial-gradient.png"},chart:{borderColor:"#4572A7",borderRadius:0,defaultSeriesType:"line",ignoreHiddenSeries:!0,spacing:[10,10,15,10],backgroundColor:"#FFFFFF",plotBorderColor:"#C0C0C0",resetZoomButton:{theme:{zIndex:20},position:{align:"right",x:-10,y:10}}},title:{text:"Chart title",align:"center",margin:15,style:{color:"#333333",fontSize:"18px"}},subtitle:{text:"",align:"center",style:{color:"#555555"}},plotOptions:{line:{allowPointSelect:!1,showCheckbox:!1,animation:{duration:1e3},events:{},lineWidth:2,marker:{lineWidth:0,radius:4,lineColor:"#FFFFFF",states:{hover:{enabled:!0},select:{fillColor:"#FFFFFF",lineColor:"#000000",lineWidth:2}}},point:{events:{}},dataLabels:w(N,{align:"center",enabled:!1,formatter:function(){return null===this.y?"":Ga(this.y,-1)},verticalAlign:"bottom",y:0}),cropThreshold:300,pointRange:0,states:{hover:{marker:{},halo:{size:10,opacity:.25}},select:{marker:{}}},stickyTracking:!0,turboThreshold:1e3}},labels:{style:{position:"absolute",color:"#3E576F"}},legend:{enabled:!0,align:"center",layout:"horizontal",labelFormatter:function(){return this.name},borderColor:"#909090",borderRadius:0,navigation:{activeColor:"#274b6d",inactiveColor:"#CCC"},shadow:!1,itemStyle:{color:"#333333",fontSize:"12px",fontWeight:"bold"},itemHoverStyle:{color:"#000"},itemHiddenStyle:{color:"#CCC"},itemCheckboxStyle:{position:"absolute",width:"13px",height:"13px"},symbolPadding:5,verticalAlign:"bottom",x:0,y:0,title:{style:{fontWeight:"bold"}}},loading:{labelStyle:{fontWeight:"bold",position:"relative",top:"1em"},style:{position:"absolute",backgroundColor:"white",opacity:.5,textAlign:"center"}},tooltip:{enabled:!0,animation:aa,backgroundColor:"rgba(249, 249, 249, .85)",borderWidth:1,borderRadius:3,dateTimeLabelFormats:{millisecond:"%A, %b %e, %H:%M:%S.%L",second:"%A, %b %e, %H:%M:%S",minute:"%A, %b %e, %H:%M",hour:"%A, %b %e, %H:%M",day:"%A, %b %e, %Y",week:"Week from %A, %b %e, %Y",month:"%B %Y",year:"%Y"},headerFormat:'<span style="font-size: 10px">{point.key}</span><br/>',pointFormat:'<span style="color:{series.color}">â—</span> {series.name}: <b>{point.y}</b><br/>',shadow:!0,snap:Jb?25:10,style:{color:"#333333",cursor:"default",fontSize:"12px",padding:"8px",whiteSpace:"nowrap"}},credits:{enabled:!0,text:"Highcharts.com",href:"http://www.highcharts.com",position:{align:"right",x:-10,verticalAlign:"bottom",y:-5},style:{cursor:"pointer",color:"#909090",fontSize:"9px"}}};var ba=E.plotOptions,S=ba.line;Cb();var Tb=/rgba\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]?(?:\.[0-9]+)?)\s*\)/,Ub=/#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/,Vb=/rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/,ya=function(a){var c,d,b=[];return function(a){a&&a.stops?d=Ua(a.stops,function(a){return ya(a[1])}):(c=Tb.exec(a))?b=[z(c[1]),z(c[2]),z(c[3]),parseFloat(c[4],10)]:(c=Ub.exec(a))?b=[z(c[1],16),z(c[2],16),z(c[3],16),1]:(c=Vb.exec(a))&&(b=[z(c[1]),z(c[2]),z(c[3]),1])}(a),{get:function(c){var f;return d?(f=w(a),f.stops=[].concat(f.stops),p(d,function(a,b){f.stops[b]=[f.stops[b][0],a.get(c)]})):f=b&&!isNaN(b[0])?"rgb"===c?"rgb("+b[0]+","+b[1]+","+b[2]+")":"a"===c?b[3]:"rgba("+b.join(",")+")":a,f},brighten:function(a){if(d)p(d,function(b){b.brighten(a)});else if(ha(a)&&0!==a){var c;for(c=0;3>c;c++)b[c]+=z(255*a),b[c]<0&&(b[c]=0),b[c]>255&&(b[c]=255)}return this},rgba:b,setOpacity:function(a){return b[3]=a,this}}};P.prototype={init:function(a,b){this.element="span"===b?Y(b):y.createElementNS(xa,b),this.renderer=a},opacity:1,animate:function(a,b,c){b=m(b,va,!0),bb(this),b?(b=w(b,{}),c&&(b.complete=c),kb(this,a,b)):(this.attr(a),c&&c())},colorGradient:function(a,b,c){var e,f,g,h,i,j,k,l,o,n,d=this.renderer,s=[];if(a.linearGradient?f="linearGradient":a.radialGradient&&(f="radialGradient"),f){g=a[f],h=d.gradients,j=a.stops,o=c.radialReference,La(g)&&(a[f]=g={x1:g[0],y1:g[1],x2:g[2],y2:g[3],gradientUnits:"userSpaceOnUse"}),"radialGradient"===f&&o&&!r(g.gradientUnits)&&(g=w(g,{cx:o[0]-o[2]/2+g.cx*o[2],cy:o[1]-o[2]/2+g.cy*o[2],r:g.r*o[2],gradientUnits:"userSpaceOnUse"}));for(n in g)"id"!==n&&s.push(n,g[n]);for(n in j)s.push(j[n]);s=s.join(","),h[s]?a=h[s].attr("id"):(g.id=a="highcharts-"+tb++,h[s]=i=d.createElement(f).attr(g).add(d.defs),i.stops=[],p(j,function(a){0===a[1].indexOf("rgba")?(e=ya(a[1]),k=e.get("rgb"),l=e.get("a")):(k=a[1],l=1),a=d.createElement("stop").attr({offset:a[0],"stop-color":k,"stop-opacity":l}).add(i),i.stops.push(a)})),c.setAttribute(b,"url("+d.url+"#"+a+")")}},attr:function(a,b){var c,d,f,h,e=this.element,g=this;if("string"==typeof a&&b!==t&&(c=a,a={},a[c]=b),"string"==typeof a)g=(this[a+"Getter"]||this._defaultGetter).call(this,a,e);else{for(c in a)d=a[c],h=!1,this.symbolName&&/^(x|y|width|height|r|start|end|innerR|anchorX|anchorY)/.test(c)&&(f||(this.symbolAttr(a),f=!0),h=!0),!this.rotation||"x"!==c&&"y"!==c||(this.doTransform=!0),h||(this[c+"Setter"]||this._defaultSetter).call(this,d,c,e),this.shadows&&/^(width|height|visibility|x|y|d|transform|cx|cy|r)$/.test(c)&&this.updateShadows(c,d);this.doTransform&&(this.updateTransform(),this.doTransform=!1)}return g},updateShadows:function(a,b){for(var c=this.shadows,d=c.length;d--;)c[d].setAttribute(a,"height"===a?v(b-(c[d].cutHeight||0),0):"d"===a?this.d:b)},addClass:function(a){var b=this.element,c=H(b,"class")||"";return-1===c.indexOf(a)&&H(b,"class",c+" "+a),this},symbolAttr:function(a){var b=this;p("x,y,r,start,end,width,height,innerR,anchorX,anchorY".split(","),function(c){b[c]=m(a[c],b[c])}),b.attr({d:b.renderer.symbols[b.symbolName](b.x,b.y,b.width,b.height,b)})},clip:function(a){return this.attr("clip-path",a?"url("+this.renderer.url+"#"+a.id+")":Q)},crisp:function(a){var b,d,c={},e=a.strokeWidth||this.strokeWidth||this.attr&&this.attr("stroke-width")||0;d=u(e)%2/2,a.x=T(a.x||this.x||0)+d,a.y=T(a.y||this.y||0)+d,a.width=T((a.width||this.width||0)-2*d),a.height=T((a.height||this.height||0)-2*d),a.strokeWidth=e;for(b in a)this[b]!==a[b]&&(this[b]=c[b]=a[b]);return c},css:function(a){var e,f,b=this.styles,c={},d=this.element,g="";if(e=!b,a&&a.color&&(a.fill=a.color),b)for(f in a)a[f]!==b[f]&&(c[f]=a[f],e=!0);if(e){if(e=this.textWidth=a&&a.width&&"text"===d.nodeName.toLowerCase()&&z(a.width),b&&(a=q(b,c)),this.styles=a,e&&(fa||!aa&&this.renderer.forExport)&&delete a.width,Aa&&!aa)G(this.element,a);else{b=function(a,b){return"-"+b.toLowerCase()};for(f in a)g+=f.replace(/([A-Z])/g,b)+":"+a[f]+";";H(d,"style",g)}e&&this.added&&this.renderer.buildText(this)}return this},on:function(a,b){var c=this,d=c.element;return $a&&"click"===a?(d.ontouchstart=function(a){c.touchEventFired=Date.now(),a.preventDefault(),b.call(d,a)},d.onclick=function(a){(-1===wa.indexOf("Android")||Date.now()-(c.touchEventFired||0)>1100)&&b.call(d,a)}):d["on"+a]=b,this},setRadialReference:function(a){return this.element.radialReference=a,this},translate:function(a,b){return this.attr({translateX:a,translateY:b})},invert:function(){return this.inverted=!0,this.updateTransform(),this},updateTransform:function(){var a=this.translateX||0,b=this.translateY||0,c=this.scaleX,d=this.scaleY,e=this.inverted,f=this.rotation,g=this.element;e&&(a+=this.attr("width"),b+=this.attr("height")),a=["translate("+a+","+b+")"],e?a.push("rotate(90) scale(-1,1)"):f&&a.push("rotate("+f+" "+(g.getAttribute("x")||0)+" "+(g.getAttribute("y")||0)+")"),(r(c)||r(d))&&a.push("scale("+m(c,1)+" "+m(d,1)+")"),a.length&&g.setAttribute("transform",a.join(" "))},toFront:function(){var a=this.element;return a.parentNode.appendChild(a),this},align:function(a,b,c){var d,e,f,g,h={};return e=this.renderer,f=e.alignedObjects,a?(this.alignOptions=a,this.alignByTranslate=b,(!c||Fa(c))&&(this.alignTo=d=c||"renderer",ja(f,this),f.push(this),c=null)):(a=this.alignOptions,b=this.alignByTranslate,d=this.alignTo),c=m(c,e[d],e),d=a.align,e=a.verticalAlign,f=(c.x||0)+(a.x||0),g=(c.y||0)+(a.y||0),("right"===d||"center"===d)&&(f+=(c.width-(a.width||0))/{right:1,center:2}[d]),h[b?"translateX":"x"]=u(f),("bottom"===e||"middle"===e)&&(g+=(c.height-(a.height||0))/({bottom:1,middle:2}[e]||1)),h[b?"translateY":"y"]=u(g),this[this.placed?"animate":"attr"](h),this.placed=!0,this.alignAttr=h,this},getBBox:function(){var c,d,a=this.bBox,b=this.renderer,e=this.rotation;c=this.element;var f=this.styles,g=e*Ca;d=this.textStr;var h;if((""===d||Ob.test(d))&&(h="num."+d.toString().length+(f?"|"+f.fontSize+"|"+f.fontFamily:"")),h&&(a=b.cache[h]),!a){if(c.namespaceURI===xa||b.forExport){try{a=c.getBBox?q({},c.getBBox()):{width:c.offsetWidth,height:c.offsetHeight}}catch(i){}(!a||a.width<0)&&(a={width:0,height:0})}else a=this.htmlGetBBox();b.isSVG&&(c=a.width,d=a.height,Aa&&f&&"11px"===f.fontSize&&"16.9"===d.toPrecision(3)&&(a.height=d=14),e&&(a.width=M(d*ea(g))+M(c*Z(g)),a.height=M(d*Z(g))+M(c*ea(g)))),this.bBox=a,h&&(b.cache[h]=a)}return a},show:function(a){return a&&this.element.namespaceURI===xa?(this.element.removeAttribute("visibility"),this):this.attr({visibility:a?"inherit":"visible"})},hide:function(){return this.attr({visibility:"hidden"})},fadeOut:function(a){var b=this;b.animate({opacity:0},{duration:a||150,complete:function(){b.hide()}})},add:function(a){var g,h,b=this.renderer,c=a||b,d=c.element||b.box,e=this.element,f=this.zIndex;if(a&&(this.parentGroup=a),this.parentInverted=a&&a.inverted,void 0!==this.textStr&&b.buildText(this),f&&(c.handleZ=!0,f=z(f)),c.handleZ)for(a=d.childNodes,g=0;g<a.length;g++)if(b=a[g],c=H(b,"zIndex"),b!==e&&(z(c)>f||!r(f)&&r(c))){d.insertBefore(e,b),h=!0;break}return h||d.appendChild(e),this.added=!0,this.onAdd&&this.onAdd(),this},safeRemoveChild:function(a){var b=a.parentNode;b&&b.removeChild(a)},destroy:function(){var e,f,a=this,b=a.element||{},c=a.shadows,d=a.renderer.isSVG&&"SPAN"===b.nodeName&&a.parentGroup;if(b.onclick=b.onmouseout=b.onmouseover=b.onmousemove=b.point=null,bb(a),a.clipPath&&(a.clipPath=a.clipPath.destroy()),a.stops){for(f=0;f<a.stops.length;f++)a.stops[f]=a.stops[f].destroy();a.stops=null}for(a.safeRemoveChild(b),c&&p(c,function(b){a.safeRemoveChild(b)});d&&0===d.div.childNodes.length;)b=d.parentGroup,a.safeRemoveChild(d.div),delete d.div,d=b;a.alignTo&&ja(a.renderer.alignedObjects,a);for(e in a)delete a[e];return null},shadow:function(a,b,c){var e,f,h,i,j,k,d=[],g=this.element;if(a){for(i=m(a.width,3),j=(a.opacity||.15)/i,k=this.parentInverted?"(-1,-1)":"("+m(a.offsetX,1)+", "+m(a.offsetY,1)+")",e=1;i>=e;e++)f=g.cloneNode(0),h=2*i+1-2*e,H(f,{isShadow:"true",stroke:a.color||"black","stroke-opacity":j*e,"stroke-width":h,transform:"translate"+k,fill:Q}),c&&(H(f,"height",v(H(f,"height")-h,0)),f.cutHeight=h),b?b.element.appendChild(f):g.parentNode.insertBefore(f,g),d.push(f);this.shadows=d}return this},xGetter:function(a){return"circle"===this.element.nodeName&&(a={x:"cx",y:"cy"}[a]||a),this._defaultGetter(a)},_defaultGetter:function(a){return a=m(this[a],this.element?this.element.getAttribute(a):null,0),/^[0-9\.]+$/.test(a)&&(a=parseFloat(a)),a},dSetter:function(a,b,c){a&&a.join&&(a=a.join(" ")),/(NaN| {2}|^$)/.test(a)&&(a="M 0 0"),c.setAttribute(b,a),this[b]=a},dashstyleSetter:function(a){var b;if(a=a&&a.toLowerCase()){for(a=a.replace("shortdashdotdot","3,1,1,1,1,1,").replace("shortdashdot","3,1,1,1").replace("shortdot","1,1,").replace("shortdash","3,1,").replace("longdash","8,3,").replace(/dot/g,"1,3,").replace("dash","4,3,").replace(/,$/,"").split(","),b=a.length;b--;)a[b]=z(a[b])*this.element.getAttribute("stroke-width");a=a.join(","),this.element.setAttribute("stroke-dasharray",a)}},alignSetter:function(a){this.element.setAttribute("text-anchor",{left:"start",center:"middle",right:"end"}[a])},opacitySetter:function(a,b,c){this[b]=a,c.setAttribute(b,a)},"stroke-widthSetter":function(a,b,c){0===a&&(a=1e-5),this.strokeWidth=a,c.setAttribute(b,a)},titleSetter:function(a){var b=this.element.getElementsByTagName("title")[0];b||(b=y.createElementNS(xa,"title"),this.element.appendChild(b)),b.textContent=a},textSetter:function(a){a!==this.textStr&&(delete this.bBox,this.textStr=a,this.added&&this.renderer.buildText(this))},fillSetter:function(a,b,c){"string"==typeof a?c.setAttribute(b,a):a&&this.colorGradient(a,b,c)},zIndexSetter:function(a,b,c){c.setAttribute(b,a),this[b]=a},_defaultSetter:function(a,b,c){c.setAttribute(b,a)}},P.prototype.yGetter=P.prototype.xGetter,P.prototype.translateXSetter=P.prototype.translateYSetter=P.prototype.rotationSetter=P.prototype.verticalAlignSetter=P.prototype.scaleXSetter=P.prototype.scaleYSetter=function(a,b){this[b]=a,this.doTransform=!0},P.prototype.strokeSetter=P.prototype.fillSetter;var ta=function(){this.init.apply(this,arguments)};ta.prototype={Element:P,init:function(a,b,c,d,e){var g,f=location,d=this.createElement("svg").attr({version:"1.1"}).css(this.getStyle(d));g=d.element,a.appendChild(g),-1===a.innerHTML.indexOf("xmlns")&&H(g,"xmlns",xa),this.isSVG=!0,this.box=g,this.boxWrapper=d,this.alignedObjects=[],this.url=(Ta||ib)&&y.getElementsByTagName("base").length?f.href.replace(/#.*?$/,"").replace(/([\('\)])/g,"\\$1").replace(/ /g,"%20"):"",this.createElement("desc").add().element.appendChild(y.createTextNode("Created with Highcharts 4.0.1")),this.defs=this.createElement("defs").add(),this.forExport=e,this.gradients={},this.cache={},this.setSize(b,c,!1);var h;Ta&&a.getBoundingClientRect&&(this.subPixelFix=b=function(){G(a,{left:0,top:0}),h=a.getBoundingClientRect(),G(a,{left:Ka(h.left)-h.left+"px",top:Ka(h.top)-h.top+"px"})},b(),K(I,"resize",b))},getStyle:function(a){return this.style=q({fontFamily:'"Lucida Grande", "Lucida Sans Unicode", Arial, Helvetica, sans-serif',fontSize:"12px"},a)},isHidden:function(){return!this.boxWrapper.getBBox().width},destroy:function(){var a=this.defs;return this.box=null,this.boxWrapper=this.boxWrapper.destroy(),Oa(this.gradients||{}),this.gradients=null,a&&(this.defs=a.destroy()),this.subPixelFix&&W(I,"resize",this.subPixelFix),this.alignedObjects=null},createElement:function(a){var b=new this.Element;return b.init(this,a),b},draw:function(){},buildText:function(a){for(var h,i,b=a.element,c=this,d=c.forExport,e=m(a.textStr,"").toString(),f=-1!==e.indexOf("<"),g=b.childNodes,j=H(b,"x"),k=a.styles,l=a.textWidth,o=k&&k.lineHeight,n=g.length,s=function(a){return o?z(o):c.fontMetrics(/(px|em)$/.test(a&&a.style.fontSize)?a.style.fontSize:k&&k.fontSize||c.style.fontSize||12).h};n--;)b.removeChild(g[n]);f||-1!==e.indexOf(" ")?(h=/<.*style="([^"]+)".*>/,i=/<.*href="(http[^"]+)".*>/,l&&!a.added&&this.box.appendChild(b),e=f?e.replace(/<(b|strong)>/g,'<span style="font-weight:bold">').replace(/<(i|em)>/g,'<span style="font-style:italic">').replace(/<a/g,"<span").replace(/<\/(b|strong|i|em|a)>/g,"</span>").split(/<br.*?>/g):[e],""===e[e.length-1]&&e.pop(),p(e,function(e,f){var g,n=0,e=e.replace(/<span/g,"|||<span").replace(/<\/span>/g,"</span>|||");g=e.split("|||"),p(g,function(e){if(""!==e||1===g.length){var p,o={},m=y.createElementNS(xa,"tspan");if(h.test(e)&&(p=e.match(h)[1].replace(/(;| |^)color([ :])/,"$1fill$2"),H(m,"style",p)),i.test(e)&&!d&&(H(m,"onclick",'location.href="'+e.match(i)[1]+'"'),G(m,{cursor:"pointer"})),e=(e.replace(/<(.|\n)*?>/g,"")||" ").replace(/</g,"<").replace(/>/g,">")," "!==e&&(m.appendChild(y.createTextNode(e)),n?o.dx=0:f&&null!==j&&(o.x=j),H(m,o),!n&&f&&(!aa&&d&&G(m,{display:"block"}),H(m,"dy",s(m),ib&&m.offsetHeight)),b.appendChild(m),n++,l))for(var $,r,e=e.replace(/([^\^])-/g,"$1- ").split(" "),o=e.length>1&&"nowrap"!==k.whiteSpace,B=a._clipHeight,q=[],v=s(),t=1;o&&(e.length||q.length);)delete a.bBox,$=a.getBBox(),r=$.width,!aa&&c.forExport&&(r=c.measureSpanWidth(m.firstChild.data,a.styles)),$=r>l,$&&1!==e.length?(m.removeChild(m.firstChild),q.unshift(e.pop())):(e=q,q=[],e.length&&(t++,B&&t*v>B?(e=["..."],a.attr("title",a.textStr)):(m=y.createElementNS(xa,"tspan"),H(m,{dy:v,x:j}),p&&H(m,"style",p),b.appendChild(m),r>l&&(l=r)))),e.length&&m.appendChild(y.createTextNode(e.join(" ").replace(/- /g,"-")))}})})):b.appendChild(y.createTextNode(e))},button:function(a,b,c,d,e,f,g,h,i){var l,o,n,s,m,p,j=this.label(a,b,c,i,null,null,null,null,"button"),k=0,a={x1:0,y1:0,x2:0,y2:1},e=w({"stroke-width":1,stroke:"#CCCCCC",fill:{linearGradient:a,stops:[[0,"#FEFEFE"],[1,"#F6F6F6"]]},r:2,padding:5,style:{color:"black"}},e);return n=e.style,delete e.style,f=w(e,{stroke:"#68A",fill:{linearGradient:a,stops:[[0,"#FFF"],[1,"#ACF"]]}},f),s=f.style,delete f.style,g=w(e,{stroke:"#68A",fill:{linearGradient:a,stops:[[0,"#9BD"],[1,"#CDF"]]}},g),m=g.style,delete g.style,h=w(e,{style:{color:"#CCC"}},h),p=h.style,delete h.style,K(j.element,Aa?"mouseover":"mouseenter",function(){3!==k&&j.attr(f).css(s)}),K(j.element,Aa?"mouseout":"mouseleave",function(){3!==k&&(l=[e,f,g][k],o=[n,s,m][k],j.attr(l).css(o))}),j.setState=function(a){(j.state=k=a)?2===a?j.attr(g).css(m):3===a&&j.attr(h).css(p):j.attr(e).css(n)},j.on("click",function(){3!==k&&d.call(j)}).attr(e).css(q({cursor:"default"},n))},crispLine:function(a,b){return a[1]===a[4]&&(a[1]=a[4]=u(a[1])-b%2/2),a[2]===a[5]&&(a[2]=a[5]=u(a[2])+b%2/2),a},path:function(a){var b={fill:Q};return La(a)?b.d=a:ca(a)&&q(b,a),this.createElement("path").attr(b)},circle:function(a,b,c){return a=ca(a)?a:{x:a,y:b,r:c},b=this.createElement("circle"),b.xSetter=function(a){this.element.setAttribute("cx",a)},b.ySetter=function(a){this.element.setAttribute("cy",a)},b.attr(a)},arc:function(a,b,c,d,e,f){return ca(a)&&(b=a.y,c=a.r,d=a.innerR,e=a.start,f=a.end,a=a.x),a=this.symbol("arc",a||0,b||0,c||0,c||0,{innerR:d||0,start:e||0,end:f||0}),a.r=c,a},rect:function(a,b,c,d,e,f){var e=ca(a)?a.r:e,g=this.createElement("rect"),a=ca(a)?a:a===t?{}:{x:a,y:b,width:v(c,0),height:v(d,0)};return f!==t&&(a.strokeWidth=f,a=g.crisp(a)),e&&(a.r=e),g.rSetter=function(a){H(this.element,{rx:a,ry:a})},g.attr(a)},setSize:function(a,b,c){var d=this.alignedObjects,e=d.length;for(this.width=a,this.height=b,this.boxWrapper[m(c,!0)?"animate":"attr"]({width:a,height:b});e--;)d[e].align()},g:function(a){var b=this.createElement("g");return r(a)?b.attr({"class":"highcharts-"+a}):b},image:function(a,b,c,d,e){var f={preserveAspectRatio:Q};return arguments.length>1&&q(f,{x:b,y:c,width:d,height:e}),f=this.createElement("image").attr(f),f.element.setAttributeNS?f.element.setAttributeNS("http://www.w3.org/1999/xlink","href",a):f.element.setAttribute("hc-svg-href",a),f},symbol:function(a,b,c,d,e,f){var g,j,k,h=this.symbols[a],h=h&&h(u(b),u(c),d,e,f),i=/^url\((.*?)\)$/;return h?(g=this.path(h),q(g,{symbolName:a,x:b,y:c,width:d,height:e}),f&&q(g,f)):i.test(a)&&(k=function(a,b){a.element&&(a.attr({width:b[0],height:b[1]}),a.alignByTranslate||a.translate(u((d-b[0])/2),u((e-b[1])/2)))},j=a.match(i)[1],a=Kb[j],g=this.image(j).attr({x:b,y:c}),g.isImg=!0,a?k(g,a):(g.attr({width:0,height:0}),Y("img",{onload:function(){k(g,Kb[j]=[this.width,this.height])},src:j}))),g},symbols:{circle:function(a,b,c,d){var e=.166*c;return["M",a+c/2,b,"C",a+c+e,b,a+c+e,b+d,a+c/2,b+d,"C",a-e,b+d,a-e,b,a+c/2,b,"Z"]},square:function(a,b,c,d){return["M",a,b,"L",a+c,b,a+c,b+d,a,b+d,"Z"]},triangle:function(a,b,c,d){return["M",a+c/2,b,"L",a+c,b+d,a,b+d,"Z"]},"triangle-down":function(a,b,c,d){return["M",a,b,"L",a+c,b,a+c/2,b+d,"Z"]},diamond:function(a,b,c,d){return["M",a+c/2,b,"L",a+c,b+d/2,a+c/2,b+d,a,b+d/2,"Z"]},arc:function(a,b,c,d,e){var f=e.start,c=e.r||c||d,g=e.end-.001,d=e.innerR,h=e.open,i=Z(f),j=ea(f),k=Z(g),g=ea(g),e=e.end-f<ma?0:1;return["M",a+c*i,b+c*j,"A",c,c,0,e,1,a+c*k,b+c*g,h?"M":"L",a+d*k,b+d*g,"A",d,d,0,e,0,a+d*i,b+d*j,h?"":"Z"]},callout:function(a,b,c,d,e){var f=C(e&&e.r||0,c,d),g=f+6,h=e&&e.anchorX,i=e&&e.anchorY,e=u(e.strokeWidth||0)%2/2;return a+=e,b+=e,e=["M",a+f,b,"L",a+c-f,b,"C",a+c,b,a+c,b,a+c,b+f,"L",a+c,b+d-f,"C",a+c,b+d,a+c,b+d,a+c-f,b+d,"L",a+f,b+d,"C",a,b+d,a,b+d,a,b+d-f,"L",a,b+f,"C",a,b,a,b,a+f,b],h&&h>c&&i>b+g&&b+d-g>i?e.splice(13,3,"L",a+c,i-6,a+c+6,i,a+c,i+6,a+c,b+d-f):h&&0>h&&i>b+g&&b+d-g>i?e.splice(33,3,"L",a,i+6,a-6,i,a,i-6,a,b+f):i&&i>d&&h>a+g&&a+c-g>h?e.splice(23,3,"L",h+6,b+d,h,b+d+6,h-6,b+d,a+f,b+d):i&&0>i&&h>a+g&&a+c-g>h&&e.splice(3,3,"L",h-6,b,h,b-6,h+6,b,c-f,b),e}},clipRect:function(a,b,c,d){var e="highcharts-"+tb++,f=this.createElement("clipPath").attr({id:e}).add(this.defs),a=this.rect(a,b,c,d,0).add(f);return a.id=e,a.clipPath=f,a
|
2 |
+
},text:function(a,b,c,d){var e=fa||!aa&&this.forExport,f={};return d&&!this.forExport?this.html(a,b,c):(f.x=Math.round(b||0),c&&(f.y=Math.round(c)),(a||0===a)&&(f.text=a),a=this.createElement("text").attr(f),e&&a.css({position:"absolute"}),d||(a.xSetter=function(a,b,c){var e,f,d=c.childNodes;for(f=1;f<d.length;f++)e=d[f],e.getAttribute("x")===c.getAttribute("x")&&e.setAttribute("x",a);c.setAttribute(b,a)}),a)},fontMetrics:function(a){var a=a||this.style.fontSize,a=/px/.test(a)?z(a):/em/.test(a)?12*parseFloat(a):12,a=24>a?a+4:u(1.2*a),b=u(.8*a);return{h:a,b:b}},label:function(a,b,c,d,e,f,g,h,i){function j(){var a,b;a=s.element.style,J=(void 0===Va||void 0===wb||n.styles.textAlign)&&s.textStr&&s.getBBox(),n.width=(Va||J.width||0)+2*x+v,n.height=(wb||J.height||0)+2*x,na=x+o.fontMetrics(a&&a.fontSize).b,z&&(m||(a=u(-L*x),b=h?-na:0,n.box=m=d?o.symbol(d,a,b,n.width,n.height,B):o.rect(a,b,n.width,n.height,0,B[Pb]),m.attr("fill",Q).add(n)),m.isImg||m.attr(q({width:u(n.width),height:u(n.height)},B)),B=null)}function k(){var c,a=n.styles,a=a&&a.textAlign,b=v+x*(1-L);c=h?0:na,r(Va)&&J&&("center"===a||"right"===a)&&(b+={center:.5,right:1}[a]*(Va-J.width)),(b!==s.x||c!==s.y)&&(s.attr("x",b),c!==t&&s.attr("y",c)),s.x=b,s.y=c}function l(a,b){m?m.attr(a,b):B[a]=b}var m,J,Va,wb,xb,yb,na,z,o=this,n=o.g(i),s=o.text("",0,0,g).attr({zIndex:1}),L=0,x=3,v=0,y=0,B={};n.onAdd=function(){s.add(n),n.attr({text:a||"",x:b,y:c}),m&&r(e)&&n.attr({anchorX:e,anchorY:f})},n.widthSetter=function(a){Va=a},n.heightSetter=function(a){wb=a},n.paddingSetter=function(a){r(a)&&a!==x&&(x=a,k())},n.paddingLeftSetter=function(a){r(a)&&a!==v&&(v=a,k())},n.alignSetter=function(a){L={left:0,center:.5,right:1}[a]},n.textSetter=function(a){a!==t&&s.textSetter(a),j(),k()},n["stroke-widthSetter"]=function(a,b){a&&(z=!0),y=a%2/2,l(b,a)},n.strokeSetter=n.fillSetter=n.rSetter=function(a,b){"fill"===b&&a&&(z=!0),l(b,a)},n.anchorXSetter=function(a,b){e=a,l(b,a+y-xb)},n.anchorYSetter=function(a,b){f=a,l(b,a-yb)},n.xSetter=function(a){n.x=a,L&&(a-=L*((Va||J.width)+x)),xb=u(a),n.attr("translateX",xb)},n.ySetter=function(a){yb=n.y=u(a),n.attr("translateY",yb)};var A=n.css;return q(n,{css:function(a){if(a){var b={},a=w(a);p("fontSize,fontWeight,fontFamily,color,lineHeight,width,textDecoration,textShadow".split(","),function(c){a[c]!==t&&(b[c]=a[c],delete a[c])}),s.css(b)}return A.call(n,a)},getBBox:function(){return{width:J.width+2*x,height:J.height+2*x,x:J.x-x,y:J.y-x}},shadow:function(a){return m&&m.shadow(a),n},destroy:function(){W(n.element,"mouseenter"),W(n.element,"mouseleave"),s&&(s=s.destroy()),m&&(m=m.destroy()),P.prototype.destroy.call(n),n=o=j=k=l=null}})}},Za=ta,q(P.prototype,{htmlCss:function(a){var b=this.element;return(b=a&&"SPAN"===b.tagName&&a.width)&&(delete a.width,this.textWidth=b,this.updateTransform()),this.styles=q(this.styles,a),G(this.element,a),this},htmlGetBBox:function(){var a=this.element,b=this.bBox;return b||("text"===a.nodeName&&(a.style.position="absolute"),b=this.bBox={x:a.offsetLeft,y:a.offsetTop,width:a.offsetWidth,height:a.offsetHeight}),b},htmlUpdateTransform:function(){if(this.added){var a=this.renderer,b=this.element,c=this.translateX||0,d=this.translateY||0,e=this.x||0,f=this.y||0,g=this.textAlign||"left",h={left:0,center:.5,right:1}[g],i=this.shadows;if(G(b,{marginLeft:c,marginTop:d}),i&&p(i,function(a){G(a,{marginLeft:c+1,marginTop:d+1})}),this.inverted&&p(b.childNodes,function(c){a.invertChild(c,b)}),"SPAN"===b.tagName){var k,j=this.rotation,l=z(this.textWidth),o=[j,g,b.innerHTML,this.textWidth].join(",");o!==this.cTT&&(k=a.fontMetrics(b.style.fontSize).b,r(j)&&this.setSpanRotation(j,h,k),i=m(this.elemWidth,b.offsetWidth),i>l&&/[ \-]/.test(b.textContent||b.innerText)&&(G(b,{width:l+"px",display:"block",whiteSpace:"normal"}),i=l),this.getSpanCorrection(i,k,h,j,g)),G(b,{left:e+(this.xCorr||0)+"px",top:f+(this.yCorr||0)+"px"}),ib&&(k=b.offsetHeight),this.cTT=o}}else this.alignOnAdd=!0},setSpanRotation:function(a,b,c){var d={},e=Aa?"-ms-transform":ib?"-webkit-transform":Ta?"MozTransform":Ib?"-o-transform":"";d[e]=d.transform="rotate("+a+"deg)",d[e+(Ta?"Origin":"-origin")]=d.transformOrigin=100*b+"% "+c+"px",G(this.element,d)},getSpanCorrection:function(a,b,c){this.xCorr=-a*c,this.yCorr=-b}}),q(ta.prototype,{html:function(a,b,c){var d=this.createElement("span"),e=d.element,f=d.renderer;return d.textSetter=function(a){a!==e.innerHTML&&delete this.bBox,e.innerHTML=this.textStr=a},d.xSetter=d.ySetter=d.alignSetter=d.rotationSetter=function(a,b){"align"===b&&(b="textAlign"),d[b]=a,d.htmlUpdateTransform()},d.attr({text:a,x:u(b),y:u(c)}).css({position:"absolute",whiteSpace:"nowrap",fontFamily:this.style.fontFamily,fontSize:this.style.fontSize}),d.css=d.htmlCss,f.isSVG&&(d.add=function(a){var b,c=f.box.parentNode,j=[];if(this.parentGroup=a){if(b=a.div,!b){for(;a;)j.push(a),a=a.parentGroup;p(j.reverse(),function(a){var d;b=a.div=a.div||Y(Ja,{className:H(a.element,"class")},{position:"absolute",left:(a.translateX||0)+"px",top:(a.translateY||0)+"px"},b||c),d=b.style,q(a,{translateXSetter:function(b,c){d.left=b+"px",a[c]=b,a.doTransform=!0},translateYSetter:function(b,c){d.top=b+"px",a[c]=b,a.doTransform=!0},visibilitySetter:function(a,b){d[b]=a}})})}}else b=c;return b.appendChild(e),d.added=!0,d.alignOnAdd&&d.htmlUpdateTransform(),d}),d}});var X;if(!aa&&!fa){R.VMLElement=X={init:function(a,b){var c=["<",b,' filled="f" stroked="f"'],d=["position: ","absolute",";"],e=b===Ja;("shape"===b||e)&&d.push("left:0;top:0;width:1px;height:1px;"),d.push("visibility: ",e?"hidden":"visible"),c.push(' style="',d.join(""),'"/>'),b&&(c=e||"span"===b||"img"===b?c.join(""):a.prepVML(c),this.element=Y(c)),this.renderer=a},add:function(a){var b=this.renderer,c=this.element,d=b.box,d=a?a.element||a:d;return a&&a.inverted&&b.invertChild(c,d),d.appendChild(c),this.added=!0,this.alignOnAdd&&!this.deferUpdateTransform&&this.updateTransform(),this.onAdd&&this.onAdd(),this},updateTransform:P.prototype.htmlUpdateTransform,setSpanRotation:function(){var a=this.rotation,b=Z(a*Ca),c=ea(a*Ca);G(this.element,{filter:a?["progid:DXImageTransform.Microsoft.Matrix(M11=",b,", M12=",-c,", M21=",c,", M22=",b,", sizingMethod='auto expand')"].join(""):Q})},getSpanCorrection:function(a,b,c,d,e){var i,f=d?Z(d*Ca):1,g=d?ea(d*Ca):0,h=m(this.elemHeight,this.element.offsetHeight);this.xCorr=0>f&&-a,this.yCorr=0>g&&-h,i=0>f*g,this.xCorr+=g*b*(i?1-c:c),this.yCorr-=f*b*(d?i?c:1-c:1),e&&"left"!==e&&(this.xCorr-=a*c*(0>f?-1:1),d&&(this.yCorr-=h*c*(0>g?-1:1)),G(this.element,{textAlign:e}))},pathToVML:function(a){for(var b=a.length,c=[];b--;)ha(a[b])?c[b]=u(10*a[b])-5:"Z"===a[b]?c[b]="x":(c[b]=a[b],!a.isArc||"wa"!==a[b]&&"at"!==a[b]||(c[b+5]===c[b+7]&&(c[b+7]+=a[b+7]>a[b+5]?1:-1),c[b+6]===c[b+8]&&(c[b+8]+=a[b+8]>a[b+6]?1:-1)));return c.join(" ")||"x"},clip:function(a){var c,b=this;return a?(c=a.members,ja(c,b),c.push(b),b.destroyClip=function(){ja(c,b)},a=a.getCSS(b)):(b.destroyClip&&b.destroyClip(),a={clip:hb?"inherit":"rect(auto)"}),b.css(a)},css:P.prototype.htmlCss,safeRemoveChild:function(a){a.parentNode&&Pa(a)},destroy:function(){return this.destroyClip&&this.destroyClip(),P.prototype.destroy.apply(this)},on:function(a,b){return this.element["on"+a]=function(){var a=I.event;a.target=a.srcElement,b(a)},this},cutOffPath:function(a,b){var c,a=a.split(/[ ,]/);return c=a.length,(9===c||11===c)&&(a[c-4]=a[c-2]=z(a[c-2])-10*b),a.join(" ")},shadow:function(a,b,c){var e,h,j,l,o,n,s,d=[],f=this.element,g=this.renderer,i=f.style,k=f.path;if(k&&"string"!=typeof k.value&&(k="x"),o=k,a){for(n=m(a.width,3),s=(a.opacity||.15)/n,e=1;3>=e;e++)l=2*n+1-2*e,c&&(o=this.cutOffPath(k.value,l+.5)),j=['<shape isShadow="true" strokeweight="',l,'" filled="false" path="',o,'" coordsize="10 10" style="',f.style.cssText,'" />'],h=Y(g.prepVML(j),null,{left:z(i.left)+m(a.offsetX,1),top:z(i.top)+m(a.offsetY,1)}),c&&(h.cutOff=l+1),j=['<stroke color="',a.color||"black",'" opacity="',s*e,'"/>'],Y(g.prepVML(j),null,null,h),b?b.element.appendChild(h):f.parentNode.insertBefore(h,f),d.push(h);this.shadows=d}return this},updateShadows:sa,setAttr:function(a,b){hb?this.element[a]=b:this.element.setAttribute(a,b)},classSetter:function(a){this.element.className=a},dashstyleSetter:function(a,b,c){(c.getElementsByTagName("stroke")[0]||Y(this.renderer.prepVML(["<stroke/>"]),null,null,c))[b]=a||"solid",this[b]=a},dSetter:function(a,b,c){var d=this.shadows,a=a||[];if(this.d=a.join(" "),c.path=a=this.pathToVML(a),d)for(c=d.length;c--;)d[c].path=d[c].cutOff?this.cutOffPath(a,d[c].cutOff):a;this.setAttr(b,a)},fillSetter:function(a,b,c){var d=c.nodeName;"SPAN"===d?c.style.color=a:"IMG"!==d&&(c.filled=a!==Q,this.setAttr("fillcolor",this.renderer.color(a,c,b,this)))},opacitySetter:sa,rotationSetter:function(a,b,c){c=c.style,this[b]=c[b]=a,c.left=-u(ea(a*Ca)+1)+"px",c.top=u(Z(a*Ca))+"px"},strokeSetter:function(a,b,c){this.setAttr("strokecolor",this.renderer.color(a,c,b))},"stroke-widthSetter":function(a,b,c){c.stroked=!!a,this[b]=a,ha(a)&&(a+="px"),this.setAttr("strokeweight",a)},titleSetter:function(a,b){this.setAttr(b,a)},visibilitySetter:function(a,b,c){"inherit"===a&&(a="visible"),this.shadows&&p(this.shadows,function(c){c.style[b]=a}),"DIV"===c.nodeName&&(a="hidden"===a?"-999em":0,hb||(c.style[b]=a?"visible":"hidden"),b="top"),c.style[b]=a},xSetter:function(a,b,c){this[b]=a,"x"===b?b="left":"y"===b&&(b="top"),this.updateClipping?(this[b]=a,this.updateClipping()):c.style[b]=a},zIndexSetter:function(a,b,c){c.style[b]=a}},X=ka(P,X),X.prototype.ySetter=X.prototype.widthSetter=X.prototype.heightSetter=X.prototype.xSetter;var ga={Element:X,isIE8:wa.indexOf("MSIE 8.0")>-1,init:function(a,b,c,d){var e;if(this.alignedObjects=[],d=this.createElement(Ja).css(q(this.getStyle(d),{position:"relative"})),e=d.element,a.appendChild(d.element),this.isVML=!0,this.box=e,this.boxWrapper=d,this.cache={},this.setSize(b,c,!1),!y.namespaces.hcv){y.namespaces.add("hcv","urn:schemas-microsoft-com:vml");try{y.createStyleSheet().cssText="hcv\\:fill, hcv\\:path, hcv\\:shape, hcv\\:stroke{ behavior:url(#default#VML); display: inline-block; } "}catch(f){y.styleSheets[0].cssText+="hcv\\:fill, hcv\\:path, hcv\\:shape, hcv\\:stroke{ behavior:url(#default#VML); display: inline-block; } "}}},isHidden:function(){return!this.box.offsetWidth},clipRect:function(a,b,c,d){var e=this.createElement(),f=ca(a);return q(e,{members:[],left:(f?a.x:a)+1,top:(f?a.y:b)+1,width:(f?a.width:c)-1,height:(f?a.height:d)-1,getCSS:function(a){var b=a.element,c=b.nodeName,a=a.inverted,d=this.top-("shape"===c?b.offsetTop:0),e=this.left,b=e+this.width,f=d+this.height,d={clip:"rect("+u(a?e:d)+"px,"+u(a?f:b)+"px,"+u(a?b:f)+"px,"+u(a?d:e)+"px)"};return!a&&hb&&"DIV"===c&&q(d,{width:b+"px",height:f+"px"}),d},updateClipping:function(){p(e.members,function(a){a.element&&a.css(e.getCSS(a))})}})},color:function(a,b,c,d){var f,h,i,e=this,g=/^rgba/,j=Q;if(a&&a.linearGradient?i="gradient":a&&a.radialGradient&&(i="pattern"),i){var k,l,n,s,m,J,L,r,o=a.linearGradient||a.radialGradient,x="",a=a.stops,v=[],q=function(){h=['<fill colors="'+v.join(",")+'" opacity="',m,'" o:opacity2="',s,'" type="',i,'" ',x,'focus="100%" method="any" />'],Y(e.prepVML(h),null,null,b)};if(n=a[0],r=a[a.length-1],n[0]>0&&a.unshift([0,n[1]]),r[0]<1&&a.push([1,r[1]]),p(a,function(a,b){g.test(a[1])?(f=ya(a[1]),k=f.get("rgb"),l=f.get("a")):(k=a[1],l=1),v.push(100*a[0]+"% "+k),b?(m=l,J=k):(s=l,L=k)}),"fill"===c)if("gradient"===i)c=o.x1||o[0]||0,a=o.y1||o[1]||0,n=o.x2||o[2]||0,o=o.y2||o[3]||0,x='angle="'+(90-180*U.atan((o-a)/(n-c))/ma)+'"',q();else{var w,j=o.r,t=2*j,u=2*j,y=o.cx,B=o.cy,na=b.radialReference,j=function(){na&&(w=d.getBBox(),y+=(na[0]-w.x)/w.width-.5,B+=(na[1]-w.y)/w.height-.5,t*=na[2]/w.width,u*=na[2]/w.height),x='src="'+E.global.VMLRadialGradientURL+'" size="'+t+","+u+'" origin="0.5,0.5" position="'+y+","+B+'" color2="'+L+'" ',q()};d.added?j():d.onAdd=j,j=J}else j=k}else g.test(a)&&"IMG"!==b.tagName?(f=ya(a),h=["<",c,' opacity="',f.get("a"),'"/>'],Y(this.prepVML(h),null,null,b),j=f.get("rgb")):(j=b.getElementsByTagName(c),j.length&&(j[0].opacity=1,j[0].type="solid"),j=a);return j},prepVML:function(a){var b=this.isIE8,a=a.join("");return b?(a=a.replace("/>",' xmlns="urn:schemas-microsoft-com:vml" />'),a=-1===a.indexOf('style="')?a.replace("/>",' style="display:inline-block;behavior:url(#default#VML);" />'):a.replace('style="','style="display:inline-block;behavior:url(#default#VML);')):a=a.replace("<","<hcv:"),a},text:ta.prototype.html,path:function(a){var b={coordsize:"10 10"};return La(a)?b.d=a:ca(a)&&q(b,a),this.createElement("shape").attr(b)},circle:function(a,b,c){var d=this.symbol("circle");return ca(a)&&(c=a.r,b=a.y,a=a.x),d.isCircle=!0,d.r=c,d.attr({x:a,y:b})},g:function(a){var b;return a&&(b={className:"highcharts-"+a,"class":"highcharts-"+a}),this.createElement(Ja).attr(b)},image:function(a,b,c,d,e){var f=this.createElement("img").attr({src:a});return arguments.length>1&&f.attr({x:b,y:c,width:d,height:e}),f},createElement:function(a){return"rect"===a?this.symbol(a):ta.prototype.createElement.call(this,a)},invertChild:function(a,b){var c=this,d=b.style,e="IMG"===a.tagName&&a.style;G(a,{flip:"x",left:z(d.width)-(e?z(e.top):1),top:z(d.height)-(e?z(e.left):1),rotation:-90}),p(a.childNodes,function(b){c.invertChild(b,a)})},symbols:{arc:function(a,b,c,d,e){var f=e.start,g=e.end,h=e.r||c||d,c=e.innerR,d=Z(f),i=ea(f),j=Z(g),k=ea(g);return g-f===0?["x"]:(f=["wa",a-h,b-h,a+h,b+h,a+h*d,b+h*i,a+h*j,b+h*k],e.open&&!c&&f.push("e","M",a,b),f.push("at",a-c,b-c,a+c,b+c,a+c*j,b+c*k,a+c*d,b+c*i,"x","e"),f.isArc=!0,f)},circle:function(a,b,c,d,e){return e&&(c=d=2*e.r),e&&e.isCircle&&(a-=c/2,b-=d/2),["wa",a,b,a+c,b+d,a+c,b+d/2,a+c,b+d/2,"e"]},rect:function(a,b,c,d,e){return ta.prototype.symbols[r(e)&&e.r?"callout":"square"].call(0,a,b,c,d,e)}}};R.VMLRenderer=X=function(){this.init.apply(this,arguments)},X.prototype=w(ta.prototype,ga),Za=X}ta.prototype.measureSpanWidth=function(a,b){var d,c=y.createElement("span");return d=y.createTextNode(a),c.appendChild(d),G(c,b),this.box.appendChild(c),d=c.offsetWidth,Pa(c),d};var Lb;fa&&(R.CanVGRenderer=X=function(){xa="http://www.w3.org/1999/xhtml"},X.prototype.symbols={},Lb=function(){function a(){var d,a=b.length;for(d=0;a>d;d++)b[d]();b=[]}var b=[];return{push:function(c,d){0===b.length&&Qb(d,a),b.push(c)}}}(),Za=X),Sa.prototype={addLabel:function(){var l,a=this.axis,b=a.options,c=a.chart,d=a.horiz,e=a.categories,f=a.names,g=this.pos,h=b.labels,i=a.tickPositions,d=d&&e&&!h.step&&!h.staggerLines&&!h.rotation&&c.plotWidth/i.length||!d&&(c.margin[3]||.33*c.chartWidth),j=g===i[0],k=g===i[i.length-1],f=e?m(e[g],f[g],g):g,e=this.label,o=i.info;a.isDatetimeAxis&&o&&(l=b.dateTimeLabelFormats[o.higherRanks[g]||o.unitName]),this.isFirst=j,this.isLast=k,b=a.labelFormatter.call({axis:a,chart:c,isFirst:j,isLast:k,dateTimeLabelFormat:l,value:a.isLog?da(ia(f)):f}),g=d&&{width:v(1,u(d-2*(h.padding||10)))+"px"},g=q(g,h.style),r(e)?e&&e.attr({text:b}).css(g):(l={align:a.labelAlign},ha(h.rotation)&&(l.rotation=h.rotation),d&&h.ellipsis&&(l._clipHeight=a.len/i.length),this.label=r(b)&&h.enabled?c.renderer.text(b,0,0,h.useHTML).attr(l).css(g).add(a.labelGroup):null)},getLabelSize:function(){var a=this.label,b=this.axis;return a?a.getBBox()[b.horiz?"height":"width"]:0},getLabelSides:function(){var a=this.label.getBBox(),b=this.axis,c=b.horiz,d=b.options.labels,a=c?a.width:a.height,b=c?d.x-a*{left:0,center:.5,right:1}[b.labelAlign]:0;return[b,c?a+b:a]},handleOverflow:function(a,b){var l,o,n,c=!0,d=this.axis,e=this.isFirst,f=this.isLast,g=d.horiz?b.x:b.y,h=d.reversed,i=d.tickPositions,j=this.getLabelSides(),k=j[0],j=j[1],s=this.label.line||0;if(l=d.labelEdge,o=d.justifyLabels&&(e||f),l[s]===t||g+k>l[s]?l[s]=g+j:o||(c=!1),o){l=(o=d.justifyToPlot)?d.pos:0,o=o?l+d.len:d.chart.chartWidth;do a+=e?1:-1,n=d.ticks[i[a]];while(i[a]&&(!n||n.label.line!==s));d=n&&n.label.xy&&n.label.xy.x+n.getLabelSides()[e?0:1],e&&!h||f&&h?l>g+k&&(g=l-k,n&&g+j>d&&(c=!1)):g+j>o&&(g=o-j,n&&d>g+k&&(c=!1)),b.x=g}return c},getPosition:function(a,b,c,d){var e=this.axis,f=e.chart,g=d&&f.oldChartHeight||f.chartHeight;return{x:a?e.translate(b+c,null,null,d)+e.transB:e.left+e.offset+(e.opposite?(d&&f.oldChartWidth||f.chartWidth)-e.right-e.left:0),y:a?g-e.bottom+e.offset-(e.opposite?e.height:0):g-e.translate(b+c,null,null,d)-e.transB}},getLabelPosition:function(a,b,c,d,e,f,g,h){var i=this.axis,j=i.transA,k=i.reversed,l=i.staggerLines,o=i.chart.renderer.fontMetrics(e.style.fontSize).b,n=e.rotation,a=a+e.x-(f&&d?f*j*(k?-1:1):0),b=b+e.y-(f&&!d?f*j*(k?1:-1):0);return n&&2===i.side&&(b-=o-o*Z(n*Ca)),!r(e.y)&&!n&&(b+=o-c.getBBox().height/2),l&&(c.line=g/(h||1)%l,b+=c.line*(i.labelOffset/l)),{x:a,y:b}},getMarkPath:function(a,b,c,d,e,f){return f.crispLine(["M",a,b,"L",a+(e?0:-c),b+(e?c:0)],d)},render:function(a,b,c){var d=this.axis,e=d.options,f=d.chart.renderer,g=d.horiz,h=this.type,i=this.label,j=this.pos,k=e.labels,l=this.gridLine,o=h?h+"Grid":"grid",n=h?h+"Tick":"tick",s=e[o+"LineWidth"],p=e[o+"LineColor"],J=e[o+"LineDashStyle"],L=e[n+"Length"],o=e[n+"Width"]||0,x=e[n+"Color"],r=e[n+"Position"],n=this.mark,v=k.step,q=!0,u=d.tickmarkOffset,w=this.getPosition(g,j,u,b),y=w.x,w=w.y,B=g&&y===d.pos+d.len||!g&&w===d.pos?-1:1;this.isActive=!0,s&&(j=d.getPlotLinePath(j+u,s*B,b,!0),l===t&&(l={stroke:p,"stroke-width":s},J&&(l.dashstyle=J),h||(l.zIndex=1),b&&(l.opacity=0),this.gridLine=l=s?f.path(j).attr(l).add(d.gridGroup):null),!b&&l&&j&&l[this.isNew?"attr":"animate"]({d:j,opacity:c})),o&&L&&("inside"===r&&(L=-L),d.opposite&&(L=-L),h=this.getMarkPath(y,w,L,o*B,g,f),n?n.animate({d:h,opacity:c}):this.mark=f.path(h).attr({stroke:x,"stroke-width":o,opacity:c}).add(d.axisGroup)),i&&!isNaN(y)&&(i.xy=w=this.getLabelPosition(y,w,i,g,k,u,a,v),this.isFirst&&!this.isLast&&!m(e.showFirstLabel,1)||this.isLast&&!this.isFirst&&!m(e.showLastLabel,1)?q=!1:!d.isRadial&&!k.step&&!k.rotation&&!b&&0!==c&&(q=this.handleOverflow(a,w)),v&&a%v&&(q=!1),q&&!isNaN(w.y)?(w.opacity=c,i[this.isNew?"attr":"animate"](w),this.isNew=!1):i.attr("y",-9999))},destroy:function(){Oa(this,this.axis)}},R.PlotLineOrBand=function(a,b){this.axis=a,b&&(this.options=b,this.id=b.id)},R.PlotLineOrBand.prototype={render:function(){var p,a=this,b=a.axis,c=b.horiz,d=(b.pointRange||0)/2,e=a.options,f=e.label,g=a.label,h=e.width,i=e.to,j=e.from,k=r(j)&&r(i),l=e.value,o=e.dashStyle,n=a.svgElem,s=[],J=e.color,L=e.zIndex,x=e.events,q={},t=b.chart.renderer;if(b.isLog&&(j=za(j),i=za(i),l=za(l)),h)s=b.getPlotLinePath(l,h),q={stroke:J,"stroke-width":h},o&&(q.dashstyle=o);else{if(!k)return;j=v(j,b.min-d),i=C(i,b.max+d),s=b.getPlotBandPath(j,i,e),J&&(q.fill=J),e.borderWidth&&(q.stroke=e.borderColor,q["stroke-width"]=e.borderWidth)}if(r(L)&&(q.zIndex=L),n)s?n.animate({d:s},null,n.onGetPath):(n.hide(),n.onGetPath=function(){n.show()},g&&(a.label=g=g.destroy()));else if(s&&s.length&&(a.svgElem=n=t.path(s).attr(q).add(),x))for(p in d=function(b){n.on(b,function(c){x[b].apply(a,[c])})},x)d(p);return f&&r(f.text)&&s&&s.length&&b.width>0&&b.height>0?(f=w({align:c&&k&&"center",x:c?!k&&4:10,verticalAlign:!c&&k&&"middle",y:c?k?16:10:k?6:-4,rotation:c&&!k&&90},f),g||(q={align:f.textAlign||f.align,rotation:f.rotation},r(L)&&(q.zIndex=L),a.label=g=t.text(f.text,0,0,f.useHTML).attr(q).css(f.style).add()),b=[s[1],s[4],m(s[6],s[1])],s=[s[2],s[5],m(s[7],s[2])],c=Na(b),k=Na(s),g.align(f,!1,{x:c,y:k,width:Ba(b)-c,height:Ba(s)-k}),g.show()):g&&g.hide(),a},destroy:function(){ja(this.axis.plotLinesAndBands,this),delete this.axis,Oa(this)}},la.prototype={defaultOptions:{dateTimeLabelFormats:{millisecond:"%H:%M:%S.%L",second:"%H:%M:%S",minute:"%H:%M",hour:"%H:%M",day:"%e. %b",week:"%e. %b",month:"%b '%y",year:"%Y"},endOnTick:!1,gridLineColor:"#C0C0C0",labels:N,lineColor:"#C0D0E0",lineWidth:1,minPadding:.01,maxPadding:.01,minorGridLineColor:"#E0E0E0",minorGridLineWidth:1,minorTickColor:"#A0A0A0",minorTickLength:2,minorTickPosition:"outside",startOfWeek:1,startOnTick:!1,tickColor:"#C0D0E0",tickLength:10,tickmarkPlacement:"between",tickPixelInterval:100,tickPosition:"outside",tickWidth:1,title:{align:"middle",style:{color:"#707070"}},type:"linear"},defaultYAxisOptions:{endOnTick:!0,gridLineWidth:1,tickPixelInterval:72,showLastLabel:!0,labels:{x:-8,y:3},lineWidth:0,maxPadding:.05,minPadding:.05,startOnTick:!0,tickWidth:0,title:{rotation:270,text:"Values"},stackLabels:{enabled:!1,formatter:function(){return Ga(this.total,-1)},style:N.style}},defaultLeftAxisOptions:{labels:{x:-15,y:null},title:{rotation:270}},defaultRightAxisOptions:{labels:{x:15,y:null},title:{rotation:90}},defaultBottomAxisOptions:{labels:{x:0,y:20},title:{rotation:0}},defaultTopAxisOptions:{labels:{x:0,y:-15},title:{rotation:0}},init:function(a,b){var c=b.isX;this.horiz=a.inverted?!c:c,this.coll=(this.isXAxis=c)?"xAxis":"yAxis",this.opposite=b.opposite,this.side=b.side||(this.horiz?this.opposite?0:2:this.opposite?1:3),this.setOptions(b);var d=this.options,e=d.type;this.labelFormatter=d.labels.formatter||this.defaultLabelFormatter,this.userOptions=b,this.minPixelPadding=0,this.chart=a,this.reversed=d.reversed,this.zoomEnabled=d.zoomEnabled!==!1,this.categories=d.categories||"category"===e,this.names=[],this.isLog="logarithmic"===e,this.isDatetimeAxis="datetime"===e,this.isLinked=r(d.linkedTo),this.tickmarkOffset=this.categories&&"between"===d.tickmarkPlacement?.5:0,this.ticks={},this.labelEdge=[],this.minorTicks={},this.plotLinesAndBands=[],this.alternateBands={},this.len=0,this.minRange=this.userMinRange=d.minRange||d.maxZoom,this.range=d.range,this.offset=d.offset||0,this.stacks={},this.oldStacks={},this.min=this.max=null,this.crosshair=m(d.crosshair,qa(a.options.tooltip.crosshairs)[c?0:1],!1);var f,d=this.options.events;-1===Da(this,a.axes)&&(c&&!this.isColorAxis?a.axes.splice(a.xAxis.length,0,this):a.axes.push(this),a[this.coll].push(this)),this.series=this.series||[],a.inverted&&c&&this.reversed===t&&(this.reversed=!0),this.removePlotLine=this.removePlotBand=this.removePlotBandOrLine;for(f in d)K(this,f,d[f]);this.isLog&&(this.val2lin=za,this.lin2val=ia)},setOptions:function(a){this.options=w(this.defaultOptions,this.isXAxis?{}:this.defaultYAxisOptions,[this.defaultTopAxisOptions,this.defaultRightAxisOptions,this.defaultBottomAxisOptions,this.defaultLeftAxisOptions][this.side],w(E[this.coll],a))},defaultLabelFormatter:function(){var g,a=this.axis,b=this.value,c=a.categories,d=this.dateTimeLabelFormat,e=E.lang.numericSymbols,f=e&&e.length,h=a.options.labels.format,a=a.isLog?b:a.tickInterval;if(h)g=Ia(h,this);else if(c)g=b;else if(d)g=cb(d,b);else if(f&&a>=1e3)for(;f--&&g===t;)c=Math.pow(1e3,f+1),a>=c&&null!==e[f]&&(g=Ga(b/c,-1)+e[f]);return g===t&&(g=M(b)>=1e4?Ga(b,0):Ga(b,-1,t,"")),g},getSeriesExtremes:function(){var a=this,b=a.chart;a.hasVisibleSeries=!1,a.dataMin=a.dataMax=null,a.buildStacks&&a.buildStacks(),p(a.series,function(c){if(c.visible||!b.options.chart.ignoreHiddenSeries){var d;d=c.options.threshold;var e;a.hasVisibleSeries=!0,a.isLog&&0>=d&&(d=null),a.isXAxis?(d=c.xData,d.length&&(a.dataMin=C(m(a.dataMin,d[0]),Na(d)),a.dataMax=v(m(a.dataMax,d[0]),Ba(d)))):(c.getExtremes(),e=c.dataMax,c=c.dataMin,r(c)&&r(e)&&(a.dataMin=C(m(a.dataMin,c),c),a.dataMax=v(m(a.dataMax,e),e)),r(d)&&(a.dataMin>=d?(a.dataMin=d,a.ignoreMinPadding=!0):a.dataMax<d&&(a.dataMax=d,a.ignoreMaxPadding=!0)))}})},translate:function(a,b,c,d,e,f){var g=1,h=0,i=d?this.oldTransA:this.transA,d=d?this.oldMin:this.min,j=this.minPixelPadding,e=(this.options.ordinal||this.isLog&&e)&&this.lin2val;return i||(i=this.transA),c&&(g*=-1,h=this.len),this.reversed&&(g*=-1,h-=g*(this.sector||this.len)),b?(a=a*g+h,a-=j,a=a/i+d,e&&(a=this.lin2val(a))):(e&&(a=this.val2lin(a)),"between"===f&&(f=.5),a=g*(a-d)*i+h+g*j+(ha(f)?i*f*this.pointRange:0)),a},toPixels:function(a,b){return this.translate(a,!1,!this.horiz,null,!0)+(b?0:this.pos)},toValue:function(a,b){return this.translate(a-(b?0:this.pos),!0,!this.horiz,null,!0)},getPlotLinePath:function(a,b,c,d,e){var i,j,o,f=this.chart,g=this.left,h=this.top,k=c&&f.oldChartHeight||f.chartHeight,l=c&&f.oldChartWidth||f.chartWidth;return i=this.transB,e=m(e,this.translate(a,null,null,c)),a=c=u(e+i),i=j=u(k-e-i),isNaN(e)?o=!0:this.horiz?(i=h,j=k-this.bottom,(g>a||a>g+this.width)&&(o=!0)):(a=g,c=l-this.right,(h>i||i>h+this.height)&&(o=!0)),o&&!d?null:f.renderer.crispLine(["M",a,i,"L",c,j],b||1)},getLinearTickPositions:function(a,b,c){var d,e=da(T(b/a)*a),f=da(Ka(c/a)*a),g=[];if(b===c&&ha(b))return[b];for(b=e;f>=b&&(g.push(b),b=da(b+a),b!==d);)d=b;return g},getMinorTickPositions:function(){var e,a=this.options,b=this.tickPositions,c=this.minorTickInterval,d=[];if(this.isLog)for(e=b.length,a=1;e>a;a++)d=d.concat(this.getLogTickPositions(c,b[a-1],b[a],!0));else if(this.isDatetimeAxis&&"auto"===a.minorTickInterval)d=d.concat(this.getTimeTicks(this.normalizeTimeTickInterval(c),this.min,this.max,a.startOfWeek)),d[0]<this.min&&d.shift();else for(b=this.min+(b[0]-this.min)%c;b<=this.max;b+=c)d.push(b);return d},adjustForMinRange:function(){var d,f,g,h,i,j,a=this.options,b=this.min,c=this.max,e=this.dataMax-this.dataMin>=this.minRange;if(this.isXAxis&&this.minRange===t&&!this.isLog&&(r(a.min)||r(a.max)?this.minRange=null:(p(this.series,function(a){for(i=a.xData,g=j=a.xIncrement?1:i.length-1;g>0;g--)h=i[g]-i[g-1],(f===t||f>h)&&(f=h)}),this.minRange=C(5*f,this.dataMax-this.dataMin))),c-b<this.minRange){var k=this.minRange;d=(k-c+b)/2,d=[b-d,m(a.min,b-d)],e&&(d[2]=this.dataMin),b=Ba(d),c=[b+k,m(a.max,b+k)],e&&(c[2]=this.dataMax),c=Na(c),k>c-b&&(d[0]=c-k,d[1]=m(a.min,c-k),b=Ba(d))}this.min=b,this.max=c},setAxisTranslation:function(a){var e,b=this,c=b.max-b.min,d=b.axisPointRange||0,f=0,g=0,h=b.linkedParent,i=!!b.categories,j=b.transA;(b.isXAxis||i||d)&&(h?(f=h.minPointOffset,g=h.pointRangePadding):p(b.series,function(a){var h=i?1:b.isXAxis?a.pointRange:b.axisPointRange||0,j=a.options.pointPlacement,n=a.closestPointRange;h>c&&(h=0),d=v(d,h),f=v(f,Fa(j)?0:h/2),g=v(g,"on"===j?0:h),!a.noSharedTooltip&&r(n)&&(e=r(e)?C(e,n):n)}),h=b.ordinalSlope&&e?b.ordinalSlope/e:1,b.minPointOffset=f*=h,b.pointRangePadding=g*=h,b.pointRange=C(d,c),b.closestPointRange=e),a&&(b.oldTransA=j),b.translationSlope=b.transA=j=b.len/(c+g||1),b.transB=b.horiz?b.left:b.bottom,b.minPixelPadding=j*f},setTickPositions:function(a){var s,b=this,c=b.chart,d=b.options,e=b.isLog,f=b.isDatetimeAxis,g=b.isXAxis,h=b.isLinked,i=b.options.tickPositioner,j=d.maxPadding,k=d.minPadding,l=d.tickInterval,o=d.minTickInterval,n=d.tickPixelInterval,$=b.categories;h?(b.linkedParent=c[b.coll][d.linkedTo],c=b.linkedParent.getExtremes(),b.min=m(c.min,c.dataMin),b.max=m(c.max,c.dataMax),d.type!==b.linkedParent.options.type&&ra(11,1)):(b.min=m(b.userMin,d.min,b.dataMin),b.max=m(b.userMax,d.max,b.dataMax)),e&&(!a&&C(b.min,m(b.dataMin,b.min))<=0&&ra(10,1),b.min=da(za(b.min)),b.max=da(za(b.max))),b.range&&r(b.max)&&(b.userMin=b.min=v(b.min,b.max-b.range),b.userMax=b.max,b.range=null),b.beforePadding&&b.beforePadding(),b.adjustForMinRange(),$||b.axisPointRange||b.usePercentage||h||!r(b.min)||!r(b.max)||!(c=b.max-b.min)||(r(d.min)||r(b.userMin)||!k||!(b.dataMin<0)&&b.ignoreMinPadding||(b.min-=c*k),r(d.max)||r(b.userMax)||!j||!(b.dataMax>0)&&b.ignoreMaxPadding||(b.max+=c*j)),ha(d.floor)&&(b.min=v(b.min,d.floor)),ha(d.ceiling)&&(b.max=C(b.max,d.ceiling)),b.min===b.max||void 0===b.min||void 0===b.max?b.tickInterval=1:h&&!l&&n===b.linkedParent.options.tickPixelInterval?b.tickInterval=b.linkedParent.tickInterval:(b.tickInterval=m(l,$?1:(b.max-b.min)*n/v(b.len,n)),!r(l)&&b.len<n&&!this.isRadial&&!this.isLog&&!$&&d.startOnTick&&d.endOnTick&&(s=!0,b.tickInterval/=4)),g&&!a&&p(b.series,function(a){a.processData(b.min!==b.oldMin||b.max!==b.oldMax)}),b.setAxisTranslation(!0),b.beforeSetTickPositions&&b.beforeSetTickPositions(),b.postProcessTickInterval&&(b.tickInterval=b.postProcessTickInterval(b.tickInterval)),b.pointRange&&(b.tickInterval=v(b.pointRange,b.tickInterval)),!l&&b.tickInterval<o&&(b.tickInterval=o),f||e||l||(b.tickInterval=nb(b.tickInterval,null,mb(b.tickInterval),d)),b.minorTickInterval="auto"===d.minorTickInterval&&b.tickInterval?b.tickInterval/5:d.minorTickInterval,b.tickPositions=a=d.tickPositions?[].concat(d.tickPositions):i&&i.apply(b,[b.min,b.max]),a||(!b.ordinalPositions&&(b.max-b.min)/b.tickInterval>v(2*b.len,200)&&ra(19,!0),a=f?b.getTimeTicks(b.normalizeTimeTickInterval(b.tickInterval,d.units),b.min,b.max,d.startOfWeek,b.ordinalPositions,b.closestPointRange,!0):e?b.getLogTickPositions(b.tickInterval,b.min,b.max):b.getLinearTickPositions(b.tickInterval,b.min,b.max),s&&a.splice(1,a.length-2),b.tickPositions=a),h||(e=a[0],f=a[a.length-1],h=b.minPointOffset||0,d.startOnTick?b.min=e:b.min-h>e&&a.shift(),d.endOnTick?b.max=f:b.max+h<f&&a.pop(),1===a.length&&(d=M(b.max)>1e13?1:.001,b.min-=d,b.max+=d))},setMaxTicks:function(){var a=this.chart,b=a.maxTicks||{},c=this.tickPositions,d=this._maxTicksKey=[this.coll,this.pos,this.len].join("-");!this.isLinked&&!this.isDatetimeAxis&&c&&c.length>(b[d]||0)&&this.options.alignTicks!==!1&&(b[d]=c.length),a.maxTicks=b},adjustTickAmount:function(){var a=this._maxTicksKey,b=this.tickPositions,c=this.chart.maxTicks;if(c&&c[a]&&!this.isDatetimeAxis&&!this.categories&&!this.isLinked&&this.options.alignTicks!==!1&&this.min!==t){var d=this.tickAmount,e=b.length;if(this.tickAmount=a=c[a],a>e){for(;b.length<a;)b.push(da(b[b.length-1]+this.tickInterval));this.transA*=(e-1)/(a-1),this.max=b[b.length-1]}r(d)&&a!==d&&(this.isDirty=!0)}},setScale:function(){var b,c,d,e,a=this.stacks;if(this.oldMin=this.min,this.oldMax=this.max,this.oldAxisLength=this.len,this.setAxisSize(),e=this.len!==this.oldAxisLength,p(this.series,function(a){(a.isDirtyData||a.isDirty||a.xAxis.isDirty)&&(d=!0)}),e||d||this.isLinked||this.forceRedraw||this.userMin!==this.oldUserMin||this.userMax!==this.oldUserMax){if(!this.isXAxis)for(b in a)for(c in a[b])a[b][c].total=null,a[b][c].cum=0;this.forceRedraw=!1,this.getSeriesExtremes(),this.setTickPositions(),this.oldUserMin=this.userMin,this.oldUserMax=this.userMax,this.isDirty||(this.isDirty=e||this.min!==this.oldMin||this.max!==this.oldMax)}else if(!this.isXAxis){this.oldStacks&&(a=this.stacks=this.oldStacks);for(b in a)for(c in a[b])a[b][c].cum=a[b][c].total}this.setMaxTicks()},setExtremes:function(a,b,c,d,e){var f=this,g=f.chart,c=m(c,!0),e=q(e,{min:a,max:b});D(f,"setExtremes",e,function(){f.userMin=a,f.userMax=b,f.eventArgs=e,f.isDirtyExtremes=!0,c&&g.redraw(d)})},zoom:function(a,b){var c=this.dataMin,d=this.dataMax,e=this.options;return this.allowZoomOutside||(r(c)&&a<=C(c,m(e.min,c))&&(a=t),r(d)&&b>=v(d,m(e.max,d))&&(b=t)),this.displayBtn=a!==t||b!==t,this.setExtremes(a,b,!1,t,{trigger:"zoom"}),!0},setAxisSize:function(){var a=this.chart,b=this.options,c=b.offsetLeft||0,d=this.horiz,e=m(b.width,a.plotWidth-c+(b.offsetRight||0)),f=m(b.height,a.plotHeight),g=m(b.top,a.plotTop),b=m(b.left,a.plotLeft+c),c=/%$/;c.test(f)&&(f=parseInt(f,10)/100*a.plotHeight),c.test(g)&&(g=parseInt(g,10)/100*a.plotHeight+a.plotTop),this.left=b,this.top=g,this.width=e,this.height=f,this.bottom=a.chartHeight-f-g,this.right=a.chartWidth-e-b,this.len=v(d?e:f,0),this.pos=d?b:g},getExtremes:function(){var a=this.isLog;return{min:a?da(ia(this.min)):this.min,max:a?da(ia(this.max)):this.max,dataMin:this.dataMin,dataMax:this.dataMax,userMin:this.userMin,userMax:this.userMax}},getThreshold:function(a){var b=this.isLog,c=b?ia(this.min):this.min,b=b?ia(this.max):this.max;return c>a||null===a?a=c:a>b&&(a=b),this.translate(a,0,1,0,1)},autoLabelAlign:function(a){return a=(m(a,0)-90*this.side+720)%360,a>15&&165>a?"right":a>195&&345>a?"left":"center"},getOffset:function(){var j,l,q,y,z,A,B,a=this,b=a.chart,c=b.renderer,d=a.options,e=a.tickPositions,f=a.ticks,g=a.horiz,h=a.side,i=b.inverted?[1,0,3,2][h]:h,k=0,o=0,n=d.title,s=d.labels,$=0,J=b.axisOffset,L=b.clipOffset,x=[-1,1,1,-1][h],u=1,w=m(s.maxStaggerLines,5),na=2===h?c.fontMetrics(s.style.fontSize).b:0;if(a.hasData=j=a.hasVisibleSeries||r(a.min)&&r(a.max)&&!!e,a.showAxis=b=j||m(d.showEmpty,!0),a.staggerLines=a.horiz&&s.staggerLines,a.axisGroup||(a.gridGroup=c.g("grid").attr({zIndex:d.gridZIndex||1}).add(),a.axisGroup=c.g("axis").attr({zIndex:d.zIndex||2}).add(),a.labelGroup=c.g("axis-labels").attr({zIndex:s.zIndex||7}).addClass("highcharts-"+a.coll.toLowerCase()+"-labels").add()),j||a.isLinked){if(a.labelAlign=m(s.align||a.autoLabelAlign(s.rotation)),p(e,function(b){f[b]?f[b].addLabel():f[b]=new Sa(a,b)
|
3 |
+
}),a.horiz&&!a.staggerLines&&w&&!s.rotation){for(q=a.reversed?[].concat(e).reverse():e;w>u;){for(j=[],y=!1,s=0;s<q.length;s++)z=q[s],A=(A=f[z].label&&f[z].label.getBBox())?A.width:0,B=s%u,A&&(z=a.translate(z),j[B]!==t&&z<j[B]&&(y=!0),j[B]=z+A);if(!y)break;u++}u>1&&(a.staggerLines=u)}p(e,function(b){(0===h||2===h||{1:"left",3:"right"}[h]===a.labelAlign)&&($=v(f[b].getLabelSize(),$))}),a.staggerLines&&($*=a.staggerLines,a.labelOffset=$)}else for(q in f)f[q].destroy(),delete f[q];n&&n.text&&n.enabled!==!1&&(a.axisTitle||(a.axisTitle=c.text(n.text,0,0,n.useHTML).attr({zIndex:7,rotation:n.rotation||0,align:n.textAlign||{low:"left",middle:"center",high:"right"}[n.align]}).addClass("highcharts-"+this.coll.toLowerCase()+"-title").css(n.style).add(a.axisGroup),a.axisTitle.isNew=!0),b&&(k=a.axisTitle.getBBox()[g?"height":"width"],o=m(n.margin,g?5:10),l=n.offset),a.axisTitle[b?"show":"hide"]()),a.offset=x*m(d.offset,J[h]),a.axisTitleMargin=m(l,$+o+($&&x*d.labels[g?"y":"x"]-na)),J[h]=v(J[h],a.axisTitleMargin+k+x*a.offset),L[i]=v(L[i],2*T(d.lineWidth/2))},getLinePath:function(a){var b=this.chart,c=this.opposite,d=this.offset,e=this.horiz,f=this.left+(c?this.width:0)+d,d=b.chartHeight-this.bottom-(c?this.height:0)+d;return c&&(a*=-1),b.renderer.crispLine(["M",e?this.left:f,e?d:this.top,"L",e?b.chartWidth-this.right:f,e?d:b.chartHeight-this.bottom],a)},getTitlePosition:function(){var a=this.horiz,b=this.left,c=this.top,d=this.len,e=this.options.title,f=a?b:c,g=this.opposite,h=this.offset,i=z(e.style.fontSize||12),d={low:f+(a?0:d),middle:f+d/2,high:f+(a?d:0)}[e.align],b=(a?c+this.height:b)+(a?1:-1)*(g?-1:1)*this.axisTitleMargin+(2===this.side?i:0);return{x:a?d:b+(g?this.width:0)+h+(e.x||0),y:a?b-(g?this.height:0)+h:d+(e.y||0)}},render:function(){var j,u,z,a=this,b=a.horiz,c=a.reversed,d=a.chart,e=d.renderer,f=a.options,g=a.isLog,h=a.isLinked,i=a.tickPositions,k=a.axisTitle,l=a.ticks,o=a.minorTicks,n=a.alternateBands,s=f.stackLabels,m=f.alternateGridColor,J=a.tickmarkOffset,L=f.lineWidth,x=d.hasRendered&&r(a.oldMin)&&!isNaN(a.oldMin),q=a.hasData,v=a.showAxis,w=f.labels.overflow,y=a.justifyLabels=b&&w!==!1;a.labelEdge.length=0,a.justifyToPlot="justify"===w,p([l,o,n],function(a){for(var b in a)a[b].isActive=!1}),(q||h)&&(a.minorTickInterval&&!a.categories&&p(a.getMinorTickPositions(),function(b){o[b]||(o[b]=new Sa(a,b,"minor")),x&&o[b].isNew&&o[b].render(null,!0),o[b].render(null,!1,1)}),i.length&&(j=i.slice(),(b&&c||!b&&!c)&&j.reverse(),y&&(j=j.slice(1).concat([j[0]])),p(j,function(b,c){y&&(c=c===j.length-1?0:c+1),(!h||b>=a.min&&b<=a.max)&&(l[b]||(l[b]=new Sa(a,b)),x&&l[b].isNew&&l[b].render(c,!0,.1),l[b].render(c,!1,1))}),J&&0===a.min&&(l[-1]||(l[-1]=new Sa(a,-1,null,!0)),l[-1].render(-1))),m&&p(i,function(b,c){c%2===0&&b<a.max&&(n[b]||(n[b]=new R.PlotLineOrBand(a)),u=b+J,z=i[c+1]!==t?i[c+1]+J:a.max,n[b].options={from:g?ia(u):u,to:g?ia(z):z,color:m},n[b].render(),n[b].isActive=!0)}),a._addedPlotLB||(p((f.plotLines||[]).concat(f.plotBands||[]),function(b){a.addPlotBandOrLine(b)}),a._addedPlotLB=!0)),p([l,o,n],function(a){var b,c,e=[],f=va?va.duration||500:0,g=function(){for(c=e.length;c--;)a[e[c]]&&!a[e[c]].isActive&&(a[e[c]].destroy(),delete a[e[c]])};for(b in a)a[b].isActive||(a[b].render(b,!1,0),a[b].isActive=!1,e.push(b));a!==n&&d.hasRendered&&f?f&&setTimeout(g,f):g()}),L&&(b=a.getLinePath(L),a.axisLine?a.axisLine.animate({d:b}):a.axisLine=e.path(b).attr({stroke:f.lineColor,"stroke-width":L,zIndex:7}).add(a.axisGroup),a.axisLine[v?"show":"hide"]()),k&&v&&(k[k.isNew?"attr":"animate"](a.getTitlePosition()),k.isNew=!1),s&&s.enabled&&a.renderStackTotals(),a.isDirty=!1},redraw:function(){var a=this.chart.pointer;a&&a.reset(!0),this.render(),p(this.plotLinesAndBands,function(a){a.render()}),p(this.series,function(a){a.isDirty=!0})},destroy:function(a){var d,b=this,c=b.stacks,e=b.plotLinesAndBands;a||W(b);for(d in c)Oa(c[d]),c[d]=null;for(p([b.ticks,b.minorTicks,b.alternateBands],function(a){Oa(a)}),a=e.length;a--;)e[a].destroy();p("stackTotalGroup,axisLine,axisTitle,axisGroup,cross,gridGroup,labelGroup".split(","),function(a){b[a]&&(b[a]=b[a].destroy())}),this.cross&&this.cross.destroy()},drawCrosshair:function(a,b){if(this.crosshair)if((r(b)||!m(this.crosshair.snap,!0))===!1)this.hideCrosshair();else{var c,d=this.crosshair,e=d.animation;m(d.snap,!0)?r(b)&&(c=this.chart.inverted!=this.horiz?b.plotX:this.len-b.plotY):c=this.horiz?a.chartX-this.pos:this.len-a.chartY+this.pos,c=this.isRadial?this.getPlotLinePath(this.isXAxis?b.x:m(b.stackY,b.y)):this.getPlotLinePath(null,null,null,null,c),null===c?this.hideCrosshair():this.cross?this.cross.attr({visibility:"visible"})[e?"animate":"attr"]({d:c},e):(e={"stroke-width":d.width||1,stroke:d.color||"#C0C0C0",zIndex:d.zIndex||2},d.dashStyle&&(e.dashstyle=d.dashStyle),this.cross=this.chart.renderer.path(c).attr(e).add())}},hideCrosshair:function(){this.cross&&this.cross.hide()}},q(la.prototype,{getPlotBandPath:function(a,b){var c=this.getPlotLinePath(b),d=this.getPlotLinePath(a);return d&&c?d.push(c[4],c[5],c[1],c[2]):d=null,d},addPlotBand:function(a){this.addPlotBandOrLine(a,"plotBands")},addPlotLine:function(a){this.addPlotBandOrLine(a,"plotLines")},addPlotBandOrLine:function(a,b){var c=new R.PlotLineOrBand(this,a).render(),d=this.userOptions;return c&&(b&&(d[b]=d[b]||[],d[b].push(a)),this.plotLinesAndBands.push(c)),c},removePlotBandOrLine:function(a){for(var b=this.plotLinesAndBands,c=this.options,d=this.userOptions,e=b.length;e--;)b[e].id===a&&b[e].destroy();p([c.plotLines||[],d.plotLines||[],c.plotBands||[],d.plotBands||[]],function(b){for(e=b.length;e--;)b[e].id===a&&ja(b,b[e])})}}),la.prototype.getTimeTicks=function(a,b,c,d){var h,e=[],f={},g=E.global.useUTC,i=new Date(b-Ra),j=a.unitRange,k=a.count;if(r(b)){j>=A.second&&(i.setMilliseconds(0),i.setSeconds(j>=A.minute?0:k*T(i.getSeconds()/k))),j>=A.minute&&i[Db](j>=A.hour?0:k*T(i[pb]()/k)),j>=A.hour&&i[Eb](j>=A.day?0:k*T(i[qb]()/k)),j>=A.day&&i[sb](j>=A.month?1:k*T(i[Xa]()/k)),j>=A.month&&(i[Fb](j>=A.year?0:k*T(i[fb]()/k)),h=i[gb]()),j>=A.year&&(h-=h%k,i[Gb](h)),j===A.week&&i[sb](i[Xa]()-i[rb]()+m(d,1)),b=1,Ra&&(i=new Date(i.getTime()+Ra)),h=i[gb]();for(var d=i.getTime(),l=i[fb](),o=i[Xa](),n=g?Ra:(864e5+6e4*i.getTimezoneOffset())%864e5;c>d;)e.push(d),j===A.year?d=eb(h+b*k,0):j===A.month?d=eb(h,l+b*k):g||j!==A.day&&j!==A.week?d+=j*k:d=eb(h,l,o+b*k*(j===A.day?1:7)),b++;e.push(d),p(vb(e,function(a){return j<=A.hour&&a%A.day===n}),function(a){f[a]="day"})}return e.info=q(a,{higherRanks:f,totalRange:j*k}),e},la.prototype.normalizeTimeTickInterval=function(a,b){var g,c=b||[["millisecond",[1,2,5,10,20,25,50,100,200,500]],["second",[1,2,5,10,15,30]],["minute",[1,2,5,10,15,30]],["hour",[1,2,3,4,6,8,12]],["day",[1,2]],["week",[1,2]],["month",[1,2,3,4,6]],["year",null]],d=c[c.length-1],e=A[d[0]],f=d[1];for(g=0;g<c.length&&(d=c[g],e=A[d[0]],f=d[1],!(c[g+1]&&a<=(e*f[f.length-1]+A[c[g+1][0]])/2));g++);return e===A.year&&5*e>a&&(f=[1,2,5]),c=nb(a/e,f,"year"===d[0]?v(mb(a/e),1):1),{unitRange:e,count:c,unitName:d[0]}},la.prototype.getLogTickPositions=function(a,b,c,d){var e=this.options,f=this.len,g=[];if(d||(this._minorAutoInterval=null),a>=.5)a=u(a),g=this.getLinearTickPositions(a,b,c);else if(a>=.08)for(var h,i,j,k,l,f=T(b),e=a>.3?[1,2,4]:a>.15?[1,2,4,6,8]:[1,2,3,4,5,6,7,8,9];c+1>f&&!l;f++)for(i=e.length,h=0;i>h&&!l;h++)j=za(ia(f)*e[h]),j>b&&(!d||c>=k)&&g.push(k),k>c&&(l=!0),k=j;else b=ia(b),c=ia(c),a=e[d?"minorTickInterval":"tickInterval"],a=m("auto"===a?null:a,this._minorAutoInterval,(c-b)*(e.tickPixelInterval/(d?5:1))/((d?f/this.tickPositions.length:f)||1)),a=nb(a,null,mb(a)),g=Ua(this.getLinearTickPositions(a,b,c),za),d||(this._minorAutoInterval=a/5);return d||(this.tickInterval=a),g};var Mb=R.Tooltip=function(){this.init.apply(this,arguments)};Mb.prototype={init:function(a,b){var c=b.borderWidth,d=b.style,e=z(d.padding);this.chart=a,this.options=b,this.crosshairs=[],this.now={x:0,y:0},this.isHidden=!0,this.label=a.renderer.label("",0,0,b.shape||"callout",null,null,b.useHTML,null,"tooltip").attr({padding:e,fill:b.backgroundColor,"stroke-width":c,r:b.borderRadius,zIndex:8}).css(d).css({padding:0}).add().attr({y:-9999}),fa||this.label.shadow(b.shadow),this.shared=b.shared},destroy:function(){this.label&&(this.label=this.label.destroy()),clearTimeout(this.hideTimer),clearTimeout(this.tooltipTimeout)},move:function(a,b,c,d){var e=this,f=e.now,g=e.options.animation!==!1&&!e.isHidden,h=e.followPointer||e.len>1;q(f,{x:g?(2*f.x+a)/3:a,y:g?(f.y+b)/2:b,anchorX:h?t:g?(2*f.anchorX+c)/3:c,anchorY:h?t:g?(f.anchorY+d)/2:d}),e.label.attr(f),g&&(M(a-f.x)>1||M(b-f.y)>1)&&(clearTimeout(this.tooltipTimeout),this.tooltipTimeout=setTimeout(function(){e&&e.move(a,b,c,d)},32))},hide:function(){var b,a=this;clearTimeout(this.hideTimer),this.isHidden||(b=this.chart.hoverPoints,this.hideTimer=setTimeout(function(){a.label.fadeOut(),a.isHidden=!0},m(this.options.hideDelay,500)),b&&p(b,function(a){a.setState()}),this.chart.hoverPoints=null)},getAnchor:function(a,b){var c,i,d=this.chart,e=d.inverted,f=d.plotTop,g=0,h=0,a=qa(a);return c=a[0].tooltipPos,this.followPointer&&b&&(b.chartX===t&&(b=d.pointer.normalize(b)),c=[b.chartX-d.plotLeft,b.chartY-f]),c||(p(a,function(a){i=a.series.yAxis,g+=a.plotX,h+=(a.plotLow?(a.plotLow+a.plotHigh)/2:a.plotY)+(!e&&i?i.top-f:0)}),g/=a.length,h/=a.length,c=[e?d.plotWidth-h:g,this.shared&&!e&&a.length>1&&b?b.chartY-f:e?d.plotHeight-g:h]),Ua(c,u)},getPosition:function(a,b,c){var g,d=this.chart,e=this.distance,f={},h=["y",d.chartHeight,b,c.plotY+d.plotTop],i=["x",d.chartWidth,a,c.plotX+d.plotLeft],j=c.ttBelow||d.inverted&&!c.negative||!d.inverted&&c.negative,k=function(a,b,c,d){var g=d-e>c,b=b>d+e+c,c=d-e-c;if(d+=e,j&&b)f[a]=d;else if(!j&&g)f[a]=c;else if(g)f[a]=c;else{if(!b)return!1;f[a]=d}},l=function(a,b,c,d){return e>d||d>b-e?!1:void(f[a]=c/2>d?1:d>b-c/2?b-c-2:d-c/2)},o=function(a){var b=h;h=i,i=b,g=a},n=function(){k.apply(0,h)!==!1?l.apply(0,i)===!1&&!g&&(o(!0),n()):g?f.x=f.y=0:(o(!0),n())};return(d.inverted||this.len>1)&&o(),n(),f},defaultFormatter:function(a){var d,b=this.points||qa(this),c=b[0].series;return d=[a.tooltipHeaderFormatter(b[0])],p(b,function(a){c=a.series,d.push(c.tooltipFormatter&&c.tooltipFormatter(a)||a.point.tooltipFormatter(c.tooltipOptions.pointFormat))}),d.push(a.options.footerFormat||""),d.join("")},refresh:function(a,b){var f,g,i,c=this.chart,d=this.label,e=this.options,h={},j=[];i=e.formatter||this.defaultFormatter;var k,h=c.hoverPoints,l=this.shared;clearTimeout(this.hideTimer),this.followPointer=qa(a)[0].series.tooltipOptions.followPointer,g=this.getAnchor(a,b),f=g[0],g=g[1],!l||a.series&&a.series.noSharedTooltip?h=a.getLabelConfig():(c.hoverPoints=a,h&&p(h,function(a){a.setState()}),p(a,function(a){a.setState("hover"),j.push(a.getLabelConfig())}),h={x:a[0].category,y:a[0].y},h.points=j,this.len=j.length,a=a[0]),i=i.call(h,this),h=a.series,this.distance=m(h.tooltipOptions.distance,16),i===!1?this.hide():(this.isHidden&&(bb(d),d.attr("opacity",1).show()),d.attr({text:i}),k=e.borderColor||a.color||h.color||"#606060",d.attr({stroke:k}),this.updatePosition({plotX:f,plotY:g,negative:a.negative,ttBelow:a.ttBelow}),this.isHidden=!1),D(c,"tooltipRefresh",{text:i,x:f+c.plotLeft,y:g+c.plotTop,borderColor:k})},updatePosition:function(a){var b=this.chart,c=this.label,c=(this.options.positioner||this.getPosition).call(this,c.width,c.height,a);this.move(u(c.x),u(c.y),a.plotX+b.plotLeft,a.plotY+b.plotTop)},tooltipHeaderFormatter:function(a){var h,b=a.series,c=b.tooltipOptions,d=c.dateTimeLabelFormats,e=c.xDateFormat,f=b.xAxis,g=f&&"datetime"===f.options.type&&ha(a.key),c=c.headerFormat,f=f&&f.closestPointRange;if(g&&!e){if(f){for(h in A)if(A[h]>=f||A[h]<=A.day&&a.key%A[h]>0){e=d[h];break}}else e=d.day;e=e||d.year}return g&&e&&(c=c.replace("{point.key}","{point.key:"+e+"}")),Ia(c,{point:a,series:b})}};var oa;$a=y.documentElement.ontouchstart!==t;var Wa=R.Pointer=function(a,b){this.init(a,b)};if(Wa.prototype={init:function(a,b){var f,c=b.chart,d=c.events,e=fa?"":c.zoomType,c=a.inverted;this.options=b,this.chart=a,this.zoomX=f=/x/.test(e),this.zoomY=e=/y/.test(e),this.zoomHor=f&&!c||e&&c,this.zoomVert=e&&!c||f&&c,this.hasZoom=f||e,this.runChartClick=d&&!!d.click,this.pinchDown=[],this.lastValidTouch={},R.Tooltip&&b.tooltip.enabled&&(a.tooltip=new Mb(a,b.tooltip),this.followTouchMove=b.tooltip.followTouchMove),this.setDOMEvents()},normalize:function(a,b){var c,d,a=a||window.event,a=Sb(a);return a.target||(a.target=a.srcElement),d=a.touches?a.touches.length?a.touches.item(0):a.changedTouches[0]:a,b||(this.chartPosition=b=Rb(this.chart.container)),d.pageX===t?(c=v(a.x,a.clientX-b.left),d=a.y):(c=d.pageX-b.left,d=d.pageY-b.top),q(a,{chartX:u(c),chartY:u(d)})},getCoordinates:function(a){var b={xAxis:[],yAxis:[]};return p(this.chart.axes,function(c){b[c.isXAxis?"xAxis":"yAxis"].push({axis:c,value:c.toValue(a[c.horiz?"chartX":"chartY"])})}),b},getIndex:function(a){var b=this.chart;return b.inverted?b.plotHeight+b.plotTop-a.chartY:a.chartX-b.plotLeft},runPointActions:function(a){var e,f,i,j,b=this.chart,c=b.series,d=b.tooltip,g=b.hoverPoint,h=b.hoverSeries,k=b.chartWidth,l=this.getIndex(a);if(d&&this.options.tooltip.shared&&(!h||!h.noSharedTooltip)){for(f=[],i=c.length,j=0;i>j;j++)c[j].visible&&c[j].options.enableMouseTracking!==!1&&!c[j].noSharedTooltip&&c[j].singularTooltips!==!0&&c[j].tooltipPoints.length&&(e=c[j].tooltipPoints[l])&&e.series&&(e._dist=M(l-e.clientX),k=C(k,e._dist),f.push(e));for(i=f.length;i--;)f[i]._dist>k&&f.splice(i,1);f.length&&f[0].clientX!==this.hoverX&&(d.refresh(f,a),this.hoverX=f[0].clientX)}c=h&&h.tooltipOptions.followPointer,h&&h.tracker&&!c?(e=h.tooltipPoints[l])&&e!==g&&e.onMouseOver(a):d&&c&&!d.isHidden&&(h=d.getAnchor([{}],a),d.updatePosition({plotX:h[0],plotY:h[1]})),d&&!this._onDocumentMouseMove&&(this._onDocumentMouseMove=function(a){V[oa]&&V[oa].pointer.onDocumentMouseMove(a)},K(y,"mousemove",this._onDocumentMouseMove)),p(b.axes,function(b){b.drawCrosshair(a,m(e,g))})},reset:function(a){var b=this.chart,c=b.hoverSeries,d=b.hoverPoint,e=b.tooltip,f=e&&e.shared?b.hoverPoints:d;(a=a&&e&&f)&&qa(f)[0].plotX===t&&(a=!1),a?(e.refresh(f),d&&d.setState(d.state,!0)):(d&&d.onMouseOut(),c&&c.onMouseOut(),e&&e.hide(),this._onDocumentMouseMove&&(W(y,"mousemove",this._onDocumentMouseMove),this._onDocumentMouseMove=null),p(b.axes,function(a){a.hideCrosshair()}),this.hoverX=null)},scaleGroups:function(a,b){var d,c=this.chart;p(c.series,function(e){d=a||e.getPlotBox(),e.xAxis&&e.xAxis.zoomEnabled&&(e.group.attr(d),e.markerGroup&&(e.markerGroup.attr(d),e.markerGroup.clip(b?c.clipRect:null)),e.dataLabelsGroup&&e.dataLabelsGroup.attr(d))}),c.clipRect.attr(b||c.clipBox)},dragStart:function(a){var b=this.chart;b.mouseIsDown=a.type,b.cancelClick=!1,b.mouseDownX=this.mouseDownX=a.chartX,b.mouseDownY=this.mouseDownY=a.chartY},drag:function(a){var l,b=this.chart,c=b.options.chart,d=a.chartX,e=a.chartY,f=this.zoomHor,g=this.zoomVert,h=b.plotLeft,i=b.plotTop,j=b.plotWidth,k=b.plotHeight,o=this.mouseDownX,n=this.mouseDownY;h>d?d=h:d>h+j&&(d=h+j),i>e?e=i:e>i+k&&(e=i+k),this.hasDragged=Math.sqrt(Math.pow(o-d,2)+Math.pow(n-e,2)),this.hasDragged>10&&(l=b.isInsidePlot(o-h,n-i),b.hasCartesianSeries&&(this.zoomX||this.zoomY)&&l&&!this.selectionMarker&&(this.selectionMarker=b.renderer.rect(h,i,f?1:j,g?1:k,0).attr({fill:c.selectionMarkerFill||"rgba(69,114,167,0.25)",zIndex:7}).add()),this.selectionMarker&&f&&(d-=o,this.selectionMarker.attr({width:M(d),x:(d>0?0:d)+o})),this.selectionMarker&&g&&(d=e-n,this.selectionMarker.attr({height:M(d),y:(d>0?0:d)+n})),l&&!this.selectionMarker&&c.panning&&b.pan(a,c.panning))},drop:function(a){var b=this.chart,c=this.hasPinched;if(this.selectionMarker){var i,d={xAxis:[],yAxis:[],originalEvent:a.originalEvent||a},a=this.selectionMarker,e=a.attr?a.attr("x"):a.x,f=a.attr?a.attr("y"):a.y,g=a.attr?a.attr("width"):a.width,h=a.attr?a.attr("height"):a.height;(this.hasDragged||c)&&(p(b.axes,function(a){if(a.zoomEnabled){var b=a.horiz,c=a.toValue(b?e:f),b=a.toValue(b?e+g:f+h);!isNaN(c)&&!isNaN(b)&&(d[a.coll].push({axis:a,min:C(c,b),max:v(c,b)}),i=!0)}}),i&&D(b,"selection",d,function(a){b.zoom(q(a,c?{animation:!1}:null))})),this.selectionMarker=this.selectionMarker.destroy(),c&&this.scaleGroups()}b&&(G(b.container,{cursor:b._cursor}),b.cancelClick=this.hasDragged>10,b.mouseIsDown=this.hasDragged=this.hasPinched=!1,this.pinchDown=[])},onContainerMouseDown:function(a){a=this.normalize(a),a.preventDefault&&a.preventDefault(),this.dragStart(a)},onDocumentMouseUp:function(a){V[oa]&&V[oa].pointer.drop(a)},onDocumentMouseMove:function(a){var b=this.chart,c=this.chartPosition,d=b.hoverSeries,a=this.normalize(a,c);c&&d&&!this.inClass(a.target,"highcharts-tracker")&&!b.isInsidePlot(a.chartX-b.plotLeft,a.chartY-b.plotTop)&&this.reset()},onContainerMouseLeave:function(){var a=V[oa];a&&(a.pointer.reset(),a.pointer.chartPosition=null)},onContainerMouseMove:function(a){var b=this.chart;oa=b.index,a=this.normalize(a),"mousedown"===b.mouseIsDown&&this.drag(a),(this.inClass(a.target,"highcharts-tracker")||b.isInsidePlot(a.chartX-b.plotLeft,a.chartY-b.plotTop))&&!b.openMenu&&this.runPointActions(a)},inClass:function(a,b){for(var c;a;){if(c=H(a,"class")){if(-1!==c.indexOf(b))return!0;if(-1!==c.indexOf("highcharts-container"))return!1}a=a.parentNode}},onTrackerMouseOut:function(a){var b=this.chart.hoverSeries,c=(a=a.relatedTarget||a.toElement)&&a.point&&a.point.series;!b||b.options.stickyTracking||this.inClass(a,"highcharts-tooltip")||c===b||b.onMouseOut()},onContainerClick:function(a){var b=this.chart,c=b.hoverPoint,d=b.plotLeft,e=b.plotTop,a=this.normalize(a);a.cancelBubble=!0,b.cancelClick||(c&&this.inClass(a.target,"highcharts-tracker")?(D(c.series,"click",q(a,{point:c})),b.hoverPoint&&c.firePointEvent("click",a)):(q(a,this.getCoordinates(a)),b.isInsidePlot(a.chartX-d,a.chartY-e)&&D(b,"click",a)))},setDOMEvents:function(){var a=this,b=a.chart.container;b.onmousedown=function(b){a.onContainerMouseDown(b)},b.onmousemove=function(b){a.onContainerMouseMove(b)},b.onclick=function(b){a.onContainerClick(b)},K(b,"mouseleave",a.onContainerMouseLeave),1===ab&&K(y,"mouseup",a.onDocumentMouseUp),$a&&(b.ontouchstart=function(b){a.onContainerTouchStart(b)},b.ontouchmove=function(b){a.onContainerTouchMove(b)},1===ab&&K(y,"touchend",a.onDocumentTouchEnd))},destroy:function(){var a;W(this.chart.container,"mouseleave",this.onContainerMouseLeave),ab||(W(y,"mouseup",this.onDocumentMouseUp),W(y,"touchend",this.onDocumentTouchEnd)),clearInterval(this.tooltipTimeout);for(a in this)this[a]=null}},q(R.Pointer.prototype,{pinchTranslate:function(a,b,c,d,e,f){(this.zoomHor||this.pinchHor)&&this.pinchTranslateDirection(!0,a,b,c,d,e,f),(this.zoomVert||this.pinchVert)&&this.pinchTranslateDirection(!1,a,b,c,d,e,f)},pinchTranslateDirection:function(a,b,c,d,e,f,g,h){var s,m,y,i=this.chart,j=a?"x":"y",k=a?"X":"Y",l="chart"+k,o=a?"width":"height",n=i["plot"+(a?"Left":"Top")],p=h||1,q=i.inverted,x=i.bounds[a?"h":"v"],r=1===b.length,v=b[0][l],u=c[0][l],t=!r&&b[1][l],w=!r&&c[1][l],c=function(){!r&&M(v-t)>20&&(p=h||M(u-w)/M(v-t)),m=(n-u)/p+v,s=i["plot"+(a?"Width":"Height")]/p};c(),b=m,b<x.min?(b=x.min,y=!0):b+s>x.max&&(b=x.max-s,y=!0),y?(u-=.8*(u-g[j][0]),r||(w-=.8*(w-g[j][1])),c()):g[j]=[u,w],q||(f[j]=m-n,f[o]=s),f=q?1/p:p,e[o]=s,e[j]=b,d[q?a?"scaleY":"scaleX":"scale"+k]=p,d["translate"+k]=f*n+(u-f*v)},pinch:function(a){var b=this,c=b.chart,d=b.pinchDown,e=b.followTouchMove,f=a.touches,g=f.length,h=b.lastValidTouch,i=b.hasZoom,j=b.selectionMarker,k={},l=1===g&&(b.inClass(a.target,"highcharts-tracker")&&c.runTrackerClick||c.runChartClick),o={};(i||e)&&!l&&a.preventDefault(),Ua(f,function(a){return b.normalize(a)}),"touchstart"===a.type?(p(f,function(a,b){d[b]={chartX:a.chartX,chartY:a.chartY}}),h.x=[d[0].chartX,d[1]&&d[1].chartX],h.y=[d[0].chartY,d[1]&&d[1].chartY],p(c.axes,function(a){if(a.zoomEnabled){var b=c.bounds[a.horiz?"h":"v"],d=a.minPixelPadding,e=a.toPixels(a.dataMin),f=a.toPixels(a.dataMax),g=C(e,f),e=v(e,f);b.min=C(a.pos,g-d),b.max=v(a.pos+a.len,e+d)}})):d.length&&(j||(b.selectionMarker=j=q({destroy:sa},c.plotBox)),b.pinchTranslate(d,f,k,j,o,h),b.hasPinched=i,b.scaleGroups(k,o),!i&&e&&1===g&&this.runPointActions(b.normalize(a)))},onContainerTouchStart:function(a){var b=this.chart;oa=b.index,1===a.touches.length?(a=this.normalize(a),b.isInsidePlot(a.chartX-b.plotLeft,a.chartY-b.plotTop)?(this.runPointActions(a),this.pinch(a)):this.reset()):2===a.touches.length&&this.pinch(a)},onContainerTouchMove:function(a){(1===a.touches.length||2===a.touches.length)&&this.pinch(a)},onDocumentTouchEnd:function(a){V[oa]&&V[oa].pointer.drop(a)}}),I.PointerEvent||I.MSPointerEvent){var ua={},zb=!!I.PointerEvent,Wb=function(){var a,b=[];b.item=function(a){return this[a]};for(a in ua)ua.hasOwnProperty(a)&&b.push({pageX:ua[a].pageX,pageY:ua[a].pageY,target:ua[a].target});return b},Ab=function(a,b,c,d){a=a.originalEvent||a,"touch"!==a.pointerType&&a.pointerType!==a.MSPOINTER_TYPE_TOUCH||!V[oa]||(d(a),d=V[oa].pointer,d[b]({type:c,target:a.currentTarget,preventDefault:sa,touches:Wb()}))};q(Wa.prototype,{onContainerPointerDown:function(a){Ab(a,"onContainerTouchStart","touchstart",function(a){ua[a.pointerId]={pageX:a.pageX,pageY:a.pageY,target:a.currentTarget}})},onContainerPointerMove:function(a){Ab(a,"onContainerTouchMove","touchmove",function(a){ua[a.pointerId]={pageX:a.pageX,pageY:a.pageY},ua[a.pointerId].target||(ua[a.pointerId].target=a.currentTarget)})},onDocumentPointerUp:function(a){Ab(a,"onContainerTouchEnd","touchend",function(a){delete ua[a.pointerId]})},batchMSEvents:function(a){a(this.chart.container,zb?"pointerdown":"MSPointerDown",this.onContainerPointerDown),a(this.chart.container,zb?"pointermove":"MSPointerMove",this.onContainerPointerMove),a(y,zb?"pointerup":"MSPointerUp",this.onDocumentPointerUp)}}),Ma(Wa.prototype,"init",function(a,b,c){a.call(this,b,c),(this.hasZoom||this.followTouchMove)&&G(b.container,{"-ms-touch-action":Q,"touch-action":Q})}),Ma(Wa.prototype,"setDOMEvents",function(a){a.apply(this),(this.hasZoom||this.followTouchMove)&&this.batchMSEvents(K)}),Ma(Wa.prototype,"destroy",function(a){this.batchMSEvents(W),a.call(this)})}var lb=R.Legend=function(a,b){this.init(a,b)};lb.prototype={init:function(a,b){var c=this,d=b.itemStyle,e=m(b.padding,8),f=b.itemMarginTop||0;this.options=b,b.enabled&&(c.baseline=z(d.fontSize)+3+f,c.itemStyle=d,c.itemHiddenStyle=w(d,b.itemHiddenStyle),c.itemMarginTop=f,c.padding=e,c.initialItemX=e,c.initialItemY=e-5,c.maxItemWidth=0,c.chart=a,c.itemHeight=0,c.lastLineHeight=0,c.symbolWidth=m(b.symbolWidth,16),c.pages=[],c.render(),K(c.chart,"endResize",function(){c.positionCheckboxes()}))},colorizeItem:function(a,b){var j,c=this.options,d=a.legendItem,e=a.legendLine,f=a.legendSymbol,g=this.itemHiddenStyle.color,c=b?c.itemStyle.color:g,h=b?a.legendColor||a.color||"#CCC":g,g=a.options&&a.options.marker,i={fill:h};if(d&&d.css({fill:c,color:c}),e&&e.attr({stroke:h}),f){if(g&&f.isMarker)for(j in i.stroke=h,g=a.convertAttribs(g))d=g[j],d!==t&&(i[j]=d);f.attr(i)}},positionItem:function(a){var b=this.options,c=b.symbolPadding,b=!b.rtl,d=a._legendItemPos,e=d[0],d=d[1],f=a.checkbox;a.legendGroup&&a.legendGroup.translate(b?e:this.legendWidth-e-2*c-4,d),f&&(f.x=e,f.y=d)},destroyItem:function(a){var b=a.checkbox;p(["legendItem","legendLine","legendSymbol","legendGroup"],function(b){a[b]&&(a[b]=a[b].destroy())}),b&&Pa(a.checkbox)},destroy:function(){var a=this.group,b=this.box;b&&(this.box=b.destroy()),a&&(this.group=a.destroy())},positionCheckboxes:function(a){var c,b=this.group.alignAttr,d=this.clipHeight||this.legendHeight;b&&(c=b.translateY,p(this.allItems,function(e){var g,f=e.checkbox;f&&(g=c+f.y+(a||0)+3,G(f,{left:b.translateX+e.checkboxOffset+f.x-20+"px",top:g+"px",display:g>c-6&&c+d-6>g?"":Q}))}))},renderTitle:function(){var a=this.padding,b=this.options.title,c=0;b.text&&(this.title||(this.title=this.chart.renderer.label(b.text,a-3,a-4,null,null,null,null,null,"legend-title").attr({zIndex:1}).css(b.style).add(this.group)),a=this.title.getBBox(),c=a.height,this.offsetWidth=a.width,this.contentGroup.attr({translateY:c})),this.titleHeight=c},renderItem:function(a){var b=this.chart,c=b.renderer,d=this.options,e="horizontal"===d.layout,f=this.symbolWidth,g=d.symbolPadding,h=this.itemStyle,i=this.itemHiddenStyle,j=this.padding,k=e?m(d.itemDistance,20):0,l=!d.rtl,o=d.width,n=d.itemMarginBottom||0,s=this.itemMarginTop,p=this.initialItemX,q=a.legendItem,r=a.series&&a.series.drawLegendSymbol?a.series:a,x=r.options,x=this.createCheckboxForItem&&x&&x.showCheckbox,t=d.useHTML;q||(a.legendGroup=c.g("legend-item").attr({zIndex:1}).add(this.scrollGroup),r.drawLegendSymbol(this,a),a.legendItem=q=c.text(d.labelFormat?Ia(d.labelFormat,a):d.labelFormatter.call(a),l?f+g:-g,this.baseline,t).css(w(a.visible?h:i)).attr({align:l?"left":"right",zIndex:2}).add(a.legendGroup),this.setItemEvents&&this.setItemEvents(a,q,t,h,i),this.colorizeItem(a,a.visible),x&&this.createCheckboxForItem(a)),c=q.getBBox(),f=a.checkboxOffset=d.itemWidth||a.legendItemWidth||f+g+c.width+k+(x?20:0),this.itemHeight=g=u(a.legendItemHeight||c.height),e&&this.itemX-p+f>(o||b.chartWidth-2*j-p-d.x)&&(this.itemX=p,this.itemY+=s+this.lastLineHeight+n,this.lastLineHeight=0),this.maxItemWidth=v(this.maxItemWidth,f),this.lastItemY=s+this.itemY+n,this.lastLineHeight=v(g,this.lastLineHeight),a._legendItemPos=[this.itemX,this.itemY],e?this.itemX+=f:(this.itemY+=s+g+n,this.lastLineHeight=g),this.offsetWidth=o||v((e?this.itemX-p-k:f)+j,this.offsetWidth)},getAllItems:function(){var a=[];return p(this.chart.series,function(b){var c=b.options;m(c.showInLegend,r(c.linkedTo)?!1:t,!0)&&(a=a.concat(b.legendItems||("point"===c.legendType?b.data:b)))}),a},render:function(){var e,f,g,h,a=this,b=a.chart,c=b.renderer,d=a.group,i=a.box,j=a.options,k=a.padding,l=j.borderWidth,o=j.backgroundColor;a.itemX=a.initialItemX,a.itemY=a.initialItemY,a.offsetWidth=0,a.lastItemY=0,d||(a.group=d=c.g("legend").attr({zIndex:7}).add(),a.contentGroup=c.g().attr({zIndex:1}).add(d),a.scrollGroup=c.g().add(a.contentGroup)),a.renderTitle(),e=a.getAllItems(),ob(e,function(a,b){return(a.options&&a.options.legendIndex||0)-(b.options&&b.options.legendIndex||0)}),j.reversed&&e.reverse(),a.allItems=e,a.display=f=!!e.length,p(e,function(b){a.renderItem(b)}),g=j.width||a.offsetWidth,h=a.lastItemY+a.lastLineHeight+a.titleHeight,h=a.handleOverflow(h),(l||o)&&(g+=k,h+=k,i?g>0&&h>0&&(i[i.isNew?"attr":"animate"](i.crisp({width:g,height:h})),i.isNew=!1):(a.box=i=c.rect(0,0,g,h,j.borderRadius,l||0).attr({stroke:j.borderColor,"stroke-width":l||0,fill:o||Q}).add(d).shadow(j.shadow),i.isNew=!0),i[f?"show":"hide"]()),a.legendWidth=g,a.legendHeight=h,p(e,function(b){a.positionItem(b)}),f&&d.align(q({width:g,height:h},j),!0,"spacingBox"),b.isResizing||this.positionCheckboxes()},handleOverflow:function(a){var h,s,b=this,c=this.chart,d=c.renderer,e=this.options,f=e.y,f=c.spacingBox.height+("top"===e.verticalAlign?-f:f)-this.padding,g=e.maxHeight,i=this.clipRect,j=e.navigation,k=m(j.animation,!0),l=j.arrowSize||12,o=this.nav,n=this.pages,q=this.allItems;return"horizontal"===e.layout&&(f/=2),g&&(f=C(f,g)),n.length=0,a>f&&!e.useHTML?(this.clipHeight=h=f-20-this.titleHeight-this.padding,this.currentPage=m(this.currentPage,1),this.fullHeight=a,p(q,function(a,b){var c=a._legendItemPos[1],d=u(a.legendItem.getBBox().height),e=n.length;(!e||c-n[e-1]>h&&(s||c)!==n[e-1])&&(n.push(s||c),e++),b===q.length-1&&c+d-n[e-1]>h&&n.push(c),c!==s&&(s=c)}),i||(i=b.clipRect=d.clipRect(0,this.padding,9999,0),b.contentGroup.clip(i)),i.attr({height:h}),o||(this.nav=o=d.g().attr({zIndex:1}).add(this.group),this.up=d.symbol("triangle",0,0,l,l).on("click",function(){b.scroll(-1,k)}).add(o),this.pager=d.text("",15,10).css(j.style).add(o),this.down=d.symbol("triangle-down",0,0,l,l).on("click",function(){b.scroll(1,k)}).add(o)),b.scroll(0),a=f):o&&(i.attr({height:c.chartHeight}),o.hide(),this.scrollGroup.attr({translateY:1}),this.clipHeight=0),a},scroll:function(a,b){var c=this.pages,d=c.length,e=this.currentPage+a,f=this.clipHeight,g=this.options.navigation,h=g.activeColor,g=g.inactiveColor,i=this.pager,j=this.padding;e>d&&(e=d),e>0&&(b!==t&&Qa(b,this.chart),this.nav.attr({translateX:j,translateY:f+this.padding+7+this.titleHeight,visibility:"visible"}),this.up.attr({fill:1===e?g:h}).css({cursor:1===e?"default":"pointer"}),i.attr({text:e+"/"+d}),this.down.attr({x:18+this.pager.getBBox().width,fill:e===d?g:h}).css({cursor:e===d?"default":"pointer"}),c=-c[e-1]+this.initialItemY,this.scrollGroup.animate({translateY:c}),this.currentPage=e,this.positionCheckboxes(c))}},N=R.LegendSymbolMixin={drawRectangle:function(a,b){var c=a.options.symbolHeight||12;b.legendSymbol=this.chart.renderer.rect(0,a.baseline-5-c/2,a.symbolWidth,c,a.options.symbolRadius||0).attr({zIndex:3}).add(b.legendGroup)},drawLineMarker:function(a){var d,b=this.options,c=b.marker;d=a.symbolWidth;var g,e=this.chart.renderer,f=this.legendGroup,a=a.baseline-u(.3*e.fontMetrics(a.options.itemStyle.fontSize).b);b.lineWidth&&(g={"stroke-width":b.lineWidth},b.dashStyle&&(g.dashstyle=b.dashStyle),this.legendLine=e.path(["M",0,a,"L",d,a]).attr(g).add(f)),c&&c.enabled!==!1&&(b=c.radius,this.legendSymbol=d=e.symbol(this.symbol,d/2-b,a-b,2*b,2*b).add(f),d.isMarker=!0)}},(/Trident\/7\.0/.test(wa)||Ta)&&Ma(lb.prototype,"positionItem",function(a,b){var c=this,d=function(){b._legendItemPos&&a.call(c,b)};d(),setTimeout(d)}),Ya.prototype={init:function(a,b){var c,d=a.series;a.series=null,c=w(E,a),c.series=a.series=d,this.userOptions=a,d=c.chart,this.margin=this.splashArray("margin",d),this.spacing=this.splashArray("spacing",d);var e=d.events;this.bounds={h:{},v:{}},this.callback=b,this.isResizing=0,this.options=c,this.axes=[],this.series=[],this.hasCartesianSeries=d.showAxes;var g,f=this;if(f.index=V.length,V.push(f),ab++,d.reflow!==!1&&K(f,"load",function(){f.initReflow()}),e)for(g in e)K(f,g,e[g]);f.xAxis=[],f.yAxis=[],f.animation=fa?!1:m(d.animation,!0),f.pointCount=0,f.counters=new Bb,f.firstRender()},initSeries:function(a){var b=this.options.chart;return(b=F[a.type||b.type||b.defaultSeriesType])||ra(17,!0),b=new b,b.init(this,a),b},isInsidePlot:function(a,b,c){var d=c?b:a,a=c?a:b;return d>=0&&d<=this.plotWidth&&a>=0&&a<=this.plotHeight},adjustTickAmounts:function(){this.options.chart.alignTicks!==!1&&p(this.axes,function(a){a.adjustTickAmount()}),this.maxTicks=null},redraw:function(a){var g,h,b=this.axes,c=this.series,d=this.pointer,e=this.legend,f=this.isDirtyLegend,i=this.isDirtyBox,j=c.length,k=j,l=this.renderer,o=l.isHidden(),n=[];for(Qa(a,this),o&&this.cloneRenderTo(),this.layOutTitles();k--;)if(a=c[k],a.options.stacking&&(g=!0,a.isDirty)){h=!0;break}if(h)for(k=j;k--;)a=c[k],a.options.stacking&&(a.isDirty=!0);p(c,function(a){a.isDirty&&"point"===a.options.legendType&&(f=!0)}),f&&e.options.enabled&&(e.render(),this.isDirtyLegend=!1),g&&this.getStacks(),this.hasCartesianSeries&&(this.isResizing||(this.maxTicks=null,p(b,function(a){a.setScale()})),this.adjustTickAmounts(),this.getMargins(),p(b,function(a){a.isDirty&&(i=!0)}),p(b,function(a){a.isDirtyExtremes&&(a.isDirtyExtremes=!1,n.push(function(){D(a,"afterSetExtremes",q(a.eventArgs,a.getExtremes())),delete a.eventArgs})),(i||g)&&a.redraw()})),i&&this.drawChartBox(),p(c,function(a){a.isDirty&&a.visible&&(!a.isCartesian||a.xAxis)&&a.redraw()}),d&&d.reset(!0),l.draw(),D(this,"redraw"),o&&this.cloneRenderTo(!0),p(n,function(a){a.call()})},get:function(a){var d,e,b=this.axes,c=this.series;for(d=0;d<b.length;d++)if(b[d].options.id===a)return b[d];for(d=0;d<c.length;d++)if(c[d].options.id===a)return c[d];for(d=0;d<c.length;d++)for(e=c[d].points||[],b=0;b<e.length;b++)if(e[b].id===a)return e[b];return null},getAxes:function(){var a=this,b=this.options,c=b.xAxis=qa(b.xAxis||{}),b=b.yAxis=qa(b.yAxis||{});p(c,function(a,b){a.index=b,a.isX=!0}),p(b,function(a,b){a.index=b}),c=c.concat(b),p(c,function(b){new la(a,b)}),a.adjustTickAmounts()},getSelectedPoints:function(){var a=[];return p(this.series,function(b){a=a.concat(vb(b.points||[],function(a){return a.selected}))
|
4 |
+
}),a},getSelectedSeries:function(){return vb(this.series,function(a){return a.selected})},getStacks:function(){var a=this;p(a.yAxis,function(a){a.stacks&&a.hasVisibleSeries&&(a.oldStacks=a.stacks)}),p(a.series,function(b){!b.options.stacking||b.visible!==!0&&a.options.chart.ignoreHiddenSeries!==!1||(b.stackKey=b.type+m(b.options.stack,""))})},setTitle:function(a,b,c){var g,f,d=this,e=d.options;f=e.title=w(e.title,a),g=e.subtitle=w(e.subtitle,b),e=g,p([["title",a,f],["subtitle",b,e]],function(a){var b=a[0],c=d[b],e=a[1],a=a[2];c&&e&&(d[b]=c=c.destroy()),a&&a.text&&!c&&(d[b]=d.renderer.text(a.text,0,0,a.useHTML).attr({align:a.align,"class":"highcharts-"+b,zIndex:a.zIndex||4}).css(a.style).add())}),d.layOutTitles(c)},layOutTitles:function(a){var b=0,c=this.title,d=this.subtitle,e=this.options,f=e.title,e=e.subtitle,g=this.spacingBox.width-44;!c||(c.css({width:(f.width||g)+"px"}).align(q({y:15},f),!1,"spacingBox"),f.floating||f.verticalAlign)||(b=c.getBBox().height),d&&(d.css({width:(e.width||g)+"px"}).align(q({y:b+f.margin},e),!1,"spacingBox"),!e.floating&&!e.verticalAlign&&(b=Ka(b+d.getBBox().height))),c=this.titleOffset!==b,this.titleOffset=b,!this.isDirtyBox&&c&&(this.isDirtyBox=c,this.hasRendered&&m(a,!0)&&this.isDirtyBox&&this.redraw())},getChartSize:function(){var a=this.options.chart,b=a.width,a=a.height,c=this.renderToClone||this.renderTo;r(b)||(this.containerWidth=jb(c,"width")),r(a)||(this.containerHeight=jb(c,"height")),this.chartWidth=v(0,b||this.containerWidth||600),this.chartHeight=v(0,m(a,this.containerHeight>19?this.containerHeight:400))},cloneRenderTo:function(a){var b=this.renderToClone,c=this.container;a?b&&(this.renderTo.appendChild(c),Pa(b),delete this.renderToClone):(c&&c.parentNode===this.renderTo&&this.renderTo.removeChild(c),this.renderToClone=b=this.renderTo.cloneNode(0),G(b,{position:"absolute",top:"-9999px",display:"block"}),b.style.setProperty&&b.style.setProperty("display","block","important"),y.body.appendChild(b),c&&b.appendChild(c))},getContainer:function(){var a,c,d,e,b=this.options.chart;this.renderTo=a=b.renderTo,e="highcharts-"+tb++,Fa(a)&&(this.renderTo=a=y.getElementById(a)),a||ra(13,!0),c=z(H(a,"data-highcharts-chart")),!isNaN(c)&&V[c]&&V[c].hasRendered&&V[c].destroy(),H(a,"data-highcharts-chart",this.index),a.innerHTML="",!b.skipClone&&!a.offsetWidth&&this.cloneRenderTo(),this.getChartSize(),c=this.chartWidth,d=this.chartHeight,this.container=a=Y(Ja,{className:"highcharts-container"+(b.className?" "+b.className:""),id:e},q({position:"relative",overflow:"hidden",width:c+"px",height:d+"px",textAlign:"left",lineHeight:"normal",zIndex:0,"-webkit-tap-highlight-color":"rgba(0,0,0,0)"},b.style),this.renderToClone||a),this._cursor=a.style.cursor,this.renderer=b.forExport?new ta(a,c,d,b.style,!0):new Za(a,c,d,b.style),fa&&this.renderer.create(this,a,c,d)},getMargins:function(){var b,a=this.spacing,c=this.legend,d=this.margin,e=this.options.legend,f=m(e.margin,20),g=e.x,h=e.y,i=e.align,j=e.verticalAlign,k=this.titleOffset;this.resetMargins(),b=this.axisOffset,k&&!r(d[0])&&(this.plotTop=v(this.plotTop,k+this.options.title.margin+a[0])),c.display&&!e.floating&&("right"===i?r(d[1])||(this.marginRight=v(this.marginRight,c.legendWidth-g+f+a[1])):"left"===i?r(d[3])||(this.plotLeft=v(this.plotLeft,c.legendWidth+g+f+a[3])):"top"===j?r(d[0])||(this.plotTop=v(this.plotTop,c.legendHeight+h+f+a[0])):"bottom"!==j||r(d[2])||(this.marginBottom=v(this.marginBottom,c.legendHeight-h+f+a[2]))),this.extraBottomMargin&&(this.marginBottom+=this.extraBottomMargin),this.extraTopMargin&&(this.plotTop+=this.extraTopMargin),this.hasCartesianSeries&&p(this.axes,function(a){a.getOffset()}),r(d[3])||(this.plotLeft+=b[3]),r(d[0])||(this.plotTop+=b[0]),r(d[2])||(this.marginBottom+=b[2]),r(d[1])||(this.marginRight+=b[1]),this.setChartSize()},reflow:function(a){var b=this,c=b.options.chart,d=b.renderTo,e=c.width||jb(d,"width"),f=c.height||jb(d,"height"),c=a?a.target:I,d=function(){b.container&&(b.setSize(e,f,!1),b.hasUserSize=null)};b.hasUserSize||!e||!f||c!==I&&c!==y||((e!==b.containerWidth||f!==b.containerHeight)&&(clearTimeout(b.reflowTimeout),a?b.reflowTimeout=setTimeout(d,100):d()),b.containerWidth=e,b.containerHeight=f)},initReflow:function(){var a=this,b=function(b){a.reflow(b)};K(I,"resize",b),K(a,"destroy",function(){W(I,"resize",b)})},setSize:function(a,b,c){var e,f,g,d=this;d.isResizing+=1,g=function(){d&&D(d,"endResize",null,function(){d.isResizing-=1})},Qa(c,d),d.oldChartHeight=d.chartHeight,d.oldChartWidth=d.chartWidth,r(a)&&(d.chartWidth=e=v(0,u(a)),d.hasUserSize=!!e),r(b)&&(d.chartHeight=f=v(0,u(b))),(va?kb:G)(d.container,{width:e+"px",height:f+"px"},va),d.setChartSize(!0),d.renderer.setSize(e,f,c),d.maxTicks=null,p(d.axes,function(a){a.isDirty=!0,a.setScale()}),p(d.series,function(a){a.isDirty=!0}),d.isDirtyLegend=!0,d.isDirtyBox=!0,d.layOutTitles(),d.getMargins(),d.redraw(c),d.oldChartHeight=null,D(d,"resize"),va===!1?g():setTimeout(g,va&&va.duration||500)},setChartSize:function(a){var i,j,k,l,b=this.inverted,c=this.renderer,d=this.chartWidth,e=this.chartHeight,f=this.options.chart,g=this.spacing,h=this.clipOffset;this.plotLeft=i=u(this.plotLeft),this.plotTop=j=u(this.plotTop),this.plotWidth=k=v(0,u(d-i-this.marginRight)),this.plotHeight=l=v(0,u(e-j-this.marginBottom)),this.plotSizeX=b?l:k,this.plotSizeY=b?k:l,this.plotBorderWidth=f.plotBorderWidth||0,this.spacingBox=c.spacingBox={x:g[3],y:g[0],width:d-g[3]-g[1],height:e-g[0]-g[2]},this.plotBox=c.plotBox={x:i,y:j,width:k,height:l},d=2*T(this.plotBorderWidth/2),b=Ka(v(d,h[3])/2),c=Ka(v(d,h[0])/2),this.clipBox={x:b,y:c,width:T(this.plotSizeX-v(d,h[1])/2-b),height:T(this.plotSizeY-v(d,h[2])/2-c)},a||p(this.axes,function(a){a.setAxisSize(),a.setAxisTranslation()})},resetMargins:function(){var a=this.spacing,b=this.margin;this.plotTop=m(b[0],a[0]),this.marginRight=m(b[1],a[1]),this.marginBottom=m(b[2],a[2]),this.plotLeft=m(b[3],a[3]),this.axisOffset=[0,0,0,0],this.clipOffset=[0,0,0,0]},drawChartBox:function(){var n,a=this.options.chart,b=this.renderer,c=this.chartWidth,d=this.chartHeight,e=this.chartBackground,f=this.plotBackground,g=this.plotBorder,h=this.plotBGImage,i=a.borderWidth||0,j=a.backgroundColor,k=a.plotBackgroundColor,l=a.plotBackgroundImage,o=a.plotBorderWidth||0,s=this.plotLeft,m=this.plotTop,p=this.plotWidth,q=this.plotHeight,r=this.plotBox,v=this.clipRect,u=this.clipBox;n=i+(a.shadow?8:0),(i||j)&&(e?e.animate(e.crisp({width:c-n,height:d-n})):(e={fill:j||Q},i&&(e.stroke=a.borderColor,e["stroke-width"]=i),this.chartBackground=b.rect(n/2,n/2,c-n,d-n,a.borderRadius,i).attr(e).addClass("highcharts-background").add().shadow(a.shadow))),k&&(f?f.animate(r):this.plotBackground=b.rect(s,m,p,q,0).attr({fill:k}).add().shadow(a.plotShadow)),l&&(h?h.animate(r):this.plotBGImage=b.image(l,s,m,p,q).add()),v?v.animate({width:u.width,height:u.height}):this.clipRect=b.clipRect(u),o&&(g?g.animate(g.crisp({x:s,y:m,width:p,height:q})):this.plotBorder=b.rect(s,m,p,q,0,-o).attr({stroke:a.plotBorderColor,"stroke-width":o,fill:Q,zIndex:1}).add()),this.isDirtyBox=!1},propFromSeries:function(){var c,e,f,a=this,b=a.options.chart,d=a.options.series;p(["inverted","angular","polar"],function(g){for(c=F[b.type||b.defaultSeriesType],f=a[g]||b[g]||c&&c.prototype[g],e=d&&d.length;!f&&e--;)(c=F[d[e].type])&&c.prototype[g]&&(f=!0);a[g]=f})},linkSeries:function(){var a=this,b=a.series;p(b,function(a){a.linkedSeries.length=0}),p(b,function(b){var d=b.options.linkedTo;Fa(d)&&(d=":previous"===d?a.series[b.index-1]:a.get(d))&&(d.linkedSeries.push(b),b.linkedParent=d)})},renderSeries:function(){p(this.series,function(a){a.translate(),a.setTooltipPoints&&a.setTooltipPoints(),a.render()})},render:function(){var g,a=this,b=a.axes,c=a.renderer,d=a.options,e=d.labels,f=d.credits;a.setTitle(),a.legend=new lb(a,d.legend),a.getStacks(),p(b,function(a){a.setScale()}),a.getMargins(),a.maxTicks=null,p(b,function(a){a.setTickPositions(!0),a.setMaxTicks()}),a.adjustTickAmounts(),a.getMargins(),a.drawChartBox(),a.hasCartesianSeries&&p(b,function(a){a.render()}),a.seriesGroup||(a.seriesGroup=c.g("series-group").attr({zIndex:3}).add()),a.renderSeries(),e.items&&p(e.items,function(b){var d=q(e.style,b.style),f=z(d.left)+a.plotLeft,g=z(d.top)+a.plotTop+12;delete d.left,delete d.top,c.text(b.html,f,g).attr({zIndex:2}).css(d).add()}),f.enabled&&!a.credits&&(g=f.href,a.credits=c.text(f.text,0,0).on("click",function(){g&&(location.href=g)}).attr({align:f.position.align,zIndex:8}).css(f.style).add().align(f.position)),a.hasRendered=!0},destroy:function(){var e,a=this,b=a.axes,c=a.series,d=a.container,f=d&&d.parentNode;for(D(a,"destroy"),V[a.index]=t,ab--,a.renderTo.removeAttribute("data-highcharts-chart"),W(a),e=b.length;e--;)b[e]=b[e].destroy();for(e=c.length;e--;)c[e]=c[e].destroy();p("title,subtitle,chartBackground,plotBackground,plotBGImage,plotBorder,seriesGroup,clipRect,credits,pointer,scroller,rangeSelector,legend,resetZoomButton,tooltip,renderer".split(","),function(b){var c=a[b];c&&c.destroy&&(a[b]=c.destroy())}),d&&(d.innerHTML="",W(d),f&&Pa(d));for(e in a)delete a[e]},isReadyToRender:function(){var a=this;return!aa&&I==I.top&&"complete"!==y.readyState||fa&&!I.canvg?(fa?Lb.push(function(){a.firstRender()},a.options.global.canvasToolsURL):y.attachEvent("onreadystatechange",function(){y.detachEvent("onreadystatechange",a.firstRender),"complete"===y.readyState&&a.firstRender()}),!1):!0},firstRender:function(){var a=this,b=a.options,c=a.callback;a.isReadyToRender()&&(a.getContainer(),D(a,"init"),a.resetMargins(),a.setChartSize(),a.propFromSeries(),a.getAxes(),p(b.series||[],function(b){a.initSeries(b)}),a.linkSeries(),D(a,"beforeRender"),R.Pointer&&(a.pointer=new Wa(a,b)),a.render(),a.renderer.draw(),c&&c.apply(a,[a]),p(a.callbacks,function(b){b.apply(a,[a])}),a.cloneRenderTo(!0),D(a,"load"))},splashArray:function(a,b){var c=b[a],c=ca(c)?c:[c,c,c,c];return[m(b[a+"Top"],c[0]),m(b[a+"Right"],c[1]),m(b[a+"Bottom"],c[2]),m(b[a+"Left"],c[3])]}},Ya.prototype.callbacks=[],X=R.CenteredSeriesMixin={getCenter:function(){var d,h,a=this.options,b=this.chart,c=2*(a.slicedOffset||0),e=b.plotWidth-2*c,f=b.plotHeight-2*c,b=a.center,a=[m(b[0],"50%"),m(b[1],"50%"),a.size||"100%",a.innerSize||0],g=C(e,f);return Ua(a,function(a,b){return h=/%$/.test(a),d=2>b||2===b&&h,(h?[e,f,g,g][b]*z(a)/100:a)+(d?c:0)})}};var Ea=function(){};Ea.prototype={init:function(a,b,c){return this.series=a,this.applyOptions(b,c),this.pointAttr={},a.options.colorByPoint&&(b=a.options.colors||a.chart.options.colors,this.color=this.color||b[a.colorCounter++],a.colorCounter===b.length)&&(a.colorCounter=0),a.chart.pointCount++,this},applyOptions:function(a,b){var c=this.series,d=c.pointValKey,a=Ea.prototype.optionsToObject.call(this,a);return q(this,a),this.options=this.options?q(this.options,a):a,d&&(this.y=this[d]),this.x===t&&c&&(this.x=b===t?c.autoIncrement():b),this},optionsToObject:function(a){var b={},c=this.series,d=c.pointArrayMap||["y"],e=d.length,f=0,g=0;if("number"==typeof a||null===a)b[d[0]]=a;else if(La(a))for(a.length>e&&(c=typeof a[0],"string"===c?b.name=a[0]:"number"===c&&(b.x=a[0]),f++);e>g;)b[d[g++]]=a[f++];else"object"==typeof a&&(b=a,a.dataLabels&&(c._hasPointLabels=!0),a.marker&&(c._hasPointMarkers=!0));return b},destroy:function(){var c,a=this.series.chart,b=a.hoverPoints;a.pointCount--,b&&(this.setState(),ja(b,this),!b.length)&&(a.hoverPoints=null),this===a.hoverPoint&&this.onMouseOut(),(this.graphic||this.dataLabel)&&(W(this),this.destroyElements()),this.legendItem&&a.legend.destroyItem(this);for(c in this)this[c]=null},destroyElements:function(){for(var b,a="graphic,dataLabel,dataLabelUpper,group,connector,shadowGroup".split(","),c=6;c--;)b=a[c],this[b]&&(this[b]=this[b].destroy())},getLabelConfig:function(){return{x:this.category,y:this.y,key:this.name||this.category,series:this.series,point:this,percentage:this.percentage,total:this.total||this.stackTotal}},tooltipFormatter:function(a){var b=this.series,c=b.tooltipOptions,d=m(c.valueDecimals,""),e=c.valuePrefix||"",f=c.valueSuffix||"";return p(b.pointArrayMap||["y"],function(b){b="{point."+b,(e||f)&&(a=a.replace(b+"}",e+b+"}"+f)),a=a.replace(b+"}",b+":,."+d+"f}")}),Ia(a,{point:this,series:this.series})},firePointEvent:function(a,b,c){var d=this,e=this.series.options;(e.point.events[a]||d.options&&d.options.events&&d.options.events[a])&&this.importEvents(),"click"===a&&e.allowPointSelect&&(c=function(a){d.select(null,a.ctrlKey||a.metaKey||a.shiftKey)}),D(this,a,b,c)}};var O=function(){};O.prototype={isCartesian:!0,type:"line",pointClass:Ea,sorted:!0,requireSorting:!0,pointAttrToOptions:{stroke:"lineColor","stroke-width":"lineWidth",fill:"fillColor",r:"radius"},axisTypes:["xAxis","yAxis"],colorCounter:0,parallelArrays:["x","y"],init:function(a,b){var d,e,c=this,f=a.series,g=function(a,b){return m(a.options.index,a._i)-m(b.options.index,b._i)};c.chart=a,c.options=b=c.setOptions(b),c.linkedSeries=[],c.bindAxes(),q(c,{name:b.name,state:"",pointAttr:{},visible:b.visible!==!1,selected:b.selected===!0}),fa&&(b.animation=!1),e=b.events;for(d in e)K(c,d,e[d]);(e&&e.click||b.point&&b.point.events&&b.point.events.click||b.allowPointSelect)&&(a.runTrackerClick=!0),c.getColor(),c.getSymbol(),p(c.parallelArrays,function(a){c[a+"Data"]=[]}),c.setData(b.data,!1),c.isCartesian&&(a.hasCartesianSeries=!0),f.push(c),c._i=f.length-1,ob(f,g),this.yAxis&&ob(this.yAxis.series,g),p(f,function(a,b){a.index=b,a.name=a.name||"Series "+(b+1)})},bindAxes:function(){var d,a=this,b=a.options,c=a.chart;p(a.axisTypes||[],function(e){p(c[e],function(c){d=c.options,(b[e]===d.index||b[e]!==t&&b[e]===d.id||b[e]===t&&0===d.index)&&(c.series.push(a),a[e]=c,c.isDirty=!0)}),!a[e]&&a.optionalAxis!==e&&ra(18,!0)})},updateParallelArrays:function(a,b){var c=a.series,d=arguments;p(c.parallelArrays,"number"==typeof b?function(d){var f="y"===d&&c.toYData?c.toYData(a):a[d];c[d+"Data"][b]=f}:function(a){Array.prototype[b].apply(c[a+"Data"],Array.prototype.slice.call(d,2))})},autoIncrement:function(){var a=this.options,b=this.xIncrement,b=m(b,a.pointStart,0);return this.pointInterval=m(this.pointInterval,a.pointInterval,1),this.xIncrement=b+this.pointInterval,b},getSegments:function(){var c,a=-1,b=[],d=this.points,e=d.length;if(e)if(this.options.connectNulls){for(c=e;c--;)null===d[c].y&&d.splice(c,1);d.length&&(b=[d])}else p(d,function(c,g){null===c.y?(g>a+1&&b.push(d.slice(a+1,g)),a=g):g===e-1&&b.push(d.slice(a+1,g+1))});this.segments=b},setOptions:function(a){var b=this.chart,c=b.options.plotOptions,b=b.userOptions||{},d=b.plotOptions||{},e=c[this.type];return this.userOptions=a,c=w(e,c.series,a),this.tooltipOptions=w(E.tooltip,E.plotOptions[this.type].tooltip,b.tooltip,d.series&&d.series.tooltip,d[this.type]&&d[this.type].tooltip,a.tooltip),null===e.marker&&delete c.marker,c},getColor:function(){var e,a=this.options,b=this.userOptions,c=this.chart.options.colors,d=this.chart.counters;e=a.color||ba[this.type].color,e||a.colorByPoint||(r(b._colorIndex)?a=b._colorIndex:(b._colorIndex=d.color,a=d.color++),e=c[a]),this.color=e,d.wrapColor(c.length)},getSymbol:function(){var a=this.userOptions,b=this.options.marker,c=this.chart,d=c.options.symbols,c=c.counters;this.symbol=b.symbol,this.symbol||(r(a._symbolIndex)?a=a._symbolIndex:(a._symbolIndex=c.symbol,a=c.symbol++),this.symbol=d[a]),/^url/.test(this.symbol)&&(b.radius=0),c.wrapSymbol(d.length)},drawLegendSymbol:N.drawLineMarker,setData:function(a,b,c,d){var h,e=this,f=e.points,g=f&&f.length||0,i=e.options,j=e.chart,k=null,l=e.xAxis,o=l&&!!l.categories,n=e.tooltipPoints,s=i.turboThreshold,q=this.xData,r=this.yData,v=(h=e.pointArrayMap)&&h.length,a=a||[];if(h=a.length,b=m(b,!0),d===!1||!h||g!==h||e.cropped||e.hasGroupedData){if(e.xIncrement=null,e.pointRange=o?1:i.pointRange,e.colorCounter=0,p(this.parallelArrays,function(a){e[a+"Data"].length=0}),s&&h>s){for(c=0;null===k&&h>c;)k=a[c],c++;if(ha(k)){for(o=m(i.pointStart,0),i=m(i.pointInterval,1),c=0;h>c;c++)q[c]=o,r[c]=a[c],o+=i;e.xIncrement=o}else if(La(k))if(v)for(c=0;h>c;c++)i=a[c],q[c]=i[0],r[c]=i.slice(1,v+1);else for(c=0;h>c;c++)i=a[c],q[c]=i[0],r[c]=i[1];else ra(12)}else for(c=0;h>c;c++)a[c]!==t&&(i={series:e},e.pointClass.prototype.applyOptions.apply(i,[a[c]]),e.updateParallelArrays(i,c),o&&i.name)&&(l.names[i.x]=i.name);for(Fa(r[0])&&ra(14,!0),e.data=[],e.options.data=a,c=g;c--;)f[c]&&f[c].destroy&&f[c].destroy();n&&(n.length=0),l&&(l.minRange=l.userMinRange),e.isDirty=e.isDirtyData=j.isDirtyBox=!0,c=!1}else p(a,function(a,b){f[b].update(a,!1)});b&&j.redraw(c)},processData:function(a){var e,b=this.xData,c=this.yData,d=b.length;e=0;var f,g,o,n,h=this.xAxis,i=this.options,j=i.cropThreshold,k=0,l=this.isCartesian;if(l&&!this.isDirty&&!h.isDirty&&!this.yAxis.isDirty&&!a)return!1;for(l&&this.sorted&&(!j||d>j||this.forceCrop)&&(o=h.min,n=h.max,b[d-1]<o||b[0]>n?(b=[],c=[]):(b[0]<o||b[d-1]>n)&&(e=this.cropData(this.xData,this.yData,o,n),b=e.xData,c=e.yData,e=e.start,f=!0,k=b.length)),d=b.length-1;d>=0;d--)a=b[d]-b[d-1],!f&&b[d]>o&&b[d]<n&&k++,a>0&&(g===t||g>a)?g=a:0>a&&this.requireSorting&&ra(15);this.cropped=f,this.cropStart=e,this.processedXData=b,this.processedYData=c,this.activePointCount=k,null===i.pointRange&&(this.pointRange=g||1),this.closestPointRange=g},cropData:function(a,b,c,d){var i,e=a.length,f=0,g=e,h=m(this.cropShoulder,1);for(i=0;e>i;i++)if(a[i]>=c){f=v(0,i-h);break}for(;e>i;i++)if(a[i]>d){g=i+h;break}return{xData:a.slice(f,g),yData:b.slice(f,g),start:f,end:g}},generatePoints:function(){var c,i,k,o,a=this.options.data,b=this.data,d=this.processedXData,e=this.processedYData,f=this.pointClass,g=d.length,h=this.cropStart||0,j=this.hasGroupedData,l=[];for(b||j||(b=[],b.length=a.length,b=this.data=b),o=0;g>o;o++)i=h+o,j?l[o]=(new f).init(this,[d[o]].concat(qa(e[o]))):(b[i]?k=b[i]:a[i]!==t&&(b[i]=k=(new f).init(this,a[i],d[o])),l[o]=k);if(b&&(g!==(c=b.length)||j))for(o=0;c>o;o++)o===h&&!j&&(o+=g),b[o]&&(b[o].destroyElements(),b[o].plotX=t);this.data=b,this.points=l},getExtremes:function(a){var d,b=this.yAxis,c=this.processedXData,e=[],f=0;d=this.xAxis.getExtremes();var i,j,k,l,g=d.min,h=d.max,a=a||this.stackedYData||this.processedYData;for(d=a.length,l=0;d>l;l++)if(j=c[l],k=a[l],i=null!==k&&k!==t&&(!b.isLog||k.length||k>0),j=this.getExtremesFromAll||this.cropped||(c[l+1]||j)>=g&&(c[l-1]||j)<=h,i&&j)if(i=k.length)for(;i--;)null!==k[i]&&(e[f++]=k[i]);else e[f++]=k;this.dataMin=m(void 0,Na(e)),this.dataMax=m(void 0,Ba(e))},translate:function(){this.processedXData||this.processData(),this.generatePoints();for(var a=this.options,b=a.stacking,c=this.xAxis,d=c.categories,e=this.yAxis,f=this.points,g=f.length,h=!!this.modifyValue,i=a.pointPlacement,j="between"===i||ha(i),k=a.threshold,a=0;g>a;a++){var l=f[a],o=l.x,n=l.y,s=l.low,p=b&&e.stacks[(this.negStacks&&k>n?"-":"")+this.stackKey];e.isLog&&0>=n&&(l.y=n=null),l.plotX=c.translate(o,0,0,0,1,i,"flags"===this.type),b&&this.visible&&p&&p[o]&&(p=p[o],n=p.points[this.index+","+a],s=n[0],n=n[1],0===s&&(s=m(k,e.min)),e.isLog&&0>=s&&(s=null),l.total=l.stackTotal=p.total,l.percentage=p.total&&l.y/p.total*100,l.stackY=n,p.setOffset(this.pointXOffset||0,this.barW||0)),l.yBottom=r(s)?e.translate(s,0,1,0,1):null,h&&(n=this.modifyValue(n,l)),l.plotY="number"==typeof n&&1/0!==n?e.translate(n,0,1,0,1):t,l.clientX=j?c.translate(o,0,0,0,1):l.plotX,l.negative=l.y<(k||0),l.category=d&&d[l.x]!==t?d[l.x]:l.x}this.getSegments()},animate:function(a){var d,b=this.chart,c=b.renderer;d=this.options.animation;var g,e=this.clipBox||b.clipBox,f=b.inverted;d&&!ca(d)&&(d=ba[this.type].animation),g=["_sharedClip",d.duration,d.easing,e.height].join(","),a?(a=b[g],d=b[g+"m"],a||(b[g]=a=c.clipRect(q(e,{width:0})),b[g+"m"]=d=c.clipRect(-99,f?-b.plotLeft:-b.plotTop,99,f?b.chartWidth:b.chartHeight)),this.group.clip(a),this.markerGroup.clip(d),this.sharedClipKey=g):((a=b[g])&&a.animate({width:b.plotSizeX},d),b[g+"m"]&&b[g+"m"].animate({width:b.plotSizeX+99},d),this.animate=null)},afterAnimate:function(){var a=this.chart,b=this.sharedClipKey,c=this.group,d=this.clipBox;c&&this.options.clip!==!1&&(b&&d||c.clip(d?a.renderer.clipRect(d):a.clipRect),this.markerGroup.clip()),D(this,"afterAnimate"),setTimeout(function(){b&&a[b]&&(d||(a[b]=a[b].destroy()),a[b+"m"]&&(a[b+"m"]=a[b+"m"].destroy()))},100)},drawPoints:function(){var a,d,e,f,g,h,i,j,k,b=this.points,c=this.chart;d=this.options.marker;var o,l=this.pointAttr[""],n=this.markerGroup,s=m(d.enabled,this.activePointCount<.5*this.xAxis.len/d.radius);if(d.enabled!==!1||this._hasPointMarkers)for(f=b.length;f--;)g=b[f],d=T(g.plotX),e=g.plotY,k=g.graphic,i=g.marker||{},a=s&&i.enabled===t||i.enabled,o=c.isInsidePlot(u(d),e,c.inverted),a&&e!==t&&!isNaN(e)&&null!==g.y?(a=g.pointAttr[g.selected?"select":""]||l,h=a.r,i=m(i.symbol,this.symbol),j=0===i.indexOf("url"),k?k[o?"show":"hide"](!0).animate(q({x:d-h,y:e-h},k.symbolName?{width:2*h,height:2*h}:{})):o&&(h>0||j)&&(g.graphic=c.renderer.symbol(i,d-h,e-h,2*h,2*h).attr(a).add(n))):k&&(g.graphic=k.destroy())},convertAttribs:function(a,b,c,d){var f,g,e=this.pointAttrToOptions,h={},a=a||{},b=b||{},c=c||{},d=d||{};for(f in e)g=e[f],h[f]=m(a[g],b[f],c[f],d[f]);return h},getAttribs:function(){var f,a=this,b=a.options,c=ba[a.type].marker?b.marker:b,d=c.states,e=d.hover,g=a.color;f={stroke:g,fill:g};var i,k,h=a.points||[],j=[],l=a.pointAttrToOptions;k=a.hasPointSpecificOptions;var o=b.negativeColor,n=c.lineColor,s=c.fillColor;i=b.turboThreshold;var m;if(b.marker?(e.radius=e.radius||c.radius+2,e.lineWidth=e.lineWidth||c.lineWidth+1):e.color=e.color||ya(e.color||g).brighten(e.brightness).get(),j[""]=a.convertAttribs(c,f),p(["hover","select"],function(b){j[b]=a.convertAttribs(d[b],j[""])}),a.pointAttr=j,g=h.length,!i||i>g||k)for(;g--;){if(i=h[g],(c=i.options&&i.options.marker||i.options)&&c.enabled===!1&&(c.radius=0),i.negative&&o&&(i.color=i.fillColor=o),k=b.colorByPoint||i.color,i.options)for(m in l)r(c[l[m]])&&(k=!0);k?(c=c||{},k=[],d=c.states||{},f=d.hover=d.hover||{},b.marker||(f.color=f.color||!i.options.color&&e.color||ya(i.color).brighten(f.brightness||e.brightness).get()),f={color:i.color},s||(f.fillColor=i.color),n||(f.lineColor=i.color),k[""]=a.convertAttribs(q(f,c),j[""]),k.hover=a.convertAttribs(d.hover,j.hover,k[""]),k.select=a.convertAttribs(d.select,j.select,k[""])):k=j,i.pointAttr=k}},destroy:function(){var d,e,g,h,i,a=this,b=a.chart,c=/AppleWebKit\/533/.test(wa),f=a.data||[];for(D(a,"destroy"),W(a),p(a.axisTypes||[],function(b){(i=a[b])&&(ja(i.series,a),i.isDirty=i.forceRedraw=!0)}),a.legendItem&&a.chart.legend.destroyItem(a),e=f.length;e--;)(g=f[e])&&g.destroy&&g.destroy();a.points=null,clearTimeout(a.animationTimeout),p("area,graph,dataLabelsGroup,group,markerGroup,tracker,graphNeg,areaNeg,posClip,negClip".split(","),function(b){a[b]&&(d=c&&"group"===b?"hide":"destroy",a[b][d]())}),b.hoverSeries===a&&(b.hoverSeries=null),ja(b.series,a);for(h in a)delete a[h]},getSegmentPath:function(a){var b=this,c=[],d=b.options.step;return p(a,function(e,f){var i,g=e.plotX,h=e.plotY;b.getPointSpline?c.push.apply(c,b.getPointSpline(a,e,f)):(c.push(f?"L":"M"),d&&f&&(i=a[f-1],"right"===d?c.push(i.plotX,h):"center"===d?c.push((i.plotX+g)/2,i.plotY,(i.plotX+g)/2,h):c.push(g,i.plotY)),c.push(e.plotX,e.plotY))}),c},getGraphPath:function(){var c,a=this,b=[],d=[];return p(a.segments,function(e){c=a.getSegmentPath(e),e.length>1?b=b.concat(c):d.push(e[0])}),a.singlePoints=d,a.graphPath=b},drawGraph:function(){var a=this,b=this.options,c=[["graph",b.lineColor||this.color]],d=b.lineWidth,e=b.dashStyle,f="square"!==b.linecap,g=this.getGraphPath(),h=b.negativeColor;h&&c.push(["graphNeg",h]),p(c,function(c,h){var k=c[0],l=a[k];l?(bb(l),l.animate({d:g})):d&&g.length&&(l={stroke:c[1],"stroke-width":d,fill:Q,zIndex:1},e?l.dashstyle=e:f&&(l["stroke-linecap"]=l["stroke-linejoin"]="round"),a[k]=a.chart.renderer.path(g).attr(l).add(a.group).shadow(!h&&b.shadow))})},clipNeg:function(){var e,a=this.options,b=this.chart,c=b.renderer,d=a.negativeColor||a.negativeFillColor,f=this.graph,g=this.area,h=this.posClip,i=this.negClip;e=b.chartWidth;var j=b.chartHeight,k=v(e,j),l=this.yAxis;d&&(f||g)&&(d=u(l.toPixels(a.threshold||0,!0)),0>d&&(k-=d),a={x:0,y:0,width:k,height:d},k={x:0,y:d,width:k,height:k},b.inverted&&(a.height=k.y=b.plotWidth-d,c.isVML&&(a={x:b.plotWidth-d-b.plotLeft,y:0,width:e,height:j},k={x:d+b.plotLeft-e,y:0,width:b.plotLeft+d,height:e})),l.reversed?(b=k,e=a):(b=a,e=k),h?(h.animate(b),i.animate(e)):(this.posClip=h=c.clipRect(b),this.negClip=i=c.clipRect(e),f&&this.graphNeg&&(f.clip(h),this.graphNeg.clip(i)),g&&(g.clip(h),this.areaNeg.clip(i))))},invertGroups:function(){function a(){var a={width:b.yAxis.len,height:b.xAxis.len};p(["group","markerGroup"],function(c){b[c]&&b[c].attr(a).invert()})}var b=this,c=b.chart;b.xAxis&&(K(c,"resize",a),K(b,"destroy",function(){W(c,"resize",a)}),a(),b.invertGroups=a)},plotGroup:function(a,b,c,d,e){var f=this[a],g=!f;return g&&(this[a]=f=this.chart.renderer.g(b).attr({visibility:c,zIndex:d||.1}).add(e)),f[g?"attr":"animate"](this.getPlotBox()),f},getPlotBox:function(){var a=this.chart,b=this.xAxis,c=this.yAxis;return a.inverted&&(b=c,c=this.xAxis),{translateX:b?b.left:a.plotLeft,translateY:c?c.top:a.plotTop,scaleX:1,scaleY:1}},render:function(){var c,a=this,b=a.chart,d=a.options,e=(c=d.animation)&&!!a.animate&&b.renderer.isSVG&&m(c.duration,500)||0,f=a.visible?"visible":"hidden",g=d.zIndex,h=a.hasRendered,i=b.seriesGroup;c=a.plotGroup("group","series",f,g,i),a.markerGroup=a.plotGroup("markerGroup","markers",f,g,i),e&&a.animate(!0),a.getAttribs(),c.inverted=a.isCartesian?b.inverted:!1,a.drawGraph&&(a.drawGraph(),a.clipNeg()),a.drawDataLabels&&a.drawDataLabels(),a.visible&&a.drawPoints(),a.drawTracker&&a.options.enableMouseTracking!==!1&&a.drawTracker(),b.inverted&&a.invertGroups(),d.clip!==!1&&!a.sharedClipKey&&!h&&c.clip(b.clipRect),e&&a.animate(),h||(e?a.animationTimeout=setTimeout(function(){a.afterAnimate()},e):a.afterAnimate()),a.isDirty=a.isDirtyData=!1,a.hasRendered=!0},redraw:function(){var a=this.chart,b=this.isDirtyData,c=this.group,d=this.xAxis,e=this.yAxis;c&&(a.inverted&&c.attr({width:a.plotWidth,height:a.plotHeight}),c.animate({translateX:m(d&&d.left,a.plotLeft),translateY:m(e&&e.top,a.plotTop)})),this.translate(),this.setTooltipPoints&&this.setTooltipPoints(!0),this.render(),b&&D(this,"updatedData")}},Hb.prototype={destroy:function(){Oa(this,this.axis)},render:function(a){var b=this.options,c=b.format,c=c?Ia(c,this):b.formatter.call(this);this.label?this.label.attr({text:c,visibility:"hidden"}):this.label=this.axis.chart.renderer.text(c,null,null,b.useHTML).css(b.style).attr({align:this.textAlign,rotation:b.rotation,visibility:"hidden"}).add(a)},setOffset:function(a,b){var c=this.axis,d=c.chart,e=d.inverted,f=this.isNegative,g=c.translate(c.usePercentage?100:this.total,0,0,0,1),c=c.translate(0),c=M(g-c),h=d.xAxis[0].translate(this.x)+a,i=d.plotHeight,f={x:e?f?g:g-c:h,y:e?i-h-b:f?i-g-c:i-g,width:e?c:b,height:e?b:c};(e=this.label)&&(e.align(this.alignOptions,null,f),f=e.alignAttr,e[this.options.crop===!1||d.isInsidePlot(f.x,f.y)?"show":"hide"](!0))}},la.prototype.buildStacks=function(){var a=this.series,b=m(this.options.reversedStacks,!0),c=a.length;if(!this.isXAxis){for(this.usePercentage=!1;c--;)a[b?c:a.length-c-1].setStackedPoints();if(this.usePercentage)for(c=0;c<a.length;c++)a[c].setPercentStacks()}},la.prototype.renderStackTotals=function(){var d,e,a=this.chart,b=a.renderer,c=this.stacks,f=this.stackTotalGroup;f||(this.stackTotalGroup=f=b.g("stack-labels").attr({visibility:"visible",zIndex:6}).add()),f.translate(a.plotLeft,a.plotTop);for(d in c)for(e in a=c[d])a[e].render(f)},O.prototype.setStackedPoints=function(){if(this.options.stacking&&(this.visible===!0||this.chart.options.chart.ignoreHiddenSeries===!1)){var n,m,p,q,r,u,a=this.processedXData,b=this.processedYData,c=[],d=b.length,e=this.options,f=e.threshold,g=e.stack,e=e.stacking,h=this.stackKey,i="-"+h,j=this.negStacks,k=this.yAxis,l=k.stacks,o=k.oldStacks;for(q=0;d>q;q++)r=a[q],u=b[q],p=this.index+","+q,m=(n=j&&f>u)?i:h,l[m]||(l[m]={}),l[m][r]||(o[m]&&o[m][r]?(l[m][r]=o[m][r],l[m][r].total=null):l[m][r]=new Hb(k,k.options.stackLabels,n,r,g)),m=l[m][r],m.points[p]=[m.cum||0],"percent"===e?(n=n?h:i,j&&l[n]&&l[n][r]?(n=l[n][r],m.total=n.total=v(n.total,m.total)+M(u)||0):m.total=da(m.total+(M(u)||0))):m.total=da(m.total+(u||0)),m.cum=(m.cum||0)+(u||0),m.points[p].push(m.cum),c[q]=m.cum;"percent"===e&&(k.usePercentage=!0),this.stackedYData=c,k.oldStacks={}}},O.prototype.setPercentStacks=function(){var a=this,b=a.stackKey,c=a.yAxis.stacks,d=a.processedXData;p([b,"-"+b],function(b){for(var e,g,h,f=d.length;f--;)g=d[f],e=(h=c[b]&&c[b][g])&&h.points[a.index+","+f],(g=e)&&(h=h.total?100/h.total:0,g[0]=da(g[0]*h),g[1]=da(g[1]*h),a.stackedYData[f]=g[1])})},q(Ya.prototype,{addSeries:function(a,b,c){var d,e=this;return a&&(b=m(b,!0),D(e,"addSeries",{options:a},function(){d=e.initSeries(a),e.isDirtyLegend=!0,e.linkSeries(),b&&e.redraw(c)})),d},addAxis:function(a,b,c,d){var e=b?"xAxis":"yAxis",f=this.options;new la(this,w(a,{index:this[e].length,isX:b})),f[e]=qa(f[e]||{}),f[e].push(a),m(c,!0)&&this.redraw(d)},showLoading:function(a){var b=this.options,c=this.loadingDiv,d=b.loading;c||(this.loadingDiv=c=Y(Ja,{className:"highcharts-loading"},q(d.style,{zIndex:10,display:Q}),this.container),this.loadingSpan=Y("span",null,d.labelStyle,c)),this.loadingSpan.innerHTML=a||b.lang.loading,this.loadingShown||(G(c,{opacity:0,display:"",left:this.plotLeft+"px",top:this.plotTop+"px",width:this.plotWidth+"px",height:this.plotHeight+"px"}),kb(c,{opacity:d.style.opacity},{duration:d.showDuration||0}),this.loadingShown=!0)},hideLoading:function(){var a=this.options,b=this.loadingDiv;b&&kb(b,{opacity:0},{duration:a.loading.hideDuration||100,complete:function(){G(b,{display:Q})}}),this.loadingShown=!1}}),q(Ea.prototype,{update:function(a,b,c){var g,d=this,e=d.series,f=d.graphic,h=e.data,i=e.chart,j=e.options,b=m(b,!0);d.firePointEvent("update",{options:a},function(){d.applyOptions(a),ca(a)&&(e.getAttribs(),f&&(a&&a.marker&&a.marker.symbol?d.graphic=f.destroy():f.attr(d.pointAttr[d.state||""])),a&&a.dataLabels&&d.dataLabel&&(d.dataLabel=d.dataLabel.destroy())),g=Da(d,h),e.updateParallelArrays(d,g),j.data[g]=d.options,e.isDirty=e.isDirtyData=!0,!e.fixedBox&&e.hasCartesianSeries&&(i.isDirtyBox=!0),"point"===j.legendType&&i.legend.destroyItem(d),b&&i.redraw(c)})},remove:function(a,b){var g,c=this,d=c.series,e=d.points,f=d.chart,h=d.data;Qa(b,f),a=m(a,!0),c.firePointEvent("remove",null,function(){g=Da(c,h),h.length===e.length&&e.splice(g,1),h.splice(g,1),d.options.data.splice(g,1),d.updateParallelArrays(c,"splice",g,1),c.destroy(),d.isDirty=!0,d.isDirtyData=!0,a&&f.redraw()})}}),q(O.prototype,{addPoint:function(a,b,c,d){var o,e=this.options,f=this.data,g=this.graph,h=this.area,i=this.chart,j=this.xAxis&&this.xAxis.names,k=g&&g.shift||0,l=e.data,n=this.xData;if(Qa(d,i),c&&p([g,h,this.graphNeg,this.areaNeg],function(a){a&&(a.shift=k+1)}),h&&(h.isArea=!0),b=m(b,!0),d={series:this},this.pointClass.prototype.applyOptions.apply(d,[a]),g=d.x,h=n.length,this.requireSorting&&g<n[h-1])for(o=!0;h&&n[h-1]>g;)h--;this.updateParallelArrays(d,"splice",h,0,0),this.updateParallelArrays(d,h),j&&(j[g]=d.name),l.splice(h,0,a),o&&(this.data.splice(h,0,null),this.processData()),"point"===e.legendType&&this.generatePoints(),c&&(f[0]&&f[0].remove?f[0].remove(!1):(f.shift(),this.updateParallelArrays(d,"shift"),l.shift())),this.isDirtyData=this.isDirty=!0,b&&(this.getAttribs(),i.redraw())},remove:function(a,b){var c=this,d=c.chart,a=m(a,!0);c.isRemoving||(c.isRemoving=!0,D(c,"remove",null,function(){c.destroy(),d.isDirtyLegend=d.isDirtyBox=!0,d.linkSeries(),a&&d.redraw(b)})),c.isRemoving=!1},update:function(a,b){var f,c=this.chart,d=this.type,e=F[d].prototype,a=w(this.userOptions,{animation:!1,index:this.index,pointStart:this.xData[0]},{data:this.options.data},a);this.remove(!1);for(f in e)e.hasOwnProperty(f)&&(this[f]=t);q(this,F[a.type||d].prototype),this.init(c,a),m(b,!0)&&c.redraw(!1)}}),q(la.prototype,{update:function(a,b){var c=this.chart,a=c.options[this.coll][this.options.index]=w(this.userOptions,a);
|
5 |
+
this.destroy(!0),this._addedPlotLB=t,this.init(c,q(a,{events:t})),c.isDirtyBox=!0,m(b,!0)&&c.redraw()},remove:function(a){for(var b=this.chart,c=this.coll,d=this.series,e=d.length;e--;)d[e]&&d[e].remove(!1);ja(b.axes,this),ja(b[c],this),b.options[c].splice(this.options.index,1),p(b[c],function(a,b){a.options.index=b}),this.destroy(),b.isDirtyBox=!0,m(a,!0)&&b.redraw()},setTitle:function(a,b){this.update({title:a},b)},setCategories:function(a,b){this.update({categories:a},b)}}),ga=ka(O),F.line=ga,ba.area=w(S,{threshold:0});var pa=ka(O,{type:"area",getSegments:function(){var h,i,l,o,n,a=[],b=[],c=[],d=this.xAxis,e=this.yAxis,f=e.stacks[this.stackKey],g={},j=this.points,k=this.options.connectNulls;if(this.options.stacking&&!this.cropped){for(o=0;o<j.length;o++)g[j[o].x]=j[o];for(n in f)null!==f[n].total&&c.push(+n);c.sort(function(a,b){return a-b}),p(c,function(a){(!k||g[a]&&null!==g[a].y)&&(g[a]?b.push(g[a]):(h=d.translate(a),l=f[a].percent?f[a].total?100*f[a].cum/f[a].total:0:f[a].cum,i=e.toPixels(l,!0),b.push({y:null,plotX:h,clientX:h,plotY:i,yBottom:i,onMouseOver:sa})))}),b.length&&a.push(b)}else O.prototype.getSegments.call(this),a=this.segments;this.segments=a},getSegmentPath:function(a){var d,b=O.prototype.getSegmentPath.call(this,a),c=[].concat(b),e=this.options;d=b.length;var g,f=this.yAxis.getThreshold(e.threshold);if(3===d&&c.push("L",b[1],b[2]),e.stacking&&!this.closedStacks)for(d=a.length-1;d>=0;d--)g=m(a[d].yBottom,f),d<a.length-1&&e.step&&c.push(a[d+1].plotX,g),c.push(a[d].plotX,g);else this.closeSegment(c,a,f);return this.areaPath=this.areaPath.concat(c),b},closeSegment:function(a,b,c){a.push("L",b[b.length-1].plotX,c,"L",b[0].plotX,c)},drawGraph:function(){this.areaPath=[],O.prototype.drawGraph.apply(this);var a=this,b=this.areaPath,c=this.options,d=c.negativeColor,e=c.negativeFillColor,f=[["area",this.color,c.fillColor]];(d||e)&&f.push(["areaNeg",d,e]),p(f,function(d){var e=d[0],f=a[e];f?f.animate({d:b}):a[e]=a.chart.renderer.path(b).attr({fill:m(d[2],ya(d[1]).setOpacity(m(c.fillOpacity,.75)).get()),zIndex:0}).add(a.group)})},drawLegendSymbol:N.drawRectangle});F.area=pa,ba.spline=w(S),ga=ka(O,{type:"spline",getPointSpline:function(a,b,c){var h,i,j,k,d=b.plotX,e=b.plotY,f=a[c-1],g=a[c+1];if(f&&g){a=f.plotY,j=g.plotX;var l,g=g.plotY;h=(1.5*d+f.plotX)/2.5,i=(1.5*e+a)/2.5,j=(1.5*d+j)/2.5,k=(1.5*e+g)/2.5,l=(k-i)*(j-d)/(j-h)+e-k,i+=l,k+=l,i>a&&i>e?(i=v(a,e),k=2*e-i):a>i&&e>i&&(i=C(a,e),k=2*e-i),k>g&&k>e?(k=v(g,e),i=2*e-k):g>k&&e>k&&(k=C(g,e),i=2*e-k),b.rightContX=j,b.rightContY=k}return c?(b=["C",f.rightContX||f.plotX,f.rightContY||f.plotY,h||d,i||e,d,e],f.rightContX=f.rightContY=null):b=["M",d,e],b}}),F.spline=ga,ba.areaspline=w(ba.area),pa=pa.prototype,ga=ka(ga,{type:"areaspline",closedStacks:!0,getSegmentPath:pa.getSegmentPath,closeSegment:pa.closeSegment,drawGraph:pa.drawGraph,drawLegendSymbol:N.drawRectangle}),F.areaspline=ga,ba.column=w(S,{borderColor:"#FFFFFF",borderRadius:0,groupPadding:.2,marker:null,pointPadding:.1,minPointLength:0,cropThreshold:50,pointRange:null,states:{hover:{brightness:.1,shadow:!1,halo:!1},select:{color:"#C0C0C0",borderColor:"#000000",shadow:!1}},dataLabels:{align:null,verticalAlign:null,y:null},stickyTracking:!1,tooltip:{distance:6},threshold:0}),ga=ka(O,{type:"column",pointAttrToOptions:{stroke:"borderColor",fill:"color",r:"borderRadius"},cropShoulder:0,trackerGroups:["group","dataLabelsGroup"],negStacks:!0,init:function(){O.prototype.init.apply(this,arguments);var a=this,b=a.chart;b.hasRendered&&p(b.series,function(b){b.type===a.type&&(b.isDirty=!0)})},getColumnMetrics:function(){var f,h,a=this,b=a.options,c=a.xAxis,d=a.yAxis,e=c.reversed,g={},i=0;b.grouping===!1?i=1:p(a.chart.series,function(b){var c=b.options,e=b.yAxis;b.type===a.type&&b.visible&&d.len===e.len&&d.pos===e.pos&&(c.stacking?(f=b.stackKey,g[f]===t&&(g[f]=i++),h=g[f]):c.grouping!==!1&&(h=i++),b.columnIndex=h)});var c=C(M(c.transA)*(c.ordinalSlope||b.pointRange||c.closestPointRange||c.tickInterval||1),c.len),j=c*b.groupPadding,k=(c-2*j)/i,l=b.pointWidth,b=r(l)?(k-l)/2:k*b.pointPadding,l=m(l,k-2*b);return a.columnMetrics={width:l,offset:b+(j+((e?i-(a.columnIndex||0):a.columnIndex)||0)*k-c/2)*(e?-1:1)}},translate:function(){var a=this,b=a.chart,c=a.options,d=a.borderWidth=m(c.borderWidth,a.activePointCount>.5*a.xAxis.len?0:1),e=a.yAxis,f=a.translatedThreshold=e.getThreshold(c.threshold),g=m(c.minPointLength,5),c=a.getColumnMetrics(),h=c.width,i=a.barW=Ka(v(h,1+2*d)),j=a.pointXOffset=c.offset,k=-(d%2?.5:0),l=d%2?.5:1;b.renderer.isVML&&b.inverted&&(l+=1),O.prototype.translate.apply(a),p(a.points,function(c){var x,d=m(c.yBottom,f),p=C(v(-999-d,c.plotY),e.len+999+d),q=c.plotX+j,r=i,t=C(p,d);x=v(p,d)-t,M(x)<g&&g&&(x=g,t=u(M(t-f)>g?d-g:f-(e.translate(c.y,0,1,0,1)<=f?g:0))),c.barX=q,c.pointWidth=h,c.tooltipPos=b.inverted?[e.len-p,a.xAxis.len-q-r/2]:[q+r/2,p],d=M(q)<.5,r=u(q+r)+k,q=u(q)+k,r-=q,p=M(t)<.5,x=u(t+x)+l,t=u(t)+l,x-=t,d&&(q+=1,r-=1),p&&(t-=1,x+=1),c.shapeType="rect",c.shapeArgs={x:q,y:t,width:r,height:x}})},getSymbol:sa,drawLegendSymbol:N.drawRectangle,drawGraph:sa,drawPoints:function(){var f,g,h,a=this,b=this.chart,c=a.options,d=b.renderer,e=c.animationLimit||250;p(a.points,function(i){var j=i.plotY,k=i.graphic;j===t||isNaN(j)||null===i.y?k&&(i.graphic=k.destroy()):(f=i.shapeArgs,h=r(a.borderWidth)?{"stroke-width":a.borderWidth}:{},g=i.pointAttr[i.selected?"select":""]||a.pointAttr[""],k?(bb(k),k.attr(h)[b.pointCount<e?"animate":"attr"](w(f))):i.graphic=d[i.shapeType](f).attr(g).attr(h).add(a.group).shadow(c.shadow,null,c.stacking&&!c.borderRadius))})},animate:function(a){var b=this.yAxis,c=this.options,d=this.chart.inverted,e={};aa&&(a?(e.scaleY=.001,a=C(b.pos+b.len,v(b.pos,b.toPixels(c.threshold))),d?e.translateX=a-b.len:e.translateY=a,this.group.attr(e)):(e.scaleY=1,e[d?"translateX":"translateY"]=b.pos,this.group.animate(e,this.options.animation),this.animate=null))},remove:function(){var a=this,b=a.chart;b.hasRendered&&p(b.series,function(b){b.type===a.type&&(b.isDirty=!0)}),O.prototype.remove.apply(a,arguments)}}),F.column=ga,ba.bar=w(ba.column),pa=ka(ga,{type:"bar",inverted:!0}),F.bar=pa,ba.scatter=w(S,{lineWidth:0,tooltip:{headerFormat:'<span style="color:{series.color}">â—</span> <span style="font-size: 10px;"> {series.name}</span><br/>',pointFormat:"x: <b>{point.x}</b><br/>y: <b>{point.y}</b><br/>"},stickyTracking:!1}),pa=ka(O,{type:"scatter",sorted:!1,requireSorting:!1,noSharedTooltip:!0,trackerGroups:["markerGroup"],takeOrdinalPosition:!1,singularTooltips:!0,drawGraph:function(){this.options.lineWidth&&O.prototype.drawGraph.call(this)}}),F.scatter=pa,ba.pie=w(S,{borderColor:"#FFFFFF",borderWidth:1,center:[null,null],clip:!1,colorByPoint:!0,dataLabels:{distance:30,enabled:!0,formatter:function(){return this.point.name}},ignoreHiddenPoint:!0,legendType:"point",marker:null,size:null,showInLegend:!1,slicedOffset:10,states:{hover:{brightness:.1,shadow:!1}},stickyTracking:!1,tooltip:{followPointer:!0}}),S={type:"pie",isCartesian:!1,pointClass:ka(Ea,{init:function(){Ea.prototype.init.apply(this,arguments);var b,a=this;return a.y<0&&(a.y=null),q(a,{visible:a.visible!==!1,name:m(a.name,"Slice")}),b=function(b){a.slice("select"===b.type)},K(a,"select",b),K(a,"unselect",b),a},setVisible:function(a){var b=this,c=b.series,d=c.chart;b.visible=b.options.visible=a=a===t?!b.visible:a,c.options.data[Da(b,c.data)]=b.options,p(["graphic","dataLabel","connector","shadowGroup"],function(c){b[c]&&b[c][a?"show":"hide"](!0)}),b.legendItem&&d.legend.colorizeItem(b,a),!c.isDirty&&c.options.ignoreHiddenPoint&&(c.isDirty=!0,d.redraw())},slice:function(a,b,c){var d=this.series;Qa(c,d.chart),m(b,!0),this.sliced=this.options.sliced=a=r(a)?a:!this.sliced,d.options.data[Da(this,d.data)]=this.options,a=a?this.slicedTranslation:{translateX:0,translateY:0},this.graphic.animate(a),this.shadowGroup&&this.shadowGroup.animate(a)},haloPath:function(a){var b=this.shapeArgs,c=this.series.chart;return this.series.chart.renderer.symbols.arc(c.plotLeft+b.x,c.plotTop+b.y,b.r+a,b.r+a,{innerR:this.shapeArgs.r,start:b.start,end:b.end})}}),requireSorting:!1,noSharedTooltip:!0,trackerGroups:["group","dataLabelsGroup"],axisTypes:[],pointAttrToOptions:{stroke:"borderColor","stroke-width":"borderWidth",fill:"color"},singularTooltips:!0,getColor:sa,animate:function(a){var b=this,c=b.points,d=b.startAngleRad;a||(p(c,function(a){var c=a.graphic,a=a.shapeArgs;c&&(c.attr({r:b.center[3]/2,start:d,end:d}),c.animate({r:a.r,start:a.start,end:a.end},b.options.animation))}),b.animate=null)},setData:function(a,b,c,d){O.prototype.setData.call(this,a,!1,c,d),this.processData(),this.generatePoints(),m(b,!0)&&this.chart.redraw(c)},generatePoints:function(){var a,c,d,e,b=0,f=this.options.ignoreHiddenPoint;for(O.prototype.generatePoints.call(this),c=this.points,d=c.length,a=0;d>a;a++)e=c[a],b+=f&&!e.visible?0:e.y;for(this.total=b,a=0;d>a;a++)e=c[a],e.percentage=b>0?e.y/b*100:0,e.total=b},translate:function(a){this.generatePoints();var f,g,h,o,p,b=0,c=this.options,d=c.slicedOffset,e=d+c.borderWidth,i=c.startAngle||0,j=this.startAngleRad=ma/180*(i-90),i=(this.endAngleRad=ma/180*(m(c.endAngle,i+360)-90))-j,k=this.points,l=c.dataLabels.distance,c=c.ignoreHiddenPoint,n=k.length;for(a||(this.center=a=this.getCenter()),this.getX=function(b,c){return h=U.asin(C((b-a[1])/(a[2]/2+l),1)),a[0]+(c?-1:1)*Z(h)*(a[2]/2+l)},o=0;n>o;o++)p=k[o],f=j+b*i,(!c||p.visible)&&(b+=p.percentage/100),g=j+b*i,p.shapeType="arc",p.shapeArgs={x:a[0],y:a[1],r:a[2]/2,innerR:a[3]/2,start:u(1e3*f)/1e3,end:u(1e3*g)/1e3},h=(g+f)/2,h>1.5*ma?h-=2*ma:-ma/2>h&&(h+=2*ma),p.slicedTranslation={translateX:u(Z(h)*d),translateY:u(ea(h)*d)},f=Z(h)*a[2]/2,g=ea(h)*a[2]/2,p.tooltipPos=[a[0]+.7*f,a[1]+.7*g],p.half=-ma/2>h||h>ma/2?1:0,p.angle=h,e=C(e,l/2),p.labelPos=[a[0]+f+Z(h)*l,a[1]+g+ea(h)*l,a[0]+f+Z(h)*e,a[1]+g+ea(h)*e,a[0]+f,a[1]+g,0>l?"center":p.half?"right":"left",h]},drawGraph:null,drawPoints:function(){var c,d,f,g,a=this,b=a.chart.renderer,e=a.options.shadow;e&&!a.shadowGroup&&(a.shadowGroup=b.g("shadow").add(a.group)),p(a.points,function(h){d=h.graphic,g=h.shapeArgs,f=h.shadowGroup,e&&!f&&(f=h.shadowGroup=b.g("shadow").add(a.shadowGroup)),c=h.sliced?h.slicedTranslation:{translateX:0,translateY:0},f&&f.attr(c),d?d.animate(q(g,c)):h.graphic=d=b[h.shapeType](g).setRadialReference(a.center).attr(h.pointAttr[h.selected?"select":""]).attr({"stroke-linejoin":"round"}).attr(c).add(a.group).shadow(e,f),void 0!==h.visible&&h.setVisible(h.visible)})},sortByAngle:function(a,b){a.sort(function(a,d){return void 0!==a.angle&&(d.angle-a.angle)*b})},drawLegendSymbol:N.drawRectangle,getCenter:X.getCenter,getSymbol:sa},S=ka(O,S),F.pie=S,O.prototype.drawDataLabels=function(){var f,g,h,i,a=this,b=a.options,c=b.cursor,d=b.dataLabels,e=a.points;(d.enabled||a._hasPointLabels)&&(a.dlProcessOptions&&a.dlProcessOptions(d),i=a.plotGroup("dataLabelsGroup","data-labels","hidden",d.zIndex||6),!a.hasRendered&&m(d.defer,!0)&&(i.attr({opacity:0}),K(a,"afterAnimate",function(){a.dataLabelsGroup.show()[b.animation?"animate":"attr"]({opacity:1},{duration:200})})),g=d,p(e,function(b){var e,o,n,l=b.dataLabel,p=b.connector,u=!0;if(f=b.options&&b.options.dataLabels,e=m(f&&f.enabled,g.enabled),l&&!e)b.dataLabel=l.destroy();else if(e){if(d=w(g,f),e=d.rotation,o=b.getLabelConfig(),h=d.format?Ia(d.format,o):d.formatter.call(o,d),d.style.color=m(d.color,d.style.color,a.color,"black"),l)r(h)?(l.attr({text:h}),u=!1):(b.dataLabel=l=l.destroy(),p&&(b.connector=p.destroy()));else if(r(h)){l={fill:d.backgroundColor,stroke:d.borderColor,"stroke-width":d.borderWidth,r:d.borderRadius||0,rotation:e,padding:d.padding,zIndex:1};for(n in l)l[n]===t&&delete l[n];l=b.dataLabel=a.chart.renderer[e?"text":"label"](h,0,-999,null,null,null,d.useHTML).attr(l).css(q(d.style,c&&{cursor:c})).add(i).shadow(d.shadow)}l&&a.alignDataLabel(b,l,d,null,u)}}))},O.prototype.alignDataLabel=function(a,b,c,d,e){var f=this.chart,g=f.inverted,h=m(a.plotX,-999),i=m(a.plotY,-999),j=b.getBBox();(a=this.visible&&(a.series.forceDL||f.isInsidePlot(h,u(i),g)||d&&f.isInsidePlot(h,g?d.x+1:d.y+d.height-1,g)))&&(d=q({x:g?f.plotWidth-i:h,y:u(g?f.plotHeight-h:i),width:0,height:0},d),q(c,{width:j.width,height:j.height}),c.rotation?(g={align:c.align,x:d.x+c.x+d.width/2,y:d.y+c.y+d.height/2},b[e?"attr":"animate"](g)):(b.align(c,null,d),g=b.alignAttr,"justify"===m(c.overflow,"justify")?this.justifyDataLabel(b,c,g,j,d,e):m(c.crop,!0)&&(a=f.isInsidePlot(g.x,g.y)&&f.isInsidePlot(g.x+j.width,g.y+j.height)))),a||(b.attr({y:-999}),b.placed=!1)},O.prototype.justifyDataLabel=function(a,b,c,d,e,f){var j,k,g=this.chart,h=b.align,i=b.verticalAlign;j=c.x,0>j&&("right"===h?b.align="left":b.x=-j,k=!0),j=c.x+d.width,j>g.plotWidth&&("left"===h?b.align="right":b.x=g.plotWidth-j,k=!0),j=c.y,0>j&&("bottom"===i?b.verticalAlign="top":b.y=-j,k=!0),j=c.y+d.height,j>g.plotHeight&&("top"===i?b.verticalAlign="bottom":b.y=g.plotHeight-j,k=!0),k&&(a.placed=!f,a.align(b,null,e))},F.pie&&(F.pie.prototype.drawDataLabels=function(){var c,i,j,t,w,x,y,A,C,G,D,B,a=this,b=a.data,d=a.chart,e=a.options.dataLabels,f=m(e.connectorPadding,10),g=m(e.connectorWidth,1),h=d.plotWidth,d=d.plotHeight,k=m(e.softConnector,!0),l=e.distance,o=a.center,n=o[2]/2,q=o[1],r=l>0,z=[[],[]],F=[0,0,0,0],N=function(a,b){return b.y-a.y};if(a.visible&&(e.enabled||a._hasPointLabels)){for(O.prototype.drawDataLabels.apply(a),p(b,function(a){a.dataLabel&&a.visible&&z[a.half].push(a)}),D=0;!y&&b[D];)y=b[D]&&b[D].dataLabel&&(b[D].dataLabel.getBBox().height||21),D++;for(D=2;D--;){var E,b=[],K=[],H=z[D],I=H.length;if(a.sortByAngle(H,D-.5),l>0){for(B=q-n-l;q+n+l>=B;B+=y)b.push(B);if(w=b.length,I>w){for(c=[].concat(H),c.sort(N),B=I;B--;)c[B].rank=B;for(B=I;B--;)H[B].rank>=w&&H.splice(B,1);I=H.length}for(B=0;I>B;B++){c=H[B],x=c.labelPos,c=9999;var Q,P;for(P=0;w>P;P++)Q=M(b[P]-x[1]),c>Q&&(c=Q,E=P);if(B>E&&null!==b[B])E=B;else for(I-B+E>w&&null!==b[B]&&(E=w-I+B);null===b[E];)E++;K.push({i:E,y:b[E]}),b[E]=null}K.sort(N)}for(B=0;I>B;B++)c=H[B],x=c.labelPos,t=c.dataLabel,G=c.visible===!1?"hidden":"visible",c=x[1],l>0?(w=K.pop(),E=w.i,C=w.y,(c>C&&null!==b[E+1]||C>c&&null!==b[E-1])&&(C=c)):C=c,A=e.justify?o[0]+(D?-1:1)*(n+l):a.getX(0===E||E===b.length-1?c:C,D),t._attr={visibility:G,align:x[6]},t._pos={x:A+e.x+({left:f,right:-f}[x[6]]||0),y:C+e.y-10},t.connX=A,t.connY=C,null===this.options.size&&(w=t.width,f>A-w?F[3]=v(u(w-A+f),F[3]):A+w>h-f&&(F[1]=v(u(A+w-h+f),F[1])),0>C-y/2?F[0]=v(u(-C+y/2),F[0]):C+y/2>d&&(F[2]=v(u(C+y/2-d),F[2])))}(0===Ba(F)||this.verifyDataLabelOverflow(F))&&(this.placeDataLabels(),r&&g&&p(this.points,function(b){i=b.connector,x=b.labelPos,(t=b.dataLabel)&&t._pos?(G=t._attr.visibility,A=t.connX,C=t.connY,j=k?["M",A+("left"===x[6]?5:-5),C,"C",A,C,2*x[2]-x[4],2*x[3]-x[5],x[2],x[3],"L",x[4],x[5]]:["M",A+("left"===x[6]?5:-5),C,"L",x[2],x[3],"L",x[4],x[5]],i?(i.animate({d:j}),i.attr("visibility",G)):b.connector=i=a.chart.renderer.path(j).attr({"stroke-width":g,stroke:e.connectorColor||b.color||"#606060",visibility:G}).add(a.dataLabelsGroup)):i&&(b.connector=i.destroy())}))}},F.pie.prototype.placeDataLabels=function(){p(this.points,function(a){var b,a=a.dataLabel;a&&((b=a._pos)?(a.attr(a._attr),a[a.moved?"animate":"attr"](b),a.moved=!0):a&&a.attr({y:-999}))})},F.pie.prototype.alignDataLabel=sa,F.pie.prototype.verifyDataLabelOverflow=function(a){var f,b=this.center,c=this.options,d=c.center,e=c=c.minSize||80;return null!==d[0]?e=v(b[2]-v(a[1],a[3]),c):(e=v(b[2]-a[1]-a[3],c),b[0]+=(a[3]-a[1])/2),null!==d[1]?e=v(C(e,b[2]-v(a[0],a[2])),c):(e=v(C(e,b[2]-a[0]-a[2]),c),b[1]+=(a[0]-a[2])/2),e<b[2]?(b[2]=e,this.translate(b),p(this.points,function(a){a.dataLabel&&(a.dataLabel._pos=null)}),this.drawDataLabels&&this.drawDataLabels()):f=!0,f}),F.column&&(F.column.prototype.alignDataLabel=function(a,b,c,d,e){var f=this.chart,g=f.inverted,h=a.dlBox||a.shapeArgs,i=a.below||a.plotY>m(this.translatedThreshold,f.plotSizeY),j=m(c.inside,!!this.options.stacking);h&&(d=w(h),g&&(d={x:f.plotWidth-d.y-d.height,y:f.plotHeight-d.x-d.width,width:d.height,height:d.width}),!j)&&(g?(d.x+=i?0:d.width,d.width=0):(d.y+=i?d.height:0,d.height=0)),c.align=m(c.align,!g||j?"center":i?"right":"left"),c.verticalAlign=m(c.verticalAlign,g||j?"middle":i?"top":"bottom"),O.prototype.alignDataLabel.call(this,a,b,c,d,e)}),S=R.TrackerMixin={drawTrackerPoint:function(){var a=this,b=a.chart,c=b.pointer,d=a.options.cursor,e=d&&{cursor:d},f=function(c){var e,d=c.target;for(b.hoverSeries!==a&&a.onMouseOver();d&&!e;)e=d.point,d=d.parentNode;e!==t&&e!==b.hoverPoint&&e.onMouseOver(c)};p(a.points,function(a){a.graphic&&(a.graphic.element.point=a),a.dataLabel&&(a.dataLabel.element.point=a)}),a._hasTracking||(p(a.trackerGroups,function(b){a[b]&&(a[b].addClass("highcharts-tracker").on("mouseover",f).on("mouseout",function(a){c.onTrackerMouseOut(a)}).css(e),$a)&&a[b].on("touchstart",f)}),a._hasTracking=!0)},drawTrackerGraph:function(){var m,a=this,b=a.options,c=b.trackByArea,d=[].concat(c?a.areaPath:a.graphPath),e=d.length,f=a.chart,g=f.pointer,h=f.renderer,i=f.options.tooltip.snap,j=a.tracker,k=b.cursor,l=k&&{cursor:k},k=a.singlePoints,n=function(){f.hoverSeries!==a&&a.onMouseOver()},q="rgba(192,192,192,"+(aa?1e-4:.002)+")";if(e&&!c)for(m=e+1;m--;)"M"===d[m]&&d.splice(m+1,0,d[m+1]-i,d[m+2],"L"),(m&&"M"===d[m]||m===e)&&d.splice(m,0,"L",d[m-2]+i,d[m-1]);for(m=0;m<k.length;m++)e=k[m],d.push("M",e.plotX-i,e.plotY,"L",e.plotX+i,e.plotY);j?j.attr({d:d}):(a.tracker=h.path(d).attr({"stroke-linejoin":"round",visibility:a.visible?"visible":"hidden",stroke:q,fill:c?q:Q,"stroke-width":b.lineWidth+(c?0:2*i),zIndex:2}).add(a.group),p([a.tracker,a.markerGroup],function(a){a.addClass("highcharts-tracker").on("mouseover",n).on("mouseout",function(a){g.onTrackerMouseOut(a)}).css(l),$a&&a.on("touchstart",n)}))}},F.column&&(ga.prototype.drawTracker=S.drawTrackerPoint),F.pie&&(F.pie.prototype.drawTracker=S.drawTrackerPoint),F.scatter&&(pa.prototype.drawTracker=S.drawTrackerPoint),q(lb.prototype,{setItemEvents:function(a,b,c,d,e){var f=this;(c?b:a.legendGroup).on("mouseover",function(){a.setState("hover"),b.css(f.options.itemHoverStyle)}).on("mouseout",function(){b.css(a.visible?d:e),a.setState()}).on("click",function(b){var c=function(){a.setVisible()},b={browserEvent:b};a.firePointEvent?a.firePointEvent("legendItemClick",b,c):D(a,"legendItemClick",b,c)})},createCheckboxForItem:function(a){a.checkbox=Y("input",{type:"checkbox",checked:a.selected,defaultChecked:a.selected},this.options.itemCheckboxStyle,this.chart.container),K(a.checkbox,"click",function(b){D(a,"checkboxClick",{checked:b.target.checked},function(){a.select()})})}}),E.legend.itemStyle.cursor="pointer",q(Ya.prototype,{showResetZoom:function(){var a=this,b=E.lang,c=a.options.chart.resetZoomButton,d=c.theme,e=d.states,f="chart"===c.relativeTo?null:"plotBox";this.resetZoomButton=a.renderer.button(b.resetZoom,null,null,function(){a.zoomOut()},d,e&&e.hover).attr({align:c.position.align,title:b.resetZoomTitle}).add().align(c.position,!1,f)},zoomOut:function(){var a=this;D(a,"selection",{resetSelection:!0},function(){a.zoom()})},zoom:function(a){var b,e,c=this.pointer,d=!1;!a||a.resetSelection?p(this.axes,function(a){b=a.zoom()}):p(a.xAxis.concat(a.yAxis),function(a){var e=a.axis,h=e.isXAxis;(c[h?"zoomX":"zoomY"]||c[h?"pinchX":"pinchY"])&&(b=e.zoom(a.min,a.max),e.displayBtn&&(d=!0))}),e=this.resetZoomButton,d&&!e?this.showResetZoom():!d&&ca(e)&&(this.resetZoomButton=e.destroy()),b&&this.redraw(m(this.options.chart.animation,a&&a.animation,this.pointCount<100))},pan:function(a,b){var e,c=this,d=c.hoverPoints;d&&p(d,function(a){a.setState()}),p("xy"===b?[1,0]:[1],function(b){var d=a[b?"chartX":"chartY"],h=c[b?"xAxis":"yAxis"][0],i=c[b?"mouseDownX":"mouseDownY"],j=(h.pointRange||0)/2,k=h.getExtremes(),l=h.toValue(i-d,!0)+j,i=h.toValue(i+c[b?"plotWidth":"plotHeight"]-d,!0)-j;h.series.length&&l>C(k.dataMin,k.min)&&i<v(k.dataMax,k.max)&&(h.setExtremes(l,i,!1,!1,{trigger:"pan"}),e=!0),c[b?"mouseDownX":"mouseDownY"]=d}),e&&c.redraw(!1),G(c.container,{cursor:"move"})}}),q(Ea.prototype,{select:function(a,b){var c=this,d=c.series,e=d.chart,a=m(a,!c.selected);c.firePointEvent(a?"select":"unselect",{accumulate:b},function(){c.selected=c.options.selected=a,d.options.data[Da(c,d.data)]=c.options,c.setState(a&&"select"),b||p(e.getSelectedPoints(),function(a){a.selected&&a!==c&&(a.selected=a.options.selected=!1,d.options.data[Da(a,d.data)]=a.options,a.setState(""),a.firePointEvent("unselect"))})})},onMouseOver:function(a){var b=this.series,c=b.chart,d=c.tooltip,e=c.hoverPoint;e&&e!==this&&e.onMouseOut(),this.firePointEvent("mouseOver"),d&&(!d.shared||b.noSharedTooltip)&&d.refresh(this,a),this.setState("hover"),c.hoverPoint=this},onMouseOut:function(){var a=this.series.chart,b=a.hoverPoints;b&&-1!==Da(this,b)||(this.firePointEvent("mouseOut"),this.setState(),a.hoverPoint=null)},importEvents:function(){if(!this.hasImportedEvents){var b,a=w(this.series.options.point,this.options).events;this.events=a;for(b in a)K(this,b,a[b]);this.hasImportedEvents=!0}},setState:function(a,b){var p,c=this.plotX,d=this.plotY,e=this.series,f=e.options.states,g=ba[e.type].marker&&e.options.marker,h=g&&!g.enabled,i=g&&g.states[a],j=i&&i.enabled===!1,k=e.stateMarkerGraphic,l=this.marker||{},m=e.chart,n=e.halo,a=a||"";p=this.pointAttr[a]||e.pointAttr[a],a===this.state&&!b||this.selected&&"select"!==a||f[a]&&f[a].enabled===!1||a&&(j||h&&i.enabled===!1)||a&&l.states&&l.states[a]&&l.states[a].enabled===!1||(this.graphic?(g=g&&this.graphic.symbolName&&p.r,this.graphic.attr(w(p,g?{x:c-g,y:d-g,width:2*g,height:2*g}:{})),k&&k.hide()):(a&&i&&(g=i.radius,l=l.symbol||e.symbol,k&&k.currentSymbol!==l&&(k=k.destroy()),k?k[b?"animate":"attr"]({x:c-g,y:d-g}):l&&(e.stateMarkerGraphic=k=m.renderer.symbol(l,c-g,d-g,2*g,2*g).attr(p).add(e.markerGroup),k.currentSymbol=l)),k&&k[a&&m.isInsidePlot(c,d,m.inverted)?"show":"hide"]()),(c=f[a]&&f[a].halo)&&c.size?(n||(e.halo=n=m.renderer.path().add(e.seriesGroup)),n.attr(q({fill:ya(this.color||e.color).setOpacity(c.opacity).get()},c.attributes))[b?"animate":"attr"]({d:this.haloPath(c.size)})):n&&n.attr({d:[]}),this.state=a)},haloPath:function(a){var b=this.series,c=b.chart,d=b.getPlotBox(),e=c.inverted;return c.renderer.symbols.circle(d.translateX+(e?b.yAxis.len-this.plotY:this.plotX)-a,d.translateY+(e?b.xAxis.len-this.plotX:this.plotY)-a,2*a,2*a)}}),q(O.prototype,{onMouseOver:function(){var a=this.chart,b=a.hoverSeries;b&&b!==this&&b.onMouseOut(),this.options.events.mouseOver&&D(this,"mouseOver"),this.setState("hover"),a.hoverSeries=this},onMouseOut:function(){var a=this.options,b=this.chart,c=b.tooltip,d=b.hoverPoint;d&&d.onMouseOut(),this&&a.events.mouseOut&&D(this,"mouseOut"),c&&!a.stickyTracking&&(!c.shared||this.noSharedTooltip)&&c.hide(),this.setState(),b.hoverSeries=null},setState:function(a){var b=this.options,c=this.graph,d=this.graphNeg,e=b.states,b=b.lineWidth,a=a||"";this.state!==a&&(this.state=a,e[a]&&e[a].enabled===!1||(a&&(b=e[a].lineWidth||b+1),c&&!c.dashstyle&&(a={"stroke-width":b},c.attr(a),d&&d.attr(a))))},setVisible:function(a,b){var f,c=this,d=c.chart,e=c.legendItem,g=d.options.chart.ignoreHiddenSeries,h=c.visible;f=(c.visible=a=c.userOptions.visible=a===t?!h:a)?"show":"hide",p(["group","dataLabelsGroup","markerGroup","tracker"],function(a){c[a]&&c[a][f]()}),d.hoverSeries===c&&c.onMouseOut(),e&&d.legend.colorizeItem(c,a),c.isDirty=!0,c.options.stacking&&p(d.series,function(a){a.options.stacking&&a.visible&&(a.isDirty=!0)}),p(c.linkedSeries,function(b){b.setVisible(a,!1)}),g&&(d.isDirtyBox=!0),b!==!1&&d.redraw(),D(c,f)},setTooltipPoints:function(a){var c,d,h,i,b=[],e=this.xAxis,f=e&&e.getExtremes(),g=e?e.tooltipLen||e.len:this.chart.plotSizeX,j=[];if(this.options.enableMouseTracking!==!1&&!this.singularTooltips){for(a&&(this.tooltipPoints=null),p(this.segments||this.points,function(a){b=b.concat(a)}),e&&e.reversed&&(b=b.reverse()),this.orderTooltipPoints&&this.orderTooltipPoints(b),a=b.length,i=0;a>i;i++)if(e=b[i],c=e.x,c>=f.min&&c<=f.max)for(h=b[i+1],c=d===t?0:d+1,d=b[i+1]?C(v(0,T((e.clientX+(h?h.wrappedClientX||h.clientX:g))/2)),g):g;c>=0&&d>=c;)j[c++]=e;this.tooltipPoints=j}},show:function(){this.setVisible(!0)},hide:function(){this.setVisible(!1)},select:function(a){this.selected=a=a===t?!this.selected:a,this.checkbox&&(this.checkbox.checked=a),D(this,a?"select":"unselect")},drawTracker:S.drawTrackerGraph}),q(R,{Axis:la,Chart:Ya,Color:ya,Point:Ea,Tick:Sa,Renderer:Za,Series:O,SVGElement:P,SVGRenderer:ta,arrayMin:Na,arrayMax:Ba,charts:V,dateFormat:cb,format:Ia,pathAnim:ub,getOptions:function(){return E},hasBidiBug:Nb,isTouchDevice:Jb,numberFormat:Ga,seriesTypes:F,setOptions:function(a){return E=w(!0,E,a),Cb(),E},addEvent:K,removeEvent:W,createElement:Y,discardElement:Pa,css:G,each:p,extend:q,map:Ua,merge:w,pick:m,splat:qa,extendClass:ka,pInt:z,wrap:Ma,svg:aa,canvas:fa,vml:!aa&&!fa,product:"Highcharts",version:"4.0.1"})}(),jQuery(document).ready(function($){$("#close-share").click(function(){$.cookie("ignore_social_share",1,{expires:30})}),$(".big-button--share").click(function(){$.cookie("ignore_social_share",1)}),$.cookie("ignore_social_share")||leadin_check_social_share_popup(),$("#filter_action").select2(),$("#filter_action").change(function(){var $this=$(this);"submitted"==$this.val()?$("#form-filter-input").show():($("#form-filter-input").hide(),$("#filter_form").select2("val","any form"))}),$("#view-all-do-not-track-selectors").click(function(){$(".form-do-not-track, #view-less-do-not-track-selectors").not(".do-not-track-always-show").show(),$("#view-all-do-not-track-selectors").hide()}),$("#view-less-do-not-track-selectors").click(function(){$(".form-do-not-track, #view-less-do-not-track-selectors").not(".do-not-track-always-show").hide(),$("#view-all-do-not-track-selectors").show()}),$("#filter_content").select2({query:function(query){var key=query.term;$.ajax({type:"POST",url:li_admin_ajax.ajax_url,data:{action:"leadin_get_posts_and_pages",search_term:key},success:function(data){var i,json_data=jQuery.parseJSON(data),data_test={results:[]};for(i=0;i<json_data.length;i++)data_test.results.push({id:json_data[i].post_title,text:json_data[i].post_title});query.callback(data_test)}})},initSelection:function(){$("#filter_content").val()?$("#filter_content").select2("data",{id:$("#filter_content").val(),text:$("#filter_content").val()}):$("#filter_content").select2("data",{id:"any page",text:"any page"})}}),$("#filter_form").select2({query:function(query){var key=query.term;$.ajax({type:"POST",url:li_admin_ajax.ajax_url,data:{action:"leadin_get_form_selectors",search_term:key},success:function(data){var i,json_data=jQuery.parseJSON(data),data_test={results:[]};for(i=0;i<json_data.length;i++)data_test.results.push({id:json_data[i],text:json_data[i]});query.callback(data_test)}})},initSelection:function(){$("#filter_form").val()?$("#filter_form").select2("data",{id:$("#filter_form").val(),text:$("#filter_form").val()}):$("#filter_form").select2("data",{id:"any form",text:"any form"})}}),$("#leadin-contact-status").change(function(){$("#leadin-contact-status-button").addClass("button-primary")}),$("input[name=popup-position]:radio").change(function(){$("#btn-activate-subscribe").attr("href",window.location.href+"&leadin_action=activate&power_up=subscribe_widget&redirect_to="+encodeURIComponent(window.location.href+"&activate_popup=true&popup_position="+$("input:radio[name='popup-position']:checked").val()))}),$("#li_subscribe_vex_class, #li_subscribe_heading, #li_subscribe_text, #li_subscribe_btn_label, #li_subscribe_name_fields:checkbox, #li_subscribe_phone_field:checkbox").change(function(){var preview_link=$("#wp-admin-bar-view-site a.ab-item").attr("href")+"?preview-subscribe=1";preview_link+="&lis_heading="+$("#li_subscribe_heading").val(),preview_link+="&lis_desc="+$("#li_subscribe_text").val(),preview_link+="&lis_show_names="+($("#li_subscribe_name_fields").is(":checked")?1:0),preview_link+="&lis_show_phone="+($("#li_subscribe_phone_field").is(":checked")?1:0),preview_link+="&lis_btn_label="+$("#li_subscribe_btn_label").val(),preview_link+="&lis_vex_class="+$("#li_subscribe_vex_class option:selected").val(),$("#preview-popup-link").attr("href",preview_link)}),$("#pro-upgrade-button").click(function(e){return e.preventDefault(),$("#agree-pp").is(":checked")?($("#agree-pp-error").hide(),$(this).addClass("btn-submitting").text("Upgrading..."),void $.ajax({type:"POST",url:li_admin_ajax.ajax_url,data:{action:"leadin_upgrade_to_pro"},success:function(redirect_to){redirect_to&&(window.location.href=redirect_to+"&pro_upgrade=1")}})):($("#agree-pp-error").show(),!1)})}),jQuery(document).ready(function($){var $bulk_opt_selected=$('.bulkactions select option[value="add_tag_to_selected"], .bulkactions select option[value="remove_tag_from_selected"], .bulkactions select option[value="delete_selected"]');$("#leadin-contacts input:checkbox").not("thead input:checkbox, tfoot input:checkbox").bind("change",function(){var cb_count=0,selected_vals="",$btn_selected=$("#leadin-export-selected-leads"),$input_selected_vals=$(".leadin-selected-contacts"),$cb_selected=$("#leadin-contacts input:checkbox:checked").not("thead input:checkbox, tfoot input:checkbox");$cb_selected.length>0?($btn_selected.attr("disabled",!1),$bulk_opt_selected.attr("disabled",!1)):($btn_selected.attr("disabled",!0),$bulk_opt_selected.attr("disabled",!0)),$cb_selected.each(function(){selected_vals+=$(this).val(),cb_count!=$cb_selected.length-1&&(selected_vals+=","),cb_count++}),$input_selected_vals.val(selected_vals),$(".selected-contacts-count").text(cb_count)}),$("#cb-select-all-1, #cb-select-all-2").bind("change",function(){var cb_count=0,selected_vals="",$this=$(this),$btn_selected=$("#leadin-export-selected-leads"),$cb_selected=$("#leadin-contacts input:checkbox").not("thead input:checkbox, tfoot input:checkbox"),$input_selected_vals=$(".leadin-selected-contacts");$cb_selected.each(function(){selected_vals+=$(this).val(),cb_count!=$cb_selected.length-1&&(selected_vals+=","),cb_count++}),$input_selected_vals.val(selected_vals),$this.is(":checked")?($btn_selected.attr("disabled",!1),$bulk_opt_selected.attr("disabled",!1)):($btn_selected.attr("disabled",!0),$bulk_opt_selected.attr("disabled",!0),$(".selected-contacts-count").text($("#contact-count").text())),$(".selected-contacts-count").text(cb_count)}),$(".postbox .handlediv").bind("click",function(){var $postbox=$(this).parent();$postbox.hasClass("closed")?$postbox.removeClass("closed"):$postbox.addClass("closed")}),$(".selected-contacts-count").text($("#contact-count").text()),$bulk_opt_selected.attr("disabled",!0),$(".bulkactions select").change(function(){{var $this=$(this);$("#contact-count").text()}"add_tag_to_all"==$this.val()||"add_tag_to_selected"==$this.val()?($("#bulk-edit-tags h2").html($("#bulk-edit-tags h2").html().replace("remove from","add to")),$("#bulk-edit-button").val("Add Tag"),$("#bulk-edit-tag-action").val("add_tag"),tb_show("","#TB_inline?width=400&height=175&inlineId=bulk-edit-tags"),$(".bulkactions select").val("-1")):("remove_tag_from_all"==$this.val()||"remove_tag_from_selected"==$this.val())&&($("#bulk-edit-tags h2").html($("#bulk-edit-tags h2").html().replace("add to","remove from")),$("#bulk-edit-button").val("Remove Tag"),$("#bulk-edit-tag-action").val("remove_tag"),tb_show("","#TB_inline?width=400&height=175&inlineId=bulk-edit-tags"),$(".bulkactions select").val("-1"))}),$("#contact-detail-read-more").click(function(){$("#company-detail-overview-short").hide(),$("#company-detail-overview-full").show()}),$("#contact-detail-read-less").click(function(){$("#company-detail-overview-full").hide(),$("#company-detail-overview-short").show()})}),function($){"undefined"==typeof $.fn.each2&&$.extend($.fn,{each2:function(c){for(var j=$([0]),i=-1,l=this.length;++i<l&&(j.context=j[0]=this[i])&&c.call(j[0],i,j)!==!1;);return this}})}(jQuery),function($,undefined){"use strict";function reinsertElement(element){var placeholder=$(document.createTextNode(""));element.before(placeholder),placeholder.before(element),placeholder.remove()}function stripDiacritics(str){function match(a){return DIACRITICS[a]||a
|
6 |
+
}return str.replace(/[^\u0000-\u007E]/g,match)}function indexOf(value,array){for(var i=0,l=array.length;l>i;i+=1)if(equal(value,array[i]))return i;return-1}function measureScrollbar(){var $template=$(MEASURE_SCROLLBAR_TEMPLATE);$template.appendTo("body");var dim={width:$template.width()-$template[0].clientWidth,height:$template.height()-$template[0].clientHeight};return $template.remove(),dim}function equal(a,b){return a===b?!0:a===undefined||b===undefined?!1:null===a||null===b?!1:a.constructor===String?a+""==b+"":b.constructor===String?b+""==a+"":!1}function splitVal(string,separator){var val,i,l;if(null===string||string.length<1)return[];for(val=string.split(separator),i=0,l=val.length;l>i;i+=1)val[i]=$.trim(val[i]);return val}function getSideBorderPadding(element){return element.outerWidth(!1)-element.width()}function installKeyUpChangeEvent(element){var key="keyup-change-value";element.on("keydown",function(){$.data(element,key)===undefined&&$.data(element,key,element.val())}),element.on("keyup",function(){var val=$.data(element,key);val!==undefined&&element.val()!==val&&($.removeData(element,key),element.trigger("keyup-change"))})}function installFilteredMouseMove(element){element.on("mousemove",function(e){var lastpos=lastMousePosition;(lastpos===undefined||lastpos.x!==e.pageX||lastpos.y!==e.pageY)&&$(e.target).trigger("mousemove-filtered",e)})}function debounce(quietMillis,fn,ctx){ctx=ctx||undefined;var timeout;return function(){var args=arguments;window.clearTimeout(timeout),timeout=window.setTimeout(function(){fn.apply(ctx,args)},quietMillis)}}function installDebouncedScroll(threshold,element){var notify=debounce(threshold,function(e){element.trigger("scroll-debounced",e)});element.on("scroll",function(e){indexOf(e.target,element.get())>=0&¬ify(e)})}function focus($el){$el[0]!==document.activeElement&&window.setTimeout(function(){var range,el=$el[0],pos=$el.val().length;$el.focus();var isVisible=el.offsetWidth>0||el.offsetHeight>0;isVisible&&el===document.activeElement&&(el.setSelectionRange?el.setSelectionRange(pos,pos):el.createTextRange&&(range=el.createTextRange(),range.collapse(!1),range.select()))},0)}function getCursorInfo(el){el=$(el)[0];var offset=0,length=0;if("selectionStart"in el)offset=el.selectionStart,length=el.selectionEnd-offset;else if("selection"in document){el.focus();var sel=document.selection.createRange();length=document.selection.createRange().text.length,sel.moveStart("character",-el.value.length),offset=sel.text.length-length}return{offset:offset,length:length}}function killEvent(event){event.preventDefault(),event.stopPropagation()}function killEventImmediately(event){event.preventDefault(),event.stopImmediatePropagation()}function measureTextWidth(e){if(!sizer){var style=e[0].currentStyle||window.getComputedStyle(e[0],null);sizer=$(document.createElement("div")).css({position:"absolute",left:"-10000px",top:"-10000px",display:"none",fontSize:style.fontSize,fontFamily:style.fontFamily,fontStyle:style.fontStyle,fontWeight:style.fontWeight,letterSpacing:style.letterSpacing,textTransform:style.textTransform,whiteSpace:"nowrap"}),sizer.attr("class","select2-sizer"),$("body").append(sizer)}return sizer.text(e.val()),sizer.width()}function syncCssClasses(dest,src,adapter){var classes,adapted,replacements=[];classes=dest.attr("class"),classes&&(classes=""+classes,$(classes.split(" ")).each2(function(){0===this.indexOf("select2-")&&replacements.push(this)})),classes=src.attr("class"),classes&&(classes=""+classes,$(classes.split(" ")).each2(function(){0!==this.indexOf("select2-")&&(adapted=adapter(this),adapted&&replacements.push(adapted))})),dest.attr("class",replacements.join(" "))}function markMatch(text,term,markup,escapeMarkup){var match=stripDiacritics(text.toUpperCase()).indexOf(stripDiacritics(term.toUpperCase())),tl=term.length;return 0>match?void markup.push(escapeMarkup(text)):(markup.push(escapeMarkup(text.substring(0,match))),markup.push("<span class='select2-match'>"),markup.push(escapeMarkup(text.substring(match,match+tl))),markup.push("</span>"),void markup.push(escapeMarkup(text.substring(match+tl,text.length))))}function defaultEscapeMarkup(markup){var replace_map={"\\":"\","&":"&","<":"<",">":">",'"':""","'":"'","/":"/"};return String(markup).replace(/[&<>"'\/\\]/g,function(match){return replace_map[match]})}function ajax(options){var timeout,handler=null,quietMillis=options.quietMillis||100,ajaxUrl=options.url,self=this;return function(query){window.clearTimeout(timeout),timeout=window.setTimeout(function(){var data=options.data,url=ajaxUrl,transport=options.transport||$.fn.select2.ajaxDefaults.transport,deprecated={type:options.type||"GET",cache:options.cache||!1,jsonpCallback:options.jsonpCallback||undefined,dataType:options.dataType||"json"},params=$.extend({},$.fn.select2.ajaxDefaults.params,deprecated);data=data?data.call(self,query.term,query.page,query.context):null,url="function"==typeof url?url.call(self,query.term,query.page,query.context):url,handler&&"function"==typeof handler.abort&&handler.abort(),options.params&&($.isFunction(options.params)?$.extend(params,options.params.call(self)):$.extend(params,options.params)),$.extend(params,{url:url,dataType:options.dataType,data:data,success:function(data){var results=options.results(data,query.page);query.callback(results)}}),handler=transport.call(self,params)},quietMillis)}}function local(options){var dataText,tmp,data=options,text=function(item){return""+item.text};$.isArray(data)&&(tmp=data,data={results:tmp}),$.isFunction(data)===!1&&(tmp=data,data=function(){return tmp});var dataItem=data();return dataItem.text&&(text=dataItem.text,$.isFunction(text)||(dataText=dataItem.text,text=function(item){return item[dataText]})),function(query){var process,t=query.term,filtered={results:[]};return""===t?void query.callback(data()):(process=function(datum,collection){var group,attr;if(datum=datum[0],datum.children){group={};for(attr in datum)datum.hasOwnProperty(attr)&&(group[attr]=datum[attr]);group.children=[],$(datum.children).each2(function(i,childDatum){process(childDatum,group.children)}),(group.children.length||query.matcher(t,text(group),datum))&&collection.push(group)}else query.matcher(t,text(datum),datum)&&collection.push(datum)},$(data().results).each2(function(i,datum){process(datum,filtered.results)}),void query.callback(filtered))}}function tags(data){var isFunc=$.isFunction(data);return function(query){var t=query.term,filtered={results:[]},result=isFunc?data(query):data;$.isArray(result)&&($(result).each(function(){var isObject=this.text!==undefined,text=isObject?this.text:this;(""===t||query.matcher(t,text))&&filtered.results.push(isObject?this:{id:this,text:this})}),query.callback(filtered))}}function checkFormatter(formatter,formatterName){if($.isFunction(formatter))return!0;if(!formatter)return!1;if("string"==typeof formatter)return!0;throw new Error(formatterName+" must be a string, function, or falsy value")}function evaluate(val){if($.isFunction(val)){var args=Array.prototype.slice.call(arguments,1);return val.apply(null,args)}return val}function countResults(results){var count=0;return $.each(results,function(i,item){item.children?count+=countResults(item.children):count++}),count}function defaultTokenizer(input,selection,selectCallback,opts){var token,index,i,l,separator,original=input,dupe=!1;if(!opts.createSearchChoice||!opts.tokenSeparators||opts.tokenSeparators.length<1)return undefined;for(;;){for(index=-1,i=0,l=opts.tokenSeparators.length;l>i&&(separator=opts.tokenSeparators[i],index=input.indexOf(separator),!(index>=0));i++);if(0>index)break;if(token=input.substring(0,index),input=input.substring(index+separator.length),token.length>0&&(token=opts.createSearchChoice.call(this,token,selection),token!==undefined&&null!==token&&opts.id(token)!==undefined&&null!==opts.id(token))){for(dupe=!1,i=0,l=selection.length;l>i;i++)if(equal(opts.id(token),opts.id(selection[i]))){dupe=!0;break}dupe||selectCallback(token)}}return original!==input?input:void 0}function cleanupJQueryElements(){var self=this;Array.prototype.forEach.call(arguments,function(element){self[element].remove(),self[element]=null})}function clazz(SuperClass,methods){var constructor=function(){};return constructor.prototype=new SuperClass,constructor.prototype.constructor=constructor,constructor.prototype.parent=SuperClass.prototype,constructor.prototype=$.extend(constructor.prototype,methods),constructor}if(window.Select2===undefined){var KEY,AbstractSelect2,SingleSelect2,MultiSelect2,nextUid,sizer,$document,scrollBarDimensions,lastMousePosition={x:0,y:0},KEY={TAB:9,ENTER:13,ESC:27,SPACE:32,LEFT:37,UP:38,RIGHT:39,DOWN:40,SHIFT:16,CTRL:17,ALT:18,PAGE_UP:33,PAGE_DOWN:34,HOME:36,END:35,BACKSPACE:8,DELETE:46,isArrow:function(k){switch(k=k.which?k.which:k){case KEY.LEFT:case KEY.RIGHT:case KEY.UP:case KEY.DOWN:return!0}return!1},isControl:function(e){var k=e.which;switch(k){case KEY.SHIFT:case KEY.CTRL:case KEY.ALT:return!0}return e.metaKey?!0:!1},isFunctionKey:function(k){return k=k.which?k.which:k,k>=112&&123>=k}},MEASURE_SCROLLBAR_TEMPLATE="<div class='select2-measure-scrollbar'></div>",DIACRITICS={"Ⓐ":"A","A":"A","À":"A","Á":"A","Â":"A","Ầ":"A","Ấ":"A","Ẫ":"A","Ẩ":"A","Ã":"A","Ā":"A","Ă":"A","Ằ":"A","Ắ":"A","Ẵ":"A","Ẳ":"A","Ȧ":"A","Ǡ":"A","Ä":"A","Ǟ":"A","Ả":"A","Å":"A","Ǻ":"A","Ǎ":"A","Ȁ":"A","Ȃ":"A","Ạ":"A","Ậ":"A","Ặ":"A","Ḁ":"A","Ą":"A","Ⱥ":"A","Ɐ":"A","Ꜳ":"AA","Æ":"AE","Ǽ":"AE","Ǣ":"AE","Ꜵ":"AO","Ꜷ":"AU","Ꜹ":"AV","Ꜻ":"AV","Ꜽ":"AY","Ⓑ":"B","B":"B","Ḃ":"B","Ḅ":"B","Ḇ":"B","Ƀ":"B","Ƃ":"B","Ɓ":"B","Ⓒ":"C","C":"C","Ć":"C","Ĉ":"C","Ċ":"C","Č":"C","Ç":"C","Ḉ":"C","Ƈ":"C","Ȼ":"C","Ꜿ":"C","Ⓓ":"D","D":"D","Ḋ":"D","Ď":"D","Ḍ":"D","Ḑ":"D","Ḓ":"D","Ḏ":"D","Đ":"D","Ƌ":"D","Ɗ":"D","Ɖ":"D","Ꝺ":"D","DZ":"DZ","DŽ":"DZ","Dz":"Dz","Dž":"Dz","Ⓔ":"E","E":"E","È":"E","É":"E","Ê":"E","Ề":"E","Ế":"E","Ễ":"E","Ể":"E","Ẽ":"E","Ē":"E","Ḕ":"E","Ḗ":"E","Ĕ":"E","Ė":"E","Ë":"E","Ẻ":"E","Ě":"E","Ȅ":"E","Ȇ":"E","Ẹ":"E","Ệ":"E","Ȩ":"E","Ḝ":"E","Ę":"E","Ḙ":"E","Ḛ":"E","Ɛ":"E","Ǝ":"E","Ⓕ":"F","F":"F","Ḟ":"F","Ƒ":"F","Ꝼ":"F","Ⓖ":"G","G":"G","Ǵ":"G","Ĝ":"G","Ḡ":"G","Ğ":"G","Ġ":"G","Ǧ":"G","Ģ":"G","Ǥ":"G","Ɠ":"G","Ꞡ":"G","Ᵹ":"G","Ꝿ":"G","Ⓗ":"H","H":"H","Ĥ":"H","Ḣ":"H","Ḧ":"H","Ȟ":"H","Ḥ":"H","Ḩ":"H","Ḫ":"H","Ħ":"H","Ⱨ":"H","Ⱶ":"H","Ɥ":"H","Ⓘ":"I","I":"I","Ì":"I","Í":"I","Î":"I","Ĩ":"I","Ī":"I","Ĭ":"I","İ":"I","Ï":"I","Ḯ":"I","Ỉ":"I","Ǐ":"I","Ȉ":"I","Ȋ":"I","Ị":"I","Į":"I","Ḭ":"I","Ɨ":"I","Ⓙ":"J","J":"J","Ĵ":"J","Ɉ":"J","Ⓚ":"K","K":"K","Ḱ":"K","Ǩ":"K","Ḳ":"K","Ķ":"K","Ḵ":"K","Ƙ":"K","Ⱪ":"K","Ꝁ":"K","Ꝃ":"K","Ꝅ":"K","Ꞣ":"K","Ⓛ":"L","L":"L","Ŀ":"L","Ĺ":"L","Ľ":"L","Ḷ":"L","Ḹ":"L","Ļ":"L","Ḽ":"L","Ḻ":"L","Ł":"L","Ƚ":"L","Ɫ":"L","Ⱡ":"L","Ꝉ":"L","Ꝇ":"L","Ꞁ":"L","LJ":"LJ","Lj":"Lj","Ⓜ":"M","M":"M","Ḿ":"M","Ṁ":"M","Ṃ":"M","Ɱ":"M","Ɯ":"M","Ⓝ":"N","N":"N","Ǹ":"N","Ń":"N","Ñ":"N","Ṅ":"N","Ň":"N","Ṇ":"N","Ņ":"N","Ṋ":"N","Ṉ":"N","Ƞ":"N","Ɲ":"N","Ꞑ":"N","Ꞥ":"N","NJ":"NJ","Nj":"Nj","Ⓞ":"O","O":"O","Ò":"O","Ó":"O","Ô":"O","Ồ":"O","Ố":"O","Ỗ":"O","Ổ":"O","Õ":"O","Ṍ":"O","Ȭ":"O","Ṏ":"O","Ō":"O","Ṑ":"O","Ṓ":"O","Ŏ":"O","Ȯ":"O","Ȱ":"O","Ö":"O","Ȫ":"O","Ỏ":"O","Ő":"O","Ǒ":"O","Ȍ":"O","Ȏ":"O","Ơ":"O","Ờ":"O","Ớ":"O","Ỡ":"O","Ở":"O","Ợ":"O","Ọ":"O","Ộ":"O","Ǫ":"O","Ǭ":"O","Ø":"O","Ǿ":"O","Ɔ":"O","Ɵ":"O","Ꝋ":"O","Ꝍ":"O","Ƣ":"OI","Ꝏ":"OO","Ȣ":"OU","Ⓟ":"P","P":"P","Ṕ":"P","Ṗ":"P","Ƥ":"P","Ᵽ":"P","Ꝑ":"P","Ꝓ":"P","Ꝕ":"P","Ⓠ":"Q","Q":"Q","Ꝗ":"Q","Ꝙ":"Q","Ɋ":"Q","Ⓡ":"R","R":"R","Ŕ":"R","Ṙ":"R","Ř":"R","Ȑ":"R","Ȓ":"R","Ṛ":"R","Ṝ":"R","Ŗ":"R","Ṟ":"R","Ɍ":"R","Ɽ":"R","Ꝛ":"R","Ꞧ":"R","Ꞃ":"R","Ⓢ":"S","S":"S","ẞ":"S","Ś":"S","Ṥ":"S","Ŝ":"S","Ṡ":"S","Š":"S","Ṧ":"S","Ṣ":"S","Ṩ":"S","Ș":"S","Ş":"S","Ȿ":"S","Ꞩ":"S","Ꞅ":"S","Ⓣ":"T","T":"T","Ṫ":"T","Ť":"T","Ṭ":"T","Ț":"T","Ţ":"T","Ṱ":"T","Ṯ":"T","Ŧ":"T","Ƭ":"T","Ʈ":"T","Ⱦ":"T","Ꞇ":"T","Ꜩ":"TZ","Ⓤ":"U","U":"U","Ù":"U","Ú":"U","Û":"U","Ũ":"U","Ṹ":"U","Ū":"U","Ṻ":"U","Ŭ":"U","Ü":"U","Ǜ":"U","Ǘ":"U","Ǖ":"U","Ǚ":"U","Ủ":"U","Ů":"U","Ű":"U","Ǔ":"U","Ȕ":"U","Ȗ":"U","Ư":"U","Ừ":"U","Ứ":"U","Ữ":"U","Ử":"U","Ự":"U","Ụ":"U","Ṳ":"U","Ų":"U","Ṷ":"U","Ṵ":"U","Ʉ":"U","Ⓥ":"V","V":"V","Ṽ":"V","Ṿ":"V","Ʋ":"V","Ꝟ":"V","Ʌ":"V","Ꝡ":"VY","Ⓦ":"W","W":"W","Ẁ":"W","Ẃ":"W","Ŵ":"W","Ẇ":"W","Ẅ":"W","Ẉ":"W","Ⱳ":"W","Ⓧ":"X","X":"X","Ẋ":"X","Ẍ":"X","Ⓨ":"Y","Y":"Y","Ỳ":"Y","Ý":"Y","Ŷ":"Y","Ỹ":"Y","Ȳ":"Y","Ẏ":"Y","Ÿ":"Y","Ỷ":"Y","Ỵ":"Y","Ƴ":"Y","Ɏ":"Y","Ỿ":"Y","Ⓩ":"Z","Z":"Z","Ź":"Z","Ẑ":"Z","Ż":"Z","Ž":"Z","Ẓ":"Z","Ẕ":"Z","Ƶ":"Z","Ȥ":"Z","Ɀ":"Z","Ⱬ":"Z","Ꝣ":"Z","ⓐ":"a","a":"a","ẚ":"a","à":"a","á":"a","â":"a","ầ":"a","ấ":"a","ẫ":"a","ẩ":"a","ã":"a","ā":"a","ă":"a","ằ":"a","ắ":"a","ẵ":"a","ẳ":"a","ȧ":"a","ǡ":"a","ä":"a","ǟ":"a","ả":"a","å":"a","ǻ":"a","ǎ":"a","ȁ":"a","ȃ":"a","ạ":"a","ậ":"a","ặ":"a","ḁ":"a","ą":"a","ⱥ":"a","ɐ":"a","ꜳ":"aa","æ":"ae","ǽ":"ae","ǣ":"ae","ꜵ":"ao","ꜷ":"au","ꜹ":"av","ꜻ":"av","ꜽ":"ay","ⓑ":"b","b":"b","ḃ":"b","ḅ":"b","ḇ":"b","ƀ":"b","ƃ":"b","ɓ":"b","ⓒ":"c","c":"c","ć":"c","ĉ":"c","ċ":"c","č":"c","ç":"c","ḉ":"c","ƈ":"c","ȼ":"c","ꜿ":"c","ↄ":"c","ⓓ":"d","d":"d","ḋ":"d","ď":"d","ḍ":"d","ḑ":"d","ḓ":"d","ḏ":"d","đ":"d","ƌ":"d","ɖ":"d","ɗ":"d","ꝺ":"d","dz":"dz","dž":"dz","ⓔ":"e","e":"e","è":"e","é":"e","ê":"e","ề":"e","ế":"e","ễ":"e","ể":"e","ẽ":"e","ē":"e","ḕ":"e","ḗ":"e","ĕ":"e","ė":"e","ë":"e","ẻ":"e","ě":"e","ȅ":"e","ȇ":"e","ẹ":"e","ệ":"e","ȩ":"e","ḝ":"e","ę":"e","ḙ":"e","ḛ":"e","ɇ":"e","ɛ":"e","ǝ":"e","ⓕ":"f","f":"f","ḟ":"f","ƒ":"f","ꝼ":"f","ⓖ":"g","g":"g","ǵ":"g","ĝ":"g","ḡ":"g","ğ":"g","ġ":"g","ǧ":"g","ģ":"g","ǥ":"g","ɠ":"g","ꞡ":"g","ᵹ":"g","ꝿ":"g","ⓗ":"h","h":"h","ĥ":"h","ḣ":"h","ḧ":"h","ȟ":"h","ḥ":"h","ḩ":"h","ḫ":"h","ẖ":"h","ħ":"h","ⱨ":"h","ⱶ":"h","ɥ":"h","ƕ":"hv","ⓘ":"i","i":"i","ì":"i","í":"i","î":"i","ĩ":"i","ī":"i","ĭ":"i","ï":"i","ḯ":"i","ỉ":"i","ǐ":"i","ȉ":"i","ȋ":"i","ị":"i","į":"i","ḭ":"i","ɨ":"i","ı":"i","ⓙ":"j","j":"j","ĵ":"j","ǰ":"j","ɉ":"j","ⓚ":"k","k":"k","ḱ":"k","ǩ":"k","ḳ":"k","ķ":"k","ḵ":"k","ƙ":"k","ⱪ":"k","ꝁ":"k","ꝃ":"k","ꝅ":"k","ꞣ":"k","ⓛ":"l","l":"l","ŀ":"l","ĺ":"l","ľ":"l","ḷ":"l","ḹ":"l","ļ":"l","ḽ":"l","ḻ":"l","ſ":"l","ł":"l","ƚ":"l","ɫ":"l","ⱡ":"l","ꝉ":"l","ꞁ":"l","ꝇ":"l","lj":"lj","ⓜ":"m","m":"m","ḿ":"m","ṁ":"m","ṃ":"m","ɱ":"m","ɯ":"m","ⓝ":"n","n":"n","ǹ":"n","ń":"n","ñ":"n","ṅ":"n","ň":"n","ṇ":"n","ņ":"n","ṋ":"n","ṉ":"n","ƞ":"n","ɲ":"n","ʼn":"n","ꞑ":"n","ꞥ":"n","nj":"nj","ⓞ":"o","o":"o","ò":"o","ó":"o","ô":"o","ồ":"o","ố":"o","ỗ":"o","ổ":"o","õ":"o","ṍ":"o","ȭ":"o","ṏ":"o","ō":"o","ṑ":"o","ṓ":"o","ŏ":"o","ȯ":"o","ȱ":"o","ö":"o","ȫ":"o","ỏ":"o","ő":"o","ǒ":"o","ȍ":"o","ȏ":"o","ơ":"o","ờ":"o","ớ":"o","ỡ":"o","ở":"o","ợ":"o","ọ":"o","ộ":"o","ǫ":"o","ǭ":"o","ø":"o","ǿ":"o","ɔ":"o","ꝋ":"o","ꝍ":"o","ɵ":"o","ƣ":"oi","ȣ":"ou","ꝏ":"oo","ⓟ":"p","p":"p","ṕ":"p","ṗ":"p","ƥ":"p","ᵽ":"p","ꝑ":"p","ꝓ":"p","ꝕ":"p","ⓠ":"q","q":"q","ɋ":"q","ꝗ":"q","ꝙ":"q","ⓡ":"r","r":"r","ŕ":"r","ṙ":"r","ř":"r","ȑ":"r","ȓ":"r","ṛ":"r","ṝ":"r","ŗ":"r","ṟ":"r","ɍ":"r","ɽ":"r","ꝛ":"r","ꞧ":"r","ꞃ":"r","ⓢ":"s","s":"s","ß":"s","ś":"s","ṥ":"s","ŝ":"s","ṡ":"s","š":"s","ṧ":"s","ṣ":"s","ṩ":"s","ș":"s","ş":"s","ȿ":"s","ꞩ":"s","ꞅ":"s","ẛ":"s","ⓣ":"t","t":"t","ṫ":"t","ẗ":"t","ť":"t","ṭ":"t","ț":"t","ţ":"t","ṱ":"t","ṯ":"t","ŧ":"t","ƭ":"t","ʈ":"t","ⱦ":"t","ꞇ":"t","ꜩ":"tz","ⓤ":"u","u":"u","ù":"u","ú":"u","û":"u","ũ":"u","ṹ":"u","ū":"u","ṻ":"u","ŭ":"u","ü":"u","ǜ":"u","ǘ":"u","ǖ":"u","ǚ":"u","ủ":"u","ů":"u","ű":"u","ǔ":"u","ȕ":"u","ȗ":"u","ư":"u","ừ":"u","ứ":"u","ữ":"u","ử":"u","ự":"u","ụ":"u","ṳ":"u","ų":"u","ṷ":"u","ṵ":"u","ʉ":"u","ⓥ":"v","v":"v","ṽ":"v","ṿ":"v","ʋ":"v","ꝟ":"v","ʌ":"v","ꝡ":"vy","ⓦ":"w","w":"w","ẁ":"w","ẃ":"w","ŵ":"w","ẇ":"w","ẅ":"w","ẘ":"w","ẉ":"w","ⱳ":"w","ⓧ":"x","x":"x","ẋ":"x","ẍ":"x","ⓨ":"y","y":"y","ỳ":"y","ý":"y","ŷ":"y","ỹ":"y","ȳ":"y","ẏ":"y","ÿ":"y","ỷ":"y","ẙ":"y","ỵ":"y","ƴ":"y","ɏ":"y","ỿ":"y","ⓩ":"z","z":"z","ź":"z","ẑ":"z","ż":"z","ž":"z","ẓ":"z","ẕ":"z","ƶ":"z","ȥ":"z","ɀ":"z","ⱬ":"z","ꝣ":"z"};$document=$(document),nextUid=function(){var counter=1;return function(){return counter++}}(),$document.on("mousemove",function(e){lastMousePosition.x=e.pageX,lastMousePosition.y=e.pageY}),AbstractSelect2=clazz(Object,{bind:function(func){var self=this;return function(){func.apply(self,arguments)}},init:function(opts){var results,search,resultsSelector=".select2-results";this.opts=opts=this.prepareOpts(opts),this.id=opts.id,opts.element.data("select2")!==undefined&&null!==opts.element.data("select2")&&opts.element.data("select2").destroy(),this.container=this.createContainer(),this.liveRegion=$("<span>",{role:"status","aria-live":"polite"}).addClass("select2-hidden-accessible").appendTo(document.body),this.containerId="s2id_"+(opts.element.attr("id")||"autogen"+nextUid()),this.containerEventName=this.containerId.replace(/([.])/g,"_").replace(/([;&,\-\.\+\*\~':"\!\^#$%@\[\]\(\)=>\|])/g,"\\$1"),this.container.attr("id",this.containerId),this.container.attr("title",opts.element.attr("title")),this.body=$("body"),syncCssClasses(this.container,this.opts.element,this.opts.adaptContainerCssClass),this.container.attr("style",opts.element.attr("style")),this.container.css(evaluate(opts.containerCss)),this.container.addClass(evaluate(opts.containerCssClass)),this.elementTabIndex=this.opts.element.attr("tabindex"),this.opts.element.data("select2",this).attr("tabindex","-1").before(this.container).on("click.select2",killEvent),this.container.data("select2",this),this.dropdown=this.container.find(".select2-drop"),syncCssClasses(this.dropdown,this.opts.element,this.opts.adaptDropdownCssClass),this.dropdown.addClass(evaluate(opts.dropdownCssClass)),this.dropdown.data("select2",this),this.dropdown.on("click",killEvent),this.results=results=this.container.find(resultsSelector),this.search=search=this.container.find("input.select2-input"),this.queryCount=0,this.resultsPage=0,this.context=null,this.initContainer(),this.container.on("click",killEvent),installFilteredMouseMove(this.results),this.dropdown.on("mousemove-filtered",resultsSelector,this.bind(this.highlightUnderEvent)),this.dropdown.on("touchstart touchmove touchend",resultsSelector,this.bind(function(event){this._touchEvent=!0,this.highlightUnderEvent(event)})),this.dropdown.on("touchmove",resultsSelector,this.bind(this.touchMoved)),this.dropdown.on("touchstart touchend",resultsSelector,this.bind(this.clearTouchMoved)),this.dropdown.on("click",this.bind(function(){this._touchEvent&&(this._touchEvent=!1,this.selectHighlighted())})),installDebouncedScroll(80,this.results),this.dropdown.on("scroll-debounced",resultsSelector,this.bind(this.loadMoreIfNeeded)),$(this.container).on("change",".select2-input",function(e){e.stopPropagation()}),$(this.dropdown).on("change",".select2-input",function(e){e.stopPropagation()}),$.fn.mousewheel&&results.mousewheel(function(e,delta,deltaX,deltaY){var top=results.scrollTop();deltaY>0&&0>=top-deltaY?(results.scrollTop(0),killEvent(e)):0>deltaY&&results.get(0).scrollHeight-results.scrollTop()+deltaY<=results.height()&&(results.scrollTop(results.get(0).scrollHeight-results.height()),killEvent(e))}),installKeyUpChangeEvent(search),search.on("keyup-change input paste",this.bind(this.updateResults)),search.on("focus",function(){search.addClass("select2-focused")}),search.on("blur",function(){search.removeClass("select2-focused")}),this.dropdown.on("mouseup",resultsSelector,this.bind(function(e){$(e.target).closest(".select2-result-selectable").length>0&&(this.highlightUnderEvent(e),this.selectHighlighted(e))})),this.dropdown.on("click mouseup mousedown touchstart touchend focusin",function(e){e.stopPropagation()}),this.nextSearchTerm=undefined,$.isFunction(this.opts.initSelection)&&(this.initSelection(),this.monitorSource()),null!==opts.maximumInputLength&&this.search.attr("maxlength",opts.maximumInputLength);var disabled=opts.element.prop("disabled");disabled===undefined&&(disabled=!1),this.enable(!disabled);var readonly=opts.element.prop("readonly");readonly===undefined&&(readonly=!1),this.readonly(readonly),scrollBarDimensions=scrollBarDimensions||measureScrollbar(),this.autofocus=opts.element.prop("autofocus"),opts.element.prop("autofocus",!1),this.autofocus&&this.focus(),this.search.attr("placeholder",opts.searchInputPlaceholder)},destroy:function(){var element=this.opts.element,select2=element.data("select2");this.close(),this.propertyObserver&&(this.propertyObserver.disconnect(),this.propertyObserver=null),select2!==undefined&&(select2.container.remove(),select2.liveRegion.remove(),select2.dropdown.remove(),element.removeClass("select2-offscreen").removeData("select2").off(".select2").prop("autofocus",this.autofocus||!1),this.elementTabIndex?element.attr({tabindex:this.elementTabIndex}):element.removeAttr("tabindex"),element.show()),cleanupJQueryElements.call(this,"container","liveRegion","dropdown","results","search")},optionToData:function(element){return element.is("option")?{id:element.prop("value"),text:element.text(),element:element.get(),css:element.attr("class"),disabled:element.prop("disabled"),locked:equal(element.attr("locked"),"locked")||equal(element.data("locked"),!0)}:element.is("optgroup")?{text:element.attr("label"),children:[],element:element.get(),css:element.attr("class")}:void 0},prepareOpts:function(opts){var element,select,idKey,ajaxUrl,self=this;if(element=opts.element,"select"===element.get(0).tagName.toLowerCase()&&(this.select=select=opts.element),select&&$.each(["id","multiple","ajax","query","createSearchChoice","initSelection","data","tags"],function(){if(this in opts)throw new Error("Option '"+this+"' is not allowed for Select2 when attached to a <select> element.")}),opts=$.extend({},{populateResults:function(container,results,query){var populate,id=this.opts.id,liveRegion=this.liveRegion;(populate=function(results,container,depth){var i,l,result,selectable,disabled,compound,node,label,innerContainer,formatted;for(results=opts.sortResults(results,container,query),i=0,l=results.length;l>i;i+=1)result=results[i],disabled=result.disabled===!0,selectable=!disabled&&id(result)!==undefined,compound=result.children&&result.children.length>0,node=$("<li></li>"),node.addClass("select2-results-dept-"+depth),node.addClass("select2-result"),node.addClass(selectable?"select2-result-selectable":"select2-result-unselectable"),disabled&&node.addClass("select2-disabled"),compound&&node.addClass("select2-result-with-children"),node.addClass(self.opts.formatResultCssClass(result)),node.attr("role","presentation"),label=$(document.createElement("div")),label.addClass("select2-result-label"),label.attr("id","select2-result-label-"+nextUid()),label.attr("role","option"),formatted=opts.formatResult(result,label,query,self.opts.escapeMarkup),formatted!==undefined&&(label.html(formatted),node.append(label)),compound&&(innerContainer=$("<ul></ul>"),innerContainer.addClass("select2-result-sub"),populate(result.children,innerContainer,depth+1),node.append(innerContainer)),node.data("select2-data",result),container.append(node);liveRegion.text(opts.formatMatches(results.length))})(results,container,0)}},$.fn.select2.defaults,opts),"function"!=typeof opts.id&&(idKey=opts.id,opts.id=function(e){return e[idKey]}),$.isArray(opts.element.data("select2Tags"))){if("tags"in opts)throw"tags specified as both an attribute 'data-select2-tags' and in options of Select2 "+opts.element.attr("id");opts.tags=opts.element.data("select2Tags")}if(select?(opts.query=this.bind(function(query){var children,placeholderOption,process,data={results:[],more:!1},term=query.term;process=function(element,collection){var group;element.is("option")?query.matcher(term,element.text(),element)&&collection.push(self.optionToData(element)):element.is("optgroup")&&(group=self.optionToData(element),element.children().each2(function(i,elm){process(elm,group.children)}),group.children.length>0&&collection.push(group))},children=element.children(),this.getPlaceholder()!==undefined&&children.length>0&&(placeholderOption=this.getPlaceholderOption(),placeholderOption&&(children=children.not(placeholderOption))),children.each2(function(i,elm){process(elm,data.results)}),query.callback(data)}),opts.id=function(e){return e.id}):"query"in opts||("ajax"in opts?(ajaxUrl=opts.element.data("ajax-url"),ajaxUrl&&ajaxUrl.length>0&&(opts.ajax.url=ajaxUrl),opts.query=ajax.call(opts.element,opts.ajax)):"data"in opts?opts.query=local(opts.data):"tags"in opts&&(opts.query=tags(opts.tags),opts.createSearchChoice===undefined&&(opts.createSearchChoice=function(term){return{id:$.trim(term),text:$.trim(term)}}),opts.initSelection===undefined&&(opts.initSelection=function(element,callback){var data=[];$(splitVal(element.val(),opts.separator)).each(function(){var obj={id:this,text:this},tags=opts.tags;$.isFunction(tags)&&(tags=tags()),$(tags).each(function(){return equal(this.id,obj.id)?(obj=this,!1):void 0}),data.push(obj)}),callback(data)}))),"function"!=typeof opts.query)throw"query function not defined for Select2 "+opts.element.attr("id");if("top"===opts.createSearchChoicePosition)opts.createSearchChoicePosition=function(list,item){list.unshift(item)};else if("bottom"===opts.createSearchChoicePosition)opts.createSearchChoicePosition=function(list,item){list.push(item)};else if("function"!=typeof opts.createSearchChoicePosition)throw"invalid createSearchChoicePosition option must be 'top', 'bottom' or a custom function";return opts},monitorSource:function(){var sync,observer,el=this.opts.element;el.on("change.select2",this.bind(function(){this.opts.element.data("select2-change-triggered")!==!0&&this.initSelection()})),sync=this.bind(function(){var disabled=el.prop("disabled");disabled===undefined&&(disabled=!1),this.enable(!disabled);var readonly=el.prop("readonly");readonly===undefined&&(readonly=!1),this.readonly(readonly),syncCssClasses(this.container,this.opts.element,this.opts.adaptContainerCssClass),this.container.addClass(evaluate(this.opts.containerCssClass)),syncCssClasses(this.dropdown,this.opts.element,this.opts.adaptDropdownCssClass),this.dropdown.addClass(evaluate(this.opts.dropdownCssClass))}),el.length&&el[0].attachEvent&&el.each(function(){this.attachEvent("onpropertychange",sync)}),observer=window.MutationObserver||window.WebKitMutationObserver||window.MozMutationObserver,observer!==undefined&&(this.propertyObserver&&(delete this.propertyObserver,this.propertyObserver=null),this.propertyObserver=new observer(function(mutations){mutations.forEach(sync)}),this.propertyObserver.observe(el.get(0),{attributes:!0,subtree:!1}))},triggerSelect:function(data){var evt=$.Event("select2-selecting",{val:this.id(data),object:data});return this.opts.element.trigger(evt),!evt.isDefaultPrevented()},triggerChange:function(details){details=details||{},details=$.extend({},details,{type:"change",val:this.val()}),this.opts.element.data("select2-change-triggered",!0),this.opts.element.trigger(details),this.opts.element.data("select2-change-triggered",!1),this.opts.element.click(),this.opts.blurOnChange&&this.opts.element.blur()},isInterfaceEnabled:function(){return this.enabledInterface===!0},enableInterface:function(){var enabled=this._enabled&&!this._readonly,disabled=!enabled;return enabled===this.enabledInterface?!1:(this.container.toggleClass("select2-container-disabled",disabled),this.close(),this.enabledInterface=enabled,!0)},enable:function(enabled){enabled===undefined&&(enabled=!0),this._enabled!==enabled&&(this._enabled=enabled,this.opts.element.prop("disabled",!enabled),this.enableInterface())},disable:function(){this.enable(!1)},readonly:function(enabled){enabled===undefined&&(enabled=!1),this._readonly!==enabled&&(this._readonly=enabled,this.opts.element.prop("readonly",enabled),this.enableInterface())},opened:function(){return this.container.hasClass("select2-dropdown-open")},positionDropdown:function(){var bodyOffset,above,changeDirection,css,resultsListNode,$dropdown=this.dropdown,offset=this.container.offset(),height=this.container.outerHeight(!1),width=this.container.outerWidth(!1),dropHeight=$dropdown.outerHeight(!1),$window=$(window),windowWidth=$window.width(),windowHeight=$window.height(),viewPortRight=$window.scrollLeft()+windowWidth,viewportBottom=$window.scrollTop()+windowHeight,dropTop=offset.top+height,dropLeft=offset.left,enoughRoomBelow=viewportBottom>=dropTop+dropHeight,enoughRoomAbove=offset.top-dropHeight>=$window.scrollTop(),dropWidth=$dropdown.outerWidth(!1),enoughRoomOnRight=viewPortRight>=dropLeft+dropWidth,aboveNow=$dropdown.hasClass("select2-drop-above");aboveNow?(above=!0,!enoughRoomAbove&&enoughRoomBelow&&(changeDirection=!0,above=!1)):(above=!1,!enoughRoomBelow&&enoughRoomAbove&&(changeDirection=!0,above=!0)),changeDirection&&($dropdown.hide(),offset=this.container.offset(),height=this.container.outerHeight(!1),width=this.container.outerWidth(!1),dropHeight=$dropdown.outerHeight(!1),viewPortRight=$window.scrollLeft()+windowWidth,viewportBottom=$window.scrollTop()+windowHeight,dropTop=offset.top+height,dropLeft=offset.left,dropWidth=$dropdown.outerWidth(!1),enoughRoomOnRight=viewPortRight>=dropLeft+dropWidth,$dropdown.show(),this.focusSearch()),this.opts.dropdownAutoWidth?(resultsListNode=$(".select2-results",$dropdown)[0],$dropdown.addClass("select2-drop-auto-width"),$dropdown.css("width",""),dropWidth=$dropdown.outerWidth(!1)+(resultsListNode.scrollHeight===resultsListNode.clientHeight?0:scrollBarDimensions.width),dropWidth>width?width=dropWidth:dropWidth=width,dropHeight=$dropdown.outerHeight(!1),enoughRoomOnRight=viewPortRight>=dropLeft+dropWidth):this.container.removeClass("select2-drop-auto-width"),"static"!==this.body.css("position")&&(bodyOffset=this.body.offset(),dropTop-=bodyOffset.top,dropLeft-=bodyOffset.left),enoughRoomOnRight||(dropLeft=offset.left+this.container.outerWidth(!1)-dropWidth),css={left:dropLeft,width:width},above?(css.top=offset.top-dropHeight,css.bottom="auto",this.container.addClass("select2-drop-above"),$dropdown.addClass("select2-drop-above")):(css.top=dropTop,css.bottom="auto",this.container.removeClass("select2-drop-above"),$dropdown.removeClass("select2-drop-above")),css=$.extend(css,evaluate(this.opts.dropdownCss)),$dropdown.css(css)},shouldOpen:function(){var event;return this.opened()?!1:this._enabled===!1||this._readonly===!0?!1:(event=$.Event("select2-opening"),this.opts.element.trigger(event),!event.isDefaultPrevented())},clearDropdownAlignmentPreference:function(){this.container.removeClass("select2-drop-above"),this.dropdown.removeClass("select2-drop-above")},open:function(){return this.shouldOpen()?(this.opening(),!0):!1},opening:function(){var mask,cid=this.containerEventName,scroll="scroll."+cid,resize="resize."+cid,orient="orientationchange."+cid;this.container.addClass("select2-dropdown-open").addClass("select2-container-active"),this.clearDropdownAlignmentPreference(),this.dropdown[0]!==this.body.children().last()[0]&&this.dropdown.detach().appendTo(this.body),mask=$("#select2-drop-mask"),0==mask.length&&(mask=$(document.createElement("div")),mask.attr("id","select2-drop-mask").attr("class","select2-drop-mask"),mask.hide(),mask.appendTo(this.body),mask.on("mousedown touchstart click",function(e){reinsertElement(mask);var self,dropdown=$("#select2-drop");dropdown.length>0&&(self=dropdown.data("select2"),self.opts.selectOnBlur&&self.selectHighlighted({noFocus:!0}),self.close(),e.preventDefault(),e.stopPropagation())})),this.dropdown.prev()[0]!==mask[0]&&this.dropdown.before(mask),$("#select2-drop").removeAttr("id"),this.dropdown.attr("id","select2-drop"),mask.show(),this.positionDropdown(),this.dropdown.show(),this.positionDropdown(),this.dropdown.addClass("select2-drop-active");var that=this;this.container.parents().add(window).each(function(){$(this).on(resize+" "+scroll+" "+orient,function(){that.opened()&&that.positionDropdown()})})},close:function(){if(this.opened()){var cid=this.containerEventName,scroll="scroll."+cid,resize="resize."+cid,orient="orientationchange."+cid;this.container.parents().add(window).each(function(){$(this).off(scroll).off(resize).off(orient)}),this.clearDropdownAlignmentPreference(),$("#select2-drop-mask").hide(),this.dropdown.removeAttr("id"),this.dropdown.hide(),this.container.removeClass("select2-dropdown-open").removeClass("select2-container-active"),this.results.empty(),this.clearSearch(),this.search.removeClass("select2-active"),this.opts.element.trigger($.Event("select2-close"))
|
7 |
+
}},externalSearch:function(term){this.open(),this.search.val(term),this.updateResults(!1)},clearSearch:function(){},getMaximumSelectionSize:function(){return evaluate(this.opts.maximumSelectionSize)},ensureHighlightVisible:function(){var children,index,child,hb,rb,y,more,results=this.results;if(index=this.highlight(),!(0>index)){if(0==index)return void results.scrollTop(0);children=this.findHighlightableChoices().find(".select2-result-label"),child=$(children[index]),hb=child.offset().top+child.outerHeight(!0),index===children.length-1&&(more=results.find("li.select2-more-results"),more.length>0&&(hb=more.offset().top+more.outerHeight(!0))),rb=results.offset().top+results.outerHeight(!0),hb>rb&&results.scrollTop(results.scrollTop()+(hb-rb)),y=child.offset().top-results.offset().top,0>y&&"none"!=child.css("display")&&results.scrollTop(results.scrollTop()+y)}},findHighlightableChoices:function(){return this.results.find(".select2-result-selectable:not(.select2-disabled):not(.select2-selected)")},moveHighlight:function(delta){for(var choices=this.findHighlightableChoices(),index=this.highlight();index>-1&&index<choices.length;){index+=delta;var choice=$(choices[index]);if(choice.hasClass("select2-result-selectable")&&!choice.hasClass("select2-disabled")&&!choice.hasClass("select2-selected")){this.highlight(index);break}}},highlight:function(index){var choice,data,choices=this.findHighlightableChoices();return 0===arguments.length?indexOf(choices.filter(".select2-highlighted")[0],choices.get()):(index>=choices.length&&(index=choices.length-1),0>index&&(index=0),this.removeHighlight(),choice=$(choices[index]),choice.addClass("select2-highlighted"),this.search.attr("aria-activedescendant",choice.find(".select2-result-label").attr("id")),this.ensureHighlightVisible(),this.liveRegion.text(choice.text()),data=choice.data("select2-data"),void(data&&this.opts.element.trigger({type:"select2-highlight",val:this.id(data),choice:data})))},removeHighlight:function(){this.results.find(".select2-highlighted").removeClass("select2-highlighted")},touchMoved:function(){this._touchMoved=!0},clearTouchMoved:function(){this._touchMoved=!1},countSelectableResults:function(){return this.findHighlightableChoices().length},highlightUnderEvent:function(event){var el=$(event.target).closest(".select2-result-selectable");if(el.length>0&&!el.is(".select2-highlighted")){var choices=this.findHighlightableChoices();this.highlight(choices.index(el))}else 0==el.length&&this.removeHighlight()},loadMoreIfNeeded:function(){var below,results=this.results,more=results.find("li.select2-more-results"),page=this.resultsPage+1,self=this,term=this.search.val(),context=this.context;0!==more.length&&(below=more.offset().top-results.offset().top-results.height(),below<=this.opts.loadMorePadding&&(more.addClass("select2-active"),this.opts.query({element:this.opts.element,term:term,page:page,context:context,matcher:this.opts.matcher,callback:this.bind(function(data){self.opened()&&(self.opts.populateResults.call(this,results,data.results,{term:term,page:page,context:context}),self.postprocessResults(data,!1,!1),data.more===!0?(more.detach().appendTo(results).text(evaluate(self.opts.formatLoadMore,page+1)),window.setTimeout(function(){self.loadMoreIfNeeded()},10)):more.remove(),self.positionDropdown(),self.resultsPage=page,self.context=data.context,this.opts.element.trigger({type:"select2-loaded",items:data}))})})))},tokenize:function(){},updateResults:function(initial){function postRender(){search.removeClass("select2-active"),self.positionDropdown(),self.liveRegion.text(results.find(".select2-no-results,.select2-selection-limit,.select2-searching").length?results.text():self.opts.formatMatches(results.find(".select2-result-selectable").length))}function render(html){results.html(html),postRender()}var data,input,queryNumber,search=this.search,results=this.results,opts=this.opts,self=this,term=search.val(),lastTerm=$.data(this.container,"select2-last-term");if((initial===!0||!lastTerm||!equal(term,lastTerm))&&($.data(this.container,"select2-last-term",term),initial===!0||this.showSearchInput!==!1&&this.opened())){queryNumber=++this.queryCount;var maxSelSize=this.getMaximumSelectionSize();if(maxSelSize>=1&&(data=this.data(),$.isArray(data)&&data.length>=maxSelSize&&checkFormatter(opts.formatSelectionTooBig,"formatSelectionTooBig")))return void render("<li class='select2-selection-limit'>"+evaluate(opts.formatSelectionTooBig,maxSelSize)+"</li>");if(search.val().length<opts.minimumInputLength)return render(checkFormatter(opts.formatInputTooShort,"formatInputTooShort")?"<li class='select2-no-results'>"+evaluate(opts.formatInputTooShort,search.val(),opts.minimumInputLength)+"</li>":""),void(initial&&this.showSearch&&this.showSearch(!0));if(opts.maximumInputLength&&search.val().length>opts.maximumInputLength)return void render(checkFormatter(opts.formatInputTooLong,"formatInputTooLong")?"<li class='select2-no-results'>"+evaluate(opts.formatInputTooLong,search.val(),opts.maximumInputLength)+"</li>":"");opts.formatSearching&&0===this.findHighlightableChoices().length&&render("<li class='select2-searching'>"+evaluate(opts.formatSearching)+"</li>"),search.addClass("select2-active"),this.removeHighlight(),input=this.tokenize(),input!=undefined&&null!=input&&search.val(input),this.resultsPage=1,opts.query({element:opts.element,term:search.val(),page:this.resultsPage,context:null,matcher:opts.matcher,callback:this.bind(function(data){var def;if(queryNumber==this.queryCount){if(!this.opened())return void this.search.removeClass("select2-active");if(this.context=data.context===undefined?null:data.context,this.opts.createSearchChoice&&""!==search.val()&&(def=this.opts.createSearchChoice.call(self,search.val(),data.results),def!==undefined&&null!==def&&self.id(def)!==undefined&&null!==self.id(def)&&0===$(data.results).filter(function(){return equal(self.id(this),self.id(def))}).length&&this.opts.createSearchChoicePosition(data.results,def)),0===data.results.length&&checkFormatter(opts.formatNoMatches,"formatNoMatches"))return void render("<li class='select2-no-results'>"+evaluate(opts.formatNoMatches,search.val())+"</li>");results.empty(),self.opts.populateResults.call(this,results,data.results,{term:search.val(),page:this.resultsPage,context:null}),data.more===!0&&checkFormatter(opts.formatLoadMore,"formatLoadMore")&&(results.append("<li class='select2-more-results'>"+self.opts.escapeMarkup(evaluate(opts.formatLoadMore,this.resultsPage))+"</li>"),window.setTimeout(function(){self.loadMoreIfNeeded()},10)),this.postprocessResults(data,initial),postRender(),this.opts.element.trigger({type:"select2-loaded",items:data})}})})}},cancel:function(){this.close()},blur:function(){this.opts.selectOnBlur&&this.selectHighlighted({noFocus:!0}),this.close(),this.container.removeClass("select2-container-active"),this.search[0]===document.activeElement&&this.search.blur(),this.clearSearch(),this.selection.find(".select2-search-choice-focus").removeClass("select2-search-choice-focus")},focusSearch:function(){focus(this.search)},selectHighlighted:function(options){if(this._touchMoved)return void this.clearTouchMoved();var index=this.highlight(),highlighted=this.results.find(".select2-highlighted"),data=highlighted.closest(".select2-result").data("select2-data");data?(this.highlight(index),this.onSelect(data,options)):options&&options.noFocus&&this.close()},getPlaceholder:function(){var placeholderOption;return this.opts.element.attr("placeholder")||this.opts.element.attr("data-placeholder")||this.opts.element.data("placeholder")||this.opts.placeholder||((placeholderOption=this.getPlaceholderOption())!==undefined?placeholderOption.text():undefined)},getPlaceholderOption:function(){if(this.select){var firstOption=this.select.children("option").first();if(this.opts.placeholderOption!==undefined)return"first"===this.opts.placeholderOption&&firstOption||"function"==typeof this.opts.placeholderOption&&this.opts.placeholderOption(this.select);if(""===$.trim(firstOption.text())&&""===firstOption.val())return firstOption}},initContainerWidth:function(){function resolveContainerWidth(){var style,attrs,matches,i,l,attr;if("off"===this.opts.width)return null;if("element"===this.opts.width)return 0===this.opts.element.outerWidth(!1)?"auto":this.opts.element.outerWidth(!1)+"px";if("copy"===this.opts.width||"resolve"===this.opts.width){if(style=this.opts.element.attr("style"),style!==undefined)for(attrs=style.split(";"),i=0,l=attrs.length;l>i;i+=1)if(attr=attrs[i].replace(/\s/g,""),matches=attr.match(/^width:(([-+]?([0-9]*\.)?[0-9]+)(px|em|ex|%|in|cm|mm|pt|pc))/i),null!==matches&&matches.length>=1)return matches[1];return"resolve"===this.opts.width?(style=this.opts.element.css("width"),style.indexOf("%")>0?style:0===this.opts.element.outerWidth(!1)?"auto":this.opts.element.outerWidth(!1)+"px"):null}return $.isFunction(this.opts.width)?this.opts.width():this.opts.width}var width=resolveContainerWidth.call(this);null!==width&&this.container.css("width",width)}}),SingleSelect2=clazz(AbstractSelect2,{createContainer:function(){var container=$(document.createElement("div")).attr({"class":"select2-container"}).html(["<a href='javascript:void(0)' class='select2-choice' tabindex='-1'>"," <span class='select2-chosen'> </span><abbr class='select2-search-choice-close'></abbr>"," <span class='select2-arrow' role='presentation'><b role='presentation'></b></span>","</a>","<label for='' class='select2-offscreen'></label>","<input class='select2-focusser select2-offscreen' type='text' aria-haspopup='true' role='button' />","<div class='select2-drop select2-display-none'>"," <div class='select2-search'>"," <label for='' class='select2-offscreen'></label>"," <input type='text' autocomplete='off' autocorrect='off' autocapitalize='off' spellcheck='false' class='select2-input' role='combobox' aria-expanded='true'"," aria-autocomplete='list' />"," </div>"," <ul class='select2-results' role='listbox'>"," </ul>","</div>"].join(""));return container},enableInterface:function(){this.parent.enableInterface.apply(this,arguments)&&this.focusser.prop("disabled",!this.isInterfaceEnabled())},opening:function(){var el,range,len;this.opts.minimumResultsForSearch>=0&&this.showSearch(!0),this.parent.opening.apply(this,arguments),this.showSearchInput!==!1&&this.search.val(this.focusser.val()),this.opts.shouldFocusInput(this)&&(this.search.focus(),el=this.search.get(0),el.createTextRange?(range=el.createTextRange(),range.collapse(!1),range.select()):el.setSelectionRange&&(len=this.search.val().length,el.setSelectionRange(len,len))),""===this.search.val()&&this.nextSearchTerm!=undefined&&(this.search.val(this.nextSearchTerm),this.search.select()),this.focusser.prop("disabled",!0).val(""),this.updateResults(!0),this.opts.element.trigger($.Event("select2-open"))},close:function(){this.opened()&&(this.parent.close.apply(this,arguments),this.focusser.prop("disabled",!1),this.opts.shouldFocusInput(this)&&this.focusser.focus())},focus:function(){this.opened()?this.close():(this.focusser.prop("disabled",!1),this.opts.shouldFocusInput(this)&&this.focusser.focus())},isFocused:function(){return this.container.hasClass("select2-container-active")},cancel:function(){this.parent.cancel.apply(this,arguments),this.focusser.prop("disabled",!1),this.opts.shouldFocusInput(this)&&this.focusser.focus()},destroy:function(){$("label[for='"+this.focusser.attr("id")+"']").attr("for",this.opts.element.attr("id")),this.parent.destroy.apply(this,arguments),cleanupJQueryElements.call(this,"selection","focusser")},initContainer:function(){var selection,elementLabel,container=this.container,dropdown=this.dropdown,idSuffix=nextUid();this.showSearch(this.opts.minimumResultsForSearch<0?!1:!0),this.selection=selection=container.find(".select2-choice"),this.focusser=container.find(".select2-focusser"),selection.find(".select2-chosen").attr("id","select2-chosen-"+idSuffix),this.focusser.attr("aria-labelledby","select2-chosen-"+idSuffix),this.results.attr("id","select2-results-"+idSuffix),this.search.attr("aria-owns","select2-results-"+idSuffix),this.focusser.attr("id","s2id_autogen"+idSuffix),elementLabel=$("label[for='"+this.opts.element.attr("id")+"']"),this.focusser.prev().text(elementLabel.text()).attr("for",this.focusser.attr("id"));var originalTitle=this.opts.element.attr("title");this.opts.element.attr("title",originalTitle||elementLabel.text()),this.focusser.attr("tabindex",this.elementTabIndex),this.search.attr("id",this.focusser.attr("id")+"_search"),this.search.prev().text($("label[for='"+this.focusser.attr("id")+"']").text()).attr("for",this.search.attr("id")),this.search.on("keydown",this.bind(function(e){if(this.isInterfaceEnabled()){if(e.which===KEY.PAGE_UP||e.which===KEY.PAGE_DOWN)return void killEvent(e);switch(e.which){case KEY.UP:case KEY.DOWN:return this.moveHighlight(e.which===KEY.UP?-1:1),void killEvent(e);case KEY.ENTER:return this.selectHighlighted(),void killEvent(e);case KEY.TAB:return void this.selectHighlighted({noFocus:!0});case KEY.ESC:return this.cancel(e),void killEvent(e)}}})),this.search.on("blur",this.bind(function(){document.activeElement===this.body.get(0)&&window.setTimeout(this.bind(function(){this.opened()&&this.search.focus()}),0)})),this.focusser.on("keydown",this.bind(function(e){if(this.isInterfaceEnabled()&&e.which!==KEY.TAB&&!KEY.isControl(e)&&!KEY.isFunctionKey(e)&&e.which!==KEY.ESC){if(this.opts.openOnEnter===!1&&e.which===KEY.ENTER)return void killEvent(e);if(e.which==KEY.DOWN||e.which==KEY.UP||e.which==KEY.ENTER&&this.opts.openOnEnter){if(e.altKey||e.ctrlKey||e.shiftKey||e.metaKey)return;return this.open(),void killEvent(e)}return e.which==KEY.DELETE||e.which==KEY.BACKSPACE?(this.opts.allowClear&&this.clear(),void killEvent(e)):void 0}})),installKeyUpChangeEvent(this.focusser),this.focusser.on("keyup-change input",this.bind(function(e){if(this.opts.minimumResultsForSearch>=0){if(e.stopPropagation(),this.opened())return;this.open()}})),selection.on("mousedown touchstart","abbr",this.bind(function(e){this.isInterfaceEnabled()&&(this.clear(),killEventImmediately(e),this.close(),this.selection.focus())})),selection.on("mousedown touchstart",this.bind(function(e){reinsertElement(selection),this.container.hasClass("select2-container-active")||this.opts.element.trigger($.Event("select2-focus")),this.opened()?this.close():this.isInterfaceEnabled()&&this.open(),killEvent(e)})),dropdown.on("mousedown touchstart",this.bind(function(){this.opts.shouldFocusInput(this)&&this.search.focus()})),selection.on("focus",this.bind(function(e){killEvent(e)})),this.focusser.on("focus",this.bind(function(){this.container.hasClass("select2-container-active")||this.opts.element.trigger($.Event("select2-focus")),this.container.addClass("select2-container-active")})).on("blur",this.bind(function(){this.opened()||(this.container.removeClass("select2-container-active"),this.opts.element.trigger($.Event("select2-blur")))})),this.search.on("focus",this.bind(function(){this.container.hasClass("select2-container-active")||this.opts.element.trigger($.Event("select2-focus")),this.container.addClass("select2-container-active")})),this.initContainerWidth(),this.opts.element.addClass("select2-offscreen"),this.setPlaceholder()},clear:function(triggerChange){var data=this.selection.data("select2-data");if(data){var evt=$.Event("select2-clearing");if(this.opts.element.trigger(evt),evt.isDefaultPrevented())return;var placeholderOption=this.getPlaceholderOption();this.opts.element.val(placeholderOption?placeholderOption.val():""),this.selection.find(".select2-chosen").empty(),this.selection.removeData("select2-data"),this.setPlaceholder(),triggerChange!==!1&&(this.opts.element.trigger({type:"select2-removed",val:this.id(data),choice:data}),this.triggerChange({removed:data}))}},initSelection:function(){if(this.isPlaceholderOptionSelected())this.updateSelection(null),this.close(),this.setPlaceholder();else{var self=this;this.opts.initSelection.call(null,this.opts.element,function(selected){selected!==undefined&&null!==selected&&(self.updateSelection(selected),self.close(),self.setPlaceholder(),self.nextSearchTerm=self.opts.nextSearchTerm(selected,self.search.val()))})}},isPlaceholderOptionSelected:function(){var placeholderOption;return this.getPlaceholder()===undefined?!1:(placeholderOption=this.getPlaceholderOption())!==undefined&&placeholderOption.prop("selected")||""===this.opts.element.val()||this.opts.element.val()===undefined||null===this.opts.element.val()},prepareOpts:function(){var opts=this.parent.prepareOpts.apply(this,arguments),self=this;return"select"===opts.element.get(0).tagName.toLowerCase()?opts.initSelection=function(element,callback){var selected=element.find("option").filter(function(){return this.selected&&!this.disabled});callback(self.optionToData(selected))}:"data"in opts&&(opts.initSelection=opts.initSelection||function(element,callback){var id=element.val(),match=null;opts.query({matcher:function(term,text,el){var is_match=equal(id,opts.id(el));return is_match&&(match=el),is_match},callback:$.isFunction(callback)?function(){callback(match)}:$.noop})}),opts},getPlaceholder:function(){return this.select&&this.getPlaceholderOption()===undefined?undefined:this.parent.getPlaceholder.apply(this,arguments)},setPlaceholder:function(){var placeholder=this.getPlaceholder();if(this.isPlaceholderOptionSelected()&&placeholder!==undefined){if(this.select&&this.getPlaceholderOption()===undefined)return;this.selection.find(".select2-chosen").html(this.opts.escapeMarkup(placeholder)),this.selection.addClass("select2-default"),this.container.removeClass("select2-allowclear")}},postprocessResults:function(data,initial,noHighlightUpdate){var selected=0,self=this;if(this.findHighlightableChoices().each2(function(i,elm){return equal(self.id(elm.data("select2-data")),self.opts.element.val())?(selected=i,!1):void 0}),noHighlightUpdate!==!1&&this.highlight(initial===!0&&selected>=0?selected:0),initial===!0){var min=this.opts.minimumResultsForSearch;min>=0&&this.showSearch(countResults(data.results)>=min)}},showSearch:function(showSearchInput){this.showSearchInput!==showSearchInput&&(this.showSearchInput=showSearchInput,this.dropdown.find(".select2-search").toggleClass("select2-search-hidden",!showSearchInput),this.dropdown.find(".select2-search").toggleClass("select2-offscreen",!showSearchInput),$(this.dropdown,this.container).toggleClass("select2-with-searchbox",showSearchInput))},onSelect:function(data,options){if(this.triggerSelect(data)){var old=this.opts.element.val(),oldData=this.data();this.opts.element.val(this.id(data)),this.updateSelection(data),this.opts.element.trigger({type:"select2-selected",val:this.id(data),choice:data}),this.nextSearchTerm=this.opts.nextSearchTerm(data,this.search.val()),this.close(),options&&options.noFocus||!this.opts.shouldFocusInput(this)||this.focusser.focus(),equal(old,this.id(data))||this.triggerChange({added:data,removed:oldData})}},updateSelection:function(data){var formatted,cssClass,container=this.selection.find(".select2-chosen");this.selection.data("select2-data",data),container.empty(),null!==data&&(formatted=this.opts.formatSelection(data,container,this.opts.escapeMarkup)),formatted!==undefined&&container.append(formatted),cssClass=this.opts.formatSelectionCssClass(data,container),cssClass!==undefined&&container.addClass(cssClass),this.selection.removeClass("select2-default"),this.opts.allowClear&&this.getPlaceholder()!==undefined&&this.container.addClass("select2-allowclear")},val:function(){var val,triggerChange=!1,data=null,self=this,oldData=this.data();if(0===arguments.length)return this.opts.element.val();if(val=arguments[0],arguments.length>1&&(triggerChange=arguments[1]),this.select)this.select.val(val).find("option").filter(function(){return this.selected}).each2(function(i,elm){return data=self.optionToData(elm),!1}),this.updateSelection(data),this.setPlaceholder(),triggerChange&&this.triggerChange({added:data,removed:oldData});else{if(!val&&0!==val)return void this.clear(triggerChange);if(this.opts.initSelection===undefined)throw new Error("cannot call val() if initSelection() is not defined");this.opts.element.val(val),this.opts.initSelection(this.opts.element,function(data){self.opts.element.val(data?self.id(data):""),self.updateSelection(data),self.setPlaceholder(),triggerChange&&self.triggerChange({added:data,removed:oldData})})}},clearSearch:function(){this.search.val(""),this.focusser.val("")},data:function(value){var data,triggerChange=!1;return 0===arguments.length?(data=this.selection.data("select2-data"),data==undefined&&(data=null),data):(arguments.length>1&&(triggerChange=arguments[1]),void(value?(data=this.data(),this.opts.element.val(value?this.id(value):""),this.updateSelection(value),triggerChange&&this.triggerChange({added:value,removed:data})):this.clear(triggerChange)))}}),MultiSelect2=clazz(AbstractSelect2,{createContainer:function(){var container=$(document.createElement("div")).attr({"class":"select2-container select2-container-multi"}).html(["<ul class='select2-choices'>"," <li class='select2-search-field'>"," <label for='' class='select2-offscreen'></label>"," <input type='text' autocomplete='off' autocorrect='off' autocapitalize='off' spellcheck='false' class='select2-input'>"," </li>","</ul>","<div class='select2-drop select2-drop-multi select2-display-none'>"," <ul class='select2-results'>"," </ul>","</div>"].join(""));return container},prepareOpts:function(){var opts=this.parent.prepareOpts.apply(this,arguments),self=this;return"select"===opts.element.get(0).tagName.toLowerCase()?opts.initSelection=function(element,callback){var data=[];element.find("option").filter(function(){return this.selected&&!this.disabled}).each2(function(i,elm){data.push(self.optionToData(elm))}),callback(data)}:"data"in opts&&(opts.initSelection=opts.initSelection||function(element,callback){var ids=splitVal(element.val(),opts.separator),matches=[];opts.query({matcher:function(term,text,el){var is_match=$.grep(ids,function(id){return equal(id,opts.id(el))}).length;return is_match&&matches.push(el),is_match},callback:$.isFunction(callback)?function(){for(var ordered=[],i=0;i<ids.length;i++)for(var id=ids[i],j=0;j<matches.length;j++){var match=matches[j];if(equal(id,opts.id(match))){ordered.push(match),matches.splice(j,1);break}}callback(ordered)}:$.noop})}),opts},selectChoice:function(choice){var selected=this.container.find(".select2-search-choice-focus");selected.length&&choice&&choice[0]==selected[0]||(selected.length&&this.opts.element.trigger("choice-deselected",selected),selected.removeClass("select2-search-choice-focus"),choice&&choice.length&&(this.close(),choice.addClass("select2-search-choice-focus"),this.opts.element.trigger("choice-selected",choice)))},destroy:function(){$("label[for='"+this.search.attr("id")+"']").attr("for",this.opts.element.attr("id")),this.parent.destroy.apply(this,arguments),cleanupJQueryElements.call(this,"searchContainer","selection")},initContainer:function(){var selection,selector=".select2-choices";this.searchContainer=this.container.find(".select2-search-field"),this.selection=selection=this.container.find(selector);var _this=this;this.selection.on("click",".select2-search-choice:not(.select2-locked)",function(){_this.search[0].focus(),_this.selectChoice($(this))}),this.search.attr("id","s2id_autogen"+nextUid()),this.search.prev().text($("label[for='"+this.opts.element.attr("id")+"']").text()).attr("for",this.search.attr("id")),this.search.on("input paste",this.bind(function(){this.isInterfaceEnabled()&&(this.opened()||this.open())})),this.search.attr("tabindex",this.elementTabIndex),this.keydowns=0,this.search.on("keydown",this.bind(function(e){if(this.isInterfaceEnabled()){++this.keydowns;var selected=selection.find(".select2-search-choice-focus"),prev=selected.prev(".select2-search-choice:not(.select2-locked)"),next=selected.next(".select2-search-choice:not(.select2-locked)"),pos=getCursorInfo(this.search);if(selected.length&&(e.which==KEY.LEFT||e.which==KEY.RIGHT||e.which==KEY.BACKSPACE||e.which==KEY.DELETE||e.which==KEY.ENTER)){var selectedChoice=selected;return e.which==KEY.LEFT&&prev.length?selectedChoice=prev:e.which==KEY.RIGHT?selectedChoice=next.length?next:null:e.which===KEY.BACKSPACE?this.unselect(selected.first())&&(this.search.width(10),selectedChoice=prev.length?prev:next):e.which==KEY.DELETE?this.unselect(selected.first())&&(this.search.width(10),selectedChoice=next.length?next:null):e.which==KEY.ENTER&&(selectedChoice=null),this.selectChoice(selectedChoice),killEvent(e),void(selectedChoice&&selectedChoice.length||this.open())}if((e.which===KEY.BACKSPACE&&1==this.keydowns||e.which==KEY.LEFT)&&0==pos.offset&&!pos.length)return this.selectChoice(selection.find(".select2-search-choice:not(.select2-locked)").last()),void killEvent(e);if(this.selectChoice(null),this.opened())switch(e.which){case KEY.UP:case KEY.DOWN:return this.moveHighlight(e.which===KEY.UP?-1:1),void killEvent(e);case KEY.ENTER:return this.selectHighlighted(),void killEvent(e);case KEY.TAB:return this.selectHighlighted({noFocus:!0}),void this.close();case KEY.ESC:return this.cancel(e),void killEvent(e)}if(e.which!==KEY.TAB&&!KEY.isControl(e)&&!KEY.isFunctionKey(e)&&e.which!==KEY.BACKSPACE&&e.which!==KEY.ESC){if(e.which===KEY.ENTER){if(this.opts.openOnEnter===!1)return;if(e.altKey||e.ctrlKey||e.shiftKey||e.metaKey)return}this.open(),(e.which===KEY.PAGE_UP||e.which===KEY.PAGE_DOWN)&&killEvent(e),e.which===KEY.ENTER&&killEvent(e)}}})),this.search.on("keyup",this.bind(function(){this.keydowns=0,this.resizeSearch()})),this.search.on("blur",this.bind(function(e){this.container.removeClass("select2-container-active"),this.search.removeClass("select2-focused"),this.selectChoice(null),this.opened()||this.clearSearch(),e.stopImmediatePropagation(),this.opts.element.trigger($.Event("select2-blur"))})),this.container.on("click",selector,this.bind(function(e){this.isInterfaceEnabled()&&($(e.target).closest(".select2-search-choice").length>0||(this.selectChoice(null),this.clearPlaceholder(),this.container.hasClass("select2-container-active")||this.opts.element.trigger($.Event("select2-focus")),this.open(),this.focusSearch(),e.preventDefault()))})),this.container.on("focus",selector,this.bind(function(){this.isInterfaceEnabled()&&(this.container.hasClass("select2-container-active")||this.opts.element.trigger($.Event("select2-focus")),this.container.addClass("select2-container-active"),this.dropdown.addClass("select2-drop-active"),this.clearPlaceholder())})),this.initContainerWidth(),this.opts.element.addClass("select2-offscreen"),this.clearSearch()},enableInterface:function(){this.parent.enableInterface.apply(this,arguments)&&this.search.prop("disabled",!this.isInterfaceEnabled())},initSelection:function(){if(""===this.opts.element.val()&&""===this.opts.element.text()&&(this.updateSelection([]),this.close(),this.clearSearch()),this.select||""!==this.opts.element.val()){var self=this;this.opts.initSelection.call(null,this.opts.element,function(data){data!==undefined&&null!==data&&(self.updateSelection(data),self.close(),self.clearSearch())})}},clearSearch:function(){var placeholder=this.getPlaceholder(),maxWidth=this.getMaxSearchWidth();placeholder!==undefined&&0===this.getVal().length&&this.search.hasClass("select2-focused")===!1?(this.search.val(placeholder).addClass("select2-default"),this.search.width(maxWidth>0?maxWidth:this.container.css("width"))):this.search.val("").width(10)},clearPlaceholder:function(){this.search.hasClass("select2-default")&&this.search.val("").removeClass("select2-default")},opening:function(){this.clearPlaceholder(),this.resizeSearch(),this.parent.opening.apply(this,arguments),this.focusSearch(),""===this.search.val()&&this.nextSearchTerm!=undefined&&(this.search.val(this.nextSearchTerm),this.search.select()),this.updateResults(!0),this.opts.shouldFocusInput(this)&&this.search.focus(),this.opts.element.trigger($.Event("select2-open"))},close:function(){this.opened()&&this.parent.close.apply(this,arguments)},focus:function(){this.close(),this.search.focus()},isFocused:function(){return this.search.hasClass("select2-focused")},updateSelection:function(data){var ids=[],filtered=[],self=this;$(data).each(function(){indexOf(self.id(this),ids)<0&&(ids.push(self.id(this)),filtered.push(this))}),data=filtered,this.selection.find(".select2-search-choice").remove(),$(data).each(function(){self.addSelectedChoice(this)}),self.postprocessResults()},tokenize:function(){var input=this.search.val();input=this.opts.tokenizer.call(this,input,this.data(),this.bind(this.onSelect),this.opts),null!=input&&input!=undefined&&(this.search.val(input),input.length>0&&this.open())},onSelect:function(data,options){this.triggerSelect(data)&&(this.addSelectedChoice(data),this.opts.element.trigger({type:"selected",val:this.id(data),choice:data}),this.nextSearchTerm=this.opts.nextSearchTerm(data,this.search.val()),this.clearSearch(),this.updateResults(),(this.select||!this.opts.closeOnSelect)&&this.postprocessResults(data,!1,this.opts.closeOnSelect===!0),this.opts.closeOnSelect?(this.close(),this.search.width(10)):this.countSelectableResults()>0?(this.search.width(10),this.resizeSearch(),this.getMaximumSelectionSize()>0&&this.val().length>=this.getMaximumSelectionSize()?this.updateResults(!0):this.nextSearchTerm!=undefined&&(this.search.val(this.nextSearchTerm),this.updateResults(),this.search.select()),this.positionDropdown()):(this.close(),this.search.width(10)),this.triggerChange({added:data}),options&&options.noFocus||this.focusSearch())},cancel:function(){this.close(),this.focusSearch()},addSelectedChoice:function(data){var formatted,cssClass,enableChoice=!data.locked,enabledItem=$("<li class='select2-search-choice'> <div></div> <a href='#' class='select2-search-choice-close' tabindex='-1'></a></li>"),disabledItem=$("<li class='select2-search-choice select2-locked'><div></div></li>"),choice=enableChoice?enabledItem:disabledItem,id=this.id(data),val=this.getVal();formatted=this.opts.formatSelection(data,choice.find("div"),this.opts.escapeMarkup),formatted!=undefined&&choice.find("div").replaceWith("<div>"+formatted+"</div>"),cssClass=this.opts.formatSelectionCssClass(data,choice.find("div")),cssClass!=undefined&&choice.addClass(cssClass),enableChoice&&choice.find(".select2-search-choice-close").on("mousedown",killEvent).on("click dblclick",this.bind(function(e){this.isInterfaceEnabled()&&(this.unselect($(e.target)),this.selection.find(".select2-search-choice-focus").removeClass("select2-search-choice-focus"),killEvent(e),this.close(),this.focusSearch())})).on("focus",this.bind(function(){this.isInterfaceEnabled()&&(this.container.addClass("select2-container-active"),this.dropdown.addClass("select2-drop-active"))})),choice.data("select2-data",data),choice.insertBefore(this.searchContainer),val.push(id),this.setVal(val)},unselect:function(selected){var data,index,val=this.getVal();if(selected=selected.closest(".select2-search-choice"),0===selected.length)throw"Invalid argument: "+selected+". Must be .select2-search-choice";if(data=selected.data("select2-data")){var evt=$.Event("select2-removing");if(evt.val=this.id(data),evt.choice=data,this.opts.element.trigger(evt),evt.isDefaultPrevented())return!1;for(;(index=indexOf(this.id(data),val))>=0;)val.splice(index,1),this.setVal(val),this.select&&this.postprocessResults();return selected.remove(),this.opts.element.trigger({type:"select2-removed",val:this.id(data),choice:data}),this.triggerChange({removed:data}),!0}},postprocessResults:function(data,initial,noHighlightUpdate){var val=this.getVal(),choices=this.results.find(".select2-result"),compound=this.results.find(".select2-result-with-children"),self=this;choices.each2(function(i,choice){var id=self.id(choice.data("select2-data"));indexOf(id,val)>=0&&(choice.addClass("select2-selected"),choice.find(".select2-result-selectable").addClass("select2-selected"))
|
8 |
+
}),compound.each2(function(i,choice){choice.is(".select2-result-selectable")||0!==choice.find(".select2-result-selectable:not(.select2-selected)").length||choice.addClass("select2-selected")}),-1==this.highlight()&&noHighlightUpdate!==!1&&self.highlight(0),!this.opts.createSearchChoice&&!choices.filter(".select2-result:not(.select2-selected)").length>0&&(!data||data&&!data.more&&0===this.results.find(".select2-no-results").length)&&checkFormatter(self.opts.formatNoMatches,"formatNoMatches")&&this.results.append("<li class='select2-no-results'>"+evaluate(self.opts.formatNoMatches,self.search.val())+"</li>")},getMaxSearchWidth:function(){return this.selection.width()-getSideBorderPadding(this.search)},resizeSearch:function(){var minimumWidth,left,maxWidth,containerLeft,searchWidth,sideBorderPadding=getSideBorderPadding(this.search);minimumWidth=measureTextWidth(this.search)+10,left=this.search.offset().left,maxWidth=this.selection.width(),containerLeft=this.selection.offset().left,searchWidth=maxWidth-(left-containerLeft)-sideBorderPadding,minimumWidth>searchWidth&&(searchWidth=maxWidth-sideBorderPadding),40>searchWidth&&(searchWidth=maxWidth-sideBorderPadding),0>=searchWidth&&(searchWidth=minimumWidth),this.search.width(Math.floor(searchWidth))},getVal:function(){var val;return this.select?(val=this.select.val(),null===val?[]:val):(val=this.opts.element.val(),splitVal(val,this.opts.separator))},setVal:function(val){var unique;this.select?this.select.val(val):(unique=[],$(val).each(function(){indexOf(this,unique)<0&&unique.push(this)}),this.opts.element.val(0===unique.length?"":unique.join(this.opts.separator)))},buildChangeDetails:function(old,current){for(var current=current.slice(0),old=old.slice(0),i=0;i<current.length;i++)for(var j=0;j<old.length;j++)equal(this.opts.id(current[i]),this.opts.id(old[j]))&&(current.splice(i,1),i>0&&i--,old.splice(j,1),j--);return{added:current,removed:old}},val:function(val,triggerChange){var oldData,self=this;if(0===arguments.length)return this.getVal();if(oldData=this.data(),oldData.length||(oldData=[]),!val&&0!==val)return this.opts.element.val(""),this.updateSelection([]),this.clearSearch(),void(triggerChange&&this.triggerChange({added:this.data(),removed:oldData}));if(this.setVal(val),this.select)this.opts.initSelection(this.select,this.bind(this.updateSelection)),triggerChange&&this.triggerChange(this.buildChangeDetails(oldData,this.data()));else{if(this.opts.initSelection===undefined)throw new Error("val() cannot be called if initSelection() is not defined");this.opts.initSelection(this.opts.element,function(data){var ids=$.map(data,self.id);self.setVal(ids),self.updateSelection(data),self.clearSearch(),triggerChange&&self.triggerChange(self.buildChangeDetails(oldData,self.data()))})}this.clearSearch()},onSortStart:function(){if(this.select)throw new Error("Sorting of elements is not supported when attached to <select>. Attach to <input type='hidden'/> instead.");this.search.width(0),this.searchContainer.hide()},onSortEnd:function(){var val=[],self=this;this.searchContainer.show(),this.searchContainer.appendTo(this.searchContainer.parent()),this.resizeSearch(),this.selection.find(".select2-search-choice").each(function(){val.push(self.opts.id($(this).data("select2-data")))}),this.setVal(val),this.triggerChange()},data:function(values,triggerChange){var ids,old,self=this;return 0===arguments.length?this.selection.children(".select2-search-choice").map(function(){return $(this).data("select2-data")}).get():(old=this.data(),values||(values=[]),ids=$.map(values,function(e){return self.opts.id(e)}),this.setVal(ids),this.updateSelection(values),this.clearSearch(),triggerChange&&this.triggerChange(this.buildChangeDetails(old,this.data())),void 0)}}),$.fn.select2=function(){var opts,select2,method,value,multiple,args=Array.prototype.slice.call(arguments,0),allowedMethods=["val","destroy","opened","open","close","focus","isFocused","container","dropdown","onSortStart","onSortEnd","enable","disable","readonly","positionDropdown","data","search"],valueMethods=["opened","isFocused","container","dropdown"],propertyMethods=["val","data"],methodsMap={search:"externalSearch"};return this.each(function(){if(0===args.length||"object"==typeof args[0])opts=0===args.length?{}:$.extend({},args[0]),opts.element=$(this),"select"===opts.element.get(0).tagName.toLowerCase()?multiple=opts.element.prop("multiple"):(multiple=opts.multiple||!1,"tags"in opts&&(opts.multiple=multiple=!0)),select2=multiple?new window.Select2["class"].multi:new window.Select2["class"].single,select2.init(opts);else{if("string"!=typeof args[0])throw"Invalid arguments to select2 plugin: "+args;if(indexOf(args[0],allowedMethods)<0)throw"Unknown method: "+args[0];if(value=undefined,select2=$(this).data("select2"),select2===undefined)return;if(method=args[0],"container"===method?value=select2.container:"dropdown"===method?value=select2.dropdown:(methodsMap[method]&&(method=methodsMap[method]),value=select2[method].apply(select2,args.slice(1))),indexOf(args[0],valueMethods)>=0||indexOf(args[0],propertyMethods)>=0&&1==args.length)return!1}}),value===undefined?this:value},$.fn.select2.defaults={width:"copy",loadMorePadding:0,closeOnSelect:!0,openOnEnter:!0,containerCss:{},dropdownCss:{},containerCssClass:"",dropdownCssClass:"",formatResult:function(result,container,query,escapeMarkup){var markup=[];return markMatch(result.text,query.term,markup,escapeMarkup),markup.join("")},formatSelection:function(data,container,escapeMarkup){return data?escapeMarkup(data.text):undefined},sortResults:function(results){return results},formatResultCssClass:function(data){return data.css},formatSelectionCssClass:function(){return undefined},formatMatches:function(matches){return matches+" results are available, use up and down arrow keys to navigate."},formatNoMatches:function(){return"No matches found"},formatInputTooShort:function(input,min){var n=min-input.length;return"Please enter "+n+" or more character"+(1==n?"":"s")},formatInputTooLong:function(input,max){var n=input.length-max;return"Please delete "+n+" character"+(1==n?"":"s")},formatSelectionTooBig:function(limit){return"You can only select "+limit+" item"+(1==limit?"":"s")},formatLoadMore:function(){return"Loading more results…"},formatSearching:function(){return"Searching…"},minimumResultsForSearch:0,minimumInputLength:0,maximumInputLength:null,maximumSelectionSize:0,id:function(e){return e==undefined?null:e.id},matcher:function(term,text){return stripDiacritics(""+text).toUpperCase().indexOf(stripDiacritics(""+term).toUpperCase())>=0},separator:",",tokenSeparators:[],tokenizer:defaultTokenizer,escapeMarkup:defaultEscapeMarkup,blurOnChange:!1,selectOnBlur:!1,adaptContainerCssClass:function(c){return c},adaptDropdownCssClass:function(){return null},nextSearchTerm:function(){return undefined},searchInputPlaceholder:"",createSearchChoicePosition:"top",shouldFocusInput:function(instance){var supportsTouchEvents="ontouchstart"in window||navigator.msMaxTouchPoints>0;return supportsTouchEvents&&instance.opts.minimumResultsForSearch<0?!1:!0}},$.fn.select2.ajaxDefaults={transport:$.ajax,params:{type:"GET",cache:!1,dataType:"json"}},window.Select2={query:{ajax:ajax,local:local,tags:tags},util:{debounce:debounce,markMatch:markMatch,escapeMarkup:defaultEscapeMarkup,stripDiacritics:stripDiacritics},"class":{"abstract":AbstractSelect2,single:SingleSelect2,multi:MultiSelect2}}}}(jQuery),jQuery(document).ready(function($){$("#filter_action, #filter_content, #filter_form").change(function(){$("#leadin-contacts-filter-button").addClass("button-primary")})});
|
assets/js/build/leadin-subscribe.js
CHANGED
@@ -404,10 +404,11 @@ jQuery(document).ready( function ( $ ) {
|
|
404 |
|
405 |
function bind_leadin_subscribe_widget ( lis_heading, lis_desc, lis_show_names, lis_show_phone, lis_btn_label, lis_vex_class, lis_confirmation )
|
406 |
{
|
407 |
-
|
408 |
-
|
409 |
-
|
410 |
-
|
|
|
411 |
lis_confirmation = ( lis_confirmation ? lis_confirmation : 1 );
|
412 |
|
413 |
(function(){
|
@@ -469,7 +470,7 @@ function bind_leadin_subscribe_widget ( lis_heading, lis_desc, lis_show_names, l
|
|
469 |
( parseInt(lis_confirmation) ? '<h3>Thanks!<br>You should receive a confirmation email in your inbox shortly.</h3>' : '<h3>Thanks!<br>We received your submission.</h3>' ) +
|
470 |
'<div id="powered-by-leadin-thank-you">' +
|
471 |
'<span class="powered-by">Powered by Leadin</span>' +
|
472 |
-
'<a href="http://leadin.com/wordpress-subscribe-widget-plugin
|
473 |
'</div>'
|
474 |
).css('text-align', 'center').fadeIn(250);
|
475 |
});
|
@@ -487,9 +488,7 @@ function bind_leadin_subscribe_widget ( lis_heading, lis_desc, lis_show_names, l
|
|
487 |
}
|
488 |
});
|
489 |
|
490 |
-
|
491 |
-
|
492 |
-
$('.leadin-subscribe form.vex-dialog-form').append('<a href="http://leadin.com/wordpress-subscribe-widget-plugin/?utm_campaign=subscribe_widget&utm_medium=widget&utm_source=' + document.URL + '" id="leadin-subscribe-powered-by" class="leadin-subscribe-powered-by">Powered by Leadin</a>');
|
493 |
};
|
494 |
|
495 |
subscribe._open = function() {
|
404 |
|
405 |
function bind_leadin_subscribe_widget ( lis_heading, lis_desc, lis_show_names, lis_show_phone, lis_btn_label, lis_vex_class, lis_confirmation )
|
406 |
{
|
407 |
+
|
408 |
+
lis_heading = ( lis_heading ? lis_heading : 'Sign up for email updates' );
|
409 |
+
lis_desc = ( lis_desc ? lis_desc : '' );
|
410 |
+
lis_btn_label = ( lis_btn_label ? lis_btn_label : 'SUBSCRIBE' );
|
411 |
+
lis_vex_class = ( lis_vex_class ? lis_vex_class : 'vex-theme-bottom-right-corner' );
|
412 |
lis_confirmation = ( lis_confirmation ? lis_confirmation : 1 );
|
413 |
|
414 |
(function(){
|
470 |
( parseInt(lis_confirmation) ? '<h3>Thanks!<br>You should receive a confirmation email in your inbox shortly.</h3>' : '<h3>Thanks!<br>We received your submission.</h3>' ) +
|
471 |
'<div id="powered-by-leadin-thank-you">' +
|
472 |
'<span class="powered-by">Powered by Leadin</span>' +
|
473 |
+
'<a href="http://leadin.com/wordpress-subscribe-widget-plugin?utm_source=virality&utm_medium=referral&utm_term=' + window.location.host + '&utm_content=e11&utm_campaign=subscribe%20widget"><img alt="Leadin" height="20px" width="99px" src="' + document.location.protocol + '//leadin.com/wp-content/themes/LeadIn-WP-Theme/library/images/logos/Leadin_logo@2x.png" alt="leadin.com"/></a>' +
|
474 |
'</div>'
|
475 |
).css('text-align', 'center').fadeIn(250);
|
476 |
});
|
488 |
}
|
489 |
});
|
490 |
|
491 |
+
$('.leadin-subscribe form.vex-dialog-form').append('<a href="http://leadin.com/wordpress-subscribe-widget-plugin?utm_source=virality&utm_medium=referral&utm_term=' + window.location.host + '&utm_content=e11&utm_campaign=subscribe%20widget" id="leadin-subscribe-powered-by" class="leadin-subscribe-powered-by">Powered by Leadin</a>');
|
|
|
|
|
492 |
};
|
493 |
|
494 |
subscribe._open = function() {
|
assets/js/build/leadin-subscribe.min.js
CHANGED
@@ -1 +1 @@
|
|
1 |
-
function bind_leadin_subscribe_widget(lis_heading,lis_desc,lis_show_names,lis_show_phone,lis_btn_label,lis_vex_class,lis_confirmation){lis_heading=lis_heading?lis_heading:"Sign up for email updates",lis_desc=lis_desc?lis_desc:"",lis_btn_label=lis_btn_label?lis_btn_label:"SUBSCRIBE",lis_vex_class=lis_vex_class?lis_vex_class:"vex-theme-bottom-right-corner",lis_confirmation=lis_confirmation?lis_confirmation:1,function(){var $=jQuery,subscribe={};subscribe.vex=void 0,subscribe.init=function(){$(window).scrollTop()+$(window).height()>$(document).height()/2&&subscribe.open(),$(window).scroll(function(){$(window).scrollTop()+$(window).height()>$(document).height()/2&&subscribe.open()})},subscribe.open=function(){return subscribe.vex?subscribe._open():(subscribe.vex=vex.dialog.open({showCloseButton:!0,className:"leadin-subscribe "+lis_vex_class,message:"<h4>"+lis_heading+"</h4><p>"+lis_desc+"</p>",input:'<input id="leadin-subscribe-email" name="email" type="email" placeholder="Email address" />'+(parseInt(lis_show_names)?'<input id="leadin-subscribe-fname" name="fname" type="text" placeholder="First Name" /><input id="leadin-subscribe-lname" name="lname" type="text" placeholder="Last Name" />':"")+(parseInt(lis_show_phone)?'<input id="leadin-subscribe-phone" name="phone" type="tel" placeholder="Phone" />':""),buttons:[$.extend({},vex.dialog.buttons.YES,{text:lis_btn_label?lis_btn_label:"SUBSCRIBE"})],onSubmit:function(){$subscribe_form=$(this),$subscribe_form.find("input.error").removeClass("error");var form_validated=!0;return $subscribe_form.find("input").each(function(){var $input=$(this);$input.val()||($input.addClass("error"),form_validated=!1)}),form_validated?($(".vex-dialog-form").fadeOut(300,function(){$(".vex-dialog-form").html('<div class="vex-close"></div>'+(parseInt(lis_confirmation)?"<h3>Thanks!<br>You should receive a confirmation email in your inbox shortly.</h3>":"<h3>Thanks!<br>We received your submission.</h3>")+'<div id="powered-by-leadin-thank-you"><span class="powered-by">Powered by Leadin</span><a href="http://leadin.com/wordpress-subscribe-widget-plugin/?utm_campaign=subscribe_widget&utm_medium=email&utm_source='+window.location.host+'"><img alt="Leadin" height="20px" width="99px" src="'+document.location.protocol+'//leadin.com/wp-content/themes/LeadIn-WP-Theme/library/images/logos/Leadin_logo@2x.png" alt="leadin.com"/></a></div>').css("text-align","center").fadeIn(250)}),leadin_submit_form($(".leadin-subscribe form"),$),$.cookie("li_subscribe","ignore",{path:"/",domain:"",expires:ignore_date}),!1):!1},callback:function(data){data===!1&&$.cookie("li_subscribe","ignore",{path:"/",domain:"",expires:ignore_date}),$.cookie("li_subscribe","ignore",{path:"/",domain:"",expires:ignore_date})}}),void $(".leadin-subscribe form.vex-dialog-form").append('<a href="http://leadin.com/wordpress-subscribe-widget-plugin/?utm_campaign=subscribe_widget&utm_medium=widget&utm_source='+document.URL+'" id="leadin-subscribe-powered-by" class="leadin-subscribe-powered-by">Powered by Leadin</a>'))},subscribe._open=function(){subscribe.vex.parent().removeClass("vex-closing")},subscribe.close=function(){subscribe.vex&&subscribe.vex.parent().addClass("vex-closing")},subscribe.init(),window.subscribe=subscribe}()}function leadin_subscribe_check_mobile($){var is_mobile=!1;return"none"==$("#leadin-subscribe-mobile-check").css("display")&&(is_mobile=!0),is_mobile}function leadin_subscribe_show(){jQuery.ajax({type:"POST",url:li_ajax.ajax_url,data:{action:"leadin_subscribe_show"},success:function(){},error:function(){}})}function leadin_get_parameter_by_name(name){name=name.replace(/[\[]/,"\\[").replace(/[\]]/,"\\]");var regex=new RegExp("[\\?&]"+name+"=([^&#]*)"),results=regex.exec(location.search);return null==results?"":decodeURIComponent(results[1].replace(/\+/g," "))}(function(){var vexFactory;vexFactory=function($){var animationEndSupport,vex;return animationEndSupport=!1,$(function(){var s;return s=(document.body||document.documentElement).style,animationEndSupport=void 0!==s.animation||void 0!==s.WebkitAnimation||void 0!==s.MozAnimation||void 0!==s.MsAnimation||void 0!==s.OAnimation,$(window).bind("keyup.vex",function(event){return 27===event.keyCode?vex.closeByEscape():void 0})}),vex={globalID:1,animationEndEvent:"animationend webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend",baseClassNames:{vex:"vex",content:"vex-content",overlay:"vex-overlay",close:"vex-close",closing:"vex-closing",open:"vex-open"},defaultOptions:{content:"",showCloseButton:!0,escapeButtonCloses:!0,overlayClosesOnClick:!0,appendLocation:"body",className:"",css:{},overlayClassName:"",overlayCSS:{},contentClassName:"",contentCSS:{},closeClassName:"",closeCSS:{}},open:function(options){return options=$.extend({},vex.defaultOptions,options),options.id=vex.globalID,vex.globalID+=1,options.$vex=$("<div>").addClass(vex.baseClassNames.vex).addClass(options.className).css(options.css).data({vex:options}),options.$vexOverlay=$("<div>").addClass(vex.baseClassNames.overlay).addClass(options.overlayClassName).css(options.overlayCSS).data({vex:options}),options.overlayClosesOnClick&&options.$vexOverlay.bind("click.vex",function(e){return e.target===this?vex.close($(this).data().vex.id):void 0}),options.$vex.append(options.$vexOverlay),options.$vexContent=$("<div>").addClass(vex.baseClassNames.content).addClass(options.contentClassName).css(options.contentCSS).append(options.content).data({vex:options}),options.$vex.append(options.$vexContent),options.showCloseButton&&(options.$closeButton=$("<div>").addClass(vex.baseClassNames.close).addClass(options.closeClassName).css(options.closeCSS).data({vex:options}).bind("click.vex",function(){return vex.close($(this).data().vex.id)}),options.$vexContent.append(options.$closeButton)),$(options.appendLocation).append(options.$vex),vex.setupBodyClassName(options.$vex),options.afterOpen&&options.afterOpen(options.$vexContent,options),setTimeout(function(){return options.$vexContent.trigger("vexOpen",options)},0),options.$vexContent},getAllVexes:function(){return $("."+vex.baseClassNames.vex+':not(".'+vex.baseClassNames.closing+'") .'+vex.baseClassNames.content)},getVexByID:function(id){return vex.getAllVexes().filter(function(){return $(this).data().vex.id===id})},close:function(id){var $lastVex;if(!id){if($lastVex=vex.getAllVexes().last(),!$lastVex.length)return!1;id=$lastVex.data().vex.id}return vex.closeByID(id)},closeAll:function(){var ids;return ids=vex.getAllVexes().map(function(){return $(this).data().vex.id}).toArray(),(null!=ids?ids.length:void 0)?($.each(ids.reverse(),function(index,id){return vex.closeByID(id)}),!0):!1},closeByID:function(id){var $vex,$vexContent,beforeClose,close,options;return $vexContent=vex.getVexByID(id),$vexContent.length?($vex=$vexContent.data().vex.$vex,options=$.extend({},$vexContent.data().vex),beforeClose=function(){return options.beforeClose?options.beforeClose($vexContent,options):void 0},close=function(){return $vexContent.trigger("vexClose",options),$vex.remove(),options.afterClose?options.afterClose($vexContent,options):void 0},animationEndSupport?(beforeClose(),$vex.unbind(vex.animationEndEvent).bind(vex.animationEndEvent,function(){return close()}).addClass(vex.baseClassNames.closing)):(beforeClose(),close()),!0):void 0},closeByEscape:function(){var $lastVex,id,ids;return ids=vex.getAllVexes().map(function(){return $(this).data().vex.id}).toArray(),(null!=ids?ids.length:void 0)?(id=Math.max.apply(Math,ids),$lastVex=vex.getVexByID(id),$lastVex.data().vex.escapeButtonCloses!==!0?!1:vex.closeByID(id)):!1},setupBodyClassName:function($vex){return $vex.bind("vexOpen.vex",function(){return $("body").addClass(vex.baseClassNames.open)}).bind("vexClose.vex",function(){return vex.getAllVexes().length?void 0:$("body").removeClass(vex.baseClassNames.open)})},hideLoading:function(){return $(".vex-loading-spinner").remove()},showLoading:function(){return vex.hideLoading(),$("body").append('<div class="vex-loading-spinner '+vex.defaultOptions.className+'"></div>')}}},"function"==typeof define&&define.amd?define(["jquery"],vexFactory):"object"==typeof exports?module.exports=vexFactory(require("jquery")):window.vex=vexFactory(jQuery)}).call(this),function(){var vexDialogFactory;vexDialogFactory=function($,vex){var $formToObject,dialog;return null==vex?$.error("Vex is required to use vex.dialog"):($formToObject=function($form){var object;return object={},$.each($form.serializeArray(),function(){return object[this.name]?(object[this.name].push||(object[this.name]=[object[this.name]]),object[this.name].push(this.value||"")):object[this.name]=this.value||""}),object},dialog={},dialog.buttons={YES:{text:"OK",type:"submit",className:"vex-dialog-button-primary"},NO:{text:"Cancel",type:"button",className:"vex-dialog-button-secondary",click:function($vexContent){return $vexContent.data().vex.value=!1,vex.close($vexContent.data().vex.id)}}},dialog.defaultOptions={callback:function(){},afterOpen:function(){},message:"Message",input:'<input name="vex" type="hidden" value="_vex-empty-value" />',value:!1,buttons:[dialog.buttons.YES,dialog.buttons.NO],showCloseButton:!1,onSubmit:function(event){var $form,$vexContent;return $form=$(this),$vexContent=$form.parent(),event.preventDefault(),event.stopPropagation(),$vexContent.data().vex.value=dialog.getFormValueOnSubmit($formToObject($form)),vex.close($vexContent.data().vex.id)},focusFirstInput:!0},dialog.defaultAlertOptions={message:"Alert",buttons:[dialog.buttons.YES]},dialog.defaultConfirmOptions={message:"Confirm"},dialog.open=function(options){var $vexContent;return options=$.extend({},vex.defaultOptions,dialog.defaultOptions,options),options.content=dialog.buildDialogForm(options),options.beforeClose=function($vexContent){return options.callback($vexContent.data().vex.value)},$vexContent=vex.open(options),options.focusFirstInput&&$vexContent.find('input[type="submit"], textarea, input[type="date"], input[type="datetime"], input[type="datetime-local"], input[type="email"], input[type="month"], input[type="number"], input[type="password"], input[type="search"], input[type="tel"], input[type="text"], input[type="time"], input[type="url"], input[type="week"]').first().focus(),$vexContent},dialog.alert=function(options){return"string"==typeof options&&(options={message:options}),options=$.extend({},dialog.defaultAlertOptions,options),dialog.open(options)},dialog.confirm=function(options){return"string"==typeof options?$.error("dialog.confirm(options) requires options.callback."):(options=$.extend({},dialog.defaultConfirmOptions,options),dialog.open(options))},dialog.prompt=function(options){var defaultPromptOptions;return"string"==typeof options?$.error("dialog.prompt(options) requires options.callback."):(defaultPromptOptions={message:'<label for="vex">'+(options.label||"Prompt:")+"</label>",input:'<input name="vex" type="text" class="vex-dialog-prompt-input" placeholder="'+(options.placeholder||"")+'" value="'+(options.value||"")+'" />'},options=$.extend({},defaultPromptOptions,options),dialog.open(options))},dialog.buildDialogForm=function(options){var $form,$input,$message;return $form=$('<form class="vex-dialog-form" />'),$message=$('<div class="vex-dialog-message" />'),$input=$('<div class="vex-dialog-input" />'),$form.append($message.append(options.message)).append($input.append(options.input)).append(dialog.buttonsToDOM(options.buttons)).bind("submit.vex",options.onSubmit),$form},dialog.getFormValueOnSubmit=function(formData){return formData.vex||""===formData.vex?"_vex-empty-value"===formData.vex?!0:formData.vex:formData},dialog.buttonsToDOM=function(buttons){var $buttons;return $buttons=$('<div class="vex-dialog-buttons" />'),$.each(buttons,function(index,button){return $buttons.append($('<input type="'+button.type+'" />').val(button.text).addClass(button.className+" vex-dialog-button "+(0===index?"vex-first ":"")+(index===buttons.length-1?"vex-last ":"")).bind("click.vex",function(e){return button.click?button.click($(this).parents("."+vex.baseClassNames.content),e):void 0}))}),$buttons},dialog)},"function"==typeof define&&define.amd?define(["jquery","vex"],vexDialogFactory):"object"==typeof exports?module.exports=vexDialogFactory(require("jquery"),require("vex")):window.vex.dialog=vexDialogFactory(window.jQuery,window.vex)}.call(this);var ignore_date=new Date;ignore_date.setTime(ignore_date.getTime()+12096e5),jQuery(document).ready(function($){var li_subscribe_flag=$.cookie("li_subscribe"),preview_subscribe=leadin_get_parameter_by_name("preview-subscribe");leadin_subscribe_check_mobile($)||preview_subscribe?preview_subscribe&&(bind_leadin_subscribe_widget(leadin_get_parameter_by_name("lis_heading"),leadin_get_parameter_by_name("lis_desc"),leadin_get_parameter_by_name("lis_show_names"),leadin_get_parameter_by_name("lis_show_phone"),leadin_get_parameter_by_name("lis_btn_label"),leadin_get_parameter_by_name("lis_vex_class"),leadin_get_parameter_by_name("lis_confirmation")),subscribe.open()):li_subscribe_flag?"show"==li_subscribe_flag&&bind_leadin_subscribe_widget($("#leadin-subscribe-heading").val(),$("#leadin-subscribe-text").val(),$("#leadin-subscribe-name-fields").val(),$("#leadin-subscribe-phone-field").val(),$("#leadin-subscribe-btn-label").val(),$("#leadin-subscribe-vex-class").val(),$("#leadin-subscribe-confirmation").val()):leadin_check_visitor_status($.cookie("li_hash"),function(data){"vex_set"!=data?($.cookie("li_subscribe","show",{path:"/",domain:""}),bind_leadin_subscribe_widget($("#leadin-subscribe-heading").val(),$("#leadin-subscribe-text").val(),$("#leadin-subscribe-name-fields").val(),$("#leadin-subscribe-phone-field").val(),$("#leadin-subscribe-btn-label").val(),$("#leadin-subscribe-vex-class").val(),$("#leadin-subscribe-confirmation").val())):$.cookie("li_subscribe","ignore",{path:"/",domain:"",expires:ignore_date})})});
|
1 |
+
function bind_leadin_subscribe_widget(lis_heading,lis_desc,lis_show_names,lis_show_phone,lis_btn_label,lis_vex_class,lis_confirmation){lis_heading=lis_heading?lis_heading:"Sign up for email updates",lis_desc=lis_desc?lis_desc:"",lis_btn_label=lis_btn_label?lis_btn_label:"SUBSCRIBE",lis_vex_class=lis_vex_class?lis_vex_class:"vex-theme-bottom-right-corner",lis_confirmation=lis_confirmation?lis_confirmation:1,function(){var $=jQuery,subscribe={};subscribe.vex=void 0,subscribe.init=function(){$(window).scrollTop()+$(window).height()>$(document).height()/2&&subscribe.open(),$(window).scroll(function(){$(window).scrollTop()+$(window).height()>$(document).height()/2&&subscribe.open()})},subscribe.open=function(){return subscribe.vex?subscribe._open():(subscribe.vex=vex.dialog.open({showCloseButton:!0,className:"leadin-subscribe "+lis_vex_class,message:"<h4>"+lis_heading+"</h4><p>"+lis_desc+"</p>",input:'<input id="leadin-subscribe-email" name="email" type="email" placeholder="Email address" />'+(parseInt(lis_show_names)?'<input id="leadin-subscribe-fname" name="fname" type="text" placeholder="First Name" /><input id="leadin-subscribe-lname" name="lname" type="text" placeholder="Last Name" />':"")+(parseInt(lis_show_phone)?'<input id="leadin-subscribe-phone" name="phone" type="tel" placeholder="Phone" />':""),buttons:[$.extend({},vex.dialog.buttons.YES,{text:lis_btn_label?lis_btn_label:"SUBSCRIBE"})],onSubmit:function(){$subscribe_form=$(this),$subscribe_form.find("input.error").removeClass("error");var form_validated=!0;return $subscribe_form.find("input").each(function(){var $input=$(this);$input.val()||($input.addClass("error"),form_validated=!1)}),form_validated?($(".vex-dialog-form").fadeOut(300,function(){$(".vex-dialog-form").html('<div class="vex-close"></div>'+(parseInt(lis_confirmation)?"<h3>Thanks!<br>You should receive a confirmation email in your inbox shortly.</h3>":"<h3>Thanks!<br>We received your submission.</h3>")+'<div id="powered-by-leadin-thank-you"><span class="powered-by">Powered by Leadin</span><a href="http://leadin.com/wordpress-subscribe-widget-plugin?utm_source=virality&utm_medium=referral&utm_term='+window.location.host+'&utm_content=e11&utm_campaign=subscribe%20widget"><img alt="Leadin" height="20px" width="99px" src="'+document.location.protocol+'//leadin.com/wp-content/themes/LeadIn-WP-Theme/library/images/logos/Leadin_logo@2x.png" alt="leadin.com"/></a></div>').css("text-align","center").fadeIn(250)}),leadin_submit_form($(".leadin-subscribe form"),$),$.cookie("li_subscribe","ignore",{path:"/",domain:"",expires:ignore_date}),!1):!1},callback:function(data){data===!1&&$.cookie("li_subscribe","ignore",{path:"/",domain:"",expires:ignore_date}),$.cookie("li_subscribe","ignore",{path:"/",domain:"",expires:ignore_date})}}),void $(".leadin-subscribe form.vex-dialog-form").append('<a href="http://leadin.com/wordpress-subscribe-widget-plugin?utm_source=virality&utm_medium=referral&utm_term='+window.location.host+'&utm_content=e11&utm_campaign=subscribe%20widget" id="leadin-subscribe-powered-by" class="leadin-subscribe-powered-by">Powered by Leadin</a>'))},subscribe._open=function(){subscribe.vex.parent().removeClass("vex-closing")},subscribe.close=function(){subscribe.vex&&subscribe.vex.parent().addClass("vex-closing")},subscribe.init(),window.subscribe=subscribe}()}function leadin_subscribe_check_mobile($){var is_mobile=!1;return"none"==$("#leadin-subscribe-mobile-check").css("display")&&(is_mobile=!0),is_mobile}function leadin_subscribe_show(){jQuery.ajax({type:"POST",url:li_ajax.ajax_url,data:{action:"leadin_subscribe_show"},success:function(){},error:function(){}})}function leadin_get_parameter_by_name(name){name=name.replace(/[\[]/,"\\[").replace(/[\]]/,"\\]");var regex=new RegExp("[\\?&]"+name+"=([^&#]*)"),results=regex.exec(location.search);return null==results?"":decodeURIComponent(results[1].replace(/\+/g," "))}(function(){var vexFactory;vexFactory=function($){var animationEndSupport,vex;return animationEndSupport=!1,$(function(){var s;return s=(document.body||document.documentElement).style,animationEndSupport=void 0!==s.animation||void 0!==s.WebkitAnimation||void 0!==s.MozAnimation||void 0!==s.MsAnimation||void 0!==s.OAnimation,$(window).bind("keyup.vex",function(event){return 27===event.keyCode?vex.closeByEscape():void 0})}),vex={globalID:1,animationEndEvent:"animationend webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend",baseClassNames:{vex:"vex",content:"vex-content",overlay:"vex-overlay",close:"vex-close",closing:"vex-closing",open:"vex-open"},defaultOptions:{content:"",showCloseButton:!0,escapeButtonCloses:!0,overlayClosesOnClick:!0,appendLocation:"body",className:"",css:{},overlayClassName:"",overlayCSS:{},contentClassName:"",contentCSS:{},closeClassName:"",closeCSS:{}},open:function(options){return options=$.extend({},vex.defaultOptions,options),options.id=vex.globalID,vex.globalID+=1,options.$vex=$("<div>").addClass(vex.baseClassNames.vex).addClass(options.className).css(options.css).data({vex:options}),options.$vexOverlay=$("<div>").addClass(vex.baseClassNames.overlay).addClass(options.overlayClassName).css(options.overlayCSS).data({vex:options}),options.overlayClosesOnClick&&options.$vexOverlay.bind("click.vex",function(e){return e.target===this?vex.close($(this).data().vex.id):void 0}),options.$vex.append(options.$vexOverlay),options.$vexContent=$("<div>").addClass(vex.baseClassNames.content).addClass(options.contentClassName).css(options.contentCSS).append(options.content).data({vex:options}),options.$vex.append(options.$vexContent),options.showCloseButton&&(options.$closeButton=$("<div>").addClass(vex.baseClassNames.close).addClass(options.closeClassName).css(options.closeCSS).data({vex:options}).bind("click.vex",function(){return vex.close($(this).data().vex.id)}),options.$vexContent.append(options.$closeButton)),$(options.appendLocation).append(options.$vex),vex.setupBodyClassName(options.$vex),options.afterOpen&&options.afterOpen(options.$vexContent,options),setTimeout(function(){return options.$vexContent.trigger("vexOpen",options)},0),options.$vexContent},getAllVexes:function(){return $("."+vex.baseClassNames.vex+':not(".'+vex.baseClassNames.closing+'") .'+vex.baseClassNames.content)},getVexByID:function(id){return vex.getAllVexes().filter(function(){return $(this).data().vex.id===id})},close:function(id){var $lastVex;if(!id){if($lastVex=vex.getAllVexes().last(),!$lastVex.length)return!1;id=$lastVex.data().vex.id}return vex.closeByID(id)},closeAll:function(){var ids;return ids=vex.getAllVexes().map(function(){return $(this).data().vex.id}).toArray(),(null!=ids?ids.length:void 0)?($.each(ids.reverse(),function(index,id){return vex.closeByID(id)}),!0):!1},closeByID:function(id){var $vex,$vexContent,beforeClose,close,options;return $vexContent=vex.getVexByID(id),$vexContent.length?($vex=$vexContent.data().vex.$vex,options=$.extend({},$vexContent.data().vex),beforeClose=function(){return options.beforeClose?options.beforeClose($vexContent,options):void 0},close=function(){return $vexContent.trigger("vexClose",options),$vex.remove(),options.afterClose?options.afterClose($vexContent,options):void 0},animationEndSupport?(beforeClose(),$vex.unbind(vex.animationEndEvent).bind(vex.animationEndEvent,function(){return close()}).addClass(vex.baseClassNames.closing)):(beforeClose(),close()),!0):void 0},closeByEscape:function(){var $lastVex,id,ids;return ids=vex.getAllVexes().map(function(){return $(this).data().vex.id}).toArray(),(null!=ids?ids.length:void 0)?(id=Math.max.apply(Math,ids),$lastVex=vex.getVexByID(id),$lastVex.data().vex.escapeButtonCloses!==!0?!1:vex.closeByID(id)):!1},setupBodyClassName:function($vex){return $vex.bind("vexOpen.vex",function(){return $("body").addClass(vex.baseClassNames.open)}).bind("vexClose.vex",function(){return vex.getAllVexes().length?void 0:$("body").removeClass(vex.baseClassNames.open)})},hideLoading:function(){return $(".vex-loading-spinner").remove()},showLoading:function(){return vex.hideLoading(),$("body").append('<div class="vex-loading-spinner '+vex.defaultOptions.className+'"></div>')}}},"function"==typeof define&&define.amd?define(["jquery"],vexFactory):"object"==typeof exports?module.exports=vexFactory(require("jquery")):window.vex=vexFactory(jQuery)}).call(this),function(){var vexDialogFactory;vexDialogFactory=function($,vex){var $formToObject,dialog;return null==vex?$.error("Vex is required to use vex.dialog"):($formToObject=function($form){var object;return object={},$.each($form.serializeArray(),function(){return object[this.name]?(object[this.name].push||(object[this.name]=[object[this.name]]),object[this.name].push(this.value||"")):object[this.name]=this.value||""}),object},dialog={},dialog.buttons={YES:{text:"OK",type:"submit",className:"vex-dialog-button-primary"},NO:{text:"Cancel",type:"button",className:"vex-dialog-button-secondary",click:function($vexContent){return $vexContent.data().vex.value=!1,vex.close($vexContent.data().vex.id)}}},dialog.defaultOptions={callback:function(){},afterOpen:function(){},message:"Message",input:'<input name="vex" type="hidden" value="_vex-empty-value" />',value:!1,buttons:[dialog.buttons.YES,dialog.buttons.NO],showCloseButton:!1,onSubmit:function(event){var $form,$vexContent;return $form=$(this),$vexContent=$form.parent(),event.preventDefault(),event.stopPropagation(),$vexContent.data().vex.value=dialog.getFormValueOnSubmit($formToObject($form)),vex.close($vexContent.data().vex.id)},focusFirstInput:!0},dialog.defaultAlertOptions={message:"Alert",buttons:[dialog.buttons.YES]},dialog.defaultConfirmOptions={message:"Confirm"},dialog.open=function(options){var $vexContent;return options=$.extend({},vex.defaultOptions,dialog.defaultOptions,options),options.content=dialog.buildDialogForm(options),options.beforeClose=function($vexContent){return options.callback($vexContent.data().vex.value)},$vexContent=vex.open(options),options.focusFirstInput&&$vexContent.find('input[type="submit"], textarea, input[type="date"], input[type="datetime"], input[type="datetime-local"], input[type="email"], input[type="month"], input[type="number"], input[type="password"], input[type="search"], input[type="tel"], input[type="text"], input[type="time"], input[type="url"], input[type="week"]').first().focus(),$vexContent},dialog.alert=function(options){return"string"==typeof options&&(options={message:options}),options=$.extend({},dialog.defaultAlertOptions,options),dialog.open(options)},dialog.confirm=function(options){return"string"==typeof options?$.error("dialog.confirm(options) requires options.callback."):(options=$.extend({},dialog.defaultConfirmOptions,options),dialog.open(options))},dialog.prompt=function(options){var defaultPromptOptions;return"string"==typeof options?$.error("dialog.prompt(options) requires options.callback."):(defaultPromptOptions={message:'<label for="vex">'+(options.label||"Prompt:")+"</label>",input:'<input name="vex" type="text" class="vex-dialog-prompt-input" placeholder="'+(options.placeholder||"")+'" value="'+(options.value||"")+'" />'},options=$.extend({},defaultPromptOptions,options),dialog.open(options))},dialog.buildDialogForm=function(options){var $form,$input,$message;return $form=$('<form class="vex-dialog-form" />'),$message=$('<div class="vex-dialog-message" />'),$input=$('<div class="vex-dialog-input" />'),$form.append($message.append(options.message)).append($input.append(options.input)).append(dialog.buttonsToDOM(options.buttons)).bind("submit.vex",options.onSubmit),$form},dialog.getFormValueOnSubmit=function(formData){return formData.vex||""===formData.vex?"_vex-empty-value"===formData.vex?!0:formData.vex:formData},dialog.buttonsToDOM=function(buttons){var $buttons;return $buttons=$('<div class="vex-dialog-buttons" />'),$.each(buttons,function(index,button){return $buttons.append($('<input type="'+button.type+'" />').val(button.text).addClass(button.className+" vex-dialog-button "+(0===index?"vex-first ":"")+(index===buttons.length-1?"vex-last ":"")).bind("click.vex",function(e){return button.click?button.click($(this).parents("."+vex.baseClassNames.content),e):void 0}))}),$buttons},dialog)},"function"==typeof define&&define.amd?define(["jquery","vex"],vexDialogFactory):"object"==typeof exports?module.exports=vexDialogFactory(require("jquery"),require("vex")):window.vex.dialog=vexDialogFactory(window.jQuery,window.vex)}.call(this);var ignore_date=new Date;ignore_date.setTime(ignore_date.getTime()+12096e5),jQuery(document).ready(function($){var li_subscribe_flag=$.cookie("li_subscribe"),preview_subscribe=leadin_get_parameter_by_name("preview-subscribe");leadin_subscribe_check_mobile($)||preview_subscribe?preview_subscribe&&(bind_leadin_subscribe_widget(leadin_get_parameter_by_name("lis_heading"),leadin_get_parameter_by_name("lis_desc"),leadin_get_parameter_by_name("lis_show_names"),leadin_get_parameter_by_name("lis_show_phone"),leadin_get_parameter_by_name("lis_btn_label"),leadin_get_parameter_by_name("lis_vex_class"),leadin_get_parameter_by_name("lis_confirmation")),subscribe.open()):li_subscribe_flag?"show"==li_subscribe_flag&&bind_leadin_subscribe_widget($("#leadin-subscribe-heading").val(),$("#leadin-subscribe-text").val(),$("#leadin-subscribe-name-fields").val(),$("#leadin-subscribe-phone-field").val(),$("#leadin-subscribe-btn-label").val(),$("#leadin-subscribe-vex-class").val(),$("#leadin-subscribe-confirmation").val()):leadin_check_visitor_status($.cookie("li_hash"),function(data){"vex_set"!=data?($.cookie("li_subscribe","show",{path:"/",domain:""}),bind_leadin_subscribe_widget($("#leadin-subscribe-heading").val(),$("#leadin-subscribe-text").val(),$("#leadin-subscribe-name-fields").val(),$("#leadin-subscribe-phone-field").val(),$("#leadin-subscribe-btn-label").val(),$("#leadin-subscribe-vex-class").val(),$("#leadin-subscribe-confirmation").val())):$.cookie("li_subscribe","ignore",{path:"/",domain:"",expires:ignore_date})})});
|
images/power-up-icon-aweber-connect.png
ADDED
Binary file
|
images/power-up-icon-aweber-connect@2x.png
ADDED
Binary file
|
images/power-up-icon-aweber-connect_small.png
ADDED
Binary file
|
images/power-up-icon-aweber-connect_small@2x.png
ADDED
Binary file
|
images/power-up-icon-campaign-monitor-connect.png
ADDED
Binary file
|
images/power-up-icon-campaign-monitor-connect@2x.png
ADDED
Binary file
|
images/power-up-icon-campaign-monitor-connect_small.png
ADDED
Binary file
|
images/power-up-icon-campaign-monitor-connect_small@2x.png
ADDED
Binary file
|
images/power-up-icon-getresponse-connect.png
ADDED
Binary file
|
images/power-up-icon-getresponse-connect@2x.png
ADDED
Binary file
|
images/power-up-icon-getresponse-connect_small.png
ADDED
Binary file
|
images/power-up-icon-getresponse-connect_small@2x.png
ADDED
Binary file
|
images/power-up-icon-getresponse-list-sync_small.png
ADDED
Binary file
|
images/power-up-icon-getresponse-list-sync_small@2x.png
ADDED
Binary file
|
images/powerup-icon-lookups.png
ADDED
Binary file
|
images/powerup-icon-lookups@2x.png
ADDED
Binary file
|
inc/class-emailer.php
CHANGED
@@ -32,13 +32,6 @@ class LI_Emailer {
|
|
32 |
// Each line in an email can only be 998 characters long, so lines need to be broken with a wordwrap
|
33 |
$body = wordwrap($body, 900, "\r\n");
|
34 |
|
35 |
-
$from = $history->lead->lead_email;
|
36 |
-
$headers = "From: " . $from . " <" . $from . ">\r\n";
|
37 |
-
$headers.= "Reply-To: " . $from . " <" . $from . ">\r\n";
|
38 |
-
$headers.= "X-Mailer: PHP/" . phpversion() . "\r\n";
|
39 |
-
$headers.= "MIME-Version: 1.0\r\n";
|
40 |
-
$headers.= "Content-type: text/html; charset=utf-8\r\n";
|
41 |
-
|
42 |
// Get email from plugin settings, if none set, use admin email
|
43 |
$options = get_option('leadin_options');
|
44 |
$to = ( $options['li_email'] ? $options['li_email'] : get_bloginfo('admin_email') ); // Get email from plugin settings, if none set, use admin email
|
@@ -55,8 +48,38 @@ class LI_Emailer {
|
|
55 |
$return_status = 'by a returning contact ';
|
56 |
|
57 |
$subject = "Form submission " . $tag_status . $return_status . "on " . get_bloginfo('name') . " - " . $history->lead->lead_email;
|
58 |
-
$email_sent = wp_mail($to, $subject, $body, $headers);
|
59 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
60 |
|
61 |
return $email_sent;
|
62 |
}
|
@@ -70,7 +93,8 @@ class LI_Emailer {
|
|
70 |
function build_body ( $li_contact )
|
71 |
{
|
72 |
$format = '<html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html;charset=utf-8"/><meta name="viewport" content="width=device-width"/></head><body style="width: 100%%;min-width: 100%%;-webkit-text-size-adjust: 100%%;-ms-text-size-adjust: 100%%;margin: 0;padding: 0;color: #222222;font-family: Helvetica, Arial, sans-serif;font-weight: normal;text-align: left;line-height: 19px;font-size: 14px;background-color: #f1f1f1;"><table class="body" style="border-spacing: 0;border-collapse: collapse;padding: 0;vertical-align: top;text-align: left;height: 100%%;width: 100%%;color: #222222;font-family: Helvetica, Arial, sans-serif;font-weight: normal;margin: 0;line-height: 19px;font-size: 14px;background-color: #f1f1f1;"><tr style="padding: 0;vertical-align: top;text-align: left;"><td class="center" align="center" valign="top" style="word-break: break-word;-webkit-hyphens: auto;-moz-hyphens: auto;hyphens: auto;border-collapse: collapse;padding: 0;vertical-align: top;text-align: center;color: #222222;font-family: Helvetica, Arial, sans-serif;font-weight: normal;margin: 0;line-height: 19px;font-size: 14px;"><center style="width: 100%%;min-width: 580px;"><table class="container" style="border-spacing: 0;border-collapse: collapse;padding: 0;vertical-align: top;text-align: inherit;width: 580px;margin: 0 auto;"><tr style="padding: 0;vertical-align: top;text-align: left;"><td style="word-break: break-word;-webkit-hyphens: auto;-moz-hyphens: auto;hyphens: auto;border-collapse: collapse;padding: 0;vertical-align: top;text-align: left;color: #222222;font-family: Helvetica, Arial, sans-serif;font-weight: normal;margin: 0;line-height: 19px;font-size: 14px;">%s%s%s%s%s</td></tr></table></center></td></tr></table></body></html>';
|
73 |
-
|
|
|
74 |
|
75 |
return $built_body;
|
76 |
}
|
@@ -84,6 +108,7 @@ class LI_Emailer {
|
|
84 |
function build_submission_details ( $url ) {
|
85 |
$format = '<table class="row submission-detail" style="border-spacing: 0;border-collapse: collapse;padding: 0px;vertical-align: top;text-align: left;width: 100%%;position: relative;display: block;"><tr style="padding: 0;vertical-align: top;text-align: left;"><td class="wrapper last" style="word-break: break-word;-webkit-hyphens: auto;-moz-hyphens: auto;hyphens: auto;border-collapse: collapse;padding: 10px 20px 0px 0px;vertical-align: top;text-align: left;position: relative;padding-right: 0px;color: #222222;font-family: Helvetica, Arial, sans-serif;font-weight: normal;margin: 0;line-height: 19px;font-size: 14px;"><table class="twelve columns" style="border-spacing: 0;border-collapse: collapse;padding: 0;vertical-align: top;text-align: left;margin: 0 auto;width: 580px;"><tr style="padding: 0;vertical-align: top;text-align: left;"><td class="text-pad" style="word-break: break-word;-webkit-hyphens: auto;-moz-hyphens: auto;hyphens: auto;border-collapse: collapse;padding: 0px 0px 10px;vertical-align: top;text-align: left;padding-left: 10px;padding-right: 10px;color: #222222;font-family: Helvetica, Arial, sans-serif;font-weight: normal;margin: 0;line-height: 19px;font-size: 14px;"><h3 style="color: #666;font-family: Helvetica, Arial, sans-serif;font-weight: normal;padding: 0;margin: 0;text-align: left;line-height: 1.3;word-break: normal;font-size: 18px;">New submission on <a href="%s" style="color: #2ba6cb;text-decoration: none;">%s</a></h3></td><td class="expander" style="word-break: break-word;-webkit-hyphens: auto;-moz-hyphens: auto;hyphens: auto;border-collapse: collapse;padding: 0;vertical-align: top;text-align: left;visibility: hidden;width: 0px;color: #222222;font-family: Helvetica, Arial, sans-serif;font-weight: normal;margin: 0;line-height: 19px;font-size: 14px;"></td></tr></table></td></tr></table>' . "\r\n";
|
86 |
$built_submission_details = sprintf($format, $url, get_bloginfo('name'));
|
|
|
87 |
|
88 |
return $built_submission_details;
|
89 |
}
|
@@ -223,19 +248,193 @@ class LI_Emailer {
|
|
223 |
return $built_source_url_params;
|
224 |
}
|
225 |
|
226 |
-
|
227 |
/**
|
228 |
* Creates the data lookup content for the contact notificaiton email
|
229 |
*
|
230 |
* @param stdClass history from LI_Contact
|
231 |
* @return string footer content
|
232 |
*/
|
233 |
-
function build_enrichment_data ( )
|
234 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
235 |
|
236 |
return $built_enrichment_data;
|
237 |
}
|
238 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
239 |
/**
|
240 |
* Creates the footer content for the contact notificaiton email
|
241 |
*
|
@@ -323,14 +522,7 @@ class LI_Emailer {
|
|
323 |
$body .="You may also contact us at:<br/><a href='mailto:" . $leadin_email . "'>" . $leadin_email . "</a>";
|
324 |
$body .= "</td></tr></table></td><td class='expander' style='word-break: break-word;-webkit-hyphens: auto;-moz-hyphens: auto;hyphens: auto;border-collapse: collapse !important;vertical-align: top;text-align: left;visibility: hidden;width: 0px;padding: 0;border: 0;' align='left' valign='top'></td></tr></table></td></tr></table>";
|
325 |
|
326 |
-
|
327 |
-
if ( isset($options['premium']) )
|
328 |
-
{
|
329 |
-
if ( ! $options['premium'] )
|
330 |
-
$body .= $this->build_powered_by_link();
|
331 |
-
}
|
332 |
-
else
|
333 |
-
$body .= $this->build_powered_by_link();
|
334 |
|
335 |
// @EMAIL - end form section
|
336 |
|
@@ -341,7 +533,7 @@ class LI_Emailer {
|
|
341 |
// Each line in an email can only be 998 characters long, so lines need to be broken with a wordwrap
|
342 |
$body = wordwrap($body, 900, "\r\n");
|
343 |
|
344 |
-
$headers = "From: Leadin <
|
345 |
$headers.= "Reply-To: Leadin <" . $from . ">\r\n";
|
346 |
$headers.= "X-Mailer: PHP/" . phpversion() . "\r\n";
|
347 |
$headers.= "MIME-Version: 1.0\r\n";
|
@@ -363,9 +555,64 @@ class LI_Emailer {
|
|
363 |
$powered_by = '';
|
364 |
|
365 |
$powered_by .= "<table class='row section' style='border-spacing: 0;border-collapse: collapse;vertical-align: top;text-align: left;width: 100%;position: relative;display: block;margin-top: 20px;padding: 0px;'><tr style='vertical-align: top;text-align: left;padding: 0;' align='left'><td class='wrapper last' style='word-break: break-word;-webkit-hyphens: auto;-moz-hyphens: auto;hyphens: auto;border-collapse: collapse !important;vertical-align: top;text-align: left;position: relative;padding: 0 0px 0 0;' align='left' valign='top'><table class='twelve columns' style='border-spacing: 0;border-collapse: collapse;vertical-align: top;text-align: left;width: 580px;margin: 0 auto;padding: 0;'><tr style='vertical-align: top;text-align: left;padding: 0;' align='left'><td style='padding: 10px 20px;' align='left' valign='top'><table style='border-spacing: 0;border-collapse: collapse;vertical-align: top;text-align: left;width: 100%;overflow: hidden;padding: 0;'><tr style='vertical-align: top;text-align: left;padding: 0;' align='left'><td style='word-break: break-word;-webkit-hyphens: auto;-moz-hyphens: auto;hyphens: auto;border-collapse: collapse !important;vertical-align: top;text-align: center;display: block;width: auto !important;font-size: 16px;padding: 10px 20px;' align='center' valign='top'>";
|
366 |
-
$powered_by .="<div style='font-size: 11px; color: #888; padding: 0 0 5px 0;'>Powered by</div><a href='http://leadin.com/wordpress-subscribe-widget-plugin
|
367 |
$powered_by .= "</td></tr></table></td><td class='expander' style='word-break: break-word;-webkit-hyphens: auto;-moz-hyphens: auto;hyphens: auto;border-collapse: collapse !important;vertical-align: top;text-align: left;visibility: hidden;width: 0px;padding: 0;border: 0;' align='left' valign='top'></td></tr></table></td></tr></table>";
|
368 |
|
369 |
return $powered_by;
|
370 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
371 |
}
|
32 |
// Each line in an email can only be 998 characters long, so lines need to be broken with a wordwrap
|
33 |
$body = wordwrap($body, 900, "\r\n");
|
34 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
35 |
// Get email from plugin settings, if none set, use admin email
|
36 |
$options = get_option('leadin_options');
|
37 |
$to = ( $options['li_email'] ? $options['li_email'] : get_bloginfo('admin_email') ); // Get email from plugin settings, if none set, use admin email
|
48 |
$return_status = 'by a returning contact ';
|
49 |
|
50 |
$subject = "Form submission " . $tag_status . $return_status . "on " . get_bloginfo('name') . " - " . $history->lead->lead_email;
|
|
|
51 |
|
52 |
+
$headers = "From: Leadin <notifications@leadin.com>\r\n";
|
53 |
+
$headers .= "Reply-To: Leadin <notifications@leadin.com>\r\n";
|
54 |
+
$headers .= "X-Mailer: PHP/" . phpversion() . "\r\n";
|
55 |
+
$headers .= "MIME-Version: 1.0\r\n";
|
56 |
+
$headers .= "Content-type: text/html; charset=utf-8\r\n";
|
57 |
+
|
58 |
+
if ( isset($options['pro']) && $options['pro'] )
|
59 |
+
{
|
60 |
+
$email_sent = $this->send_email_via_sendgrid($to, $subject, $body, get_bloginfo('wpurl'));
|
61 |
+
|
62 |
+
if ( $email_sent )
|
63 |
+
{
|
64 |
+
leadin_track_plugin_activity('Contact Notification Sent', array('service' => 'sendgrid'));
|
65 |
+
}
|
66 |
+
else
|
67 |
+
{
|
68 |
+
$email_sent = wp_mail($to, $subject, $body, $headers);
|
69 |
+
leadin_track_plugin_activity('Contact Notification Sent', array('service' => 'php_mail'));
|
70 |
+
}
|
71 |
+
}
|
72 |
+
else
|
73 |
+
{
|
74 |
+
$headers = "From: Leadin <notifications@leadin.com>\r\n";
|
75 |
+
$headers .= "Reply-To: Leadin <notifications@leadin.com>\r\n";
|
76 |
+
$headers .= "X-Mailer: PHP/" . phpversion() . "\r\n";
|
77 |
+
$headers .= "MIME-Version: 1.0\r\n";
|
78 |
+
$headers .= "Content-type: text/html; charset=utf-8\r\n";
|
79 |
+
|
80 |
+
$email_sent = wp_mail($to, $subject, $body, $headers);
|
81 |
+
leadin_track_plugin_activity('Contact Notification Sent', array('service' => 'php_mail'));
|
82 |
+
}
|
83 |
|
84 |
return $email_sent;
|
85 |
}
|
93 |
function build_body ( $li_contact )
|
94 |
{
|
95 |
$format = '<html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html;charset=utf-8"/><meta name="viewport" content="width=device-width"/></head><body style="width: 100%%;min-width: 100%%;-webkit-text-size-adjust: 100%%;-ms-text-size-adjust: 100%%;margin: 0;padding: 0;color: #222222;font-family: Helvetica, Arial, sans-serif;font-weight: normal;text-align: left;line-height: 19px;font-size: 14px;background-color: #f1f1f1;"><table class="body" style="border-spacing: 0;border-collapse: collapse;padding: 0;vertical-align: top;text-align: left;height: 100%%;width: 100%%;color: #222222;font-family: Helvetica, Arial, sans-serif;font-weight: normal;margin: 0;line-height: 19px;font-size: 14px;background-color: #f1f1f1;"><tr style="padding: 0;vertical-align: top;text-align: left;"><td class="center" align="center" valign="top" style="word-break: break-word;-webkit-hyphens: auto;-moz-hyphens: auto;hyphens: auto;border-collapse: collapse;padding: 0;vertical-align: top;text-align: center;color: #222222;font-family: Helvetica, Arial, sans-serif;font-weight: normal;margin: 0;line-height: 19px;font-size: 14px;"><center style="width: 100%%;min-width: 580px;"><table class="container" style="border-spacing: 0;border-collapse: collapse;padding: 0;vertical-align: top;text-align: inherit;width: 580px;margin: 0 auto;"><tr style="padding: 0;vertical-align: top;text-align: left;"><td style="word-break: break-word;-webkit-hyphens: auto;-moz-hyphens: auto;hyphens: auto;border-collapse: collapse;padding: 0;vertical-align: top;text-align: left;color: #222222;font-family: Helvetica, Arial, sans-serif;font-weight: normal;margin: 0;line-height: 19px;font-size: 14px;">%s%s%s%s%s</td></tr></table></center></td></tr></table></body></html>';
|
96 |
+
|
97 |
+
$built_body = sprintf($format, $this->build_submission_details(get_bloginfo('url')), $this->build_contact_identity($li_contact->history->lead->lead_email), $this->build_sessions($li_contact->history), $this->build_enrichment_data($li_contact), $this->build_footer($li_contact));
|
98 |
|
99 |
return $built_body;
|
100 |
}
|
108 |
function build_submission_details ( $url ) {
|
109 |
$format = '<table class="row submission-detail" style="border-spacing: 0;border-collapse: collapse;padding: 0px;vertical-align: top;text-align: left;width: 100%%;position: relative;display: block;"><tr style="padding: 0;vertical-align: top;text-align: left;"><td class="wrapper last" style="word-break: break-word;-webkit-hyphens: auto;-moz-hyphens: auto;hyphens: auto;border-collapse: collapse;padding: 10px 20px 0px 0px;vertical-align: top;text-align: left;position: relative;padding-right: 0px;color: #222222;font-family: Helvetica, Arial, sans-serif;font-weight: normal;margin: 0;line-height: 19px;font-size: 14px;"><table class="twelve columns" style="border-spacing: 0;border-collapse: collapse;padding: 0;vertical-align: top;text-align: left;margin: 0 auto;width: 580px;"><tr style="padding: 0;vertical-align: top;text-align: left;"><td class="text-pad" style="word-break: break-word;-webkit-hyphens: auto;-moz-hyphens: auto;hyphens: auto;border-collapse: collapse;padding: 0px 0px 10px;vertical-align: top;text-align: left;padding-left: 10px;padding-right: 10px;color: #222222;font-family: Helvetica, Arial, sans-serif;font-weight: normal;margin: 0;line-height: 19px;font-size: 14px;"><h3 style="color: #666;font-family: Helvetica, Arial, sans-serif;font-weight: normal;padding: 0;margin: 0;text-align: left;line-height: 1.3;word-break: normal;font-size: 18px;">New submission on <a href="%s" style="color: #2ba6cb;text-decoration: none;">%s</a></h3></td><td class="expander" style="word-break: break-word;-webkit-hyphens: auto;-moz-hyphens: auto;hyphens: auto;border-collapse: collapse;padding: 0;vertical-align: top;text-align: left;visibility: hidden;width: 0px;color: #222222;font-family: Helvetica, Arial, sans-serif;font-weight: normal;margin: 0;line-height: 19px;font-size: 14px;"></td></tr></table></td></tr></table>' . "\r\n";
|
110 |
$built_submission_details = sprintf($format, $url, get_bloginfo('name'));
|
111 |
+
$built_submission_details .= '<img src="' . $this->create_tracking_pixel() . '"/>';
|
112 |
|
113 |
return $built_submission_details;
|
114 |
}
|
248 |
return $built_source_url_params;
|
249 |
}
|
250 |
|
|
|
251 |
/**
|
252 |
* Creates the data lookup content for the contact notificaiton email
|
253 |
*
|
254 |
* @param stdClass history from LI_Contact
|
255 |
* @return string footer content
|
256 |
*/
|
257 |
+
function build_enrichment_data ( $li_contact )
|
258 |
+
{
|
259 |
+
$built_enrichment_data = "";
|
260 |
+
|
261 |
+
if ( leadin_check_pro_user() )
|
262 |
+
{
|
263 |
+
$format = '<table class="row contact-details" style="border-spacing: 0;border-collapse: collapse;padding: 0px;vertical-align: top;text-align: left;width: 100%%;position: relative;display: block;"><tr style="padding: 0;vertical-align: top;text-align: left;"><td class="wrapper last" style="word-break: break-word;-webkit-hyphens: auto;-moz-hyphens: auto;hyphens: auto;border-collapse: collapse;padding: 10px 20px 0px 0px;vertical-align: top;text-align: left;position: relative;padding-right: 0px;color: #222222;font-family: Helvetica, Arial, sans-serif;font-weight: normal;margin: 0;line-height: 19px;font-size: 14px;"><table class="twelve columns" style="border-spacing: 0;border-collapse: collapse;padding: 0;vertical-align: top;text-align: left;margin: 0 auto;width: 580px;"><tr style="padding: 0;vertical-align: top;text-align: left;"><td class="text-pad" style="word-break: break-word;-webkit-hyphens: auto;-moz-hyphens: auto;hyphens: auto;border-collapse: collapse;padding: 0px 0px 10px;vertical-align: top;text-align: left;padding-left: 10px;padding-right: 10px;color: #222222;font-family: Helvetica, Arial, sans-serif;font-weight: normal;margin: 0;line-height: 19px;font-size: 14px;"><h2 class="data-lookup-header" style="color: #222222;font-family: Helvetica, Arial, sans-serif;font-weight: normal;padding: 0;margin: 0;text-align: left;line-height: 1.3;word-break: normal;font-size: 20px;margin-bottom: 15px;">Data Lookup</h2><p class="data-lookup-limit" style="margin: 0;color: #222222;font-family: Helvetica, Arial, sans-serif;font-weight: normal;padding: 0;text-align: left;line-height: 19px;font-size: 14px;margin-bottom: 10px;">You have <span class="green" style="font-weight: bold;color: green;">unlimited free data lookups remaining</span> this month.</p></td><td class="expander" style="word-break: break-word;-webkit-hyphens: auto;-moz-hyphens: auto;hyphens: auto;border-collapse: collapse;padding: 0;vertical-align: top;text-align: left;visibility: hidden;width: 0px;color: #222222;font-family: Helvetica, Arial, sans-serif;font-weight: normal;margin: 0;line-height: 19px;font-size: 14px;"></td></tr></table></td></tr></table><table class="row contact-details" style="border-spacing: 0;border-collapse: collapse;padding: 0px;vertical-align: top;text-align: left;width: 100%%;position: relative;display: block;"><tr style="padding: 0;vertical-align: top;text-align: left;">%s%s</tr></table>';
|
264 |
+
$built_enrichment_personal = $this->build_enrichment_personal($li_contact);
|
265 |
+
$built_enrichment_data .= sprintf($format, ( $built_enrichment_personal ? $built_enrichment_personal : 'No dice' ), $this->build_enrichment_company($li_contact));
|
266 |
+
}
|
267 |
+
else
|
268 |
+
{
|
269 |
+
$built_enrichment_data = '<table class="row contact-details" style="border-spacing: 0;border-collapse: collapse;padding: 0px;vertical-align: top;text-align: left;width: 100%%;position: relative;display: block;"><tr style="padding: 0;vertical-align: top;text-align: left;"><td class="wrapper last" style="word-break: break-word;-webkit-hyphens: auto;-moz-hyphens: auto;hyphens: auto;border-collapse: collapse;padding: 10px 20px 0px 0px;vertical-align: top;text-align: left;position: relative;padding-right: 0px;color: #222222;font-family: Helvetica, Arial, sans-serif;font-weight: normal;margin: 0;line-height: 19px;font-size: 14px;"><table class="twelve columns" style="border-spacing: 0;border-collapse: collapse;padding: 0;vertical-align: top;text-align: left;margin: 0 auto;width: 580px;"><tr style="padding: 0;vertical-align: top;text-align: left;"><td class="text-pad" style="word-break: break-word;-webkit-hyphens: auto;-moz-hyphens: auto;hyphens: auto;border-collapse: collapse;padding: 0px 0px 10px;vertical-align: top;text-align: left;padding-left: 10px;padding-right: 10px;color: #222222;font-family: Helvetica, Arial, sans-serif;font-weight: normal;margin: 0;line-height: 19px;font-size: 14px;"><h2 class="data-lookup-header" style="color: #222222;font-family: Helvetica, Arial, sans-serif;font-weight: normal;padding: 0;margin: 0;text-align: left;line-height: 1.3;word-break: normal;font-size: 20px;margin-bottom: 15px;">Data Lookup</h2><p class="data-lookup-limit" style="margin: 0;color: #222222;font-family: Helvetica, Arial, sans-serif;font-weight: normal;padding: 0;text-align: left;line-height: 19px;font-size: 14px;margin-bottom: 10px;"><a href="'. admin_url() . 'admin.php?page=leadin_pro_upgrade">Upgrade to Leadin Pro for free</a> to get unlimited data lookups!</p></td><td class="expander" style="word-break: break-word;-webkit-hyphens: auto;-moz-hyphens: auto;hyphens: auto;border-collapse: collapse;padding: 0;vertical-align: top;text-align: left;visibility: hidden;width: 0px;color: #222222;font-family: Helvetica, Arial, sans-serif;font-weight: normal;margin: 0;line-height: 19px;font-size: 14px;"></td></tr></table></td></tr></table>';
|
270 |
+
}
|
271 |
|
272 |
return $built_enrichment_data;
|
273 |
}
|
274 |
|
275 |
+
/**
|
276 |
+
* Creates the personal info column in the data lookup content for the contact notificaiton email
|
277 |
+
*
|
278 |
+
* @param stdClass history from LI_Contact
|
279 |
+
* @return string footer content
|
280 |
+
*/
|
281 |
+
function build_enrichment_personal ( $li_contact )
|
282 |
+
{
|
283 |
+
$properties = ( isset($li_contact->history->lead->social_data->properties) ? $li_contact->history->lead->social_data->properties : '' );
|
284 |
+
$built_personal_data = "";
|
285 |
+
|
286 |
+
if ( ! isset($properties->primary) && empty($properties->social_profiles) )
|
287 |
+
{
|
288 |
+
$format = '<td class="wrapper" style="word-break: break-word;-webkit-hyphens: auto;-moz-hyphens: auto;hyphens: auto;border-collapse: collapse;padding: 10px 20px 0px 0px;vertical-align: top;text-align: left;position: relative;color: #222222;font-family: Helvetica, Arial, sans-serif;font-weight: normal;margin: 0;line-height: 19px;font-size: 14px;"><table class="six columns" style="border-spacing: 0;border-collapse: collapse;padding: 0;vertical-align: top;text-align: left;margin: 0 auto;width: 280px;"><tr style="padding: 0;vertical-align: top;text-align: left;"><td class="text-pad" style="word-break: break-word;-webkit-hyphens: auto;-moz-hyphens: auto;hyphens: auto;border-collapse: collapse;padding: 0px 0px 10px;vertical-align: top;text-align: left;padding-left: 10px;padding-right: 10px;color: #222222;font-family: Helvetica, Arial, sans-serif;font-weight: normal;margin: 0;line-height: 19px;font-size: 14px;"><p class="contact-description" style="margin: 0;color: #666;font-family: Helvetica, Arial, sans-serif;font-weight: normal;padding: 0;text-align: left;line-height: 19px;font-size: 14px;margin-bottom: 10px;">%s</p></td><td class="expander" style="word-break: break-word;-webkit-hyphens: auto;-moz-hyphens: auto;hyphens: auto;border-collapse: collapse;padding: 0;vertical-align: top;text-align: left;visibility: hidden;width: 0px;color: #222222;font-family: Helvetica, Arial, sans-serif;font-weight: normal;margin: 0;line-height: 19px;font-size: 14px;"></td></tr></table></td>';
|
289 |
+
$built_personal_data .= sprintf($format, 'We couldn\'t find any personal info for this contact.');
|
290 |
+
|
291 |
+
return $built_personal_data;
|
292 |
+
}
|
293 |
+
|
294 |
+
$format = '<td class="wrapper" style="word-break: break-word;-webkit-hyphens: auto;-moz-hyphens: auto;hyphens: auto;border-collapse: collapse;padding: 10px 20px 0px 0px;vertical-align: top;text-align: left;position: relative;color: #222222;font-family: Helvetica, Arial, sans-serif;font-weight: normal;margin: 0;line-height: 19px;font-size: 14px;"><table class="six columns" style="border-spacing: 0;border-collapse: collapse;padding: 0;vertical-align: top;text-align: left;margin: 0 auto;width: 280px;"><tr style="padding: 0;vertical-align: top;text-align: left;"><td class="text-pad" style="word-break: break-word;-webkit-hyphens: auto;-moz-hyphens: auto;hyphens: auto;border-collapse: collapse;padding: 0px 0px 10px;vertical-align: top;text-align: left;padding-left: 10px;padding-right: 10px;color: #222222;font-family: Helvetica, Arial, sans-serif;font-weight: normal;margin: 0;line-height: 19px;font-size: 14px;"><h3 class="contact-name" style="color: #444;font-family: Helvetica, Arial, sans-serif;font-weight: bold;padding: 0;margin: 0;text-align: left;line-height: 1.3;word-break: normal;font-size: 14px;">%s</h3><h4 class="contact-name-subhead" style="color: #444;font-family: Helvetica, Arial, sans-serif;font-weight: 400;padding: 0;margin: 0;text-align: left;line-height: 1.3;word-break: normal;font-size: 14px;margin-bottom: 15px;">%s</h4><p class="contact-description" style="margin: 0;color: #666;font-family: Helvetica, Arial, sans-serif;font-weight: normal;padding: 0;text-align: left;line-height: 19px;font-size: 14px;margin-bottom: 10px;">%s</p>%s</td><td class="expander" style="word-break: break-word;-webkit-hyphens: auto;-moz-hyphens: auto;hyphens: auto;border-collapse: collapse;padding: 0;vertical-align: top;text-align: left;visibility: hidden;width: 0px;color: #222222;font-family: Helvetica, Arial, sans-serif;font-weight: normal;margin: 0;line-height: 19px;font-size: 14px;"></td></tr></table></td>';
|
295 |
+
$format = '<td class="wrapper" style="word-break: break-word;-webkit-hyphens: auto;-moz-hyphens: auto;hyphens: auto;border-collapse: collapse;padding: 10px 20px 0px 0px;vertical-align: top;text-align: left;position: relative;color: #222222;font-family: Helvetica, Arial, sans-serif;font-weight: normal;margin: 0;line-height: 19px;font-size: 14px;"><table class="six columns" style="border-spacing: 0;border-collapse: collapse;padding: 0;vertical-align: top;text-align: left;margin: 0 auto;width: 280px;"><tr style="padding: 0;vertical-align: top;text-align: left;"><td class="text-pad" style="word-break: break-word;-webkit-hyphens: auto;-moz-hyphens: auto;hyphens: auto;border-collapse: collapse;padding: 0px 0px 10px;vertical-align: top;text-align: left;padding-left: 10px;padding-right: 10px;color: #222222;font-family: Helvetica, Arial, sans-serif;font-weight: normal;margin: 0;line-height: 19px;font-size: 14px;"><h3 class="contact-name" style="color: #444;font-family: Helvetica, Arial, sans-serif;font-weight: bold;padding: 0;margin: 0;text-align: left;line-height: 1.3;word-break: normal;font-size: 14px;">%s</h3><h4 class="contact-name-subhead" style="color: #444;font-family: Helvetica, Arial, sans-serif;font-weight: 400;padding: 0;margin: 0;text-align: left;line-height: 1.3;word-break: normal;font-size: 14px;margin-bottom: 15px;">%s</h4><p class="contact-description" style="margin: 0;color: #666;font-family: Helvetica, Arial, sans-serif;font-weight: normal;padding: 0;text-align: left;line-height: 19px;font-size: 14px;margin-bottom: 10px;">%s</p>%s</td><td class="expander" style="word-break: break-word;-webkit-hyphens: auto;-moz-hyphens: auto;hyphens: auto;border-collapse: collapse;padding: 0;vertical-align: top;text-align: left;visibility: hidden;width: 0px;color: #222222;font-family: Helvetica, Arial, sans-serif;font-weight: normal;margin: 0;line-height: 19px;font-size: 14px;"></td></tr></table></td>';
|
296 |
+
|
297 |
+
$contact_name = $li_contact->history->lead->lead_first_name . ' ' . $li_contact->history->lead->lead_last_name;
|
298 |
+
|
299 |
+
$contact_job_title = '';
|
300 |
+
if ( isset($properties->primary) )
|
301 |
+
$contact_job_title = $properties->primary->title . ( $properties->primary->company_name ? ' - ' . $properties->primary->company_name : '' );
|
302 |
+
|
303 |
+
$contact_bio = ( ! empty($properties->description) ? $properties->description : '');
|
304 |
+
|
305 |
+
$built_personal_data .= sprintf($format, $contact_name, $contact_job_title, $contact_bio, $this->build_enrichment_personal_fields($li_contact));
|
306 |
+
|
307 |
+
return $built_personal_data;
|
308 |
+
}
|
309 |
+
|
310 |
+
/**
|
311 |
+
* Creates the personal info column in the data lookup content for the contact notificaiton email
|
312 |
+
*
|
313 |
+
* @param stdClass history from LI_Contact
|
314 |
+
* @return string footer content
|
315 |
+
*/
|
316 |
+
function build_enrichment_personal_fields ( $li_contact ) {
|
317 |
+
$built_personal_data_fields = "";
|
318 |
+
|
319 |
+
$format = '<p class="lead-timeline__submission-field" style="margin: 0;color: #222222;font-family: Helvetica, Arial, sans-serif;font-weight: normal;padding: 0;text-align: left;line-height: 19px;font-size: 14px;margin-bottom: 10px;"><label class="lead-timeline__submission-label" style="text-transform: uppercase;font-size: 12px;color: #999;letter-spacing: 0.05em;">%s</label><br/>%s</p>';
|
320 |
+
|
321 |
+
if ( isset($li_contact->history->lead->social_data->properties->social_profiles) )
|
322 |
+
{
|
323 |
+
if ( count($li_contact->history->lead->social_data->properties->social_profiles) )
|
324 |
+
{
|
325 |
+
foreach ( $li_contact->history->lead->social_data->properties->social_profiles as $key => $profile )
|
326 |
+
{
|
327 |
+
$field_label = $profile->typename;
|
328 |
+
$field_data = '<a href="' . leadin_safe_social_profile_url($profile->url) . '" target="_blank">' . ( $profile->typeid == 'twitter' ? '@' : '' ) . ( $profile->typeid == 'linkedin' ? '/in/' : '' ) . $profile->username . '</a>';
|
329 |
+
|
330 |
+
$built_personal_data_fields .= sprintf($format, $field_label, $field_data);
|
331 |
+
}
|
332 |
+
}
|
333 |
+
}
|
334 |
+
|
335 |
+
return $built_personal_data_fields;
|
336 |
+
}
|
337 |
+
|
338 |
+
/**
|
339 |
+
* Creates the personal info column in the data lookup content for the contact notificaiton email
|
340 |
+
*
|
341 |
+
* @param stdClass history from LI_Contact
|
342 |
+
* @return string footer content
|
343 |
+
*/
|
344 |
+
function build_enrichment_company ( $li_contact )
|
345 |
+
{
|
346 |
+
$built_company_data = "";
|
347 |
+
|
348 |
+
$company_data_exists = FALSE;
|
349 |
+
$properties = ( isset($li_contact->history->lead->company_data->properties) ? $li_contact->history->lead->company_data->properties : '' );
|
350 |
+
|
351 |
+
$company_name = '';
|
352 |
+
$company_location = '';
|
353 |
+
$company_bio = '';
|
354 |
+
|
355 |
+
if ( isset($properties->name) && $properties->name )
|
356 |
+
$company_name .= $properties->name;
|
357 |
+
|
358 |
+
if ( isset($properties->city) && $properties->city )
|
359 |
+
{
|
360 |
+
$company_location .= $properties->city;
|
361 |
+
$company_data_exists = TRUE;
|
362 |
+
}
|
363 |
+
|
364 |
+
if ( isset($properties->state) && $properties->state )
|
365 |
+
{
|
366 |
+
$company_location .= ', ' . $properties->state;
|
367 |
+
$company_data_exists = TRUE;
|
368 |
+
}
|
369 |
+
|
370 |
+
if ( isset($properties->country) && $properties->country )
|
371 |
+
{
|
372 |
+
$company_location .= ', ' . $properties->country;
|
373 |
+
$company_data_exists = TRUE;
|
374 |
+
}
|
375 |
+
|
376 |
+
if ( isset($properties->overview) )
|
377 |
+
{
|
378 |
+
if ( strlen($properties->overview) < 260 )
|
379 |
+
$company_bio = $properties->overview;
|
380 |
+
else
|
381 |
+
$company_bio = substr($properties->overview, 0, strpos($properties->overview, '.', 260)) . ' ...';
|
382 |
+
|
383 |
+
$company_data_exists = TRUE;
|
384 |
+
}
|
385 |
+
|
386 |
+
if ( $company_data_exists )
|
387 |
+
{
|
388 |
+
$format = '<td class="wrapper" style="word-break: break-word;-webkit-hyphens: auto;-moz-hyphens: auto;hyphens: auto;border-collapse: collapse;padding: 10px 20px 0px 0px;vertical-align: top;text-align: left;position: relative;color: #222222;font-family: Helvetica, Arial, sans-serif;font-weight: normal;margin: 0;line-height: 19px;font-size: 14px;"><table class="six columns" style="border-spacing: 0;border-collapse: collapse;padding: 0;vertical-align: top;text-align: left;margin: 0 auto;width: 280px;"><tr style="padding: 0;vertical-align: top;text-align: left;"><td class="text-pad" style="word-break: break-word;-webkit-hyphens: auto;-moz-hyphens: auto;hyphens: auto;border-collapse: collapse;padding: 0px 0px 10px;vertical-align: top;text-align: left;padding-left: 10px;padding-right: 10px;color: #222222;font-family: Helvetica, Arial, sans-serif;font-weight: normal;margin: 0;line-height: 19px;font-size: 14px;"><h3 class="contact-name" style="color: #444;font-family: Helvetica, Arial, sans-serif;font-weight: bold;padding: 0;margin: 0;text-align: left;line-height: 1.3;word-break: normal;font-size: 14px;">%s</h3><h4 class="contact-name-subhead" style="color: #444;font-family: Helvetica, Arial, sans-serif;font-weight: 400;padding: 0;margin: 0;text-align: left;line-height: 1.3;word-break: normal;font-size: 14px;margin-bottom: 15px;">%s</h4><p class="contact-description" style="margin: 0;color: #666;font-family: Helvetica, Arial, sans-serif;font-weight: normal;padding: 0;text-align: left;line-height: 19px;font-size: 14px;margin-bottom: 10px;">%s</p>%s</td><td class="expander" style="word-break: break-word;-webkit-hyphens: auto;-moz-hyphens: auto;hyphens: auto;border-collapse: collapse;padding: 0;vertical-align: top;text-align: left;visibility: hidden;width: 0px;color: #222222;font-family: Helvetica, Arial, sans-serif;font-weight: normal;margin: 0;line-height: 19px;font-size: 14px;"></td></tr></table></td>';
|
389 |
+
$built_company_data .= sprintf($format, $company_name, $company_location, $company_bio, $this->build_enrichment_company_fields($li_contact));
|
390 |
+
}
|
391 |
+
else
|
392 |
+
{
|
393 |
+
$format = '<td class="wrapper" style="word-break: break-word;-webkit-hyphens: auto;-moz-hyphens: auto;hyphens: auto;border-collapse: collapse;padding: 10px 20px 0px 0px;vertical-align: top;text-align: left;position: relative;color: #222222;font-family: Helvetica, Arial, sans-serif;font-weight: normal;margin: 0;line-height: 19px;font-size: 14px;"><table class="six columns" style="border-spacing: 0;border-collapse: collapse;padding: 0;vertical-align: top;text-align: left;margin: 0 auto;width: 280px;"><tr style="padding: 0;vertical-align: top;text-align: left;"><td class="text-pad" style="word-break: break-word;-webkit-hyphens: auto;-moz-hyphens: auto;hyphens: auto;border-collapse: collapse;padding: 0px 0px 10px;vertical-align: top;text-align: left;padding-left: 10px;padding-right: 10px;color: #222222;font-family: Helvetica, Arial, sans-serif;font-weight: normal;margin: 0;line-height: 19px;font-size: 14px;"><p class="contact-description" style="margin: 0;color: #666;font-family: Helvetica, Arial, sans-serif;font-weight: normal;padding: 0;text-align: left;line-height: 19px;font-size: 14px;margin-bottom: 10px;">%s</p></td><td class="expander" style="word-break: break-word;-webkit-hyphens: auto;-moz-hyphens: auto;hyphens: auto;border-collapse: collapse;padding: 0;vertical-align: top;text-align: left;visibility: hidden;width: 0px;color: #222222;font-family: Helvetica, Arial, sans-serif;font-weight: normal;margin: 0;line-height: 19px;font-size: 14px;"></td></tr></table></td>';
|
394 |
+
$built_company_data .= sprintf($format, 'We couldn\'t find any company info for this contact.');
|
395 |
+
}
|
396 |
+
|
397 |
+
return $built_company_data;
|
398 |
+
}
|
399 |
+
|
400 |
+
/**
|
401 |
+
* Creates the company info column in the data lookup content for the contact notificaiton email
|
402 |
+
*
|
403 |
+
* @param stdClass history from LI_Contact
|
404 |
+
* @return string footer content
|
405 |
+
*/
|
406 |
+
function build_enrichment_company_fields ( $li_contact ) {
|
407 |
+
$properties = $li_contact->history->lead->company_data->properties;
|
408 |
+
|
409 |
+
$built_company_data_fields = "";
|
410 |
+
|
411 |
+
$format = '<p class="lead-timeline__submission-field" style="margin: 0;color: #222222;font-family: Helvetica, Arial, sans-serif;font-weight: normal;padding: 0;text-align: left;line-height: 19px;font-size: 14px;margin-bottom: 10px;"><label class="lead-timeline__submission-label" style="text-transform: uppercase;font-size: 12px;color: #999;letter-spacing: 0.05em;">%s</label><br/>%s</p>';
|
412 |
+
|
413 |
+
if ( !empty($properties->facebookpageurl) )
|
414 |
+
{
|
415 |
+
$field_label = "Facebook";
|
416 |
+
$field_data = '<a href="' . $properties->facebookpageurl . '" target="_blank">' . $properties->name . '</a>';
|
417 |
+
$built_company_data_fields .= sprintf($format, $field_label, $field_data);
|
418 |
+
}
|
419 |
+
|
420 |
+
if ( !empty($properties->twitterusername) )
|
421 |
+
{
|
422 |
+
$field_label = "Twitter";
|
423 |
+
$field_data = '<a href="' . $properties->twitterurl . '" target="_blank">' . '@' . $properties->twitterusername . '</a>';
|
424 |
+
$built_company_data_fields .= sprintf($format, $field_label, $field_data);
|
425 |
+
}
|
426 |
+
|
427 |
+
if ( !empty($properties->linkedinurl) )
|
428 |
+
{
|
429 |
+
$field_label = "LinkedIn";
|
430 |
+
$field_data = '<a href="' . $properties->linkedinurl . '" target="_blank">' . $properties->name . '</a>';
|
431 |
+
$built_company_data_fields .= sprintf($format, $field_label, $field_data);
|
432 |
+
}
|
433 |
+
|
434 |
+
|
435 |
+
return $built_company_data_fields;
|
436 |
+
}
|
437 |
+
|
438 |
/**
|
439 |
* Creates the footer content for the contact notificaiton email
|
440 |
*
|
522 |
$body .="You may also contact us at:<br/><a href='mailto:" . $leadin_email . "'>" . $leadin_email . "</a>";
|
523 |
$body .= "</td></tr></table></td><td class='expander' style='word-break: break-word;-webkit-hyphens: auto;-moz-hyphens: auto;hyphens: auto;border-collapse: collapse !important;vertical-align: top;text-align: left;visibility: hidden;width: 0px;padding: 0;border: 0;' align='left' valign='top'></td></tr></table></td></tr></table>";
|
524 |
|
525 |
+
$body .= $this->build_powered_by_link();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
526 |
|
527 |
// @EMAIL - end form section
|
528 |
|
533 |
// Each line in an email can only be 998 characters long, so lines need to be broken with a wordwrap
|
534 |
$body = wordwrap($body, 900, "\r\n");
|
535 |
|
536 |
+
$headers = "From: Leadin <notifications@leadin.com>\r\n";
|
537 |
$headers.= "Reply-To: Leadin <" . $from . ">\r\n";
|
538 |
$headers.= "X-Mailer: PHP/" . phpversion() . "\r\n";
|
539 |
$headers.= "MIME-Version: 1.0\r\n";
|
555 |
$powered_by = '';
|
556 |
|
557 |
$powered_by .= "<table class='row section' style='border-spacing: 0;border-collapse: collapse;vertical-align: top;text-align: left;width: 100%;position: relative;display: block;margin-top: 20px;padding: 0px;'><tr style='vertical-align: top;text-align: left;padding: 0;' align='left'><td class='wrapper last' style='word-break: break-word;-webkit-hyphens: auto;-moz-hyphens: auto;hyphens: auto;border-collapse: collapse !important;vertical-align: top;text-align: left;position: relative;padding: 0 0px 0 0;' align='left' valign='top'><table class='twelve columns' style='border-spacing: 0;border-collapse: collapse;vertical-align: top;text-align: left;width: 580px;margin: 0 auto;padding: 0;'><tr style='vertical-align: top;text-align: left;padding: 0;' align='left'><td style='padding: 10px 20px;' align='left' valign='top'><table style='border-spacing: 0;border-collapse: collapse;vertical-align: top;text-align: left;width: 100%;overflow: hidden;padding: 0;'><tr style='vertical-align: top;text-align: left;padding: 0;' align='left'><td style='word-break: break-word;-webkit-hyphens: auto;-moz-hyphens: auto;hyphens: auto;border-collapse: collapse !important;vertical-align: top;text-align: center;display: block;width: auto !important;font-size: 16px;padding: 10px 20px;' align='center' valign='top'>";
|
558 |
+
$powered_by .="<div style='font-size: 11px; color: #888; padding: 0 0 5px 0;'>Powered by</div><a href='http://leadin.com/wordpress-subscribe-widget-plugin?utm_source=virality&utm_medium=referral&utm_term=" . get_bloginfo('wpurl') . "&utm_content=e11&utm_campaign=subscribe%20confirmation%20email'><img alt='Leadin' height='20px' width='99px' src='http://leadin.com/wp-content/themes/LeadIn-WP-Theme/library/images/logos/leadin_logo_small_grey.png' alt='leadin.com'/></a>";
|
559 |
$powered_by .= "</td></tr></table></td><td class='expander' style='word-break: break-word;-webkit-hyphens: auto;-moz-hyphens: auto;hyphens: auto;border-collapse: collapse !important;vertical-align: top;text-align: left;visibility: hidden;width: 0px;padding: 0;border: 0;' align='left' valign='top'></td></tr></table></td></tr></table>";
|
560 |
|
561 |
return $powered_by;
|
562 |
}
|
563 |
+
|
564 |
+
/**
|
565 |
+
* Creates Mixpanel tracking email pixel
|
566 |
+
*
|
567 |
+
* @return string specs @ https://mixpanel.com/docs/api-documentation/pixel-based-event-tracking
|
568 |
+
*/
|
569 |
+
function create_tracking_pixel ( )
|
570 |
+
{
|
571 |
+
$url_properties = array(
|
572 |
+
'token' => MIXPANEL_PROJECT_TOKEN
|
573 |
+
);
|
574 |
+
|
575 |
+
$leadin_user = leadin_get_current_user();
|
576 |
+
$leadin_user_properties = array(
|
577 |
+
'distinct_id' => $leadin_user['user_id'],
|
578 |
+
'$wp-url' => $leadin_user['wp_url'],
|
579 |
+
'$wp-version' => $leadin_user['wp_version'],
|
580 |
+
'$li-version' => $leadin_user['li_version']
|
581 |
+
);
|
582 |
+
|
583 |
+
$properties = array_merge($url_properties, $leadin_user_properties);
|
584 |
+
|
585 |
+
$params = array ( 'event' => 'Contact Notification Opened', 'properties' => $properties );
|
586 |
+
|
587 |
+
return 'http://api.mixpanel.com/track/?data=' . base64_encode(json_encode($params)) . '&ip=1&img=1';
|
588 |
+
}
|
589 |
+
|
590 |
+
/**
|
591 |
+
* Creates Mixpanel tracking email pixel
|
592 |
+
*
|
593 |
+
* @param string email address to send notification to
|
594 |
+
* @param string subject line for contact notification email
|
595 |
+
* @param string html body of email
|
596 |
+
* @return string specs @ https://mixpanel.com/docs/api-documentation/pixel-based-event-tracking
|
597 |
+
*/
|
598 |
+
function send_email_via_sendgrid ( $to = '', $subject = '', $body = '', $domain = '' )
|
599 |
+
{
|
600 |
+
$fields = array(
|
601 |
+
'to_email' => urlencode($to),
|
602 |
+
'subject' => urlencode($subject),
|
603 |
+
'message' => urlencode($body),
|
604 |
+
'domain' => urlencode($domain)
|
605 |
+
);
|
606 |
+
|
607 |
+
$fields_string = http_build_query($fields);
|
608 |
+
|
609 |
+
$ch = curl_init();
|
610 |
+
curl_setopt($ch,CURLOPT_URL, 'http://leadin.com/pro/notifications/sendgrid_email.php');
|
611 |
+
curl_setopt($ch,CURLOPT_POST, 1);
|
612 |
+
curl_setopt($ch,CURLOPT_POSTFIELDS, $fields_string);
|
613 |
+
$result = curl_exec($ch);
|
614 |
+
curl_close($ch);
|
615 |
+
|
616 |
+
return $result;
|
617 |
+
}
|
618 |
}
|
inc/class-leadin-updater.php
CHANGED
@@ -19,9 +19,7 @@ class WPLeadInUpdater {
|
|
19 |
*/
|
20 |
function __construct ( $update_type = 'beta' )
|
21 |
{
|
22 |
-
if ( $update_type == '
|
23 |
-
$this->api_url = 'http://leadin.com/plugins/index.php';
|
24 |
-
else if ( $update_type == 'pro' )
|
25 |
$this->api_url = 'http://leadin.com/pro/index.php';
|
26 |
|
27 |
$this->plugin_slug = LEADIN_PLUGIN_SLUG;
|
19 |
*/
|
20 |
function __construct ( $update_type = 'beta' )
|
21 |
{
|
22 |
+
if ( $update_type == 'pro' )
|
|
|
|
|
23 |
$this->api_url = 'http://leadin.com/pro/index.php';
|
24 |
|
25 |
$this->plugin_slug = LEADIN_PLUGIN_SLUG;
|
inc/class-leadin.php
CHANGED
@@ -30,6 +30,7 @@ class WPLeadIn {
|
|
30 |
}
|
31 |
else
|
32 |
{
|
|
|
33 |
if ( in_array($GLOBALS['pagenow'], array('wp-login.php', 'wp-register.php')) )
|
34 |
add_action('login_enqueue_scripts', array($this, 'add_leadin_frontend_scripts'));
|
35 |
else
|
@@ -48,7 +49,7 @@ class WPLeadIn {
|
|
48 |
{
|
49 |
wp_register_script('leadin-tracking', LEADIN_PATH . '/assets/js/build/leadin-tracking.min.js', array ('jquery'), FALSE, TRUE);
|
50 |
wp_enqueue_script('leadin-tracking');
|
51 |
-
|
52 |
// replace https with http for admin-ajax calls for SSLed backends
|
53 |
$admin_url = admin_url('admin-ajax.php');
|
54 |
wp_localize_script(
|
@@ -61,7 +62,7 @@ class WPLeadIn {
|
|
61 |
/**
|
62 |
* Adds Leadin link to top-level admin bar
|
63 |
*/
|
64 |
-
function add_leadin_link_to_admin_bar ( $wp_admin_bar )
|
65 |
{
|
66 |
global $wp_version;
|
67 |
|
@@ -73,7 +74,7 @@ class WPLeadIn {
|
|
73 |
|
74 |
$args = array(
|
75 |
'id' => 'leadin-admin-menu',
|
76 |
-
'title' => '<span class="ab-icon" '. ( $wp_version < 3.8 && !is_plugin_active('mp6/mp6.php') ? ' style="margin-top: 3px;"' : ''). '><img src="' .
|
77 |
'parent' => FALSE, // set parent to false to make it a top level (parent) node
|
78 |
'href' => get_bloginfo('wpurl') . '/wp-admin/admin.php?page=leadin_stats',
|
79 |
'meta' => array('title' => 'Leadin')
|
@@ -107,12 +108,13 @@ class WPLeadIn {
|
|
107 |
$power_up->link_uri = $headers['uri'];
|
108 |
$power_up->description = $headers['description'];
|
109 |
$power_up->icon = $headers['icon'];
|
|
|
110 |
$power_up->permanent = ( $headers['permanent'] == 'Yes' ? 1 : 0 );
|
111 |
$power_up->auto_activate = ( $headers['auto_activate'] == 'Yes' ? 1 : 0 );
|
112 |
$power_up->hidden = ( $headers['hidden'] == 'Yes' ? 1 : 0 );
|
113 |
$power_up->curl_required = ( $headers['curl_required'] == 'Yes' ? 1 : 0 );
|
114 |
-
$power_up->
|
115 |
-
|
116 |
// Set the small icons HTML for the settings page
|
117 |
if ( strstr($headers['icon_small'], 'dashicons') )
|
118 |
$power_up->icon_small = '<span class="dashicons ' . $headers['icon_small'] . '"></span>';
|
@@ -165,7 +167,8 @@ class WPLeadIn {
|
|
165 |
'permanent' => 'Permanently Enabled',
|
166 |
'power_up_tags' => 'Power-up Tags',
|
167 |
'hidden' => 'Hidden',
|
168 |
-
'curl_required' => 'cURL Required'
|
|
|
169 |
);
|
170 |
|
171 |
$file = self::get_power_up_path( self::get_power_up_slug( $power_up ) );
|
@@ -211,10 +214,15 @@ class WPLeadIn {
|
|
211 |
}
|
212 |
|
213 |
$files = leadin_sort_power_ups($files, array(
|
214 |
-
LEADIN_PLUGIN_DIR . '/power-ups/contacts.php',
|
|
|
215 |
LEADIN_PLUGIN_DIR . '/power-ups/subscribe-widget.php',
|
216 |
LEADIN_PLUGIN_DIR . '/power-ups/mailchimp-connect.php',
|
217 |
-
LEADIN_PLUGIN_DIR . '/power-ups/constant-contact-connect.php'
|
|
|
|
|
|
|
|
|
218 |
));
|
219 |
|
220 |
closedir( $dir );
|
@@ -247,7 +255,7 @@ class WPLeadIn {
|
|
247 |
return array();
|
248 |
}
|
249 |
|
250 |
-
public static function activate_power_up
|
251 |
{
|
252 |
if ( ! strlen( $power_up_slug ) )
|
253 |
return FALSE;
|
@@ -278,12 +286,12 @@ class WPLeadIn {
|
|
278 |
}
|
279 |
}
|
280 |
|
281 |
-
public static function deactivate_power_up
|
282 |
{
|
283 |
if ( ! strlen( $power_up_slug ) )
|
284 |
return FALSE;
|
285 |
|
286 |
-
// If it's already
|
287 |
$active = self::is_power_up_active($power_up_slug);
|
288 |
if ( ! $active )
|
289 |
return TRUE;
|
@@ -297,61 +305,7 @@ class WPLeadIn {
|
|
297 |
{
|
298 |
exit;
|
299 |
}
|
300 |
-
}
|
301 |
|
302 |
-
/**
|
303 |
-
* Throws an error for when the premium version and the free version are activated in tandem
|
304 |
-
*/
|
305 |
-
function deactivate_leadin_notice ()
|
306 |
-
{
|
307 |
-
?>
|
308 |
-
<div id="message" class="update-nag">
|
309 |
-
<?php
|
310 |
-
_e(
|
311 |
-
'<p>' .
|
312 |
-
'<a style="font-size: 14px; float: right; color: #ccc; text-decoration: none; margin-top: -15px;" href="#">✖</a>' .
|
313 |
-
'<b>Leadin Pro is now avaialble!</b>' .
|
314 |
-
'</p>' .
|
315 |
-
'<p>' .
|
316 |
-
'Leadin Pro includes all the features you\'ve come to love from our plugin along with some powerful new ones too. <a href="#">See all the features</a>' .
|
317 |
-
'</p>' .
|
318 |
-
'<p>' .
|
319 |
-
'The launch of Leadin Pro also means that we are no longer supporting the version of Leadin hosted by the WordPress Plugin Directory.' .
|
320 |
-
'Read more about why we are making this change on <a href="http://leadin.com/the-move-to-pro">the Leadin blog</a>. ' .
|
321 |
-
'</p>' .
|
322 |
-
'<p>' .
|
323 |
-
'If you run have any questions or concerns, please feel free to email us - <a href="mailto:support@leadin.com">support@leadin.com</a>' .
|
324 |
-
'</p>' .
|
325 |
-
'<p>' .
|
326 |
-
'<a class="button button-primary" href="http://leadin.com">Download Leadin Pro for Free</a> ' .
|
327 |
-
'</p>',
|
328 |
-
'my-text-domain'
|
329 |
-
);
|
330 |
-
?>
|
331 |
-
</div>
|
332 |
-
<?php
|
333 |
-
}
|
334 |
-
|
335 |
-
/* Display a notice that can be dismissed */
|
336 |
-
|
337 |
-
function example_admin_notice() {
|
338 |
-
global $current_user ;
|
339 |
-
$user_id = $current_user->ID;
|
340 |
-
/* Check that the user hasn't already clicked to ignore the message */
|
341 |
-
if ( ! get_user_meta($user_id, 'example_ignore_notice') ) {
|
342 |
-
echo '<div class="updated"><p>';
|
343 |
-
printf(__('This is an annoying nag message. Why do people make these? | <a href="%1$s">Hide Notice</a>'), '?example_nag_ignore=0');
|
344 |
-
echo "</p></div>";
|
345 |
-
}
|
346 |
-
}
|
347 |
-
|
348 |
-
function example_nag_ignore() {
|
349 |
-
global $current_user;
|
350 |
-
$user_id = $current_user->ID;
|
351 |
-
/* If user clicks to ignore the notice, add that to their user meta */
|
352 |
-
if ( isset($_GET['example_nag_ignore']) && '0' == $_GET['example_nag_ignore'] ) {
|
353 |
-
add_user_meta($user_id, 'example_ignore_notice', 'true', true);
|
354 |
-
}
|
355 |
}
|
356 |
}
|
357 |
|
30 |
}
|
31 |
else
|
32 |
{
|
33 |
+
// Adds the leadin-tracking script to wp-login.php page which doesnt hook into the enqueue logic
|
34 |
if ( in_array($GLOBALS['pagenow'], array('wp-login.php', 'wp-register.php')) )
|
35 |
add_action('login_enqueue_scripts', array($this, 'add_leadin_frontend_scripts'));
|
36 |
else
|
49 |
{
|
50 |
wp_register_script('leadin-tracking', LEADIN_PATH . '/assets/js/build/leadin-tracking.min.js', array ('jquery'), FALSE, TRUE);
|
51 |
wp_enqueue_script('leadin-tracking');
|
52 |
+
|
53 |
// replace https with http for admin-ajax calls for SSLed backends
|
54 |
$admin_url = admin_url('admin-ajax.php');
|
55 |
wp_localize_script(
|
62 |
/**
|
63 |
* Adds Leadin link to top-level admin bar
|
64 |
*/
|
65 |
+
function add_leadin_link_to_admin_bar ( $wp_admin_bar )
|
66 |
{
|
67 |
global $wp_version;
|
68 |
|
74 |
|
75 |
$args = array(
|
76 |
'id' => 'leadin-admin-menu',
|
77 |
+
'title' => '<span class="ab-icon" '. ( $wp_version < 3.8 && !is_plugin_active('mp6/mp6.php') ? ' style="margin-top: 3px;"' : ''). '><img src="data:image/svg+xml;base64,' . base64_encode(file_get_contents(LEADIN_PATH . '/images/leadin-svg-icon.svg')). '"></span><span class="ab-label">Leadin</span>', // alter the title of existing node
|
78 |
'parent' => FALSE, // set parent to false to make it a top level (parent) node
|
79 |
'href' => get_bloginfo('wpurl') . '/wp-admin/admin.php?page=leadin_stats',
|
80 |
'meta' => array('title' => 'Leadin')
|
108 |
$power_up->link_uri = $headers['uri'];
|
109 |
$power_up->description = $headers['description'];
|
110 |
$power_up->icon = $headers['icon'];
|
111 |
+
$power_up->activated = $headers['activated'];
|
112 |
$power_up->permanent = ( $headers['permanent'] == 'Yes' ? 1 : 0 );
|
113 |
$power_up->auto_activate = ( $headers['auto_activate'] == 'Yes' ? 1 : 0 );
|
114 |
$power_up->hidden = ( $headers['hidden'] == 'Yes' ? 1 : 0 );
|
115 |
$power_up->curl_required = ( $headers['curl_required'] == 'Yes' ? 1 : 0 );
|
116 |
+
$power_up->pro_only = ( $headers['pro_only'] == 'Yes' ? 1 : 0 );
|
117 |
+
|
118 |
// Set the small icons HTML for the settings page
|
119 |
if ( strstr($headers['icon_small'], 'dashicons') )
|
120 |
$power_up->icon_small = '<span class="dashicons ' . $headers['icon_small'] . '"></span>';
|
167 |
'permanent' => 'Permanently Enabled',
|
168 |
'power_up_tags' => 'Power-up Tags',
|
169 |
'hidden' => 'Hidden',
|
170 |
+
'curl_required' => 'cURL Required',
|
171 |
+
'pro_only' => 'Pro Only'
|
172 |
);
|
173 |
|
174 |
$file = self::get_power_up_path( self::get_power_up_slug( $power_up ) );
|
214 |
}
|
215 |
|
216 |
$files = leadin_sort_power_ups($files, array(
|
217 |
+
LEADIN_PLUGIN_DIR . '/power-ups/contacts.php',
|
218 |
+
LEADIN_PLUGIN_DIR . '/power-ups/lookups.php',
|
219 |
LEADIN_PLUGIN_DIR . '/power-ups/subscribe-widget.php',
|
220 |
LEADIN_PLUGIN_DIR . '/power-ups/mailchimp-connect.php',
|
221 |
+
LEADIN_PLUGIN_DIR . '/power-ups/constant-contact-connect.php',
|
222 |
+
LEADIN_PLUGIN_DIR . '/power-ups/aweber-connect.php',
|
223 |
+
LEADIN_PLUGIN_DIR . '/power-ups/campaign-monitor-connect.php',
|
224 |
+
LEADIN_PLUGIN_DIR . '/power-ups/getresponse-connect.php',
|
225 |
+
LEADIN_PLUGIN_DIR . '/power-ups/beta-program.php'
|
226 |
));
|
227 |
|
228 |
closedir( $dir );
|
255 |
return array();
|
256 |
}
|
257 |
|
258 |
+
public static function activate_power_up( $power_up_slug, $exit = TRUE )
|
259 |
{
|
260 |
if ( ! strlen( $power_up_slug ) )
|
261 |
return FALSE;
|
286 |
}
|
287 |
}
|
288 |
|
289 |
+
public static function deactivate_power_up( $power_up_slug, $exit = TRUE )
|
290 |
{
|
291 |
if ( ! strlen( $power_up_slug ) )
|
292 |
return FALSE;
|
293 |
|
294 |
+
// If it's already active, then don't do it again
|
295 |
$active = self::is_power_up_active($power_up_slug);
|
296 |
if ( ! $active )
|
297 |
return TRUE;
|
305 |
{
|
306 |
exit;
|
307 |
}
|
|
|
308 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
309 |
}
|
310 |
}
|
311 |
|
inc/leadin-ajax-functions.php
CHANGED
@@ -175,11 +175,11 @@ function leadin_insert_form_submission ()
|
|
175 |
$contact = $wpdb->get_row($q);
|
176 |
|
177 |
// Check if either of the names field are set and a value was filled out that's different than the existing name field
|
178 |
-
$lead_first_name = $contact->lead_first_name;
|
179 |
if ( strlen($first_name) && $lead_first_name != $first_name )
|
180 |
$lead_first_name = $first_name;
|
181 |
|
182 |
-
$lead_last_name = $contact->lead_last_name;
|
183 |
if ( strlen($last_name) && $lead_last_name != $last_name )
|
184 |
$lead_last_name = $last_name;
|
185 |
|
@@ -188,7 +188,7 @@ function leadin_insert_form_submission ()
|
|
188 |
$existing_contacts = $wpdb->get_results($q);
|
189 |
|
190 |
// Setup the string for the existing hashkeys
|
191 |
-
$existing_contact_hashkeys = $contact->merged_hashkeys;
|
192 |
if ( $contact->merged_hashkeys && count($existing_contacts) )
|
193 |
$existing_contact_hashkeys .= ',';
|
194 |
|
@@ -277,11 +277,10 @@ function leadin_insert_form_submission ()
|
|
277 |
// e.g. leadin_constant_contact_connect_wp
|
278 |
$leadin_esp_wp = 'leadin_' . $synced_list['esp'] . '_connect_wp';
|
279 |
global ${$leadin_esp_wp};
|
280 |
-
|
281 |
-
if ( isset(${$leadin_esp_wp}) )
|
282 |
{
|
283 |
-
|
284 |
-
${$leadin_esp_wp}->push_contact_to_list($synced_list['list_id'], $email, $first_name, $last_name, $phone);
|
285 |
}
|
286 |
}
|
287 |
}
|
@@ -290,6 +289,7 @@ function leadin_insert_form_submission ()
|
|
290 |
}
|
291 |
|
292 |
// Apply the tag relationship to contacts for class rules
|
|
|
293 |
if ( $form_selector_classes )
|
294 |
$form_classes = explode(',', $form_selector_classes);
|
295 |
|
@@ -316,8 +316,10 @@ function leadin_insert_form_submission ()
|
|
316 |
$leadin_esp_wp = 'leadin_' . $synced_list['esp'] . '_connect_wp';
|
317 |
global ${$leadin_esp_wp};
|
318 |
|
319 |
-
if ( ${$leadin_esp_wp}->activated )
|
|
|
320 |
${$leadin_esp_wp}->push_contact_to_list($synced_list['list_id'], $email, $first_name, $last_name, $phone);
|
|
|
321 |
}
|
322 |
}
|
323 |
}
|
@@ -342,6 +344,8 @@ function leadin_insert_form_submission ()
|
|
342 |
else if ( strstr($form_selector_id, 'commentform') )
|
343 |
$contact_type = 'comment';
|
344 |
|
|
|
|
|
345 |
return $rows_updated;
|
346 |
}
|
347 |
|
@@ -385,6 +389,7 @@ add_action('wp_ajax_nopriv_leadin_check_visitor_status', 'leadin_check_visitor_s
|
|
385 |
*/
|
386 |
function leadin_subscribe_show ()
|
387 |
{
|
|
|
388 |
die();
|
389 |
}
|
390 |
|
@@ -400,6 +405,8 @@ function leadin_get_posts_and_pages ( )
|
|
400 |
{
|
401 |
global $wpdb;
|
402 |
|
|
|
|
|
403 |
$search_term = $_POST['search_term'];
|
404 |
|
405 |
$q = $wpdb->prepare("SELECT post_title, post_name FROM " . $wpdb->prefix . "posts WHERE post_status = 'publish' AND ( post_name LIKE '%%%s%%' OR post_title LIKE '%%%s%%' ) GROUP BY post_name ORDER BY post_date DESC LIMIT 25", $search_term, $search_term);
|
@@ -428,6 +435,8 @@ function leadin_get_form_selectors ( )
|
|
428 |
{
|
429 |
global $wpdb;
|
430 |
|
|
|
|
|
431 |
$search_term = $_POST['search_term'];
|
432 |
$tagger = new LI_Tag_Editor();
|
433 |
|
@@ -477,4 +486,56 @@ function leadin_get_form_selectors ( )
|
|
477 |
add_action('wp_ajax_leadin_get_form_selectors', 'leadin_get_form_selectors'); // Call when user logged in
|
478 |
add_action('wp_ajax_nopriv_leadin_get_form_selectors', 'leadin_get_form_selectors'); // Call when user is not logged in
|
479 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
480 |
?>
|
175 |
$contact = $wpdb->get_row($q);
|
176 |
|
177 |
// Check if either of the names field are set and a value was filled out that's different than the existing name field
|
178 |
+
$lead_first_name = ( isset($contact->lead_first_name) ? $contact->lead_first_name : '' );
|
179 |
if ( strlen($first_name) && $lead_first_name != $first_name )
|
180 |
$lead_first_name = $first_name;
|
181 |
|
182 |
+
$lead_last_name = ( isset($contact->lead_last_name) ? $contact->lead_last_name : '' );
|
183 |
if ( strlen($last_name) && $lead_last_name != $last_name )
|
184 |
$lead_last_name = $last_name;
|
185 |
|
188 |
$existing_contacts = $wpdb->get_results($q);
|
189 |
|
190 |
// Setup the string for the existing hashkeys
|
191 |
+
$existing_contact_hashkeys = ( isset($contact->merged_hashkeys) ? $contact->merged_hashkeys : '' );
|
192 |
if ( $contact->merged_hashkeys && count($existing_contacts) )
|
193 |
$existing_contact_hashkeys .= ',';
|
194 |
|
277 |
// e.g. leadin_constant_contact_connect_wp
|
278 |
$leadin_esp_wp = 'leadin_' . $synced_list['esp'] . '_connect_wp';
|
279 |
global ${$leadin_esp_wp};
|
280 |
+
|
281 |
+
if ( isset(${$leadin_esp_wp}->activated) && ${$leadin_esp_wp}->activated )
|
282 |
{
|
283 |
+
${$leadin_esp_wp}->push_contact_to_list($synced_list['list_id'], $email, $first_name, $last_name, $phone);
|
|
|
284 |
}
|
285 |
}
|
286 |
}
|
289 |
}
|
290 |
|
291 |
// Apply the tag relationship to contacts for class rules
|
292 |
+
$form_classes = '';
|
293 |
if ( $form_selector_classes )
|
294 |
$form_classes = explode(',', $form_selector_classes);
|
295 |
|
316 |
$leadin_esp_wp = 'leadin_' . $synced_list['esp'] . '_connect_wp';
|
317 |
global ${$leadin_esp_wp};
|
318 |
|
319 |
+
if ( isset(${$leadin_esp_wp}->activated) && ${$leadin_esp_wp}->activated )
|
320 |
+
{
|
321 |
${$leadin_esp_wp}->push_contact_to_list($synced_list['list_id'], $email, $first_name, $last_name, $phone);
|
322 |
+
}
|
323 |
}
|
324 |
}
|
325 |
}
|
344 |
else if ( strstr($form_selector_id, 'commentform') )
|
345 |
$contact_type = 'comment';
|
346 |
|
347 |
+
leadin_track_plugin_activity("New lead", array("contact_type" => $contact_type));
|
348 |
+
|
349 |
return $rows_updated;
|
350 |
}
|
351 |
|
389 |
*/
|
390 |
function leadin_subscribe_show ()
|
391 |
{
|
392 |
+
leadin_track_plugin_activity('widget shown');
|
393 |
die();
|
394 |
}
|
395 |
|
405 |
{
|
406 |
global $wpdb;
|
407 |
|
408 |
+
leadin_track_plugin_activity('Filter action clicked', array( "filter_type" => "page" ));
|
409 |
+
|
410 |
$search_term = $_POST['search_term'];
|
411 |
|
412 |
$q = $wpdb->prepare("SELECT post_title, post_name FROM " . $wpdb->prefix . "posts WHERE post_status = 'publish' AND ( post_name LIKE '%%%s%%' OR post_title LIKE '%%%s%%' ) GROUP BY post_name ORDER BY post_date DESC LIMIT 25", $search_term, $search_term);
|
435 |
{
|
436 |
global $wpdb;
|
437 |
|
438 |
+
leadin_track_plugin_activity('Filter action clicked', array( "filter_type" => "form" ));
|
439 |
+
|
440 |
$search_term = $_POST['search_term'];
|
441 |
$tagger = new LI_Tag_Editor();
|
442 |
|
486 |
add_action('wp_ajax_leadin_get_form_selectors', 'leadin_get_form_selectors'); // Call when user logged in
|
487 |
add_action('wp_ajax_nopriv_leadin_get_form_selectors', 'leadin_get_form_selectors'); // Call when user is not logged in
|
488 |
|
489 |
+
/**
|
490 |
+
* Sets the Pro flag for the Leadin Pro upgrade
|
491 |
+
*
|
492 |
+
*/
|
493 |
+
function leadin_upgrade_to_pro ( )
|
494 |
+
{
|
495 |
+
global $wpdb;
|
496 |
+
|
497 |
+
$options = get_option('leadin_options');
|
498 |
+
if ( isset($options['pro']) && $options['pro'] )
|
499 |
+
{
|
500 |
+
echo get_bloginfo('wpurl') . '/wp-admin/admin.php?page=leadin_contacts';
|
501 |
+
}
|
502 |
+
else
|
503 |
+
{
|
504 |
+
$updated = leadin_update_option('leadin_options', 'pro', 1);
|
505 |
+
echo get_bloginfo('wpurl') . '/wp-admin/admin.php?page=leadin_contacts';
|
506 |
+
}
|
507 |
+
|
508 |
+
WPLeadIn::activate_power_up('lookups', FALSE);
|
509 |
+
|
510 |
+
// Create the user in Segment
|
511 |
+
$traits = leadin_get_segment_traits();
|
512 |
+
$traits["last_activated"] = date("Y-m-d H:i:s");
|
513 |
+
$traits["li-status"] = "activated";
|
514 |
+
leadin_set_user_properties($traits);
|
515 |
+
|
516 |
+
leadin_track_plugin_activity("Upgraded to Pro");
|
517 |
+
|
518 |
+
die();
|
519 |
+
}
|
520 |
+
|
521 |
+
add_action('wp_ajax_leadin_upgrade_to_pro', 'leadin_upgrade_to_pro'); // Call when user logged in
|
522 |
+
add_action('wp_ajax_nopriv_leadin_upgrade_to_pro', 'leadin_upgrade_to_pro'); // Call when user is not logged in
|
523 |
+
|
524 |
+
/**
|
525 |
+
* Checks the first entry in the pageviews table and echos flag to Javascript
|
526 |
+
*
|
527 |
+
*/
|
528 |
+
function leadin_check_installation_date ( )
|
529 |
+
{
|
530 |
+
if ( leadin_check_first_pageview_data() )
|
531 |
+
echo 1;
|
532 |
+
else
|
533 |
+
echo 0;
|
534 |
+
|
535 |
+
die();
|
536 |
+
}
|
537 |
+
|
538 |
+
add_action('wp_ajax_leadin_check_installation_date', 'leadin_check_installation_date'); // Call when user logged in
|
539 |
+
add_action('wp_ajax_nopriv_leadin_check_installation_date', 'leadin_check_installation_date'); // Call when user is not logged in
|
540 |
+
|
541 |
?>
|
inc/leadin-constants.php
ADDED
@@ -0,0 +1,15 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
if ( ! defined('LEADIN_UTM_SOURCE') )
|
4 |
+
define('LEADIN_UTM_SOURCE', 'leadin%20repo%20plugin');
|
5 |
+
|
6 |
+
if ( ! defined('LEADIN_UTM_MEDIUM') )
|
7 |
+
define('LEADIN_UTM_MEDIUM', 'referral');
|
8 |
+
|
9 |
+
if ( ! defined('LEADIN_UTM_CONTENT') )
|
10 |
+
define('LEADIN_UTM_CONTENT', 'e10');
|
11 |
+
|
12 |
+
if ( ! defined('LEADIN_UTM_CAMPAIGN') )
|
13 |
+
define('LEADIN_UTM_CAMPAIGN', 'one%20click%20updater');
|
14 |
+
|
15 |
+
?>
|
inc/leadin-functions.php
CHANGED
@@ -101,26 +101,122 @@ function leadin_get_current_user ()
|
|
101 |
'alias' => $current_user->display_name,
|
102 |
'wp_url' => get_bloginfo('wpurl'),
|
103 |
'li_version' => LEADIN_PLUGIN_VERSION,
|
104 |
-
'wp_version' => $wp_version
|
|
|
105 |
);
|
106 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
107 |
return $leadin_user;
|
108 |
}
|
109 |
|
110 |
/**
|
111 |
-
*
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
112 |
*
|
113 |
* @return bool
|
114 |
*/
|
115 |
-
function
|
116 |
{
|
117 |
-
|
118 |
-
|
|
|
|
|
|
|
119 |
|
120 |
$leadin_user = leadin_get_current_user();
|
121 |
-
|
122 |
-
// Sync to email to MailChimp
|
123 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
124 |
$MailChimp = new LI_MailChimp(MC_KEY);
|
125 |
$contact_synced = $MailChimp->call("lists/subscribe", array(
|
126 |
"id" => 'c390aea726',
|
@@ -133,7 +229,91 @@ function leadin_subscribe_user_updates ()
|
|
133 |
"merge_vars" => array('EMAIL' => $leadin_user['email'], 'WEBSITE' => get_site_url() )
|
134 |
));
|
135 |
|
136 |
-
return
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
137 |
}
|
138 |
|
139 |
/**
|
@@ -706,11 +886,11 @@ function leadin_in_array_deep ( $needle, $haystack )
|
|
706 |
*/
|
707 |
function leadin_array_search_deep ( $needle, $array, $index )
|
708 |
{
|
709 |
-
|
710 |
-
|
711 |
-
|
712 |
-
|
713 |
-
|
714 |
|
715 |
return NULL;
|
716 |
}
|
@@ -835,7 +1015,13 @@ function leadin_ignore_logged_in_user ()
|
|
835 |
return FALSE;
|
836 |
}
|
837 |
|
838 |
-
function
|
|
|
|
|
|
|
|
|
|
|
|
|
839 |
{
|
840 |
$default_options = array(
|
841 |
'li_installed' => 1,
|
@@ -853,18 +1039,65 @@ function leadin_check_multisite_missing_options ( $options )
|
|
853 |
'names_added_to_contacts' => 1
|
854 |
);
|
855 |
|
|
|
|
|
|
|
|
|
|
|
856 |
if ( count($options) && is_array($options) )
|
857 |
{
|
858 |
foreach ( $default_options as $key => $value )
|
859 |
{
|
860 |
if ( ! array_key_exists($key, $options) )
|
|
|
861 |
$options[$key] = $value;
|
|
|
|
|
862 |
}
|
863 |
}
|
864 |
|
865 |
-
|
|
|
866 |
|
867 |
return $options;
|
868 |
}
|
869 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
870 |
?>
|
101 |
'alias' => $current_user->display_name,
|
102 |
'wp_url' => get_bloginfo('wpurl'),
|
103 |
'li_version' => LEADIN_PLUGIN_VERSION,
|
104 |
+
'wp_version' => $wp_version,
|
105 |
+
'total_contacts' => get_total_contacts()
|
106 |
);
|
107 |
|
108 |
+
if ( defined('LEADIN_REFERRAL_SOURCE') )
|
109 |
+
$leadin_user['referral_source'] = LEADIN_REFERRAL_SOURCE;
|
110 |
+
else
|
111 |
+
$leadin_user['referral_source'] = '';
|
112 |
+
|
113 |
+
if ( defined('LEADIN_UTM_SOURCE') )
|
114 |
+
$leadin_user['utm_source'] = LEADIN_UTM_SOURCE;
|
115 |
+
else
|
116 |
+
$leadin_user['utm_source'] = '';
|
117 |
+
|
118 |
+
if ( defined('LEADIN_UTM_MEDIUM') )
|
119 |
+
$leadin_user['utm_medium'] = LEADIN_UTM_MEDIUM;
|
120 |
+
else
|
121 |
+
$leadin_user['utm_medium'] = '';
|
122 |
+
|
123 |
+
if ( defined('LEADIN_UTM_TERM') )
|
124 |
+
$leadin_user['utm_term'] = LEADIN_UTM_TERM;
|
125 |
+
else
|
126 |
+
$leadin_user['utm_term'] = '';
|
127 |
+
|
128 |
+
if ( defined('LEADIN_UTM_CONTENT') )
|
129 |
+
$leadin_user['utm_content'] = LEADIN_UTM_CONTENT;
|
130 |
+
else
|
131 |
+
$leadin_user['utm_content'] = '';
|
132 |
+
|
133 |
+
if ( defined('LEADIN_UTM_CAMPAIGN') )
|
134 |
+
$leadin_user['utm_campaign'] = LEADIN_UTM_CAMPAIGN;
|
135 |
+
else
|
136 |
+
$leadin_user['utm_campaign'] = '';
|
137 |
+
|
138 |
return $leadin_user;
|
139 |
}
|
140 |
|
141 |
/**
|
142 |
+
* Get list of traits converted for Segment
|
143 |
+
*
|
144 |
+
* @return array
|
145 |
+
*/
|
146 |
+
function leadin_get_segment_traits ()
|
147 |
+
{
|
148 |
+
$leadin_user = leadin_get_current_user();
|
149 |
+
$traits = array(
|
150 |
+
"name" => $leadin_user['alias'],
|
151 |
+
"email" => $leadin_user['email'],
|
152 |
+
"wp-url" => $leadin_user["wp_url"],
|
153 |
+
"wp-version" => $leadin_user["wp_version"],
|
154 |
+
"li-version" => $leadin_user["li_version"],
|
155 |
+
"li-source" => LEADIN_SOURCE,
|
156 |
+
"createdAt" => date("Y-m-d H:i:s"),
|
157 |
+
"website" => $leadin_user["wp_url"],
|
158 |
+
"company" => $leadin_user["wp_url"],
|
159 |
+
"contacts" => $leadin_user["total_contacts"],
|
160 |
+
"utm_source" => $leadin_user["utm_source"],
|
161 |
+
"utm_medium" => $leadin_user["utm_medium"],
|
162 |
+
"utm_term" => $leadin_user["utm_term"],
|
163 |
+
"utm_content" => $leadin_user["utm_content"],
|
164 |
+
"utm_campaign" => $leadin_user["utm_campaign"],
|
165 |
+
"referral_source" => $leadin_user["referral_source"]
|
166 |
+
);
|
167 |
+
|
168 |
+
return $traits;
|
169 |
+
}
|
170 |
+
|
171 |
+
|
172 |
+
|
173 |
+
|
174 |
+
/**
|
175 |
+
* Gets the total number of contacts, comments and subscribers for above the table
|
176 |
+
*/
|
177 |
+
function get_total_contacts ()
|
178 |
+
{
|
179 |
+
global $wpdb;
|
180 |
+
|
181 |
+
if ( ! isset($wpdb->li_leads) )
|
182 |
+
return 0;
|
183 |
+
|
184 |
+
$q = "
|
185 |
+
SELECT
|
186 |
+
COUNT(DISTINCT hashkey) AS total_contacts
|
187 |
+
FROM
|
188 |
+
$wpdb->li_leads
|
189 |
+
WHERE
|
190 |
+
lead_email != '' AND lead_deleted = 0 AND hashkey != ''";
|
191 |
+
|
192 |
+
$total_contacts = $wpdb->get_var($q);
|
193 |
+
return $total_contacts;
|
194 |
+
}
|
195 |
+
|
196 |
+
/**
|
197 |
+
* Register Leadin user
|
198 |
*
|
199 |
* @return bool
|
200 |
*/
|
201 |
+
function leadin_register_user ()
|
202 |
{
|
203 |
+
if ( ! leadin_check_pro_user() )
|
204 |
+
return FALSE;
|
205 |
+
|
206 |
+
if ( ! function_exists('curl_init') )
|
207 |
+
return FALSE;
|
208 |
|
209 |
$leadin_user = leadin_get_current_user();
|
210 |
+
$traits = leadin_get_segment_traits();
|
|
|
211 |
|
212 |
+
Segment::init(SEGMENT_WRITE_KEY);
|
213 |
+
|
214 |
+
Segment::identify(array(
|
215 |
+
"userId" => $leadin_user['user_id'],
|
216 |
+
"traits" => $traits
|
217 |
+
));
|
218 |
+
|
219 |
+
// Sync to email to MailChimp
|
220 |
$MailChimp = new LI_MailChimp(MC_KEY);
|
221 |
$contact_synced = $MailChimp->call("lists/subscribe", array(
|
222 |
"id" => 'c390aea726',
|
229 |
"merge_vars" => array('EMAIL' => $leadin_user['email'], 'WEBSITE' => get_site_url() )
|
230 |
));
|
231 |
|
232 |
+
return TRUE;
|
233 |
+
}
|
234 |
+
|
235 |
+
/**
|
236 |
+
* Set Premium propertey on Leadin user in Segment
|
237 |
+
*
|
238 |
+
* @return bool
|
239 |
+
*/
|
240 |
+
function leadin_set_user_properties ( $properties = array() )
|
241 |
+
{
|
242 |
+
if ( ! leadin_check_pro_user() )
|
243 |
+
return FALSE;
|
244 |
+
|
245 |
+
if ( ! function_exists('curl_init') )
|
246 |
+
return FALSE;
|
247 |
+
|
248 |
+
$leadin_user = leadin_get_current_user();
|
249 |
+
|
250 |
+
Segment::init(SEGMENT_WRITE_KEY);
|
251 |
+
|
252 |
+
Segment::identify(array(
|
253 |
+
"userId" => $leadin_user['user_id'],
|
254 |
+
"traits" => $properties
|
255 |
+
));
|
256 |
+
}
|
257 |
+
|
258 |
+
/**
|
259 |
+
* Send Mixpanel event when plugin is activated/deactivated
|
260 |
+
*
|
261 |
+
* @param bool
|
262 |
+
*
|
263 |
+
* @return bool
|
264 |
+
*/
|
265 |
+
function leadin_track_plugin_registration_hook ( $activated )
|
266 |
+
{
|
267 |
+
$properties = array();
|
268 |
+
|
269 |
+
if ( $activated )
|
270 |
+
{
|
271 |
+
leadin_register_user();
|
272 |
+
leadin_track_plugin_activity("Activated Plugin");
|
273 |
+
$properties["last_activated"] = date("Y-m-d H:i:s");
|
274 |
+
$properties["li-status"] = "activated";
|
275 |
+
}
|
276 |
+
else
|
277 |
+
{
|
278 |
+
leadin_track_plugin_activity("Deactivated Plugin");
|
279 |
+
$properties["last_deactivated"] = date("Y-m-d H:i:s");
|
280 |
+
$properties["li-status"] = "deactivated";
|
281 |
+
}
|
282 |
+
|
283 |
+
leadin_set_user_properties( $properties );
|
284 |
+
|
285 |
+
return TRUE;
|
286 |
+
}
|
287 |
+
|
288 |
+
/**
|
289 |
+
* Track plugin activity
|
290 |
+
*
|
291 |
+
* @param string
|
292 |
+
*
|
293 |
+
* @return array
|
294 |
+
*/
|
295 |
+
function leadin_track_plugin_activity ( $activity_desc, $custom_properties = array() )
|
296 |
+
{
|
297 |
+
if ( ! leadin_check_pro_user() )
|
298 |
+
return FALSE;
|
299 |
+
|
300 |
+
if ( ! function_exists('curl_init') )
|
301 |
+
return FALSE;
|
302 |
+
|
303 |
+
$leadin_user = leadin_get_current_user();
|
304 |
+
|
305 |
+
$default_properties = leadin_get_segment_traits();
|
306 |
+
$properties = array_merge((array)$default_properties, (array)$custom_properties);
|
307 |
+
|
308 |
+
Segment::init(SEGMENT_WRITE_KEY);
|
309 |
+
|
310 |
+
Segment::track(array(
|
311 |
+
'userId' => $leadin_user['user_id'],
|
312 |
+
'event' => $activity_desc,
|
313 |
+
'properties' => $properties
|
314 |
+
));
|
315 |
+
|
316 |
+
return TRUE;
|
317 |
}
|
318 |
|
319 |
/**
|
886 |
*/
|
887 |
function leadin_array_search_deep ( $needle, $array, $index )
|
888 |
{
|
889 |
+
foreach ( $array as $key => $val )
|
890 |
+
{
|
891 |
+
if ( $val[$index] == $needle )
|
892 |
+
return $key;
|
893 |
+
}
|
894 |
|
895 |
return NULL;
|
896 |
}
|
1015 |
return FALSE;
|
1016 |
}
|
1017 |
|
1018 |
+
function leadin_safe_social_profile_url ( $url )
|
1019 |
+
{
|
1020 |
+
$url = str_replace('∖', '/', $url);
|
1021 |
+
return $url;
|
1022 |
+
}
|
1023 |
+
|
1024 |
+
function leadin_check_missing_options ( $options )
|
1025 |
{
|
1026 |
$default_options = array(
|
1027 |
'li_installed' => 1,
|
1039 |
'names_added_to_contacts' => 1
|
1040 |
);
|
1041 |
|
1042 |
+
// Add the Pro flag if this is a pro installation
|
1043 |
+
if ( ( defined('LEADIN_UTM_SOURCE') && LEADIN_UTM_SOURCE != 'leadin%20repo%20plugin') || ! defined('LEADIN_UTM_SOURCE') )
|
1044 |
+
$default_options['pro'] = 1;
|
1045 |
+
|
1046 |
+
$update_option = FALSE;
|
1047 |
if ( count($options) && is_array($options) )
|
1048 |
{
|
1049 |
foreach ( $default_options as $key => $value )
|
1050 |
{
|
1051 |
if ( ! array_key_exists($key, $options) )
|
1052 |
+
{
|
1053 |
$options[$key] = $value;
|
1054 |
+
$update_option = TRUE;
|
1055 |
+
}
|
1056 |
}
|
1057 |
}
|
1058 |
|
1059 |
+
if ( $update_option )
|
1060 |
+
update_option('leadin_options', $options);
|
1061 |
|
1062 |
return $options;
|
1063 |
}
|
1064 |
|
1065 |
+
/**
|
1066 |
+
* Checks to see if an installation is Leadin Pro enabled
|
1067 |
+
*
|
1068 |
+
* @return bool
|
1069 |
+
*/
|
1070 |
+
function leadin_check_pro_user ( )
|
1071 |
+
{
|
1072 |
+
$options = get_option('leadin_options');
|
1073 |
+
if ( isset($options['pro']) && $options['pro'])
|
1074 |
+
return TRUE;
|
1075 |
+
else
|
1076 |
+
return FALSE;
|
1077 |
+
}
|
1078 |
+
|
1079 |
+
/**
|
1080 |
+
* Checks the first entry in the pageviews table
|
1081 |
+
*
|
1082 |
+
*/
|
1083 |
+
function leadin_check_first_pageview_data ( )
|
1084 |
+
{
|
1085 |
+
global $wpdb;
|
1086 |
+
|
1087 |
+
$q = "SELECT pageview_date FROM $wpdb->li_pageviews ORDER BY pageview_date ASC LIMIT 1";
|
1088 |
+
$date = $wpdb->get_var($q);
|
1089 |
+
|
1090 |
+
if ( $date )
|
1091 |
+
{
|
1092 |
+
if ( strtotime($date) < strtotime('-30 days') )
|
1093 |
+
return TRUE;
|
1094 |
+
else
|
1095 |
+
return FALSE;
|
1096 |
+
}
|
1097 |
+
else
|
1098 |
+
{
|
1099 |
+
return FALSE;
|
1100 |
+
}
|
1101 |
+
}
|
1102 |
+
|
1103 |
?>
|
leadin.php
CHANGED
@@ -3,7 +3,7 @@
|
|
3 |
Plugin Name: Leadin
|
4 |
Plugin URI: http://leadin.com
|
5 |
Description: Leadin is an easy-to-use marketing automation and lead tracking plugin for WordPress that helps you better understand your web site visitors.
|
6 |
-
Version:
|
7 |
Author: Andy Cook, Nelson Joyce
|
8 |
Author URI: http://leadin.com
|
9 |
License: GPL2
|
@@ -26,7 +26,13 @@ if ( !defined('LEADIN_DB_VERSION') )
|
|
26 |
define('LEADIN_DB_VERSION', '2.2.4');
|
27 |
|
28 |
if ( !defined('LEADIN_PLUGIN_VERSION') )
|
29 |
-
define('LEADIN_PLUGIN_VERSION', '
|
|
|
|
|
|
|
|
|
|
|
|
|
30 |
|
31 |
if ( !defined('MC_KEY') )
|
32 |
define('MC_KEY', '934aaed05049dde737d308be26167eef-us3');
|
@@ -38,18 +44,30 @@ if ( !defined('LEADIN_SOURCE') )
|
|
38 |
// Include Needed Files
|
39 |
//=============================================
|
40 |
|
|
|
|
|
|
|
41 |
require_once(LEADIN_PLUGIN_DIR . '/inc/leadin-ajax-functions.php');
|
42 |
require_once(LEADIN_PLUGIN_DIR . '/inc/leadin-functions.php');
|
43 |
require_once(LEADIN_PLUGIN_DIR . '/inc/class-emailer.php');
|
44 |
require_once(LEADIN_PLUGIN_DIR . '/inc/class-leadin-updater.php');
|
45 |
require_once(LEADIN_PLUGIN_DIR . '/admin/leadin-admin.php');
|
46 |
|
|
|
|
|
47 |
require_once(LEADIN_PLUGIN_DIR . '/inc/class-leadin.php');
|
48 |
|
49 |
require_once(LEADIN_PLUGIN_DIR . '/power-ups/subscribe-widget.php');
|
50 |
require_once(LEADIN_PLUGIN_DIR . '/power-ups/contacts.php');
|
51 |
require_once(LEADIN_PLUGIN_DIR . '/power-ups/mailchimp-connect.php');
|
52 |
require_once(LEADIN_PLUGIN_DIR . '/power-ups/constant-contact-connect.php');
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
53 |
|
54 |
//=============================================
|
55 |
// Hooks & Filters
|
@@ -78,6 +96,7 @@ function activate_leadin ( $network_wide )
|
|
78 |
switch_to_blog($blog_id);
|
79 |
add_leadin_defaults();
|
80 |
$activated[] = $blog_id;
|
|
|
81 |
}
|
82 |
|
83 |
// Switch back to the current blog
|
@@ -89,6 +108,7 @@ function activate_leadin ( $network_wide )
|
|
89 |
else
|
90 |
{
|
91 |
add_leadin_defaults();
|
|
|
92 |
}
|
93 |
}
|
94 |
|
@@ -105,7 +125,7 @@ function add_leadin_defaults ( )
|
|
105 |
{
|
106 |
$opt = array(
|
107 |
'li_installed' => 1,
|
108 |
-
'leadin_version'
|
109 |
'li_db_version' => LEADIN_DB_VERSION,
|
110 |
'li_email' => get_bloginfo('admin_email'),
|
111 |
'li_updates_subscription' => 1,
|
@@ -114,10 +134,15 @@ function add_leadin_defaults ( )
|
|
114 |
'ignore_settings_popup' => 0,
|
115 |
'data_recovered' => 1,
|
116 |
'delete_flags_fixed' => 1,
|
|
|
117 |
'converted_to_tags' => 1,
|
118 |
'names_added_to_contacts' => 1
|
119 |
);
|
120 |
-
|
|
|
|
|
|
|
|
|
121 |
// this is a hack because multisite doesn't recognize local options using either update_option or update_site_option...
|
122 |
if ( is_multisite() )
|
123 |
{
|
@@ -134,26 +159,55 @@ function add_leadin_defaults ( )
|
|
134 |
leadin_db_install();
|
135 |
|
136 |
$multisite_prefix = ( is_multisite() ? $wpdb->prefix : '' );
|
137 |
-
$q =
|
138 |
INSERT INTO " . $multisite_prefix . "li_tags
|
139 |
( tag_text, tag_slug, tag_form_selectors, tag_synced_lists, tag_order )
|
140 |
VALUES ('Commenters', 'commenters', '#commentform', '', 1),
|
141 |
('Leads', 'leads', '', '', 2),
|
142 |
('Contacted', 'contacted', '', '', 3),
|
143 |
-
('Customers', 'customers', '', '', 4)"
|
144 |
$wpdb->query($q);
|
145 |
}
|
146 |
|
147 |
$leadin_active_power_ups = get_option('leadin_active_power_ups');
|
148 |
|
149 |
-
if (
|
150 |
{
|
151 |
$auto_activate = array(
|
152 |
-
'contacts'
|
|
|
153 |
);
|
154 |
|
155 |
update_option('leadin_active_power_ups', serialize($auto_activate));
|
156 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
157 |
}
|
158 |
|
159 |
/**
|
@@ -174,11 +228,14 @@ function deactivate_leadin ( $network_wide )
|
|
174 |
foreach ( $blog_ids as $blog_id )
|
175 |
{
|
176 |
switch_to_blog($blog_id);
|
|
|
177 |
}
|
178 |
|
179 |
// Switch back to the current blog
|
180 |
switch_to_blog($current_blog);
|
181 |
}
|
|
|
|
|
182 |
}
|
183 |
|
184 |
function activate_leadin_on_new_blog ( $blog_id, $user_id, $domain, $path, $site_id, $meta )
|
3 |
Plugin Name: Leadin
|
4 |
Plugin URI: http://leadin.com
|
5 |
Description: Leadin is an easy-to-use marketing automation and lead tracking plugin for WordPress that helps you better understand your web site visitors.
|
6 |
+
Version: 3.1.4
|
7 |
Author: Andy Cook, Nelson Joyce
|
8 |
Author URI: http://leadin.com
|
9 |
License: GPL2
|
26 |
define('LEADIN_DB_VERSION', '2.2.4');
|
27 |
|
28 |
if ( !defined('LEADIN_PLUGIN_VERSION') )
|
29 |
+
define('LEADIN_PLUGIN_VERSION', '3.1.4');
|
30 |
+
|
31 |
+
if ( !defined('MIXPANEL_PROJECT_TOKEN') )
|
32 |
+
define('MIXPANEL_PROJECT_TOKEN', '2791b6942b57bbef2ba12b2452468253');
|
33 |
+
|
34 |
+
if ( !defined('SEGMENT_WRITE_KEY') )
|
35 |
+
define('SEGMENT_WRITE_KEY', 'fklilck6m2');
|
36 |
|
37 |
if ( !defined('MC_KEY') )
|
38 |
define('MC_KEY', '934aaed05049dde737d308be26167eef-us3');
|
44 |
// Include Needed Files
|
45 |
//=============================================
|
46 |
|
47 |
+
if ( file_exists(LEADIN_PLUGIN_DIR . '/inc/leadin-constants.php') )
|
48 |
+
include_once(LEADIN_PLUGIN_DIR . '/inc/leadin-constants.php');
|
49 |
+
|
50 |
require_once(LEADIN_PLUGIN_DIR . '/inc/leadin-ajax-functions.php');
|
51 |
require_once(LEADIN_PLUGIN_DIR . '/inc/leadin-functions.php');
|
52 |
require_once(LEADIN_PLUGIN_DIR . '/inc/class-emailer.php');
|
53 |
require_once(LEADIN_PLUGIN_DIR . '/inc/class-leadin-updater.php');
|
54 |
require_once(LEADIN_PLUGIN_DIR . '/admin/leadin-admin.php');
|
55 |
|
56 |
+
require_once(LEADIN_PLUGIN_DIR . '/lib/mixpanel/LI_Mixpanel.php');
|
57 |
+
require_once(LEADIN_PLUGIN_DIR . '/lib/segment/lib/Segment.php');
|
58 |
require_once(LEADIN_PLUGIN_DIR . '/inc/class-leadin.php');
|
59 |
|
60 |
require_once(LEADIN_PLUGIN_DIR . '/power-ups/subscribe-widget.php');
|
61 |
require_once(LEADIN_PLUGIN_DIR . '/power-ups/contacts.php');
|
62 |
require_once(LEADIN_PLUGIN_DIR . '/power-ups/mailchimp-connect.php');
|
63 |
require_once(LEADIN_PLUGIN_DIR . '/power-ups/constant-contact-connect.php');
|
64 |
+
require_once(LEADIN_PLUGIN_DIR . '/power-ups/aweber-connect.php');
|
65 |
+
require_once(LEADIN_PLUGIN_DIR . '/power-ups/campaign-monitor-connect.php');
|
66 |
+
require_once(LEADIN_PLUGIN_DIR . '/power-ups/getresponse-connect.php');
|
67 |
+
require_once(LEADIN_PLUGIN_DIR . '/power-ups/beta-program.php');
|
68 |
+
require_once(LEADIN_PLUGIN_DIR . '/power-ups/lookups.php');
|
69 |
+
|
70 |
+
|
71 |
|
72 |
//=============================================
|
73 |
// Hooks & Filters
|
96 |
switch_to_blog($blog_id);
|
97 |
add_leadin_defaults();
|
98 |
$activated[] = $blog_id;
|
99 |
+
leadin_track_plugin_registration_hook(TRUE);
|
100 |
}
|
101 |
|
102 |
// Switch back to the current blog
|
108 |
else
|
109 |
{
|
110 |
add_leadin_defaults();
|
111 |
+
leadin_track_plugin_registration_hook(TRUE);
|
112 |
}
|
113 |
}
|
114 |
|
125 |
{
|
126 |
$opt = array(
|
127 |
'li_installed' => 1,
|
128 |
+
'leadin_version' => LEADIN_PLUGIN_VERSION,
|
129 |
'li_db_version' => LEADIN_DB_VERSION,
|
130 |
'li_email' => get_bloginfo('admin_email'),
|
131 |
'li_updates_subscription' => 1,
|
134 |
'ignore_settings_popup' => 0,
|
135 |
'data_recovered' => 1,
|
136 |
'delete_flags_fixed' => 1,
|
137 |
+
'beta_tester' => 0,
|
138 |
'converted_to_tags' => 1,
|
139 |
'names_added_to_contacts' => 1
|
140 |
);
|
141 |
+
|
142 |
+
// Add the Pro flag if this is a pro installation
|
143 |
+
if ( ( defined('LEADIN_UTM_SOURCE') && LEADIN_UTM_SOURCE != 'leadin%20repo%20plugin' ) || ! defined('LEADIN_UTM_SOURCE') )
|
144 |
+
$opt['pro'] = 1;
|
145 |
+
|
146 |
// this is a hack because multisite doesn't recognize local options using either update_option or update_site_option...
|
147 |
if ( is_multisite() )
|
148 |
{
|
159 |
leadin_db_install();
|
160 |
|
161 |
$multisite_prefix = ( is_multisite() ? $wpdb->prefix : '' );
|
162 |
+
$q = "
|
163 |
INSERT INTO " . $multisite_prefix . "li_tags
|
164 |
( tag_text, tag_slug, tag_form_selectors, tag_synced_lists, tag_order )
|
165 |
VALUES ('Commenters', 'commenters', '#commentform', '', 1),
|
166 |
('Leads', 'leads', '', '', 2),
|
167 |
('Contacted', 'contacted', '', '', 3),
|
168 |
+
('Customers', 'customers', '', '', 4)";
|
169 |
$wpdb->query($q);
|
170 |
}
|
171 |
|
172 |
$leadin_active_power_ups = get_option('leadin_active_power_ups');
|
173 |
|
174 |
+
if ( ! $leadin_active_power_ups )
|
175 |
{
|
176 |
$auto_activate = array(
|
177 |
+
'contacts',
|
178 |
+
'lookups' // 3.1.4 change - auto activating this power-up and using the Pro flag to toggle on/off
|
179 |
);
|
180 |
|
181 |
update_option('leadin_active_power_ups', serialize($auto_activate));
|
182 |
}
|
183 |
+
|
184 |
+
setcookie ( "ignore_social_share" , "1", 2592000, "/" );
|
185 |
+
|
186 |
+
// This is in here because Segment doesn't have register_once, so it's in a method that's only called once
|
187 |
+
if ( leadin_check_pro_user() )
|
188 |
+
{
|
189 |
+
$traits = array();
|
190 |
+
|
191 |
+
if ( defined('LEADIN_REFERRAL_SOURCE') )
|
192 |
+
$traits['referral_source'] = LEADIN_REFERRAL_SOURCE;
|
193 |
+
|
194 |
+
if ( defined('LEADIN_UTM_SOURCE') )
|
195 |
+
$traits['utm_source'] = LEADIN_UTM_SOURCE;
|
196 |
+
|
197 |
+
if ( defined('LEADIN_UTM_MEDIUM') )
|
198 |
+
$traits['utm_medium'] = LEADIN_UTM_MEDIUM;
|
199 |
+
|
200 |
+
if ( defined('LEADIN_UTM_TERM') )
|
201 |
+
$traits['utm_term'] = LEADIN_UTM_TERM;
|
202 |
+
|
203 |
+
if ( defined('LEADIN_UTM_CONTENT') )
|
204 |
+
$traits['utm_content'] = LEADIN_UTM_CONTENT;
|
205 |
+
|
206 |
+
if ( defined('LEADIN_UTM_CAMPAIGN') )
|
207 |
+
$traits['utm_campaign'] = LEADIN_UTM_CAMPAIGN;
|
208 |
+
|
209 |
+
leadin_set_user_properties($traits);
|
210 |
+
}
|
211 |
}
|
212 |
|
213 |
/**
|
228 |
foreach ( $blog_ids as $blog_id )
|
229 |
{
|
230 |
switch_to_blog($blog_id);
|
231 |
+
leadin_track_plugin_registration_hook(FALSE);
|
232 |
}
|
233 |
|
234 |
// Switch back to the current blog
|
235 |
switch_to_blog($current_blog);
|
236 |
}
|
237 |
+
else
|
238 |
+
leadin_track_plugin_registration_hook(FALSE);
|
239 |
}
|
240 |
|
241 |
function activate_leadin_on_new_blog ( $blog_id, $user_id, $domain, $path, $site_id, $meta )
|
lib/mixpanel/Base/LI_MixpanelBase.php
ADDED
@@ -0,0 +1,68 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* This a Base class which all Mixpanel classes extend from to provide some very basic
|
5 |
+
* debugging and logging functionality. It also serves to persist $_options across the library.
|
6 |
+
*
|
7 |
+
*/
|
8 |
+
|
9 |
+
|
10 |
+
|
11 |
+
class LI_Base_MixpanelBase {
|
12 |
+
|
13 |
+
|
14 |
+
/**
|
15 |
+
* Default options that can be overridden via the $options constructor arg
|
16 |
+
* @var array
|
17 |
+
*/
|
18 |
+
private $_defaults = array(
|
19 |
+
"max_batch_size" => 50, // the max batch size Mixpanel will accept is 50,
|
20 |
+
"max_queue_size" => 1000, // the max num of items to hold in memory before flushing
|
21 |
+
"debug" => false, // enable/disable debug mode
|
22 |
+
"consumer" => "curl", // which consumer to use
|
23 |
+
"host" => "api.mixpanel.com", // the host name for api calls
|
24 |
+
"events_endpoint" => "/track", // host relative endpoint for events
|
25 |
+
"people_endpoint" => "/engage", // host relative endpoint for people updates
|
26 |
+
"use_ssl" => true, // use ssl when available
|
27 |
+
"error_callback" => null // callback to use on consumption failures
|
28 |
+
);
|
29 |
+
|
30 |
+
|
31 |
+
/**
|
32 |
+
* An array of options to be used by the Mixpanel library.
|
33 |
+
* @var array
|
34 |
+
*/
|
35 |
+
protected $_options = array();
|
36 |
+
|
37 |
+
|
38 |
+
/**
|
39 |
+
* Construct a new MixpanelBase object and merge custom options with defaults
|
40 |
+
* @param array $options
|
41 |
+
*/
|
42 |
+
public function __construct($options = array()) {
|
43 |
+
$options = array_merge($this->_defaults, $options);
|
44 |
+
$this->_options = $options;
|
45 |
+
}
|
46 |
+
|
47 |
+
|
48 |
+
/**
|
49 |
+
* Log a message to PHP's error log
|
50 |
+
* @param $msg
|
51 |
+
*/
|
52 |
+
protected function _log($msg) {
|
53 |
+
$arr = debug_backtrace();
|
54 |
+
$class = $arr[0]['class'];
|
55 |
+
$line = $arr[0]['line'];
|
56 |
+
error_log ( "[ $class - line $line ] : " . $msg );
|
57 |
+
}
|
58 |
+
|
59 |
+
|
60 |
+
/**
|
61 |
+
* Returns true if in debug mode, false if in production mode
|
62 |
+
* @return bool
|
63 |
+
*/
|
64 |
+
protected function _debug() {
|
65 |
+
return array_key_exists("debug", $this->_options) && $this->_options["debug"] == true;
|
66 |
+
}
|
67 |
+
|
68 |
+
}
|
lib/mixpanel/ConsumerStrategies/LI_AbstractConsumer.php
ADDED
@@ -0,0 +1,58 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
require_once(dirname(__FILE__) . "/../Base/LI_MixpanelBase.php");
|
4 |
+
|
5 |
+
/**
|
6 |
+
* Provides some base methods for use by a Consumer implementation
|
7 |
+
*/
|
8 |
+
abstract class LI_ConsumerStrategies_AbstractConsumer extends LI_Base_MixpanelBase {
|
9 |
+
|
10 |
+
/**
|
11 |
+
* Creates a new AbstractConsumer
|
12 |
+
* @param array $options
|
13 |
+
*/
|
14 |
+
function __construct($options = array()) {
|
15 |
+
|
16 |
+
parent::__construct($options);
|
17 |
+
|
18 |
+
if ($this->_debug()) {
|
19 |
+
$this->_log("Instantiated new Consumer");
|
20 |
+
}
|
21 |
+
|
22 |
+
}
|
23 |
+
|
24 |
+
/**
|
25 |
+
* Encode an array to be persisted
|
26 |
+
* @param array $params
|
27 |
+
* @return string
|
28 |
+
*/
|
29 |
+
protected function _encode($params) {
|
30 |
+
return base64_encode(json_encode($params));
|
31 |
+
}
|
32 |
+
|
33 |
+
/**
|
34 |
+
* Handles errors that occur in a consumer
|
35 |
+
* @param $code
|
36 |
+
* @param $msg
|
37 |
+
*/
|
38 |
+
protected function _handleError($code, $msg) {
|
39 |
+
if (isset($this->_options['error_callback'])) {
|
40 |
+
$handler = $this->_options['error_callback'];
|
41 |
+
call_user_func($handler, $code, $msg);
|
42 |
+
}
|
43 |
+
|
44 |
+
if ($this->_debug()) {
|
45 |
+
$arr = debug_backtrace();
|
46 |
+
$class = get_class($arr[0]['object']);
|
47 |
+
$line = $arr[0]['line'];
|
48 |
+
error_log ( "[ $class - line $line ] : " . print_r($msg, true) );
|
49 |
+
}
|
50 |
+
}
|
51 |
+
|
52 |
+
/**
|
53 |
+
* Persist a batch of messages in whatever way the implementer sees fit
|
54 |
+
* @param array $batch an array of messages to consume
|
55 |
+
* @return boolean success or fail
|
56 |
+
*/
|
57 |
+
abstract function persist($batch);
|
58 |
+
}
|
lib/mixpanel/ConsumerStrategies/LI_CurlConsumer.php
ADDED
@@ -0,0 +1,222 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
require_once(dirname(__FILE__) . "/LI_AbstractConsumer.php");
|
4 |
+
|
5 |
+
/**
|
6 |
+
* Consumes messages and sends them to a host/endpoint using cURL
|
7 |
+
*/
|
8 |
+
class LI_ConsumerStrategies_CurlConsumer extends LI_ConsumerStrategies_AbstractConsumer {
|
9 |
+
|
10 |
+
/**
|
11 |
+
* @var string the host to connect to (e.g. api.mixpanel.com)
|
12 |
+
*/
|
13 |
+
protected $_host;
|
14 |
+
|
15 |
+
|
16 |
+
/**
|
17 |
+
* @var string the host-relative endpoint to write to (e.g. /engage)
|
18 |
+
*/
|
19 |
+
protected $_endpoint;
|
20 |
+
|
21 |
+
|
22 |
+
/**
|
23 |
+
* @var int connect_timeout The number of seconds to wait while trying to connect. Default is 5 seconds.
|
24 |
+
*/
|
25 |
+
protected $_connect_timeout;
|
26 |
+
|
27 |
+
|
28 |
+
/**
|
29 |
+
* @var int timeout The maximum number of seconds to allow cURL call to execute. Default is 30 seconds.
|
30 |
+
*/
|
31 |
+
protected $_timeout;
|
32 |
+
|
33 |
+
|
34 |
+
/**
|
35 |
+
* @var string the protocol to use for the cURL connection
|
36 |
+
*/
|
37 |
+
protected $_protocol;
|
38 |
+
|
39 |
+
|
40 |
+
/**
|
41 |
+
* @var bool|null true to fork the cURL process (using exec) or false to use PHP's cURL extension. false by default
|
42 |
+
*/
|
43 |
+
protected $_fork = null;
|
44 |
+
|
45 |
+
|
46 |
+
/**
|
47 |
+
* Creates a new LI_CurlConsumer and assigns properties from the $options array
|
48 |
+
* @param array $options
|
49 |
+
* @throws Exception
|
50 |
+
*/
|
51 |
+
function __construct($options) {
|
52 |
+
parent::__construct($options);
|
53 |
+
|
54 |
+
$this->_host = $options['host'];
|
55 |
+
$this->_endpoint = $options['endpoint'];
|
56 |
+
$this->_connect_timeout = array_key_exists('connect_timeout', $options) ? $options['connect_timeout'] : 5;
|
57 |
+
$this->_timeout = array_key_exists('timeout', $options) ? $options['timeout'] : 30;
|
58 |
+
$this->_protocol = array_key_exists('use_ssl', $options) && $options['use_ssl'] == true ? "https" : "http";
|
59 |
+
$this->_fork = array_key_exists('fork', $options) ? ($options['fork'] == true) : false;
|
60 |
+
|
61 |
+
// ensure the environment is workable for the given settings
|
62 |
+
/*if ($this->_fork == true) {
|
63 |
+
$exists = function_exists('exec');
|
64 |
+
if (!$exists) {
|
65 |
+
throw new Exception('The "exec" function must exist to use the cURL consumer in "fork" mode. Try setting fork = false or use another consumer.');
|
66 |
+
}
|
67 |
+
$disabled = explode(', ', ini_get('disable_functions'));
|
68 |
+
$enabled = !in_array('exec', $disabled);
|
69 |
+
if (!$enabled) {
|
70 |
+
throw new Exception('The "exec" function must be enabled to use the cURL consumer in "fork" mode. Try setting fork = false or use another consumer.');
|
71 |
+
}
|
72 |
+
} else {
|
73 |
+
if (!function_exists('curl_init')) {
|
74 |
+
throw new Exception('The cURL PHP extension is required to use the cURL consumer with fork = false. Try setting fork = true or use another consumer.');
|
75 |
+
}
|
76 |
+
}*/
|
77 |
+
}
|
78 |
+
|
79 |
+
|
80 |
+
/**
|
81 |
+
* Write to the given host/endpoint using either a forked cURL process or using PHP's cURL extension
|
82 |
+
* @param array $batch
|
83 |
+
* @return bool
|
84 |
+
*/
|
85 |
+
public function persist($batch) {
|
86 |
+
if (count($batch) > 0) {
|
87 |
+
$data = "data=" . $this->_encode($batch);
|
88 |
+
$url = $this->_protocol . "://" . $this->_host . $this->_endpoint;
|
89 |
+
if ($this->_fork) {
|
90 |
+
return $this->_execute_forked($url, $data);
|
91 |
+
} else {
|
92 |
+
return $this->_execute($url, $data);
|
93 |
+
}
|
94 |
+
} else {
|
95 |
+
return true;
|
96 |
+
}
|
97 |
+
}
|
98 |
+
|
99 |
+
|
100 |
+
/**
|
101 |
+
* Write using the cURL php extension
|
102 |
+
* @param $url
|
103 |
+
* @param $data
|
104 |
+
* @return bool
|
105 |
+
*/
|
106 |
+
protected function _execute($url, $data) {
|
107 |
+
if ($this->_debug()) {
|
108 |
+
$this->_log("Making blocking cURL call to $url");
|
109 |
+
}
|
110 |
+
|
111 |
+
$ch = curl_init();
|
112 |
+
curl_setopt($ch, CURLOPT_URL, $url);
|
113 |
+
curl_setopt($ch, CURLOPT_HEADER, 0);
|
114 |
+
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $this->_connect_timeout);
|
115 |
+
curl_setopt($ch, CURLOPT_TIMEOUT, $this->_timeout);
|
116 |
+
curl_setopt($ch, CURLOPT_POST, 1);
|
117 |
+
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
|
118 |
+
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
|
119 |
+
$response = curl_exec($ch);
|
120 |
+
if (false === $response) {
|
121 |
+
$curl_error = curl_error($ch);
|
122 |
+
$curl_errno = curl_errno($ch);
|
123 |
+
curl_close($ch);
|
124 |
+
$this->_handleError($curl_errno, $curl_error);
|
125 |
+
return false;
|
126 |
+
} else {
|
127 |
+
curl_close($ch);
|
128 |
+
if (trim($response) == "1") {
|
129 |
+
return true;
|
130 |
+
} else {
|
131 |
+
$this->_handleError(0, $response);
|
132 |
+
return false;
|
133 |
+
}
|
134 |
+
}
|
135 |
+
}
|
136 |
+
|
137 |
+
|
138 |
+
/**
|
139 |
+
* Write using a forked cURL process
|
140 |
+
* @param $url
|
141 |
+
* @param $data
|
142 |
+
* @return bool
|
143 |
+
*/
|
144 |
+
protected function _execute_forked($url, $data) {
|
145 |
+
|
146 |
+
if ($this->_debug()) {
|
147 |
+
$this->_log("Making forked cURL call to $url");
|
148 |
+
}
|
149 |
+
|
150 |
+
$exec = 'curl -X POST -H "Content-Type: application/x-www-form-urlencoded" -d ' . $data . ' "' . $url . '"';
|
151 |
+
|
152 |
+
if(!$this->_debug()) {
|
153 |
+
$exec .= " >/dev/null 2>&1 &";
|
154 |
+
}
|
155 |
+
|
156 |
+
exec($exec, $output, $return_var);
|
157 |
+
|
158 |
+
if ($return_var != 0) {
|
159 |
+
$this->_handleError($return_var, $output);
|
160 |
+
}
|
161 |
+
|
162 |
+
return $return_var == 0;
|
163 |
+
}
|
164 |
+
|
165 |
+
/**
|
166 |
+
* @return int
|
167 |
+
*/
|
168 |
+
public function getConnectTimeout()
|
169 |
+
{
|
170 |
+
return $this->_connect_timeout;
|
171 |
+
}
|
172 |
+
|
173 |
+
/**
|
174 |
+
* @return string
|
175 |
+
*/
|
176 |
+
public function getEndpoint()
|
177 |
+
{
|
178 |
+
return $this->_endpoint;
|
179 |
+
}
|
180 |
+
|
181 |
+
/**
|
182 |
+
* @return bool|null
|
183 |
+
*/
|
184 |
+
public function getFork()
|
185 |
+
{
|
186 |
+
return $this->_fork;
|
187 |
+
}
|
188 |
+
|
189 |
+
/**
|
190 |
+
* @return string
|
191 |
+
*/
|
192 |
+
public function getHost()
|
193 |
+
{
|
194 |
+
return $this->_host;
|
195 |
+
}
|
196 |
+
|
197 |
+
/**
|
198 |
+
* @return array
|
199 |
+
*/
|
200 |
+
public function getOptions()
|
201 |
+
{
|
202 |
+
return $this->_options;
|
203 |
+
}
|
204 |
+
|
205 |
+
/**
|
206 |
+
* @return string
|
207 |
+
*/
|
208 |
+
public function getProtocol()
|
209 |
+
{
|
210 |
+
return $this->_protocol;
|
211 |
+
}
|
212 |
+
|
213 |
+
/**
|
214 |
+
* @return int
|
215 |
+
*/
|
216 |
+
public function getTimeout()
|
217 |
+
{
|
218 |
+
return $this->_timeout;
|
219 |
+
}
|
220 |
+
|
221 |
+
|
222 |
+
}
|
lib/mixpanel/ConsumerStrategies/LI_FileConsumer.php
ADDED
@@ -0,0 +1,39 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
require_once(dirname(__FILE__) . "/LI_AbstractConsumer.php");
|
4 |
+
/**
|
5 |
+
* Consumes messages and writes them to a file
|
6 |
+
*/
|
7 |
+
class ConsumerStrategies_LI_FileConsumer extends LI_ConsumerStrategies_AbstractConsumer {
|
8 |
+
|
9 |
+
/**
|
10 |
+
* @var string path to a file that we want to write the messages to
|
11 |
+
*/
|
12 |
+
private $_file;
|
13 |
+
|
14 |
+
|
15 |
+
/**
|
16 |
+
* Creates a new LI_FileConsumer and assigns properties from the $options array
|
17 |
+
* @param array $options
|
18 |
+
*/
|
19 |
+
function __construct($options) {
|
20 |
+
parent::__construct($options);
|
21 |
+
|
22 |
+
// what file to write to?
|
23 |
+
$this->_file = array_key_exists("file", $options) ? $options['file'] : dirname(__FILE__)."/../../messages.txt";
|
24 |
+
}
|
25 |
+
|
26 |
+
|
27 |
+
/**
|
28 |
+
* Append $batch to a file
|
29 |
+
* @param array $batch
|
30 |
+
* @return bool
|
31 |
+
*/
|
32 |
+
public function persist($batch) {
|
33 |
+
if (count($batch) > 0) {
|
34 |
+
return file_put_contents($this->_file, json_encode($batch)."\n", FILE_APPEND | LOCK_EX) !== false;
|
35 |
+
} else {
|
36 |
+
return true;
|
37 |
+
}
|
38 |
+
}
|
39 |
+
}
|
lib/mixpanel/ConsumerStrategies/LI_SocketConsumer.php
ADDED
@@ -0,0 +1,309 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Portions of this class were borrowed from
|
4 |
+
* https://github.com/segmentio/analytics-php/blob/master/lib/Analytics/Consumer/Socket.php.
|
5 |
+
* Thanks for the work!
|
6 |
+
*
|
7 |
+
* WWWWWW||WWWWWW
|
8 |
+
* W W W||W W W
|
9 |
+
* ||
|
10 |
+
* ( OO )__________
|
11 |
+
* / | \
|
12 |
+
* /o o| MIT \
|
13 |
+
* \___/||_||__||_|| *
|
14 |
+
* || || || ||
|
15 |
+
* _||_|| _||_||
|
16 |
+
* (__|__|(__|__|
|
17 |
+
* (The MIT License)
|
18 |
+
*
|
19 |
+
* Copyright (c) 2013 Segment.io Inc. friends@segment.io
|
20 |
+
*
|
21 |
+
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
|
22 |
+
* documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the
|
23 |
+
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
|
24 |
+
* permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
25 |
+
*
|
26 |
+
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the
|
27 |
+
* Software.
|
28 |
+
*
|
29 |
+
* THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
|
30 |
+
* WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
|
31 |
+
* OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
32 |
+
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
33 |
+
*/
|
34 |
+
|
35 |
+
require_once(dirname(__FILE__) . "/LI_AbstractConsumer.php");
|
36 |
+
|
37 |
+
/**
|
38 |
+
* Consumes messages and writes them to host/endpoint using a persistent socket
|
39 |
+
*/
|
40 |
+
class LI_ConsumerStrategies_SocketConsumer extends LI_ConsumerStrategies_AbstractConsumer {
|
41 |
+
|
42 |
+
/**
|
43 |
+
* @var string the host to connect to (e.g. api.mixpanel.com)
|
44 |
+
*/
|
45 |
+
private $_host;
|
46 |
+
|
47 |
+
|
48 |
+
/**
|
49 |
+
* @var string the host-relative endpoint to write to (e.g. /engage)
|
50 |
+
*/
|
51 |
+
private $_endpoint;
|
52 |
+
|
53 |
+
|
54 |
+
/**
|
55 |
+
* @var int connect_timeout the socket connection timeout in seconds
|
56 |
+
*/
|
57 |
+
private $_connect_timeout;
|
58 |
+
|
59 |
+
|
60 |
+
/**
|
61 |
+
* @var string the protocol to use for the socket connection
|
62 |
+
*/
|
63 |
+
private $_protocol;
|
64 |
+
|
65 |
+
|
66 |
+
/**
|
67 |
+
* @var resource holds the socket resource
|
68 |
+
*/
|
69 |
+
private $_socket;
|
70 |
+
|
71 |
+
/**
|
72 |
+
* @var bool whether or not to wait for a response
|
73 |
+
*/
|
74 |
+
private $_async;
|
75 |
+
|
76 |
+
|
77 |
+
/**
|
78 |
+
* Creates a new SocketConsumer and assigns properties from the $options array
|
79 |
+
* @param array $options
|
80 |
+
*/
|
81 |
+
public function __construct($options = array()) {
|
82 |
+
parent::__construct($options);
|
83 |
+
|
84 |
+
|
85 |
+
$this->_host = $options['host'];
|
86 |
+
$this->_endpoint = $options['endpoint'];
|
87 |
+
$this->_connect_timeout = array_key_exists('connect_timeout', $options) ? $options['connect_timeout'] : 5;
|
88 |
+
$this->_async = array_key_exists('async', $options) && $options['async'] === false ? false : true;
|
89 |
+
|
90 |
+
if (array_key_exists('use_ssl', $options) && $options['use_ssl'] == true) {
|
91 |
+
$this->_protocol = "ssl";
|
92 |
+
$this->_port = 443;
|
93 |
+
} else {
|
94 |
+
$this->_protocol = "tcp";
|
95 |
+
$this->_port = 80;
|
96 |
+
}
|
97 |
+
}
|
98 |
+
|
99 |
+
|
100 |
+
/**
|
101 |
+
* Write using a persistent socket connection.
|
102 |
+
* @param array $batch
|
103 |
+
* @return bool
|
104 |
+
*/
|
105 |
+
public function persist($batch) {
|
106 |
+
|
107 |
+
$socket = $this->_getSocket();
|
108 |
+
if (!is_resource($socket)) {
|
109 |
+
return false;
|
110 |
+
}
|
111 |
+
|
112 |
+
$data = "data=".$this->_encode($batch);
|
113 |
+
|
114 |
+
$body = "";
|
115 |
+
$body.= "POST ".$this->_endpoint." HTTP/1.1\r\n";
|
116 |
+
$body.= "Host: " . $this->_host . "\r\n";
|
117 |
+
$body.= "Content-Type: application/x-www-form-urlencoded\r\n";
|
118 |
+
$body.= "Accept: application/json\r\n";
|
119 |
+
$body.= "Content-length: " . strlen($data) . "\r\n";
|
120 |
+
$body.= "\r\n";
|
121 |
+
$body.= $data;
|
122 |
+
|
123 |
+
return $this->_write($socket, $body);
|
124 |
+
}
|
125 |
+
|
126 |
+
|
127 |
+
/**
|
128 |
+
* Return cached socket if open or create a new persistent socket
|
129 |
+
* @return bool|resource
|
130 |
+
*/
|
131 |
+
private function _getSocket() {
|
132 |
+
if(is_resource($this->_socket)) {
|
133 |
+
|
134 |
+
if ($this->_debug()) {
|
135 |
+
$this->_log("Using existing socket");
|
136 |
+
}
|
137 |
+
|
138 |
+
return $this->_socket;
|
139 |
+
} else {
|
140 |
+
|
141 |
+
if ($this->_debug()) {
|
142 |
+
$this->_log("Creating new socket at ".time());
|
143 |
+
}
|
144 |
+
|
145 |
+
return $this->_createSocket();
|
146 |
+
}
|
147 |
+
}
|
148 |
+
|
149 |
+
/**
|
150 |
+
* Attempt to open a new socket connection, cache it, and return the resource
|
151 |
+
* @param bool $retry
|
152 |
+
* @return bool|resource
|
153 |
+
*/
|
154 |
+
private function _createSocket($retry = true) {
|
155 |
+
try {
|
156 |
+
$socket = pfsockopen($this->_protocol . "://" . $this->_host, $this->_port, $err_no, $err_msg, $this->_connect_timeout);
|
157 |
+
|
158 |
+
if ($this->_debug()) {
|
159 |
+
$this->_log("Opening socket connection to " . $this->_protocol . "://" . $this->_host . ":" . $this->_port);
|
160 |
+
}
|
161 |
+
|
162 |
+
if ($err_no != 0) {
|
163 |
+
$this->_handleError($err_no, $err_msg);
|
164 |
+
return $retry == true ? $this->_createSocket(false) : false;
|
165 |
+
} else {
|
166 |
+
// cache the socket
|
167 |
+
$this->_socket = $socket;
|
168 |
+
return $socket;
|
169 |
+
}
|
170 |
+
|
171 |
+
} catch (Exception $e) {
|
172 |
+
$this->_handleError($e->getCode(), $e->getMessage());
|
173 |
+
return $retry == true ? $this->_createSocket(false) : false;
|
174 |
+
}
|
175 |
+
}
|
176 |
+
|
177 |
+
/**
|
178 |
+
* Attempt to close and dereference a socket resource
|
179 |
+
*/
|
180 |
+
private function _destroySocket() {
|
181 |
+
$socket = $this->_socket;
|
182 |
+
$this->_socket = null;
|
183 |
+
fclose($socket);
|
184 |
+
}
|
185 |
+
|
186 |
+
|
187 |
+
/**
|
188 |
+
* Write $data through the given $socket
|
189 |
+
* @param $socket
|
190 |
+
* @param $data
|
191 |
+
* @param bool $retry
|
192 |
+
* @return bool
|
193 |
+
*/
|
194 |
+
private function _write($socket, $data, $retry = true) {
|
195 |
+
|
196 |
+
$bytes_sent = 0;
|
197 |
+
$bytes_total = strlen($data);
|
198 |
+
$socket_closed = false;
|
199 |
+
$success = true;
|
200 |
+
$max_bytes_per_write = 8192;
|
201 |
+
|
202 |
+
// if we have no data to write just return true
|
203 |
+
if ($bytes_total == 0) {
|
204 |
+
return true;
|
205 |
+
}
|
206 |
+
|
207 |
+
// try to write the data
|
208 |
+
while (!$socket_closed && $bytes_sent < $bytes_total) {
|
209 |
+
|
210 |
+
try {
|
211 |
+
$bytes = fwrite($socket, $data, $max_bytes_per_write);
|
212 |
+
|
213 |
+
if ($this->_debug()) {
|
214 |
+
$this->_log("Socket wrote ".$bytes." bytes");
|
215 |
+
}
|
216 |
+
|
217 |
+
// if we actually wrote data, then remove the written portion from $data left to write
|
218 |
+
if ($bytes > 0) {
|
219 |
+
$data = substr($data, $max_bytes_per_write);
|
220 |
+
}
|
221 |
+
|
222 |
+
} catch (Exception $e) {
|
223 |
+
$this->_handleError($e->getCode(), $e->getMessage());
|
224 |
+
$socket_closed = true;
|
225 |
+
}
|
226 |
+
|
227 |
+
if (isset($bytes) && $bytes) {
|
228 |
+
$bytes_sent += $bytes;
|
229 |
+
} else {
|
230 |
+
$socket_closed = true;
|
231 |
+
}
|
232 |
+
}
|
233 |
+
|
234 |
+
// create a new socket if the current one is closed and retry the message
|
235 |
+
if ($socket_closed) {
|
236 |
+
|
237 |
+
$this->_destroySocket();
|
238 |
+
|
239 |
+
if ($retry) {
|
240 |
+
if ($this->_debug()) {
|
241 |
+
$this->_log("Retrying socket write...");
|
242 |
+
}
|
243 |
+
$socket = $this->_getSocket();
|
244 |
+
if ($socket) return $this->_write($socket, $data, false);
|
245 |
+
}
|
246 |
+
|
247 |
+
return false;
|
248 |
+
}
|
249 |
+
|
250 |
+
|
251 |
+
// only wait for the response in debug mode or if we explicitly want to be synchronous
|
252 |
+
if ($this->_debug() || !$this->_async) {
|
253 |
+
$res = $this->handleResponse(fread($socket, 2048));
|
254 |
+
if ($res["status"] != "200") {
|
255 |
+
$this->_handleError($res["status"], $res["body"]);
|
256 |
+
$success = false;
|
257 |
+
}
|
258 |
+
}
|
259 |
+
|
260 |
+
return $success;
|
261 |
+
}
|
262 |
+
|
263 |
+
|
264 |
+
/**
|
265 |
+
* Parse the response from a socket write (only used for debugging)
|
266 |
+
* @param $response
|
267 |
+
* @return array
|
268 |
+
*/
|
269 |
+
private function handleResponse($response) {
|
270 |
+
|
271 |
+
$lines = explode("\n", $response);
|
272 |
+
|
273 |
+
// extract headers
|
274 |
+
$headers = array();
|
275 |
+
foreach($lines as $line) {
|
276 |
+
$kvsplit = explode(":", $line);
|
277 |
+
if (count($kvsplit) == 2) {
|
278 |
+
$header = $kvsplit[0];
|
279 |
+
$value = $kvsplit[1];
|
280 |
+
$headers[$header] = trim($value);
|
281 |
+
}
|
282 |
+
|
283 |
+
}
|
284 |
+
|
285 |
+
// extract status
|
286 |
+
$line_one_exploded = explode(" ", $lines[0]);
|
287 |
+
$status = $line_one_exploded[1];
|
288 |
+
|
289 |
+
// extract body
|
290 |
+
$body = $lines[count($lines) - 1];
|
291 |
+
|
292 |
+
// if the connection has been closed lets kill the socket
|
293 |
+
if ($headers['Connection'] == "close") {
|
294 |
+
$this->_destroySocket();
|
295 |
+
if ($this->_debug()) {
|
296 |
+
$this->_log("Server told us connection closed so lets destroy the socket so it'll reconnect on next call");
|
297 |
+
}
|
298 |
+
}
|
299 |
+
|
300 |
+
$ret = array(
|
301 |
+
"status" => $status,
|
302 |
+
"body" => $body,
|
303 |
+
);
|
304 |
+
|
305 |
+
return $ret;
|
306 |
+
}
|
307 |
+
|
308 |
+
|
309 |
+
}
|
lib/mixpanel/LI_Mixpanel.php
ADDED
@@ -0,0 +1,305 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
require_once(dirname(__FILE__) . "/Base/LI_MixpanelBase.php");
|
4 |
+
require_once(dirname(__FILE__) . "/Producers/LI_MixpanelPeople.php");
|
5 |
+
require_once(dirname(__FILE__) . "/Producers/LI_MixpanelEvents.php");
|
6 |
+
|
7 |
+
/**
|
8 |
+
* This is the main class for the Mixpanel PHP Library which provides all of the methods you need to track events and
|
9 |
+
* create/update profiles.
|
10 |
+
*
|
11 |
+
* Architecture
|
12 |
+
* -------------
|
13 |
+
*
|
14 |
+
* This library is built such that all messages are buffered in an in-memory "queue"
|
15 |
+
* The queue will be automatically flushed at the end of every request. Alternatively, you can call "flush()" manually
|
16 |
+
* at any time. Flushed messages will be passed to a Consumer's "persist" method. The library comes with a handful of
|
17 |
+
* Consumers. The "LI_CurlConsumer" is used by default which will send the messages to Mixpanel using forked cURL processes.
|
18 |
+
* You can implement your own custom Consumer to customize how a message is sent to Mixpanel. This can be useful when
|
19 |
+
* you want to put messages onto a distributed queue (such as ActiveMQ or Kestrel) instead of writing to Mixpanel in
|
20 |
+
* the user thread.
|
21 |
+
*
|
22 |
+
* Options
|
23 |
+
* -------------
|
24 |
+
*
|
25 |
+
* <table width="100%" cellpadding="5">
|
26 |
+
* <tr>
|
27 |
+
* <th>Option</th>
|
28 |
+
* <th>Description</th>
|
29 |
+
* <th>Default</th>
|
30 |
+
* </tr>
|
31 |
+
* <tr>
|
32 |
+
* <td>max_queue_size</td>
|
33 |
+
* <td>The maximum number of items to buffer in memory before flushing</td>
|
34 |
+
* <td>1000</td>
|
35 |
+
* </tr>
|
36 |
+
* <tr>
|
37 |
+
* <td>debug</td>
|
38 |
+
* <td>Enable/disable debug mode</td>
|
39 |
+
* <td>false</td>
|
40 |
+
* </tr>
|
41 |
+
* <tr>
|
42 |
+
* <td>consumer</td>
|
43 |
+
* <td>The consumer to use for writing messages</td>
|
44 |
+
* <td>curl</td>
|
45 |
+
* </tr>
|
46 |
+
* <tr>
|
47 |
+
* <td>consumers</td>
|
48 |
+
* <td>An array of custom consumers in the format array(consumer_key => class_name)</td>
|
49 |
+
* <td>null</td>
|
50 |
+
* </tr>
|
51 |
+
* <tr>
|
52 |
+
* <td>host</td>
|
53 |
+
* <td>The host name for api calls (used by some consumers)</td>
|
54 |
+
* <td>api.mixpanel.com</td>
|
55 |
+
* </tr>
|
56 |
+
* <tr>
|
57 |
+
* <td>events_endpoint</td>
|
58 |
+
* <td>The endpoint for tracking events (relative to the host)</td>
|
59 |
+
* <td>/events</td>
|
60 |
+
* </tr>
|
61 |
+
* <tr>
|
62 |
+
* <td>people_endpoint</td>
|
63 |
+
* <td>The endpoint for making people updates (relative to the host)</td>
|
64 |
+
* <td>/engage</td>
|
65 |
+
* </tr>
|
66 |
+
* <tr>
|
67 |
+
* <td>use_ssl</td>
|
68 |
+
* <td>Tell the consumer whether or not to use ssl (when available)</td>
|
69 |
+
* <td>true</td>
|
70 |
+
* </tr>
|
71 |
+
* <tr>
|
72 |
+
* <td>error_callback</td>
|
73 |
+
* <td>The name of a function to be called on consumption failures</td>
|
74 |
+
* <td>null</td>
|
75 |
+
* </tr>
|
76 |
+
* <tr>
|
77 |
+
* <td>connect_timeout</td>
|
78 |
+
* <td>In both the SocketConsumer and LI_CurlConsumer, this is used for the connection timeout (i.e. How long it has take to actually make a connection).
|
79 |
+
* <td>5</td>
|
80 |
+
* </tr>
|
81 |
+
* <tr>
|
82 |
+
* <td>timeout</td>
|
83 |
+
* <td>In the LI_CurlConsumer (non-forked), it is used to determine how long the cURL call has to execute.
|
84 |
+
* <td>30</td>
|
85 |
+
* </tr>
|
86 |
+
* </table>
|
87 |
+
*
|
88 |
+
* Example: Tracking an Event
|
89 |
+
* -------------
|
90 |
+
*
|
91 |
+
* $mp = Mixpanel::getInstance("MY_TOKEN");
|
92 |
+
*
|
93 |
+
* $mp->track("My Event");
|
94 |
+
*
|
95 |
+
* Example: Setting Profile Properties
|
96 |
+
* -------------
|
97 |
+
*
|
98 |
+
* $mp = Mixpanel::getInstance("MY_TOKEN", array("use_ssl" => false));
|
99 |
+
*
|
100 |
+
* $mp->people->set(12345, array(
|
101 |
+
* '$first_name' => "John",
|
102 |
+
* '$last_name' => "Doe",
|
103 |
+
* '$email' => "john.doe@example.com",
|
104 |
+
* '$phone' => "5555555555",
|
105 |
+
* 'Favorite Color' => "red"
|
106 |
+
* ));
|
107 |
+
*
|
108 |
+
*/
|
109 |
+
class LI_Mixpanel extends LI_Base_MixpanelBase {
|
110 |
+
|
111 |
+
|
112 |
+
/**
|
113 |
+
* An instance of the MixpanelPeople class (used to create/update profiles)
|
114 |
+
* @var MixpanelPeople
|
115 |
+
*/
|
116 |
+
public $people;
|
117 |
+
|
118 |
+
|
119 |
+
/**
|
120 |
+
* An instance of the MixpanelEvents class
|
121 |
+
* @var Producers_MixpanelEvents
|
122 |
+
*/
|
123 |
+
private $_events;
|
124 |
+
|
125 |
+
|
126 |
+
/**
|
127 |
+
* An instance of the Mixpanel class (for singleton use)
|
128 |
+
* @var Mixpanel
|
129 |
+
*/
|
130 |
+
public $instance;
|
131 |
+
|
132 |
+
|
133 |
+
/**
|
134 |
+
* Instantiates a new Mixpanel instance.
|
135 |
+
* @param $token
|
136 |
+
* @param array $options
|
137 |
+
*/
|
138 |
+
public function __construct($token, $options = array()) {
|
139 |
+
parent::__construct($options);
|
140 |
+
$this->people = new LI_Producers_MixpanelPeople($token, $options);
|
141 |
+
$this->_events = new LI_Producers_MixpanelEvents($token, $options);
|
142 |
+
}
|
143 |
+
|
144 |
+
|
145 |
+
/**
|
146 |
+
* Returns a singleton instance of Mixpanel
|
147 |
+
* @param $token
|
148 |
+
* @param array $options
|
149 |
+
* @return Mixpanel
|
150 |
+
*/
|
151 |
+
public static function getInstance($token, $options = array()) {
|
152 |
+
|
153 |
+
|
154 |
+
|
155 |
+
|
156 |
+
$this->instance = new LI_Mixpanel($token, $options);
|
157 |
+
|
158 |
+
|
159 |
+
}
|
160 |
+
|
161 |
+
|
162 |
+
/**
|
163 |
+
* Add an array representing a message to be sent to Mixpanel to the in-memory queue.
|
164 |
+
* @param array $message
|
165 |
+
*/
|
166 |
+
public function enqueue($message = array()) {
|
167 |
+
$this->_events->enqueue($message);
|
168 |
+
}
|
169 |
+
|
170 |
+
|
171 |
+
/**
|
172 |
+
* Add an array representing a list of messages to be sent to Mixpanel to a queue.
|
173 |
+
* @param array $messages
|
174 |
+
*/
|
175 |
+
public function enqueueAll($messages = array()) {
|
176 |
+
$this->_events->enqueueAll($messages);
|
177 |
+
}
|
178 |
+
|
179 |
+
|
180 |
+
/**
|
181 |
+
* Flush the events queue
|
182 |
+
* @param int $desired_batch_size
|
183 |
+
*/
|
184 |
+
public function flush($desired_batch_size = 50) {
|
185 |
+
$this->_events->flush($desired_batch_size);
|
186 |
+
}
|
187 |
+
|
188 |
+
|
189 |
+
/**
|
190 |
+
* Empty the events queue
|
191 |
+
*/
|
192 |
+
public function reset() {
|
193 |
+
$this->_events->reset();
|
194 |
+
}
|
195 |
+
|
196 |
+
|
197 |
+
/**
|
198 |
+
* Identify the user you want to associate to tracked events
|
199 |
+
* @param string|int $user_id
|
200 |
+
*/
|
201 |
+
public function identify($user_id) {
|
202 |
+
$this->_events->identify($user_id);
|
203 |
+
}
|
204 |
+
|
205 |
+
/**
|
206 |
+
* Track an event defined by $event associated with metadata defined by $properties
|
207 |
+
* @param string $event
|
208 |
+
* @param array $properties
|
209 |
+
*/
|
210 |
+
public function track($event, $properties = array()) {
|
211 |
+
$this->_events->track($event, $properties);
|
212 |
+
}
|
213 |
+
|
214 |
+
|
215 |
+
/**
|
216 |
+
* Register a property to be sent with every event.
|
217 |
+
*
|
218 |
+
* If the property has already been registered, it will be
|
219 |
+
* overwritten. NOTE: Registered properties are only persisted for the life of the Mixpanel class instance.
|
220 |
+
* @param string $property
|
221 |
+
* @param mixed $value
|
222 |
+
*/
|
223 |
+
public function register($property, $value) {
|
224 |
+
$this->_events->register($property, $value);
|
225 |
+
}
|
226 |
+
|
227 |
+
|
228 |
+
/**
|
229 |
+
* Register multiple properties to be sent with every event.
|
230 |
+
*
|
231 |
+
* If any of the properties have already been registered,
|
232 |
+
* they will be overwritten. NOTE: Registered properties are only persisted for the life of the Mixpanel class
|
233 |
+
* instance.
|
234 |
+
* @param array $props_and_vals
|
235 |
+
*/
|
236 |
+
public function registerAll($props_and_vals = array()) {
|
237 |
+
$this->_events->registerAll($props_and_vals);
|
238 |
+
}
|
239 |
+
|
240 |
+
|
241 |
+
/**
|
242 |
+
* Register a property to be sent with every event.
|
243 |
+
*
|
244 |
+
* If the property has already been registered, it will NOT be
|
245 |
+
* overwritten. NOTE: Registered properties are only persisted for the life of the Mixpanel class instance.
|
246 |
+
* @param $property
|
247 |
+
* @param $value
|
248 |
+
*/
|
249 |
+
public function registerOnce($property, $value) {
|
250 |
+
$this->_events->registerOnce($property, $value);
|
251 |
+
}
|
252 |
+
|
253 |
+
|
254 |
+
/**
|
255 |
+
* Register multiple properties to be sent with every event.
|
256 |
+
*
|
257 |
+
* If any of the properties have already been registered,
|
258 |
+
* they will NOT be overwritten. NOTE: Registered properties are only persisted for the life of the Mixpanel class
|
259 |
+
* instance.
|
260 |
+
* @param array $props_and_vals
|
261 |
+
*/
|
262 |
+
public function registerAllOnce($props_and_vals = array()) {
|
263 |
+
$this->_events->registerAllOnce($props_and_vals);
|
264 |
+
}
|
265 |
+
|
266 |
+
|
267 |
+
/**
|
268 |
+
* Un-register an property to be sent with every event.
|
269 |
+
* @param string $property
|
270 |
+
*/
|
271 |
+
public function unregister($property) {
|
272 |
+
$this->_events->unregister($property);
|
273 |
+
}
|
274 |
+
|
275 |
+
|
276 |
+
/**
|
277 |
+
* Un-register a list of properties to be sent with every event.
|
278 |
+
* @param array $properties
|
279 |
+
*/
|
280 |
+
public function unregisterAll($properties) {
|
281 |
+
$this->_events->unregisterAll($properties);
|
282 |
+
}
|
283 |
+
|
284 |
+
|
285 |
+
/**
|
286 |
+
* Get a property that is set to be sent with every event
|
287 |
+
* @param string $property
|
288 |
+
* @return mixed
|
289 |
+
*/
|
290 |
+
public function getProperty($property)
|
291 |
+
{
|
292 |
+
return $this->_events->getProperty($property);
|
293 |
+
}
|
294 |
+
|
295 |
+
|
296 |
+
/**
|
297 |
+
* Alias an existing id with a different unique id. This is helpful when you want to associate a generated id
|
298 |
+
* (such as a session id) to a user id or username.
|
299 |
+
* @param string|int $original_id
|
300 |
+
* @param string|int $new_id
|
301 |
+
*/
|
302 |
+
public function createAlias($original_id, $new_id) {
|
303 |
+
$this->_events->createAlias($original_id, $new_id);
|
304 |
+
}
|
305 |
+
}
|
lib/mixpanel/Producers/LI_MixpanelBaseProducer.php
ADDED
@@ -0,0 +1,230 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
require_once(dirname(__FILE__) . "/../Base/LI_MixpanelBase.php");
|
4 |
+
require_once(dirname(__FILE__) . "/../ConsumerStrategies/LI_FileConsumer.php");
|
5 |
+
require_once(dirname(__FILE__) . "/../ConsumerStrategies/LI_CurlConsumer.php");
|
6 |
+
require_once(dirname(__FILE__) . "/../ConsumerStrategies/LI_SocketConsumer.php");
|
7 |
+
|
8 |
+
if (!function_exists('json_encode')) {
|
9 |
+
throw new Exception('The JSON PHP extension is required.');
|
10 |
+
}
|
11 |
+
|
12 |
+
/**
|
13 |
+
* Provides some base methods for use by a message Producer
|
14 |
+
*/
|
15 |
+
abstract class LI_Producers_MixpanelBaseProducer extends LI_Base_MixpanelBase {
|
16 |
+
|
17 |
+
|
18 |
+
/**
|
19 |
+
* @var string a token associated to a Mixpanel project
|
20 |
+
*/
|
21 |
+
protected $_token;
|
22 |
+
|
23 |
+
|
24 |
+
/**
|
25 |
+
* @var array a queue to hold messages in memory before flushing in batches
|
26 |
+
*/
|
27 |
+
private $_queue = array();
|
28 |
+
|
29 |
+
|
30 |
+
/**
|
31 |
+
* @var LI_ConsumerStrategies_AbstractConsumer the consumer to use when flushing messages
|
32 |
+
*/
|
33 |
+
private $_consumer = null;
|
34 |
+
|
35 |
+
|
36 |
+
/**
|
37 |
+
* @var array The list of available consumers
|
38 |
+
*/
|
39 |
+
private $_consumers = array(
|
40 |
+
"file" => "LI_ConsumerStrategies_FileConsumer",
|
41 |
+
"curl" => "LI_ConsumerStrategies_CurlConsumer",
|
42 |
+
"socket" => "LI_ConsumerStrategies_SocketConsumer"
|
43 |
+
);
|
44 |
+
|
45 |
+
|
46 |
+
/**
|
47 |
+
* If the queue reaches this size we'll auto-flush to prevent out of memory errors
|
48 |
+
* @var int
|
49 |
+
*/
|
50 |
+
protected $_max_queue_size = 1000;
|
51 |
+
|
52 |
+
|
53 |
+
/**
|
54 |
+
* Creates a new MixpanelBaseProducer, assings Mixpanel project token, registers custom Consumers, and instantiates
|
55 |
+
* the desired consumer
|
56 |
+
* @param $token
|
57 |
+
* @param array $options
|
58 |
+
*/
|
59 |
+
public function __construct($token, $options = array()) {
|
60 |
+
|
61 |
+
parent::__construct($options);
|
62 |
+
|
63 |
+
// register any customer consumers
|
64 |
+
if (array_key_exists("consumers", $options)) {
|
65 |
+
$this->_consumers = array_merge($this->_consumers, $options['consumers']);
|
66 |
+
}
|
67 |
+
|
68 |
+
// set max queue size
|
69 |
+
if (array_key_exists("max_queue_size", $options)) {
|
70 |
+
$this->_max_queue_size = $options['max_queue_size'];
|
71 |
+
}
|
72 |
+
|
73 |
+
// associate token
|
74 |
+
$this->_token = $token;
|
75 |
+
|
76 |
+
if ($this->_debug()) {
|
77 |
+
$this->_log("Using token: ".$this->_token);
|
78 |
+
}
|
79 |
+
|
80 |
+
// instantiate the chosen consumer
|
81 |
+
$this->_consumer = $this->_getConsumer();
|
82 |
+
|
83 |
+
}
|
84 |
+
|
85 |
+
|
86 |
+
/**
|
87 |
+
* Flush the queue when we destruct the client with retries
|
88 |
+
*/
|
89 |
+
public function __destruct() {
|
90 |
+
$attempts = 0;
|
91 |
+
$max_attempts = 10;
|
92 |
+
$success = false;
|
93 |
+
while (!$success && $attempts < $max_attempts) {
|
94 |
+
if ($this->_debug()) {
|
95 |
+
$this->_log("destruct flush attempt #".($attempts+1));
|
96 |
+
}
|
97 |
+
$success = $this->flush();
|
98 |
+
$attempts++;
|
99 |
+
}
|
100 |
+
}
|
101 |
+
|
102 |
+
|
103 |
+
/**
|
104 |
+
* Iterate the queue and write in batches using the instantiated Consumer Strategy
|
105 |
+
* @param int $desired_batch_size
|
106 |
+
* @return bool whether or not the flush was successful
|
107 |
+
*/
|
108 |
+
public function flush($desired_batch_size = 50) {
|
109 |
+
$queue_size = count($this->_queue);
|
110 |
+
$succeeded = true;
|
111 |
+
if ($this->_debug()) {
|
112 |
+
$this->_log("Flush called - queue size: ".$queue_size);
|
113 |
+
}
|
114 |
+
|
115 |
+
while($queue_size > 0 && $succeeded) {
|
116 |
+
$batch_size = min(array($queue_size, $desired_batch_size, $this->_options['max_batch_size']));
|
117 |
+
$batch = array_splice($this->_queue, 0, $batch_size);
|
118 |
+
$succeeded = $this->_persist($batch);
|
119 |
+
|
120 |
+
if (!$succeeded) {
|
121 |
+
if ($this->_debug()) {
|
122 |
+
$this->_log("Batch consumption failed!");
|
123 |
+
}
|
124 |
+
$this->_queue = array_merge($batch, $this->_queue);
|
125 |
+
|
126 |
+
if ($this->_debug()) {
|
127 |
+
$this->_log("added batch back to queue, queue size is now $queue_size");
|
128 |
+
}
|
129 |
+
}
|
130 |
+
|
131 |
+
$queue_size = count($this->_queue);
|
132 |
+
|
133 |
+
if ($this->_debug()) {
|
134 |
+
$this->_log("Batch of $batch_size consumed, queue size is now $queue_size");
|
135 |
+
}
|
136 |
+
}
|
137 |
+
return $succeeded;
|
138 |
+
}
|
139 |
+
|
140 |
+
|
141 |
+
/**
|
142 |
+
* Empties the queue without persisting any of the messages
|
143 |
+
*/
|
144 |
+
public function reset() {
|
145 |
+
$this->_queue = array();
|
146 |
+
}
|
147 |
+
|
148 |
+
|
149 |
+
/**
|
150 |
+
* Returns the in-memory queue
|
151 |
+
* @return array
|
152 |
+
*/
|
153 |
+
public function getQueue() {
|
154 |
+
return $this->_queue;
|
155 |
+
}
|
156 |
+
|
157 |
+
/**
|
158 |
+
* Returns the current Mixpanel project token
|
159 |
+
* @return string
|
160 |
+
*/
|
161 |
+
public function getToken() {
|
162 |
+
return $this->_token;
|
163 |
+
}
|
164 |
+
|
165 |
+
|
166 |
+
/**
|
167 |
+
* Given a strategy type, return a new PersistenceStrategy object
|
168 |
+
* @return LI_ConsumerStrategies_AbstractConsumer
|
169 |
+
*/
|
170 |
+
protected function _getConsumer() {
|
171 |
+
$key = $this->_options['consumer'];
|
172 |
+
$Strategy = $this->_consumers[$key];
|
173 |
+
if ($this->_debug()) {
|
174 |
+
$this->_log("Using consumer: " . $key . " -> " . $Strategy);
|
175 |
+
}
|
176 |
+
$this->_options['endpoint'] = $this->_getEndpoint();
|
177 |
+
|
178 |
+
return new $Strategy($this->_options);
|
179 |
+
}
|
180 |
+
|
181 |
+
|
182 |
+
/**
|
183 |
+
* Add an array representing a message to be sent to Mixpanel to a queue.
|
184 |
+
* @param array $message
|
185 |
+
*/
|
186 |
+
public function enqueue($message = array()) {
|
187 |
+
array_push($this->_queue, $message);
|
188 |
+
|
189 |
+
// force a flush if we've reached our threshold
|
190 |
+
if (count($this->_queue) > $this->_max_queue_size) {
|
191 |
+
$this->flush();
|
192 |
+
}
|
193 |
+
|
194 |
+
if ($this->_debug()) {
|
195 |
+
$this->_log("Queued message: ".json_encode($message));
|
196 |
+
}
|
197 |
+
}
|
198 |
+
|
199 |
+
|
200 |
+
/**
|
201 |
+
* Add an array representing a list of messages to be sent to Mixpanel to a queue.
|
202 |
+
* @param array $messages
|
203 |
+
*/
|
204 |
+
public function enqueueAll($messages = array()) {
|
205 |
+
foreach($messages as $message) {
|
206 |
+
$this->enqueue($message);
|
207 |
+
}
|
208 |
+
|
209 |
+
}
|
210 |
+
|
211 |
+
|
212 |
+
/**
|
213 |
+
* Given an array of messages, persist it with the instantiated Persistence Strategy
|
214 |
+
* @param $message
|
215 |
+
* @return mixed
|
216 |
+
*/
|
217 |
+
protected function _persist($message) {
|
218 |
+
return $this->_consumer->persist($message);
|
219 |
+
}
|
220 |
+
|
221 |
+
|
222 |
+
|
223 |
+
|
224 |
+
/**
|
225 |
+
* Return the endpoint that should be used by a consumer that consumes messages produced by this producer.
|
226 |
+
* @return string
|
227 |
+
*/
|
228 |
+
abstract function _getEndpoint();
|
229 |
+
|
230 |
+
}
|
lib/mixpanel/Producers/LI_MixpanelEvents.php
ADDED
@@ -0,0 +1,165 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
require_once(dirname(__FILE__) . "/LI_MixpanelBaseProducer.php");
|
4 |
+
require_once(dirname(__FILE__) . "/LI_MixpanelPeople.php");
|
5 |
+
require_once(dirname(__FILE__) . "/../ConsumerStrategies/LI_CurlConsumer.php");
|
6 |
+
|
7 |
+
/**
|
8 |
+
* Provides an API to track events on Mixpanel
|
9 |
+
*/
|
10 |
+
class LI_Producers_MixpanelEvents extends LI_Producers_MixpanelBaseProducer {
|
11 |
+
|
12 |
+
/**
|
13 |
+
* An array of properties to attach to every tracked event
|
14 |
+
* @var array
|
15 |
+
*/
|
16 |
+
private $_super_properties = array("mp_lib" => "php");
|
17 |
+
|
18 |
+
|
19 |
+
/**
|
20 |
+
* Track an event defined by $event associated with metadata defined by $properties
|
21 |
+
* @param string $event
|
22 |
+
* @param array $properties
|
23 |
+
*/
|
24 |
+
public function track($event, $properties = array()) {
|
25 |
+
|
26 |
+
// if no token is passed in, use current token
|
27 |
+
if (!array_key_exists("token", $properties)) $properties['token'] = $this->_token;
|
28 |
+
|
29 |
+
// if no time is passed in, use the current time
|
30 |
+
if (!array_key_exists('time', $properties)) $properties['time'] = time();
|
31 |
+
|
32 |
+
$params['event'] = $event;
|
33 |
+
$params['properties'] = array_merge($this->_super_properties, $properties);
|
34 |
+
|
35 |
+
$this->enqueue($params);
|
36 |
+
}
|
37 |
+
|
38 |
+
|
39 |
+
/**
|
40 |
+
* Register a property to be sent with every event. If the property has already been registered, it will be
|
41 |
+
* overwritten.
|
42 |
+
* @param string $property
|
43 |
+
* @param mixed $value
|
44 |
+
*/
|
45 |
+
public function register($property, $value) {
|
46 |
+
$this->_super_properties[$property] = $value;
|
47 |
+
}
|
48 |
+
|
49 |
+
|
50 |
+
/**
|
51 |
+
* Register multiple properties to be sent with every event. If any of the properties have already been registered,
|
52 |
+
* they will be overwritten.
|
53 |
+
* @param array $props_and_vals
|
54 |
+
*/
|
55 |
+
public function registerAll($props_and_vals = array()) {
|
56 |
+
foreach($props_and_vals as $property => $value) {
|
57 |
+
$this->register($property, $value);
|
58 |
+
}
|
59 |
+
}
|
60 |
+
|
61 |
+
|
62 |
+
/**
|
63 |
+
* Register a property to be sent with every event. If the property has already been registered, it will NOT be
|
64 |
+
* overwritten.
|
65 |
+
* @param $property
|
66 |
+
* @param $value
|
67 |
+
*/
|
68 |
+
public function registerOnce($property, $value) {
|
69 |
+
if (!isset($this->_super_properties[$property])) {
|
70 |
+
$this->register($property, $value);
|
71 |
+
}
|
72 |
+
}
|
73 |
+
|
74 |
+
|
75 |
+
/**
|
76 |
+
* Register multiple properties to be sent with every event. If any of the properties have already been registered,
|
77 |
+
* they will NOT be overwritten.
|
78 |
+
* @param array $props_and_vals
|
79 |
+
*/
|
80 |
+
public function registerAllOnce($props_and_vals = array()) {
|
81 |
+
foreach($props_and_vals as $property => $value) {
|
82 |
+
if (!isset($this->_super_properties[$property])) {
|
83 |
+
$this->register($property, $value);
|
84 |
+
}
|
85 |
+
}
|
86 |
+
}
|
87 |
+
|
88 |
+
|
89 |
+
/**
|
90 |
+
* Un-register an property to be sent with every event.
|
91 |
+
* @param string $property
|
92 |
+
*/
|
93 |
+
public function unregister($property) {
|
94 |
+
unset($this->_super_properties[$property]);
|
95 |
+
}
|
96 |
+
|
97 |
+
|
98 |
+
/**
|
99 |
+
* Un-register a list of properties to be sent with every event.
|
100 |
+
* @param array $properties
|
101 |
+
*/
|
102 |
+
public function unregisterAll($properties) {
|
103 |
+
foreach($properties as $property) {
|
104 |
+
$this->unregister($property);
|
105 |
+
}
|
106 |
+
}
|
107 |
+
|
108 |
+
|
109 |
+
/**
|
110 |
+
* Get a property that is set to be sent with every event
|
111 |
+
* @param string $property
|
112 |
+
* @return mixed
|
113 |
+
*/
|
114 |
+
public function getProperty($property) {
|
115 |
+
return $this->_super_properties[$property];
|
116 |
+
}
|
117 |
+
|
118 |
+
|
119 |
+
/**
|
120 |
+
* Identify the user you want to associate to tracked events
|
121 |
+
* @param string|int $user_id
|
122 |
+
*/
|
123 |
+
public function identify($user_id) {
|
124 |
+
$this->register("distinct_id", $user_id);
|
125 |
+
}
|
126 |
+
|
127 |
+
|
128 |
+
/**
|
129 |
+
* Alias an existing id with a different unique id. This is helpful when you want to associate a generated id to
|
130 |
+
* a username or e-mail address.
|
131 |
+
*
|
132 |
+
* Because aliasing can be extremely vulnerable to race conditions and ordering issues, we'll make a synchronous
|
133 |
+
* call directly to Mixpanel when this method is called. If it fails we'll throw an Exception as subsequent
|
134 |
+
* events are likely to be incorrectly tracked.
|
135 |
+
* @param string|int $original_id
|
136 |
+
* @param string|int $new_id
|
137 |
+
* @return array $msg
|
138 |
+
* @throws Exception
|
139 |
+
*/
|
140 |
+
public function createAlias($original_id, $new_id) {
|
141 |
+
$msg = array(
|
142 |
+
"event" => '$create_alias',
|
143 |
+
"properties" => array("distinct_id" => $original_id, "alias" => $new_id, "token" => $this->_token)
|
144 |
+
);
|
145 |
+
|
146 |
+
$options = array_merge($this->_options, array("endpoint" => $this->_getEndpoint(), "fork" => false));
|
147 |
+
$LI_CurlConsumer = new LI_ConsumerStrategies_CurlConsumer($options);
|
148 |
+
$success = $LI_CurlConsumer->persist(array($msg));
|
149 |
+
if (!$success) {
|
150 |
+
//error_log("Creating Mixpanel Alias (original id: $original_id, new id: $new_id) failed");
|
151 |
+
//throw new Exception("Tried to create an alias but the call was not successful");
|
152 |
+
} else {
|
153 |
+
return $msg;
|
154 |
+
}
|
155 |
+
}
|
156 |
+
|
157 |
+
|
158 |
+
/**
|
159 |
+
* Returns the "events" endpoint
|
160 |
+
* @return string
|
161 |
+
*/
|
162 |
+
function _getEndpoint() {
|
163 |
+
return $this->_options['events_endpoint'];
|
164 |
+
}
|
165 |
+
}
|
lib/mixpanel/Producers/LI_MixpanelPeople.php
ADDED
@@ -0,0 +1,139 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
require_once(dirname(__FILE__) . "/LI_MixpanelBaseProducer.php");
|
4 |
+
|
5 |
+
/**
|
6 |
+
* Provides an API to create/update profiles on Mixpanel
|
7 |
+
*/
|
8 |
+
class LI_Producers_MixpanelPeople extends LI_Producers_MixpanelBaseProducer {
|
9 |
+
|
10 |
+
/**
|
11 |
+
* Internal method to prepare a message given the message data
|
12 |
+
* @param $distinct_id
|
13 |
+
* @param $operation
|
14 |
+
* @param $value
|
15 |
+
* @param null $ip
|
16 |
+
* @return array
|
17 |
+
*/
|
18 |
+
private function _constructPayload($distinct_id, $operation, $value, $ip = null) {
|
19 |
+
$payload = array(
|
20 |
+
'$token' => $this->_token,
|
21 |
+
'$distinct_id' => $distinct_id,
|
22 |
+
$operation => $value
|
23 |
+
);
|
24 |
+
if ($ip !== null) $payload['$ip'] = $ip;
|
25 |
+
return $payload;
|
26 |
+
}
|
27 |
+
|
28 |
+
/**
|
29 |
+
* Set properties on a user record. If the profile does not exist, it creates it with these properties.
|
30 |
+
* If it does exist, it sets the properties to these values, overwriting existing values.
|
31 |
+
* @param string|int $distinct_id the distinct_id or alias of a user
|
32 |
+
* @param array $props associative array of properties to set on the profile
|
33 |
+
* @param string|null $ip the ip address of the client (used for geo-location)
|
34 |
+
*/
|
35 |
+
public function set($distinct_id, $props, $ip = null) {
|
36 |
+
$payload = $this->_constructPayload($distinct_id, '$set', $props, $ip);
|
37 |
+
$this->enqueue($payload);
|
38 |
+
}
|
39 |
+
|
40 |
+
/**
|
41 |
+
* Set properties on a user record. If the profile does not exist, it creates it with these properties.
|
42 |
+
* If it does exist, it sets the properties to these values but WILL NOT overwrite existing values.
|
43 |
+
* @param string|int $distinct_id the distinct_id or alias of a user
|
44 |
+
* @param array $props associative array of properties to set on the profile
|
45 |
+
* @param string|null $ip the ip address of the client (used for geo-location)
|
46 |
+
*/
|
47 |
+
public function setOnce($distinct_id, $props, $ip = null) {
|
48 |
+
$payload = $this->_constructPayload($distinct_id, '$set_once', $props, $ip);
|
49 |
+
$this->enqueue($payload);
|
50 |
+
}
|
51 |
+
|
52 |
+
/**
|
53 |
+
* Unset properties on a user record. If the profile does not exist, it creates it with no properties.
|
54 |
+
* If it does exist, it unsets these properties. NOTE: In other libraries we use 'unset' which is
|
55 |
+
* a reserved word in PHP.
|
56 |
+
* @param string|int $distinct_id the distinct_id or alias of a user
|
57 |
+
* @param array $props associative array of properties to unset on the profile
|
58 |
+
* @param string|null $ip the ip address of the client (used for geo-location)
|
59 |
+
*/
|
60 |
+
public function remove($distinct_id, $props, $ip = null) {
|
61 |
+
$payload = $this->_constructPayload($distinct_id, '$unset', $props, $ip);
|
62 |
+
$this->enqueue($payload);
|
63 |
+
}
|
64 |
+
|
65 |
+
/**
|
66 |
+
* Increments the value of a property on a user record. If the profile does not exist, it creates it and sets the
|
67 |
+
* property to the increment value.
|
68 |
+
* @param string|int $distinct_id the distinct_id or alias of a user
|
69 |
+
* @param $prop string the property to increment
|
70 |
+
* @param int $val the amount to increment the property by
|
71 |
+
* @param string|null $ip the ip address of the client (used for geo-location)
|
72 |
+
*/
|
73 |
+
public function increment($distinct_id, $prop, $val, $ip = null) {
|
74 |
+
$payload = $this->_constructPayload($distinct_id, '$add', array("$prop" => $val), $ip);
|
75 |
+
$this->enqueue($payload);
|
76 |
+
}
|
77 |
+
|
78 |
+
/**
|
79 |
+
* Adds $val to a list located at $prop. If the property does not exist, it will be created. If $val is a string
|
80 |
+
* and the list is empty or does not exist, a new list with one value will be created.
|
81 |
+
* @param string|int $distinct_id the distinct_id or alias of a user
|
82 |
+
* @param string $prop the property that holds the list
|
83 |
+
* @param string|array $val items to add to the list
|
84 |
+
* @param string|null $ip the ip address of the client (used for geo-location)
|
85 |
+
*/
|
86 |
+
public function append($distinct_id, $prop, $val, $ip = null) {
|
87 |
+
$operation = gettype($val) == "array" ? '$union' : '$append';
|
88 |
+
$payload = $this->_constructPayload($distinct_id, $operation, array("$prop" => $val), $ip);
|
89 |
+
$this->enqueue($payload);
|
90 |
+
}
|
91 |
+
|
92 |
+
/**
|
93 |
+
* Adds a transaction to the user's profile for revenue tracking
|
94 |
+
* @param string|int $distinct_id the distinct_id or alias of a user
|
95 |
+
* @param string $amount the transaction amount e.g. "20.50"
|
96 |
+
* @param null $timestamp the timestamp of when the transaction occurred (default to current timestamp)
|
97 |
+
* @param string|null $ip the ip address of the client (used for geo-location)
|
98 |
+
*/
|
99 |
+
public function trackCharge($distinct_id, $amount, $timestamp = null, $ip = null) {
|
100 |
+
$timestamp = $timestamp == null ? time() : $timestamp;
|
101 |
+
$date_iso = date("c", $timestamp);
|
102 |
+
$transaction = array(
|
103 |
+
'$time' => $date_iso,
|
104 |
+
'$amount' => $amount
|
105 |
+
);
|
106 |
+
$val = array('$transactions' => $transaction);
|
107 |
+
$payload = $this->_constructPayload($distinct_id, '$append', $val, $ip);
|
108 |
+
$this->enqueue($payload);
|
109 |
+
}
|
110 |
+
|
111 |
+
/**
|
112 |
+
* Clear all transactions stored on a user's profile
|
113 |
+
* @param string|int $distinct_id the distinct_id or alias of a user
|
114 |
+
* @param string|null $ip the ip address of the client (used for geo-location)
|
115 |
+
*/
|
116 |
+
public function clearCharges($distinct_id, $ip = null) {
|
117 |
+
$payload = $this->_constructPayload($distinct_id, '$set', array('$transactions' => array()), $ip);
|
118 |
+
$this->enqueue($payload);
|
119 |
+
}
|
120 |
+
|
121 |
+
/**
|
122 |
+
* Delete this profile from Mixpanel
|
123 |
+
* @param string|int $distinct_id the distinct_id or alias of a user
|
124 |
+
* @param string|null $ip the ip address of the client (used for geo-location)
|
125 |
+
*/
|
126 |
+
public function deleteUser($distinct_id, $ip = null) {
|
127 |
+
$payload = $this->_constructPayload($distinct_id, '$delete', "", $ip);
|
128 |
+
$this->enqueue($payload);
|
129 |
+
}
|
130 |
+
|
131 |
+
/**
|
132 |
+
* Returns the "engage" endpoint
|
133 |
+
* @return string
|
134 |
+
*/
|
135 |
+
function _getEndpoint() {
|
136 |
+
return $this->_options['people_endpoint'];
|
137 |
+
}
|
138 |
+
|
139 |
+
}
|
lib/segment/lib/Segment.php
ADDED
@@ -0,0 +1,145 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
if (!function_exists('json_encode')) {
|
4 |
+
throw new Exception('Segment needs the JSON PHP extension.');
|
5 |
+
}
|
6 |
+
|
7 |
+
require(dirname(__FILE__) . '/Segment/Client.php');
|
8 |
+
|
9 |
+
|
10 |
+
class Segment {
|
11 |
+
|
12 |
+
private static $client;
|
13 |
+
|
14 |
+
/**
|
15 |
+
* Initializes the default client to use. Uses the socket consumer by default.
|
16 |
+
* @param string $secret your project's secret key
|
17 |
+
* @param array $options passed straight to the client
|
18 |
+
*/
|
19 |
+
public static function init($secret, $options = array()) {
|
20 |
+
self::assert($secret, "Segment::init() requires secret");
|
21 |
+
self::$client = new Segment_Client($secret, $options);
|
22 |
+
}
|
23 |
+
|
24 |
+
/**
|
25 |
+
* Tracks a user action
|
26 |
+
*
|
27 |
+
* @param array $message
|
28 |
+
* @return boolean whether the track call succeeded
|
29 |
+
*/
|
30 |
+
public static function track(array $message) {
|
31 |
+
self::checkClient();
|
32 |
+
$event = !empty($message["event"]);
|
33 |
+
self::assert($event, "Segment::track() expects an event");
|
34 |
+
self::validate($message, "track");
|
35 |
+
return self::$client->track($message);
|
36 |
+
}
|
37 |
+
|
38 |
+
/**
|
39 |
+
* Tags traits about the user.
|
40 |
+
*
|
41 |
+
* @param array $message
|
42 |
+
* @return boolean whether the identify call succeeded
|
43 |
+
*/
|
44 |
+
public static function identify(array $message) {
|
45 |
+
self::checkClient();
|
46 |
+
$message["type"] = "identify";
|
47 |
+
self::validate($message, "identify");
|
48 |
+
return self::$client->identify($message);
|
49 |
+
}
|
50 |
+
|
51 |
+
/**
|
52 |
+
* Tags traits about the group.
|
53 |
+
*
|
54 |
+
* @param array $message
|
55 |
+
* @return boolean whether the group call succeeded
|
56 |
+
*/
|
57 |
+
public static function group(array $message) {
|
58 |
+
self::checkClient();
|
59 |
+
$groupId = !empty($message["groupId"]);
|
60 |
+
$userId = !empty($message["userId"]);
|
61 |
+
self::assert($groupId && $userId, "Segment::group() expects userId and groupId");
|
62 |
+
return self::$client->group($message);
|
63 |
+
}
|
64 |
+
|
65 |
+
/**
|
66 |
+
* Tracks a page view
|
67 |
+
*
|
68 |
+
* @param array $message
|
69 |
+
* @return boolean whether the page call succeeded
|
70 |
+
*/
|
71 |
+
public static function page(array $message) {
|
72 |
+
self::checkClient();
|
73 |
+
self::validate($message, "page");
|
74 |
+
return self::$client->page($message);
|
75 |
+
}
|
76 |
+
|
77 |
+
/**
|
78 |
+
* Tracks a screen view
|
79 |
+
*
|
80 |
+
* @param array $message
|
81 |
+
* @return boolean whether the screen call succeeded
|
82 |
+
*/
|
83 |
+
public static function screen(array $message) {
|
84 |
+
self::checkClient();
|
85 |
+
self::validate($message, "screen");
|
86 |
+
return self::$client->screen($message);
|
87 |
+
}
|
88 |
+
|
89 |
+
/**
|
90 |
+
* Aliases the user id from a temporary id to a permanent one
|
91 |
+
*
|
92 |
+
* @param array $from user id to alias from
|
93 |
+
* @return boolean whether the alias call succeeded
|
94 |
+
*/
|
95 |
+
public static function alias(array $message) {
|
96 |
+
self::checkClient();
|
97 |
+
$userId = !empty($message["userId"]);
|
98 |
+
$previousId = !empty($message["previousId"]);
|
99 |
+
self::assert($userId && $previousId, "Segment::alias() requires both userId and previousId");
|
100 |
+
return self::$client->alias($message);
|
101 |
+
}
|
102 |
+
|
103 |
+
/**
|
104 |
+
* Validate common properties.
|
105 |
+
*
|
106 |
+
* @param array $msg
|
107 |
+
* @param string $type
|
108 |
+
*/
|
109 |
+
public static function validate($msg, $type){
|
110 |
+
$userId = !empty($msg["userId"]);
|
111 |
+
$anonId = !empty($msg["anonymousId"]);
|
112 |
+
self::assert($userId || $anonId, "Segment::$type() requires userId or anonymousId");
|
113 |
+
}
|
114 |
+
|
115 |
+
/**
|
116 |
+
* Flush the client
|
117 |
+
*/
|
118 |
+
|
119 |
+
public static function flush(){
|
120 |
+
self::checkClient();
|
121 |
+
return self::$client->flush();
|
122 |
+
}
|
123 |
+
|
124 |
+
/**
|
125 |
+
* Check the client.
|
126 |
+
*
|
127 |
+
* @throws Exception
|
128 |
+
*/
|
129 |
+
private static function checkClient(){
|
130 |
+
if (null != self::$client) return;
|
131 |
+
throw new Exception("Analytics::init() must be called before any other tracking method.");
|
132 |
+
}
|
133 |
+
|
134 |
+
/**
|
135 |
+
* Assert `value` or throw.
|
136 |
+
*
|
137 |
+
* @param array $value
|
138 |
+
* @param string $msg
|
139 |
+
* @throws Exception
|
140 |
+
*/
|
141 |
+
private static function assert($value, $msg){
|
142 |
+
if (!$value) throw new Exception($msg);
|
143 |
+
}
|
144 |
+
|
145 |
+
}
|
lib/segment/lib/Segment/Client.php
ADDED
@@ -0,0 +1,201 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
require(__DIR__ . '/Consumer.php');
|
4 |
+
require(__DIR__ . '/QueueConsumer.php');
|
5 |
+
require(__DIR__ . '/Consumer/File.php');
|
6 |
+
require(__DIR__ . '/Consumer/ForkCurl.php');
|
7 |
+
require(__DIR__ . '/Consumer/Socket.php');
|
8 |
+
|
9 |
+
class Segment_Client {
|
10 |
+
|
11 |
+
/**
|
12 |
+
* VERSION
|
13 |
+
*/
|
14 |
+
|
15 |
+
const VERSION = "1.1.0";
|
16 |
+
|
17 |
+
private $consumer;
|
18 |
+
|
19 |
+
/**
|
20 |
+
* Create a new analytics object with your app's secret
|
21 |
+
* key
|
22 |
+
*
|
23 |
+
* @param string $secret
|
24 |
+
* @param array $options array of consumer options [optional]
|
25 |
+
* @param string Consumer constructor to use, socket by default.
|
26 |
+
*/
|
27 |
+
public function __construct($secret, $options = array()) {
|
28 |
+
|
29 |
+
$consumers = array(
|
30 |
+
"socket" => "Segment_Consumer_Socket",
|
31 |
+
"file" => "Segment_Consumer_File",
|
32 |
+
"fork_curl" => "Segment_Consumer_ForkCurl"
|
33 |
+
);
|
34 |
+
|
35 |
+
# Use our socket consumer by default
|
36 |
+
$consumer_type = isset($options["consumer"]) ? $options["consumer"] :
|
37 |
+
"socket";
|
38 |
+
$Consumer = $consumers[$consumer_type];
|
39 |
+
|
40 |
+
$this->consumer = new $Consumer($secret, $options);
|
41 |
+
}
|
42 |
+
|
43 |
+
public function __destruct() {
|
44 |
+
$this->consumer->__destruct();
|
45 |
+
}
|
46 |
+
|
47 |
+
/**
|
48 |
+
* Tracks a user action
|
49 |
+
*
|
50 |
+
* @param array $message
|
51 |
+
* @return [boolean] whether the track call succeeded
|
52 |
+
*/
|
53 |
+
public function track(array $message) {
|
54 |
+
$message = $this->message($message, "properties");
|
55 |
+
$message["type"] = "track";
|
56 |
+
return $this->consumer->track($message);
|
57 |
+
}
|
58 |
+
|
59 |
+
/**
|
60 |
+
* Tags traits about the user.
|
61 |
+
*
|
62 |
+
* @param [array] $message
|
63 |
+
* @return [boolean] whether the track call succeeded
|
64 |
+
*/
|
65 |
+
public function identify(array $message) {
|
66 |
+
$message = $this->message($message, "traits");
|
67 |
+
$message["type"] = "identify";
|
68 |
+
return $this->consumer->identify($message);
|
69 |
+
}
|
70 |
+
|
71 |
+
/**
|
72 |
+
* Tags traits about the group.
|
73 |
+
*
|
74 |
+
* @param [array] $message
|
75 |
+
* @return [boolean] whether the group call succeeded
|
76 |
+
*/
|
77 |
+
public function group(array $message) {
|
78 |
+
$message = $this->message($message, "traits");
|
79 |
+
$message["type"] = "group";
|
80 |
+
return $this->consumer->group($message);
|
81 |
+
}
|
82 |
+
|
83 |
+
/**
|
84 |
+
* Tracks a page view.
|
85 |
+
*
|
86 |
+
* @param [array] $message
|
87 |
+
* @return [boolean] whether the page call succeeded
|
88 |
+
*/
|
89 |
+
public function page(array $message) {
|
90 |
+
$message = $this->message($message, "properties");
|
91 |
+
$message["type"] = "page";
|
92 |
+
return $this->consumer->page($message);
|
93 |
+
}
|
94 |
+
|
95 |
+
/**
|
96 |
+
* Tracks a screen view.
|
97 |
+
*
|
98 |
+
* @param [array] $message
|
99 |
+
* @return [boolean] whether the screen call succeeded
|
100 |
+
*/
|
101 |
+
public function screen(array $message) {
|
102 |
+
$message = $this->message($message, "properties");
|
103 |
+
$message["type"] = "screen";
|
104 |
+
return $this->consumer->screen($message);
|
105 |
+
}
|
106 |
+
|
107 |
+
/**
|
108 |
+
* Aliases from one user id to another
|
109 |
+
*
|
110 |
+
* @param array $message
|
111 |
+
* @return boolean whether the alias call succeeded
|
112 |
+
*/
|
113 |
+
public function alias(array $message) {
|
114 |
+
$message = $this->message($message);
|
115 |
+
$message["type"] = "alias";
|
116 |
+
return $this->consumer->alias($message);
|
117 |
+
}
|
118 |
+
|
119 |
+
/**
|
120 |
+
* Flush any async consumers
|
121 |
+
*/
|
122 |
+
public function flush() {
|
123 |
+
if (!method_exists($this->consumer, 'flush')) return;
|
124 |
+
$this->consumer->flush();
|
125 |
+
}
|
126 |
+
|
127 |
+
/**
|
128 |
+
* Formats a timestamp by making sure it is set
|
129 |
+
* and converting it to iso8601.
|
130 |
+
*
|
131 |
+
* The timestamp can be time in seconds `time()` or `microseconds(true)`.
|
132 |
+
* any other input is considered an error and the method will return a new date.
|
133 |
+
*
|
134 |
+
* Note: php's date() "u" format (for microseconds) has a bug in it
|
135 |
+
* it always shows `.000` for microseconds since `date()` only accepts
|
136 |
+
* ints, so we have to construct the date ourselves if microtime is passed.
|
137 |
+
*
|
138 |
+
* @param time $timestamp - time in seconds (time())
|
139 |
+
*/
|
140 |
+
private function formatTime($ts) {
|
141 |
+
if ($ts == null) $ts = time();
|
142 |
+
if ("integer" == gettype($ts)) return date("c", $ts);
|
143 |
+
if (-1 == ($pos = strrpos($ts, "."))) return date("c");
|
144 |
+
$sec = substr($ts, 0, $pos);
|
145 |
+
$usec = substr($ts, $pos);
|
146 |
+
$fmt = sprintf("Y-m-d\TH:i:s%sP", $usec);
|
147 |
+
return date($fmt, (int)$sec);
|
148 |
+
}
|
149 |
+
|
150 |
+
/**
|
151 |
+
* Add common fields to the gvien `message`
|
152 |
+
*
|
153 |
+
* @param array $msg
|
154 |
+
* @param string $def
|
155 |
+
* @return array
|
156 |
+
*/
|
157 |
+
|
158 |
+
private function message($msg, $def = ""){
|
159 |
+
if ($def && !isset($msg[$def])) $msg[$def] = array();
|
160 |
+
if ($def && empty($msg[$def])) $msg[$def] = (object)$msg[$def];
|
161 |
+
if (!isset($msg["context"])) $msg["context"] = array();
|
162 |
+
if (!isset($msg["timestamp"])) $msg["timestamp"] = null;
|
163 |
+
$msg["context"] = array_merge($msg["context"], $this->getContext());
|
164 |
+
$msg["timestamp"] = $this->formatTime($msg["timestamp"]);
|
165 |
+
$msg["messageId"] = self::messageId();
|
166 |
+
return $msg;
|
167 |
+
}
|
168 |
+
|
169 |
+
/**
|
170 |
+
* Generate a random messageId.
|
171 |
+
*
|
172 |
+
* https://gist.github.com/dahnielson/508447#file-uuid-php-L74
|
173 |
+
*
|
174 |
+
* @return string
|
175 |
+
*/
|
176 |
+
|
177 |
+
private static function messageId(){
|
178 |
+
return sprintf("%04x%04x-%04x-%04x-%04x-%04x%04x%04x"
|
179 |
+
, mt_rand(0, 0xffff)
|
180 |
+
, mt_rand(0, 0xffff)
|
181 |
+
, mt_rand(0, 0xffff)
|
182 |
+
, mt_rand(0, 0x0fff) | 0x4000
|
183 |
+
, mt_rand(0, 0x3fff) | 0x8000
|
184 |
+
, mt_rand(0, 0xffff)
|
185 |
+
, mt_rand(0, 0xffff)
|
186 |
+
, mt_rand(0, 0xffff));
|
187 |
+
}
|
188 |
+
|
189 |
+
/**
|
190 |
+
* Add the segment.io context to the request
|
191 |
+
* @return array additional context
|
192 |
+
*/
|
193 |
+
private function getContext () {
|
194 |
+
return array(
|
195 |
+
"library" => array(
|
196 |
+
"name" => "analytics-php",
|
197 |
+
"version" => self::VERSION
|
198 |
+
)
|
199 |
+
);
|
200 |
+
}
|
201 |
+
}
|
lib/segment/lib/Segment/Consumer.php
ADDED
@@ -0,0 +1,104 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
abstract class Segment_Consumer {
|
3 |
+
|
4 |
+
protected $type = "Consumer";
|
5 |
+
|
6 |
+
protected $options;
|
7 |
+
protected $secret;
|
8 |
+
|
9 |
+
/**
|
10 |
+
* Store our secret and options as part of this consumer
|
11 |
+
* @param string $secret
|
12 |
+
* @param array $options
|
13 |
+
*/
|
14 |
+
public function __construct($secret, $options = array()) {
|
15 |
+
$this->secret = $secret;
|
16 |
+
$this->options = $options;
|
17 |
+
}
|
18 |
+
|
19 |
+
|
20 |
+
/**
|
21 |
+
* Tracks a user action
|
22 |
+
*
|
23 |
+
* @param array $message
|
24 |
+
* @return boolean whether the track call succeeded
|
25 |
+
*/
|
26 |
+
abstract public function track(array $message);
|
27 |
+
|
28 |
+
/**
|
29 |
+
* Tags traits about the user.
|
30 |
+
*
|
31 |
+
* @param array $message
|
32 |
+
* @return boolean whether the identify call succeeded
|
33 |
+
*/
|
34 |
+
abstract public function identify(array $message);
|
35 |
+
|
36 |
+
/**
|
37 |
+
* Tags traits about the group.
|
38 |
+
*
|
39 |
+
* @param array $message
|
40 |
+
* @return boolean whether the group call succeeded
|
41 |
+
*/
|
42 |
+
abstract public function group(array $message);
|
43 |
+
|
44 |
+
/**
|
45 |
+
* Tracks a page view.
|
46 |
+
*
|
47 |
+
* @param array $message
|
48 |
+
* @return boolean whether the page call succeeded
|
49 |
+
*/
|
50 |
+
abstract public function page(array $message);
|
51 |
+
|
52 |
+
/**
|
53 |
+
* Tracks a screen view.
|
54 |
+
*
|
55 |
+
* @param array $message
|
56 |
+
* @return boolean whether the group call succeeded
|
57 |
+
*/
|
58 |
+
abstract public function screen(array $message);
|
59 |
+
|
60 |
+
/**
|
61 |
+
* Aliases from one user id to another
|
62 |
+
*
|
63 |
+
* @param array $message
|
64 |
+
* @return boolean whether the alias call succeeded
|
65 |
+
*/
|
66 |
+
abstract public function alias(array $message);
|
67 |
+
|
68 |
+
/**
|
69 |
+
* Check whether debug mode is enabled
|
70 |
+
* @return boolean
|
71 |
+
*/
|
72 |
+
protected function debug() {
|
73 |
+
return isset($this->options["debug"]) ? $this->options["debug"] : false;
|
74 |
+
}
|
75 |
+
|
76 |
+
/**
|
77 |
+
* Check whether we should connect to the API using SSL. This is enabled by
|
78 |
+
* default with connections which make batching requests. For connections
|
79 |
+
* which can save on round-trip times, we disable it.
|
80 |
+
* @return boolean
|
81 |
+
*/
|
82 |
+
protected function ssl() {
|
83 |
+
return isset($this->options["ssl"]) ? $this->options["ssl"] : false;
|
84 |
+
}
|
85 |
+
|
86 |
+
|
87 |
+
/**
|
88 |
+
* On an error, try and call the error handler, if debugging output to
|
89 |
+
* error_log as well.
|
90 |
+
* @param string $code
|
91 |
+
* @param string $msg
|
92 |
+
*/
|
93 |
+
protected function handleError($code, $msg) {
|
94 |
+
|
95 |
+
if (isset($this->options['error_handler'])) {
|
96 |
+
$handler = $this->options['error_handler'];
|
97 |
+
$handler($code, $msg);
|
98 |
+
}
|
99 |
+
|
100 |
+
if ($this->debug()) {
|
101 |
+
error_log("[Analytics][" . $this->type . "] " . $msg);
|
102 |
+
}
|
103 |
+
}
|
104 |
+
}
|
lib/segment/lib/Segment/Consumer/File.php
ADDED
@@ -0,0 +1,111 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class Segment_Consumer_File extends Segment_Consumer {
|
4 |
+
|
5 |
+
private $file_handle;
|
6 |
+
protected $type = "File";
|
7 |
+
|
8 |
+
/**
|
9 |
+
* The file consumer writes track and identify calls to a file.
|
10 |
+
* @param string $secret
|
11 |
+
* @param array $options
|
12 |
+
* string "filename" - where to log the analytics calls
|
13 |
+
*/
|
14 |
+
public function __construct($secret, $options = array()) {
|
15 |
+
|
16 |
+
if (!isset($options["filename"]))
|
17 |
+
$options["filename"] = sys_get_temp_dir() . DIRECTORY_SEPARATOR . "analytics.log";
|
18 |
+
|
19 |
+
parent::__construct($secret, $options);
|
20 |
+
|
21 |
+
try {
|
22 |
+
$this->file_handle = fopen($options["filename"], "a");
|
23 |
+
chmod($options["filename"], 0777);
|
24 |
+
} catch (Exception $e) {
|
25 |
+
$this->handleError($e->getCode(), $e->getMessage());
|
26 |
+
}
|
27 |
+
}
|
28 |
+
|
29 |
+
public function __destruct() {
|
30 |
+
if ($this->file_handle &&
|
31 |
+
get_resource_type($this->file_handle) != "Unknown") {
|
32 |
+
fclose($this->file_handle);
|
33 |
+
}
|
34 |
+
}
|
35 |
+
|
36 |
+
/**
|
37 |
+
* Tracks a user action
|
38 |
+
*
|
39 |
+
* @param array $message
|
40 |
+
* @return [boolean] whether the track call succeeded
|
41 |
+
*/
|
42 |
+
public function track(array $message) {
|
43 |
+
return $this->write($message);
|
44 |
+
}
|
45 |
+
|
46 |
+
/**
|
47 |
+
* Tags traits about the user.
|
48 |
+
*
|
49 |
+
* @param array $message
|
50 |
+
* @return [boolean] whether the identify call succeeded
|
51 |
+
*/
|
52 |
+
public function identify(array $message) {
|
53 |
+
return $this->write($message);
|
54 |
+
}
|
55 |
+
|
56 |
+
/**
|
57 |
+
* Tags traits about the group.
|
58 |
+
*
|
59 |
+
* @param array $message
|
60 |
+
* @return [boolean] whether the group call succeeded
|
61 |
+
*/
|
62 |
+
public function group(array $message) {
|
63 |
+
return $this->write($message);
|
64 |
+
}
|
65 |
+
|
66 |
+
/**
|
67 |
+
* Tracks a page view.
|
68 |
+
*
|
69 |
+
* @param array $message
|
70 |
+
* @return [boolean] whether the page call succeeded
|
71 |
+
*/
|
72 |
+
public function page(array $message) {
|
73 |
+
return $this->write($message);
|
74 |
+
}
|
75 |
+
|
76 |
+
/**
|
77 |
+
* Tracks a screen view.
|
78 |
+
*
|
79 |
+
* @param array $message
|
80 |
+
* @return [boolean] whether the screen call succeeded
|
81 |
+
*/
|
82 |
+
public function screen(array $message) {
|
83 |
+
return $this->write($message);
|
84 |
+
}
|
85 |
+
|
86 |
+
/**
|
87 |
+
* Aliases from one user id to another
|
88 |
+
*
|
89 |
+
* @param array $message
|
90 |
+
* @return boolean whether the alias call succeeded
|
91 |
+
*/
|
92 |
+
public function alias(array $message) {
|
93 |
+
return $this->write($message);
|
94 |
+
}
|
95 |
+
|
96 |
+
/**
|
97 |
+
* Writes the API call to a file as line-delimited json
|
98 |
+
* @param [array] $body post body content.
|
99 |
+
* @return [boolean] whether the request succeeded
|
100 |
+
*/
|
101 |
+
private function write($body) {
|
102 |
+
|
103 |
+
if (!$this->file_handle)
|
104 |
+
return false;
|
105 |
+
|
106 |
+
$content = json_encode($body);
|
107 |
+
$content.= "\n";
|
108 |
+
|
109 |
+
return fwrite($this->file_handle, $content) == strlen($content);
|
110 |
+
}
|
111 |
+
}
|
lib/segment/lib/Segment/Consumer/ForkCurl.php
ADDED
@@ -0,0 +1,59 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class Segment_Consumer_ForkCurl extends Segment_QueueConsumer {
|
4 |
+
|
5 |
+
protected $type = "ForkCurl";
|
6 |
+
|
7 |
+
|
8 |
+
/**
|
9 |
+
* Creates a new queued fork consumer which queues fork and identify
|
10 |
+
* calls before adding them to
|
11 |
+
* @param string $secret
|
12 |
+
* @param array $options
|
13 |
+
* boolean "debug" - whether to use debug output, wait for response.
|
14 |
+
* number "max_queue_size" - the max size of messages to enqueue
|
15 |
+
* number "batch_size" - how many messages to send in a single request
|
16 |
+
*/
|
17 |
+
public function __construct($secret, $options = array()) {
|
18 |
+
parent::__construct($secret, $options);
|
19 |
+
}
|
20 |
+
|
21 |
+
/**
|
22 |
+
* Make an async request to our API. Fork a curl process, immediately send
|
23 |
+
* to the API. If debug is enabled, we wait for the response.
|
24 |
+
* @param array $messages array of all the messages to send
|
25 |
+
* @return boolean whether the request succeeded
|
26 |
+
*/
|
27 |
+
public function flushBatch($messages) {
|
28 |
+
|
29 |
+
$body = array(
|
30 |
+
"batch" => $messages,
|
31 |
+
);
|
32 |
+
|
33 |
+
$payload = json_encode($body);
|
34 |
+
|
35 |
+
# Escape for shell usage.
|
36 |
+
$payload = escapeshellarg($payload);
|
37 |
+
$secret = $this->secret;
|
38 |
+
|
39 |
+
$protocol = $this->ssl() ? "https://" : "http://";
|
40 |
+
$host = "api.segment.io";
|
41 |
+
$path = "/v1/import";
|
42 |
+
$url = $protocol . $host . $path;
|
43 |
+
|
44 |
+
$cmd = "curl -u $secret: -X POST -H 'Content-Type: application/json'";
|
45 |
+
$cmd.= " -d " . $payload . " '" . $url . "'";
|
46 |
+
|
47 |
+
if (!$this->debug()) {
|
48 |
+
$cmd .= " > /dev/null 2>&1 &";
|
49 |
+
}
|
50 |
+
|
51 |
+
exec($cmd, $output, $exit);
|
52 |
+
|
53 |
+
if ($exit != 0) {
|
54 |
+
$this->handleError($exit, $output);
|
55 |
+
}
|
56 |
+
|
57 |
+
return $exit == 0;
|
58 |
+
}
|
59 |
+
}
|
lib/segment/lib/Segment/Consumer/Socket.php
ADDED
@@ -0,0 +1,174 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class Segment_Consumer_Socket extends Segment_QueueConsumer {
|
4 |
+
|
5 |
+
protected $type = "Socket";
|
6 |
+
private $socket_failed;
|
7 |
+
|
8 |
+
/**
|
9 |
+
* Creates a new socket consumer for dispatching async requests immediately
|
10 |
+
* @param string $secret
|
11 |
+
* @param array $options
|
12 |
+
* number "timeout" - the timeout for connecting
|
13 |
+
* function "error_handler" - function called back on errors.
|
14 |
+
* boolean "debug" - whether to use debug output, wait for response.
|
15 |
+
*/
|
16 |
+
public function __construct($secret, $options = array()) {
|
17 |
+
|
18 |
+
if (!isset($options["timeout"]))
|
19 |
+
$options["timeout"] = 0.5;
|
20 |
+
|
21 |
+
if (!isset($options["host"]))
|
22 |
+
$options["host"] = "api.segment.io";
|
23 |
+
|
24 |
+
parent::__construct($secret, $options);
|
25 |
+
}
|
26 |
+
|
27 |
+
|
28 |
+
public function flushBatch($batch) {
|
29 |
+
$socket = $this->createSocket();
|
30 |
+
|
31 |
+
if (!$socket)
|
32 |
+
return;
|
33 |
+
|
34 |
+
$payload = array("batch" => $batch);
|
35 |
+
|
36 |
+
$payload = json_encode($payload);
|
37 |
+
|
38 |
+
$body = $this->createBody($this->options["host"], $payload);
|
39 |
+
return $this->makeRequest($socket, $body);
|
40 |
+
}
|
41 |
+
|
42 |
+
|
43 |
+
private function createSocket() {
|
44 |
+
|
45 |
+
if ($this->socket_failed)
|
46 |
+
return false;
|
47 |
+
|
48 |
+
$protocol = $this->ssl() ? "ssl" : "tcp";
|
49 |
+
$host = $this->options["host"];
|
50 |
+
$port = $this->ssl() ? 443 : 80;
|
51 |
+
$timeout = $this->options["timeout"];
|
52 |
+
|
53 |
+
try {
|
54 |
+
# Open our socket to the API Server.
|
55 |
+
# Since we're try catch'ing prevent PHP logs.
|
56 |
+
$socket = @pfsockopen($protocol . "://" . $host, $port, $errno,
|
57 |
+
$errstr, $timeout);
|
58 |
+
|
59 |
+
# If we couldn't open the socket, handle the error.
|
60 |
+
if ($errno != 0) {
|
61 |
+
$this->handleError($errno, $errstr);
|
62 |
+
$this->socket_failed = true;
|
63 |
+
return false;
|
64 |
+
}
|
65 |
+
|
66 |
+
return $socket;
|
67 |
+
|
68 |
+
} catch (Exception $e) {
|
69 |
+
$this->handleError($e->getCode(), $e->getMessage());
|
70 |
+
$this->socket_failed = true;
|
71 |
+
return false;
|
72 |
+
}
|
73 |
+
}
|
74 |
+
|
75 |
+
/**
|
76 |
+
* Attempt to write the request to the socket, wait for response if debug
|
77 |
+
* mode is enabled.
|
78 |
+
* @param stream $socket the handle for the socket
|
79 |
+
* @param string $req request body
|
80 |
+
* @return boolean $success
|
81 |
+
*/
|
82 |
+
private function makeRequest($socket, $req, $retry = true) {
|
83 |
+
|
84 |
+
$bytes_written = 0;
|
85 |
+
$bytes_total = strlen($req);
|
86 |
+
$closed = false;
|
87 |
+
|
88 |
+
# Write the request
|
89 |
+
while (!$closed && $bytes_written < $bytes_total) {
|
90 |
+
try {
|
91 |
+
# Since we're try catch'ing prevent PHP logs.
|
92 |
+
$written = @fwrite($socket, substr($req, $bytes_written));
|
93 |
+
} catch (Exception $e) {
|
94 |
+
$this->handleError($e->getCode(), $e->getMessage());
|
95 |
+
$closed = true;
|
96 |
+
}
|
97 |
+
if (!isset($written) || !$written) {
|
98 |
+
$closed = true;
|
99 |
+
} else {
|
100 |
+
$bytes_written += $written;
|
101 |
+
}
|
102 |
+
}
|
103 |
+
|
104 |
+
# If the socket has been closed, attempt to retry a single time.
|
105 |
+
if ($closed) {
|
106 |
+
fclose($socket);
|
107 |
+
|
108 |
+
if ($retry) {
|
109 |
+
$socket = $this->createSocket();
|
110 |
+
if ($socket) return $this->makeRequest($socket, $req, false);
|
111 |
+
}
|
112 |
+
return false;
|
113 |
+
}
|
114 |
+
|
115 |
+
|
116 |
+
$success = true;
|
117 |
+
|
118 |
+
if ($this->debug()) {
|
119 |
+
$res = $this->parseResponse(fread($socket, 2048));
|
120 |
+
|
121 |
+
if ($res["status"] != "200") {
|
122 |
+
$this->handleError($res["status"], $res["message"]);
|
123 |
+
$success = false;
|
124 |
+
}
|
125 |
+
}
|
126 |
+
|
127 |
+
return $success;
|
128 |
+
}
|
129 |
+
|
130 |
+
|
131 |
+
/**
|
132 |
+
* Create the body to send as the post request.
|
133 |
+
* @param string $host
|
134 |
+
* @param string $content
|
135 |
+
* @return string body
|
136 |
+
*/
|
137 |
+
private function createBody($host, $content) {
|
138 |
+
|
139 |
+
$req = "";
|
140 |
+
$req.= "POST /v1/import HTTP/1.1\r\n";
|
141 |
+
$req.= "Host: " . $host . "\r\n";
|
142 |
+
$req.= "Content-Type: application/json\r\n";
|
143 |
+
$req.= "Authorization: Basic " . base64_encode($this->secret . ":") . "\r\n";
|
144 |
+
$req.= "Accept: application/json\r\n";
|
145 |
+
$req.= "Content-length: " . strlen($content) . "\r\n";
|
146 |
+
$req.= "\r\n";
|
147 |
+
$req.= $content;
|
148 |
+
|
149 |
+
return $req;
|
150 |
+
}
|
151 |
+
|
152 |
+
|
153 |
+
/**
|
154 |
+
* Parse our response from the server, check header and body.
|
155 |
+
* @param string $res
|
156 |
+
* @return array
|
157 |
+
* string $status HTTP code, e.g. "200"
|
158 |
+
* string $message JSON response from the api
|
159 |
+
*/
|
160 |
+
private function parseResponse($res) {
|
161 |
+
|
162 |
+
$contents = explode("\n", $res);
|
163 |
+
|
164 |
+
# Response comes back as HTTP/1.1 200 OK
|
165 |
+
# Final line contains HTTP response.
|
166 |
+
$status = explode(" ", $contents[0], 3);
|
167 |
+
$result = $contents[count($contents) - 1];
|
168 |
+
|
169 |
+
return array(
|
170 |
+
"status" => isset($status[1]) ? $status[1] : null,
|
171 |
+
"message" => $result
|
172 |
+
);
|
173 |
+
}
|
174 |
+
}
|
lib/segment/lib/Segment/QueueConsumer.php
ADDED
@@ -0,0 +1,138 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
abstract class Segment_QueueConsumer extends Segment_Consumer {
|
3 |
+
|
4 |
+
protected $type = "QueueConsumer";
|
5 |
+
|
6 |
+
protected $queue;
|
7 |
+
protected $max_queue_size = 1000;
|
8 |
+
protected $batch_size = 100;
|
9 |
+
|
10 |
+
/**
|
11 |
+
* Store our secret and options as part of this consumer
|
12 |
+
* @param string $secret
|
13 |
+
* @param array $options
|
14 |
+
*/
|
15 |
+
public function __construct($secret, $options = array()) {
|
16 |
+
parent::__construct($secret, $options);
|
17 |
+
|
18 |
+
if (isset($options["max_queue_size"]))
|
19 |
+
$this->max_queue_size = $options["max_queue_size"];
|
20 |
+
|
21 |
+
if (isset($options["batch_size"]))
|
22 |
+
$this->batch_size = $options["batch_size"];
|
23 |
+
|
24 |
+
$this->queue = array();
|
25 |
+
}
|
26 |
+
|
27 |
+
public function __destruct() {
|
28 |
+
# Flush our queue on destruction
|
29 |
+
$this->flush();
|
30 |
+
}
|
31 |
+
|
32 |
+
/**
|
33 |
+
* Tracks a user action
|
34 |
+
*
|
35 |
+
* @param array $message
|
36 |
+
* @return boolean whether the track call succeeded
|
37 |
+
*/
|
38 |
+
public function track(array $message) {
|
39 |
+
return $this->enqueue($message);
|
40 |
+
}
|
41 |
+
|
42 |
+
/**
|
43 |
+
* Tags traits about the user.
|
44 |
+
*
|
45 |
+
* @param array $message
|
46 |
+
* @return boolean whether the identify call succeeded
|
47 |
+
*/
|
48 |
+
public function identify(array $message) {
|
49 |
+
return $this->enqueue($message);
|
50 |
+
}
|
51 |
+
|
52 |
+
/**
|
53 |
+
* Tags traits about the group.
|
54 |
+
*
|
55 |
+
* @param array $message
|
56 |
+
* @return boolean whether the group call succeeded
|
57 |
+
*/
|
58 |
+
public function group(array $message) {
|
59 |
+
return $this->enqueue($message);
|
60 |
+
}
|
61 |
+
|
62 |
+
/**
|
63 |
+
* Tracks a page view.
|
64 |
+
*
|
65 |
+
* @param array $message
|
66 |
+
* @return boolean whether the page call succeeded
|
67 |
+
*/
|
68 |
+
public function page(array $message) {
|
69 |
+
return $this->enqueue($message);
|
70 |
+
}
|
71 |
+
|
72 |
+
/**
|
73 |
+
* Tracks a screen view.
|
74 |
+
*
|
75 |
+
* @param array $message
|
76 |
+
* @return boolean whether the screen call succeeded
|
77 |
+
*/
|
78 |
+
public function screen(array $message) {
|
79 |
+
return $this->enqueue($message);
|
80 |
+
}
|
81 |
+
|
82 |
+
/**
|
83 |
+
* Aliases from one user id to another
|
84 |
+
*
|
85 |
+
* @param array $message
|
86 |
+
* @return boolean whether the alias call succeeded
|
87 |
+
*/
|
88 |
+
public function alias(array $message) {
|
89 |
+
return $this->enqueue($message);
|
90 |
+
}
|
91 |
+
|
92 |
+
/**
|
93 |
+
* Adds an item to our queue.
|
94 |
+
* @param mixed $item
|
95 |
+
* @return boolean whether the queue has room
|
96 |
+
*/
|
97 |
+
protected function enqueue($item) {
|
98 |
+
|
99 |
+
$count = count($this->queue);
|
100 |
+
|
101 |
+
if ($count > $this->max_queue_size)
|
102 |
+
return false;
|
103 |
+
|
104 |
+
$count = array_push($this->queue, $item);
|
105 |
+
|
106 |
+
if ($count > $this->batch_size)
|
107 |
+
$this->flush();
|
108 |
+
|
109 |
+
return true;
|
110 |
+
}
|
111 |
+
|
112 |
+
|
113 |
+
/**
|
114 |
+
* Flushes our queue of messages by batching them to the server
|
115 |
+
*/
|
116 |
+
public function flush() {
|
117 |
+
|
118 |
+
$count = count($this->queue);
|
119 |
+
$success = true;
|
120 |
+
|
121 |
+
while($count > 0 && $success) {
|
122 |
+
|
123 |
+
$batch = array_splice($this->queue, 0, min($this->batch_size, $count));
|
124 |
+
$success = $this->flushBatch($batch);
|
125 |
+
|
126 |
+
$count = count($this->queue);
|
127 |
+
}
|
128 |
+
|
129 |
+
return $success;
|
130 |
+
}
|
131 |
+
|
132 |
+
/**
|
133 |
+
* Flushes a batch of messages.
|
134 |
+
* @param [type] $batch [description]
|
135 |
+
* @return [type] [description]
|
136 |
+
*/
|
137 |
+
abstract function flushBatch($batch);
|
138 |
+
}
|
lib/segment/send.php
ADDED
@@ -0,0 +1,106 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* require client
|
5 |
+
*/
|
6 |
+
|
7 |
+
require(__DIR__ . "/lib/Segment.php");
|
8 |
+
|
9 |
+
/**
|
10 |
+
* Args
|
11 |
+
*/
|
12 |
+
|
13 |
+
$args = parse($argv);
|
14 |
+
|
15 |
+
/**
|
16 |
+
* Make sure both are set
|
17 |
+
*/
|
18 |
+
|
19 |
+
if (!isset($args["secret"])) die("--secret must be given");
|
20 |
+
if (!isset($args["file"])) die("--file must be given");
|
21 |
+
|
22 |
+
$file = $args["file"];
|
23 |
+
if ($file[0] != '/') $file = __DIR__ . "/" . $file;
|
24 |
+
|
25 |
+
/**
|
26 |
+
* Rename the file so we don't write the same calls
|
27 |
+
* multiple times
|
28 |
+
*/
|
29 |
+
|
30 |
+
$dir = dirname($file);
|
31 |
+
$old = $file;
|
32 |
+
$file = $dir . '/analytics-' . rand() . '.log';
|
33 |
+
|
34 |
+
if(!file_exists($old)) {
|
35 |
+
print("file: $old does not exist");
|
36 |
+
exit(0);
|
37 |
+
}
|
38 |
+
|
39 |
+
if (!rename($old, $file)) {
|
40 |
+
print("error renaming from $old to $new\n");
|
41 |
+
exit(1);
|
42 |
+
}
|
43 |
+
|
44 |
+
/**
|
45 |
+
* File contents.
|
46 |
+
*/
|
47 |
+
|
48 |
+
$contents = file_get_contents($file);
|
49 |
+
$lines = explode("\n", $contents);
|
50 |
+
|
51 |
+
/**
|
52 |
+
* Initialize the client.
|
53 |
+
*/
|
54 |
+
|
55 |
+
Segment::init($args["secret"], array(
|
56 |
+
"debug" => true,
|
57 |
+
"on_error" => function($code, $msg){
|
58 |
+
print("$code: $msg\n");
|
59 |
+
exit(1);
|
60 |
+
}
|
61 |
+
));
|
62 |
+
|
63 |
+
/**
|
64 |
+
* Payloads
|
65 |
+
*/
|
66 |
+
|
67 |
+
$total = 0;
|
68 |
+
$successful = 0;
|
69 |
+
foreach ($lines as $line) {
|
70 |
+
if (!trim($line)) continue;
|
71 |
+
$payload = json_decode($line, true);
|
72 |
+
$dt = new DateTime($payload["timestamp"]);
|
73 |
+
$ts = floatval($dt->getTimestamp() . "." . $dt->format("u"));
|
74 |
+
$payload["timestamp"] = $ts;
|
75 |
+
$type = $payload["type"];
|
76 |
+
$ret = call_user_func_array(array("Segment", $type), array($payload));
|
77 |
+
if ($ret) $successful++;
|
78 |
+
$total++;
|
79 |
+
if ($total % 100 === 0) Segment::flush();
|
80 |
+
}
|
81 |
+
|
82 |
+
Segment::flush();
|
83 |
+
unlink($file);
|
84 |
+
|
85 |
+
/**
|
86 |
+
* Sent
|
87 |
+
*/
|
88 |
+
|
89 |
+
print("sent $successful from $total requests successfully");
|
90 |
+
exit(0);
|
91 |
+
|
92 |
+
/**
|
93 |
+
* Parse arguments
|
94 |
+
*/
|
95 |
+
|
96 |
+
function parse($argv){
|
97 |
+
$ret = array();
|
98 |
+
|
99 |
+
for ($i = 0; $i < count($argv); ++$i) {
|
100 |
+
$arg = $argv[$i];
|
101 |
+
if ('--' != substr($arg, 0, 2)) continue;
|
102 |
+
$ret[substr($arg, 2, strlen($arg))] = trim($argv[++$i]);
|
103 |
+
}
|
104 |
+
|
105 |
+
return $ret;
|
106 |
+
}
|
power-ups/aweber-connect.php
ADDED
@@ -0,0 +1,168 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Power-up Name: AWeber
|
4 |
+
* Power-up Class: LIAWeberConnect
|
5 |
+
* Power-up Menu Text:
|
6 |
+
* Power-up Slug: aweber_connect
|
7 |
+
* Power-up Menu Link: settings
|
8 |
+
* Power-up URI: http://leadin.com/wordpress-mailchimp-sync-plugin/
|
9 |
+
* Power-up Description: Push your contacts to AWeber email lists.
|
10 |
+
* Power-up Icon: power-up-icon-aweber-connect
|
11 |
+
* Power-up Icon Small: power-up-icon-aweber-connect_small
|
12 |
+
* First Introduced: 2.3.0
|
13 |
+
* Power-up Tags: Newsletter, Email
|
14 |
+
* Auto Activate: No
|
15 |
+
* Permanently Enabled: No
|
16 |
+
* Hidden: No
|
17 |
+
* cURL Required: Yes
|
18 |
+
*/
|
19 |
+
|
20 |
+
//=============================================
|
21 |
+
// Define Constants
|
22 |
+
//=============================================
|
23 |
+
|
24 |
+
if ( !defined('LEADIN_AWEBER_CONNECT_PATH') )
|
25 |
+
define('LEADIN_AWEBER_CONNECT_PATH', LEADIN_PATH . '/power-ups/aweber-connect');
|
26 |
+
|
27 |
+
if ( !defined('LEADIN_AWEBER_CONNECT_PLUGIN_DIR') )
|
28 |
+
define('LEADIN_AWEBER_CONNECT_PLUGIN_DIR', LEADIN_PLUGIN_DIR . '/power-ups/aweber-connect');
|
29 |
+
|
30 |
+
if ( !defined('LEADIN_AWEBER_CONNECT_PLUGIN_SLUG') )
|
31 |
+
define('LEADIN_AWEBER_CONNECT_PLUGIN_SLUG', basename(dirname(__FILE__)));
|
32 |
+
|
33 |
+
//=============================================
|
34 |
+
// Include Needed Files
|
35 |
+
//=============================================
|
36 |
+
require_once(LEADIN_AWEBER_CONNECT_PLUGIN_DIR . '/admin/aweber-connect-admin.php');
|
37 |
+
require_once(LEADIN_AWEBER_CONNECT_PLUGIN_DIR . '/inc/aweber_api/li_aweber_api.php');
|
38 |
+
|
39 |
+
//=============================================
|
40 |
+
// WPLeadIn Class
|
41 |
+
//=============================================
|
42 |
+
class LIAWeberConnect extends WPLeadIn {
|
43 |
+
|
44 |
+
var $admin;
|
45 |
+
var $options;
|
46 |
+
var $power_option_name = 'leadin_aweber_connect_options';
|
47 |
+
|
48 |
+
/**
|
49 |
+
* Class constructor
|
50 |
+
*/
|
51 |
+
function __construct ( $activated )
|
52 |
+
{
|
53 |
+
//=============================================
|
54 |
+
// Hooks & Filters
|
55 |
+
//=============================================
|
56 |
+
|
57 |
+
if ( ! $activated )
|
58 |
+
return false;
|
59 |
+
|
60 |
+
global $leadin_aweber_connect_wp;
|
61 |
+
$leadin_aweber_connect_wp = $this;
|
62 |
+
$this->options = get_option($this->power_option_name);
|
63 |
+
}
|
64 |
+
|
65 |
+
public function admin_init ( )
|
66 |
+
{
|
67 |
+
$admin_class = get_class($this) . 'Admin';
|
68 |
+
$this->admin = new $admin_class($this->icon_small);
|
69 |
+
}
|
70 |
+
|
71 |
+
function power_up_setup_callback ( )
|
72 |
+
{
|
73 |
+
$this->admin->power_up_setup_callback();
|
74 |
+
}
|
75 |
+
|
76 |
+
/**
|
77 |
+
* Activate the power-up and add the defaults
|
78 |
+
*/
|
79 |
+
function add_defaults ()
|
80 |
+
{
|
81 |
+
|
82 |
+
}
|
83 |
+
|
84 |
+
/**
|
85 |
+
* Adds a subcsriber to a specific list
|
86 |
+
*
|
87 |
+
* @param string
|
88 |
+
* @param string
|
89 |
+
* @param string
|
90 |
+
* @param string
|
91 |
+
* @param string
|
92 |
+
* @return int/bool
|
93 |
+
*/
|
94 |
+
function push_contact_to_list ( $list_id = '', $email = '', $first_name = '', $last_name = '', $phone = '' )
|
95 |
+
{
|
96 |
+
if ( isset($this->options['li_ac_ck']) && $this->options['li_ac_ck'] && $list_id )
|
97 |
+
{
|
98 |
+
try
|
99 |
+
{
|
100 |
+
$aweber = new LI_AWeberAPI($this->options['li_ac_ck'], $this->options['li_ac_cs']);
|
101 |
+
$account = $aweber->getAccount($this->options['li_ac_ak'], $this->options['li_ac_as']);
|
102 |
+
|
103 |
+
$list_url = "/accounts/" . $account->id . "/lists/" . $list_id;
|
104 |
+
|
105 |
+
//Check if custom Field Exists
|
106 |
+
$list_custom_fields_url = "/accounts/" . $account->id . "/lists/" . $list_id . "/custom_fields";
|
107 |
+
$list_custom_fields = $account->loadFromUrl($list_custom_fields_url);
|
108 |
+
|
109 |
+
$params = array(
|
110 |
+
'email' => $email,
|
111 |
+
'name' => $first_name . $last_name
|
112 |
+
);
|
113 |
+
|
114 |
+
if ( count($list_custom_fields->data['entries']) )
|
115 |
+
{
|
116 |
+
foreach ( $list_custom_fields->data['entries'] as $entry )
|
117 |
+
{
|
118 |
+
if ( $entry['name'] == 'phone' )
|
119 |
+
{
|
120 |
+
$params['custom_fields'] = array('phone' => $phone);
|
121 |
+
break;
|
122 |
+
}
|
123 |
+
}
|
124 |
+
}
|
125 |
+
|
126 |
+
$list = $account->loadFromUrl($list_url);
|
127 |
+
|
128 |
+
$subscribers = $list->subscribers;
|
129 |
+
$subscribers->create($params);
|
130 |
+
|
131 |
+
leadin_track_plugin_activity('Contact Pushed to List', array('esp_connector' => 'aweber'));
|
132 |
+
|
133 |
+
return TRUE;
|
134 |
+
}
|
135 |
+
catch ( AWeberAPIException $exc )
|
136 |
+
{
|
137 |
+
|
138 |
+
}
|
139 |
+
}
|
140 |
+
|
141 |
+
return FALSE;
|
142 |
+
}
|
143 |
+
|
144 |
+
/**
|
145 |
+
* Adds a subcsriber to a specific list
|
146 |
+
*
|
147 |
+
* @param string
|
148 |
+
* @param array
|
149 |
+
* @return int/bool API status code OR false if api key not set
|
150 |
+
*/
|
151 |
+
function bulk_push_contact_to_list ( $list_id = '', $contacts = '' )
|
152 |
+
{
|
153 |
+
/*
|
154 |
+
The majority of our user base doesn't use AWeber, so we decided not to retroactively sync contacts to the list.
|
155 |
+
If people complain, we will respond with a support ticket and ask them to export/import manually.
|
156 |
+
*/
|
157 |
+
|
158 |
+
return FALSE;
|
159 |
+
}
|
160 |
+
}
|
161 |
+
|
162 |
+
//=============================================
|
163 |
+
// ESP Connect Init
|
164 |
+
//=============================================
|
165 |
+
|
166 |
+
global $leadin_aweber_connect_wp;
|
167 |
+
|
168 |
+
?>
|
power-ups/aweber-connect/admin/aweber-connect-admin.php
ADDED
@@ -0,0 +1,323 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
//=============================================
|
3 |
+
// LIAweberConnectAdmin Class
|
4 |
+
//=============================================
|
5 |
+
class LIAweberConnectAdmin extends WPLeadInAdmin {
|
6 |
+
|
7 |
+
var $power_up_settings_section = 'leadin_aweber_connect_options_section';
|
8 |
+
var $power_option_name = 'leadin_aweber_connect_options';
|
9 |
+
var $power_up_icon;
|
10 |
+
var $options;
|
11 |
+
var $authed = FALSE;
|
12 |
+
var $invalid_key = FALSE;
|
13 |
+
|
14 |
+
/**
|
15 |
+
* Class constructor
|
16 |
+
*/
|
17 |
+
function __construct ( $power_up_icon_small )
|
18 |
+
{
|
19 |
+
//=============================================
|
20 |
+
// Hooks & Filters
|
21 |
+
//=============================================
|
22 |
+
|
23 |
+
if ( is_admin() )
|
24 |
+
{
|
25 |
+
$this->power_up_icon = $power_up_icon_small;
|
26 |
+
add_action('admin_init', array($this, 'leadin_build_esp_settings_page'));
|
27 |
+
$this->options = get_option($this->power_option_name);
|
28 |
+
$this->authed = ( isset($this->options['li_ac_auth_code']) && $this->options['li_ac_auth_code'] ? TRUE : FALSE );
|
29 |
+
|
30 |
+
if ( $this->authed )
|
31 |
+
{
|
32 |
+
if ( ! isset($this->options['li_ac_ck']) )
|
33 |
+
{
|
34 |
+
$this->li_ac_connect_to_api($this->options['li_ac_auth_code']);
|
35 |
+
}
|
36 |
+
else
|
37 |
+
{
|
38 |
+
$this->invalid_key = $this->li_ac_check_invalid_auth_code($this->options['li_ac_ck'], $this->options['li_ac_cs'], $this->options['li_ac_ak'], $this->options['li_ac_as']);
|
39 |
+
}
|
40 |
+
}
|
41 |
+
}
|
42 |
+
}
|
43 |
+
|
44 |
+
//=============================================
|
45 |
+
// Settings Page
|
46 |
+
//=============================================
|
47 |
+
|
48 |
+
/**
|
49 |
+
* Creates settings options
|
50 |
+
*/
|
51 |
+
function leadin_build_esp_settings_page ()
|
52 |
+
{
|
53 |
+
register_setting('leadin_settings_options', $this->power_option_name, array($this, 'sanitize'));
|
54 |
+
add_settings_section($this->power_up_settings_section, $this->power_up_icon . "AWeber", array($this, 'aweber_connect_section_callback'), LEADIN_ADMIN_PATH);
|
55 |
+
add_settings_field('li_ac_auth_code', 'Authorization Code', array($this, 'li_ac_auth_code_callback'), LEADIN_ADMIN_PATH, $this->power_up_settings_section);
|
56 |
+
|
57 |
+
if ( isset($this->options['li_ac_auth_code']) )
|
58 |
+
{
|
59 |
+
if ( $this->options['li_ac_auth_code'] )
|
60 |
+
add_settings_field('li_print_synced_lists', 'Synced tags', array($this, 'li_print_synced_lists'), LEADIN_ADMIN_PATH, $this->power_up_settings_section);
|
61 |
+
}
|
62 |
+
}
|
63 |
+
|
64 |
+
function aweber_connect_section_callback ( )
|
65 |
+
{
|
66 |
+
$this->print_hidden_settings_fields();
|
67 |
+
}
|
68 |
+
|
69 |
+
function print_hidden_settings_fields ()
|
70 |
+
{
|
71 |
+
// Hacky solution to solve the Settings API overwriting the default values
|
72 |
+
$li_ac_ck = ( $this->options['li_ac_ck'] ? $this->options['li_ac_ck'] : '' );
|
73 |
+
$li_ac_cs = ( $this->options['li_ac_cs'] ? $this->options['li_ac_cs'] : '' );
|
74 |
+
$li_ac_ak = ( $this->options['li_ac_ak'] ? $this->options['li_ac_ak'] : '' );
|
75 |
+
$li_ac_as = ( $this->options['li_ac_as'] ? $this->options['li_ac_as'] : '' );
|
76 |
+
|
77 |
+
if ( $li_ac_ck )
|
78 |
+
{
|
79 |
+
printf(
|
80 |
+
'<input id="li_ac_ck" type="hidden" name="' . $this->power_option_name . '[li_ac_ck]" value="%s"/>',
|
81 |
+
$li_ac_ck
|
82 |
+
);
|
83 |
+
}
|
84 |
+
|
85 |
+
if ( $li_ac_cs )
|
86 |
+
{
|
87 |
+
printf(
|
88 |
+
'<input id="li_ac_cs" type="hidden" name="' . $this->power_option_name . '[li_ac_cs]" value="%s"/>',
|
89 |
+
$li_ac_cs
|
90 |
+
);
|
91 |
+
}
|
92 |
+
|
93 |
+
if ( $li_ac_ak )
|
94 |
+
{
|
95 |
+
printf(
|
96 |
+
'<input id="li_ac_ak" type="hidden" name="' . $this->power_option_name . '[li_ac_ak]" value="%s"/>',
|
97 |
+
$li_ac_ak
|
98 |
+
);
|
99 |
+
}
|
100 |
+
|
101 |
+
if ( $li_ac_as )
|
102 |
+
{
|
103 |
+
printf(
|
104 |
+
'<input id="li_ac_as" type="hidden" name="' . $this->power_option_name . '[li_ac_as]" value="%s"/>',
|
105 |
+
$li_ac_as
|
106 |
+
);
|
107 |
+
}
|
108 |
+
}
|
109 |
+
|
110 |
+
/**
|
111 |
+
* Sanitize each setting field as needed
|
112 |
+
*
|
113 |
+
* @param array $input Contains all settings fields as array keys
|
114 |
+
*/
|
115 |
+
public function sanitize ( $input )
|
116 |
+
{
|
117 |
+
$new_input = array();
|
118 |
+
|
119 |
+
if ( isset( $input['li_ac_auth_code'] ) )
|
120 |
+
$new_input['li_ac_auth_code'] = sanitize_text_field( $input['li_ac_auth_code'] );
|
121 |
+
|
122 |
+
if ( isset( $input['li_ac_ck'] ) )
|
123 |
+
$new_input['li_ac_ck'] = sanitize_text_field( $input['li_ac_ck'] );
|
124 |
+
|
125 |
+
if ( isset( $input['li_ac_cs'] ) )
|
126 |
+
$new_input['li_ac_cs'] = sanitize_text_field( $input['li_ac_cs'] );
|
127 |
+
|
128 |
+
if ( isset( $input['li_ac_ak'] ) )
|
129 |
+
$new_input['li_ac_ak'] = sanitize_text_field( $input['li_ac_ak'] );
|
130 |
+
|
131 |
+
if ( isset( $input['li_ac_as'] ) )
|
132 |
+
$new_input['li_ac_as'] = sanitize_text_field( $input['li_ac_as'] );
|
133 |
+
|
134 |
+
return $new_input;
|
135 |
+
}
|
136 |
+
|
137 |
+
/**
|
138 |
+
* Prints API key input for settings page
|
139 |
+
*/
|
140 |
+
function li_ac_auth_code_callback ()
|
141 |
+
{
|
142 |
+
$li_ac_auth_code = ( $this->options['li_ac_auth_code'] ? $this->options['li_ac_auth_code'] : '' ); // Get header from options, or show default
|
143 |
+
|
144 |
+
printf(
|
145 |
+
'<input id="li_ac_auth_code" type="text" id="title" name="' . $this->power_option_name . '[li_ac_auth_code]" value="%s" style="width: 430px;"/>',
|
146 |
+
$li_ac_auth_code
|
147 |
+
);
|
148 |
+
|
149 |
+
if ( ! isset($li_ac_auth_code) || ! $li_ac_auth_code )
|
150 |
+
echo '<p><a target="_blank" href="https://help.aweber.com/hc/en-us/articles/204031226-How-Do-I-Authorize-an-App-">Get your Authorization Code</a> from <a href="https://auth.aweber.com/1.0/oauth/authorize_app/156b03fb" target="_blank">AWeber.com</a></p>';
|
151 |
+
}
|
152 |
+
|
153 |
+
/**
|
154 |
+
* Prints synced lists out for settings page in format Tag Name → ESP list
|
155 |
+
*/
|
156 |
+
function li_print_synced_lists ()
|
157 |
+
{
|
158 |
+
$li_ac_auth_code = ( $this->options['li_ac_auth_code'] ? $this->options['li_ac_auth_code'] : '' ); // Get header from options, or show default
|
159 |
+
|
160 |
+
if ( isset($li_ac_auth_code ) )
|
161 |
+
{
|
162 |
+
$synced_lists = $this->li_get_synced_list_for_esp('aweber');
|
163 |
+
$list_value_pairs = array();
|
164 |
+
$synced_list_count = 0;
|
165 |
+
|
166 |
+
echo '<table>';
|
167 |
+
foreach ( $synced_lists as $synced_list )
|
168 |
+
{
|
169 |
+
foreach ( stripslashes_deep(unserialize($synced_list->tag_synced_lists)) as $tag_synced_list )
|
170 |
+
{
|
171 |
+
if ( $tag_synced_list['esp'] == 'aweber' )
|
172 |
+
{
|
173 |
+
echo '<tr class="synced-list-row">';
|
174 |
+
echo '<td class="synced-list-cell"><span class="icon-tag"></span> ' . $synced_list->tag_text . '</td>';
|
175 |
+
echo '<td class="synced-list-cell"><span class="synced-list-arrow">→</span></td>';
|
176 |
+
echo '<td class="synced-list-cell"><span class="icon-envelope"></span> ' . $tag_synced_list['list_name'] . '</td>';
|
177 |
+
echo '<td class="synced-list-edit"><a href="' . get_bloginfo('wpurl') . '/wp-admin/admin.php?page=leadin_tags&action=edit_tag&tag=' . $synced_list->tag_id . '">edit tag</a></td>';
|
178 |
+
echo '</tr>';
|
179 |
+
|
180 |
+
$synced_list_count++;
|
181 |
+
}
|
182 |
+
}
|
183 |
+
}
|
184 |
+
echo '</table>';
|
185 |
+
|
186 |
+
if ( ! $synced_list_count ) {
|
187 |
+
echo '<p>AWeber connected succesfully! <a href="' . get_bloginfo('wpurl') . '/wp-admin/admin.php?page=leadin_tags">Select a tag to send contacts to AWeber</a>.</p>';
|
188 |
+
} else {
|
189 |
+
echo '<p><a href="' . get_bloginfo('wpurl') . '/wp-admin/admin.php?page=leadin_tags">Edit your tags</a> or <a href="https://www.aweber.com/users/newlist#about" target="_blank">Create a new list on AWeber.com</a></p>';
|
190 |
+
}
|
191 |
+
}
|
192 |
+
}
|
193 |
+
|
194 |
+
/**
|
195 |
+
* Get synced list for the ESP from the WordPress database
|
196 |
+
*
|
197 |
+
* @return array/object
|
198 |
+
*/
|
199 |
+
function li_get_synced_list_for_esp ( $esp_name, $output_type = 'OBJECT' )
|
200 |
+
{
|
201 |
+
global $wpdb;
|
202 |
+
|
203 |
+
$q = $wpdb->prepare("SELECT * FROM $wpdb->li_tags WHERE tag_synced_lists LIKE '%%%s%%' AND tag_deleted = 0", $esp_name);
|
204 |
+
$synced_lists = $wpdb->get_results($q, $output_type);
|
205 |
+
|
206 |
+
return $synced_lists;
|
207 |
+
}
|
208 |
+
|
209 |
+
/**
|
210 |
+
* Format API-returned lists into parseable format on front end for Leadin to consume
|
211 |
+
*
|
212 |
+
* @return array
|
213 |
+
*/
|
214 |
+
function li_get_lists ( )
|
215 |
+
{
|
216 |
+
$lists = $this->li_get_api_lists($this->options['li_ac_ck'], $this->options['li_ac_cs'], $this->options['li_ac_ak'], $this->options['li_ac_as']);
|
217 |
+
|
218 |
+
$sanitized_lists = array();
|
219 |
+
if ( count($lists) )
|
220 |
+
{
|
221 |
+
foreach ( $lists as $list )
|
222 |
+
{
|
223 |
+
$list_obj = (Object)NULL;
|
224 |
+
$list_obj->id = $list->id;
|
225 |
+
$list_obj->name = $list->name;
|
226 |
+
|
227 |
+
array_push($sanitized_lists, $list_obj);;
|
228 |
+
}
|
229 |
+
}
|
230 |
+
|
231 |
+
return $sanitized_lists;
|
232 |
+
}
|
233 |
+
|
234 |
+
/**
|
235 |
+
* Get lists from AWeber account
|
236 |
+
*
|
237 |
+
* @param string
|
238 |
+
* @return array
|
239 |
+
*/
|
240 |
+
function li_get_api_lists ( $consumer_key, $consumer_secret, $access_key, $access_secret )
|
241 |
+
{
|
242 |
+
try
|
243 |
+
{
|
244 |
+
$aweber = new LI_AWeberAPI($consumer_key, $consumer_secret);
|
245 |
+
$account = $aweber->getAccount($access_key, $access_secret);
|
246 |
+
$lists = $account->lists;
|
247 |
+
return $lists;
|
248 |
+
}
|
249 |
+
catch ( LI_AWeberAPIException $exc )
|
250 |
+
{
|
251 |
+
/*print "<h3>AWeberAPIException:</h3>";
|
252 |
+
print " <li> Type: $exc->type <br>";
|
253 |
+
print " <li> Msg : $exc->message <br>";
|
254 |
+
print " <li> Docs: $exc->documentation_url <br>";
|
255 |
+
print "<hr>";*/
|
256 |
+
}
|
257 |
+
}
|
258 |
+
|
259 |
+
/**
|
260 |
+
* Use MailChimp API key to try to grab corresponding user profile to check validity of key
|
261 |
+
*
|
262 |
+
* @param string
|
263 |
+
* @return bool
|
264 |
+
*/
|
265 |
+
function li_ac_check_invalid_auth_code ( $consumer_key, $consumer_secret, $access_key, $access_secret )
|
266 |
+
{
|
267 |
+
try
|
268 |
+
{
|
269 |
+
$aweber = new LI_AWeberAPI($consumer_key, $consumer_secret);
|
270 |
+
$account = $aweber->getAccount($access_key, $access_secret);
|
271 |
+
|
272 |
+
return FALSE;
|
273 |
+
}
|
274 |
+
catch ( LI_AWeberAPIException $exc )
|
275 |
+
{
|
276 |
+
if ( $exc->type == 'UnauthorizedError' )
|
277 |
+
{
|
278 |
+
unset($this->options['li_ac_auth_code']);
|
279 |
+
unset($this->options['li_ac_ck']);
|
280 |
+
unset($this->options['li_ac_cs']);
|
281 |
+
unset($this->options['li_ac_ak']);
|
282 |
+
unset($this->options['li_ac_as']);
|
283 |
+
|
284 |
+
update_option($this->power_option_name, $this->options);
|
285 |
+
return TRUE;
|
286 |
+
}
|
287 |
+
else
|
288 |
+
return FALSE;
|
289 |
+
|
290 |
+
/*print "<h3>AWeberAPIException:</h3>";
|
291 |
+
print " <li> Type: $exc->type <br>";
|
292 |
+
print " <li> Msg : $exc->message <br>";
|
293 |
+
print " <li> Docs: $exc->documentation_url <br>";
|
294 |
+
print "<hr>";*/
|
295 |
+
}
|
296 |
+
}
|
297 |
+
|
298 |
+
function li_ac_connect_to_api ( $auth_code )
|
299 |
+
{
|
300 |
+
try
|
301 |
+
{
|
302 |
+
$auth = LI_AWeberAPI::getDataFromAweberID($auth_code);
|
303 |
+
list($consumerKey, $consumerSecret, $accessKey, $accessSecret) = $auth;
|
304 |
+
|
305 |
+
$this->options['li_ac_ck'] = $consumerKey;
|
306 |
+
$this->options['li_ac_cs'] = $consumerSecret;
|
307 |
+
$this->options['li_ac_ak'] = $accessKey;
|
308 |
+
$this->options['li_ac_as'] = $accessSecret;
|
309 |
+
|
310 |
+
update_option($this->power_option_name, $this->options);
|
311 |
+
}
|
312 |
+
catch ( LI_AWeberAPIException $exc )
|
313 |
+
{
|
314 |
+
/*print "<h3>AWeberAPIException:</h3>";
|
315 |
+
print " <li> Type: $exc->type <br>";
|
316 |
+
print " <li> Msg : $exc->message <br>";
|
317 |
+
print " <li> Docs: $exc->documentation_url <br>";
|
318 |
+
print "<hr>";*/
|
319 |
+
}
|
320 |
+
}
|
321 |
+
}
|
322 |
+
|
323 |
+
?>
|
power-ups/aweber-connect/inc/aweber_api/li_aweber.php
ADDED
@@ -0,0 +1,292 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
require_once('li_exceptions.php');
|
3 |
+
require_once('li_oauth_adapter.php');
|
4 |
+
require_once('li_oauth_application.php');
|
5 |
+
require_once('li_aweber_response.php');
|
6 |
+
require_once('li_aweber_collection.php');
|
7 |
+
require_once('li_aweber_entry_data_array.php');
|
8 |
+
require_once('li_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 LI_AWeberServiceProvider implements LI_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 LI_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 LI_AWeberEntry($response, $url, $this->adapter);
|
125 |
+
} else if (array_key_exists('entries', $response)) {
|
126 |
+
return new LI_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 LI_AWeberAPI extends LI_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) = LI_AWeberAPI::_parseAweberID($string);
|
166 |
+
|
167 |
+
if (!$verifier) {
|
168 |
+
return null;
|
169 |
+
}
|
170 |
+
$aweber = new LI_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 LI_AWeberServiceProvider();
|
224 |
+
$adapter = new LI_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 LI_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 |
+
?>
|
power-ups/aweber-connect/inc/aweber_api/li_aweber_api.php
ADDED
@@ -0,0 +1,8 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
if (class_exists('LI_AWeberAPI')) {
|
4 |
+
trigger_error("Duplicate: Another LI_AWeberAPI client library is already in scope.", E_USER_WARNING);
|
5 |
+
}
|
6 |
+
else {
|
7 |
+
require_once('li_aweber.php');
|
8 |
+
}
|
power-ups/aweber-connect/inc/aweber_api/li_aweber_collection.php
ADDED
@@ -0,0 +1,268 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
class LI_AWeberCollection extends LI_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 LI_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 LI_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 LI_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 LI_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 |
+
}
|
power-ups/aweber-connect/inc/aweber_api/li_aweber_entry.php
ADDED
@@ -0,0 +1,343 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class LI_AWeberEntry extends LI_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(LI_AWeberAPI::$_collectionMap[$this->type])) {
|
41 |
+
foreach (LI_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 LI_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 LI_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 LI_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 LI_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 LI_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 LI_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 LI_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 LI_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 LI_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(LI_AWeberAPI::$_collectionMap[$this->type]) &&
|
339 |
+
in_array($value, LI_AWeberAPI::$_collectionMap[$this->type])) return true;
|
340 |
+
return false;
|
341 |
+
}
|
342 |
+
|
343 |
+
}
|
power-ups/aweber-connect/inc/aweber_api/li_aweber_entry_data_array.php
ADDED
@@ -0,0 +1,68 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class LI_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 |
+
?>
|
power-ups/aweber-connect/inc/aweber_api/li_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 LI_AWeberResponse extends LI_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 |
+
|
power-ups/aweber-connect/inc/aweber_api/li_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 LI_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 LI_CurlObject implements LI_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 |
+
?>
|
power-ups/aweber-connect/inc/aweber_api/li_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 LI_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 |
+
}
|
power-ups/aweber-connect/inc/aweber_api/li_exceptions.php
ADDED
@@ -0,0 +1,130 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class LI_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 LI_AWeberAPIException extends LI_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 LI_AWeberResourceNotImplemented extends LI_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 LI_AWeberMethodNotImplemented extends LI_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 LI_AWeberOAuthException extends LI_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 LI_AWeberOAuthDataMissing extends LI_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 LI_AWeberResponseError extends LI_AWeberException {
|
124 |
+
|
125 |
+
public function __construct($uri) {
|
126 |
+
$this->uri = $uri;
|
127 |
+
parent::__construct("Request for {$uri} did not respond properly.");
|
128 |
+
}
|
129 |
+
|
130 |
+
}
|
power-ups/aweber-connect/inc/aweber_api/li_oauth_adapter.php
ADDED
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
interface LI_AWeberOAuthAdapter {
|
4 |
+
|
5 |
+
public function request($method, $uri, $data = array());
|
6 |
+
public function getRequestToken($callbackUrl=false);
|
7 |
+
|
8 |
+
}
|
9 |
+
|
10 |
+
|
11 |
+
?>
|
power-ups/aweber-connect/inc/aweber_api/li_oauth_application.php
ADDED
@@ -0,0 +1,681 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
if (!class_exists('LI_CurlObject')) require_once('li_curl_object.php');
|
3 |
+
if (!class_exists('LI_CurlResponse')) require_once('li_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 LI_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 LI_OAuthApplication implements LI_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, 'LI_OAuthServiceProvider')) {
|
91 |
+
throw new Exception('Parent App must be a valid LI_OAuthServiceProvider!');
|
92 |
+
}
|
93 |
+
$this->app = $parentApp;
|
94 |
+
}
|
95 |
+
$this->user = new LI_OAuthUser();
|
96 |
+
$this->curl = new LI_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 LI_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 LI_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 LI_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 LI_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(utf8_encode($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 |
+
return $method.'&'.$url.'&'.$data;
|
388 |
+
}
|
389 |
+
|
390 |
+
/**
|
391 |
+
* collapseDataForSignature
|
392 |
+
*
|
393 |
+
* Turns an array of request data into a string, as used by the oauth
|
394 |
+
* signature
|
395 |
+
* @param mixed $data
|
396 |
+
* @access public
|
397 |
+
* @return void
|
398 |
+
*/
|
399 |
+
public function collapseDataForSignature($data) {
|
400 |
+
ksort($data);
|
401 |
+
$collapse = '';
|
402 |
+
foreach ($data as $key => $val) {
|
403 |
+
if (!empty($collapse)) $collapse .= '&';
|
404 |
+
$collapse .= $key.'='.$this->encode($val);
|
405 |
+
}
|
406 |
+
return $collapse;
|
407 |
+
}
|
408 |
+
|
409 |
+
/**
|
410 |
+
* signRequest
|
411 |
+
*
|
412 |
+
* Signs the request.
|
413 |
+
*
|
414 |
+
* @param mixed $method HTTP method
|
415 |
+
* @param mixed $url URL for the request
|
416 |
+
* @param mixed $data The data to be signed
|
417 |
+
* @access public
|
418 |
+
* @return array The data, with the signature.
|
419 |
+
*/
|
420 |
+
public function signRequest($method, $url, $data) {
|
421 |
+
$base = $this->createSignatureBase($method, $url, $data);
|
422 |
+
$key = $this->createSignatureKey();
|
423 |
+
$data['oauth_signature'] = $this->createSignature($base, $key);
|
424 |
+
ksort($data);
|
425 |
+
return $data;
|
426 |
+
}
|
427 |
+
|
428 |
+
|
429 |
+
/**
|
430 |
+
* makeRequest
|
431 |
+
*
|
432 |
+
* Public facing function to make a request
|
433 |
+
*
|
434 |
+
* @param mixed $method
|
435 |
+
* @param mixed $url - Reserved characters in query params MUST be escaped
|
436 |
+
* @param mixed $data - Reserved characters in values MUST NOT be escaped
|
437 |
+
* @access public
|
438 |
+
* @return void
|
439 |
+
*/
|
440 |
+
public function makeRequest($method, $url, $data=array()) {
|
441 |
+
|
442 |
+
if ($this->debug) echo "\n** {$method}: $url\n";
|
443 |
+
|
444 |
+
switch (strtoupper($method)) {
|
445 |
+
case 'POST':
|
446 |
+
$oauth = $this->prepareRequest($method, $url, $data);
|
447 |
+
$resp = $this->post($url, $oauth);
|
448 |
+
break;
|
449 |
+
|
450 |
+
case 'GET':
|
451 |
+
$oauth = $this->prepareRequest($method, $url, $data);
|
452 |
+
$resp = $this->get($url, $oauth, $data);
|
453 |
+
break;
|
454 |
+
|
455 |
+
case 'DELETE':
|
456 |
+
$oauth = $this->prepareRequest($method, $url, $data);
|
457 |
+
$resp = $this->delete($url, $oauth);
|
458 |
+
break;
|
459 |
+
|
460 |
+
case 'PATCH':
|
461 |
+
$oauth = $this->prepareRequest($method, $url, array());
|
462 |
+
$resp = $this->patch($url, $oauth, $data);
|
463 |
+
break;
|
464 |
+
}
|
465 |
+
|
466 |
+
// enable debug output
|
467 |
+
if ($this->debug) {
|
468 |
+
echo "<pre>";
|
469 |
+
print_r($oauth);
|
470 |
+
echo " --> Status: {$resp->headers['Status-Code']}\n";
|
471 |
+
echo " --> Body: {$resp->body}";
|
472 |
+
echo "</pre>";
|
473 |
+
}
|
474 |
+
|
475 |
+
if (!$resp) {
|
476 |
+
$msg = 'Unable to connect to the AWeber API. (' . $this->error . ')';
|
477 |
+
$error = array('message' => $msg, 'type' => 'APIUnreachableError',
|
478 |
+
'documentation_url' => 'https://labs.aweber.com/docs/troubleshooting');
|
479 |
+
throw new LI_AWeberAPIException($error, $url);
|
480 |
+
}
|
481 |
+
|
482 |
+
if($resp->headers['Status-Code'] >= 400) {
|
483 |
+
$data = json_decode($resp->body, true);
|
484 |
+
throw new LI_AWeberAPIException($data['error'], $url);
|
485 |
+
}
|
486 |
+
|
487 |
+
return $resp;
|
488 |
+
}
|
489 |
+
|
490 |
+
/**
|
491 |
+
* put
|
492 |
+
*
|
493 |
+
* Prepare an OAuth put method.
|
494 |
+
*
|
495 |
+
* @param mixed $url URL where we are making the request to
|
496 |
+
* @param mixed $data Data that is used to make the request
|
497 |
+
* @access protected
|
498 |
+
* @return void
|
499 |
+
*/
|
500 |
+
protected function patch($url, $oauth, $data) {
|
501 |
+
$url = $this->_addParametersToUrl($url, $oauth);
|
502 |
+
$handle = $this->curl->init($url);
|
503 |
+
$this->curl->setopt($handle, CURLOPT_CUSTOMREQUEST, 'PATCH');
|
504 |
+
$this->curl->setopt($handle, CURLOPT_POSTFIELDS, json_encode($data));
|
505 |
+
$resp = $this->_sendRequest($handle, array('Expect:', 'Content-Type: application/json'));
|
506 |
+
return $resp;
|
507 |
+
}
|
508 |
+
|
509 |
+
/**
|
510 |
+
* post
|
511 |
+
*
|
512 |
+
* Prepare an OAuth post method.
|
513 |
+
*
|
514 |
+
* @param mixed $url URL where we are making the request to
|
515 |
+
* @param mixed $data Data that is used to make the request
|
516 |
+
* @access protected
|
517 |
+
* @return void
|
518 |
+
*/
|
519 |
+
protected function post($url, $oauth) {
|
520 |
+
$handle = $this->curl->init($url);
|
521 |
+
$postData = $this->buildData($oauth);
|
522 |
+
$this->curl->setopt($handle, CURLOPT_POST, true);
|
523 |
+
$this->curl->setopt($handle, CURLOPT_POSTFIELDS, $postData);
|
524 |
+
$resp = $this->_sendRequest($handle);
|
525 |
+
return $resp;
|
526 |
+
}
|
527 |
+
|
528 |
+
/**
|
529 |
+
* delete
|
530 |
+
*
|
531 |
+
* Makes a DELETE request
|
532 |
+
* @param mixed $url URL where we are making the request to
|
533 |
+
* @param mixed $data Data that is used in the request
|
534 |
+
* @access protected
|
535 |
+
* @return void
|
536 |
+
*/
|
537 |
+
protected function delete($url, $data) {
|
538 |
+
$url = $this->_addParametersToUrl($url, $data);
|
539 |
+
$handle = $this->curl->init($url);
|
540 |
+
$this->curl->setopt($handle, CURLOPT_CUSTOMREQUEST, 'DELETE');
|
541 |
+
$resp = $this->_sendRequest($handle);
|
542 |
+
return $resp;
|
543 |
+
}
|
544 |
+
|
545 |
+
/**
|
546 |
+
* buildData
|
547 |
+
*
|
548 |
+
* Creates a string of data for either post or get requests.
|
549 |
+
* @param mixed $data Array of key value pairs
|
550 |
+
* @access public
|
551 |
+
* @return void
|
552 |
+
*/
|
553 |
+
public function buildData($data) {
|
554 |
+
ksort($data);
|
555 |
+
$params = array();
|
556 |
+
foreach ($data as $key => $value) {
|
557 |
+
$params[] = $key.'='.$this->encode($value);
|
558 |
+
}
|
559 |
+
return implode('&', $params);
|
560 |
+
}
|
561 |
+
|
562 |
+
/**
|
563 |
+
* _sendRequest
|
564 |
+
*
|
565 |
+
* Actually makes a request.
|
566 |
+
* @param mixed $handle Curl handle
|
567 |
+
* @param array $headers Additional headers needed for request
|
568 |
+
* @access private
|
569 |
+
* @return void
|
570 |
+
*/
|
571 |
+
private function _sendRequest($handle, $headers = array('Expect:')) {
|
572 |
+
$this->curl->setopt($handle, CURLOPT_RETURNTRANSFER, true);
|
573 |
+
$this->curl->setopt($handle, CURLOPT_HEADER, true);
|
574 |
+
$this->curl->setopt($handle, CURLOPT_HTTPHEADER, $headers);
|
575 |
+
$this->curl->setopt($handle, CURLOPT_USERAGENT, $this->userAgent);
|
576 |
+
$this->curl->setopt($handle, CURLOPT_SSL_VERIFYPEER, FALSE);
|
577 |
+
$this->curl->setopt($handle, CURLOPT_VERBOSE, FALSE);
|
578 |
+
$this->curl->setopt($handle, CURLOPT_CONNECTTIMEOUT, 10);
|
579 |
+
$this->curl->setopt($handle, CURLOPT_TIMEOUT, 90);
|
580 |
+
$resp = $this->curl->execute($handle);
|
581 |
+
if ($resp) {
|
582 |
+
return new LI_CurlResponse($resp);
|
583 |
+
}
|
584 |
+
$this->error = $this->curl->errno($handle) . ' - ' .
|
585 |
+
$this->curl->error($handle);
|
586 |
+
return false;
|
587 |
+
}
|
588 |
+
|
589 |
+
/**
|
590 |
+
* prepareRequest
|
591 |
+
*
|
592 |
+
* @param mixed $method HTTP method
|
593 |
+
* @param mixed $url URL for the request
|
594 |
+
* @param mixed $data The data to generate oauth data and be signed
|
595 |
+
* @access public
|
596 |
+
* @return void The data, with all its OAuth variables and signature
|
597 |
+
*/
|
598 |
+
public function prepareRequest($method, $url, $data) {
|
599 |
+
$data = $this->mergeOAuthData($data);
|
600 |
+
$data = $this->signRequest($method, $url, $data);
|
601 |
+
return $data;
|
602 |
+
}
|
603 |
+
|
604 |
+
/**
|
605 |
+
* parseResponse
|
606 |
+
*
|
607 |
+
* Parses the body of the response into an array
|
608 |
+
* @param mixed $string The body of a response
|
609 |
+
* @access public
|
610 |
+
* @return void
|
611 |
+
*/
|
612 |
+
public function parseResponse($resp) {
|
613 |
+
$data = array();
|
614 |
+
|
615 |
+
if (!$resp) { return $data; }
|
616 |
+
if (empty($resp)) { return $data; }
|
617 |
+
if (empty($resp->body)) { return $data; }
|
618 |
+
|
619 |
+
switch ($this->format) {
|
620 |
+
case 'json':
|
621 |
+
$data = json_decode($resp->body);
|
622 |
+
break;
|
623 |
+
default:
|
624 |
+
parse_str($resp->body, $data);
|
625 |
+
}
|
626 |
+
$this->parseAsError($data);
|
627 |
+
return $data;
|
628 |
+
}
|
629 |
+
|
630 |
+
}
|
631 |
+
|
632 |
+
/**
|
633 |
+
* OAuthUser
|
634 |
+
*
|
635 |
+
* Simple data class representing the user in an OAuth application.
|
636 |
+
* @package
|
637 |
+
* @version $id$
|
638 |
+
*/
|
639 |
+
class LI_OAuthUser {
|
640 |
+
|
641 |
+
public $authorizedToken = false;
|
642 |
+
public $requestToken = false;
|
643 |
+
public $verifier = false;
|
644 |
+
public $tokenSecret = false;
|
645 |
+
public $accessToken = false;
|
646 |
+
|
647 |
+
/**
|
648 |
+
* isAuthorized
|
649 |
+
*
|
650 |
+
* Checks if this user is authorized.
|
651 |
+
* @access public
|
652 |
+
* @return void
|
653 |
+
*/
|
654 |
+
public function isAuthorized() {
|
655 |
+
if (empty($this->authorizedToken) && empty($this->accessToken)) {
|
656 |
+
return false;
|
657 |
+
}
|
658 |
+
return true;
|
659 |
+
}
|
660 |
+
|
661 |
+
|
662 |
+
/**
|
663 |
+
* getHighestPriorityToken
|
664 |
+
*
|
665 |
+
* Returns highest priority token - used to define authorization
|
666 |
+
* state for a given OAuthUser
|
667 |
+
* @access public
|
668 |
+
* @return void
|
669 |
+
*/
|
670 |
+
public function getHighestPriorityToken() {
|
671 |
+
if (!empty($this->accessToken)) return $this->accessToken;
|
672 |
+
if (!empty($this->authorizedToken)) return $this->authorizedToken;
|
673 |
+
if (!empty($this->requestToken)) return $this->requestToken;
|
674 |
+
|
675 |
+
// Return no token, new user
|
676 |
+
return '';
|
677 |
+
}
|
678 |
+
|
679 |
+
}
|
680 |
+
|
681 |
+
?>
|
power-ups/campaign-monitor-connect.php
ADDED
@@ -0,0 +1,141 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Power-up Name: Campaign Monitor
|
4 |
+
* Power-up Class: LICampaignMonitorConnect
|
5 |
+
* Power-up Menu Text:
|
6 |
+
* Power-up Slug: campaign_monitor_connect
|
7 |
+
* Power-up Menu Link: settings
|
8 |
+
* Power-up URI: http://leadin.com/mailchimp-connect
|
9 |
+
* Power-up Description: Push your contacts to Campaign Monitor email lists.
|
10 |
+
* Power-up Icon: power-up-icon-campaign-monitor-connect
|
11 |
+
* Power-up Icon Small: power-up-icon-campaign-monitor-connect_small
|
12 |
+
* First Introduced: 0.7.0
|
13 |
+
* Power-up Tags: Newsletter, Email
|
14 |
+
* Auto Activate: No
|
15 |
+
* Permanently Enabled: No
|
16 |
+
* Hidden: No
|
17 |
+
* cURL Required: Yes
|
18 |
+
*/
|
19 |
+
|
20 |
+
//=============================================
|
21 |
+
// Define Constants
|
22 |
+
//=============================================
|
23 |
+
|
24 |
+
if ( !defined('LEADIN_CAMPAIGN_MONITOR_CONNECT_PATH') )
|
25 |
+
define('LEADIN_CAMPAIGN_MONITOR_CONNECT_PATH', LEADIN_PATH . '/power-ups/campaign-monitor-connect');
|
26 |
+
|
27 |
+
if ( !defined('LEADIN_CAMPAIGN_MONITOR_CONNECT_PLUGIN_DIR') )
|
28 |
+
define('LEADIN_CAMPAIGN_MONITOR_CONNECT_PLUGIN_DIR', LEADIN_PLUGIN_DIR . '/power-ups/campaign-monitor-connect');
|
29 |
+
|
30 |
+
if ( !defined('LEADIN_CAMPAIGN_MONITOR_CONNECT_PLUGIN_SLUG') )
|
31 |
+
define('LEADIN_CAMPAIGN_MONITOR_CONNECT_SLUG', basename(dirname(__FILE__)));
|
32 |
+
|
33 |
+
//=============================================
|
34 |
+
// Include Needed Files
|
35 |
+
//=============================================
|
36 |
+
require_once(LEADIN_CAMPAIGN_MONITOR_CONNECT_PLUGIN_DIR . '/admin/campaign-monitor-connect-admin.php');
|
37 |
+
require_once(LEADIN_CAMPAIGN_MONITOR_CONNECT_PLUGIN_DIR . '/inc/li_campaign_monitor.php');
|
38 |
+
|
39 |
+
//=============================================
|
40 |
+
// WPLeadIn Class
|
41 |
+
//=============================================
|
42 |
+
class LICampaignMonitorConnect extends WPLeadIn {
|
43 |
+
|
44 |
+
var $admin;
|
45 |
+
var $options;
|
46 |
+
var $power_option_name = 'leadin_campaign_monitor_connect_options';
|
47 |
+
|
48 |
+
/**
|
49 |
+
* Class constructor
|
50 |
+
*/
|
51 |
+
function __construct ( $activated )
|
52 |
+
{
|
53 |
+
//=============================================
|
54 |
+
// Hooks & Filters
|
55 |
+
//=============================================
|
56 |
+
|
57 |
+
if ( ! $activated )
|
58 |
+
return false;
|
59 |
+
|
60 |
+
global $leadin_campaign_monitor_connect_wp;
|
61 |
+
$leadin_campaign_monitor_connect_wp = $this;
|
62 |
+
$this->options = get_option($this->power_option_name);
|
63 |
+
}
|
64 |
+
|
65 |
+
public function admin_init ( )
|
66 |
+
{
|
67 |
+
$admin_class = get_class($this) . 'Admin';
|
68 |
+
$this->admin = new $admin_class($this->icon_small);
|
69 |
+
}
|
70 |
+
|
71 |
+
function power_up_setup_callback ( )
|
72 |
+
{
|
73 |
+
$this->admin->power_up_setup_callback();
|
74 |
+
}
|
75 |
+
|
76 |
+
/**
|
77 |
+
* Activate the power-up and add the defaults
|
78 |
+
*/
|
79 |
+
function add_defaults ()
|
80 |
+
{
|
81 |
+
|
82 |
+
}
|
83 |
+
|
84 |
+
/**
|
85 |
+
* Adds a subcsriber to a specific list
|
86 |
+
*
|
87 |
+
* @param string
|
88 |
+
* @param string
|
89 |
+
* @param string
|
90 |
+
* @param string
|
91 |
+
* @param string
|
92 |
+
* @return int/bool API status code OR false if api key not set
|
93 |
+
*/
|
94 |
+
function push_contact_to_list ( $list_id = '', $email = '', $first_name = '', $last_name = '', $phone = '' )
|
95 |
+
{
|
96 |
+
if ( isset($this->options['li_cm_api_key']) && $this->options['li_cm_api_key'] && $list_id )
|
97 |
+
{
|
98 |
+
$cm = new LI_Campaign_Monitor($this->options['li_cm_api_key']);
|
99 |
+
$r = $cm->call('subscribers/' . $list_id, 'POST', array(
|
100 |
+
'EmailAddress' => $email,
|
101 |
+
'Name' => $first_name . ' ' . $last_name,
|
102 |
+
'Resubscribe' => TRUE
|
103 |
+
));
|
104 |
+
|
105 |
+
if ( $r['code'] <= 400 )
|
106 |
+
{
|
107 |
+
leadin_track_plugin_activity('Contact Pushed to List', array('esp_connector' => 'campaign_monitor'));
|
108 |
+
return TRUE;
|
109 |
+
}
|
110 |
+
else
|
111 |
+
return FALSE;
|
112 |
+
}
|
113 |
+
|
114 |
+
return FALSE;
|
115 |
+
}
|
116 |
+
|
117 |
+
/**
|
118 |
+
* Adds a subcsriber to a specific list
|
119 |
+
*
|
120 |
+
* @param string
|
121 |
+
* @param array
|
122 |
+
* @return int/bool API status code OR false if api key not set
|
123 |
+
*/
|
124 |
+
function bulk_push_contact_to_list ( $list_id = '', $contacts = '' )
|
125 |
+
{
|
126 |
+
/*
|
127 |
+
The majority of our user base doesn't use Campaign Monitor, so we decided not to retroactively sync contacts to the list.
|
128 |
+
If people complain, we will respond with a support ticket and ask them to export/import manually.
|
129 |
+
*/
|
130 |
+
|
131 |
+
return FALSE;
|
132 |
+
}
|
133 |
+
}
|
134 |
+
|
135 |
+
//=============================================
|
136 |
+
// ESP Connect Init
|
137 |
+
//=============================================
|
138 |
+
|
139 |
+
global $leadin_campaign_monitor_connect_wp;
|
140 |
+
|
141 |
+
?>
|
power-ups/campaign-monitor-connect/admin/campaign-monitor-connect-admin.php
ADDED
@@ -0,0 +1,225 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
//=============================================
|
3 |
+
// LICampaignMonitorConnectAdmin Class
|
4 |
+
//=============================================
|
5 |
+
class LICampaignMonitorConnectAdmin extends WPLeadInAdmin {
|
6 |
+
|
7 |
+
var $power_up_settings_section = 'leadin_campaign_monitor_connect_options_section';
|
8 |
+
var $power_option_name = 'leadin_campaign_monitor_connect_options';
|
9 |
+
var $power_up_icon;
|
10 |
+
var $options;
|
11 |
+
var $authed = FALSE;
|
12 |
+
var $invalid_key = FALSE;
|
13 |
+
|
14 |
+
/**
|
15 |
+
* Class constructor
|
16 |
+
*/
|
17 |
+
function __construct ( $power_up_icon_small )
|
18 |
+
{
|
19 |
+
//=============================================
|
20 |
+
// Hooks & Filters
|
21 |
+
//=============================================
|
22 |
+
|
23 |
+
if ( is_admin() )
|
24 |
+
{
|
25 |
+
$this->power_up_icon = $power_up_icon_small;
|
26 |
+
add_action('admin_init', array($this, 'leadin_build_esp_settings_page'));
|
27 |
+
$this->options = get_option($this->power_option_name);
|
28 |
+
$this->authed = ( isset($this->options['li_cm_api_key']) && $this->options['li_cm_api_key'] ? TRUE : FALSE );
|
29 |
+
|
30 |
+
if ( $this->authed )
|
31 |
+
$this->invalid_key = $this->li_check_invalid_api_key($this->options['li_cm_api_key']);
|
32 |
+
}
|
33 |
+
}
|
34 |
+
|
35 |
+
//=============================================
|
36 |
+
// Settings Page
|
37 |
+
//=============================================
|
38 |
+
|
39 |
+
/**
|
40 |
+
* Creates settings options
|
41 |
+
*/
|
42 |
+
function leadin_build_esp_settings_page ()
|
43 |
+
{
|
44 |
+
register_setting('leadin_settings_options', $this->power_option_name, array($this, 'sanitize'));
|
45 |
+
add_settings_section($this->power_up_settings_section, $this->power_up_icon . "Campaign Monitor", '', LEADIN_ADMIN_PATH);
|
46 |
+
add_settings_field('li_cm_api_key', 'API key', array($this, 'li_cm_api_key_callback'), LEADIN_ADMIN_PATH, $this->power_up_settings_section);
|
47 |
+
|
48 |
+
if ( isset($this->options['li_cm_api_key']) )
|
49 |
+
{
|
50 |
+
if ( $this->options['li_cm_api_key'] )
|
51 |
+
add_settings_field('li_print_synced_lists', 'Synced tags', array($this, 'li_print_synced_lists'), LEADIN_ADMIN_PATH, $this->power_up_settings_section);
|
52 |
+
}
|
53 |
+
}
|
54 |
+
|
55 |
+
/**
|
56 |
+
* Sanitize each setting field as needed
|
57 |
+
*
|
58 |
+
* @param array $input Contains all settings fields as array keys
|
59 |
+
*/
|
60 |
+
public function sanitize ( $input )
|
61 |
+
{
|
62 |
+
$new_input = array();
|
63 |
+
|
64 |
+
if ( isset( $input['li_cm_api_key'] ) )
|
65 |
+
$new_input['li_cm_api_key'] = sanitize_text_field( $input['li_cm_api_key'] );
|
66 |
+
|
67 |
+
return $new_input;
|
68 |
+
}
|
69 |
+
|
70 |
+
/**
|
71 |
+
* Prints API key input for settings page
|
72 |
+
*/
|
73 |
+
function li_cm_api_key_callback ()
|
74 |
+
{
|
75 |
+
$li_cm_api_key = ( $this->options['li_cm_api_key'] ? $this->options['li_cm_api_key'] : '' ); // Get header from options, or show default
|
76 |
+
|
77 |
+
printf(
|
78 |
+
'<input id="li_cm_api_key" type="text" id="title" name="' . $this->power_option_name . '[li_cm_api_key]" value="%s" style="width: 430px;"/>',
|
79 |
+
$li_cm_api_key
|
80 |
+
);
|
81 |
+
|
82 |
+
if ( ! isset($li_cm_api_key) || ! $li_cm_api_key )
|
83 |
+
echo '<p><a target="_blank" href="http://help.campaignmonitor.com/topic.aspx?t=206">Get your API key</a> from <a href="https://login.createsend.com/l" target="_blank">CampaignMonitor.com</a></p>';
|
84 |
+
}
|
85 |
+
|
86 |
+
/**
|
87 |
+
* Prints synced lists out for settings page in format Tag Name → ESP list
|
88 |
+
*/
|
89 |
+
function li_print_synced_lists ()
|
90 |
+
{
|
91 |
+
$li_cm_api_key = ( $this->options['li_cm_api_key'] ? $this->options['li_cm_api_key'] : '' ); // Get header from options, or show default
|
92 |
+
|
93 |
+
if ( isset($li_cm_api_key ) )
|
94 |
+
{
|
95 |
+
$synced_lists = $this->li_get_synced_list_for_esp('campaign_monitor');
|
96 |
+
$list_value_pairs = array();
|
97 |
+
$synced_list_count = 0;
|
98 |
+
|
99 |
+
echo '<table>';
|
100 |
+
foreach ( $synced_lists as $synced_list )
|
101 |
+
{
|
102 |
+
foreach ( stripslashes_deep(unserialize($synced_list->tag_synced_lists)) as $tag_synced_list )
|
103 |
+
{
|
104 |
+
if ( $tag_synced_list['esp'] == 'campaign_monitor' )
|
105 |
+
{
|
106 |
+
echo '<tr class="synced-list-row">';
|
107 |
+
echo '<td class="synced-list-cell"><span class="icon-tag"></span> ' . $synced_list->tag_text . '</td>';
|
108 |
+
echo '<td class="synced-list-cell"><span class="synced-list-arrow">→</span></td>';
|
109 |
+
echo '<td class="synced-list-cell"><span class="icon-envelope"></span> ' . $tag_synced_list['list_name'] . '</td>';
|
110 |
+
echo '<td class="synced-list-edit"><a href="' . get_bloginfo('wpurl') . '/wp-admin/admin.php?page=leadin_tags&action=edit_tag&tag=' . $synced_list->tag_id . '">edit tag</a></td>';
|
111 |
+
echo '</tr>';
|
112 |
+
|
113 |
+
$synced_list_count++;
|
114 |
+
}
|
115 |
+
}
|
116 |
+
}
|
117 |
+
echo '</table>';
|
118 |
+
|
119 |
+
if ( ! $synced_list_count ) {
|
120 |
+
echo '<p>Campaign Monitor connected succesfully! <a href="' . get_bloginfo('wpurl') . '/wp-admin/admin.php?page=leadin_tags">Select a tag to send contacts to Campaign Monitor</a>.</p>';
|
121 |
+
} else {
|
122 |
+
echo '<p><a href="' . get_bloginfo('wpurl') . '/wp-admin/admin.php?page=leadin_tags">Edit your tags</a> or <a href="https://login.createsend.com/l" target="_blank">Create a new list on CampaignMonitor.com</a></p>';
|
123 |
+
}
|
124 |
+
}
|
125 |
+
}
|
126 |
+
|
127 |
+
/**
|
128 |
+
* Get synced list for the ESP from the WordPress database
|
129 |
+
*
|
130 |
+
* @return array/object
|
131 |
+
*/
|
132 |
+
function li_get_synced_list_for_esp ( $esp_name, $output_type = 'OBJECT' )
|
133 |
+
{
|
134 |
+
global $wpdb;
|
135 |
+
|
136 |
+
$q = $wpdb->prepare("SELECT * FROM $wpdb->li_tags WHERE tag_synced_lists LIKE '%%%s%%' AND tag_deleted = 0", $esp_name);
|
137 |
+
$synced_lists = $wpdb->get_results($q, $output_type);
|
138 |
+
|
139 |
+
return $synced_lists;
|
140 |
+
}
|
141 |
+
|
142 |
+
/**
|
143 |
+
* Format API-returned lists into parseable format on front end
|
144 |
+
*
|
145 |
+
* @return array
|
146 |
+
*/
|
147 |
+
function li_get_lists ( )
|
148 |
+
{
|
149 |
+
$lists = $this->li_get_api_lists($this->options['li_cm_api_key']);
|
150 |
+
|
151 |
+
$sanitized_lists = array();
|
152 |
+
if ( count($lists) )
|
153 |
+
{
|
154 |
+
foreach ( $lists as $list )
|
155 |
+
{
|
156 |
+
$list_obj = (Object)NULL;
|
157 |
+
$list_obj->id = $list['ListID'];
|
158 |
+
$list_obj->name = $list['Name'] . ' (Client: ' . $list['ClientName'] . ')';
|
159 |
+
|
160 |
+
array_push($sanitized_lists, $list_obj);;
|
161 |
+
}
|
162 |
+
}
|
163 |
+
|
164 |
+
return $sanitized_lists;
|
165 |
+
}
|
166 |
+
|
167 |
+
/**
|
168 |
+
* Get lists from Campaign Monitor account
|
169 |
+
*
|
170 |
+
* @param string
|
171 |
+
* @return array
|
172 |
+
*/
|
173 |
+
function li_get_api_lists ( $api_key )
|
174 |
+
{
|
175 |
+
$all_lists = array();
|
176 |
+
|
177 |
+
$cm = new LI_Campaign_Monitor($api_key);
|
178 |
+
$clients = $cm->call('clients', 'GET');
|
179 |
+
|
180 |
+
if ( count($clients['response']) )
|
181 |
+
{
|
182 |
+
foreach ( $clients['response'] as $client )
|
183 |
+
{
|
184 |
+
$lists = $cm->call('clients/' . $client['ClientID'] . '/lists', 'GET');
|
185 |
+
|
186 |
+
if ( count($lists['response']) )
|
187 |
+
{
|
188 |
+
foreach ( $lists['response'] as $list )
|
189 |
+
{
|
190 |
+
$list['ClientName'] = $client['Name'];
|
191 |
+
array_push($all_lists, $list);
|
192 |
+
}
|
193 |
+
}
|
194 |
+
}
|
195 |
+
}
|
196 |
+
|
197 |
+
return $all_lists;
|
198 |
+
}
|
199 |
+
|
200 |
+
/**
|
201 |
+
* Use MailChimp API key to try to grab corresponding user profile to check validity of key
|
202 |
+
*
|
203 |
+
* @param string
|
204 |
+
* @return bool
|
205 |
+
*/
|
206 |
+
function li_check_invalid_api_key ( $api_key )
|
207 |
+
{
|
208 |
+
$cm = new LI_Campaign_Monitor($api_key);
|
209 |
+
$test = $cm->call('clients', 'GET');
|
210 |
+
|
211 |
+
if ( $test['code'] >= 400 )
|
212 |
+
{
|
213 |
+
unset($this->options['li_cm_api_key']);
|
214 |
+
update_option($this->power_option_name, $this->options);
|
215 |
+
|
216 |
+
$invalid_key = TRUE;
|
217 |
+
}
|
218 |
+
else
|
219 |
+
$invalid_key = FALSE;
|
220 |
+
|
221 |
+
return $invalid_key;
|
222 |
+
}
|
223 |
+
}
|
224 |
+
|
225 |
+
?>
|
power-ups/campaign-monitor-connect/inc/li_campaign_monitor.php
ADDED
@@ -0,0 +1,123 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Simple Campaign Monitor API wrapper
|
4 |
+
*
|
5 |
+
* Uses cURL
|
6 |
+
* When called it returns HTTP response code and associative array of JSON response
|
7 |
+
* The HTTP response code can be used to determine if the request processed successfully
|
8 |
+
* If there is an error it is described in the associative array of JSON response
|
9 |
+
*
|
10 |
+
* @author Mehedi Hasan <mha_bd@yahoo.com>
|
11 |
+
*
|
12 |
+
* @usage
|
13 |
+
*
|
14 |
+
* $cm = new CMWrapper("{api_key}");
|
15 |
+
* $r = $cm->call("{method}", "{httpmethod}", {jsonargs}. {urlargs});
|
16 |
+
*
|
17 |
+
* @example
|
18 |
+
* the following updates a subscribers email address from name@test.com to newname@test.com
|
19 |
+
* $cm = new CMWrapper("abcd1234");
|
20 |
+
* $r = $cm->call("subscribers/xyz789", "PUT", array("EmailAddress" => "newname@test.com"), array("EmailAddress" => "name@test.com"));
|
21 |
+
*/
|
22 |
+
|
23 |
+
class LI_Campaign_Monitor
|
24 |
+
{
|
25 |
+
private $api_key;
|
26 |
+
private $api_endpoint = 'https://api.createsend.com/api/v3.1';
|
27 |
+
private $verify_ssl = false;
|
28 |
+
|
29 |
+
/**
|
30 |
+
* Create a new instance
|
31 |
+
* @param string $api_key Your Campaign Monitor API key
|
32 |
+
*/
|
33 |
+
function __construct($api_key)
|
34 |
+
{
|
35 |
+
$this->api_key = $api_key;
|
36 |
+
}
|
37 |
+
|
38 |
+
/**
|
39 |
+
* Call an API method. Every request needs the API key, so that is added automatically -- you don't need to pass it in.
|
40 |
+
* @param string $method The API method to call, e.g. 'subscribers/{listid}',
|
41 |
+
* @param string $httpmethod The HTTP method to be used, e.g. 'GET', 'POST', 'PUT', 'DELETE'
|
42 |
+
* @param array $jsonargs An array of arguments to pass to the method while using POST/PUT. Will be json encoded for you.
|
43 |
+
* @param array $urlargs An array of arguments to pass to the method. Will be appended to URL.
|
44 |
+
* @return array An array of response HTTP code and associative array of json decoded API response.
|
45 |
+
*/
|
46 |
+
public function call($method, $httpmethod, $jsonargs = array(), $urlargs = array())
|
47 |
+
{
|
48 |
+
return $this->makeRequest($method, $httpmethod, $jsonargs, $urlargs);
|
49 |
+
}
|
50 |
+
|
51 |
+
/**
|
52 |
+
* Performs the underlying HTTP request.
|
53 |
+
* @param string $method The API method to call, e.g. 'subscribers/{listid}',
|
54 |
+
* @param string $httpmethod The HTTP method to be used, e.g. 'GET', 'POST', 'PUT', 'DELETE'
|
55 |
+
* @param array $jsonargs An array of arguments to pass to the method while using POST/PUT. Will be json encoded for you.
|
56 |
+
* @param array $urlargs An array of arguments to pass to the method. Will be appended to URL.
|
57 |
+
* @return array An array of response HTTP code and associative array of json decoded API response.
|
58 |
+
*/
|
59 |
+
private function makeRequest($method, $httpmethod, $jsonargs = array(), $urlargs = array())
|
60 |
+
{
|
61 |
+
$args['apikey'] = $this->api_key;
|
62 |
+
|
63 |
+
$url = $this->api_endpoint.'/'.$method.'.json';
|
64 |
+
|
65 |
+
if( count($urlargs) > 0 ){
|
66 |
+
$url = $url . "?" . http_build_query($urlargs);
|
67 |
+
}
|
68 |
+
|
69 |
+
$ch = curl_init();
|
70 |
+
curl_setopt($ch, CURLOPT_URL, $url);
|
71 |
+
curl_setopt($ch, CURLOPT_HTTPHEADER,
|
72 |
+
array('Content-Type: application/json',
|
73 |
+
"Authorization: Basic " . base64_encode($this->api_key . ":x")
|
74 |
+
)
|
75 |
+
);
|
76 |
+
curl_setopt($ch, CURLOPT_USERAGENT, 'PHP-CMAPI');
|
77 |
+
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
78 |
+
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
|
79 |
+
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, $this->verify_ssl);
|
80 |
+
curl_setopt($ch, CURLOPT_HEADER, false);
|
81 |
+
curl_setopt($ch, CURLINFO_HEADER_OUT, true);
|
82 |
+
|
83 |
+
if( $httpmethod === "POST" ){
|
84 |
+
curl_setopt($ch, CURLOPT_POST, true);
|
85 |
+
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($jsonargs));
|
86 |
+
}
|
87 |
+
|
88 |
+
if( $httpmethod === "PUT" ){
|
89 |
+
curl_setopt($ch, CURLOPT_PUT, true);
|
90 |
+
|
91 |
+
$json = json_encode($jsonargs);
|
92 |
+
|
93 |
+
$fp = fopen('php://temp/maxmemory:256000', 'w');
|
94 |
+
fwrite($fp, $json);
|
95 |
+
fseek($fp, 0);
|
96 |
+
|
97 |
+
curl_setopt($ch, CURLOPT_INFILE, $fp);
|
98 |
+
curl_setopt($ch, CURLOPT_INFILESIZE, strlen($json));
|
99 |
+
}
|
100 |
+
|
101 |
+
if( $httpmethod === "DELETE" ){
|
102 |
+
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "DELETE");
|
103 |
+
}
|
104 |
+
|
105 |
+
$result = curl_exec($ch);
|
106 |
+
|
107 |
+
$ret = array(
|
108 |
+
"code" => curl_getinfo($ch, CURLINFO_HTTP_CODE),
|
109 |
+
"response" => json_decode($result, true),
|
110 |
+
);
|
111 |
+
|
112 |
+
curl_close($ch);
|
113 |
+
|
114 |
+
if( $httpmethod === "PUT" ){
|
115 |
+
fclose($fp);
|
116 |
+
}
|
117 |
+
|
118 |
+
//var_dump($httpmethod . " " . $url);
|
119 |
+
//var_dump($ret);
|
120 |
+
|
121 |
+
return $ret;
|
122 |
+
}
|
123 |
+
}
|
power-ups/campaign-monitor-connect/inc/test.php
ADDED
@@ -0,0 +1,35 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
//api key 6efceb8935e61ab01f2a1f216b023d4b
|
3 |
+
//client id f70880b91dd8c7dd73d599cad4a5a639
|
4 |
+
//list id de1fa82595ce3b2eb99a6f4a69bbe452
|
5 |
+
|
6 |
+
require_once("li_campaign_monitor.php");
|
7 |
+
|
8 |
+
$cm = new LI_Campaign_Monitor("6efceb8935e61ab01f2a1f216b023d4b");
|
9 |
+
|
10 |
+
//test POST request
|
11 |
+
//adding a new subscriber with email name@test.com
|
12 |
+
$r = $cm->call("clients/f70880b91dd8c7dd73d599cad4a5a639/lists", "GET");
|
13 |
+
var_dump($r);
|
14 |
+
/*
|
15 |
+
//test GET request
|
16 |
+
//get details for subscriber with email name@test.com
|
17 |
+
$r = $cm->call("subscribers/de1fa82595ce3b2eb99a6f4a69bbe452", "GET", array(), array("email" => "name@test.com"));
|
18 |
+
var_dump($r);
|
19 |
+
|
20 |
+
//test PUT request
|
21 |
+
//change email of subscriber with email name@test.com to othername@test.com
|
22 |
+
$r = $cm->call("subscribers/de1fa82595ce3b2eb99a6f4a69bbe452", "PUT", array("EmailAddress" => "othername@test.com"), array("email" => "name@test.com"));
|
23 |
+
var_dump($r);
|
24 |
+
|
25 |
+
//test PUT request again
|
26 |
+
//change email of subscriber with email othername@test.com to name@test.com
|
27 |
+
$r = $cm->call("subscribers/de1fa82595ce3b2eb99a6f4a69bbe452", "PUT", array("EmailAddress" => "name@test.com"), array("email" => "othername@test.com"));
|
28 |
+
var_dump($r);
|
29 |
+
|
30 |
+
//test DELETE request
|
31 |
+
//delete subscriber with email name@test.com
|
32 |
+
$r = $cm->call("subscribers/de1fa82595ce3b2eb99a6f4a69bbe452", "DELETE", array(), array("email" => "name@test.com"));
|
33 |
+
var_dump($r);
|
34 |
+
*/
|
35 |
+
?>
|
power-ups/constant-contact-connect.php
CHANGED
@@ -48,6 +48,7 @@ class WPConstantContactConnect extends WPLeadIn {
|
|
48 |
|
49 |
var $admin;
|
50 |
var $options;
|
|
|
51 |
var $constant_contact;
|
52 |
var $cc_id;
|
53 |
|
@@ -65,7 +66,7 @@ class WPConstantContactConnect extends WPLeadIn {
|
|
65 |
|
66 |
global $leadin_constant_contact_connect_wp;
|
67 |
$leadin_constant_contact_connect_wp = $this;
|
68 |
-
$this->options = get_option(
|
69 |
}
|
70 |
|
71 |
public function admin_init ( )
|
@@ -113,6 +114,8 @@ class WPConstantContactConnect extends WPLeadIn {
|
|
113 |
|
114 |
if ( $this->cc_id )
|
115 |
{
|
|
|
|
|
116 |
return $this->constant_contact->add_subscription($this->cc_id, $list_id, 'ACTION_BY_CLIENT');
|
117 |
}
|
118 |
else
|
@@ -133,6 +136,8 @@ class WPConstantContactConnect extends WPLeadIn {
|
|
133 |
if ( $phone )
|
134 |
$contact['WorkPhone'] = $phone;
|
135 |
|
|
|
|
|
136 |
return $this->constant_contact->add_contact($contact, array($list_id));
|
137 |
}
|
138 |
}
|
@@ -157,6 +162,8 @@ class WPConstantContactConnect extends WPLeadIn {
|
|
157 |
|
158 |
if ( $cc_id )
|
159 |
{
|
|
|
|
|
160 |
return $this->constant_contact->remove_subscription($cc_id, $list_id);
|
161 |
}
|
162 |
else
|
@@ -183,7 +190,7 @@ class WPConstantContactConnect extends WPLeadIn {
|
|
183 |
}
|
184 |
|
185 |
//=============================================
|
186 |
-
//
|
187 |
//=============================================
|
188 |
|
189 |
global $leadin_constant_contact_connect_wp;
|
48 |
|
49 |
var $admin;
|
50 |
var $options;
|
51 |
+
var $power_option_name = 'leadin_cc_options';
|
52 |
var $constant_contact;
|
53 |
var $cc_id;
|
54 |
|
66 |
|
67 |
global $leadin_constant_contact_connect_wp;
|
68 |
$leadin_constant_contact_connect_wp = $this;
|
69 |
+
$this->options = get_option($this->power_option_name);
|
70 |
}
|
71 |
|
72 |
public function admin_init ( )
|
114 |
|
115 |
if ( $this->cc_id )
|
116 |
{
|
117 |
+
leadin_track_plugin_activity('Contact Pushed to List', array('esp_connector' => 'constant_contact'));
|
118 |
+
|
119 |
return $this->constant_contact->add_subscription($this->cc_id, $list_id, 'ACTION_BY_CLIENT');
|
120 |
}
|
121 |
else
|
136 |
if ( $phone )
|
137 |
$contact['WorkPhone'] = $phone;
|
138 |
|
139 |
+
leadin_track_plugin_activity('Contact Pushed to List', array('esp_connector' => 'constant_contact'));
|
140 |
+
|
141 |
return $this->constant_contact->add_contact($contact, array($list_id));
|
142 |
}
|
143 |
}
|
162 |
|
163 |
if ( $cc_id )
|
164 |
{
|
165 |
+
leadin_track_plugin_activity('Contact Removed from List', array('esp_connector' => 'constant_contact'));
|
166 |
+
|
167 |
return $this->constant_contact->remove_subscription($cc_id, $list_id);
|
168 |
}
|
169 |
else
|
190 |
}
|
191 |
|
192 |
//=============================================
|
193 |
+
// ESP Connect Init
|
194 |
//=============================================
|
195 |
|
196 |
global $leadin_constant_contact_connect_wp;
|
power-ups/constant-contact-connect/admin/constant-contact-connect-admin.php
CHANGED
@@ -5,6 +5,7 @@
|
|
5 |
class WPConstantContactConnectAdmin extends WPLeadInAdmin {
|
6 |
|
7 |
var $power_up_settings_section = 'leadin_cc_options_section';
|
|
|
8 |
var $power_up_icon;
|
9 |
var $bad_api_call;
|
10 |
var $constant_contact;
|
@@ -26,8 +27,8 @@ class WPConstantContactConnectAdmin extends WPLeadInAdmin {
|
|
26 |
if ( is_admin() )
|
27 |
{
|
28 |
$this->power_up_icon = $power_up_icon_small;
|
29 |
-
add_action('admin_init', array($this, '
|
30 |
-
$this->options = get_option(
|
31 |
if ( isset($this->options['li_cc_email']) && isset($this->options['li_cc_password']) && $this->options['li_cc_email'] && $this->options['li_cc_password'] )
|
32 |
$this->authed = TRUE;
|
33 |
}
|
@@ -40,11 +41,11 @@ class WPConstantContactConnectAdmin extends WPLeadInAdmin {
|
|
40 |
/**
|
41 |
* Creates settings options
|
42 |
*/
|
43 |
-
function
|
44 |
{
|
45 |
global $leadin_constant_contact_connect_wp;
|
46 |
|
47 |
-
register_setting('leadin_settings_options',
|
48 |
|
49 |
// If the creds are set, check if they are any good by hitting the API
|
50 |
if ( $this->authed )
|
@@ -88,7 +89,7 @@ class WPConstantContactConnectAdmin extends WPLeadInAdmin {
|
|
88 |
if ( $li_cc_email )
|
89 |
{
|
90 |
printf(
|
91 |
-
'<input id="li_cc_email" type="hidden" name="
|
92 |
$li_cc_email
|
93 |
);
|
94 |
}
|
@@ -96,7 +97,7 @@ class WPConstantContactConnectAdmin extends WPLeadInAdmin {
|
|
96 |
if ( $li_cc_password )
|
97 |
{
|
98 |
printf(
|
99 |
-
'<input id="li_cc_password" type="hidden" name="
|
100 |
$li_cc_password
|
101 |
);
|
102 |
}
|
@@ -111,15 +112,12 @@ class WPConstantContactConnectAdmin extends WPLeadInAdmin {
|
|
111 |
{
|
112 |
$new_input = array();
|
113 |
|
114 |
-
if( isset( $input['li_cc_email'] ) )
|
115 |
$new_input['li_cc_email'] = sanitize_text_field( $input['li_cc_email'] );
|
116 |
|
117 |
-
if( isset( $input['li_cc_password'] ) )
|
118 |
$new_input['li_cc_password'] = sanitize_text_field( $input['li_cc_password'] );
|
119 |
|
120 |
-
if( isset( $input['li_cc_subscribers_to_list'] ) )
|
121 |
-
$new_input['li_cc_subscribers_to_list'] = sanitize_text_field( $input['li_cc_subscribers_to_list'] );
|
122 |
-
|
123 |
return $new_input;
|
124 |
}
|
125 |
|
@@ -131,7 +129,7 @@ class WPConstantContactConnectAdmin extends WPLeadInAdmin {
|
|
131 |
$li_cc_email = ( $this->options['li_cc_email'] ? $this->options['li_cc_email'] : '' ); // Get header from options, or show default
|
132 |
|
133 |
printf(
|
134 |
-
'<input id="li_cc_email" type="text" id="title" name="
|
135 |
$li_cc_email
|
136 |
);
|
137 |
}
|
@@ -144,48 +142,11 @@ class WPConstantContactConnectAdmin extends WPLeadInAdmin {
|
|
144 |
$li_cc_password = ( $this->options['li_cc_password'] ? $this->options['li_cc_password'] : '' ); // Get header from options, or show default
|
145 |
|
146 |
printf(
|
147 |
-
'<input id="li_cc_password" type="password" id="title" name="
|
148 |
$li_cc_password
|
149 |
);
|
150 |
}
|
151 |
|
152 |
-
/**
|
153 |
-
* Prints email input for settings page
|
154 |
-
*/
|
155 |
-
function li_cc_subscribers_to_list_callback ()
|
156 |
-
{
|
157 |
-
$li_cc_subscribers_to_list = ( isset($this->options['li_cc_subscribers_to_list']) ? $this->options['li_cc_subscribers_to_list'] : '' ); // Get header from options, or show default
|
158 |
-
|
159 |
-
echo '<select id="li_cc_subscribers_to_list" name="leadin_cc_options[li_cc_subscribers_to_list]" ' . ( ! count($this->lists) ? 'disabled' : '' ) . '>';
|
160 |
-
|
161 |
-
if ( count($this->lists) )
|
162 |
-
{
|
163 |
-
$list_set = FALSE;
|
164 |
-
|
165 |
-
foreach ( $this->lists as $list )
|
166 |
-
{
|
167 |
-
// Skip over default lists
|
168 |
-
if ( $list['Name'] == 'Active' || $list['Name'] == 'Do Not Mail' || $list['Name'] == 'Removed' )
|
169 |
-
continue;
|
170 |
-
|
171 |
-
if ( urldecode($list['ListID']) == $li_cc_subscribers_to_list && !$list_set )
|
172 |
-
$list_set = TRUE;
|
173 |
-
|
174 |
-
echo '<option ' . ( urldecode($list['ListID']) == $li_cc_subscribers_to_list ? 'selected' : '' ) . ' value="' . urldecode($list['ListID']) . '">' . $list['Name'] . '</option>';
|
175 |
-
}
|
176 |
-
|
177 |
-
if ( !$list_set )
|
178 |
-
echo '<option selected value="">No list set...</option>';
|
179 |
-
}
|
180 |
-
else
|
181 |
-
{
|
182 |
-
echo '<option value="No lists...">No lists...</option>';
|
183 |
-
}
|
184 |
-
|
185 |
-
echo '</select>';
|
186 |
-
echo '<p><a href="https://login.constantcontact.com/login/login.sdo?goto=https://ui.constantcontact.com/rnavmap/distui/contacts" target="_blank">Create a new list on ConstantContact.com</a></p>';
|
187 |
-
}
|
188 |
-
|
189 |
function li_cc_get_email_lists ( $api_key, $username, $password )
|
190 |
{
|
191 |
$this->constant_contact = new LI_ConstantContact($username, $password, $api_key, FALSE);
|
5 |
class WPConstantContactConnectAdmin extends WPLeadInAdmin {
|
6 |
|
7 |
var $power_up_settings_section = 'leadin_cc_options_section';
|
8 |
+
var $power_option_name = 'leadin_cc_options';
|
9 |
var $power_up_icon;
|
10 |
var $bad_api_call;
|
11 |
var $constant_contact;
|
27 |
if ( is_admin() )
|
28 |
{
|
29 |
$this->power_up_icon = $power_up_icon_small;
|
30 |
+
add_action('admin_init', array($this, 'leadin_build_esp_settings_page'));
|
31 |
+
$this->options = get_option($this->power_option_name);
|
32 |
if ( isset($this->options['li_cc_email']) && isset($this->options['li_cc_password']) && $this->options['li_cc_email'] && $this->options['li_cc_password'] )
|
33 |
$this->authed = TRUE;
|
34 |
}
|
41 |
/**
|
42 |
* Creates settings options
|
43 |
*/
|
44 |
+
function leadin_build_esp_settings_page ()
|
45 |
{
|
46 |
global $leadin_constant_contact_connect_wp;
|
47 |
|
48 |
+
register_setting('leadin_settings_options', $this->power_option_name, array($this, 'sanitize'));
|
49 |
|
50 |
// If the creds are set, check if they are any good by hitting the API
|
51 |
if ( $this->authed )
|
89 |
if ( $li_cc_email )
|
90 |
{
|
91 |
printf(
|
92 |
+
'<input id="li_cc_email" type="hidden" name="' . $this->power_option_name . '[li_cc_email]" value="%s"/>',
|
93 |
$li_cc_email
|
94 |
);
|
95 |
}
|
97 |
if ( $li_cc_password )
|
98 |
{
|
99 |
printf(
|
100 |
+
'<input id="li_cc_password" type="hidden" name="' . $this->power_option_name . '[li_cc_password]" value="%s"/>',
|
101 |
$li_cc_password
|
102 |
);
|
103 |
}
|
112 |
{
|
113 |
$new_input = array();
|
114 |
|
115 |
+
if ( isset( $input['li_cc_email'] ) )
|
116 |
$new_input['li_cc_email'] = sanitize_text_field( $input['li_cc_email'] );
|
117 |
|
118 |
+
if ( isset( $input['li_cc_password'] ) )
|
119 |
$new_input['li_cc_password'] = sanitize_text_field( $input['li_cc_password'] );
|
120 |
|
|
|
|
|
|
|
121 |
return $new_input;
|
122 |
}
|
123 |
|
129 |
$li_cc_email = ( $this->options['li_cc_email'] ? $this->options['li_cc_email'] : '' ); // Get header from options, or show default
|
130 |
|
131 |
printf(
|
132 |
+
'<input id="li_cc_email" type="text" id="title" name="' . $this->power_option_name . '[li_cc_email]" value="%s" style="width: 430px;"/>',
|
133 |
$li_cc_email
|
134 |
);
|
135 |
}
|
142 |
$li_cc_password = ( $this->options['li_cc_password'] ? $this->options['li_cc_password'] : '' ); // Get header from options, or show default
|
143 |
|
144 |
printf(
|
145 |
+
'<input id="li_cc_password" type="password" id="title" name="' . $this->power_option_name . '[li_cc_password]" value="%s" style="width: 430px;"/>',
|
146 |
$li_cc_password
|
147 |
);
|
148 |
}
|
149 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
150 |
function li_cc_get_email_lists ( $api_key, $username, $password )
|
151 |
{
|
152 |
$this->constant_contact = new LI_ConstantContact($username, $password, $api_key, FALSE);
|
power-ups/contacts.php
CHANGED
@@ -37,7 +37,7 @@ if ( !defined('LEADIN_CONTACTS_PLUGIN_SLUG') )
|
|
37 |
require_once(LEADIN_CONTACTS_PLUGIN_DIR . '/admin/contacts-admin.php');
|
38 |
|
39 |
//=============================================
|
40 |
-
//
|
41 |
//=============================================
|
42 |
class WPLeadInContacts extends WPLeadIn {
|
43 |
|
37 |
require_once(LEADIN_CONTACTS_PLUGIN_DIR . '/admin/contacts-admin.php');
|
38 |
|
39 |
//=============================================
|
40 |
+
// WPLeadInContacts Class
|
41 |
//=============================================
|
42 |
class WPLeadInContacts extends WPLeadIn {
|
43 |
|
power-ups/contacts/admin/contacts-admin.php
CHANGED
@@ -84,6 +84,20 @@ class WPLeadInContactsAdmin extends WPLeadInAdmin {
|
|
84 |
$li_contact->get_contact_history();
|
85 |
$lead_email = $li_contact->history->lead->lead_email;
|
86 |
$lead_source = leadin_strip_params_from_url($li_contact->history->lead->lead_source);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
87 |
|
88 |
if ( isset($_POST['edit_tags']) )
|
89 |
{
|
@@ -126,9 +140,15 @@ class WPLeadInContactsAdmin extends WPLeadInAdmin {
|
|
126 |
}
|
127 |
|
128 |
echo '<div class="contact-header-wrap">';
|
|
|
|
|
|
|
|
|
129 |
echo '<img class="contact-header-avatar leadin-dynamic-avatar_' . substr($lead_id, -1) . '" height="76px" width="76px" src="https://api.hubapi.com/socialintel/v1/avatars?email=' . $lead_email . '"/>';
|
130 |
echo '<div class="contact-header-info">';
|
131 |
echo '<h1 class="contact-name">' . $lead_email . '</h1>';
|
|
|
|
|
132 |
echo '<div class="contact-tags">';
|
133 |
foreach( $li_contact->history->tags as $tag ) {
|
134 |
if ($tag->tag_set)
|
@@ -160,7 +180,7 @@ class WPLeadInContactsAdmin extends WPLeadInAdmin {
|
|
160 |
</form>
|
161 |
</div>
|
162 |
|
163 |
-
<a class="thickbox contact-edit-tags" href="#TB_inline?width=400&height=400&inlineId=edit-contact-tags">edit tags</a>
|
164 |
|
165 |
<?php
|
166 |
|
@@ -169,7 +189,7 @@ class WPLeadInContactsAdmin extends WPLeadInAdmin {
|
|
169 |
echo '</div>';
|
170 |
|
171 |
echo '<div id="col-container">';
|
172 |
-
echo '<div id="col-right">';
|
173 |
echo '<div class="col-wrap contact-history">';
|
174 |
echo '<ul class="sessions">';
|
175 |
$sessions = $li_contact->history->sessions;
|
@@ -279,7 +299,7 @@ class WPLeadInContactsAdmin extends WPLeadInAdmin {
|
|
279 |
echo '</ul>';
|
280 |
echo '</div>';
|
281 |
echo '</div>';
|
282 |
-
echo '<div id="col-left" class="metabox-holder">';
|
283 |
echo '<div class="leadin-meta-section">';
|
284 |
echo '<h4 class="leain-meta-header">Tracking Info</h4>';
|
285 |
echo '<table class="leadin-meta-table"><tbody>';
|
@@ -314,10 +334,61 @@ class WPLeadInContactsAdmin extends WPLeadInAdmin {
|
|
314 |
echo '</tbody></table>';
|
315 |
echo '</div>'; // leadin-meta-section
|
316 |
echo '<div class="leadin-meta-section">';
|
317 |
-
echo '<h4 class="leain-meta-header leadin-premium-tag">
|
318 |
echo '<table class="leadin-meta-table"><tbody>';
|
319 |
echo '<tr>';
|
320 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
321 |
echo '</tr>';
|
322 |
echo '</tbody></table>';
|
323 |
echo '</div>'; // leadin-meta-section
|
@@ -325,12 +396,145 @@ class WPLeadInContactsAdmin extends WPLeadInAdmin {
|
|
325 |
echo '<h4 class="leain-meta-header leadin-premium-tag">Company Info</h4>';
|
326 |
echo '<table class="leadin-meta-table"><tbody>';
|
327 |
echo '<tr>';
|
328 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
329 |
echo '</tr>';
|
330 |
echo '</tbody></table>';
|
331 |
echo '</div>'; // leadin-meta-section
|
332 |
-
echo '</div>';
|
333 |
-
|
334 |
echo '</div>';
|
335 |
}
|
336 |
|
@@ -365,9 +569,15 @@ class WPLeadInContactsAdmin extends WPLeadInAdmin {
|
|
365 |
|
366 |
<?php
|
367 |
|
368 |
-
$this->leadin_header('Leadin Contacts', 'leadin-contacts__header');
|
369 |
?>
|
370 |
|
|
|
|
|
|
|
|
|
|
|
|
|
371 |
<div class="leadin-contacts__nav">
|
372 |
<?php $leadinListTable->views(); ?>
|
373 |
</div>
|
@@ -656,4 +866,5 @@ if ( isset($_POST['export-all']) || isset($_POST['export-selected']) )
|
|
656 |
exit;
|
657 |
}
|
658 |
|
|
|
659 |
?>
|
84 |
$li_contact->get_contact_history();
|
85 |
$lead_email = $li_contact->history->lead->lead_email;
|
86 |
$lead_source = leadin_strip_params_from_url($li_contact->history->lead->lead_source);
|
87 |
+
$leadin_user = leadin_get_current_user();
|
88 |
+
|
89 |
+
?>
|
90 |
+
<script type="text/javascript">
|
91 |
+
!function(){var analytics=window.analytics=window.analytics||[];if(!analytics.initialize)if(analytics.invoked)window.console&&console.error&&console.error("Segment snippet included twice.");else{analytics.invoked=!0;analytics.methods=["trackSubmit","trackClick","trackLink","trackForm","pageview","identify","group","track","ready","alias","page","once","off","on"];analytics.factory=function(t){return function(){var e=Array.prototype.slice.call(arguments);e.unshift(t);analytics.push(e);return analytics}};for(var t=0;t<analytics.methods.length;t++){var e=analytics.methods[t];analytics[e]=analytics.factory(e)}analytics.load=function(t){var e=document.createElement("script");e.type="text/javascript";e.async=!0;e.src=("https:"===document.location.protocol?"https://":"http://")+"cdn.segment.com/analytics.js/v1/"+t+"/analytics.min.js";var n=document.getElementsByTagName("script")[0];n.parentNode.insertBefore(e,n)};analytics.SNIPPET_VERSION="3.0.1";
|
92 |
+
analytics.load("<?php echo SEGMENT_WRITE_KEY ?>");
|
93 |
+
analytics.identify("<?php echo $leadin_user['user_id'] ?>", {
|
94 |
+
email : "<?php echo $leadin_user['email'] ?>",
|
95 |
+
contacts : "<?php echo $leadin_user['total_contacts'] ?>",
|
96 |
+
});
|
97 |
+
analytics.page("Loaded Contact Detail Page");
|
98 |
+
}}();
|
99 |
+
</script>
|
100 |
+
<?php
|
101 |
|
102 |
if ( isset($_POST['edit_tags']) )
|
103 |
{
|
140 |
}
|
141 |
|
142 |
echo '<div class="contact-header-wrap">';
|
143 |
+
|
144 |
+
if ( $li_contact->history->lead->lead_deleted )
|
145 |
+
$li_contact->display_error_message_for_merged_contact($li_contact->history->lead->lead_email);
|
146 |
+
|
147 |
echo '<img class="contact-header-avatar leadin-dynamic-avatar_' . substr($lead_id, -1) . '" height="76px" width="76px" src="https://api.hubapi.com/socialintel/v1/avatars?email=' . $lead_email . '"/>';
|
148 |
echo '<div class="contact-header-info">';
|
149 |
echo '<h1 class="contact-name">' . $lead_email . '</h1>';
|
150 |
+
|
151 |
+
|
152 |
echo '<div class="contact-tags">';
|
153 |
foreach( $li_contact->history->tags as $tag ) {
|
154 |
if ($tag->tag_set)
|
180 |
</form>
|
181 |
</div>
|
182 |
|
183 |
+
<a class="thickbox contact-edit-tags" <?php echo ( $li_contact->history->lead->lead_deleted ? 'style="display: none;"' : '' ); ?> href="#TB_inline?width=400&height=400&inlineId=edit-contact-tags">edit tags</a>
|
184 |
|
185 |
<?php
|
186 |
|
189 |
echo '</div>';
|
190 |
|
191 |
echo '<div id="col-container">';
|
192 |
+
echo '<div id="col-right" ' . ( $li_contact->history->lead->lead_deleted ? 'style="display: none;"' : '' ) . '>';
|
193 |
echo '<div class="col-wrap contact-history">';
|
194 |
echo '<ul class="sessions">';
|
195 |
$sessions = $li_contact->history->sessions;
|
299 |
echo '</ul>';
|
300 |
echo '</div>';
|
301 |
echo '</div>';
|
302 |
+
echo '<div id="col-left" class="metabox-holder" ' . ( $li_contact->history->lead->lead_deleted ? 'style="display: none;"' : '' ) . '>';
|
303 |
echo '<div class="leadin-meta-section">';
|
304 |
echo '<h4 class="leain-meta-header">Tracking Info</h4>';
|
305 |
echo '<table class="leadin-meta-table"><tbody>';
|
334 |
echo '</tbody></table>';
|
335 |
echo '</div>'; // leadin-meta-section
|
336 |
echo '<div class="leadin-meta-section">';
|
337 |
+
echo '<h4 class="leain-meta-header leadin-premium-tag">Personal Info</h4>';
|
338 |
echo '<table class="leadin-meta-table"><tbody>';
|
339 |
echo '<tr>';
|
340 |
+
if ( leadin_check_pro_user() )
|
341 |
+
{
|
342 |
+
$social_data = FALSE;
|
343 |
+
|
344 |
+
if ( isset($li_contact->history->lead->social_data->properties->primary) )
|
345 |
+
{
|
346 |
+
$primary = $li_contact->history->lead->social_data->properties->primary;
|
347 |
+
echo '<b>' . $primary->title . ( $primary->company_name ? ' - ' . $primary->company_name : '' ) . '</b>';
|
348 |
+
|
349 |
+
$social_data = TRUE;
|
350 |
+
}
|
351 |
+
|
352 |
+
if ( isset($li_contact->history->lead->social_data->properties->description) )
|
353 |
+
{
|
354 |
+
echo '</br>' . $li_contact->history->lead->social_data->properties->description;
|
355 |
+
|
356 |
+
$social_data = TRUE;
|
357 |
+
}
|
358 |
+
|
359 |
+
if ( isset($li_contact->history->lead->social_data->properties->social_profiles) )
|
360 |
+
{
|
361 |
+
if ( count($li_contact->history->lead->social_data->properties->social_profiles) )
|
362 |
+
{
|
363 |
+
echo '<table class="leadin-meta-table"><tbody>';
|
364 |
+
foreach ( $li_contact->history->lead->social_data->properties->social_profiles as $key => $profile )
|
365 |
+
{
|
366 |
+
echo '<tr>';
|
367 |
+
echo '<th>';
|
368 |
+
echo $profile->typename;
|
369 |
+
echo '</th>';
|
370 |
+
echo '<td>';
|
371 |
+
echo '<a href="' . leadin_safe_social_profile_url($profile->url) . '" target="_blank">' . ( $profile->typeid == 'twitter' ? '@' : '' ) . ( $profile->typeid == 'linkedin' ? '/in/' : '' ) . $profile->username . '</a>';
|
372 |
+
echo '</td>';
|
373 |
+
echo '</tr>';
|
374 |
+
}
|
375 |
+
echo '</tbody></table>';
|
376 |
+
|
377 |
+
$social_data = TRUE;
|
378 |
+
}
|
379 |
+
}
|
380 |
+
|
381 |
+
if ( ! $social_data )
|
382 |
+
echo 'We couldn\'t find any personal info for this contact.';
|
383 |
+
}
|
384 |
+
else
|
385 |
+
{
|
386 |
+
echo '<table class="leadin-meta-table"><tbody>';
|
387 |
+
echo '<tr>';
|
388 |
+
echo '<td><a href="'. admin_url() . 'admin.php?page=leadin_pro_upgrade">Upgrade to Leadin Pro for free</a> to get personal info</td>';
|
389 |
+
echo '</tr>';
|
390 |
+
echo '</tbody></table>';
|
391 |
+
}
|
392 |
echo '</tr>';
|
393 |
echo '</tbody></table>';
|
394 |
echo '</div>'; // leadin-meta-section
|
396 |
echo '<h4 class="leain-meta-header leadin-premium-tag">Company Info</h4>';
|
397 |
echo '<table class="leadin-meta-table"><tbody>';
|
398 |
echo '<tr>';
|
399 |
+
if ( leadin_check_pro_user() )
|
400 |
+
{
|
401 |
+
$company_data = FALSE;
|
402 |
+
|
403 |
+
$properties = ( isset($li_contact->history->lead->company_data->properties) ? $li_contact->history->lead->company_data->properties : '' );
|
404 |
+
|
405 |
+
if ( isset($properties->name) )
|
406 |
+
{
|
407 |
+
echo '<p>';
|
408 |
+
echo '<b>About ' . $properties->name . '</b>';
|
409 |
+
if ( isset($properties->overview) )
|
410 |
+
{
|
411 |
+
$overview = $properties->overview;
|
412 |
+
|
413 |
+
if ( strlen($overview) < 260 )
|
414 |
+
{
|
415 |
+
echo '<br>' . $overview;
|
416 |
+
}
|
417 |
+
else
|
418 |
+
{
|
419 |
+
echo '<div id="company-detail-overview-short">' . substr($overview, 0, strpos($overview, '.', 260)) . ' ... <a id="contact-detail-read-more" href="javascript:void(0);">read more</a></div>';
|
420 |
+
echo '<div style="display: none;" id="company-detail-overview-full">' . $overview . ' <a id="contact-detail-read-less" href="javascript:void(0);">read less</a></div>';
|
421 |
+
}
|
422 |
+
|
423 |
+
$company_data = TRUE;
|
424 |
+
}
|
425 |
+
echo '</p>';
|
426 |
+
}
|
427 |
+
|
428 |
+
echo '<table class="leadin-meta-table"><tbody>';
|
429 |
+
|
430 |
+
if ( !empty($properties->employees) )
|
431 |
+
{
|
432 |
+
echo '<tr>';
|
433 |
+
echo '<th>Employees</th>';
|
434 |
+
echo '<td>' . $properties->employees . '</td>';
|
435 |
+
echo '</tr>';
|
436 |
+
|
437 |
+
$company_data = TRUE;
|
438 |
+
}
|
439 |
+
|
440 |
+
if ( !empty($properties->revenue) )
|
441 |
+
{
|
442 |
+
echo '<tr>';
|
443 |
+
echo '<th>Revenue</th>';
|
444 |
+
echo '<td>' . $properties->revenue . '</td>';
|
445 |
+
echo '</tr>';
|
446 |
+
|
447 |
+
$company_data = TRUE;
|
448 |
+
}
|
449 |
+
|
450 |
+
if ( !empty($properties->state) || !empty($properties->country) )
|
451 |
+
{
|
452 |
+
echo '<tr>';
|
453 |
+
echo '<th>Headquarters</th>';
|
454 |
+
echo '<td>' . ( !empty($properties->state) ? $properties->state : '' ) . ( !empty($properties->state) && !empty($properties->country) ? ', ' : '' ) . ( !empty($properties->country) ? $properties->country : '' ) . '</td>';
|
455 |
+
echo '</tr>';
|
456 |
+
|
457 |
+
$company_data = TRUE;
|
458 |
+
}
|
459 |
+
|
460 |
+
if ( !empty($properties->founded) )
|
461 |
+
{
|
462 |
+
echo '<tr>';
|
463 |
+
echo '<th>Founded</th>';
|
464 |
+
echo '<td>' . $properties->founded . '</td>';
|
465 |
+
echo '</tr>';
|
466 |
+
|
467 |
+
$company_data = TRUE;
|
468 |
+
}
|
469 |
+
|
470 |
+
if ( !empty($properties->facebookpageurl) )
|
471 |
+
{
|
472 |
+
echo '<tr>';
|
473 |
+
echo '<th>Facebook</th>';
|
474 |
+
echo '<td>' . '<a href="' . $properties->facebookpageurl . '" target="_blank">' . $properties->name . '</a></td>';
|
475 |
+
echo '</tr>';
|
476 |
+
|
477 |
+
$company_data = TRUE;
|
478 |
+
}
|
479 |
+
|
480 |
+
if ( !empty($properties->twitterusername) )
|
481 |
+
{
|
482 |
+
echo '<tr>';
|
483 |
+
echo '<th>Twitter</th>';
|
484 |
+
echo '<td>' . '<a href="' . $properties->twitterurl . '" target="_blank">' . '@' . $properties->twitterusername . '</a></td>';
|
485 |
+
echo '</tr>';
|
486 |
+
|
487 |
+
$company_data = TRUE;
|
488 |
+
}
|
489 |
+
|
490 |
+
if ( !empty($properties->linkedinurl) )
|
491 |
+
{
|
492 |
+
echo '<tr>';
|
493 |
+
echo '<th>LinkedIn</th>';
|
494 |
+
echo '<td>' . '<a href="' . $properties->linkedinurl . '" target="_blank">' . $properties->name . '</a></td>';
|
495 |
+
echo '</tr>';
|
496 |
+
|
497 |
+
$company_data = TRUE;
|
498 |
+
}
|
499 |
+
|
500 |
+
if ( !empty($properties->address) )
|
501 |
+
{
|
502 |
+
echo '<tr>';
|
503 |
+
echo '<th>Address</th>';
|
504 |
+
echo '<td><a href="http://maps.google.com/maps?q=' . urlencode($properties->address) . '"" target="_blank">' . $properties->address . '</a></td>';
|
505 |
+
echo '</tr>';
|
506 |
+
|
507 |
+
$company_data = TRUE;
|
508 |
+
}
|
509 |
+
|
510 |
+
if ( !empty($properties->country) )
|
511 |
+
{
|
512 |
+
echo '<tr>';
|
513 |
+
echo '<th>Country</th>';
|
514 |
+
echo '<td>' . $properties->country . '</td>';
|
515 |
+
echo '</tr>';
|
516 |
+
|
517 |
+
$company_data = TRUE;
|
518 |
+
}
|
519 |
+
|
520 |
+
if ( ! $company_data )
|
521 |
+
echo 'We couldn\'t find any company info for this contact.';
|
522 |
+
|
523 |
+
|
524 |
+
echo '</tbody></table>';
|
525 |
+
}
|
526 |
+
else
|
527 |
+
{
|
528 |
+
echo '<table class="leadin-meta-table"><tbody>';
|
529 |
+
echo '<tr>';
|
530 |
+
echo '<td><a href="'. admin_url() . 'admin.php?page=leadin_pro_upgrade">Upgrade to Leadin Pro for free</a> to get company info</td>';
|
531 |
+
echo '</tr>';
|
532 |
+
echo '</tbody></table>';
|
533 |
+
}
|
534 |
echo '</tr>';
|
535 |
echo '</tbody></table>';
|
536 |
echo '</div>'; // leadin-meta-section
|
537 |
+
echo '</div>'; // col-left
|
|
|
538 |
echo '</div>';
|
539 |
}
|
540 |
|
569 |
|
570 |
<?php
|
571 |
|
572 |
+
$this->leadin_header('Leadin Contacts', 'leadin-contacts__header', 'Loaded Contact List Page');
|
573 |
?>
|
574 |
|
575 |
+
<?php if ( isset($_GET['pro_upgrade']) ) : ?>
|
576 |
+
<div class="updated">
|
577 |
+
<p><?php _e( '<p><b>Welcome to Leadin Pro!</b></p> You can now use every feature Leadin has to offer. Visit our site to <a href="http://leadin.com/go-pro" target="_blank">learn more</a> about what Leadin Pro unlocks for you.', 'my-text-domain' ); ?></p>
|
578 |
+
</div>
|
579 |
+
<?php endif; ?>
|
580 |
+
|
581 |
<div class="leadin-contacts__nav">
|
582 |
<?php $leadinListTable->views(); ?>
|
583 |
</div>
|
866 |
exit;
|
867 |
}
|
868 |
|
869 |
+
|
870 |
?>
|
power-ups/getresponse-connect.php
ADDED
@@ -0,0 +1,133 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Power-up Name: GetResponse
|
4 |
+
* Power-up Class: LIGetResponseConnect
|
5 |
+
* Power-up Menu Text:
|
6 |
+
* Power-up Slug: getresponse_connect
|
7 |
+
* Power-up Menu Link: settings
|
8 |
+
* Power-up URI: http://leadin.com/mailchimp-connect
|
9 |
+
* Power-up Description: Push your contacts to GetResponse email lists.
|
10 |
+
* Power-up Icon: power-up-icon-getresponse-connect
|
11 |
+
* Power-up Icon Small: power-up-icon-getresponse-connect_small
|
12 |
+
* First Introduced: 3.1.0
|
13 |
+
* Power-up Tags: Newsletter, Email
|
14 |
+
* Auto Activate: No
|
15 |
+
* Permanently Enabled: No
|
16 |
+
* Hidden: No
|
17 |
+
* cURL Required: Yes
|
18 |
+
*/
|
19 |
+
|
20 |
+
//=============================================
|
21 |
+
// Define Constants
|
22 |
+
//=============================================
|
23 |
+
|
24 |
+
if ( !defined('LEADIN_GETRESPONSE_CONNECT_PATH') )
|
25 |
+
define('LEADIN_GETRESPONSE_CONNECT_PATH', LEADIN_PATH . '/power-ups/getresponse-connect');
|
26 |
+
|
27 |
+
if ( !defined('LEADIN_GETRESPONSE_CONNECT_PLUGIN_DIR') )
|
28 |
+
define('LEADIN_GETRESPONSE_CONNECT_PLUGIN_DIR', LEADIN_PLUGIN_DIR . '/power-ups/getresponse-connect');
|
29 |
+
|
30 |
+
if ( !defined('LEADIN_GETRESPONSE_CONNECT_PLUGIN_SLUG') )
|
31 |
+
define('LEADIN_GETRESPONSE_CONNECT_SLUG', basename(dirname(__FILE__)));
|
32 |
+
|
33 |
+
//=============================================
|
34 |
+
// Include Needed Files
|
35 |
+
//=============================================
|
36 |
+
require_once(LEADIN_GETRESPONSE_CONNECT_PLUGIN_DIR . '/admin/getresponse-connect-admin.php');
|
37 |
+
require_once(LEADIN_GETRESPONSE_CONNECT_PLUGIN_DIR . '/inc/LI_GetResponseAPI.php');
|
38 |
+
|
39 |
+
//=============================================
|
40 |
+
// WPLeadIn Class
|
41 |
+
//=============================================
|
42 |
+
class LIGetResponseConnect extends WPLeadIn {
|
43 |
+
|
44 |
+
var $admin;
|
45 |
+
var $options;
|
46 |
+
var $power_option_name = 'leadin_getresponse_connect_options';
|
47 |
+
|
48 |
+
/**
|
49 |
+
* Class constructor
|
50 |
+
*/
|
51 |
+
function __construct ( $activated )
|
52 |
+
{
|
53 |
+
//=============================================
|
54 |
+
// Hooks & Filters
|
55 |
+
//=============================================
|
56 |
+
|
57 |
+
if ( ! $activated )
|
58 |
+
return false;
|
59 |
+
|
60 |
+
global $leadin_getresponse_connect_wp;
|
61 |
+
$leadin_getresponse_connect_wp = $this;
|
62 |
+
$this->options = get_option($this->power_option_name);
|
63 |
+
}
|
64 |
+
|
65 |
+
public function admin_init ( )
|
66 |
+
{
|
67 |
+
$admin_class = get_class($this) . 'Admin';
|
68 |
+
$this->admin = new $admin_class($this->icon_small);
|
69 |
+
}
|
70 |
+
|
71 |
+
function power_up_setup_callback ( )
|
72 |
+
{
|
73 |
+
$this->admin->power_up_setup_callback();
|
74 |
+
}
|
75 |
+
|
76 |
+
/**
|
77 |
+
* Activate the power-up and add the defaults
|
78 |
+
*/
|
79 |
+
function add_defaults ()
|
80 |
+
{
|
81 |
+
|
82 |
+
}
|
83 |
+
|
84 |
+
/**
|
85 |
+
* Adds a subcsriber to a specific list
|
86 |
+
*
|
87 |
+
* @param string
|
88 |
+
* @param string
|
89 |
+
* @param string
|
90 |
+
* @param string
|
91 |
+
* @param string
|
92 |
+
* @return int/bool
|
93 |
+
*/
|
94 |
+
function push_contact_to_list ( $list_id = '', $email = '', $first_name = '', $last_name = '', $phone = '' )
|
95 |
+
{
|
96 |
+
if ( isset($this->options['li_gr_api_key']) && $this->options['li_gr_api_key'] && $list_id )
|
97 |
+
{
|
98 |
+
$gr = new LI_GetResponse($this->options['li_gr_api_key']);
|
99 |
+
$contact_synced = $gr->addContact($list_id, $first_name . ' ' . $last_name, $email);
|
100 |
+
|
101 |
+
leadin_track_plugin_activity('Contact Pushed to List', array('esp_connector' => 'getresponse'));
|
102 |
+
|
103 |
+
return TRUE;
|
104 |
+
}
|
105 |
+
|
106 |
+
return FALSE;
|
107 |
+
}
|
108 |
+
|
109 |
+
/**
|
110 |
+
* Adds a subcsriber to a specific list
|
111 |
+
*
|
112 |
+
* @param string
|
113 |
+
* @param array
|
114 |
+
* @return int/bool API status code OR false if api key not set
|
115 |
+
*/
|
116 |
+
function bulk_push_contact_to_list ( $list_id = '', $contacts = '' )
|
117 |
+
{
|
118 |
+
/*
|
119 |
+
The majority of our user base doesn't use Get Response, so we decided not to retroactively sync contacts to the list.
|
120 |
+
If people complain, we will respond with a support ticket and ask them to export/import manually.
|
121 |
+
*/
|
122 |
+
|
123 |
+
return FALSE;
|
124 |
+
}
|
125 |
+
}
|
126 |
+
|
127 |
+
//=============================================
|
128 |
+
// ESP Connect Init
|
129 |
+
//=============================================
|
130 |
+
|
131 |
+
global $leadin_getresponse_connect_wp;
|
132 |
+
|
133 |
+
?>
|
power-ups/getresponse-connect/admin/getresponse-connect-admin.php
ADDED
@@ -0,0 +1,206 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
//=============================================
|
3 |
+
// LIGetResponseConnectAdmin Class
|
4 |
+
//=============================================
|
5 |
+
class LIGetResponseConnectAdmin extends WPLeadInAdmin {
|
6 |
+
|
7 |
+
var $power_up_settings_section = 'leadin_getresponse_connect_options_section';
|
8 |
+
var $power_option_name = 'leadin_getresponse_connect_options';
|
9 |
+
var $power_up_icon;
|
10 |
+
var $options;
|
11 |
+
var $authed = FALSE;
|
12 |
+
var $invalid_key = FALSE;
|
13 |
+
|
14 |
+
/**
|
15 |
+
* Class constructor
|
16 |
+
*/
|
17 |
+
function __construct ( $power_up_icon_small )
|
18 |
+
{
|
19 |
+
//=============================================
|
20 |
+
// Hooks & Filters
|
21 |
+
//=============================================
|
22 |
+
|
23 |
+
if ( is_admin() )
|
24 |
+
{
|
25 |
+
$this->power_up_icon = $power_up_icon_small;
|
26 |
+
add_action('admin_init', array($this, 'leadin_build_esp_settings_page'));
|
27 |
+
$this->options = get_option($this->power_option_name);
|
28 |
+
$this->authed = ( isset($this->options['li_gr_api_key']) && $this->options['li_gr_api_key'] ? TRUE : FALSE );
|
29 |
+
|
30 |
+
if ( $this->authed )
|
31 |
+
$this->invalid_key = $this->li_check_invalid_api_key($this->options['li_gr_api_key']);
|
32 |
+
}
|
33 |
+
}
|
34 |
+
|
35 |
+
//=============================================
|
36 |
+
// Settings Page
|
37 |
+
//=============================================
|
38 |
+
|
39 |
+
/**
|
40 |
+
* Creates settings options
|
41 |
+
*/
|
42 |
+
function leadin_build_esp_settings_page ()
|
43 |
+
{
|
44 |
+
register_setting('leadin_settings_options', $this->power_option_name, array($this, 'sanitize'));
|
45 |
+
add_settings_section($this->power_up_settings_section, $this->power_up_icon . "GetResponse", '', LEADIN_ADMIN_PATH);
|
46 |
+
add_settings_field('li_gr_api_key', 'API key', array($this, 'li_gr_api_key_callback'), LEADIN_ADMIN_PATH, $this->power_up_settings_section);
|
47 |
+
|
48 |
+
if ( isset($this->options['li_gr_api_key']) )
|
49 |
+
{
|
50 |
+
if ( $this->options['li_gr_api_key'] )
|
51 |
+
add_settings_field('li_print_synced_lists', 'Synced tags', array($this, 'li_print_synced_lists'), LEADIN_ADMIN_PATH, $this->power_up_settings_section);
|
52 |
+
}
|
53 |
+
}
|
54 |
+
|
55 |
+
/**
|
56 |
+
* Sanitize each setting field as needed
|
57 |
+
*
|
58 |
+
* @param array $input Contains all settings fields as array keys
|
59 |
+
*/
|
60 |
+
public function sanitize ( $input )
|
61 |
+
{
|
62 |
+
$new_input = array();
|
63 |
+
|
64 |
+
if ( isset( $input['li_gr_api_key'] ) )
|
65 |
+
$new_input['li_gr_api_key'] = sanitize_text_field( $input['li_gr_api_key'] );
|
66 |
+
|
67 |
+
return $new_input;
|
68 |
+
}
|
69 |
+
|
70 |
+
/**
|
71 |
+
* Prints API key input for settings page
|
72 |
+
*/
|
73 |
+
function li_gr_api_key_callback ()
|
74 |
+
{
|
75 |
+
$li_gr_api_key = ( $this->options['li_gr_api_key'] ? $this->options['li_gr_api_key'] : '' ); // Get header from options, or show default
|
76 |
+
|
77 |
+
printf(
|
78 |
+
'<input id="li_gr_api_key" type="text" id="title" name="' . $this->power_option_name . '[li_gr_api_key]" value="%s" size="50"/>',
|
79 |
+
$li_gr_api_key
|
80 |
+
);
|
81 |
+
|
82 |
+
if ( ! isset($li_gr_api_key) || ! $li_gr_api_key )
|
83 |
+
echo '<p><a target="_blank" href="http://support.getresponse.com/faq/where-i-find-api-key">Get your API key</a> from <a href="https://app.getresponse.com/account.html#api" target="_blank">GetResponse.com</a></p>';
|
84 |
+
}
|
85 |
+
|
86 |
+
/**
|
87 |
+
* Prints synced lists out for settings page in format Tag Name → ESP list
|
88 |
+
*/
|
89 |
+
function li_print_synced_lists ()
|
90 |
+
{
|
91 |
+
$li_gr_api_key = ( $this->options['li_gr_api_key'] ? $this->options['li_gr_api_key'] : '' ); // Get header from options, or show default
|
92 |
+
|
93 |
+
if ( isset($li_gr_api_key ) )
|
94 |
+
{
|
95 |
+
$synced_lists = $this->li_get_synced_list_for_esp('getresponse');
|
96 |
+
$list_value_pairs = array();
|
97 |
+
$synced_list_count = 0;
|
98 |
+
|
99 |
+
echo '<table>';
|
100 |
+
foreach ( $synced_lists as $synced_list )
|
101 |
+
{
|
102 |
+
foreach ( stripslashes_deep(unserialize($synced_list->tag_synced_lists)) as $tag_synced_list )
|
103 |
+
{
|
104 |
+
if ( $tag_synced_list['esp'] == 'getresponse' )
|
105 |
+
{
|
106 |
+
echo '<tr class="synced-list-row">';
|
107 |
+
echo '<td class="synced-list-cell"><span class="icon-tag"></span> ' . $synced_list->tag_text . '</td>';
|
108 |
+
echo '<td class="synced-list-cell"><span class="synced-list-arrow">→</span></td>';
|
109 |
+
echo '<td class="synced-list-cell"><span class="icon-envelope"></span> ' . $tag_synced_list['list_name'] . '</td>';
|
110 |
+
echo '<td class="synced-list-edit"><a href="' . get_bloginfo('wpurl') . '/wp-admin/admin.php?page=leadin_tags&action=edit_tag&tag=' . $synced_list->tag_id . '">edit tag</a></td>';
|
111 |
+
echo '</tr>';
|
112 |
+
|
113 |
+
$synced_list_count++;
|
114 |
+
}
|
115 |
+
}
|
116 |
+
}
|
117 |
+
echo '</table>';
|
118 |
+
|
119 |
+
if ( ! $synced_list_count ) {
|
120 |
+
echo '<p>GetResponse connected succesfully! <a href="' . get_bloginfo('wpurl') . '/wp-admin/admin.php?page=leadin_tags">Select a tag to send contacts to GetResponse</a>.</p>';
|
121 |
+
} else {
|
122 |
+
echo '<p><a href="' . get_bloginfo('wpurl') . '/wp-admin/admin.php?page=leadin_tags">Edit your tags</a> or <a href="https://app.getresponse.com/create_campaign.html" target="_blank">Create a new list on GetResponse.com</a></p>';
|
123 |
+
}
|
124 |
+
}
|
125 |
+
}
|
126 |
+
|
127 |
+
/**
|
128 |
+
* Get synced list for the ESP from the WordPress database
|
129 |
+
*
|
130 |
+
* @return array/object
|
131 |
+
*/
|
132 |
+
function li_get_synced_list_for_esp ( $esp_name, $output_type = 'OBJECT' )
|
133 |
+
{
|
134 |
+
global $wpdb;
|
135 |
+
|
136 |
+
$q = $wpdb->prepare("SELECT * FROM $wpdb->li_tags WHERE tag_synced_lists LIKE '%%%s%%' AND tag_deleted = 0", $esp_name);
|
137 |
+
$synced_lists = $wpdb->get_results($q, $output_type);
|
138 |
+
|
139 |
+
return $synced_lists;
|
140 |
+
}
|
141 |
+
|
142 |
+
/**
|
143 |
+
* Format API-returned lists into parseable format on front end
|
144 |
+
*
|
145 |
+
* @return array
|
146 |
+
*/
|
147 |
+
function li_get_lists ( )
|
148 |
+
{
|
149 |
+
$lists = $this->li_get_api_lists($this->options['li_gr_api_key']);
|
150 |
+
|
151 |
+
$sanitized_lists = array();
|
152 |
+
if ( count($lists) )
|
153 |
+
{
|
154 |
+
foreach ( $lists as $list_id => $list )
|
155 |
+
{
|
156 |
+
$list_obj = (Object)NULL;
|
157 |
+
$list_obj->id = $list_id;
|
158 |
+
$list_obj->name = $list->name;
|
159 |
+
|
160 |
+
array_push($sanitized_lists, $list_obj);;
|
161 |
+
}
|
162 |
+
}
|
163 |
+
|
164 |
+
return $sanitized_lists;
|
165 |
+
}
|
166 |
+
|
167 |
+
/**
|
168 |
+
* Get lists from GetResponse account
|
169 |
+
*
|
170 |
+
* @param string
|
171 |
+
* @return array
|
172 |
+
*/
|
173 |
+
function li_get_api_lists ( $api_key )
|
174 |
+
{
|
175 |
+
$gr = new LI_GetResponse($api_key);
|
176 |
+
$campaigns = $gr->getCampaigns();
|
177 |
+
|
178 |
+
return $campaigns;
|
179 |
+
}
|
180 |
+
|
181 |
+
/**
|
182 |
+
* Use MailChimp API key to try to grab corresponding user profile to check validity of key
|
183 |
+
*
|
184 |
+
* @param string
|
185 |
+
* @return bool
|
186 |
+
*/
|
187 |
+
function li_check_invalid_api_key ( $api_key )
|
188 |
+
{
|
189 |
+
$gr = new LI_GetResponse($api_key);
|
190 |
+
$ping = $gr->ping();
|
191 |
+
|
192 |
+
if ( ! empty($ping) )
|
193 |
+
$invalid_key = FALSE;
|
194 |
+
else
|
195 |
+
{
|
196 |
+
unset($this->options['li_gr_api_key']);
|
197 |
+
update_option($this->power_option_name, $this->options);
|
198 |
+
|
199 |
+
$invalid_key = TRUE;
|
200 |
+
}
|
201 |
+
|
202 |
+
return $invalid_key;
|
203 |
+
}
|
204 |
+
}
|
205 |
+
|
206 |
+
?>
|
power-ups/getresponse-connect/inc/LI_GetResponseAPI.php
ADDED
@@ -0,0 +1,558 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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 LI_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 autoresponder message contents by Cycle Day
|
210 |
+
* @param string $campaign Campaign ID
|
211 |
+
* @param string $cycle_day Cycle Day
|
212 |
+
* @return object|null
|
213 |
+
*/
|
214 |
+
public function getMessageContentsByCycleDay($campaign, $cycle_day)
|
215 |
+
{
|
216 |
+
$params['campaigns'] = array($campaign);
|
217 |
+
$params['type'] = "autoresponder";
|
218 |
+
$request = $this->prepRequest('get_messages', $params);
|
219 |
+
$response = $this->execute($request);
|
220 |
+
foreach($response as $key => $message) if($message->day_of_cycle==$cycle_day) return $this->getMessageContents($key);
|
221 |
+
return null;
|
222 |
+
}
|
223 |
+
|
224 |
+
/**
|
225 |
+
* Add autoresponder to a campaign at a specific day of cycle
|
226 |
+
* @param string $campaign Campaign ID
|
227 |
+
* @param string $subject Subject of message
|
228 |
+
* @param array $contents Allowed keys are "plain" and "html", at least one is mandatory
|
229 |
+
* @param int $cycle_day
|
230 |
+
* @param string $from_field From Field ID obtained through getAccountFromFields()
|
231 |
+
* @param array $flags Enables extra functionality for a message: "clicktrack", "subscription_reminder", "openrate", "google_analytics"
|
232 |
+
* @return object
|
233 |
+
*/
|
234 |
+
public function addAutoresponder($campaign, $subject, $cycle_day, $html = null, $plain = null, $from_field = null, $flags = null)
|
235 |
+
{
|
236 |
+
$params = array('campaign' => $campaign, 'subject' => $subject, 'day_of_cycle' => $cycle_day);
|
237 |
+
if(is_string($html)) $params['contents']['html'] = $html;
|
238 |
+
if(is_string($plain)) $params['contents']['plain'] = $plain;
|
239 |
+
if(is_string($from_field)) $params['from_field'] = $from_field;
|
240 |
+
if(is_array($flags)) $params['flags'] = $flags;
|
241 |
+
$request = $this->prepRequest('add_autoresponder', $params);
|
242 |
+
$response = $this->execute($request);
|
243 |
+
return $response;
|
244 |
+
}
|
245 |
+
|
246 |
+
/**
|
247 |
+
* Delete an autoresponder
|
248 |
+
* @param string $id
|
249 |
+
* @return object
|
250 |
+
*/
|
251 |
+
public function deleteAutoresponder($id)
|
252 |
+
{
|
253 |
+
$request = $this->prepRequest('delete_autoresponder', array('message' => $id));
|
254 |
+
$response = $this->execute($request);
|
255 |
+
return $response;
|
256 |
+
}
|
257 |
+
|
258 |
+
/**
|
259 |
+
* Return a list of contacts, optionally filtered by multiple conditions
|
260 |
+
* @todo Implement all conditions, this is unfinished
|
261 |
+
* @param array|null $campaigns Optional argument to narrow results by campaign ID
|
262 |
+
* @param string $operator Optional argument to change operator (default is 'CONTAINS')
|
263 |
+
* See https://github.com/GetResponse/DevZone/tree/master/API#operators for additional operator options
|
264 |
+
* @param string $comparison
|
265 |
+
* @param array $fields (an associative array, the keys of which should enable/disable comparing name or email)
|
266 |
+
* @return object
|
267 |
+
*/
|
268 |
+
public function getContacts($campaigns = null, $operator = 'CONTAINS', $comparison = '%', $fields = array('name' => true, 'email' => false))
|
269 |
+
{
|
270 |
+
$params = null;
|
271 |
+
if(is_array($campaigns)) $params['campaigns'] = $campaigns;
|
272 |
+
if($fields['name']) $params['name'] = $this->prepTextOp($operator, $comparison);
|
273 |
+
if($fields['email']) $params['email'] = $this->prepTextOp($operator, $comparison);
|
274 |
+
$request = $this->prepRequest('get_contacts', $params);
|
275 |
+
$response = $this->execute($request);
|
276 |
+
return $response;
|
277 |
+
}
|
278 |
+
|
279 |
+
/**
|
280 |
+
* Return a list of contacts by email address (optionally narrowed by campaign)
|
281 |
+
* @param string $email Email Address of Contact (or a string contained in the email address)
|
282 |
+
* @param array|null $campaigns Optional argument to narrow results by campaign ID
|
283 |
+
* @param string $operator Optional argument to change operator (default is 'CONTAINS')
|
284 |
+
* See https://github.com/GetResponse/DevZone/tree/master/API#operators for additional operator options
|
285 |
+
* @return object
|
286 |
+
*/
|
287 |
+
public function getContactsByEmail($email, $campaigns = null, $operator = 'CONTAINS')
|
288 |
+
{
|
289 |
+
$params = null;
|
290 |
+
$params['email'] = $this->prepTextOp($operator, $email);
|
291 |
+
if(is_array($campaigns)) $params['campaigns'] = $campaigns;
|
292 |
+
$request = $this->prepRequest('get_contacts', $params);
|
293 |
+
$response = $this->execute($request);
|
294 |
+
return $response;
|
295 |
+
}
|
296 |
+
|
297 |
+
/**
|
298 |
+
* Return a list of contacts filtered by custom contact information
|
299 |
+
* $customs is an associative arrays, the keys of which should correspond to the
|
300 |
+
* custom field names of the customers you wish to retrieve.
|
301 |
+
* @param array|null $campaigns Optional argument to narrow results by campaign ID
|
302 |
+
* @param string $operator
|
303 |
+
* @param array $customs
|
304 |
+
* @param string $comparison
|
305 |
+
* @return object
|
306 |
+
*/
|
307 |
+
public function getContactsByCustoms($campaigns = null, $customs, $operator = 'EQUALS')
|
308 |
+
{
|
309 |
+
$params = null;
|
310 |
+
if(is_array($campaigns)) $params['campaigns'] = $campaigns;
|
311 |
+
if(!is_array($customs)) trigger_error('Second argument must be an array', E_USER_ERROR);
|
312 |
+
foreach($customs as $key => $val) $params['customs'][] = array('name' => $key, 'content' => $this->prepTextOp($operator, $val));
|
313 |
+
$request = $this->prepRequest('get_contacts', $params);
|
314 |
+
$response = $this->execute($request);
|
315 |
+
return $response;
|
316 |
+
}
|
317 |
+
|
318 |
+
/**
|
319 |
+
* Return a contact by ID
|
320 |
+
* @param string $id User ID
|
321 |
+
* @return object
|
322 |
+
*/
|
323 |
+
public function getContactByID($id)
|
324 |
+
{
|
325 |
+
$request = $this->prepRequest('get_contact', array('contact' => $id));
|
326 |
+
$response = $this->execute($request);
|
327 |
+
return $response;
|
328 |
+
}
|
329 |
+
|
330 |
+
|
331 |
+
/**
|
332 |
+
* Set a contact name
|
333 |
+
* @param string $id User ID
|
334 |
+
* @return object
|
335 |
+
*/
|
336 |
+
public function setContactName($id, $name)
|
337 |
+
{
|
338 |
+
$request = $this->prepRequest('set_contact_name', array('contact' => $id, 'name' => $name));
|
339 |
+
$response = $this->execute($request);
|
340 |
+
return $response;
|
341 |
+
}
|
342 |
+
|
343 |
+
/**
|
344 |
+
* Set a contact cycle
|
345 |
+
* @param string $id User ID
|
346 |
+
* @param int $cycle_day Cycle Day
|
347 |
+
* @return object
|
348 |
+
*/
|
349 |
+
public function setContactCycle($id, $cycle_day)
|
350 |
+
{
|
351 |
+
$request = $this->prepRequest('set_contact_cycle', array('contact' => $id, 'cycle_day' => $cycle_day));
|
352 |
+
$response = $this->execute($request);
|
353 |
+
return $response;
|
354 |
+
}
|
355 |
+
|
356 |
+
/**
|
357 |
+
* Set a contact campaign
|
358 |
+
* @param string $id User ID
|
359 |
+
* @param string $campaign Campaign ID
|
360 |
+
* @return object
|
361 |
+
*/
|
362 |
+
public function setContactCampaign($id, $campaign)
|
363 |
+
{
|
364 |
+
$request = $this->prepRequest('move_contact', array('contact' => $id, 'campaign' => $campaign));
|
365 |
+
$response = $this->execute($request);
|
366 |
+
return $response;
|
367 |
+
}
|
368 |
+
|
369 |
+
/**
|
370 |
+
* Return a contacts custom information
|
371 |
+
* @param string $id User ID
|
372 |
+
* @return object
|
373 |
+
*/
|
374 |
+
public function getContactCustoms($id)
|
375 |
+
{
|
376 |
+
$request = $this->prepRequest('get_contact_customs', array('contact' => $id));
|
377 |
+
$response = $this->execute($request);
|
378 |
+
return $response;
|
379 |
+
}
|
380 |
+
|
381 |
+
|
382 |
+
/**
|
383 |
+
* Set custom contact information
|
384 |
+
* $customs is an associative array, the keys of which should correspond to the
|
385 |
+
* custom field name you wish to add/modify/remove.
|
386 |
+
* Actions: added if not present, updated if present, removed if value is null
|
387 |
+
* @todo Implement multivalue customs.
|
388 |
+
* @param string $id User ID
|
389 |
+
* @param array $customs
|
390 |
+
* @return object
|
391 |
+
*/
|
392 |
+
public function setContactCustoms($id, $customs)
|
393 |
+
{
|
394 |
+
if(!is_array($customs)) trigger_error('Second argument must be an array', E_USER_ERROR);
|
395 |
+
foreach($customs as $key => $val) $params[] = array('name' => $key, 'content' => $val);
|
396 |
+
$request = $this->prepRequest('set_contact_customs', array('contact' => $id, 'customs' => $params));
|
397 |
+
$response = $this->execute($request);
|
398 |
+
return $response;
|
399 |
+
}
|
400 |
+
|
401 |
+
/**
|
402 |
+
* Return a contacts GeoIP
|
403 |
+
* @param string $id User ID
|
404 |
+
* @return object
|
405 |
+
*/
|
406 |
+
public function getContactGeoIP($id)
|
407 |
+
{
|
408 |
+
$request = $this->prepRequest('get_contact_geoip', array('contact' => $id));
|
409 |
+
$response = $this->execute($request);
|
410 |
+
return $response;
|
411 |
+
}
|
412 |
+
|
413 |
+
/**
|
414 |
+
* List dates when the messages were opened by contacts
|
415 |
+
* @param string $id User ID
|
416 |
+
* @return object
|
417 |
+
*/
|
418 |
+
public function getContactOpens($id)
|
419 |
+
{
|
420 |
+
$request = $this->prepRequest('get_contact_opens', array('contact' => $id));
|
421 |
+
$response = $this->execute($request);
|
422 |
+
return $response;
|
423 |
+
}
|
424 |
+
|
425 |
+
/**
|
426 |
+
* List dates when the links in messages were clicked by contacts
|
427 |
+
* @param string $id User ID
|
428 |
+
* @return object
|
429 |
+
*/
|
430 |
+
public function getContactClicks($id)
|
431 |
+
{
|
432 |
+
$request = $this->prepRequest('get_contact_clicks', array('contact' => $id));
|
433 |
+
$response = $this->execute($request);
|
434 |
+
return $response;
|
435 |
+
}
|
436 |
+
|
437 |
+
/**
|
438 |
+
* Add contact to the specified list (Requires email verification by contact)
|
439 |
+
* The return value of this function will be "queued", and on subsequent
|
440 |
+
* submission of the same email address will be "duplicated".
|
441 |
+
* @param string $campaign Campaign ID
|
442 |
+
* @param string $name Name of contact
|
443 |
+
* @param string $email Email address of contact
|
444 |
+
* @return object
|
445 |
+
*/
|
446 |
+
public function addContact($campaign, $name, $email)
|
447 |
+
{
|
448 |
+
$params = array (
|
449 |
+
'campaign' => $campaign,
|
450 |
+
'email' => $email,
|
451 |
+
'name' => $name
|
452 |
+
);
|
453 |
+
|
454 |
+
$request = $this->prepRequest('add_contact', $params);
|
455 |
+
$response = $this->execute($request);
|
456 |
+
return $response;
|
457 |
+
}
|
458 |
+
|
459 |
+
/**
|
460 |
+
* Delete a contact
|
461 |
+
* @param string $id
|
462 |
+
* @return object
|
463 |
+
*/
|
464 |
+
public function deleteContact($id)
|
465 |
+
{
|
466 |
+
$request = $this->prepRequest('delete_contact', array('contact' => $id));
|
467 |
+
$response = $this->execute($request);
|
468 |
+
return $response;
|
469 |
+
}
|
470 |
+
|
471 |
+
/**
|
472 |
+
* Get blacklist masks on account level
|
473 |
+
* Account is determined by API key
|
474 |
+
* @return object
|
475 |
+
*/
|
476 |
+
public function getAccountBlacklist()
|
477 |
+
{
|
478 |
+
$request = $this->prepRequest('get_account_blacklist');
|
479 |
+
$response = $this->execute($request);
|
480 |
+
return $response;
|
481 |
+
}
|
482 |
+
|
483 |
+
/**
|
484 |
+
* Adds blacklist mask on account level
|
485 |
+
* @param string $mask
|
486 |
+
* @return object
|
487 |
+
*/
|
488 |
+
public function addAccountBlacklist($mask)
|
489 |
+
{
|
490 |
+
$request = $this->prepRequest('add_account_blacklist', array('mask' => $mask));
|
491 |
+
$response = $this->execute($request);
|
492 |
+
return $response;
|
493 |
+
}
|
494 |
+
|
495 |
+
/**
|
496 |
+
* Delete blacklist mask on account level
|
497 |
+
* @param string $mask
|
498 |
+
* @return object
|
499 |
+
*/
|
500 |
+
public function deleteAccountBlacklist($mask)
|
501 |
+
{
|
502 |
+
$request = $this->prepRequest('delete_account_blacklist', array('mask' => $mask));
|
503 |
+
$response = $this->execute($request);
|
504 |
+
return $response;
|
505 |
+
}
|
506 |
+
|
507 |
+
/**
|
508 |
+
* Return a key => value array for text comparison
|
509 |
+
* @param string $operator
|
510 |
+
* @param mixed $comparison
|
511 |
+
* @return array
|
512 |
+
* @access private
|
513 |
+
*/
|
514 |
+
private function prepTextOp($operator, $comparison)
|
515 |
+
{
|
516 |
+
if(!in_array($operator, $this->textOperators)) trigger_error('Invalid text operator', E_USER_ERROR);
|
517 |
+
if($operator === 'CONTAINS') $comparison = '%'.$comparison.'%';
|
518 |
+
return array($operator => $comparison);
|
519 |
+
}
|
520 |
+
|
521 |
+
/**
|
522 |
+
* Return array as a JSON encoded string
|
523 |
+
* @param string $method API method to call
|
524 |
+
* @param array $params Array of parameters
|
525 |
+
* @return string JSON encoded string
|
526 |
+
* @access private
|
527 |
+
*/
|
528 |
+
private function prepRequest($method, $params = null, $id = null)
|
529 |
+
{
|
530 |
+
$array = array($this->apiKey);
|
531 |
+
if(!is_null($params)) $array[1] = $params;
|
532 |
+
$request = json_encode(array('method' => $method, 'params' => $array, 'id' => $id));
|
533 |
+
return $request;
|
534 |
+
}
|
535 |
+
|
536 |
+
/**
|
537 |
+
* Executes an API call
|
538 |
+
* @param string $request JSON encoded array
|
539 |
+
* @return object
|
540 |
+
* @access private
|
541 |
+
*/
|
542 |
+
private function execute($request)
|
543 |
+
{
|
544 |
+
$handle = curl_init($this->apiURL);
|
545 |
+
curl_setopt($handle, CURLOPT_POST, 1);
|
546 |
+
curl_setopt($handle, CURLOPT_POSTFIELDS, $request);
|
547 |
+
curl_setopt($handle, CURLOPT_HEADER, 'Content-type: application/json');
|
548 |
+
curl_setopt($handle, CURLOPT_RETURNTRANSFER, true);
|
549 |
+
$response = json_decode(curl_exec($handle));
|
550 |
+
if(curl_error($handle)) trigger_error(curl_error($handle), E_USER_ERROR);
|
551 |
+
$httpCode = curl_getinfo($handle, CURLINFO_HTTP_CODE);
|
552 |
+
if(!(($httpCode == '200') || ($httpCode == '204'))) trigger_error('API call failed. Server returned status code '.$httpCode, E_USER_ERROR);
|
553 |
+
curl_close($handle);
|
554 |
+
if(!$response->error) return $response->result;
|
555 |
+
}
|
556 |
+
}
|
557 |
+
|
558 |
+
?>
|
power-ups/lookups.php
ADDED
@@ -0,0 +1,78 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Power-up Name: Contact Lookups
|
4 |
+
* Power-up Class: WPLeadInLookups
|
5 |
+
* Power-up Menu Text:
|
6 |
+
* Power-up Menu Link: settings
|
7 |
+
* Power-up Slug: lookups
|
8 |
+
* Power-up URI: http://leadin.com/wordpress-lead-prospecting-plugin/
|
9 |
+
* Power-up Description: See social profiles and company information for every contact.
|
10 |
+
* Power-up Icon: powerup-icon-lookups
|
11 |
+
* Power-up Icon Small:
|
12 |
+
* First Introduced: 2.3.0
|
13 |
+
* Power-up Tags: Lookups
|
14 |
+
* Auto Activate: No
|
15 |
+
* Permanently Enabled: Yes
|
16 |
+
* Hidden: No
|
17 |
+
* cURL Required: Yes
|
18 |
+
* Pro Only: Yes
|
19 |
+
*/
|
20 |
+
|
21 |
+
//=============================================
|
22 |
+
// Define Constants
|
23 |
+
//=============================================
|
24 |
+
|
25 |
+
if ( !defined('LEADIN_LOOKUPS_PATH') )
|
26 |
+
define('LEADIN_LOOKUPS_PATH', LEADIN_PATH . '/power-ups/lookups');
|
27 |
+
|
28 |
+
if ( !defined('LEADIN_LOOKUPS_PLUGIN_DIR') )
|
29 |
+
define('LEADIN_LOOKUPS_PLUGIN_DIR', LEADIN_PLUGIN_DIR . '/power-ups/lookups');
|
30 |
+
|
31 |
+
if ( !defined('LEADIN_LOOKUPS_PLUGIN_SLUG') )
|
32 |
+
define('LEADIN_LOOKUPS_PLUGIN_SLUG', basename(dirname(__FILE__)));
|
33 |
+
|
34 |
+
//=============================================
|
35 |
+
// Include Needed Files
|
36 |
+
//=============================================
|
37 |
+
|
38 |
+
require_once(LEADIN_LOOKUPS_PLUGIN_DIR . '/admin/lookups-admin.php');
|
39 |
+
|
40 |
+
//=============================================
|
41 |
+
// WPLeadInLookups Class
|
42 |
+
//=============================================
|
43 |
+
class WPLeadInLookups extends WPLeadIn {
|
44 |
+
|
45 |
+
var $admin;
|
46 |
+
var $options;
|
47 |
+
|
48 |
+
/**
|
49 |
+
* Class constructor
|
50 |
+
*/
|
51 |
+
function __construct ( $activated )
|
52 |
+
{
|
53 |
+
//=============================================
|
54 |
+
// Hooks & Filters
|
55 |
+
//=============================================
|
56 |
+
|
57 |
+
if ( ! $activated )
|
58 |
+
return false;
|
59 |
+
|
60 |
+
global $leadin_lookups;
|
61 |
+
$leadin_lookups = $this;
|
62 |
+
}
|
63 |
+
|
64 |
+
public function admin_init ( )
|
65 |
+
{
|
66 |
+
$admin_class = get_class($this) . 'Admin';
|
67 |
+
$this->admin = new $admin_class($this->icon_small);
|
68 |
+
}
|
69 |
+
|
70 |
+
function power_up_setup_callback ( )
|
71 |
+
{
|
72 |
+
$this->admin->power_up_setup_callback();
|
73 |
+
}
|
74 |
+
}
|
75 |
+
|
76 |
+
global $leadin_lookups;
|
77 |
+
|
78 |
+
?>
|
power-ups/lookups/admin/inc/blacklist_domains.php
ADDED
@@ -0,0 +1,3025 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
global $blacklist_freemail_domains;
|
4 |
+
global $blacklist_nonmail_domains;
|
5 |
+
|
6 |
+
$blacklist_nonmail_domains = array(
|
7 |
+
'calendar-server.bounces.google.com', 'postmaster.twitter.com',
|
8 |
+
'exg6.exghost.com', 'reply.ticketmaster.com', 'plus.google.com', 'bounces.amazon.com', 'facebookmail.com', 'mlb.bounce.ed10.net',
|
9 |
+
'emailer.hubspot.com', 'playstation.sony.com', 'amazonses.com', 'docs.google.com', 'resource.calendar.google.com',
|
10 |
+
'emails.incisivemedia.com', 'doclist.bounces.google.com', 'googlegroups.com', 'message.myspace.com', 'joelonsoftware.com'
|
11 |
+
);
|
12 |
+
|
13 |
+
$blacklist_freemail_domains = array('123.com',
|
14 |
+
'123box.net',
|
15 |
+
'123india.com',
|
16 |
+
'123mail.cl',
|
17 |
+
'123qwe.co.uk',
|
18 |
+
'150ml.com',
|
19 |
+
'15meg4free.com',
|
20 |
+
'163.com',
|
21 |
+
'1coolplace.com',
|
22 |
+
'1freeemail.com',
|
23 |
+
'1funplace.com',
|
24 |
+
'1internetdrive.com',
|
25 |
+
'1mail.net',
|
26 |
+
'1me.net',
|
27 |
+
'1mum.com',
|
28 |
+
'1musicrow.com',
|
29 |
+
'1netdrive.com',
|
30 |
+
'1nsyncfan.com',
|
31 |
+
'1under.com',
|
32 |
+
'1webave.com',
|
33 |
+
'1webhighway.com',
|
34 |
+
'212.com',
|
35 |
+
'24horas.com',
|
36 |
+
'2911.net',
|
37 |
+
'2d2i.com',
|
38 |
+
'2die4.com',
|
39 |
+
'3000.it',
|
40 |
+
'37.com',
|
41 |
+
'3ammagazine.com',
|
42 |
+
'3email.com',
|
43 |
+
'3xl.net',
|
44 |
+
'444.net',
|
45 |
+
'4email.com',
|
46 |
+
'4email.net',
|
47 |
+
'4mg.com',
|
48 |
+
'4newyork.com',
|
49 |
+
'4x4man.com',
|
50 |
+
'5iron.com',
|
51 |
+
'88.am',
|
52 |
+
'8848.net',
|
53 |
+
'aaronkwok.net',
|
54 |
+
'abbeyroadlondon.co.uk',
|
55 |
+
'abdulnour.com',
|
56 |
+
'aberystwyth.com',
|
57 |
+
'about.com',
|
58 |
+
'academycougars.com',
|
59 |
+
'acceso.or.cr',
|
60 |
+
'access4less.net',
|
61 |
+
'accessgcc.com',
|
62 |
+
'ace-of-base.com',
|
63 |
+
'acmemail.net',
|
64 |
+
'acninc.net',
|
65 |
+
'adexec.com',
|
66 |
+
'adios.net',
|
67 |
+
'ados.fr',
|
68 |
+
'advalvas.be',
|
69 |
+
'aeiou.pt',
|
70 |
+
'aemail4u.com',
|
71 |
+
'aeneasmail.com',
|
72 |
+
'afreeinternet.com',
|
73 |
+
'africamail.com',
|
74 |
+
'agoodmail.com',
|
75 |
+
'ahaa.dk',
|
76 |
+
'aichi.com',
|
77 |
+
'airpost.net',
|
78 |
+
'ajacied.com',
|
79 |
+
'ak47.hu',
|
80 |
+
'aknet.kg',
|
81 |
+
'albawaba.com',
|
82 |
+
'alex4all.com',
|
83 |
+
'alexandria.cc',
|
84 |
+
'algeria.com',
|
85 |
+
'alhilal.net',
|
86 |
+
'alibaba.com',
|
87 |
+
'alive.cz',
|
88 |
+
'allmail.net',
|
89 |
+
'alloymail.com',
|
90 |
+
'allsaintsfan.com',
|
91 |
+
'alskens.dk',
|
92 |
+
'altavista.com',
|
93 |
+
'altavista.se',
|
94 |
+
'alternativagratis.com',
|
95 |
+
'alumnidirector.com',
|
96 |
+
'alvilag.hu',
|
97 |
+
'amele.com',
|
98 |
+
'america.hm',
|
99 |
+
'amnetsal.com',
|
100 |
+
'amrer.net',
|
101 |
+
'amuro.net',
|
102 |
+
'amuromail.com',
|
103 |
+
'ananzi.co.za',
|
104 |
+
'andylau.net',
|
105 |
+
'anfmail.com',
|
106 |
+
'angelfire.com',
|
107 |
+
'animalwoman.net',
|
108 |
+
'anjungcafe.com',
|
109 |
+
'another.com',
|
110 |
+
'antisocial.com',
|
111 |
+
'antongijsen.com',
|
112 |
+
'antwerpen.com',
|
113 |
+
'anymoment.com',
|
114 |
+
'anytimenow.com',
|
115 |
+
'aol.com',
|
116 |
+
'apexmail.com',
|
117 |
+
'apollo.lv',
|
118 |
+
'approvers.net',
|
119 |
+
'arabia.com',
|
120 |
+
'arabtop.net',
|
121 |
+
'archaeologist.com',
|
122 |
+
'arcor.de',
|
123 |
+
'arcotronics.bg',
|
124 |
+
'argentina.com',
|
125 |
+
'arnet.com.ar',
|
126 |
+
'artlover.com',
|
127 |
+
'artlover.com.au',
|
128 |
+
'as-if.com',
|
129 |
+
'asean-mail.com',
|
130 |
+
'asheville.com',
|
131 |
+
'asia-links.com',
|
132 |
+
'asia.com',
|
133 |
+
'asianavenue.com',
|
134 |
+
'asiancityweb.com',
|
135 |
+
'asianwired.net',
|
136 |
+
'assala.com',
|
137 |
+
'assamesemail.com',
|
138 |
+
'astroboymail.com',
|
139 |
+
'astrolover.com',
|
140 |
+
'asurfer.com',
|
141 |
+
'athenachu.net',
|
142 |
+
'atina.cl',
|
143 |
+
'atl.lv',
|
144 |
+
'atlaswebmail.com',
|
145 |
+
'atozasia.com',
|
146 |
+
'att.net',
|
147 |
+
'au.ru',
|
148 |
+
'ausi.com',
|
149 |
+
'australia.edu',
|
150 |
+
'australiamail.com',
|
151 |
+
'austrosearch.net',
|
152 |
+
'autoescuelanerja.com',
|
153 |
+
'avh.hu',
|
154 |
+
'ayna.com',
|
155 |
+
'azimiweb.com',
|
156 |
+
'bachelorboy.com',
|
157 |
+
'bachelorgal.com',
|
158 |
+
'backstreet-boys.com',
|
159 |
+
'backstreetboysclub.com',
|
160 |
+
'bagherpour.com',
|
161 |
+
'baptistmail.com',
|
162 |
+
'baptized.com',
|
163 |
+
'barcelona.com',
|
164 |
+
'batuta.net',
|
165 |
+
'baudoinconsulting.com',
|
166 |
+
'bcvibes.com',
|
167 |
+
'beeebank.com',
|
168 |
+
'beenhad.com',
|
169 |
+
'beep.ru',
|
170 |
+
'beer.com',
|
171 |
+
'beethoven.com',
|
172 |
+
'belice.com',
|
173 |
+
'belizehome.com',
|
174 |
+
'bellsouth.net',
|
175 |
+
'berlin.com',
|
176 |
+
'berlin.de',
|
177 |
+
'berlinexpo.de',
|
178 |
+
'bestmail.us',
|
179 |
+
'bharatmail.com',
|
180 |
+
'bigblue.net.au',
|
181 |
+
'bigboab.com',
|
182 |
+
'bigfoot.com',
|
183 |
+
'bigfoot.de',
|
184 |
+
'bigger.com',
|
185 |
+
'bigmailbox.com',
|
186 |
+
'bigramp.com',
|
187 |
+
'bikemechanics.com',
|
188 |
+
'bikeracers.net',
|
189 |
+
'bikerider.com',
|
190 |
+
'bimla.net',
|
191 |
+
'birdowner.net',
|
192 |
+
'bitpage.net',
|
193 |
+
'bizhosting.com',
|
194 |
+
'blackburnmail.com',
|
195 |
+
'blackplanet.com',
|
196 |
+
'blazemail.com',
|
197 |
+
'bluehyppo.com',
|
198 |
+
'bluemail.ch',
|
199 |
+
'bluemail.dk',
|
200 |
+
'blushmail.com',
|
201 |
+
'bmlsports.net',
|
202 |
+
'boardermail.com',
|
203 |
+
'bol.com.br',
|
204 |
+
'bolando.com',
|
205 |
+
'bollywoodz.com',
|
206 |
+
'bolt.com',
|
207 |
+
'boltonfans.com',
|
208 |
+
'bonbon.net',
|
209 |
+
'boom.com',
|
210 |
+
'bootmail.com',
|
211 |
+
'bornnaked.com',
|
212 |
+
'bostonoffice.com',
|
213 |
+
'bounce.net',
|
214 |
+
'box.az',
|
215 |
+
'boxbg.com',
|
216 |
+
'boxemail.com',
|
217 |
+
'boxfrog.com',
|
218 |
+
'boyzoneclub.com',
|
219 |
+
'bradfordfans.com',
|
220 |
+
'brasilia.net',
|
221 |
+
'brazilmail.com.br',
|
222 |
+
'breathe.com',
|
223 |
+
'brfree.com.br',
|
224 |
+
'britneyclub.com',
|
225 |
+
'brittonsign.com',
|
226 |
+
'btinternet.com',
|
227 |
+
'btopenworld.co.uk',
|
228 |
+
'bullsfan.com',
|
229 |
+
'bullsgame.com',
|
230 |
+
'bumerang.ro',
|
231 |
+
'buryfans.com',
|
232 |
+
'business-man.com',
|
233 |
+
'businessman.net',
|
234 |
+
'bvimailbox.com',
|
235 |
+
'c2i.net',
|
236 |
+
'c3.hu',
|
237 |
+
'c4.com',
|
238 |
+
'cable.comcast.com',
|
239 |
+
'caere.it',
|
240 |
+
'cairomail.com',
|
241 |
+
'callnetuk.com',
|
242 |
+
'caltanet.it',
|
243 |
+
'camidge.com',
|
244 |
+
'canada-11.com',
|
245 |
+
'canada.com',
|
246 |
+
'canoemail.com',
|
247 |
+
'canwetalk.com',
|
248 |
+
'caramail.com',
|
249 |
+
'care2.com',
|
250 |
+
'carioca.net',
|
251 |
+
'carolina.rr.com',
|
252 |
+
'cartestraina.ro',
|
253 |
+
'catcha.com',
|
254 |
+
'catlover.com',
|
255 |
+
'cd2.com',
|
256 |
+
'celineclub.com',
|
257 |
+
'centoper.it',
|
258 |
+
'centralpets.com',
|
259 |
+
'centrum.cz',
|
260 |
+
'centrum.sk',
|
261 |
+
'cfl.rr.com',
|
262 |
+
'cgac.es',
|
263 |
+
'chaiyomail.com',
|
264 |
+
'chance2mail.com',
|
265 |
+
'chandrasekar.net',
|
266 |
+
'charter.net',
|
267 |
+
'chat.ru',
|
268 |
+
'chattown.com',
|
269 |
+
'chauhanweb.com',
|
270 |
+
'check1check.com',
|
271 |
+
'cheerful.com',
|
272 |
+
'chemist.com',
|
273 |
+
'chequemail.com',
|
274 |
+
'chickmail.com',
|
275 |
+
'china.net.vg',
|
276 |
+
'chirk.com',
|
277 |
+
'chocaholic.com.au',
|
278 |
+
'cia-agent.com',
|
279 |
+
'cia.hu',
|
280 |
+
'ciaoweb.it',
|
281 |
+
'cicciociccio.com',
|
282 |
+
'city-of-bath.org',
|
283 |
+
'city-of-birmingham.com',
|
284 |
+
'city-of-brighton.org',
|
285 |
+
'city-of-cambridge.com',
|
286 |
+
'city-of-coventry.com',
|
287 |
+
'city-of-edinburgh.com',
|
288 |
+
'city-of-lichfield.com',
|
289 |
+
'city-of-lincoln.com',
|
290 |
+
'city-of-liverpool.com',
|
291 |
+
'city-of-manchester.com',
|
292 |
+
'city-of-nottingham.com',
|
293 |
+
'city-of-oxford.com',
|
294 |
+
'city-of-swansea.com',
|
295 |
+
'city-of-westminster.com',
|
296 |
+
'city-of-westminster.net',
|
297 |
+
'city-of-york.net',
|
298 |
+
'cityofcardiff.net',
|
299 |
+
'cityoflondon.org',
|
300 |
+
'claramail.com',
|
301 |
+
'classicmail.co.za',
|
302 |
+
'clearwire.net',
|
303 |
+
'clerk.com',
|
304 |
+
'cliffhanger.com',
|
305 |
+
'close2you.net',
|
306 |
+
'club4x4.net',
|
307 |
+
'clubalfa.com',
|
308 |
+
'clubbers.net',
|
309 |
+
'clubducati.com',
|
310 |
+
'clubhonda.net',
|
311 |
+
'cluemail.com',
|
312 |
+
'coder.hu',
|
313 |
+
'coid.biz',
|
314 |
+
'columnist.com',
|
315 |
+
'comcast.net',
|
316 |
+
'comic.com',
|
317 |
+
'compuserve.com',
|
318 |
+
'computer-freak.com',
|
319 |
+
'computermail.net',
|
320 |
+
'conexcol.com',
|
321 |
+
'connect4free.net',
|
322 |
+
'connectbox.com',
|
323 |
+
'consultant.com',
|
324 |
+
'cookiemonster.com',
|
325 |
+
'cool.br',
|
326 |
+
'coolgoose.ca',
|
327 |
+
'coolgoose.com',
|
328 |
+
'coolkiwi.com',
|
329 |
+
'coollist.com',
|
330 |
+
'coolmail.com',
|
331 |
+
'coolmail.net',
|
332 |
+
'coolsend.com',
|
333 |
+
'cooooool.com',
|
334 |
+
'cooperation.net',
|
335 |
+
'cooperationtogo.net',
|
336 |
+
'copacabana.com',
|
337 |
+
'cornerpub.com',
|
338 |
+
'corporatedirtbag.com',
|
339 |
+
'correo.terra.com.gt',
|
340 |
+
'cortinet.com',
|
341 |
+
'cotas.net',
|
342 |
+
'counsellor.com',
|
343 |
+
'countrylover.com',
|
344 |
+
'cox.net',
|
345 |
+
'cracker.hu',
|
346 |
+
'crazedanddazed.com',
|
347 |
+
'crazysexycool.com',
|
348 |
+
'critterpost.com',
|
349 |
+
'croeso.com',
|
350 |
+
'crosswinds.net',
|
351 |
+
'cry4helponline.com',
|
352 |
+
'cs.com',
|
353 |
+
'csinibaba.hu',
|
354 |
+
'curio-city.com',
|
355 |
+
'cute-girl.com',
|
356 |
+
'cuteandcuddly.com',
|
357 |
+
'cutey.com',
|
358 |
+
'cww.de',
|
359 |
+
'cyberbabies.com',
|
360 |
+
'cyberforeplay.net',
|
361 |
+
'cyberinbox.com',
|
362 |
+
'cyberleports.com',
|
363 |
+
'cybernet.it',
|
364 |
+
'dabsol.net',
|
365 |
+
'dadacasa.com',
|
366 |
+
'dailypioneer.com',
|
367 |
+
'dangerous-minds.com',
|
368 |
+
'dansegulvet.com',
|
369 |
+
'data54.com',
|
370 |
+
'davegracey.com',
|
371 |
+
'dazedandconfused.com',
|
372 |
+
'dbzmail.com',
|
373 |
+
'dcemail.com',
|
374 |
+
'deadlymob.org',
|
375 |
+
'deal-maker.com',
|
376 |
+
'dearriba.com',
|
377 |
+
'death-star.com',
|
378 |
+
'deliveryman.com',
|
379 |
+
'desertmail.com',
|
380 |
+
'desilota.com',
|
381 |
+
'deskpilot.com',
|
382 |
+
'detik.com',
|
383 |
+
'devotedcouples.com',
|
384 |
+
'dfwatson.com',
|
385 |
+
'di-ve.com',
|
386 |
+
'diplomats.com',
|
387 |
+
'disinfo.net',
|
388 |
+
'dmailman.com',
|
389 |
+
'dnsmadeeasy.com',
|
390 |
+
'doctor.com',
|
391 |
+
'doglover.com',
|
392 |
+
'dogmail.co.uk',
|
393 |
+
'dogsnob.net',
|
394 |
+
'doityourself.com',
|
395 |
+
'doneasy.com',
|
396 |
+
'donjuan.com',
|
397 |
+
'dontgotmail.com',
|
398 |
+
'dontmesswithtexas.com',
|
399 |
+
'doramail.com',
|
400 |
+
'dostmail.com',
|
401 |
+
'dotcom.fr',
|
402 |
+
'dott.it',
|
403 |
+
'dplanet.ch',
|
404 |
+
'dr.com',
|
405 |
+
'dragoncon.net',
|
406 |
+
'dropzone.com',
|
407 |
+
'dubaimail.com',
|
408 |
+
'dublin.com',
|
409 |
+
'dublin.ie',
|
410 |
+
'dygo.com',
|
411 |
+
'dynamitemail.com',
|
412 |
+
'e-apollo.lv',
|
413 |
+
'e-mail.dk',
|
414 |
+
'e-mail.ru',
|
415 |
+
'e-mailanywhere.com',
|
416 |
+
'e-mails.ru',
|
417 |
+
'e-tapaal.com',
|
418 |
+
'earthalliance.com',
|
419 |
+
'earthdome.com',
|
420 |
+
'earthlink.net',
|
421 |
+
'eastcoast.co.za',
|
422 |
+
'eastmail.com',
|
423 |
+
'ecbsolutions.net',
|
424 |
+
'echina.com',
|
425 |
+
'ednatx.com',
|
426 |
+
'educacao.te.pt',
|
427 |
+
'eircom.net',
|
428 |
+
'elsitio.com',
|
429 |
+
'elvis.com',
|
430 |
+
'email-london.co.uk',
|
431 |
+
'email.com',
|
432 |
+
'email.cz',
|
433 |
+
'email.ee',
|
434 |
+
'email.it',
|
435 |
+
'email.nu',
|
436 |
+
'email.ro',
|
437 |
+
'email.ru',
|
438 |
+
'email.si',
|
439 |
+
'email2me.net',
|
440 |
+
'emailacc.com',
|
441 |
+
'emailaccount.com',
|
442 |
+
'emailchoice.com',
|
443 |
+
'emailcorner.net',
|
444 |
+
'emailengine.net',
|
445 |
+
'emailforyou.net',
|
446 |
+
'emailgroups.net',
|
447 |
+
'emailpinoy.com',
|
448 |
+
'emailplanet.com',
|
449 |
+
'emails.ru',
|
450 |
+
'emailuser.net',
|
451 |
+
'emailx.net',
|
452 |
+
'ematic.com',
|
453 |
+
'end-war.com',
|
454 |
+
'enel.net',
|
455 |
+
'engineer.com',
|
456 |
+
'england.com',
|
457 |
+
'england.edu',
|
458 |
+
'epatra.com',
|
459 |
+
'epost.de',
|
460 |
+
'eposta.hu',
|
461 |
+
'eqqu.com',
|
462 |
+
'eramail.co.za',
|
463 |
+
'eresmas.com',
|
464 |
+
'eriga.lv',
|
465 |
+
'estranet.it',
|
466 |
+
'etoast.com',
|
467 |
+
'eudoramail.com',
|
468 |
+
'europe.com',
|
469 |
+
'euroseek.com',
|
470 |
+
'every1.net',
|
471 |
+
'everyday.com.kh',
|
472 |
+
'everyone.net',
|
473 |
+
'examnotes.net',
|
474 |
+
'excite.co.jp',
|
475 |
+
'excite.com',
|
476 |
+
'excite.it',
|
477 |
+
'execs.com',
|
478 |
+
'expressasia.com',
|
479 |
+
'extended.com',
|
480 |
+
'eyou.com',
|
481 |
+
'ezcybersearch.com',
|
482 |
+
'ezmail.egine.com',
|
483 |
+
'ezmail.ru',
|
484 |
+
'ezrs.com',
|
485 |
+
'f1fans.net',
|
486 |
+
'fantasticmail.com',
|
487 |
+
'faroweb.com',
|
488 |
+
'fastem.com',
|
489 |
+
'fastemail.us',
|
490 |
+
'fastemailer.com',
|
491 |
+
'fastermail.com',
|
492 |
+
'fastimap.com',
|
493 |
+
'fastmail.fm',
|
494 |
+
'fastmailbox.net',
|
495 |
+
'fastmessaging.com',
|
496 |
+
'fatcock.net',
|
497 |
+
'fathersrightsne.org',
|
498 |
+
'fbi-agent.com',
|
499 |
+
'fbi.hu',
|
500 |
+
'federalcontractors.com',
|
501 |
+
'femenino.com',
|
502 |
+
'feyenoorder.com',
|
503 |
+
'ffanet.com',
|
504 |
+
'fiberia.com',
|
505 |
+
'filipinolinks.com',
|
506 |
+
'financemail.net',
|
507 |
+
'financier.com',
|
508 |
+
'findmail.com',
|
509 |
+
'finebody.com',
|
510 |
+
'fire-brigade.com',
|
511 |
+
'fishburne.org',
|
512 |
+
'flashmail.com',
|
513 |
+
'flipcode.com',
|
514 |
+
'fmail.co.uk',
|
515 |
+
'fmailbox.com',
|
516 |
+
'fmgirl.com',
|
517 |
+
'fmguy.com',
|
518 |
+
'fnbmail.co.za',
|
519 |
+
'fnmail.com',
|
520 |
+
'for-president.com',
|
521 |
+
'forfree.at',
|
522 |
+
'forpresident.com',
|
523 |
+
'fortuncity.com',
|
524 |
+
'forum.dk',
|
525 |
+
'free.com.pe',
|
526 |
+
'free.fr',
|
527 |
+
'freeaccess.nl',
|
528 |
+
'freeandsingle.com',
|
529 |
+
'freedomlover.com',
|
530 |
+
'freegates.be',
|
531 |
+
'freeghana.com',
|
532 |
+
'freeler.nl',
|
533 |
+
'freemail.com.au',
|
534 |
+
'freemail.com.pk',
|
535 |
+
'freemail.de',
|
536 |
+
'freemail.et',
|
537 |
+
'freemail.gr',
|
538 |
+
'freemail.hu',
|
539 |
+
'freemail.it',
|
540 |
+
'freemail.lt',
|
541 |
+
'freemail.nl',
|
542 |
+
'freemail.org.mk',
|
543 |
+
'freenet.de',
|
544 |
+
'freenet.kg',
|
545 |
+
'freeola.com',
|
546 |
+
'freeola.net',
|
547 |
+
'freeserve.co.uk',
|
548 |
+
'freestart.hu',
|
549 |
+
'freesurf.fr',
|
550 |
+
'freesurf.nl',
|
551 |
+
'freeuk.com',
|
552 |
+
'freeuk.net',
|
553 |
+
'freeukisp.co.uk',
|
554 |
+
'freeweb.org',
|
555 |
+
'freewebemail.com',
|
556 |
+
'freeyellow.com',
|
557 |
+
'freezone.co.uk',
|
558 |
+
'fresnomail.com',
|
559 |
+
'friendsfan.com',
|
560 |
+
'from-africa.com',
|
561 |
+
'from-america.com',
|
562 |
+
'from-argentina.com',
|
563 |
+
'from-asia.com',
|
564 |
+
'from-australia.com',
|
565 |
+
'from-belgium.com',
|
566 |
+
'from-brazil.com',
|
567 |
+
'from-canada.com',
|
568 |
+
'from-china.net',
|
569 |
+
'from-england.com',
|
570 |
+
'from-europe.com',
|
571 |
+
'from-france.net',
|
572 |
+
'from-germany.net',
|
573 |
+
'from-holland.com',
|
574 |
+
'from-israel.com',
|
575 |
+
'from-italy.net',
|
576 |
+
'from-japan.net',
|
577 |
+
'from-korea.com',
|
578 |
+
'from-mexico.com',
|
579 |
+
'from-outerspace.com',
|
580 |
+
'from-russia.com',
|
581 |
+
'from-spain.net',
|
582 |
+
'fromalabama.com',
|
583 |
+
'fromalaska.com',
|
584 |
+
'fromarizona.com',
|
585 |
+
'fromarkansas.com',
|
586 |
+
'fromcalifornia.com',
|
587 |
+
'fromcolorado.com',
|
588 |
+
'fromconnecticut.com',
|
589 |
+
'fromdelaware.com',
|
590 |
+
'fromflorida.net',
|
591 |
+
'fromgeorgia.com',
|
592 |
+
'fromhawaii.net',
|
593 |
+
'fromidaho.com',
|
594 |
+
'fromillinois.com',
|
595 |
+
'fromindiana.com',
|
596 |
+
'fromiowa.com',
|
597 |
+
'fromjupiter.com',
|
598 |
+
'fromkansas.com',
|
599 |
+
'fromkentucky.com',
|
600 |
+
'fromlouisiana.com',
|
601 |
+
'frommaine.net',
|
602 |
+
'frommaryland.com',
|
603 |
+
'frommassachusetts.com',
|
604 |
+
'frommiami.com',
|
605 |
+
'frommichigan.com',
|
606 |
+
'fromminnesota.com',
|
607 |
+
'frommississippi.com',
|
608 |
+
'frommissouri.com',
|
609 |
+
'frommontana.com',
|
610 |
+
'fromnebraska.com',
|
611 |
+
'fromnevada.com',
|
612 |
+
'fromnewhampshire.com',
|
613 |
+
'fromnewjersey.com',
|
614 |
+
'fromnewmexico.com',
|
615 |
+
'fromnewyork.net',
|
616 |
+
'fromnorthcarolina.com',
|
617 |
+
'fromnorthdakota.com',
|
618 |
+
'fromohio.com',
|
619 |
+
'fromoklahoma.com',
|
620 |
+
'fromoregon.net',
|
621 |
+
'frompennsylvania.com',
|
622 |
+
'fromrhodeisland.com',
|
623 |
+
'fromru.com',
|
624 |
+
'fromsouthcarolina.com',
|
625 |
+
'fromsouthdakota.com',
|
626 |
+
'fromtennessee.com',
|
627 |
+
'fromtexas.com',
|
628 |
+
'fromthestates.com',
|
629 |
+
'fromutah.com',
|
630 |
+
'fromvermont.com',
|
631 |
+
'fromvirginia.com',
|
632 |
+
'fromwashington.com',
|
633 |
+
'fromwashingtondc.com',
|
634 |
+
'fromwestvirginia.com',
|
635 |
+
'fromwisconsin.com',
|
636 |
+
'fromwyoming.com',
|
637 |
+
'front.ru',
|
638 |
+
'frostbyte.uk.net',
|
639 |
+
'fsmail.net',
|
640 |
+
'ftml.net',
|
641 |
+
'fuorissimo.com',
|
642 |
+
'furnitureprovider.com',
|
643 |
+
'fut.es',
|
644 |
+
'fxsmails.com',
|
645 |
+
'galaxy5.com',
|
646 |
+
'gamebox.net',
|
647 |
+
'gardener.com',
|
648 |
+
'gawab.com',
|
649 |
+
'gaza.net',
|
650 |
+
'gazeta.pl',
|
651 |
+
'gazibooks.com',
|
652 |
+
'geek.hu',
|
653 |
+
'geeklife.com',
|
654 |
+
'general-hospital.com',
|
655 |
+
'geologist.com',
|
656 |
+
'geopia.com',
|
657 |
+
'giga4u.de',
|
658 |
+
'givepeaceachance.com',
|
659 |
+
'glay.org',
|
660 |
+
'glendale.net',
|
661 |
+
'globalfree.it',
|
662 |
+
'globalpagan.com',
|
663 |
+
'globalsite.com.br',
|
664 |
+
'gmail.com',
|
665 |
+
'gmail.co.za',
|
666 |
+
'gmx.at',
|
667 |
+
'gmx.de',
|
668 |
+
'gmx.li',
|
669 |
+
'gmx.net',
|
670 |
+
'go.com',
|
671 |
+
'go.ro',
|
672 |
+
'go.ru',
|
673 |
+
'go2net.com',
|
674 |
+
'gofree.co.uk',
|
675 |
+
'gol.com',
|
676 |
+
'goldenmail.ru',
|
677 |
+
'goldmail.ru',
|
678 |
+
'golfemail.com',
|
679 |
+
'golfmail.be',
|
680 |
+
'googlemail.com',
|
681 |
+
'goplay.com',
|
682 |
+
'gorontalo.net',
|
683 |
+
'gothere.uk.com',
|
684 |
+
'gotmail.com',
|
685 |
+
'gotomy.com',
|
686 |
+
'gportal.hu',
|
687 |
+
'graffiti.net',
|
688 |
+
'gratisweb.com',
|
689 |
+
'grungecafe.com',
|
690 |
+
'gua.net',
|
691 |
+
'guessmail.com',
|
692 |
+
'guju.net',
|
693 |
+
'guy.com',
|
694 |
+
'guy2.com',
|
695 |
+
'guyanafriends.com',
|
696 |
+
'gyorsposta.com',
|
697 |
+
'gyorsposta.hu',
|
698 |
+
'hackermail.net',
|
699 |
+
'hailmail.net',
|
700 |
+
'hairdresser.net',
|
701 |
+
'hamptonroads.com',
|
702 |
+
'handbag.com',
|
703 |
+
'hang-ten.com',
|
704 |
+
'happemail.com',
|
705 |
+
'happycounsel.com',
|
706 |
+
'hardcorefreak.com',
|
707 |
+
'heartthrob.com',
|
708 |
+
'heerschap.com',
|
709 |
+
'heesun.net',
|
710 |
+
'hehe.com',
|
711 |
+
'hello.hu',
|
712 |
+
'helter-skelter.com',
|
713 |
+
'herediano.com',
|
714 |
+
'herono1.com',
|
715 |
+
'highmilton.com',
|
716 |
+
'highquality.com',
|
717 |
+
'highveldmail.co.za',
|
718 |
+
'hispavista.com',
|
719 |
+
'hkstarphoto.com',
|
720 |
+
'hollywoodkids.com',
|
721 |
+
'home.no.net',
|
722 |
+
'home.ro',
|
723 |
+
'home.se',
|
724 |
+
'homelocator.com',
|
725 |
+
'homestead.com',
|
726 |
+
'hongkong.com',
|
727 |
+
'hookup.net',
|
728 |
+
'horrormail.com',
|
729 |
+
'hot-shot.com',
|
730 |
+
'hot.ee',
|
731 |
+
'hotbot.com',
|
732 |
+
'hotbrev.com',
|
733 |
+
'hotfire.net',
|
734 |
+
'hotletter.com',
|
735 |
+
'hotmail.co.il',
|
736 |
+
'hotmail.com',
|
737 |
+
'hotmail.ca',
|
738 |
+
'hotmail.com.br',
|
739 |
+
'hotmail.fr',
|
740 |
+
'hotmail.kg',
|
741 |
+
'hotmail.co.uk',
|
742 |
+
'hotmail.kz',
|
743 |
+
'hotmail.ru',
|
744 |
+
'hotmail.it',
|
745 |
+
'hotpop.com',
|
746 |
+
'hotpop3.com',
|
747 |
+
'hotvoice.com',
|
748 |
+
'hsuchi.net',
|
749 |
+
'hunsa.com',
|
750 |
+
'hushmail.com',
|
751 |
+
'i-france.com',
|
752 |
+
'i-mail.com.au',
|
753 |
+
'i-p.com',
|
754 |
+
'i12.com',
|
755 |
+
'iamawoman.com',
|
756 |
+
'iamwaiting.com',
|
757 |
+
'iamwasted.com',
|
758 |
+
'iamyours.com',
|
759 |
+
'icestorm.com',
|
760 |
+
'icloud.com',
|
761 |
+
'icmsconsultants.com',
|
762 |
+
'icq.com',
|
763 |
+
'icqmail.com',
|
764 |
+
'icrazy.com',
|
765 |
+
'ididitmyway.com',
|
766 |
+
'idirect.com',
|
767 |
+
'iespana.es',
|
768 |
+
'ignazio.it',
|
769 |
+
'ignmail.com',
|
770 |
+
'ijustdontcare.com',
|
771 |
+
'ilovechocolate.com',
|
772 |
+
'ilovetocollect.net',
|
773 |
+
'ilse.nl',
|
774 |
+
'imail.ru',
|
775 |
+
'imailbox.com',
|
776 |
+
'imel.org',
|
777 |
+
'imneverwrong.com',
|
778 |
+
'imposter.co.uk',
|
779 |
+
'imstressed.com',
|
780 |
+
'imtoosexy.com',
|
781 |
+
'in-box.net',
|
782 |
+
'iname.com',
|
783 |
+
'inbox.net',
|
784 |
+
'inbox.ru',
|
785 |
+
'incamail.com',
|
786 |
+
'incredimail.com',
|
787 |
+
'indexa.fr',
|
788 |
+
'india.com',
|
789 |
+
'indiatimes.com',
|
790 |
+
'infohq.com',
|
791 |
+
'infomail.es',
|
792 |
+
'infomart.or.jp',
|
793 |
+
'infovia.com.ar',
|
794 |
+
'inicia.es',
|
795 |
+
'inmail.sk',
|
796 |
+
'inorbit.com',
|
797 |
+
'insurer.com',
|
798 |
+
'interfree.it',
|
799 |
+
'interia.pl',
|
800 |
+
'interlap.com.ar',
|
801 |
+
'intermail.co.il',
|
802 |
+
'internet-police.com',
|
803 |
+
'internetbiz.com',
|
804 |
+
'internetdrive.com',
|
805 |
+
'internetegypt.com',
|
806 |
+
'internetemails.net',
|
807 |
+
'internetmailing.net',
|
808 |
+
'inwind.it',
|
809 |
+
'inbox.com',
|
810 |
+
'iobox.com',
|
811 |
+
'iobox.fi',
|
812 |
+
'iol.it',
|
813 |
+
'ip3.com',
|
814 |
+
'iqemail.com',
|
815 |
+
'irangate.net',
|
816 |
+
'iraqmail.com',
|
817 |
+
'irj.hu',
|
818 |
+
'isellcars.com',
|
819 |
+
'islamonline.net',
|
820 |
+
'ismart.net',
|
821 |
+
'isonfire.com',
|
822 |
+
'isp9.net',
|
823 |
+
'itloox.com',
|
824 |
+
'itmom.com',
|
825 |
+
'ivebeenframed.com',
|
826 |
+
'ivillage.com',
|
827 |
+
'iwan-fals.com',
|
828 |
+
'iwon.com',
|
829 |
+
'izadpanah.com',
|
830 |
+
'jakuza.hu',
|
831 |
+
'japan.com',
|
832 |
+
'jaydemail.com',
|
833 |
+
'jazzandjava.com',
|
834 |
+
'jazzgame.com',
|
835 |
+
'jetemail.net',
|
836 |
+
'jippii.fi',
|
837 |
+
'jmail.co.za',
|
838 |
+
'joinme.com',
|
839 |
+
'jordanmail.com',
|
840 |
+
'journalist.com',
|
841 |
+
'jovem.te.pt',
|
842 |
+
'joymail.com',
|
843 |
+
'jpopmail.com',
|
844 |
+
'jubiimail.dk',
|
845 |
+
'jumpy.it',
|
846 |
+
'juno.com',
|
847 |
+
'justemail.net',
|
848 |
+
'kaazoo.com',
|
849 |
+
'kaixo.com',
|
850 |
+
'kalpoint.com',
|
851 |
+
'kapoorweb.com',
|
852 |
+
'karachian.com',
|
853 |
+
'karachioye.com',
|
854 |
+
'karbasi.com',
|
855 |
+
'katamail.com',
|
856 |
+
'kayafmmail.co.za',
|
857 |
+
'keg-party.com',
|
858 |
+
'keko.com.ar',
|
859 |
+
'kellychen.com',
|
860 |
+
'keromail.com',
|
861 |
+
'kgb.hu',
|
862 |
+
'khosropour.com',
|
863 |
+
'kickassmail.com',
|
864 |
+
'killermail.com',
|
865 |
+
'kimo.com',
|
866 |
+
'kinki-kids.com',
|
867 |
+
'kittymail.com',
|
868 |
+
'kiwibox.com',
|
869 |
+
'kiwitown.com',
|
870 |
+
'krunis.com',
|
871 |
+
'kukamail.com',
|
872 |
+
'kumarweb.com',
|
873 |
+
'kuwait-mail.com',
|
874 |
+
'ladymail.cz',
|
875 |
+
'lagerlouts.com',
|
876 |
+
'lahoreoye.com',
|
877 |
+
'lakmail.com',
|
878 |
+
'lamer.hu',
|
879 |
+
'land.ru',
|
880 |
+
'lankamail.com',
|
881 |
+
'laposte.net',
|
882 |
+
'latinmail.com',
|
883 |
+
'lawyer.com',
|
884 |
+
'leehom.net',
|
885 |
+
'legalactions.com',
|
886 |
+
'legislator.com',
|
887 |
+
'leonlai.net',
|
888 |
+
'levele.com',
|
889 |
+
'levele.hu',
|
890 |
+
'lex.bg',
|
891 |
+
'liberomail.com',
|
892 |
+
'linkmaster.com',
|
893 |
+
'linuxfreemail.com',
|
894 |
+
'linuxmail.org',
|
895 |
+
'lionsfan.com.au',
|
896 |
+
'liontrucks.com',
|
897 |
+
'list.ru',
|
898 |
+
'live.ca',
|
899 |
+
'live.com',
|
900 |
+
'live.com.au',
|
901 |
+
'live.co.uk',
|
902 |
+
'live.se',
|
903 |
+
'liverpoolfans.com',
|
904 |
+
'llandudno.com',
|
905 |
+
'llangollen.com',
|
906 |
+
'lmxmail.sk',
|
907 |
+
'lobbyist.com',
|
908 |
+
'localbar.com',
|
909 |
+
'london.com',
|
910 |
+
'looksmart.co.uk',
|
911 |
+
'looksmart.com',
|
912 |
+
'looksmart.com.au',
|
913 |
+
'lopezclub.com',
|
914 |
+
'louiskoo.com',
|
915 |
+
'love.cz',
|
916 |
+
'loveable.com',
|
917 |
+
'lovelygirl.net',
|
918 |
+
'lovemail.com',
|
919 |
+
'lover-boy.com',
|
920 |
+
'lovergirl.com',
|
921 |
+
'lovingjesus.com',
|
922 |
+
'luso.pt',
|
923 |
+
'luukku.com',
|
924 |
+
'lycos.co.uk',
|
925 |
+
'lycos.com',
|
926 |
+
'lycos.es',
|
927 |
+
'lycos.it',
|
928 |
+
'lycos.ne.jp',
|
929 |
+
'lycosmail.com',
|
930 |
+
'm-a-i-l.com',
|
931 |
+
'mac.com',
|
932 |
+
'machinecandy.com',
|
933 |
+
'macmail.com',
|
934 |
+
'madrid.com',
|
935 |
+
'maffia.hu',
|
936 |
+
'magicmail.co.za',
|
937 |
+
'mahmoodweb.com',
|
938 |
+
'mail-awu.de',
|
939 |
+
'mail-box.cz',
|
940 |
+
'mail-center.com',
|
941 |
+
'mail-central.com',
|
942 |
+
'mail-page.com',
|
943 |
+
'mail.austria.com',
|
944 |
+
'mail.az',
|
945 |
+
'mail.be',
|
946 |
+
'mail.bulgaria.com',
|
947 |
+
'mail.co.za',
|
948 |
+
'mail.com',
|
949 |
+
'mail.ee',
|
950 |
+
'mail.gr',
|
951 |
+
'mail.md',
|
952 |
+
'mail.nu',
|
953 |
+
'mail.pf',
|
954 |
+
'mail.pt',
|
955 |
+
'mail.r-o-o-t.com',
|
956 |
+
'mail.ru',
|
957 |
+
'mail.sisna.com',
|
958 |
+
'mail.vasarhely.hu',
|
959 |
+
'mail15.com',
|
960 |
+
'mail2007.com',
|
961 |
+
'mail2aaron.com',
|
962 |
+
'mail2abby.com',
|
963 |
+
'mail2abc.com',
|
964 |
+
'mail2actor.com',
|
965 |
+
'mail2admiral.com',
|
966 |
+
'mail2adorable.com',
|
967 |
+
'mail2adoration.com',
|
968 |
+
'mail2adore.com',
|
969 |
+
'mail2adventure.com',
|
970 |
+
'mail2aeolus.com',
|
971 |
+
'mail2aether.com',
|
972 |
+
'mail2affection.com',
|
973 |
+
'mail2afghanistan.com',
|
974 |
+
'mail2africa.com',
|
975 |
+
'mail2agent.com',
|
976 |
+
'mail2aha.com',
|
977 |
+
'mail2ahoy.com',
|
978 |
+
'mail2aim.com',
|
979 |
+
'mail2air.com',
|
980 |
+
'mail2airbag.com',
|
981 |
+
'mail2airforce.com',
|
982 |
+
'mail2airport.com',
|
983 |
+
'mail2alabama.com',
|
984 |
+
'mail2alan.com',
|
985 |
+
'mail2alaska.com',
|
986 |
+
'mail2albania.com',
|
987 |
+
'mail2alcoholic.com',
|
988 |
+
'mail2alec.com',
|
989 |
+
'mail2alexa.com',
|
990 |
+
'mail2algeria.com',
|
991 |
+
'mail2alicia.com',
|
992 |
+
'mail2alien.com',
|
993 |
+
'mail2allan.com',
|
994 |
+
'mail2allen.com',
|
995 |
+
'mail2allison.com',
|
996 |
+
'mail2alpha.com',
|
997 |
+
'mail2alyssa.com',
|
998 |
+
'mail2amanda.com',
|
999 |
+
'mail2amazing.com',
|
1000 |
+
'mail2amber.com',
|
1001 |
+
'mail2america.com',
|
1002 |
+
'mail2american.com',
|
1003 |
+
'mail2andorra.com',
|
1004 |
+
'mail2andrea.com',
|
1005 |
+
'mail2andy.com',
|
1006 |
+
'mail2anesthesiologist.com',
|
1007 |
+
'mail2angela.com',
|
1008 |
+
'mail2angola.com',
|
1009 |
+
'mail2ann.com',
|
1010 |
+
'mail2anna.com',
|
1011 |
+
'mail2anne.com',
|
1012 |
+
'mail2anthony.com',
|
1013 |
+
'mail2anything.com',
|
1014 |
+
'mail2aphrodite.com',
|
1015 |
+
'mail2apollo.com',
|
1016 |
+
'mail2april.com',
|
1017 |
+
'mail2aquarius.com',
|
1018 |
+
'mail2arabia.com',
|
1019 |
+
'mail2arabic.com',
|
1020 |
+
'mail2architect.com',
|
1021 |
+
'mail2ares.com',
|
1022 |
+
'mail2argentina.com',
|
1023 |
+
'mail2aries.com',
|
1024 |
+
'mail2arizona.com',
|
1025 |
+
'mail2arkansas.com',
|
1026 |
+
'mail2armenia.com',
|
1027 |
+
'mail2army.com',
|
1028 |
+
'mail2arnold.com',
|
1029 |
+
'mail2art.com',
|
1030 |
+
'mail2artemus.com',
|
1031 |
+
'mail2arthur.com',
|
1032 |
+
'mail2artist.com',
|
1033 |
+
'mail2ashley.com',
|
1034 |
+
'mail2ask.com',
|
1035 |
+
'mail2astronomer.com',
|
1036 |
+
'mail2athena.com',
|
1037 |
+
'mail2athlete.com',
|
1038 |
+
'mail2atlas.com',
|
1039 |
+
'mail2atom.com',
|
1040 |
+
'mail2attitude.com',
|
1041 |
+
'mail2auction.com',
|
1042 |
+
'mail2aunt.com',
|
1043 |
+
'mail2australia.com',
|
1044 |
+
'mail2austria.com',
|
1045 |
+
'mail2azerbaijan.com',
|
1046 |
+
'mail2baby.com',
|
1047 |
+
'mail2bahamas.com',
|
1048 |
+
'mail2bahrain.com',
|
1049 |
+
'mail2ballerina.com',
|
1050 |
+
'mail2ballplayer.com',
|
1051 |
+
'mail2band.com',
|
1052 |
+
'mail2bangladesh.com',
|
1053 |
+
'mail2bank.com',
|
1054 |
+
'mail2banker.com',
|
1055 |
+
'mail2bankrupt.com',
|
1056 |
+
'mail2baptist.com',
|
1057 |
+
'mail2bar.com',
|
1058 |
+
'mail2barbados.com',
|
1059 |
+
'mail2barbara.com',
|
1060 |
+
'mail2barter.com',
|
1061 |
+
'mail2basketball.com',
|
1062 |
+
'mail2batter.com',
|
1063 |
+
'mail2beach.com',
|
1064 |
+
'mail2beast.com',
|
1065 |
+
'mail2beatles.com',
|
1066 |
+
'mail2beauty.com',
|
1067 |
+
'mail2becky.com',
|
1068 |
+
'mail2beijing.com',
|
1069 |
+
'mail2belgium.com',
|
1070 |
+
'mail2belize.com',
|
1071 |
+
'mail2ben.com',
|
1072 |
+
'mail2bernard.com',
|
1073 |
+
'mail2beth.com',
|
1074 |
+
'mail2betty.com',
|
1075 |
+
'mail2beverly.com',
|
1076 |
+
'mail2beyond.com',
|
1077 |
+
'mail2biker.com',
|
1078 |
+
'mail2bill.com',
|
1079 |
+
'mail2billionaire.com',
|
1080 |
+
'mail2billy.com',
|
1081 |
+
'mail2bio.com',
|
1082 |
+
'mail2biologist.com',
|
1083 |
+
'mail2black.com',
|
1084 |
+
'mail2blackbelt.com',
|
1085 |
+
'mail2blake.com',
|
1086 |
+
'mail2blind.com',
|
1087 |
+
'mail2blonde.com',
|
1088 |
+
'mail2blues.com',
|
1089 |
+
'mail2bob.com',
|
1090 |
+
'mail2bobby.com',
|
1091 |
+
'mail2bolivia.com',
|
1092 |
+
'mail2bombay.com',
|
1093 |
+
'mail2bonn.com',
|
1094 |
+
'mail2bookmark.com',
|
1095 |
+
'mail2boreas.com',
|
1096 |
+
'mail2bosnia.com',
|
1097 |
+
'mail2boston.com',
|
1098 |
+
'mail2botswana.com',
|
1099 |
+
'mail2bradley.com',
|
1100 |
+
'mail2brazil.com',
|
1101 |
+
'mail2breakfast.com',
|
1102 |
+
'mail2brian.com',
|
1103 |
+
'mail2bride.com',
|
1104 |
+
'mail2brittany.com',
|
1105 |
+
'mail2broker.com',
|
1106 |
+
'mail2brook.com',
|
1107 |
+
'mail2bruce.com',
|
1108 |
+
'mail2brunei.com',
|
1109 |
+
'mail2brunette.com',
|
1110 |
+
'mail2brussels.com',
|
1111 |
+
'mail2bryan.com',
|
1112 |
+
'mail2bug.com',
|
1113 |
+
'mail2bulgaria.com',
|
1114 |
+
'mail2business.com',
|
1115 |
+
'mail2buy.com',
|
1116 |
+
'mail2ca.com',
|
1117 |
+
'mail2california.com',
|
1118 |
+
'mail2calvin.com',
|
1119 |
+
'mail2cambodia.com',
|
1120 |
+
'mail2cameroon.com',
|
1121 |
+
'mail2canada.com',
|
1122 |
+
'mail2cancer.com',
|
1123 |
+
'mail2capeverde.com',
|
1124 |
+
'mail2capricorn.com',
|
1125 |
+
'mail2cardinal.com',
|
1126 |
+
'mail2cardiologist.com',
|
1127 |
+
'mail2care.com',
|
1128 |
+
'mail2caroline.com',
|
1129 |
+
'mail2carolyn.com',
|
1130 |
+
'mail2casey.com',
|
1131 |
+
'mail2cat.com',
|
1132 |
+
'mail2caterer.com',
|
1133 |
+
'mail2cathy.com',
|
1134 |
+
'mail2catlover.com',
|
1135 |
+
'mail2catwalk.com',
|
1136 |
+
'mail2cell.com',
|
1137 |
+
'mail2chad.com',
|
1138 |
+
'mail2champaign.com',
|
1139 |
+
'mail2charles.com',
|
1140 |
+
'mail2chef.com',
|
1141 |
+
'mail2chemist.com',
|
1142 |
+
'mail2cherry.com',
|
1143 |
+
'mail2chicago.com',
|
1144 |
+
'mail2chile.com',
|
1145 |
+
'mail2china.com',
|
1146 |
+
'mail2chinese.com',
|
1147 |
+
'mail2chocolate.com',
|
1148 |
+
'mail2christian.com',
|
1149 |
+
'mail2christie.com',
|
1150 |
+
'mail2christmas.com',
|
1151 |
+
'mail2christy.com',
|
1152 |
+
'mail2chuck.com',
|
1153 |
+
'mail2cindy.com',
|
1154 |
+
'mail2clark.com',
|
1155 |
+
'mail2classifieds.com',
|
1156 |
+
'mail2claude.com',
|
1157 |
+
'mail2cliff.com',
|
1158 |
+
'mail2clinic.com',
|
1159 |
+
'mail2clint.com',
|
1160 |
+
'mail2close.com',
|
1161 |
+
'mail2club.com',
|
1162 |
+
'mail2coach.com',
|
1163 |
+
'mail2coastguard.com',
|
1164 |
+
'mail2colin.com',
|
1165 |
+
'mail2college.com',
|
1166 |
+
'mail2colombia.com',
|
1167 |
+
'mail2color.com',
|
1168 |
+
'mail2colorado.com',
|
1169 |
+
'mail2columbia.com',
|
1170 |
+
'mail2comedian.com',
|
1171 |
+
'mail2composer.com',
|
1172 |
+
'mail2computer.com',
|
1173 |
+
'mail2computers.com',
|
1174 |
+
'mail2concert.com',
|
1175 |
+
'mail2congo.com',
|
1176 |
+
'mail2connect.com',
|
1177 |
+
'mail2connecticut.com',
|
1178 |
+
'mail2consultant.com',
|
1179 |
+
'mail2convict.com',
|
1180 |
+
'mail2cook.com',
|
1181 |
+
'mail2cool.com',
|
1182 |
+
'mail2cory.com',
|
1183 |
+
'mail2costarica.com',
|
1184 |
+
'mail2country.com',
|
1185 |
+
'mail2courtney.com',
|
1186 |
+
'mail2cowboy.com',
|
1187 |
+
'mail2cowgirl.com',
|
1188 |
+
'mail2craig.com',
|
1189 |
+
'mail2crave.com',
|
1190 |
+
'mail2crazy.com',
|
1191 |
+
'mail2create.com',
|
1192 |
+
'mail2croatia.com',
|
1193 |
+
'mail2cry.com',
|
1194 |
+
'mail2crystal.com',
|
1195 |
+
'mail2cuba.com',
|
1196 |
+
'mail2culture.com',
|
1197 |
+
'mail2curt.com',
|
1198 |
+
'mail2customs.com',
|
1199 |
+
'mail2cute.com',
|
1200 |
+
'mail2cutey.com',
|
1201 |
+
'mail2cynthia.com',
|
1202 |
+
'mail2cyprus.com',
|
1203 |
+
'mail2czechrepublic.com',
|
1204 |
+
'mail2dad.com',
|
1205 |
+
'mail2dale.com',
|
1206 |
+
'mail2dallas.com',
|
1207 |
+
'mail2dan.com',
|
1208 |
+
'mail2dana.com',
|
1209 |
+
'mail2dance.com',
|
1210 |
+
'mail2dancer.com',
|
1211 |
+
'mail2danielle.com',
|
1212 |
+
'mail2danny.com',
|
1213 |
+
'mail2darlene.com',
|
1214 |
+
'mail2darling.com',
|
1215 |
+
'mail2darren.com',
|
1216 |
+
'mail2daughter.com',
|
1217 |
+
'mail2dave.com',
|
1218 |
+
'mail2dawn.com',
|
1219 |
+
'mail2dc.com',
|
1220 |
+
'mail2dealer.com',
|
1221 |
+
'mail2deanna.com',
|
1222 |
+
'mail2dearest.com',
|
1223 |
+
'mail2debbie.com',
|
1224 |
+
'mail2debby.com',
|
1225 |
+
'mail2deer.com',
|
1226 |
+
'mail2delaware.com',
|
1227 |
+
'mail2delicious.com',
|
1228 |
+
'mail2demeter.com',
|
1229 |
+
'mail2democrat.com',
|
1230 |
+
'mail2denise.com',
|
1231 |
+
'mail2denmark.com',
|
1232 |
+
'mail2dennis.com',
|
1233 |
+
'mail2dentist.com',
|
1234 |
+
'mail2derek.com',
|
1235 |
+
'mail2desert.com',
|
1236 |
+
'mail2devoted.com',
|
1237 |
+
'mail2devotion.com',
|
1238 |
+
'mail2diamond.com',
|
1239 |
+
'mail2diana.com',
|
1240 |
+
'mail2diane.com',
|
1241 |
+
'mail2diehard.com',
|
1242 |
+
'mail2dilemma.com',
|
1243 |
+
'mail2dillon.com',
|
1244 |
+
'mail2dinner.com',
|
1245 |
+
'mail2dinosaur.com',
|
1246 |
+
'mail2dionysos.com',
|
1247 |
+
'mail2diplomat.com',
|
1248 |
+
'mail2director.com',
|
1249 |
+
'mail2dirk.com',
|
1250 |
+
'mail2disco.com',
|
1251 |
+
'mail2dive.com',
|
1252 |
+
'mail2diver.com',
|
1253 |
+
'mail2divorced.com',
|
1254 |
+
'mail2djibouti.com',
|
1255 |
+
'mail2doctor.com',
|
1256 |
+
'mail2doglover.com',
|
1257 |
+
'mail2dominic.com',
|
1258 |
+
'mail2dominica.com',
|
1259 |
+
'mail2dominicanrepublic.com',
|
1260 |
+
'mail2don.com',
|
1261 |
+
'mail2donald.com',
|
1262 |
+
'mail2donna.com',
|
1263 |
+
'mail2doris.com',
|
1264 |
+
'mail2dorothy.com',
|
1265 |
+
'mail2doug.com',
|
1266 |
+
'mail2dough.com',
|
1267 |
+
'mail2douglas.com',
|
1268 |
+
'mail2dow.com',
|
1269 |
+
'mail2downtown.com',
|
1270 |
+
'mail2dream.com',
|
1271 |
+
'mail2dreamer.com',
|
1272 |
+
'mail2dude.com',
|
1273 |
+
'mail2dustin.com',
|
1274 |
+
'mail2dyke.com',
|
1275 |
+
'mail2dylan.com',
|
1276 |
+
'mail2earl.com',
|
1277 |
+
'mail2earth.com',
|
1278 |
+
'mail2eastend.com',
|
1279 |
+
'mail2eat.com',
|
1280 |
+
'mail2economist.com',
|
1281 |
+
'mail2ecuador.com',
|
1282 |
+
'mail2eddie.com',
|
1283 |
+
'mail2edgar.com',
|
1284 |
+
'mail2edwin.com',
|
1285 |
+
'mail2egypt.com',
|
1286 |
+
'mail2electron.com',
|
1287 |
+
'mail2eli.com',
|
1288 |
+
'mail2elizabeth.com',
|
1289 |
+
'mail2ellen.com',
|
1290 |
+
'mail2elliot.com',
|
1291 |
+
'mail2elsalvador.com',
|
1292 |
+
'mail2elvis.com',
|
1293 |
+
'mail2emergency.com',
|
1294 |
+
'mail2emily.com',
|
1295 |
+
'mail2engineer.com',
|
1296 |
+
'mail2english.com',
|
1297 |
+
'mail2environmentalist.com',
|
1298 |
+
'mail2eos.com',
|
1299 |
+
'mail2eric.com',
|
1300 |
+
'mail2erica.com',
|
1301 |
+
'mail2erin.com',
|
1302 |
+
'mail2erinyes.com',
|
1303 |
+
'mail2eris.com',
|
1304 |
+
'mail2eritrea.com',
|
1305 |
+
'mail2ernie.com',
|
1306 |
+
'mail2eros.com',
|
1307 |
+
'mail2estonia.com',
|
1308 |
+
'mail2ethan.com',
|
1309 |
+
'mail2ethiopia.com',
|
1310 |
+
'mail2eu.com',
|
1311 |
+
'mail2europe.com',
|
1312 |
+
'mail2eurus.com',
|
1313 |
+
'mail2eva.com',
|
1314 |
+
'mail2evan.com',
|
1315 |
+
'mail2evelyn.com',
|
1316 |
+
'mail2everything.com',
|
1317 |
+
'mail2exciting.com',
|
1318 |
+
'mail2expert.com',
|
1319 |
+
'mail2fairy.com',
|
1320 |
+
'mail2faith.com',
|
1321 |
+
'mail2fanatic.com',
|
1322 |
+
'mail2fancy.com',
|
1323 |
+
'mail2fantasy.com',
|
1324 |
+
'mail2farm.com',
|
1325 |
+
'mail2farmer.com',
|
1326 |
+
'mail2fashion.com',
|
1327 |
+
'mail2fat.com',
|
1328 |
+
'mail2feeling.com',
|
1329 |
+
'mail2female.com',
|
1330 |
+
'mail2fever.com',
|
1331 |
+
'mail2fighter.com',
|
1332 |
+
'mail2fiji.com',
|
1333 |
+
'mail2filmfestival.com',
|
1334 |
+
'mail2films.com',
|
1335 |
+
'mail2finance.com',
|
1336 |
+
'mail2finland.com',
|
1337 |
+
'mail2fireman.com',
|
1338 |
+
'mail2firm.com',
|
1339 |
+
'mail2fisherman.com',
|
1340 |
+
'mail2flexible.com',
|
1341 |
+
'mail2florence.com',
|
1342 |
+
'mail2florida.com',
|
1343 |
+
'mail2floyd.com',
|
1344 |
+
'mail2fly.com',
|
1345 |
+
'mail2fond.com',
|
1346 |
+
'mail2fondness.com',
|
1347 |
+
'mail2football.com',
|
1348 |
+
'mail2footballfan.com',
|
1349 |
+
'mail2found.com',
|
1350 |
+
'mail2france.com',
|
1351 |
+
'mail2frank.com',
|
1352 |
+
'mail2frankfurt.com',
|
1353 |
+
'mail2franklin.com',
|
1354 |
+
'mail2fred.com',
|
1355 |
+
'mail2freddie.com',
|
1356 |
+
'mail2free.com',
|
1357 |
+
'mail2freedom.com',
|
1358 |
+
'mail2french.com',
|
1359 |
+
'mail2freudian.com',
|
1360 |
+
'mail2friendship.com',
|
1361 |
+
'mail2from.com',
|
1362 |
+
'mail2fun.com',
|
1363 |
+
'mail2gabon.com',
|
1364 |
+
'mail2gabriel.com',
|
1365 |
+
'mail2gail.com',
|
1366 |
+
'mail2galaxy.com',
|
1367 |
+
'mail2gambia.com',
|
1368 |
+
'mail2games.com',
|
1369 |
+
'mail2gary.com',
|
1370 |
+
'mail2gavin.com',
|
1371 |
+
'mail2gemini.com',
|
1372 |
+
'mail2gene.com',
|
1373 |
+
'mail2genes.com',
|
1374 |
+
'mail2geneva.com',
|
1375 |
+
'mail2george.com',
|
1376 |
+
'mail2georgia.com',
|
1377 |
+
'mail2gerald.com',
|
1378 |
+
'mail2german.com',
|
1379 |
+
'mail2germany.com',
|
1380 |
+
'mail2ghana.com',
|
1381 |
+
'mail2gilbert.com',
|
1382 |
+
'mail2gina.com',
|
1383 |
+
'mail2girl.com',
|
1384 |
+
'mail2glen.com',
|
1385 |
+
'mail2gloria.com',
|
1386 |
+
'mail2goddess.com',
|
1387 |
+
'mail2gold.com',
|
1388 |
+
'mail2golfclub.com',
|
1389 |
+
'mail2golfer.com',
|
1390 |
+
'mail2gordon.com',
|
1391 |
+
'mail2government.com',
|
1392 |
+
'mail2grab.com',
|
1393 |
+
'mail2grace.com',
|
1394 |
+
'mail2graham.com',
|
1395 |
+
'mail2grandma.com',
|
1396 |
+
'mail2grandpa.com',
|
1397 |
+
'mail2grant.com',
|
1398 |
+
'mail2greece.com',
|
1399 |
+
'mail2green.com',
|
1400 |
+
'mail2greg.com',
|
1401 |
+
'mail2grenada.com',
|
1402 |
+
'mail2gsm.com',
|
1403 |
+
'mail2guard.com',
|
1404 |
+
'mail2guatemala.com',
|
1405 |
+
'mail2guy.com',
|
1406 |
+
'mail2hades.com',
|
1407 |
+
'mail2haiti.com',
|
1408 |
+
'mail2hal.com',
|
1409 |
+
'mail2handhelds.com',
|
1410 |
+
'mail2hank.com',
|
1411 |
+
'mail2hannah.com',
|
1412 |
+
'mail2harold.com',
|
1413 |
+
'mail2harry.com',
|
1414 |
+
'mail2hawaii.com',
|
1415 |
+
'mail2headhunter.com',
|
1416 |
+
'mail2heal.com',
|
1417 |
+
'mail2heather.com',
|
1418 |
+
'mail2heaven.com',
|
1419 |
+
'mail2hebe.com',
|
1420 |
+
'mail2hecate.com',
|
1421 |
+
'mail2heidi.com',
|
1422 |
+
'mail2helen.com',
|
1423 |
+
'mail2hell.com',
|
1424 |
+
'mail2help.com',
|
1425 |
+
'mail2helpdesk.com',
|
1426 |
+
'mail2henry.com',
|
1427 |
+
'mail2hephaestus.com',
|
1428 |
+
'mail2hera.com',
|
1429 |
+
'mail2hercules.com',
|
1430 |
+
'mail2herman.com',
|
1431 |
+
'mail2hermes.com',
|
1432 |
+
'mail2hespera.com',
|
1433 |
+
'mail2hestia.com',
|
1434 |
+
'mail2highschool.com',
|
1435 |
+
'mail2hindu.com',
|
1436 |
+
'mail2hip.com',
|
1437 |
+
'mail2hiphop.com',
|
1438 |
+
'mail2holland.com',
|
1439 |
+
'mail2holly.com',
|
1440 |
+
'mail2hollywood.com',
|
1441 |
+
'mail2homer.com',
|
1442 |
+
'mail2honduras.com',
|
1443 |
+
'mail2honey.com',
|
1444 |
+
'mail2hongkong.com',
|
1445 |
+
'mail2hope.com',
|
1446 |
+
'mail2horse.com',
|
1447 |
+
'mail2hot.com',
|
1448 |
+
'mail2hotel.com',
|
1449 |
+
'mail2houston.com',
|
1450 |
+
'mail2howard.com',
|
1451 |
+
'mail2hugh.com',
|
1452 |
+
'mail2human.com',
|
1453 |
+
'mail2hungary.com',
|
1454 |
+
'mail2hungry.com',
|
1455 |
+
'mail2hygeia.com',
|
1456 |
+
'mail2hyperspace.com',
|
1457 |
+
'mail2hypnos.com',
|
1458 |
+
'mail2ian.com',
|
1459 |
+
'mail2ice-cream.com',
|
1460 |
+
'mail2iceland.com',
|
1461 |
+
'mail2idaho.com',
|
1462 |
+
'mail2idontknow.com',
|
1463 |
+
'mail2illinois.com',
|
1464 |
+
'mail2imam.com',
|
1465 |
+
'mail2in.com',
|
1466 |
+
'mail2india.com',
|
1467 |
+
'mail2indian.com',
|
1468 |
+
'mail2indiana.com',
|
1469 |
+
'mail2indonesia.com',
|
1470 |
+
'mail2infinity.com',
|
1471 |
+
'mail2intense.com',
|
1472 |
+
'mail2iowa.com',
|
1473 |
+
'mail2iran.com',
|
1474 |
+
'mail2iraq.com',
|
1475 |
+
'mail2ireland.com',
|
1476 |
+
'mail2irene.com',
|
1477 |
+
'mail2iris.com',
|
1478 |
+
'mail2irresistible.com',
|
1479 |
+
'mail2irving.com',
|
1480 |
+
'mail2irwin.com',
|
1481 |
+
'mail2isaac.com',
|
1482 |
+
'mail2israel.com',
|
1483 |
+
'mail2italian.com',
|
1484 |
+
'mail2italy.com',
|
1485 |
+
'mail2jackie.com',
|
1486 |
+
'mail2jacob.com',
|
1487 |
+
'mail2jail.com',
|
1488 |
+
'mail2jaime.com',
|
1489 |
+
'mail2jake.com',
|
1490 |
+
'mail2jamaica.com',
|
1491 |
+
'mail2james.com',
|
1492 |
+
'mail2jamie.com',
|
1493 |
+
'mail2jan.com',
|
1494 |
+
'mail2jane.com',
|
1495 |
+
'mail2janet.com',
|
1496 |
+
'mail2janice.com',
|
1497 |
+
'mail2japan.com',
|
1498 |
+
'mail2japanese.com',
|
1499 |
+
'mail2jasmine.com',
|
1500 |
+
'mail2jason.com',
|
1501 |
+
'mail2java.com',
|
1502 |
+
'mail2jay.com',
|
1503 |
+
'mail2jazz.com',
|
1504 |
+
'mail2jed.com',
|
1505 |
+
'mail2jeffrey.com',
|
1506 |
+
'mail2jennifer.com',
|
1507 |
+
'mail2jenny.com',
|
1508 |
+
'mail2jeremy.com',
|
1509 |
+
'mail2jerry.com',
|
1510 |
+
'mail2jessica.com',
|
1511 |
+
'mail2jessie.com',
|
1512 |
+
'mail2jesus.com',
|
1513 |
+
'mail2jew.com',
|
1514 |
+
'mail2jeweler.com',
|
1515 |
+
'mail2jim.com',
|
1516 |
+
'mail2jimmy.com',
|
1517 |
+
'mail2joan.com',
|
1518 |
+
'mail2joann.com',
|
1519 |
+
'mail2joanna.com',
|
1520 |
+
'mail2jody.com',
|
1521 |
+
'mail2joe.com',
|
1522 |
+
'mail2joel.com',
|
1523 |
+
'mail2joey.com',
|
1524 |
+
'mail2john.com',
|
1525 |
+
'mail2join.com',
|
1526 |
+
'mail2jon.com',
|
1527 |
+
'mail2jonathan.com',
|
1528 |
+
'mail2jones.com',
|
1529 |
+
'mail2jordan.com',
|
1530 |
+
'mail2joseph.com',
|
1531 |
+
'mail2josh.com',
|
1532 |
+
'mail2joy.com',
|
1533 |
+
'mail2juan.com',
|
1534 |
+
'mail2judge.com',
|
1535 |
+
'mail2judy.com',
|
1536 |
+
'mail2juggler.com',
|
1537 |
+
'mail2julian.com',
|
1538 |
+
'mail2julie.com',
|
1539 |
+
'mail2jumbo.com',
|
1540 |
+
'mail2junk.com',
|
1541 |
+
'mail2justin.com',
|
1542 |
+
'mail2justme.com',
|
1543 |
+
'mail2kansas.com',
|
1544 |
+
'mail2karate.com',
|
1545 |
+
'mail2karen.com',
|
1546 |
+
'mail2karl.com',
|
1547 |
+
'mail2karma.com',
|
1548 |
+
'mail2kathleen.com',
|
1549 |
+
'mail2kathy.com',
|
1550 |
+
'mail2katie.com',
|
1551 |
+
'mail2kay.com',
|
1552 |
+
'mail2kazakhstan.com',
|
1553 |
+
'mail2keen.com',
|
1554 |
+
'mail2keith.com',
|
1555 |
+
'mail2kelly.com',
|
1556 |
+
'mail2kelsey.com',
|
1557 |
+
'mail2ken.com',
|
1558 |
+
'mail2kendall.com',
|
1559 |
+
'mail2kennedy.com',
|
1560 |
+
'mail2kenneth.com',
|
1561 |
+
'mail2kenny.com',
|
1562 |
+
'mail2kentucky.com',
|
1563 |
+
'mail2kenya.com',
|
1564 |
+
'mail2kerry.com',
|
1565 |
+
'mail2kevin.com',
|
1566 |
+
'mail2kim.com',
|
1567 |
+
'mail2kimberly.com',
|
1568 |
+
'mail2king.com',
|
1569 |
+
'mail2kirk.com',
|
1570 |
+
'mail2kiss.com',
|
1571 |
+
'mail2kosher.com',
|
1572 |
+
'mail2kristin.com',
|
1573 |
+
'mail2kurt.com',
|
1574 |
+
'mail2kuwait.com',
|
1575 |
+
'mail2kyle.com',
|
1576 |
+
'mail2kyrgyzstan.com',
|
1577 |
+
'mail2la.com',
|
1578 |
+
'mail2lacrosse.com',
|
1579 |
+
'mail2lance.com',
|
1580 |
+
'mail2lao.com',
|
1581 |
+
'mail2larry.com',
|
1582 |
+
'mail2latvia.com',
|
1583 |
+
'mail2laugh.com',
|
1584 |
+
'mail2laura.com',
|
1585 |
+
'mail2lauren.com',
|
1586 |
+
'mail2laurie.com',
|
1587 |
+
'mail2lawrence.com',
|
1588 |
+
'mail2lawyer.com',
|
1589 |
+
'mail2lebanon.com',
|
1590 |
+
'mail2lee.com',
|
1591 |
+
'mail2leo.com',
|
1592 |
+
'mail2leon.com',
|
1593 |
+
'mail2leonard.com',
|
1594 |
+
'mail2leone.com',
|
1595 |
+
'mail2leslie.com',
|
1596 |
+
'mail2letter.com',
|
1597 |
+
'mail2liberia.com',
|
1598 |
+
'mail2libertarian.com',
|
1599 |
+
'mail2libra.com',
|
1600 |
+
'mail2libya.com',
|
1601 |
+
'mail2liechtenstein.com',
|
1602 |
+
'mail2life.com',
|
1603 |
+
'mail2linda.com',
|
1604 |
+
'mail2linux.com',
|
1605 |
+
'mail2lionel.com',
|
1606 |
+
'mail2lipstick.com',
|
1607 |
+
'mail2liquid.com',
|
1608 |
+
'mail2lisa.com',
|
1609 |
+
'mail2lithuania.com',
|
1610 |
+
'mail2litigator.com',
|
1611 |
+
'mail2liz.com',
|
1612 |
+
'mail2lloyd.com',
|
1613 |
+
'mail2lois.com',
|
1614 |
+
'mail2lola.com',
|
1615 |
+
'mail2london.com',
|
1616 |
+
'mail2looking.com',
|
1617 |
+
'mail2lori.com',
|
1618 |
+
'mail2lost.com',
|
1619 |
+
'mail2lou.com',
|
1620 |
+
'mail2louis.com',
|
1621 |
+
'mail2louisiana.com',
|
1622 |
+
'mail2lovable.com',
|
1623 |
+
'mail2love.com',
|
1624 |
+
'mail2lucky.com',
|
1625 |
+
'mail2lucy.com',
|
1626 |
+
'mail2lunch.com',
|
1627 |
+
'mail2lust.com',
|
1628 |
+
'mail2luxembourg.com',
|
1629 |
+
'mail2luxury.com',
|
1630 |
+
'mail2lyle.com',
|
1631 |
+
'mail2lynn.com',
|
1632 |
+
'mail2madagascar.com',
|
1633 |
+
'mail2madison.com',
|
1634 |
+
'mail2madrid.com',
|
1635 |
+
'mail2maggie.com',
|
1636 |
+
'mail2mail4.com',
|
1637 |
+
'mail2maine.com',
|
1638 |
+
'mail2malawi.com',
|
1639 |
+
'mail2malaysia.com',
|
1640 |
+
'mail2maldives.com',
|
1641 |
+
'mail2mali.com',
|
1642 |
+
'mail2malta.com',
|
1643 |
+
'mail2mambo.com',
|
1644 |
+
'mail2man.com',
|
1645 |
+
'mail2mandy.com',
|
1646 |
+
'mail2manhunter.com',
|
1647 |
+
'mail2mankind.com',
|
1648 |
+
'mail2many.com',
|
1649 |
+
'mail2marc.com',
|
1650 |
+
'mail2marcia.com',
|
1651 |
+
'mail2margaret.com',
|
1652 |
+
'mail2margie.com',
|
1653 |
+
'mail2marhaba.com',
|
1654 |
+
'mail2maria.com',
|
1655 |
+
'mail2marilyn.com',
|
1656 |
+
'mail2marines.com',
|
1657 |
+
'mail2mark.com',
|
1658 |
+
'mail2marriage.com',
|
1659 |
+
'mail2married.com',
|
1660 |
+
'mail2marries.com',
|
1661 |
+
'mail2mars.com',
|
1662 |
+
'mail2marsha.com',
|
1663 |
+
'mail2marshallislands.com',
|
1664 |
+
'mail2martha.com',
|
1665 |
+
'mail2martin.com',
|
1666 |
+
'mail2marty.com',
|
1667 |
+
'mail2marvin.com',
|
1668 |
+
'mail2mary.com',
|
1669 |
+
'mail2maryland.com',
|
1670 |
+
'mail2mason.com',
|
1671 |
+
'mail2massachusetts.com',
|
1672 |
+
'mail2matt.com',
|
1673 |
+
'mail2matthew.com',
|
1674 |
+
'mail2maurice.com',
|
1675 |
+
'mail2mauritania.com',
|
1676 |
+
'mail2mauritius.com',
|
1677 |
+
'mail2max.com',
|
1678 |
+
'mail2maxwell.com',
|
1679 |
+
'mail2maybe.com',
|
1680 |
+
'mail2mba.com',
|
1681 |
+
'mail2me4u.com',
|
1682 |
+
'mail2mechanic.com',
|
1683 |
+
'mail2medieval.com',
|
1684 |
+
'mail2megan.com',
|
1685 |
+
'mail2mel.com',
|
1686 |
+
'mail2melanie.com',
|
1687 |
+
'mail2melissa.com',
|
1688 |
+
'mail2melody.com',
|
1689 |
+
'mail2member.com',
|
1690 |
+
'mail2memphis.com',
|
1691 |
+
'mail2methodist.com',
|
1692 |
+
'mail2mexican.com',
|
1693 |
+
'mail2mexico.com',
|
1694 |
+
'mail2mgz.com',
|
1695 |
+
'mail2miami.com',
|
1696 |
+
'mail2michael.com',
|
1697 |
+
'mail2michelle.com',
|
1698 |
+
'mail2michigan.com',
|
1699 |
+
'mail2mike.com',
|
1700 |
+
'mail2milan.com',
|
1701 |
+
'mail2milano.com',
|
1702 |
+
'mail2mildred.com',
|
1703 |
+
'mail2milkyway.com',
|
1704 |
+
'mail2millennium.com',
|
1705 |
+
'mail2millionaire.com',
|
1706 |
+
'mail2milton.com',
|
1707 |
+
'mail2mime.com',
|
1708 |
+
'mail2mindreader.com',
|
1709 |
+
'mail2mini.com',
|
1710 |
+
'mail2minister.com',
|
1711 |
+
'mail2minneapolis.com',
|
1712 |
+
'mail2minnesota.com',
|
1713 |
+
'mail2miracle.com',
|
1714 |
+
'mail2missionary.com',
|
1715 |
+
'mail2mississippi.com',
|
1716 |
+
'mail2missouri.com',
|
1717 |
+
'mail2mitch.com',
|
1718 |
+
'mail2model.com',
|
1719 |
+
'mail2moldova.commail2molly.com',
|
1720 |
+
'mail2mom.com',
|
1721 |
+
'mail2monaco.com',
|
1722 |
+
'mail2money.com',
|
1723 |
+
'mail2mongolia.com',
|
1724 |
+
'mail2monica.com',
|
1725 |
+
'mail2montana.com',
|
1726 |
+
'mail2monty.com',
|
1727 |
+
'mail2moon.com',
|
1728 |
+
'mail2morocco.com',
|
1729 |
+
'mail2morpheus.com',
|
1730 |
+
'mail2mors.com',
|
1731 |
+
'mail2moscow.com',
|
1732 |
+
'mail2moslem.com',
|
1733 |
+
'mail2mouseketeer.com',
|
1734 |
+
'mail2movies.com',
|
1735 |
+
'mail2mozambique.com',
|
1736 |
+
'mail2mp3.com',
|
1737 |
+
'mail2mrright.com',
|
1738 |
+
'mail2msright.com',
|
1739 |
+
'mail2museum.com',
|
1740 |
+
'mail2music.com',
|
1741 |
+
'mail2musician.com',
|
1742 |
+
'mail2muslim.com',
|
1743 |
+
'mail2my.com',
|
1744 |
+
'mail2myboat.com',
|
1745 |
+
'mail2mycar.com',
|
1746 |
+
'mail2mycell.com',
|
1747 |
+
'mail2mygsm.com',
|
1748 |
+
'mail2mylaptop.com',
|
1749 |
+
'mail2mymac.com',
|
1750 |
+
'mail2mypager.com',
|
1751 |
+
'mail2mypalm.com',
|
1752 |
+
'mail2mypc.com',
|
1753 |
+
'mail2myphone.com',
|
1754 |
+
'mail2myplane.com',
|
1755 |
+
'mail2namibia.com',
|
1756 |
+
'mail2nancy.com',
|
1757 |
+
'mail2nasdaq.com',
|
1758 |
+
'mail2nathan.com',
|
1759 |
+
'mail2nauru.com',
|
1760 |
+
'mail2navy.com',
|
1761 |
+
'mail2neal.com',
|
1762 |
+
'mail2nebraska.com',
|
1763 |
+
'mail2ned.com',
|
1764 |
+
'mail2neil.com',
|
1765 |
+
'mail2nelson.com',
|
1766 |
+
'mail2nemesis.com',
|
1767 |
+
'mail2nepal.com',
|
1768 |
+
'mail2netherlands.com',
|
1769 |
+
'mail2network.com',
|
1770 |
+
'mail2nevada.com',
|
1771 |
+
'mail2newhampshire.com',
|
1772 |
+
'mail2newjersey.com',
|
1773 |
+
'mail2newmexico.com',
|
1774 |
+
'mail2newyork.com',
|
1775 |
+
'mail2newzealand.com',
|
1776 |
+
'mail2nicaragua.com',
|
1777 |
+
'mail2nick.com',
|
1778 |
+
'mail2nicole.com',
|
1779 |
+
'mail2niger.com',
|
1780 |
+
'mail2nigeria.com',
|
1781 |
+
'mail2nike.com',
|
1782 |
+
'mail2no.com',
|
1783 |
+
'mail2noah.com',
|
1784 |
+
'mail2noel.com',
|
1785 |
+
'mail2noelle.com',
|
1786 |
+
'mail2normal.com',
|
1787 |
+
'mail2norman.com',
|
1788 |
+
'mail2northamerica.com',
|
1789 |
+
'mail2northcarolina.com',
|
1790 |
+
'mail2northdakota.com',
|
1791 |
+
'mail2northpole.com',
|
1792 |
+
'mail2norway.com',
|
1793 |
+
'mail2notus.com',
|
1794 |
+
'mail2noway.com',
|
1795 |
+
'mail2nowhere.com',
|
1796 |
+
'mail2nuclear.com',
|
1797 |
+
'mail2nun.com',
|
1798 |
+
'mail2ny.com',
|
1799 |
+
'mail2oasis.com',
|
1800 |
+
'mail2oceanographer.com',
|
1801 |
+
'mail2ohio.com',
|
1802 |
+
'mail2ok.com',
|
1803 |
+
'mail2oklahoma.com',
|
1804 |
+
'mail2oliver.com',
|
1805 |
+
'mail2oman.com',
|
1806 |
+
'mail2one.com',
|
1807 |
+
'mail2onfire.com',
|
1808 |
+
'mail2online.com',
|
1809 |
+
'mail2oops.com',
|
1810 |
+
'mail2open.com',
|
1811 |
+
'mail2ophthalmologist.com',
|
1812 |
+
'mail2optometrist.com',
|
1813 |
+
'mail2oregon.com',
|
1814 |
+
'mail2oscars.com',
|
1815 |
+
'mail2oslo.com',
|
1816 |
+
'mail2painter.com',
|
1817 |
+
'mail2pakistan.com',
|
1818 |
+
'mail2palau.com',
|
1819 |
+
'mail2pan.com',
|
1820 |
+
'mail2panama.com',
|
1821 |
+
'mail2paraguay.com',
|
1822 |
+
'mail2paralegal.com',
|
1823 |
+
'mail2paris.com',
|
1824 |
+
'mail2park.com',
|
1825 |
+
'mail2parker.com',
|
1826 |
+
'mail2party.com',
|
1827 |
+
'mail2passion.com',
|
1828 |
+
'mail2pat.com',
|
1829 |
+
'mail2patricia.com',
|
1830 |
+
'mail2patrick.com',
|
1831 |
+
'mail2patty.com',
|
1832 |
+
'mail2paul.com',
|
1833 |
+
'mail2paula.com',
|
1834 |
+
'mail2pay.com',
|
1835 |
+
'mail2peace.com',
|
1836 |
+
'mail2pediatrician.com',
|
1837 |
+
'mail2peggy.com',
|
1838 |
+
'mail2pennsylvania.com',
|
1839 |
+
'mail2perry.com',
|
1840 |
+
'mail2persephone.com',
|
1841 |
+
'mail2persian.com',
|
1842 |
+
'mail2peru.com',
|
1843 |
+
'mail2pete.com',
|
1844 |
+
'mail2peter.com',
|
1845 |
+
'mail2pharmacist.com',
|
1846 |
+
'mail2phil.com',
|
1847 |
+
'mail2philippines.com',
|
1848 |
+
'mail2phoenix.com',
|
1849 |
+
'mail2phonecall.com',
|
1850 |
+
'mail2phyllis.com',
|
1851 |
+
'mail2pickup.com',
|
1852 |
+
'mail2pilot.com',
|
1853 |
+
'mail2pisces.com',
|
1854 |
+
'mail2planet.com',
|
1855 |
+
'mail2platinum.com',
|
1856 |
+
'mail2plato.com',
|
1857 |
+
'mail2pluto.com',
|
1858 |
+
'mail2pm.com',
|
1859 |
+
'mail2podiatrist.com',
|
1860 |
+
'mail2poet.com',
|
1861 |
+
'mail2poland.com',
|
1862 |
+
'mail2policeman.com',
|
1863 |
+
'mail2policewoman.com',
|
1864 |
+
'mail2politician.com',
|
1865 |
+
'mail2pop.com',
|
1866 |
+
'mail2pope.com',
|
1867 |
+
'mail2popular.com',
|
1868 |
+
'mail2portugal.com',
|
1869 |
+
'mail2poseidon.com',
|
1870 |
+
'mail2potatohead.com',
|
1871 |
+
'mail2power.com',
|
1872 |
+
'mail2presbyterian.com',
|
1873 |
+
'mail2president.com',
|
1874 |
+
'mail2priest.com',
|
1875 |
+
'mail2prince.com',
|
1876 |
+
'mail2princess.com',
|
1877 |
+
'mail2producer.com',
|
1878 |
+
'mail2professor.com',
|
1879 |
+
'mail2protect.com',
|
1880 |
+
'mail2psychiatrist.com',
|
1881 |
+
'mail2psycho.com',
|
1882 |
+
'mail2psychologist.com',
|
1883 |
+
'mail2qatar.com',
|
1884 |
+
'mail2queen.com',
|
1885 |
+
'mail2rabbi.com',
|
1886 |
+
'mail2race.com',
|
1887 |
+
'mail2racer.com',
|
1888 |
+
'mail2rachel.com',
|
1889 |
+
'mail2rage.com',
|
1890 |
+
'mail2rainmaker.com',
|
1891 |
+
'mail2ralph.com',
|
1892 |
+
'mail2randy.com',
|
1893 |
+
'mail2rap.com',
|
1894 |
+
'mail2rare.com',
|
1895 |
+
'mail2rave.com',
|
1896 |
+
'mail2ray.com',
|
1897 |
+
'mail2raymond.com',
|
1898 |
+
'mail2realtor.com',
|
1899 |
+
'mail2rebecca.com',
|
1900 |
+
'mail2recruiter.com',
|
1901 |
+
'mail2recycle.com',
|
1902 |
+
'mail2redhead.com',
|
1903 |
+
'mail2reed.com',
|
1904 |
+
'mail2reggie.com',
|
1905 |
+
'mail2register.com',
|
1906 |
+
'mail2rent.com',
|
1907 |
+
'mail2republican.com',
|
1908 |
+
'mail2resort.com',
|
1909 |
+
'mail2rex.com',
|
1910 |
+
'mail2rhodeisland.com',
|
1911 |
+
'mail2rich.com',
|
1912 |
+
'mail2richard.com',
|
1913 |
+
'mail2ricky.com',
|
1914 |
+
'mail2ride.com',
|
1915 |
+
'mail2riley.com',
|
1916 |
+
'mail2rita.com',
|
1917 |
+
'mail2rob.com',
|
1918 |
+
'mail2robert.com',
|
1919 |
+
'mail2roberta.com',
|
1920 |
+
'mail2robin.com',
|
1921 |
+
'mail2rock.com',
|
1922 |
+
'mail2rocker.com',
|
1923 |
+
'mail2rod.com',
|
1924 |
+
'mail2rodney.com',
|
1925 |
+
'mail2romania.com',
|
1926 |
+
'mail2rome.com',
|
1927 |
+
'mail2ron.com',
|
1928 |
+
'mail2ronald.com',
|
1929 |
+
'mail2ronnie.com',
|
1930 |
+
'mail2rose.com',
|
1931 |
+
'mail2rosie.com',
|
1932 |
+
'mail2roy.com',
|
1933 |
+
'mail2rudy.com',
|
1934 |
+
'mail2rugby.com',
|
1935 |
+
'mail2runner.com',
|
1936 |
+
'mail2russell.com',
|
1937 |
+
'mail2russia.com',
|
1938 |
+
'mail2russian.com',
|
1939 |
+
'mail2rusty.com',
|
1940 |
+
'mail2ruth.com',
|
1941 |
+
'mail2rwanda.com',
|
1942 |
+
'mail2ryan.com',
|
1943 |
+
'mail2sa.com',
|
1944 |
+
'mail2sabrina.com',
|
1945 |
+
'mail2safe.com',
|
1946 |
+
'mail2sagittarius.com',
|
1947 |
+
'mail2sail.com',
|
1948 |
+
'mail2sailor.com',
|
1949 |
+
'mail2sal.com',
|
1950 |
+
'mail2salaam.com',
|
1951 |
+
'mail2sam.com',
|
1952 |
+
'mail2samantha.com',
|
1953 |
+
'mail2samoa.com',
|
1954 |
+
'mail2samurai.com',
|
1955 |
+
'mail2sandra.com',
|
1956 |
+
'mail2sandy.com',
|
1957 |
+
'mail2sanfrancisco.com',
|
1958 |
+
'mail2sanmarino.com',
|
1959 |
+
'mail2santa.com',
|
1960 |
+
'mail2sara.com',
|
1961 |
+
'mail2sarah.com',
|
1962 |
+
'mail2sat.com',
|
1963 |
+
'mail2saturn.com',
|
1964 |
+
'mail2saudi.com',
|
1965 |
+
'mail2saudiarabia.com',
|
1966 |
+
'mail2save.com',
|
1967 |
+
'mail2savings.com',
|
1968 |
+
'mail2school.com',
|
1969 |
+
'mail2scientist.com',
|
1970 |
+
'mail2scorpio.com',
|
1971 |
+
'mail2scott.com',
|
1972 |
+
'mail2sean.com',
|
1973 |
+
'mail2search.com',
|
1974 |
+
'mail2seattle.com',
|
1975 |
+
'mail2secretagent.com',
|
1976 |
+
'mail2senate.com',
|
1977 |
+
'mail2senegal.com',
|
1978 |
+
'mail2sensual.com',
|
1979 |
+
'mail2seth.com',
|
1980 |
+
'mail2sevenseas.com',
|
1981 |
+
'mail2sexy.com',
|
1982 |
+
'mail2seychelles.com',
|
1983 |
+
'mail2shane.com',
|
1984 |
+
'mail2sharon.com',
|
1985 |
+
'mail2shawn.com',
|
1986 |
+
'mail2ship.com',
|
1987 |
+
'mail2shirley.com',
|
1988 |
+
'mail2shoot.com',
|
1989 |
+
'mail2shuttle.com',
|
1990 |
+
'mail2sierraleone.com',
|
1991 |
+
'mail2simon.com',
|
1992 |
+
'mail2singapore.com',
|
1993 |
+
'mail2single.com',
|
1994 |
+
'mail2site.com',
|
1995 |
+
'mail2skater.com',
|
1996 |
+
'mail2skier.com',
|
1997 |
+
'mail2sky.com',
|
1998 |
+
'mail2sleek.com',
|
1999 |
+
'mail2slim.com',
|
2000 |
+
'mail2slovakia.com',
|
2001 |
+
'mail2slovenia.com',
|
2002 |
+
'mail2smile.com',
|
2003 |
+
'mail2smith.com',
|
2004 |
+
'mail2smooth.com',
|
2005 |
+
'mail2soccer.com',
|
2006 |
+
'mail2soccerfan.com',
|
2007 |
+
'mail2socialist.com',
|
2008 |
+
'mail2soldier.com',
|
2009 |
+
'mail2somalia.com',
|
2010 |
+
'mail2son.com',
|
2011 |
+
'mail2song.com',
|
2012 |
+
'mail2sos.com',
|
2013 |
+
'mail2sound.com',
|
2014 |
+
'mail2southafrica.com',
|
2015 |
+
'mail2southamerica.com',
|
2016 |
+
'mail2southcarolina.com',
|
2017 |
+
'mail2southdakota.com',
|
2018 |
+
'mail2southkorea.com',
|
2019 |
+
'mail2southpole.com',
|
2020 |
+
'mail2spain.com',
|
2021 |
+
'mail2spanish.com',
|
2022 |
+
'mail2spare.com',
|
2023 |
+
'mail2spectrum.com',
|
2024 |
+
'mail2splash.com',
|
2025 |
+
'mail2sponsor.com',
|
2026 |
+
'mail2sports.com',
|
2027 |
+
'mail2srilanka.com',
|
2028 |
+
'mail2stacy.com',
|
2029 |
+
'mail2stan.com',
|
2030 |
+
'mail2stanley.com',
|
2031 |
+
'mail2star.com',
|
2032 |
+
'mail2state.com',
|
2033 |
+
'mail2stephanie.com',
|
2034 |
+
'mail2steve.com',
|
2035 |
+
'mail2steven.com',
|
2036 |
+
'mail2stewart.com',
|
2037 |
+
'mail2stlouis.com',
|
2038 |
+
'mail2stock.com',
|
2039 |
+
'mail2stockholm.com',
|
2040 |
+
'mail2stockmarket.com',
|
2041 |
+
'mail2storage.com',
|
2042 |
+
'mail2store.com',
|
2043 |
+
'mail2strong.com',
|
2044 |
+
'mail2student.com',
|
2045 |
+
'mail2studio.com',
|
2046 |
+
'mail2studio54.com',
|
2047 |
+
'mail2stuntman.com',
|
2048 |
+
'mail2subscribe.com',
|
2049 |
+
'mail2sudan.com',
|
2050 |
+
'mail2superstar.com',
|
2051 |
+
'mail2surfer.com',
|
2052 |
+
'mail2suriname.com',
|
2053 |
+
'mail2susan.com',
|
2054 |
+
'mail2suzie.com',
|
2055 |
+
'mail2swaziland.com',
|
2056 |
+
'mail2sweden.com',
|
2057 |
+
'mail2sweetheart.com',
|
2058 |
+
'mail2swim.com',
|
2059 |
+
'mail2swimmer.com',
|
2060 |
+
'mail2swiss.com',
|
2061 |
+
'mail2switzerland.com',
|
2062 |
+
'mail2sydney.com',
|
2063 |
+
'mail2sylvia.com',
|
2064 |
+
'mail2syria.com',
|
2065 |
+
'mail2taboo.com',
|
2066 |
+
'mail2taiwan.com',
|
2067 |
+
'mail2tajikistan.com',
|
2068 |
+
'mail2tammy.com',
|
2069 |
+
'mail2tango.com',
|
2070 |
+
'mail2tanya.com',
|
2071 |
+
'mail2tanzania.com',
|
2072 |
+
'mail2tara.com',
|
2073 |
+
'mail2taurus.com',
|
2074 |
+
'mail2taxi.com',
|
2075 |
+
'mail2taxidermist.com',
|
2076 |
+
'mail2taylor.com',
|
2077 |
+
'mail2taz.com',
|
2078 |
+
'mail2teacher.com',
|
2079 |
+
'mail2technician.com',
|
2080 |
+
'mail2ted.com',
|
2081 |
+
'mail2telephone.com',
|
2082 |
+
'mail2teletubbie.com',
|
2083 |
+
'mail2tenderness.com',
|
2084 |
+
'mail2tennessee.com',
|
2085 |
+
'mail2tennis.com',
|
2086 |
+
'mail2tennisfan.com',
|
2087 |
+
'mail2terri.com',
|
2088 |
+
'mail2terry.com',
|
2089 |
+
'mail2test.com',
|
2090 |
+
'mail2texas.com',
|
2091 |
+
'mail2thailand.com',
|
2092 |
+
'mail2therapy.com',
|
2093 |
+
'mail2think.com',
|
2094 |
+
'mail2tickets.com',
|
2095 |
+
'mail2tiffany.com',
|
2096 |
+
'mail2tim.com',
|
2097 |
+
'mail2time.com',
|
2098 |
+
'mail2timothy.com',
|
2099 |
+
'mail2tina.com',
|
2100 |
+
'mail2titanic.com',
|
2101 |
+
'mail2toby.com',
|
2102 |
+
'mail2todd.com',
|
2103 |
+
'mail2togo.com',
|
2104 |
+
'mail2tom.com',
|
2105 |
+
'mail2tommy.com',
|
2106 |
+
'mail2tonga.com',
|
2107 |
+
'mail2tony.com',
|
2108 |
+
'mail2touch.com',
|
2109 |
+
'mail2tourist.com',
|
2110 |
+
'mail2tracey.com',
|
2111 |
+
'mail2tracy.com',
|
2112 |
+
'mail2tramp.com',
|
2113 |
+
'mail2travel.com',
|
2114 |
+
'mail2traveler.com',
|
2115 |
+
'mail2travis.com',
|
2116 |
+
'mail2trekkie.com',
|
2117 |
+
'mail2trex.com',
|
2118 |
+
'mail2triallawyer.com',
|
2119 |
+
'mail2trick.com',
|
2120 |
+
'mail2trillionaire.com',
|
2121 |
+
'mail2troy.com',
|
2122 |
+
'mail2truck.com',
|
2123 |
+
'mail2trump.com',
|
2124 |
+
'mail2try.com',
|
2125 |
+
'mail2tunisia.com',
|
2126 |
+
'mail2turbo.com',
|
2127 |
+
'mail2turkey.com',
|
2128 |
+
'mail2turkmenistan.com',
|
2129 |
+
'mail2tv.com',
|
2130 |
+
'mail2tycoon.com',
|
2131 |
+
'mail2tyler.com',
|
2132 |
+
'mail2u4me.com',
|
2133 |
+
'mail2uae.com',
|
2134 |
+
'mail2uganda.com',
|
2135 |
+
'mail2uk.com',
|
2136 |
+
'mail2ukraine.com',
|
2137 |
+
'mail2uncle.com',
|
2138 |
+
'mail2unsubscribe.com',
|
2139 |
+
'mail2uptown.com',
|
2140 |
+
'mail2uruguay.com',
|
2141 |
+
'mail2usa.com',
|
2142 |
+
'mail2utah.com',
|
2143 |
+
'mail2uzbekistan.com',
|
2144 |
+
'mail2v.com',
|
2145 |
+
'mail2vacation.com',
|
2146 |
+
'mail2valentines.com',
|
2147 |
+
'mail2valerie.com',
|
2148 |
+
'mail2valley.com',
|
2149 |
+
'mail2vamoose.com',
|
2150 |
+
'mail2vanessa.com',
|
2151 |
+
'mail2vanuatu.com',
|
2152 |
+
'mail2venezuela.com',
|
2153 |
+
'mail2venous.com',
|
2154 |
+
'mail2venus.com',
|
2155 |
+
'mail2vermont.com',
|
2156 |
+
'mail2vickie.com',
|
2157 |
+
'mail2victor.com',
|
2158 |
+
'mail2victoria.com',
|
2159 |
+
'mail2vienna.com',
|
2160 |
+
'mail2vietnam.com',
|
2161 |
+
'mail2vince.com',
|
2162 |
+
'mail2virginia.com',
|
2163 |
+
'mail2virgo.com',
|
2164 |
+
'mail2visionary.com',
|
2165 |
+
'mail2vodka.com',
|
2166 |
+
'mail2volleyball.com',
|
2167 |
+
'mail2waiter.com',
|
2168 |
+
'mail2wallstreet.com',
|
2169 |
+
'mail2wally.com',
|
2170 |
+
'mail2walter.com',
|
2171 |
+
'mail2warren.com',
|
2172 |
+
'mail2washington.com',
|
2173 |
+
'mail2wave.com',
|
2174 |
+
'mail2way.com',
|
2175 |
+
'mail2waycool.com',
|
2176 |
+
'mail2wayne.com',
|
2177 |
+
'mail2webmaster.com',
|
2178 |
+
'mail2webtop.com',
|
2179 |
+
'mail2webtv.com',
|
2180 |
+
'mail2weird.com',
|
2181 |
+
'mail2wendell.com',
|
2182 |
+
'mail2wendy.com',
|
2183 |
+
'mail2westend.com',
|
2184 |
+
'mail2westvirginia.com',
|
2185 |
+
'mail2whether.com',
|
2186 |
+
'mail2whip.com',
|
2187 |
+
'mail2white.com',
|
2188 |
+
'mail2whitehouse.com',
|
2189 |
+
'mail2whitney.com',
|
2190 |
+
'mail2why.com',
|
2191 |
+
'mail2wilbur.com',
|
2192 |
+
'mail2wild.com',
|
2193 |
+
'mail2willard.com',
|
2194 |
+
'mail2willie.com',
|
2195 |
+
'mail2wine.com',
|
2196 |
+
'mail2winner.com',
|
2197 |
+
'mail2wired.com',
|
2198 |
+
'mail2wisconsin.com',
|
2199 |
+
'mail2woman.com',
|
2200 |
+
'mail2wonder.com',
|
2201 |
+
'mail2world.com',
|
2202 |
+
'mail2worship.com',
|
2203 |
+
'mail2wow.com',
|
2204 |
+
'mail2www.com',
|
2205 |
+
'mail2wyoming.com',
|
2206 |
+
'mail2xfiles.com',
|
2207 |
+
'mail2xox.com',
|
2208 |
+
'mail2yachtclub.com',
|
2209 |
+
'mail2yahalla.com',
|
2210 |
+
'mail2yemen.com',
|
2211 |
+
'mail2yes.com',
|
2212 |
+
'mail2yugoslavia.com',
|
2213 |
+
'mail2zack.com',
|
2214 |
+
'mail2zambia.com',
|
2215 |
+
'mail2zenith.com',
|
2216 |
+
'mail2zephir.com',
|
2217 |
+
'mail2zeus.com',
|
2218 |
+
'mail2zipper.com',
|
2219 |
+
'mail2zoo.com',
|
2220 |
+
'mail2zoologist.com',
|
2221 |
+
'mail2zurich.com',
|
2222 |
+
'mail3000.com',
|
2223 |
+
'mail333.com',
|
2224 |
+
'mailandftp.com',
|
2225 |
+
'mailandnews.com',
|
2226 |
+
'mailas.com',
|
2227 |
+
'mailasia.com',
|
2228 |
+
'mailbolt.com',
|
2229 |
+
'mailbomb.net',
|
2230 |
+
'mailbox.as',
|
2231 |
+
'mailbox.co.za',
|
2232 |
+
'mailbox.gr',
|
2233 |
+
'mailbox.hu',
|
2234 |
+
'mailbr.com.br',
|
2235 |
+
'mailc.net',
|
2236 |
+
'mailcan.com',
|
2237 |
+
'mailchoose.co',
|
2238 |
+
'mailcity.com',
|
2239 |
+
'mailclub.fr',
|
2240 |
+
'mailclub.net',
|
2241 |
+
'mailexcite.com',
|
2242 |
+
'mailforce.net',
|
2243 |
+
'mailftp.com',
|
2244 |
+
'mailgenie.net',
|
2245 |
+
'mailhaven.com',
|
2246 |
+
'mailhood.com',
|
2247 |
+
'mailingweb.com',
|
2248 |
+
'mailisent.com',
|
2249 |
+
'mailite.com',
|
2250 |
+
'mailme.dk',
|
2251 |
+
'mailmight.com',
|
2252 |
+
'mailmij.nl',
|
2253 |
+
'mailnew.com',
|
2254 |
+
'mailops.com',
|
2255 |
+
'mailoye.com',
|
2256 |
+
'mailpanda.com',
|
2257 |
+
'mailpride.com',
|
2258 |
+
'mailpuppy.com',
|
2259 |
+
'mailroom.com',
|
2260 |
+
'mailru.com',
|
2261 |
+
'mailsent.net',
|
2262 |
+
'mailsurf.com',
|
2263 |
+
'mailup.net',
|
2264 |
+
'maktoob.com',
|
2265 |
+
'malayalamtelevision.net',
|
2266 |
+
'manager.de',
|
2267 |
+
'mantrafreenet.com',
|
2268 |
+
'mantramail.com',
|
2269 |
+
'mantraonline.com',
|
2270 |
+
'marchmail.com',
|
2271 |
+
'marijuana.nl',
|
2272 |
+
'married-not.com',
|
2273 |
+
'marsattack.com',
|
2274 |
+
'masrawy.com',
|
2275 |
+
'mauimail.com',
|
2276 |
+
'maxleft.com',
|
2277 |
+
'mbox.com.au',
|
2278 |
+
'mchsi.com',
|
2279 |
+
'me.com',
|
2280 |
+
'me-mail.hu',
|
2281 |
+
'meetingmall.com',
|
2282 |
+
'megago.com',
|
2283 |
+
'megamail.pt',
|
2284 |
+
'mehrani.com',
|
2285 |
+
'mehtaweb.com',
|
2286 |
+
'melodymail.com',
|
2287 |
+
'meloo.com',
|
2288 |
+
'message.hu',
|
2289 |
+
'metacrawler.com',
|
2290 |
+
'metta.lk',
|
2291 |
+
'miesto.sk',
|
2292 |
+
'mighty.co.za',
|
2293 |
+
'miho-nakayama.com',
|
2294 |
+
'millionaireintraining.com',
|
2295 |
+
'milmail.com',
|
2296 |
+
'misery.net',
|
2297 |
+
'mittalweb.com',
|
2298 |
+
'mixmail.com',
|
2299 |
+
'ml1.net',
|
2300 |
+
'mobilbatam.com',
|
2301 |
+
'mohammed.com',
|
2302 |
+
'moldova.cc',
|
2303 |
+
'moldova.com',
|
2304 |
+
'moldovacc.com',
|
2305 |
+
'montevideo.com.uy',
|
2306 |
+
'moonman.com',
|
2307 |
+
'moose-mail.com',
|
2308 |
+
'mortaza.com',
|
2309 |
+
'mosaicfx.com',
|
2310 |
+
'most-wanted.com',
|
2311 |
+
'mostlysunny.com',
|
2312 |
+
'motormania.com',
|
2313 |
+
'movemail.com',
|
2314 |
+
'mp4.it',
|
2315 |
+
'mr-potatohead.com',
|
2316 |
+
'mscold.com',
|
2317 |
+
'msgbox.com',
|
2318 |
+
'msn.com',
|
2319 |
+
'msn.cn',
|
2320 |
+
'mundomail.net',
|
2321 |
+
'munich.com',
|
2322 |
+
'musician.org',
|
2323 |
+
'musicscene.org',
|
2324 |
+
'mybox.it',
|
2325 |
+
'mycabin.com',
|
2326 |
+
'mycity.com',
|
2327 |
+
'mycool.com',
|
2328 |
+
'mydomain.com',
|
2329 |
+
'mydotcomaddress.com',
|
2330 |
+
'myfamily.com',
|
2331 |
+
'myiris.com',
|
2332 |
+
'mynamedot.com',
|
2333 |
+
'mynetaddress.com',
|
2334 |
+
'myownemail.com',
|
2335 |
+
'myownfriends.com',
|
2336 |
+
'mypersonalemail.com',
|
2337 |
+
'myplace.com',
|
2338 |
+
'myrealbox.com',
|
2339 |
+
'myself.com',
|
2340 |
+
'mystupidjob.com',
|
2341 |
+
'myway.com',
|
2342 |
+
'myworldmail.com',
|
2343 |
+
'n2.com',
|
2344 |
+
'n2business.com',
|
2345 |
+
'n2mail.com',
|
2346 |
+
'n2software.com',
|
2347 |
+
'nabc.biz',
|
2348 |
+
'nagpal.net',
|
2349 |
+
'nakedgreens.com',
|
2350 |
+
'name.com',
|
2351 |
+
'nameplanet.com',
|
2352 |
+
'nandomail.com',
|
2353 |
+
'naseej.com',
|
2354 |
+
'nativestar.net',
|
2355 |
+
'nativeweb.net',
|
2356 |
+
'navigator.lv',
|
2357 |
+
'neeva.net',
|
2358 |
+
'nemra1.com',
|
2359 |
+
'nenter.com',
|
2360 |
+
'nervhq.org',
|
2361 |
+
'net4b.pt',
|
2362 |
+
'net4you.at',
|
2363 |
+
'netbounce.com',
|
2364 |
+
'netbroadcaster.com',
|
2365 |
+
'netcenter-vn.net',
|
2366 |
+
'netcourrier.com',
|
2367 |
+
'netexecutive.com',
|
2368 |
+
'netexpressway.com',
|
2369 |
+
'netian.com',
|
2370 |
+
'netizen.com.ar',
|
2371 |
+
'netlane.com',
|
2372 |
+
'netlimit.com',
|
2373 |
+
'netmongol.com',
|
2374 |
+
'netpiper.com',
|
2375 |
+
'netposta.net',
|
2376 |
+
'netralink.com',
|
2377 |
+
'netscape.net',
|
2378 |
+
'netscapeonline.co.uk',
|
2379 |
+
'netspeedway.com',
|
2380 |
+
'netsquare.com',
|
2381 |
+
'netster.com',
|
2382 |
+
'nettaxi.com',
|
2383 |
+
'netzero.com',
|
2384 |
+
'netzero.net',
|
2385 |
+
'newmail.com',
|
2386 |
+
'newmail.net',
|
2387 |
+
'newmail.ru',
|
2388 |
+
'newyork.com',
|
2389 |
+
'nfmail.com',
|
2390 |
+
'nicegal.com',
|
2391 |
+
'nicholastse.net',
|
2392 |
+
'nicolastse.com',
|
2393 |
+
'nightmail.com',
|
2394 |
+
'nikopage.com',
|
2395 |
+
'nirvanafan.com',
|
2396 |
+
'noavar.com',
|
2397 |
+
'norika-fujiwara.com',
|
2398 |
+
'norikomail.com',
|
2399 |
+
'northgates.net',
|
2400 |
+
'nospammail.net',
|
2401 |
+
'ny.com',
|
2402 |
+
'nyc.com',
|
2403 |
+
'nycmail.com',
|
2404 |
+
'nzoomail.com',
|
2405 |
+
'o-tay.com',
|
2406 |
+
'o2.co.uk',
|
2407 |
+
'oceanfree.net',
|
2408 |
+
'oddpost.com',
|
2409 |
+
'odmail.com',
|
2410 |
+
'oicexchange.com',
|
2411 |
+
'okbank.com',
|
2412 |
+
'okhuman.com',
|
2413 |
+
'okmad.com',
|
2414 |
+
'okmagic.com',
|
2415 |
+
'okname.net',
|
2416 |
+
'okuk.com',
|
2417 |
+
'ole.com',
|
2418 |
+
'olemail.com',
|
2419 |
+
'olympist.net',
|
2420 |
+
'omaninfo.com',
|
2421 |
+
'onebox.com',
|
2422 |
+
'onenet.com.ar',
|
2423 |
+
'onet.pl',
|
2424 |
+
'oninet.pt',
|
2425 |
+
'online.ie',
|
2426 |
+
'onlinewiz.com',
|
2427 |
+
'onmilwaukee.com',
|
2428 |
+
'onobox.com',
|
2429 |
+
'operamail.com',
|
2430 |
+
'optician.com',
|
2431 |
+
'optonline.net',
|
2432 |
+
'orbitel.bg',
|
2433 |
+
'orgmail.net',
|
2434 |
+
'osite.com.br',
|
2435 |
+
'oso.com',
|
2436 |
+
'otakumail.com',
|
2437 |
+
'our-computer.com',
|
2438 |
+
'our-office.com',
|
2439 |
+
'ourbrisbane.com',
|
2440 |
+
'ournet.md',
|
2441 |
+
'outgun.com',
|
2442 |
+
'outlook.com',
|
2443 |
+
'over-the-rainbow.com',
|
2444 |
+
'ownmail.net',
|
2445 |
+
'packersfan.com',
|
2446 |
+
'pakistanoye.com',
|
2447 |
+
'palestinemail.com',
|
2448 |
+
'parkjiyoon.com',
|
2449 |
+
'parrot.com',
|
2450 |
+
'partlycloudy.com',
|
2451 |
+
'partynight.at',
|
2452 |
+
'parvazi.com',
|
2453 |
+
'pcpostal.com',
|
2454 |
+
'pediatrician.com',
|
2455 |
+
'penpen.com',
|
2456 |
+
'peopleweb.com',
|
2457 |
+
'perfectmail.com',
|
2458 |
+
'personal.ro',
|
2459 |
+
'personales.com',
|
2460 |
+
'petml.com',
|
2461 |
+
'pettypool.com',
|
2462 |
+
'pezeshkpour.com',
|
2463 |
+
'phayze.com',
|
2464 |
+
'phreaker.net',
|
2465 |
+
'picusnet.com',
|
2466 |
+
'pigpig.net',
|
2467 |
+
'pinoymail.com',
|
2468 |
+
'piracha.net',
|
2469 |
+
'pisem.net',
|
2470 |
+
'planetaccess.com',
|
2471 |
+
'planetout.com',
|
2472 |
+
'plasa.com',
|
2473 |
+
'playersodds.com',
|
2474 |
+
'playful.com',
|
2475 |
+
'plusmail.com.br',
|
2476 |
+
'pmail.net',
|
2477 |
+
'pobox.hu',
|
2478 |
+
'pobox.sk',
|
2479 |
+
'pochta.ru',
|
2480 |
+
'poczta.fm',
|
2481 |
+
'poetic.com',
|
2482 |
+
'polbox.com',
|
2483 |
+
'policeoffice.com',
|
2484 |
+
'pool-sharks.com',
|
2485 |
+
'poond.com',
|
2486 |
+
'popmail.com',
|
2487 |
+
'popsmail.com',
|
2488 |
+
'popstar.com',
|
2489 |
+
'portugalmail.com',
|
2490 |
+
'portugalmail.pt',
|
2491 |
+
'portugalnet.com',
|
2492 |
+
'positive-thinking.com',
|
2493 |
+
'post.com',
|
2494 |
+
'post.cz',
|
2495 |
+
'post.sk',
|
2496 |
+
'postaccesslite.com',
|
2497 |
+
'postafree.com',
|
2498 |
+
'postaweb.com',
|
2499 |
+
'postinbox.com',
|
2500 |
+
'postino.ch',
|
2501 |
+
'postmaster.co.uk',
|
2502 |
+
'postpro.net',
|
2503 |
+
'powerfan.com',
|
2504 |
+
'praize.com',
|
2505 |
+
'premiumservice.com',
|
2506 |
+
'presidency.com',
|
2507 |
+
'press.co.jp',
|
2508 |
+
'priest.com',
|
2509 |
+
'primposta.com',
|
2510 |
+
'primposta.hu',
|
2511 |
+
'pro.hu',
|
2512 |
+
'progetplus.it',
|
2513 |
+
'programmer.net',
|
2514 |
+
'programozo.hu',
|
2515 |
+
'proinbox.com',
|
2516 |
+
'project2k.com',
|
2517 |
+
'promessage.com',
|
2518 |
+
'prontomail.com',
|
2519 |
+
'psv-supporter.com',
|
2520 |
+
'publicist.com',
|
2521 |
+
'pulp-fiction.com',
|
2522 |
+
'punkass.com',
|
2523 |
+
'qatarmail.com',
|
2524 |
+
'qprfans.com',
|
2525 |
+
'qrio.com',
|
2526 |
+
'quackquack.com',
|
2527 |
+
'qudsmail.com',
|
2528 |
+
'quepasa.com',
|
2529 |
+
'quickwebmail.com',
|
2530 |
+
'r-o-o-t.com',
|
2531 |
+
'raakim.com',
|
2532 |
+
'racingfan.com.au',
|
2533 |
+
'radicalz.com',
|
2534 |
+
'ragingbull.com',
|
2535 |
+
'ranmamail.com',
|
2536 |
+
'rastogi.net',
|
2537 |
+
'rattle-snake.com',
|
2538 |
+
'ravearena.com',
|
2539 |
+
'razormail.com',
|
2540 |
+
'rccgmail.org',
|
2541 |
+
'realemail.net',
|
2542 |
+
'reallyfast.biz',
|
2543 |
+
'rediffmail.com',
|
2544 |
+
'rediffmailpro.com',
|
2545 |
+
'rednecks.com',
|
2546 |
+
'redseven.de',
|
2547 |
+
'redsfans.com',
|
2548 |
+
'registerednurses.com',
|
2549 |
+
'repairman.com',
|
2550 |
+
'reply.hu',
|
2551 |
+
'representative.com',
|
2552 |
+
'rescueteam.com',
|
2553 |
+
'rezai.com',
|
2554 |
+
'rickymail.com',
|
2555 |
+
'rin.ru',
|
2556 |
+
'rn.com',
|
2557 |
+
'rock.com',
|
2558 |
+
'rocketmail.com',
|
2559 |
+
'rodrun.com',
|
2560 |
+
'rogers.com',
|
2561 |
+
'rome.com',
|
2562 |
+
'roughnet.com',
|
2563 |
+
'rubyridge.com',
|
2564 |
+
'runbox.com',
|
2565 |
+
'rushpost.com',
|
2566 |
+
'ruttolibero.com',
|
2567 |
+
's-mail.com',
|
2568 |
+
'sabreshockey.com',
|
2569 |
+
'sacbeemail.com',
|
2570 |
+
'safe-mail.net',
|
2571 |
+
'sailormoon.com',
|
2572 |
+
'saintly.com',
|
2573 |
+
'sale-sale-sale.com',
|
2574 |
+
'salehi.net',
|
2575 |
+
'samerica.com',
|
2576 |
+
'samilan.net',
|
2577 |
+
'sammimail.com',
|
2578 |
+
'sanfranmail.com',
|
2579 |
+
'sanook.com',
|
2580 |
+
'sapo.pt',
|
2581 |
+
'saudia.com',
|
2582 |
+
'sayhi.net',
|
2583 |
+
'sbcglobal.net',
|
2584 |
+
'scandalmail.com',
|
2585 |
+
'schweiz.org',
|
2586 |
+
'sci.fi',
|
2587 |
+
'scientist.com',
|
2588 |
+
'scifianime.com',
|
2589 |
+
'scottishmail.co.uk',
|
2590 |
+
'scubadiving.com',
|
2591 |
+
'searchwales.com',
|
2592 |
+
'sebil.com',
|
2593 |
+
'secret-police.com',
|
2594 |
+
'secretservices.net',
|
2595 |
+
'seductive.com',
|
2596 |
+
'seekstoyboy.com',
|
2597 |
+
'send.hu',
|
2598 |
+
'sendme.cz',
|
2599 |
+
'sent.com',
|
2600 |
+
'serga.com.ar',
|
2601 |
+
'servemymail.com',
|
2602 |
+
'sesmail.com',
|
2603 |
+
'sexmagnet.com',
|
2604 |
+
'seznam.cz',
|
2605 |
+
'shahweb.net',
|
2606 |
+
'shaniastuff.com',
|
2607 |
+
'sharmaweb.com',
|
2608 |
+
'shaw.ca',
|
2609 |
+
'she.com',
|
2610 |
+
'shootmail.com',
|
2611 |
+
'shotgun.hu',
|
2612 |
+
'shuf.com',
|
2613 |
+
'sialkotcity.com',
|
2614 |
+
'sialkotian.com',
|
2615 |
+
'sialkotoye.com',
|
2616 |
+
'sify.com',
|
2617 |
+
'sinamail.com',
|
2618 |
+
'singapore.com',
|
2619 |
+
'singmail.com',
|
2620 |
+
'singnet.com.sg',
|
2621 |
+
'skim.com',
|
2622 |
+
'skizo.hu',
|
2623 |
+
'slamdunkfan.com',
|
2624 |
+
'slingshot.com',
|
2625 |
+
'slo.net',
|
2626 |
+
'slotter.com',
|
2627 |
+
'smapxsmap.net',
|
2628 |
+
'smileyface.comsmithemail.net',
|
2629 |
+
'smoothmail.com',
|
2630 |
+
'snail-mail.net',
|
2631 |
+
'snakemail.com',
|
2632 |
+
'sndt.net',
|
2633 |
+
'sneakemail.com',
|
2634 |
+
'sniper.hu',
|
2635 |
+
'snoopymail.com',
|
2636 |
+
'snowboarding.com',
|
2637 |
+
'snowdonia.net',
|
2638 |
+
'socamail.com',
|
2639 |
+
'sociologist.com',
|
2640 |
+
'softhome.net',
|
2641 |
+
'sol.dk',
|
2642 |
+
'soldier.hu',
|
2643 |
+
'soon.com',
|
2644 |
+
'soulfoodcookbook.com',
|
2645 |
+
'sp.nl',
|
2646 |
+
'space.com',
|
2647 |
+
'spacetowns.com',
|
2648 |
+
'spamex.com',
|
2649 |
+
'spartapiet.com',
|
2650 |
+
'spazmail.com',
|
2651 |
+
'speedpost.net',
|
2652 |
+
'spils.com',
|
2653 |
+
'spinfinder.com',
|
2654 |
+
'sportemail.com',
|
2655 |
+
'spray.no',
|
2656 |
+
'spray.se',
|
2657 |
+
'spymac.com',
|
2658 |
+
'srilankan.net',
|
2659 |
+
'st-davids.net',
|
2660 |
+
'stade.fr',
|
2661 |
+
'stargateradio.com',
|
2662 |
+
'starmail.com',
|
2663 |
+
'starmail.org',
|
2664 |
+
'starmedia.com',
|
2665 |
+
'starplace.com',
|
2666 |
+
'starspath.com',
|
2667 |
+
'start.com.au',
|
2668 |
+
'stopdropandroll.com',
|
2669 |
+
'stribmail.com',
|
2670 |
+
'strompost.com',
|
2671 |
+
'strongguy.com',
|
2672 |
+
'subram.com',
|
2673 |
+
'sudanmail.net',
|
2674 |
+
'suhabi.com',
|
2675 |
+
'suisse.org',
|
2676 |
+
'sunpoint.net',
|
2677 |
+
'sunrise-sunset.com',
|
2678 |
+
'sunsgame.com',
|
2679 |
+
'sunumail.sn',
|
2680 |
+
'superdada.com',
|
2681 |
+
'supereva.it',
|
2682 |
+
'supermail.ru',
|
2683 |
+
'surf3.net',
|
2684 |
+
'surfy.net',
|
2685 |
+
'surimail.com',
|
2686 |
+
'survivormail.com',
|
2687 |
+
'sweb.cz',
|
2688 |
+
'swiftdesk.com',
|
2689 |
+
'swirve.com',
|
2690 |
+
'swissinfo.org',
|
2691 |
+
'swissmail.net',
|
2692 |
+
'switchboardmail.com',
|
2693 |
+
'switzerland.org',
|
2694 |
+
'sx172.com',
|
2695 |
+
'syom.com',
|
2696 |
+
'syriamail.com',
|
2697 |
+
't2mail.com',
|
2698 |
+
'takuyakimura.com',
|
2699 |
+
'talk21.com',
|
2700 |
+
'talkcity.com',
|
2701 |
+
'tamil.com',
|
2702 |
+
'tatanova.com',
|
2703 |
+
'tech4peace.org',
|
2704 |
+
'techemail.com',
|
2705 |
+
'techie.com',
|
2706 |
+
'technisamail.co.za',
|
2707 |
+
'technologist.com',
|
2708 |
+
'teenagedirtbag.com',
|
2709 |
+
'telebot.com',
|
2710 |
+
'teleline.es',
|
2711 |
+
'telinco.net',
|
2712 |
+
'telkom.net',
|
2713 |
+
'telpage.net',
|
2714 |
+
'tenchiclub.com',
|
2715 |
+
'tenderkiss.com',
|
2716 |
+
'terra.cl',
|
2717 |
+
'terra.com',
|
2718 |
+
'terra.com.ar',
|
2719 |
+
'terra.com.br',
|
2720 |
+
'terra.es',
|
2721 |
+
'tfanus.com.er',
|
2722 |
+
'tfz.net',
|
2723 |
+
'thai.com',
|
2724 |
+
'thaimail.com',
|
2725 |
+
'thaimail.net',
|
2726 |
+
'the-african.com',
|
2727 |
+
'the-airforce.com',
|
2728 |
+
'the-aliens.com',
|
2729 |
+
'the-american.com',
|
2730 |
+
'the-animal.com',
|
2731 |
+
'the-army.com',
|
2732 |
+
'the-astronaut.com',
|
2733 |
+
'the-beauty.com',
|
2734 |
+
'the-big-apple.com',
|
2735 |
+
'the-biker.com',
|
2736 |
+
'the-boss.com',
|
2737 |
+
'the-brazilian.com',
|
2738 |
+
'the-canadian.com',
|
2739 |
+
'the-canuck.com',
|
2740 |
+
'the-captain.com',
|
2741 |
+
'the-chinese.com',
|
2742 |
+
'the-country.com',
|
2743 |
+
'the-cowboy.com',
|
2744 |
+
'the-davis-home.com',
|
2745 |
+
'the-dutchman.com',
|
2746 |
+
'the-eagles.com',
|
2747 |
+
'the-englishman.com',
|
2748 |
+
'the-fastest.net',
|
2749 |
+
'the-fool.com',
|
2750 |
+
'the-frenchman.com',
|
2751 |
+
'the-galaxy.net',
|
2752 |
+
'the-genius.com',
|
2753 |
+
'the-gentleman.com',
|
2754 |
+
'the-german.com',
|
2755 |
+
'the-gremlin.com',
|
2756 |
+
'the-hooligan.com',
|
2757 |
+
'the-italian.com',
|
2758 |
+
'the-japanese.com',
|
2759 |
+
'the-lair.com',
|
2760 |
+
'the-madman.com',
|
2761 |
+
'the-mailinglist.com',
|
2762 |
+
'the-marine.com',
|
2763 |
+
'the-master.com',
|
2764 |
+
'the-mexican.com',
|
2765 |
+
'the-ministry.com',
|
2766 |
+
'the-monkey.com',
|
2767 |
+
'the-newsletter.net',
|
2768 |
+
'the-pentagon.com',
|
2769 |
+
'the-police.com',
|
2770 |
+
'the-prayer.com',
|
2771 |
+
'the-professional.com',
|
2772 |
+
'the-quickest.com',
|
2773 |
+
'the-russian.com',
|
2774 |
+
'the-snake.com',
|
2775 |
+
'the-spaceman.com',
|
2776 |
+
'the-stock-market.com',
|
2777 |
+
'the-student.net',
|
2778 |
+
'the-whitehouse.net',
|
2779 |
+
'the-wild-west.com',
|
2780 |
+
'the18th.com',
|
2781 |
+
'thecoolguy.com',
|
2782 |
+
'thecriminals.com',
|
2783 |
+
'thedoghousemail.com',
|
2784 |
+
'theend.hu',
|
2785 |
+
'thegolfcourse.com',
|
2786 |
+
'thegooner.com',
|
2787 |
+
'theheadoffice.com',
|
2788 |
+
'thelanddownunder.com',
|
2789 |
+
'theoffice.net',
|
2790 |
+
'thepokerface.com',
|
2791 |
+
'thepostmaster.net',
|
2792 |
+
'theraces.com',
|
2793 |
+
'theracetrack.com',
|
2794 |
+
'thestreetfighter.com',
|
2795 |
+
'theteebox.com',
|
2796 |
+
'thewatercooler.com',
|
2797 |
+
'thewebpros.co.uk',
|
2798 |
+
'thewizzard.com',
|
2799 |
+
'thewizzkid.com',
|
2800 |
+
'thezhangs.net',
|
2801 |
+
'thirdage.com',
|
2802 |
+
'thundermail.com',
|
2803 |
+
'tidni.com',
|
2804 |
+
'timein.net',
|
2805 |
+
'tiscali.at',
|
2806 |
+
'tiscali.be',
|
2807 |
+
'tiscali.co.uk',
|
2808 |
+
'tiscali.lu',
|
2809 |
+
'tiscali.se',
|
2810 |
+
'tkcity.com',
|
2811 |
+
'topchat.com',
|
2812 |
+
'topgamers.co.uk',
|
2813 |
+
'topletter.com',
|
2814 |
+
'topmail.com.ar',
|
2815 |
+
'topsurf.com',
|
2816 |
+
'torchmail.com',
|
2817 |
+
'townisp.com',
|
2818 |
+
'travel.li',
|
2819 |
+
'trialbytrivia.com',
|
2820 |
+
'trmailbox.com',
|
2821 |
+
'tropicalstorm.com',
|
2822 |
+
'trust-me.com',
|
2823 |
+
'tsamail.co.za',
|
2824 |
+
'ttml.co.in',
|
2825 |
+
'tunisiamail.com',
|
2826 |
+
'turkey.com',
|
2827 |
+
'twinstarsmail.com',
|
2828 |
+
'tx.rr.com',
|
2829 |
+
'tycoonmail.com',
|
2830 |
+
'typemail.com',
|
2831 |
+
'u2club.com',
|
2832 |
+
'uae.ac',
|
2833 |
+
'uaemail.com',
|
2834 |
+
'ubbi.com',
|
2835 |
+
'ubbi.com.br',
|
2836 |
+
'uboot.com',
|
2837 |
+
'uk2k.com',
|
2838 |
+
'uk2net.com',
|
2839 |
+
'uk7.net',
|
2840 |
+
'uk8.net',
|
2841 |
+
'ukbuilder.com',
|
2842 |
+
'ukcool.com',
|
2843 |
+
'ukdreamcast.com',
|
2844 |
+
'ukr.net',
|
2845 |
+
'uku.co.uk',
|
2846 |
+
'ultapulta.com',
|
2847 |
+
'ultrapostman.com',
|
2848 |
+
'ummah.org',
|
2849 |
+
'umpire.com',
|
2850 |
+
'unbounded.com',
|
2851 |
+
'unican.es',
|
2852 |
+
'unihome.com',
|
2853 |
+
'universal.pt',
|
2854 |
+
'uno.ee',
|
2855 |
+
'uno.it',
|
2856 |
+
'unofree.it',
|
2857 |
+
'uol.com.ar',
|
2858 |
+
'uol.com.br',
|
2859 |
+
'uol.com.co',
|
2860 |
+
'uol.com.mx',
|
2861 |
+
'uol.com.ve',
|
2862 |
+
'uole.com',
|
2863 |
+
'uole.com.ve',
|
2864 |
+
'uolmail.com',
|
2865 |
+
'uomail.com',
|
2866 |
+
'ureach.com',
|
2867 |
+
'urgentmail.biz',
|
2868 |
+
'usa.com',
|
2869 |
+
'usanetmail.com',
|
2870 |
+
'uymail.com',
|
2871 |
+
'uyuyuy.com',
|
2872 |
+
'v-sexi.com',
|
2873 |
+
'velnet.co.uk',
|
2874 |
+
'velocall.com',
|
2875 |
+
'verizon.net',
|
2876 |
+
'verizonmail.com',
|
2877 |
+
'veryfast.biz',
|
2878 |
+
'veryspeedy.net',
|
2879 |
+
'violinmakers.co.uk',
|
2880 |
+
'vip.gr',
|
2881 |
+
'vipmail.ru',
|
2882 |
+
'virgilio.it',
|
2883 |
+
'virgin.net',
|
2884 |
+
'virtualmail.com',
|
2885 |
+
'visitmail.com',
|
2886 |
+
'visto.com',
|
2887 |
+
'vivianhsu.net',
|
2888 |
+
'vjtimail.com',
|
2889 |
+
'vnn.vn',
|
2890 |
+
'volcanomail.com',
|
2891 |
+
'vote-democrats.com',
|
2892 |
+
'vote-hillary.com',
|
2893 |
+
'vote-republicans.com',
|
2894 |
+
'wahoye.com',
|
2895 |
+
'wales2000.net',
|
2896 |
+
'wam.co.za',
|
2897 |
+
'wanadoo.es',
|
2898 |
+
'warmmail.com',
|
2899 |
+
'warpmail.net',
|
2900 |
+
'warrior.hu',
|
2901 |
+
'waumail.com',
|
2902 |
+
'wearab.net',
|
2903 |
+
'web-mail.com.ar',
|
2904 |
+
'web-police.com',
|
2905 |
+
'web.de',
|
2906 |
+
'webave.com',
|
2907 |
+
'webcity.ca',
|
2908 |
+
'webdream.com',
|
2909 |
+
'webindia123.com',
|
2910 |
+
'webjump.com',
|
2911 |
+
'webmail.co.yu',
|
2912 |
+
'webmail.co.za',
|
2913 |
+
'webmail.hu',
|
2914 |
+
'webmails.com',
|
2915 |
+
'webprogramming.com',
|
2916 |
+
'webstation.com',
|
2917 |
+
'websurfer.co.za',
|
2918 |
+
'webtopmail.com',
|
2919 |
+
'weedmail.com',
|
2920 |
+
'weekonline.com',
|
2921 |
+
'wehshee.com',
|
2922 |
+
'welsh-lady.com',
|
2923 |
+
'whartontx.com',
|
2924 |
+
'wheelweb.com',
|
2925 |
+
'whipmail.com',
|
2926 |
+
'whoever.com',
|
2927 |
+
'whoopymail.com',
|
2928 |
+
'wildmail.com',
|
2929 |
+
'windstream.com',
|
2930 |
+
'winmail.com.au',
|
2931 |
+
'winning.com',
|
2932 |
+
'witty.com',
|
2933 |
+
'wolf-web.com',
|
2934 |
+
'wombles.com',
|
2935 |
+
'wongfaye.com',
|
2936 |
+
'wooow.it',
|
2937 |
+
'workmail.com',
|
2938 |
+
'worldemail.com',
|
2939 |
+
'wosaddict.com',
|
2940 |
+
'wouldilie.com',
|
2941 |
+
'wowmail.com',
|
2942 |
+
'wp.pl',
|
2943 |
+
'wrexham.net',
|
2944 |
+
'writeme.com',
|
2945 |
+
'writemeback.com',
|
2946 |
+
'wrongmail.com',
|
2947 |
+
'www.com',
|
2948 |
+
'wx88.net',
|
2949 |
+
'wxs.net',
|
2950 |
+
'x-mail.net',
|
2951 |
+
'x5g.com',
|
2952 |
+
'xmsg.com',
|
2953 |
+
'xoom.com',
|
2954 |
+
'xsmail.com',
|
2955 |
+
'xuno.com',
|
2956 |
+
'xzapmail.com',
|
2957 |
+
'yada-yada.com',
|
2958 |
+
'yaho.com',
|
2959 |
+
'yahoo.ca',
|
2960 |
+
'yahoo.co.in',
|
2961 |
+
'yahoo.co.jp',
|
2962 |
+
'yahoo.co.kr',
|
2963 |
+
'yahoo.co.nz',
|
2964 |
+
'yahoo.co.uk',
|
2965 |
+
'yahoo.com',
|
2966 |
+
'yahoo.com.ar',
|
2967 |
+
'yahoo.com.au',
|
2968 |
+
'yahoo.com.br',
|
2969 |
+
'yahoo.com.cn',
|
2970 |
+
'yahoo.com.hk',
|
2971 |
+
'yahoo.com.is',
|
2972 |
+
'yahoo.com.mx',
|
2973 |
+
'yahoo.com.ru',
|
2974 |
+
'yahoo.com.sg',
|
2975 |
+
'yahoo.de',
|
2976 |
+
'yahoo.dk',
|
2977 |
+
'yahoo.es',
|
2978 |
+
'yahoo.fr',
|
2979 |
+
'yahoo.ie',
|
2980 |
+
'yahoo.it',
|
2981 |
+
'yahoo.jp',
|
2982 |
+
'yahoo.ru',
|
2983 |
+
'yahoo.se',
|
2984 |
+
'yahoofs.com',
|
2985 |
+
'yalla.com',
|
2986 |
+
'yalla.com.lb',
|
2987 |
+
'yalook.com',
|
2988 |
+
'yam.com',
|
2989 |
+
'yandex.ru',
|
2990 |
+
'yapost.com',
|
2991 |
+
'yebox.com',
|
2992 |
+
'yehey.com',
|
2993 |
+
'yemenmail.com',
|
2994 |
+
'yepmail.net',
|
2995 |
+
'yifan.net',
|
2996 |
+
'ymail.com',
|
2997 |
+
'yopolis.com',
|
2998 |
+
'youareadork.com',
|
2999 |
+
'your-house.com',
|
3000 |
+
'yourinbox.com',
|
3001 |
+
'yourlover.net',
|
3002 |
+
'yournightmare.com',
|
3003 |
+
'yours.com',
|
3004 |
+
'yourssincerely.com',
|
3005 |
+
'yourteacher.net',
|
3006 |
+
'yourwap.com',
|
3007 |
+
'yuuhuu.net',
|
3008 |
+
'yyhmail.com',
|
3009 |
+
'zahadum.com',
|
3010 |
+
'zeepost.nl',
|
3011 |
+
'zhaowei.net',
|
3012 |
+
'zip.net',
|
3013 |
+
'zipido.com',
|
3014 |
+
'ziplip.com',
|
3015 |
+
'zipmail.com',
|
3016 |
+
'zipmail.com.br',
|
3017 |
+
'zipmax.com',
|
3018 |
+
'zmail.ru',
|
3019 |
+
'zonnet.nl',
|
3020 |
+
'zubee.com',
|
3021 |
+
'zuvio.com',
|
3022 |
+
'zwallet.com',
|
3023 |
+
'zybermail.com',
|
3024 |
+
'zzn.com',
|
3025 |
+
'zzom.co.uk');
|
power-ups/lookups/admin/lookups-admin.php
ADDED
@@ -0,0 +1,44 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
//=============================================
|
3 |
+
// Include Needed Files
|
4 |
+
//=============================================
|
5 |
+
|
6 |
+
//=============================================
|
7 |
+
// WPLeadInLookupsAdmin Class
|
8 |
+
//=============================================
|
9 |
+
class WPLeadInLookupsAdmin extends WPLeadInAdmin {
|
10 |
+
|
11 |
+
/**
|
12 |
+
* Class constructor
|
13 |
+
*/
|
14 |
+
var $action;
|
15 |
+
|
16 |
+
function __construct ()
|
17 |
+
{
|
18 |
+
//=============================================
|
19 |
+
// Hooks & Filters
|
20 |
+
//=============================================
|
21 |
+
|
22 |
+
|
23 |
+
}
|
24 |
+
|
25 |
+
//=============================================
|
26 |
+
// Settings Page
|
27 |
+
//=============================================
|
28 |
+
|
29 |
+
/**
|
30 |
+
* Creates settings page
|
31 |
+
*/
|
32 |
+
function power_up_setup_callback ()
|
33 |
+
{
|
34 |
+
|
35 |
+
}
|
36 |
+
|
37 |
+
//=============================================
|
38 |
+
// Admin Styles & Scripts
|
39 |
+
//=============================================
|
40 |
+
|
41 |
+
|
42 |
+
}
|
43 |
+
|
44 |
+
?>
|
power-ups/mailchimp-connect.php
CHANGED
@@ -43,6 +43,7 @@ class WPMailChimpConnect extends WPLeadIn {
|
|
43 |
|
44 |
var $admin;
|
45 |
var $options;
|
|
|
46 |
|
47 |
/**
|
48 |
* Class constructor
|
@@ -58,7 +59,7 @@ class WPMailChimpConnect extends WPLeadIn {
|
|
58 |
|
59 |
global $leadin_mailchimp_connect_wp;
|
60 |
$leadin_mailchimp_connect_wp = $this;
|
61 |
-
$this->options = get_option(
|
62 |
}
|
63 |
|
64 |
public function admin_init ( )
|
@@ -111,33 +112,9 @@ class WPMailChimpConnect extends WPLeadIn {
|
|
111 |
)
|
112 |
));
|
113 |
|
114 |
-
|
115 |
-
}
|
116 |
-
|
117 |
-
return FALSE;
|
118 |
-
}
|
119 |
|
120 |
-
|
121 |
-
* Removes an email address from a specific list
|
122 |
-
*
|
123 |
-
* @param string
|
124 |
-
* @param string
|
125 |
-
* @return int/bool API status code OR false if api key not set
|
126 |
-
*/
|
127 |
-
function remove_contact_from_list ( $list_id = '', $email = '' )
|
128 |
-
{
|
129 |
-
if ( isset($this->options['li_mls_api_key']) && $this->options['li_mls_api_key'] && $list_id )
|
130 |
-
{
|
131 |
-
$MailChimp = new LI_MailChimp($this->options['li_mls_api_key']);
|
132 |
-
$contact_removed = $MailChimp->call("lists/unsubscribe ", array(
|
133 |
-
"id" => $list_id,
|
134 |
-
"email" => array('email' => $email),
|
135 |
-
"delete_member" => TRUE,
|
136 |
-
"send_goodbye" => FALSE,
|
137 |
-
"send_notify" => FALSE
|
138 |
-
));
|
139 |
-
|
140 |
-
return $contact_removed;
|
141 |
}
|
142 |
|
143 |
return FALSE;
|
@@ -182,6 +159,8 @@ class WPMailChimpConnect extends WPLeadIn {
|
|
182 |
"batch" => $batch_contacts,
|
183 |
));
|
184 |
|
|
|
|
|
185 |
return $list_updated;
|
186 |
}
|
187 |
|
@@ -190,7 +169,7 @@ class WPMailChimpConnect extends WPLeadIn {
|
|
190 |
}
|
191 |
|
192 |
//=============================================
|
193 |
-
//
|
194 |
//=============================================
|
195 |
|
196 |
global $leadin_mailchimp_connect_wp;
|
43 |
|
44 |
var $admin;
|
45 |
var $options;
|
46 |
+
var $power_option_name = 'leadin_mls_options';
|
47 |
|
48 |
/**
|
49 |
* Class constructor
|
59 |
|
60 |
global $leadin_mailchimp_connect_wp;
|
61 |
$leadin_mailchimp_connect_wp = $this;
|
62 |
+
$this->options = get_option($this->power_option_name);
|
63 |
}
|
64 |
|
65 |
public function admin_init ( )
|
112 |
)
|
113 |
));
|
114 |
|
115 |
+
leadin_track_plugin_activity('Contact Pushed to List', array('esp_connector' => 'mailchimp'));
|
|
|
|
|
|
|
|
|
116 |
|
117 |
+
return $contact_synced;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
118 |
}
|
119 |
|
120 |
return FALSE;
|
159 |
"batch" => $batch_contacts,
|
160 |
));
|
161 |
|
162 |
+
leadin_track_plugin_activity('Bulk Contacts Pushed to List', array('esp_connector' => 'mailchimp'));
|
163 |
+
|
164 |
return $list_updated;
|
165 |
}
|
166 |
|
169 |
}
|
170 |
|
171 |
//=============================================
|
172 |
+
// ESP Connect Init
|
173 |
//=============================================
|
174 |
|
175 |
global $leadin_mailchimp_connect_wp;
|
power-ups/mailchimp-connect/admin/mailchimp-connect-admin.php
CHANGED
@@ -5,6 +5,7 @@
|
|
5 |
class WPMailChimpConnectAdmin extends WPLeadInAdmin {
|
6 |
|
7 |
var $power_up_settings_section = 'leadin_mls_options_section';
|
|
|
8 |
var $power_up_icon;
|
9 |
var $options;
|
10 |
var $authed = FALSE;
|
@@ -22,8 +23,8 @@ class WPMailChimpConnectAdmin extends WPLeadInAdmin {
|
|
22 |
if ( is_admin() )
|
23 |
{
|
24 |
$this->power_up_icon = $power_up_icon_small;
|
25 |
-
add_action('admin_init', array($this, '
|
26 |
-
$this->options = get_option(
|
27 |
$this->authed = ( isset($this->options['li_mls_api_key']) && $this->options['li_mls_api_key'] ? TRUE : FALSE );
|
28 |
|
29 |
if ( $this->authed )
|
@@ -38,9 +39,9 @@ class WPMailChimpConnectAdmin extends WPLeadInAdmin {
|
|
38 |
/**
|
39 |
* Creates settings options
|
40 |
*/
|
41 |
-
function
|
42 |
{
|
43 |
-
register_setting('leadin_settings_options',
|
44 |
add_settings_section($this->power_up_settings_section, $this->power_up_icon . "MailChimp", '', LEADIN_ADMIN_PATH);
|
45 |
add_settings_field('li_mls_api_key', 'API key', array($this, 'li_mls_api_key_callback'), LEADIN_ADMIN_PATH, $this->power_up_settings_section);
|
46 |
|
@@ -63,9 +64,6 @@ class WPMailChimpConnectAdmin extends WPLeadInAdmin {
|
|
63 |
if( isset( $input['li_mls_api_key'] ) )
|
64 |
$new_input['li_mls_api_key'] = sanitize_text_field( $input['li_mls_api_key'] );
|
65 |
|
66 |
-
if( isset( $input['li_mls_subscribers_to_list'] ) )
|
67 |
-
$new_input['li_mls_subscribers_to_list'] = sanitize_text_field( $input['li_mls_subscribers_to_list'] );
|
68 |
-
|
69 |
return $new_input;
|
70 |
}
|
71 |
|
@@ -77,12 +75,12 @@ class WPMailChimpConnectAdmin extends WPLeadInAdmin {
|
|
77 |
$li_mls_api_key = ( $this->options['li_mls_api_key'] ? $this->options['li_mls_api_key'] : '' ); // Get header from options, or show default
|
78 |
|
79 |
printf(
|
80 |
-
'<input id="li_mls_api_key" type="text" id="title" name="
|
81 |
$li_mls_api_key
|
82 |
);
|
83 |
|
84 |
if ( ! isset($li_mls_api_key) || ! $li_mls_api_key )
|
85 |
-
echo '<p><a href="http://admin.mailchimp.com/account/api/" target="_blank">
|
86 |
}
|
87 |
|
88 |
/**
|
@@ -109,7 +107,7 @@ class WPMailChimpConnectAdmin extends WPLeadInAdmin {
|
|
109 |
echo '<td class="synced-list-cell"><span class="icon-tag"></span> ' . $synced_list->tag_text . '</td>';
|
110 |
echo '<td class="synced-list-cell"><span class="synced-list-arrow">→</span></td>';
|
111 |
echo '<td class="synced-list-cell"><span class="icon-envelope"></span> ' . $tag_synced_list['list_name'] . '</td>';
|
112 |
-
echo '<td class="synced-list-edit"><a href="' . get_bloginfo('wpurl') . '/wp-admin/admin.php?page=
|
113 |
echo '</tr>';
|
114 |
|
115 |
$synced_list_count++;
|
@@ -141,42 +139,6 @@ class WPMailChimpConnectAdmin extends WPLeadInAdmin {
|
|
141 |
return $synced_lists;
|
142 |
}
|
143 |
|
144 |
-
/**
|
145 |
-
* Prints email input for settings page
|
146 |
-
*/
|
147 |
-
function li_mls_subscribers_to_list_callback ()
|
148 |
-
{
|
149 |
-
$li_mls_subscribers_to_list = ( isset($this->options['li_mls_subscribers_to_list']) ? $this->options['li_mls_subscribers_to_list'] : '' );
|
150 |
-
|
151 |
-
$lists = $this->li_mls_get_mailchimp_lists($this->options['li_mls_api_key']);
|
152 |
-
|
153 |
-
echo '<select id="li_mls_subscribers_to_list" name="leadin_mls_options[li_mls_subscribers_to_list]" ' . ( ! count($lists['data']) ? 'disabled' : '' ) . '>';
|
154 |
-
|
155 |
-
if ( count($lists['data']) )
|
156 |
-
{
|
157 |
-
$list_set = FALSE;
|
158 |
-
|
159 |
-
foreach ( $lists['data'] as $list )
|
160 |
-
{
|
161 |
-
if ( $list['id'] == $li_mls_subscribers_to_list && !$list_set )
|
162 |
-
$list_set = TRUE;
|
163 |
-
|
164 |
-
echo '<option ' . ( $list['id'] == $li_mls_subscribers_to_list ? 'selected' : '' ) . ' value="' . $list['id'] . '">' . $list['name'] . '</option>';
|
165 |
-
}
|
166 |
-
|
167 |
-
if ( !$list_set )
|
168 |
-
echo '<option selected value="">No list set...</option>';
|
169 |
-
}
|
170 |
-
else
|
171 |
-
{
|
172 |
-
echo '<option value="No lists...">No lists...</option>';
|
173 |
-
}
|
174 |
-
|
175 |
-
echo '</select>';
|
176 |
-
|
177 |
-
echo '<p><a href="http://admin.mailchimp.com/lists/new-list/" target="_blank">Create a new list on MailChimp.com</a></p>';
|
178 |
-
}
|
179 |
-
|
180 |
/**
|
181 |
* Format API-returned lists into parseable format on front end
|
182 |
*
|
@@ -184,7 +146,7 @@ class WPMailChimpConnectAdmin extends WPLeadInAdmin {
|
|
184 |
*/
|
185 |
function li_get_lists ( )
|
186 |
{
|
187 |
-
$lists = $this->
|
188 |
|
189 |
$sanitized_lists = array();
|
190 |
if ( count($lists['data']) )
|
@@ -208,7 +170,7 @@ class WPMailChimpConnectAdmin extends WPLeadInAdmin {
|
|
208 |
* @param string
|
209 |
* @return array
|
210 |
*/
|
211 |
-
function
|
212 |
{
|
213 |
$MailChimp = new LI_MailChimp($api_key);
|
214 |
|
@@ -237,7 +199,12 @@ class WPMailChimpConnectAdmin extends WPLeadInAdmin {
|
|
237 |
if ( $user_profile )
|
238 |
$invalid_key = FALSE;
|
239 |
else
|
|
|
|
|
|
|
|
|
240 |
$invalid_key = TRUE;
|
|
|
241 |
|
242 |
return $invalid_key;
|
243 |
}
|
5 |
class WPMailChimpConnectAdmin extends WPLeadInAdmin {
|
6 |
|
7 |
var $power_up_settings_section = 'leadin_mls_options_section';
|
8 |
+
var $power_option_name = 'leadin_mls_options';
|
9 |
var $power_up_icon;
|
10 |
var $options;
|
11 |
var $authed = FALSE;
|
23 |
if ( is_admin() )
|
24 |
{
|
25 |
$this->power_up_icon = $power_up_icon_small;
|
26 |
+
add_action('admin_init', array($this, 'leadin_build_esp_settings_page'));
|
27 |
+
$this->options = get_option($this->power_option_name);
|
28 |
$this->authed = ( isset($this->options['li_mls_api_key']) && $this->options['li_mls_api_key'] ? TRUE : FALSE );
|
29 |
|
30 |
if ( $this->authed )
|
39 |
/**
|
40 |
* Creates settings options
|
41 |
*/
|
42 |
+
function leadin_build_esp_settings_page ()
|
43 |
{
|
44 |
+
register_setting('leadin_settings_options', $this->power_option_name, array($this, 'sanitize'));
|
45 |
add_settings_section($this->power_up_settings_section, $this->power_up_icon . "MailChimp", '', LEADIN_ADMIN_PATH);
|
46 |
add_settings_field('li_mls_api_key', 'API key', array($this, 'li_mls_api_key_callback'), LEADIN_ADMIN_PATH, $this->power_up_settings_section);
|
47 |
|
64 |
if( isset( $input['li_mls_api_key'] ) )
|
65 |
$new_input['li_mls_api_key'] = sanitize_text_field( $input['li_mls_api_key'] );
|
66 |
|
|
|
|
|
|
|
67 |
return $new_input;
|
68 |
}
|
69 |
|
75 |
$li_mls_api_key = ( $this->options['li_mls_api_key'] ? $this->options['li_mls_api_key'] : '' ); // Get header from options, or show default
|
76 |
|
77 |
printf(
|
78 |
+
'<input id="li_mls_api_key" type="text" id="title" name="' . $this->power_option_name . '[li_mls_api_key]" value="%s" style="width: 430px;"/>',
|
79 |
$li_mls_api_key
|
80 |
);
|
81 |
|
82 |
if ( ! isset($li_mls_api_key) || ! $li_mls_api_key )
|
83 |
+
echo '<p><a target="_blank" href="http://kb.mailchimp.com/accounts/management/about-api-keys#Find-or-Generate-Your-API-Key">Get your API key</a> from <a href="http://admin.mailchimp.com/account/api/" target="_blank">MailChimp.com</a></p>';
|
84 |
}
|
85 |
|
86 |
/**
|
107 |
echo '<td class="synced-list-cell"><span class="icon-tag"></span> ' . $synced_list->tag_text . '</td>';
|
108 |
echo '<td class="synced-list-cell"><span class="synced-list-arrow">→</span></td>';
|
109 |
echo '<td class="synced-list-cell"><span class="icon-envelope"></span> ' . $tag_synced_list['list_name'] . '</td>';
|
110 |
+
echo '<td class="synced-list-edit"><a href="' . get_bloginfo('wpurl') . '/wp-admin/admin.php?page=leadin_tags&action=edit_tag&tag=' . $synced_list->tag_id . '">edit tag</a></td>';
|
111 |
echo '</tr>';
|
112 |
|
113 |
$synced_list_count++;
|
139 |
return $synced_lists;
|
140 |
}
|
141 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
142 |
/**
|
143 |
* Format API-returned lists into parseable format on front end
|
144 |
*
|
146 |
*/
|
147 |
function li_get_lists ( )
|
148 |
{
|
149 |
+
$lists = $this->li_get_api_lists($this->options['li_mls_api_key']);
|
150 |
|
151 |
$sanitized_lists = array();
|
152 |
if ( count($lists['data']) )
|
170 |
* @param string
|
171 |
* @return array
|
172 |
*/
|
173 |
+
function li_get_api_lists ( $api_key )
|
174 |
{
|
175 |
$MailChimp = new LI_MailChimp($api_key);
|
176 |
|
199 |
if ( $user_profile )
|
200 |
$invalid_key = FALSE;
|
201 |
else
|
202 |
+
{
|
203 |
+
unset($this->options['li_mc_api_key']);
|
204 |
+
update_option($this->power_option_name, $this->options);
|
205 |
+
|
206 |
$invalid_key = TRUE;
|
207 |
+
}
|
208 |
|
209 |
return $invalid_key;
|
210 |
}
|
power-ups/subscribe-widget.php
CHANGED
@@ -177,8 +177,6 @@ class WPLeadInSubscribe extends WPLeadIn {
|
|
177 |
if ( $_SERVER["REQUEST_URI"] == '/' && ! isset ($options['li_subscribe_template_home']) )
|
178 |
return FALSE;
|
179 |
}
|
180 |
-
|
181 |
-
|
182 |
|
183 |
if ( ! is_admin() && $pagenow != 'wp-login.php' )
|
184 |
{
|
@@ -187,15 +185,6 @@ class WPLeadInSubscribe extends WPLeadIn {
|
|
187 |
|
188 |
wp_register_style('leadin-subscribe-css', LEADIN_PATH . '/assets/css/build/leadin-subscribe.css');
|
189 |
wp_enqueue_style('leadin-subscribe-css');
|
190 |
-
|
191 |
-
if ( isset($li_options['premium']) )
|
192 |
-
{
|
193 |
-
if ( $li_options['premium'] )
|
194 |
-
{
|
195 |
-
wp_register_style('leadin-subscribe-premium-css', LEADIN_PATH . '/assets/css/build/leadin-subscribe-premium.css');
|
196 |
-
wp_enqueue_style('leadin-subscribe-premium-css');
|
197 |
-
}
|
198 |
-
}
|
199 |
}
|
200 |
}
|
201 |
}
|
177 |
if ( $_SERVER["REQUEST_URI"] == '/' && ! isset ($options['li_subscribe_template_home']) )
|
178 |
return FALSE;
|
179 |
}
|
|
|
|
|
180 |
|
181 |
if ( ! is_admin() && $pagenow != 'wp-login.php' )
|
182 |
{
|
185 |
|
186 |
wp_register_style('leadin-subscribe-css', LEADIN_PATH . '/assets/css/build/leadin-subscribe.css');
|
187 |
wp_enqueue_style('leadin-subscribe-css');
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
188 |
}
|
189 |
}
|
190 |
}
|
power-ups/subscribe-widget/admin/subscribe-widget-admin.php
CHANGED
@@ -297,13 +297,13 @@ class WPLeadInSubscribeAdmin extends WPLeadInAdmin {
|
|
297 |
$options = $this->options;
|
298 |
|
299 |
$preview_link = get_bloginfo('wpurl') . '?preview-subscribe=1';
|
300 |
-
$preview_link .= '&lis_heading=' . ( $options['li_subscribe_heading'] ? $options['li_subscribe_heading'] : 'Sign up for email updates' );
|
301 |
-
$preview_link .= '&lis_desc=' . ( $options['li_subscribe_text'] ? $options['li_subscribe_text'] : '' );
|
302 |
$preview_link .= '&lis_show_names=' . ( isset($options['li_subscribe_name_fields']) ? $options['li_subscribe_name_fields'] : 0 );
|
303 |
$preview_link .= '&lis_show_phone=' . ( isset($options['li_subscribe_phone_field']) ? $options['li_subscribe_phone_field'] : 0 );
|
304 |
-
$preview_link .= '&lis_btn_label=' . ( $options['li_subscribe_btn_label'] ? $options['li_subscribe_btn_label'] : 'SUBSCRIBE' );
|
305 |
-
$preview_link .= '&lis_vex_class=' . ( $options['li_subscribe_vex_class'] ? $options['li_subscribe_vex_class'] : 'vex-theme-bottom-right-corner' );
|
306 |
-
$preview_link .= '&lis_confirmation=' . ( $options['li_subscribe_confirmation'] ? $options['li_subscribe_confirmation'] : 1 );
|
307 |
|
308 |
printf(
|
309 |
'<p><a id="preview-popup-link" href="%s" target="_blank" class="button button-secondary">Preview Pop-up Form</a></p>',
|
297 |
$options = $this->options;
|
298 |
|
299 |
$preview_link = get_bloginfo('wpurl') . '?preview-subscribe=1';
|
300 |
+
$preview_link .= '&lis_heading=' . ( isset($options['li_subscribe_heading']) ? $options['li_subscribe_heading'] : 'Sign up for email updates' );
|
301 |
+
$preview_link .= '&lis_desc=' . ( isset($options['li_subscribe_text']) ? $options['li_subscribe_text'] : '' );
|
302 |
$preview_link .= '&lis_show_names=' . ( isset($options['li_subscribe_name_fields']) ? $options['li_subscribe_name_fields'] : 0 );
|
303 |
$preview_link .= '&lis_show_phone=' . ( isset($options['li_subscribe_phone_field']) ? $options['li_subscribe_phone_field'] : 0 );
|
304 |
+
$preview_link .= '&lis_btn_label=' . ( isset($options['li_subscribe_btn_label']) ? $options['li_subscribe_btn_label'] : 'SUBSCRIBE' );
|
305 |
+
$preview_link .= '&lis_vex_class=' . ( isset($options['li_subscribe_vex_class']) ? $options['li_subscribe_vex_class'] : 'vex-theme-bottom-right-corner' );
|
306 |
+
$preview_link .= '&lis_confirmation=' . ( isset($options['li_subscribe_confirmation']) ? $options['li_subscribe_confirmation'] : 1 );
|
307 |
|
308 |
printf(
|
309 |
'<p><a id="preview-popup-link" href="%s" target="_blank" class="button button-secondary">Preview Pop-up Form</a></p>',
|
readme.txt
CHANGED
@@ -2,49 +2,49 @@
|
|
2 |
Contributors: andygcook, nelsonjoyce
|
3 |
Tags: crm, contacts, lead tracking, click tracking, visitor tracking, analytics, marketing automation, inbound marketing, subscription, marketing, lead generation, mailchimp, constant contact, newsletter, popup, popover, email list, email, contacts database, contact form, forms, form widget, popup form
|
4 |
Requires at least: 3.7
|
5 |
-
Tested up to: 4.1
|
6 |
-
Stable tag:
|
7 |
|
8 |
Leadin is an easy-to-use marketing automation and lead tracking plugin for WordPress that helps you better understand your web site visitors.
|
9 |
|
10 |
== Description ==
|
11 |
|
12 |
-
= Get
|
13 |
|
14 |
-
<a href="http://leadin.com" alt="WordPress marketing automation and lead tracking plugin">Leadin</a> is an easy-to-use marketing automation and lead tracking plugin for WordPress that helps you better understand your web site visitors.
|
15 |
|
16 |
-
|
17 |
|
18 |
-
=
|
19 |
-
|
20 |
-
1. When you activate the WordPress plugin, Leadin will track each anonymous visitor to your site with a cookie.
|
21 |
-
2. Leadin automatically identifies and watches each existing form on your site for submissions.
|
22 |
-
3. Once someone fills out any other form on your site, Leadin will identify that person with their email address. and add them to your contact list.
|
23 |
-
4. You'll also receive an email with a link to the new contact record with all of their visit history.
|
24 |
-
|
25 |
-
If you don't enjoy reading about how it works, watch this video from Brian Duffy explaining how he uses Leadin for <a href="http://wpapplied.com/track-visitors-wordpress-leadin-plugin">WPApplied</a>.
|
26 |
|
27 |
-
|
|
|
28 |
|
29 |
-
=
|
|
|
30 |
|
31 |
-
|
32 |
-
|
33 |
-
= Who's using Leadin? =
|
34 |
|
35 |
-
|
|
|
36 |
|
37 |
-
|
38 |
|
|
|
|
|
|
|
|
|
39 |
|
40 |
-
|
41 |
|
42 |
-
|
43 |
|
|
|
44 |
|
45 |
-
= Note: =
|
46 |
|
47 |
-
|
48 |
|
49 |
== Installation ==
|
50 |
|
@@ -52,67 +52,84 @@ Leadin collects usage information about this plugin so that we can better serve
|
|
52 |
2. Activate the plugin through the 'Plugins' menu in WordPress
|
53 |
3. Add an email address under 'Leadin' in your settings panel
|
54 |
|
55 |
-
|
56 |
-
|
57 |
-
= How does Leadin integrate with my forms? =
|
58 |
|
59 |
-
|
|
|
60 |
|
61 |
-
|
62 |
|
63 |
-
|
|
|
|
|
|
|
|
|
|
|
64 |
|
65 |
-
|
66 |
|
67 |
-
|
|
|
68 |
|
69 |
-
|
|
|
|
|
|
|
|
|
70 |
|
71 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
72 |
|
73 |
-
=
|
|
|
|
|
74 |
|
75 |
-
-
|
76 |
-
-
|
77 |
-
-
|
78 |
-
-
|
79 |
-
-
|
80 |
-
- Formidable
|
81 |
-
- Ninja Forms
|
82 |
-
- Contact Form Clean and Simple
|
83 |
-
- HubSpot
|
84 |
-
- Native WordPress comment forms
|
85 |
-
- Most custom forms
|
86 |
|
87 |
-
=
|
|
|
|
|
88 |
|
89 |
-
-
|
90 |
-
-
|
91 |
-
-
|
92 |
-
-
|
93 |
-
-
|
94 |
-
-
|
95 |
-
- Forms contained in an iFrame
|
96 |
|
97 |
-
=
|
|
|
|
|
|
|
|
|
98 |
|
99 |
-
|
|
|
|
|
100 |
|
101 |
-
|
|
|
|
|
102 |
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
4. Segment your contact list based on page views and submissinos.
|
107 |
-
5. Collect more contacts with the pop-up subscribe widget.
|
108 |
-
6. Create custom tagged lists, choose the form triggers to add contacts and sync your contacts to third-party email services
|
109 |
|
110 |
-
|
111 |
|
112 |
-
-
|
113 |
-
- Current version release: 2015-02-18
|
114 |
|
115 |
= 2.2.11 (2015.02.18) =
|
|
|
116 |
= Enhancements =
|
117 |
- Don't show the "You should receive a confirmation email shortly" message in the popup thank you if the confirmation email setting is toggled off
|
118 |
|
@@ -159,6 +176,15 @@ You betcha! Leadin should work just fine on Multisite right out-of-the-box witho
|
|
159 |
- Bug fixes
|
160 |
- Fixed bug with non-tagged contacts being added to tagged lists
|
161 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
162 |
= 2.2.5 (2014.11.20) =
|
163 |
- Bug fixes
|
164 |
- Fixes to bulk action labels
|
@@ -192,7 +218,7 @@ You betcha! Leadin should work just fine on Multisite right out-of-the-box witho
|
|
192 |
- Retooled tag editor to only pull down unique selectors
|
193 |
- Contact list now will go back to the previous page when clicking the back link
|
194 |
- Fixed mysterious bug where popup ignored new visitors
|
195 |
-
- NOW the subscription confirmation stays checked/
|
196 |
|
197 |
= 2.2.1 (2014.10.01) =
|
198 |
= Enhancements =
|
@@ -214,11 +240,11 @@ You betcha! Leadin should work just fine on Multisite right out-of-the-box witho
|
|
214 |
- Added ability to ignore logged in user roles from tracking
|
215 |
- Popup can be previewed on the front end site before saving changes
|
216 |
- MailChimp Connect checks for faulty API keys and prompts the user to enter in one that works on the tag editor page
|
217 |
-
- Email headers for contact
|
218 |
- Added traffic source URL parameters to contact notification emails
|
219 |
|
220 |
- Bug fixes
|
221 |
-
- Leadin now accounts for timezones
|
222 |
- Filters are now persistent when clicking the link back to the contact list from a contact timeline
|
223 |
- cURL dependency no longer prints the raw error to the screen on installation and gracefully disables cURL-dependant features
|
224 |
- Stats page and contact list totals didn't match up - fixed
|
@@ -308,7 +334,7 @@ You betcha! Leadin should work just fine on Multisite right out-of-the-box witho
|
|
308 |
= 0.10.0 (2014.06.03) =
|
309 |
- Bug fixes
|
310 |
- Fixed original referrer in contact timeline
|
311 |
-
- Fixed
|
312 |
- Only run the update check if the version number is different than the saved number
|
313 |
- Remove "fakepath" from file path text in uploaded file input types
|
314 |
|
@@ -333,7 +359,7 @@ You betcha! Leadin should work just fine on Multisite right out-of-the-box witho
|
|
333 |
|
334 |
= 0.9.1 (2014.05.14) =
|
335 |
- Bug fixes
|
336 |
-
- Fixed pop-up location dropdown not
|
337 |
- Hooked subscribe widget into get_footer action instead of loop_end filter
|
338 |
|
339 |
= 0.9.0 (2014.05.12) =
|
@@ -361,7 +387,7 @@ You betcha! Leadin should work just fine on Multisite right out-of-the-box witho
|
|
361 |
- Bug fixes
|
362 |
- Merge duplicate contacts into one record
|
363 |
- Remove url parameters from source links in contact list
|
364 |
-
- Downgrade use of singletons so classes are
|
365 |
|
366 |
= Enhancements =
|
367 |
- Swap out delete statements in favor of binary "deleted" flags to minimize data loss risk
|
@@ -406,7 +432,7 @@ You betcha! Leadin should work just fine on Multisite right out-of-the-box witho
|
|
406 |
|
407 |
= 0.6.2 (2014.04.07) =
|
408 |
- Bug fixes
|
409 |
-
- Fixed activation error for some installs by removing error
|
410 |
- MySQL query optimizations
|
411 |
- Fixed bug with MySQL V5.0+ by adding default NULL values for insert statements on contacts table
|
412 |
- Changed title for returning lead email notifications
|
@@ -455,7 +481,7 @@ You betcha! Leadin should work just fine on Multisite right out-of-the-box witho
|
|
455 |
- Improved contact history styling + interface
|
456 |
- Added visit, pageview and submission stats to the contact view
|
457 |
- Added Live Chat into the Leadin WordPress admin screens
|
458 |
-
- New Leadin icons for
|
459 |
|
460 |
= 0.4.6 (2013.02.11) =
|
461 |
- Bug fixes
|
@@ -463,7 +489,7 @@ You betcha! Leadin should work just fine on Multisite right out-of-the-box witho
|
|
463 |
- Bug fixes to contact type headings
|
464 |
- Bug fix "Select All" export
|
465 |
- Bug fix for CSS "page views" hover triangle breaking to next line
|
466 |
-
- Backwards
|
467 |
- Add Leadin link to admin bar
|
468 |
|
469 |
= Enhancements =
|
@@ -553,4 +579,4 @@ You betcha! Leadin should work just fine on Multisite right out-of-the-box witho
|
|
553 |
- Added social media avatars to emails
|
554 |
|
555 |
= 0.1.0 (2013.11.22) =
|
556 |
-
- Plugin released
|
2 |
Contributors: andygcook, nelsonjoyce
|
3 |
Tags: crm, contacts, lead tracking, click tracking, visitor tracking, analytics, marketing automation, inbound marketing, subscription, marketing, lead generation, mailchimp, constant contact, newsletter, popup, popover, email list, email, contacts database, contact form, forms, form widget, popup form
|
4 |
Requires at least: 3.7
|
5 |
+
Tested up to: 4.1.1
|
6 |
+
Stable tag: 3.1.4
|
7 |
|
8 |
Leadin is an easy-to-use marketing automation and lead tracking plugin for WordPress that helps you better understand your web site visitors.
|
9 |
|
10 |
== Description ==
|
11 |
|
12 |
+
= Get to know your website visitors =
|
13 |
|
14 |
+
<a href="http://leadin.com" alt="WordPress marketing automation and lead tracking plugin" target="_blank">Leadin</a> is an easy-to-use marketing automation and lead tracking plugin for WordPress that helps you better understand your web site visitors.
|
15 |
|
16 |
+
[youtube https://www.youtube.com/watch?v=tcMYv2r3ecg]
|
17 |
|
18 |
+
= Find out who's on your site and what they're doing =
|
19 |
+
When someone visits your site, you want to know more about them. What pages they've visited, when they return, and what social networks they’re on. Leadin gives you the details you need to make your next move.
|
|
|
|
|
|
|
|
|
|
|
|
|
20 |
|
21 |
+
= More context for your conversations =
|
22 |
+
Leadin automatically finds publicly available information about each of your contacts. Details such as location, work history, and company info can give you more context when you reach out.
|
23 |
|
24 |
+
= Convert more visitors to contacts =
|
25 |
+
Use the optional popup form to prevent people from slipping through the cracks. The popup also uses the contact data to intelligently know when to appear.
|
26 |
|
27 |
+
= Keep your contacts in sync with your email tool =
|
28 |
+
Leadin syncs your contacts to an email list of your choice without replacing any forms.
|
|
|
29 |
|
30 |
+
= Find out what content and traffic sources convert the best =
|
31 |
+
Our simple analytics show you what sources of traffic and content are driving the most contacts. No more complicated Google Analytics reports.
|
32 |
|
33 |
+
= How does it work? =
|
34 |
|
35 |
+
1. When you activate the WordPress plugin, Leadin will track each anonymous visitor to your site with a cookie.
|
36 |
+
2. Leadin automatically identifies and watches each existing form on your site for submissions.
|
37 |
+
3. Once someone fills out any other form on your site, Leadin will identify that person with their email address. and add them to your contact list.
|
38 |
+
4. You'll also receive an email with a link to the new contact record with all of their visit history. (check the screenshots sections to see it in action)
|
39 |
|
40 |
+
= Who's using Leadin? =
|
41 |
|
42 |
+
**<a href="http://www.extremeinbound.com/leadin-wordpress-crm-inbound-plugin/" target="_blank">Alan Perlman</a>**: *“I can use Leadin to get a sense of how engaged certain contacts are, and I can learn more about their behavior on my website to better drive the conversation and understand what they’re interested in or looking for.”*
|
43 |
|
44 |
+
**<a href="http://thewpvalet.com/wordpress-lead-tracking/" target="_blank">Adam W. Warner</a>**: *“…the Leadin plugin has been very useful so far in giving us an idea of the actual visitor paths to our contact forms vs. the paths we’ve intended.”*
|
45 |
|
|
|
46 |
|
47 |
+
Having trouble? Check out our <a href="http://support.leadin.com/">help documentation & support</a>
|
48 |
|
49 |
== Installation ==
|
50 |
|
52 |
2. Activate the plugin through the 'Plugins' menu in WordPress
|
53 |
3. Add an email address under 'Leadin' in your settings panel
|
54 |
|
55 |
+
Having trouble? Check out our <a href="http://support.leadin.com/" target="_blank">help documentation & support</a>
|
|
|
|
|
56 |
|
57 |
+
== Frequently Asked Questions ==
|
58 |
+
= <a href="http://support.leadin.com/article/13-frequently-asked-questions" target="_blank">Full FAQ Here</a> =
|
59 |
|
60 |
+
== Screenshots ==
|
61 |
|
62 |
+
1. See the visit history of each contact.
|
63 |
+
2. Get an email notification for every new lead.
|
64 |
+
3. Leadin stats show you where your leads are coming from.
|
65 |
+
4. Segment your contact list based on page views and submissions.
|
66 |
+
5. Collect more contacts with the pop-up subscribe widget.
|
67 |
+
6. Create custom tagged lists, choose the form triggers to add contacts and sync your contacts to third-party email services
|
68 |
|
69 |
+
== Changelog ==
|
70 |
|
71 |
+
- Current version: 3.1.4
|
72 |
+
- Current version release: 2015-03-17
|
73 |
|
74 |
+
= 3.1.4 (2015.03.17) =
|
75 |
+
= Enhancements =
|
76 |
+
- Intercom added to plugin for in-app support
|
77 |
+
- Onboarding improved for non-setup installs
|
78 |
+
- Contact notifications are now sent through email delivery service to improve deliverability
|
79 |
|
80 |
+
- Bug fixes
|
81 |
+
- Namespaced AWeber oauth libraries with LI_ prefix to avoid duplicate class warnings
|
82 |
+
- SVG icon permanently fixed for servers that don't natively support that file type
|
83 |
+
- Check if database options are set for subscribe preview button
|
84 |
+
- Added in check for default leadin_options in case they were deleted and recreate them if they are not there
|
85 |
+
- Add in checks for the contact lookups to account for default object warnings
|
86 |
+
-
|
87 |
|
88 |
+
= 3.1.3 (2015.02.19) =
|
89 |
+
= Enhancements =
|
90 |
+
- Don't show the "You should receive a confirmation email shortly" message in the popup thank you if the confirmation email setting is toggled off
|
91 |
|
92 |
+
- Bug fixes
|
93 |
+
- Fixed SVG icon
|
94 |
+
- Fixed the default object warnings in class-leadin-contact for the enrichment lookups
|
95 |
+
- Tested NinjaPopups and added to readme as unsupported form plugin
|
96 |
+
- "Namespace" AWeber with "LI_" prefix to avoid conflicts
|
|
|
|
|
|
|
|
|
|
|
|
|
97 |
|
98 |
+
= 3.1.2 (2015.01.26) =
|
99 |
+
= Enhancements =
|
100 |
+
- Tested JotForm + added compatibility to the ReadMe file
|
101 |
|
102 |
+
- Bug fixes
|
103 |
+
- Add in support for like_escape for < WordPress 4.0
|
104 |
+
- Add first + last names to bulk MailChimp connector
|
105 |
+
- Remove rogue WPDB prepare in tag list table
|
106 |
+
- Check for existence of ESP connector when pushing to an email list
|
107 |
+
- Bug fix for multisite installs with broken onboarding
|
|
|
108 |
|
109 |
+
= 3.1.1 (2014.01.20) =
|
110 |
+
= Enhancements =
|
111 |
+
- Added ability to toggle Leadin data access by user role
|
112 |
+
- Hide Leadin nav menu item for user roles without access to Leadin data
|
113 |
+
- Discontinued and disabled the beta program
|
114 |
|
115 |
+
- Bug fixes
|
116 |
+
- Fixed broken onboarding in WordPress Multisite after adding a new site to the network
|
117 |
+
- Contact totals in tag editor now link to tagged list
|
118 |
|
119 |
+
= 3.1.0 (2015.1.06) =
|
120 |
+
= Enhancements =
|
121 |
+
- GetResponse, Campaign Monitor and AWeber integrations launched
|
122 |
|
123 |
+
= 3.0.0 (2014.12.10) =
|
124 |
+
= Enhancements =
|
125 |
+
- Jumping to version 3.0.0 to indefinitely override repository version of Leadin
|
|
|
|
|
|
|
126 |
|
127 |
+
= Leadin 2.2.7 - 2.2.11 =
|
128 |
|
129 |
+
*Leadin was split into Leadin and <a href="http://leadin.com/pro-upgrade" target="_blank">Leadin Pro</a> after version 2.2.6 and later merged back together, so versions 2.2.7 - 2.2.11 and 3.0.0 - 3.1.3 share similar updates.*
|
|
|
130 |
|
131 |
= 2.2.11 (2015.02.18) =
|
132 |
+
|
133 |
= Enhancements =
|
134 |
- Don't show the "You should receive a confirmation email shortly" message in the popup thank you if the confirmation email setting is toggled off
|
135 |
|
176 |
- Bug fixes
|
177 |
- Fixed bug with non-tagged contacts being added to tagged lists
|
178 |
|
179 |
+
= 2.2.6 (2014.12.08) =
|
180 |
+
= Enhancements =
|
181 |
+
- Contact Lookup power-up
|
182 |
+
- Added names to contact exports
|
183 |
+
- Added “tagged as” to the email subject lines
|
184 |
+
|
185 |
+
- Bug fixes
|
186 |
+
- Fixed bug where Leadin would add non-tagged emails to ESP lists when it was not supposed to do those contacts
|
187 |
+
|
188 |
= 2.2.5 (2014.11.20) =
|
189 |
- Bug fixes
|
190 |
- Fixes to bulk action labels
|
218 |
- Retooled tag editor to only pull down unique selectors
|
219 |
- Contact list now will go back to the previous page when clicking the back link
|
220 |
- Fixed mysterious bug where popup ignored new visitors
|
221 |
+
- NOW the subscription confirmation stays checked/unchecked on save (Thanks Kate!)
|
222 |
|
223 |
= 2.2.1 (2014.10.01) =
|
224 |
= Enhancements =
|
240 |
- Added ability to ignore logged in user roles from tracking
|
241 |
- Popup can be previewed on the front end site before saving changes
|
242 |
- MailChimp Connect checks for faulty API keys and prompts the user to enter in one that works on the tag editor page
|
243 |
+
- Email headers for contact notificaitons come from the person who filled in the form
|
244 |
- Added traffic source URL parameters to contact notification emails
|
245 |
|
246 |
- Bug fixes
|
247 |
+
- Leadin now accounts for timezones discrepancy on some MySQL databases and offsets to local time
|
248 |
- Filters are now persistent when clicking the link back to the contact list from a contact timeline
|
249 |
- cURL dependency no longer prints the raw error to the screen on installation and gracefully disables cURL-dependant features
|
250 |
- Stats page and contact list totals didn't match up - fixed
|
334 |
= 0.10.0 (2014.06.03) =
|
335 |
- Bug fixes
|
336 |
- Fixed original referrer in contact timeline
|
337 |
+
- Fixed unnecessary queries on contact timeline
|
338 |
- Only run the update check if the version number is different than the saved number
|
339 |
- Remove "fakepath" from file path text in uploaded file input types
|
340 |
|
359 |
|
360 |
= 0.9.1 (2014.05.14) =
|
361 |
- Bug fixes
|
362 |
+
- Fixed pop-up location dropdown not defaulting to saved options value
|
363 |
- Hooked subscribe widget into get_footer action instead of loop_end filter
|
364 |
|
365 |
= 0.9.0 (2014.05.12) =
|
387 |
- Bug fixes
|
388 |
- Merge duplicate contacts into one record
|
389 |
- Remove url parameters from source links in contact list
|
390 |
+
- Downgrade use of singletons so classes are compatible with PHP 5.2
|
391 |
|
392 |
= Enhancements =
|
393 |
- Swap out delete statements in favor of binary "deleted" flags to minimize data loss risk
|
432 |
|
433 |
= 0.6.2 (2014.04.07) =
|
434 |
- Bug fixes
|
435 |
+
- Fixed activation error for some installs by removing error output
|
436 |
- MySQL query optimizations
|
437 |
- Fixed bug with MySQL V5.0+ by adding default NULL values for insert statements on contacts table
|
438 |
- Changed title for returning lead email notifications
|
481 |
- Improved contact history styling + interface
|
482 |
- Added visit, pageview and submission stats to the contact view
|
483 |
- Added Live Chat into the Leadin WordPress admin screens
|
484 |
+
- New Leadin icons for WordPress sidebar and admin nav menu
|
485 |
|
486 |
= 0.4.6 (2013.02.11) =
|
487 |
- Bug fixes
|
489 |
- Bug fixes to contact type headings
|
490 |
- Bug fix "Select All" export
|
491 |
- Bug fix for CSS "page views" hover triangle breaking to next line
|
492 |
+
- Backwards compatibility for < jQuery 1.7.0
|
493 |
- Add Leadin link to admin bar
|
494 |
|
495 |
= Enhancements =
|
579 |
- Added social media avatars to emails
|
580 |
|
581 |
= 0.1.0 (2013.11.22) =
|
582 |
+
- Plugin released
|