Popups – WordPress Popup - Version 1.4.5

Version Description

  • Fixed undefined js error
  • Fixed redeclared class error for Mobile Detect class
  • Several css and text fixes. Pull request by lucpse
  • Added switch ON/OFF button for popups
  • Removed unnedded buttons / action from admin
  • Custom status now show in display rules
Download this release

Release Info

Developer timersys
Plugin Icon 128x128 Popups – WordPress Popup
Version 1.4.5
Comparing to
See all releases

Code changes from version 1.4.4 to 1.4.5

README.txt CHANGED
@@ -3,8 +3,8 @@ Contributors: timersys
3
  Donate link: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=K4T6L69EV9G2Q
4
  Tags: popup,twitter,google+, facebook,Popups, twitter follow, facebook like, google plus,social boost, social splash, postmatic, mailpoet, facebook popup, scroll popups, popups, wordpress popup, wp popups, cf7, gf, gravity forms, contact form 7, ifs, infusion soft, subscribe, login popup, ajax login popups
5
  Requires at least: 3.6
6
- Tested up to: 4.4.1
7
- Stable tag: 1.4.4
8
  Text Domain: popups
9
  License: GPLv2 or later
10
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
@@ -62,8 +62,11 @@ There are multiple display filters that can be combined:
62
  > * Beautiful optin forms for popular mail providers
63
  > * Currently supporting MailChimp, Aweber, Postmatic, Mailpoet, Constant Contact
64
  > * New popup positions such as top/bottoms bars or fullscreen modes
 
 
65
  > * Track impressions and Conversions of social networks and forms like CF7 or Gravity forms
66
  > * Track impressions and Conversions in Google Analytics
 
67
  > * 8 New animations effects
68
  > * Exit Intent technology
69
  > * More trigger methods
@@ -182,6 +185,13 @@ If you have cache be sure to enable AJAX mode in the plugin settings page
182
 
183
  == Changelog ==
184
 
 
 
 
 
 
 
 
185
 
186
  = 1.4.4 =
187
  * Added WpGlobus Support
3
  Donate link: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=K4T6L69EV9G2Q
4
  Tags: popup,twitter,google+, facebook,Popups, twitter follow, facebook like, google plus,social boost, social splash, postmatic, mailpoet, facebook popup, scroll popups, popups, wordpress popup, wp popups, cf7, gf, gravity forms, contact form 7, ifs, infusion soft, subscribe, login popup, ajax login popups
5
  Requires at least: 3.6
6
+ Tested up to: 4.4.2
7
+ Stable tag: 1.4.5
8
  Text Domain: popups
9
  License: GPLv2 or later
10
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
62
  > * Beautiful optin forms for popular mail providers
63
  > * Currently supporting MailChimp, Aweber, Postmatic, Mailpoet, Constant Contact
64
  > * New popup positions such as top/bottoms bars or fullscreen modes
65
+ > * More Display Rules: Show after N(numbers) of pages viewed
66
+ > * More Display Rules: Show/hide if another popup already converted
67
  > * Track impressions and Conversions of social networks and forms like CF7 or Gravity forms
68
  > * Track impressions and Conversions in Google Analytics
69
+ > * Data sampling for heavy traffic sites
70
  > * 8 New animations effects
71
  > * Exit Intent technology
72
  > * More trigger methods
185
 
186
  == Changelog ==
187
 
188
+ = 1.4.5 =
189
+ * Fixed undefined js error
190
+ * Fixed redeclared class error for Mobile Detect class
191
+ * Several css and text fixes. Pull request by lucpse
192
+ * Added switch ON/OFF button for popups
193
+ * Removed unnedded buttons / action from admin
194
+ * Custom status now show in display rules
195
 
196
  = 1.4.4 =
197
  * Added WpGlobus Support
admin/assets/css/admin.css CHANGED
@@ -219,11 +219,11 @@ div#spu-premium li{
219
 
220
  @font-face {
221
  font-family: 'spufont';
222
- src:url('../../../public/assets/fonts/spufont.eot?sze5my');
223
- src:url('../../../public/assets/fonts/spufont.eot?#iefixsze5my') format('embedded-opentype'),
224
- url('../../../public/assets/fonts/spufont.woff?sze5my') format('woff'),
225
- url('../../../public/assets/fonts/spufont.ttf?sze5my') format('truetype'),
226
- url('../../../public/assets/fonts/spufont.svg?sze5my#spufont') format('svg');
227
  font-weight: normal;
228
  font-style: normal;
229
  }
@@ -236,6 +236,7 @@ div#spu-premium li{
236
  font-variant: normal;
237
  text-transform: none;
238
  line-height: 1;
 
239
 
240
  /* Better Font Rendering =========== */
241
  -webkit-font-smoothing: antialiased;
@@ -243,29 +244,37 @@ div#spu-premium li{
243
  }
244
 
245
  .spu-icon-envelope:before {
246
- content: "\f003";
247
  }
248
-
249
  .spu-icon-check:before {
250
- content: "\f00c";
251
  }
252
-
253
  .spu-icon-close:before {
254
- content: "\f00d";
255
  }
256
-
257
  .spu-icon-eye:before {
258
- content: "\f06e";
259
  }
260
-
261
  .spu-icon-gears:before {
262
- content: "\f085";
263
  }
264
  .spu-icon-magic:before {
265
  content: "\f0d0";
266
  }
 
 
 
267
  .spu-icon-angle-down:before {
268
- content: "\f107";
 
 
 
 
 
 
 
 
 
269
  }
270
  .spu-icon-spinner:before {
271
  content: "\f110";
@@ -274,9 +283,6 @@ div#spu-premium li{
274
  -o-animation: spu-rotate 1s infinite linear;
275
  -moz-animation: spu-rotate 1s infinite linear;
276
  }
277
- .spu-icon-info:before {
278
- content: "\ea0c";
279
- }
280
  h3 .spu-icon {
281
  margin-right: 7px;
282
  }
@@ -292,4 +298,23 @@ h3 .spu-icon {
292
  transform: rotate(359deg);
293
  opacity: 1;
294
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
295
  }
219
 
220
  @font-face {
221
  font-family: 'spufont';
222
+ src:url('../../../public/assets/fonts/spufont.eot?xaknv7');
223
+ src:url('../../../public/assets/fonts/spufont.eot?#iefixxaknv7') format('embedded-opentype'),
224
+ url('../../../public/assets/fonts/spufont.woff?xaknv7') format('woff'),
225
+ url('../../../public/assets/fonts/spufont.ttf?xaknv7') format('truetype'),
226
+ url('../../../public/assets/fonts/spufont.svg?xaknv7#spufont') format('svg');
227
  font-weight: normal;
228
  font-style: normal;
229
  }
236
  font-variant: normal;
237
  text-transform: none;
238
  line-height: 1;
239
+ padding-right: 5px;
240
 
241
  /* Better Font Rendering =========== */
242
  -webkit-font-smoothing: antialiased;
244
  }
245
 
246
  .spu-icon-envelope:before {
247
+ content: "\f003";
248
  }
 
249
  .spu-icon-check:before {
250
+ content: "\f00c";
251
  }
 
252
  .spu-icon-close:before {
253
+ content: "\f00d";
254
  }
 
255
  .spu-icon-eye:before {
256
+ content: "\f06e";
257
  }
 
258
  .spu-icon-gears:before {
259
+ content: "\f085";
260
  }
261
  .spu-icon-magic:before {
262
  content: "\f0d0";
263
  }
264
+ .spu-icon-angle-up:before {
265
+ content: "\f106";
266
+ }
267
  .spu-icon-angle-down:before {
268
+ content: "\f107";
269
+ }
270
+ .spu-icon-toggle-off:before {
271
+ content: "\f204";
272
+ }
273
+ .spu-icon-toggle-on:before {
274
+ content: "\f205";
275
+ }
276
+ .spu-icon-info:before {
277
+ content: "\ea0c";
278
  }
279
  .spu-icon-spinner:before {
280
  content: "\f110";
283
  -o-animation: spu-rotate 1s infinite linear;
284
  -moz-animation: spu-rotate 1s infinite linear;
285
  }
 
 
 
286
  h3 .spu-icon {
287
  margin-right: 7px;
288
  }
298
  transform: rotate(359deg);
299
  opacity: 1;
300
  }
301
+ }
302
+ th#spu_switch{
303
+ width: 70px;
304
+ text-align: center;
305
+ }
306
+ td.spu_switch{
307
+ text-align: center;
308
+ }
309
+ .spu_switch a {
310
+ font-size: 2em;
311
+ }
312
+ .spu_switch a i.spu-icon-toggle-off {
313
+ color: #999;
314
+ }
315
+ .spu_switch a i.spu-icon-toggle-on {
316
+ color: forestgreen;
317
+ }
318
+ .post-type-spucpt div#preview-action {
319
+ display: none;
320
  }
admin/class-social-popup-admin.php CHANGED
@@ -120,6 +120,8 @@ class SocialPopup_Admin {
120
  //Columns in cpt
121
  add_filter( 'manage_edit-spucpt_columns' , array( $this, 'set_custom_cpt_columns'), 10, 2 );
122
  add_action( 'manage_spucpt_posts_custom_column' , array( $this, 'custom_columns'), 10, 2 );
 
 
123
 
124
  $this->set_rules_fields();
125
  }
@@ -153,6 +155,7 @@ class SocialPopup_Admin {
153
  if( class_exists('PopupsP') ){
154
  $name .= ' - Premium v'. PopupsP::VERSION;
155
  }
 
156
  $labels = array(
157
  'name' => $name,
158
  'singular_name' => _x( 'Popups', 'post type singular name', 'popups' ),
@@ -208,7 +211,7 @@ class SocialPopup_Admin {
208
  */
209
  public function add_settings_menu() {
210
 
211
- add_submenu_page('edit.php?post_type=spucpt', 'Settings', 'Settings', apply_filters( 'spu/settings_page/roles', 'manage_options'), 'spu_settings', array( $this, 'settings_page' ) );
212
 
213
  }
214
 
@@ -737,11 +740,11 @@ class SocialPopup_Admin {
737
  function get_rules_choices() {
738
  $choices = array(
739
  __("User", 'popups' ) => array(
740
- 'user_type' => __("User role", 'popups' ),
741
- 'logged_user' => __("User is logged", 'popups' ),
742
- 'left_comment' => __("User never left a comment", 'popups' ),
743
- 'search_engine' => __("User came via a search engine", 'popups' ),
744
- 'same_site' => __("User did not arrive via another page on your site", 'popups' ),
745
  ),
746
  __("Post", 'popups' ) => array(
747
  'post' => __("Post", 'popups' ),
@@ -803,13 +806,19 @@ class SocialPopup_Admin {
803
 
804
  /**
805
  * Add custom columns to spu cpt
 
806
  * @param [type] $columns [description]
 
807
  * @since 1.3.3
 
808
  */
809
  public function set_custom_cpt_columns( $columns ){
810
- unset( $columns['date'] );
811
 
 
 
 
812
  $columns['spu_id'] = __( 'ID', 'popups' );
 
813
  return $columns;
814
  }
815
  /**
@@ -826,7 +835,53 @@ class SocialPopup_Admin {
826
  case 'spu_id' :
827
  echo '#spu-'.$post_id;
828
  break;
829
-
 
 
 
 
830
  }
831
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
832
  }
120
  //Columns in cpt
121
  add_filter( 'manage_edit-spucpt_columns' , array( $this, 'set_custom_cpt_columns'), 10, 2 );
122
  add_action( 'manage_spucpt_posts_custom_column' , array( $this, 'custom_columns'), 10, 2 );
123
+ add_action( 'admin_init' , array( $this, 'toggle_on_popup') );
124
+ add_filter( 'post_row_actions' , array( $this, 'modify_title_actions'), 10, 2 );
125
 
126
  $this->set_rules_fields();
127
  }
155
  if( class_exists('PopupsP') ){
156
  $name .= ' - Premium v'. PopupsP::VERSION;
157
  }
158
+ $name = apply_filters( 'spu/display/title', $name );
159
  $labels = array(
160
  'name' => $name,
161
  'singular_name' => _x( 'Popups', 'post type singular name', 'popups' ),
211
  */
212
  public function add_settings_menu() {
213
 
214
+ add_submenu_page('edit.php?post_type=spucpt', __( 'Settings', 'popups' ), __( 'Settings', 'popups' ), apply_filters( 'spu/settings_page/roles', 'manage_options'), 'spu_settings', array( $this, 'settings_page' ) );
215
 
216
  }
217
 
740
  function get_rules_choices() {
741
  $choices = array(
742
  __("User", 'popups' ) => array(
743
+ 'user_type' => __("User role", 'popups' ),
744
+ 'logged_user' => __("User is logged", 'popups' ),
745
+ 'left_comment' => __("User never left a comment", 'popups' ),
746
+ 'search_engine' => __("User came via a search engine", 'popups' ),
747
+ 'same_site' => __("User did not arrive via another page on your site", 'popups' ),
748
  ),
749
  __("Post", 'popups' ) => array(
750
  'post' => __("Post", 'popups' ),
806
 
807
  /**
808
  * Add custom columns to spu cpt
809
+ *
810
  * @param [type] $columns [description]
811
+ *
812
  * @since 1.3.3
813
+ * @return array|int
814
  */
815
  public function set_custom_cpt_columns( $columns ){
 
816
 
817
+ unset( $columns['date'] );
818
+ $spu_switch = array( 'spu_switch' => __( 'On / Off', 'popups' ) );
819
+ $columns = array_slice($columns, 0, 1, true) + $spu_switch + array_slice($columns, 1, count( $columns ) - 1, true) ;
820
  $columns['spu_id'] = __( 'ID', 'popups' );
821
+
822
  return $columns;
823
  }
824
  /**
835
  case 'spu_id' :
836
  echo '#spu-'.$post_id;
837
  break;
838
+ case 'spu_switch' :
839
+ echo '<a href="'. wp_nonce_url( admin_url('edit.php?post_type=spucpt&post='. $post_id . '&spu_action=spu_toggle_on'), 'spu_toggle_on', 'spu_nonce') .'"><i class="spu-icon spu-icon-';
840
+ echo get_post_status( $post_id ) == 'publish' ? 'toggle-on' : 'toggle-off';
841
+ echo '"></i></a>';
842
+ break;
843
  }
844
  }
845
+
846
+ /**
847
+ * Catch the toggle on/off action and change post status
848
+ * Redirect to clear url once is completed
849
+ */
850
+ function toggle_on_popup() {
851
+ //checks
852
+ if ( ! isset( $_GET['spu_action'] ) || $_GET['spu_action'] != 'spu_toggle_on' )
853
+ return;
854
+ if ( !isset( $_GET['spu_nonce'] ) || !wp_verify_nonce($_GET['spu_nonce'], 'spu_toggle_on') )
855
+ return;
856
+ if ( empty( $_GET['post'] ) )
857
+ return;
858
+ $post_id = esc_attr( $_GET['post'] );
859
+ $post_status = get_post_status( $post_id );
860
+
861
+ $post = array(
862
+ 'ID' => $post_id,
863
+ 'post_status' => $post_status != 'publish' ? 'publish' : 'draft'
864
+ );
865
+ wp_update_post( $post );
866
+ wp_safe_redirect( admin_url('edit.php?post_type=spucpt') );
867
+ exit;
868
+ }
869
+
870
+ /**
871
+ * Remove unneeded actions
872
+ *
873
+ * @param $actions
874
+ * @param $post
875
+ *
876
+ * @return array
877
+ */
878
+ function modify_title_actions( $actions, $post ){
879
+ if( 'spucpt' != $post->post_type )
880
+ return $actions;
881
+
882
+ unset( $actions['view'] );
883
+
884
+ return $actions;
885
+ }
886
+
887
  }
admin/views/metaboxes/metabox-help.php CHANGED
@@ -3,35 +3,35 @@
3
  if ( !defined( 'ABSPATH' ) ) exit;
4
  ?>
5
 
6
- <p><?php _e( 'You have three social shortcodes to use that will print a Facebook like, a Google+ Follow and a Twitter follow. Check the available options and <strong>configure them with your social accounts</strong>:', 'popups' );?></p>
7
 
8
- <p><strong>New Facebook page:</strong></p>
9
  <p>
10
  [spu-facebook-page href="" name="" show_faces="" hide_cover="" width=""]
11
  </p>
12
  <a href="fb-opts" onclick="jQuery('#fbpage-opts').slideToggle();return false;"><?php _e( 'View Facebook Page Options', 'popups' );?></a>
13
  <ul id="fbpage-opts" style="display:none;">
14
- <li><b>href:</b> <?php _e( 'Your facebook page url', 'popups' );?></li>
15
  <li><b>name:</b> <?php _e( 'Your page name', 'popups' );?></li>
16
  <li><b>show_faces:</b> <?php _e( 'true|false <b>Default value:</b> true', 'popups' );?></li>
17
  <li><b>hide_cover:</b> <?php _e( 'true|false <b>Default value:</b> false', 'popups' );?></li>
18
- <li><b>width:</b></li>
19
  </ul>
20
 
21
- <p><strong>Facebook:</strong></p>
22
  <p>
23
  [spu-facebook href="" layout="" show_faces="" share="" action="" width=""]
24
  </p>
25
  <a href="fb-opts" onclick="jQuery('#fb-opts').slideToggle();return false;"><?php _e( 'View Facebook Options', 'popups' );?></a>
26
  <ul id="fb-opts" style="display:none;">
27
- <li><b>href:</b> <?php _e( 'Your facebook page url', 'popups' );?></li>
28
  <li><b>layout:</b> <?php _e( 'standard, box_count, button <b>Default value:</b> button_count', 'popups' );?></li>
29
  <li><b>show_faces:</b> <?php _e( 'true <b>Default value:</b> false', 'popups' );?></li>
30
  <li><b>share:</b> <?php _e( 'true <b>Default value:</b> false', 'popups' );?></li>
31
  <li><b>action:</b> <?php _e( 'recommend <b>Default value:</b> like', 'popups' );?></li>
32
- <li><b>width:</b></li>
33
  </ul>
34
- <p><strong>Google+:</strong></p>
35
  <p>
36
  [spu-google url="" size="" annotation=""]
37
  </p>
@@ -41,19 +41,19 @@ if ( !defined( 'ABSPATH' ) ) exit;
41
  <li><b>size:</b> <?php _e( 'small, standard, tall <b>Default value:</b> medium', 'popups' );?></li>
42
  <li><b>annotation:</b> <?php _e( 'inline, none <b>Default value:</b> bubble', 'popups' );?></li>
43
  </ul>
44
- <p><strong>Twitter:</strong></p>
45
  <p>
46
  [spu-twitter user="" show_count="" size="" lang=""]
47
  </p>
48
  <a href="tw-opts" onclick="jQuery('#tw-opts').slideToggle();return false;"><?php _e( 'View Twitter Options', 'popups' );?></a>
49
  <ul id="tw-opts" style="display:none;">
50
- <li><b>user:</b> <?php _e( 'Your Twitter user <b>Default chifli</b>iiii', 'popups' );?></li>
51
  <li><b>show_count:</b> <?php _e( 'false <b>Default value:</b> true', 'popups' );?></li>
52
  <li><b>size:</b> <?php _e( 'large <b>Default value:</b> ""', 'popups' );?></li>
53
  <li><b>lang:</b> </li>
54
  </ul>
55
- <h3 style="padding-left:0;margin: 20px 0;"><strong><?php _e('Other available Shortcodes:', 'popups' );?><strong></h3>
56
- <p><strong>Close Button:</strong></p>
57
  <p>
58
  [spu-close class="" text="" align=""]
59
  </p>
3
  if ( !defined( 'ABSPATH' ) ) exit;
4
  ?>
5
 
6
+ <p><?php _e( 'You have some social shortcodes to use that will print a Facebook like, a Google+ Follow and a Twitter follow. Check the available options and <strong>configure them with your social accounts</strong>:', 'popups' );?></p>
7
 
8
+ <p><strong><?php _e( 'Facebook Page', 'popups' );?>:</strong></p>
9
  <p>
10
  [spu-facebook-page href="" name="" show_faces="" hide_cover="" width=""]
11
  </p>
12
  <a href="fb-opts" onclick="jQuery('#fbpage-opts').slideToggle();return false;"><?php _e( 'View Facebook Page Options', 'popups' );?></a>
13
  <ul id="fbpage-opts" style="display:none;">
14
+ <li><b>href:</b> <?php _e( 'Your Facebook page url', 'popups' );?></li>
15
  <li><b>name:</b> <?php _e( 'Your page name', 'popups' );?></li>
16
  <li><b>show_faces:</b> <?php _e( 'true|false <b>Default value:</b> true', 'popups' );?></li>
17
  <li><b>hide_cover:</b> <?php _e( 'true|false <b>Default value:</b> false', 'popups' );?></li>
18
+ <li><b>width:</b> <?php _e( 'number <b>Default value:</b> 500', 'popups' );?></b></li>
19
  </ul>
20
 
21
+ <p><strong><?php _e( 'Facebook Button', 'popups' );?>:</strong></p>
22
  <p>
23
  [spu-facebook href="" layout="" show_faces="" share="" action="" width=""]
24
  </p>
25
  <a href="fb-opts" onclick="jQuery('#fb-opts').slideToggle();return false;"><?php _e( 'View Facebook Options', 'popups' );?></a>
26
  <ul id="fb-opts" style="display:none;">
27
+ <li><b>href:</b> <?php _e( 'Your Facebook page url', 'popups' );?></li>
28
  <li><b>layout:</b> <?php _e( 'standard, box_count, button <b>Default value:</b> button_count', 'popups' );?></li>
29
  <li><b>show_faces:</b> <?php _e( 'true <b>Default value:</b> false', 'popups' );?></li>
30
  <li><b>share:</b> <?php _e( 'true <b>Default value:</b> false', 'popups' );?></li>
31
  <li><b>action:</b> <?php _e( 'recommend <b>Default value:</b> like', 'popups' );?></li>
32
+ <li><b>width:</b> <?php _e( 'number <b>Default value:</b>', 'popups' );?></li>
33
  </ul>
34
+ <p><strong><?php _e( 'Google+ Button', 'popups' );?>:</strong></p>
35
  <p>
36
  [spu-google url="" size="" annotation=""]
37
  </p>
41
  <li><b>size:</b> <?php _e( 'small, standard, tall <b>Default value:</b> medium', 'popups' );?></li>
42
  <li><b>annotation:</b> <?php _e( 'inline, none <b>Default value:</b> bubble', 'popups' );?></li>
43
  </ul>
44
+ <p><strong><?php _e( 'Twitter Button', 'popups' );?>:</strong></p>
45
  <p>
46
  [spu-twitter user="" show_count="" size="" lang=""]
47
  </p>
48
  <a href="tw-opts" onclick="jQuery('#tw-opts').slideToggle();return false;"><?php _e( 'View Twitter Options', 'popups' );?></a>
49
  <ul id="tw-opts" style="display:none;">
50
+ <li><b>user:</b> <?php _e( 'Your Twitter user <b>Default value: </b>', 'popups' ); echo ' ' . apply_filters( 'spu/social/tw_user', 'chifliiiii' ); ?></li>
51
  <li><b>show_count:</b> <?php _e( 'false <b>Default value:</b> true', 'popups' );?></li>
52
  <li><b>size:</b> <?php _e( 'large <b>Default value:</b> ""', 'popups' );?></li>
53
  <li><b>lang:</b> </li>
54
  </ul>
55
+ <h3 style="padding-left:0;margin: 20px 0;"><strong><?php _e('Other available Shortcodes:', 'popups' );?></strong></h3>
56
+ <p><strong><?php _e( 'Close Button', 'popups' );?>:</strong></p>
57
  <p>
58
  [spu-close class="" text="" align=""]
59
  </p>
includes/class-spu-helper.php CHANGED
@@ -215,16 +215,8 @@ class Spu_Helper {
215
  break;
216
 
217
  case "post_status" :
218
-
219
- $choices = array(
220
- 'publish' => __( 'Publish' ),
221
- 'pending' => __( 'Pending Review' ),
222
- 'draft' => __( 'Draft' ),
223
- 'future' => __( 'Future' ),
224
- 'private' => __( 'Private' ),
225
- 'inherit' => __( 'Revision' ),
226
- 'trash' => __( 'Trash' )
227
- );
228
 
229
  break;
230
 
215
  break;
216
 
217
  case "post_status" :
218
+
219
+ $choices = get_post_stati();
 
 
 
 
 
 
 
 
220
 
221
  break;
222
 
languages/popups.pot CHANGED
@@ -1,10 +1,11 @@
1
  # Copyright (C) 2013 TODO
2
  # This file is distributed under the same license as the TODO package.
 
3
  msgid ""
4
  msgstr ""
5
  "Project-Id-Version: Popups\n"
6
  "Report-Msgid-Bugs-To: http://wordpress.org/plugins/plugin-name\n"
7
- "POT-Creation-Date: 2015-06-14 00:02-0300\n"
8
  "PO-Revision-Date: 2015-06-14 00:02-0300\n"
9
  "Last-Translator: Damian Logghe <info@timersys.com>\n"
10
  "Language-Team: Timersys <info@timersys.com>\n"
@@ -12,193 +13,205 @@ msgstr ""
12
  "MIME-Version: 1.0\n"
13
  "Content-Type: text/plain; charset=UTF-8\n"
14
  "Content-Transfer-Encoding: 8bit\n"
15
- "X-Generator: Poedit 1.7.4\n"
16
  "X-Poedit-KeywordsList: __;_e;_n;_x;esc_html_e;esc_html__;esc_attr_e;"
17
  "esc_attr__;_ex:1,2c;_nx:4c,1,2;_nx_noop:4c,1,2;_x:1,2c;_n:1,2\n"
18
- "X-Poedit-Basepath: ../\n"
19
  "Plural-Forms: nplurals=2; plural=n != 1;\n"
20
  "X-Poedit-SearchPath-0: .\n"
21
 
22
- #: admin/class-social-popup-admin.php:154
23
  msgctxt "post type singular name"
24
  msgid "Popups"
25
  msgstr ""
26
 
27
- #: admin/class-social-popup-admin.php:155
28
  msgctxt "admin menu"
29
  msgid "Popups"
30
  msgstr ""
31
 
32
- #: admin/class-social-popup-admin.php:156
33
  msgctxt "add new on admin bar"
34
  msgid "Popups"
35
  msgstr ""
36
 
37
- #: admin/class-social-popup-admin.php:157
38
  msgctxt "Popups"
39
  msgid "Add New"
40
  msgstr ""
41
 
42
- #: admin/class-social-popup-admin.php:158
43
  msgid "Add New Popups"
44
  msgstr ""
45
 
46
- #: admin/class-social-popup-admin.php:159
47
  msgid "New Popups"
48
  msgstr ""
49
 
50
- #: admin/class-social-popup-admin.php:160
51
  msgid "Edit Popups"
52
  msgstr ""
53
 
54
- #: admin/class-social-popup-admin.php:161
55
  msgid "View Popups"
56
  msgstr ""
57
 
58
- #: admin/class-social-popup-admin.php:162
59
  msgid "All Popups"
60
  msgstr ""
61
 
62
- #: admin/class-social-popup-admin.php:163
63
  msgid "Search Popups"
64
  msgstr ""
65
 
66
- #: admin/class-social-popup-admin.php:164
67
  msgid "Parent Popups:"
68
  msgstr ""
69
 
70
- #: admin/class-social-popup-admin.php:165
71
  msgid "No Popups found."
72
  msgstr ""
73
 
74
- #: admin/class-social-popup-admin.php:166
75
  msgid "No Popups found in Trash."
76
  msgstr ""
77
 
78
- #: admin/class-social-popup-admin.php:255
 
 
 
 
79
  msgid "Popups Premium"
80
  msgstr ""
81
 
82
- #: admin/class-social-popup-admin.php:266
83
  msgid "PopUp Shortcodes"
84
  msgstr ""
85
 
86
- #: admin/class-social-popup-admin.php:275
 
 
 
 
87
  msgid "PopUp Display Rules"
88
  msgstr ""
89
 
90
- #: admin/class-social-popup-admin.php:284
91
  msgid "Display Options"
92
  msgstr ""
93
 
94
- #: admin/class-social-popup-admin.php:293
95
  msgid "Need support?"
96
  msgstr ""
97
 
98
- #: admin/class-social-popup-admin.php:301
99
  msgid "Donate & support"
100
  msgstr ""
101
 
102
- #: admin/class-social-popup-admin.php:309
103
  msgid "About the developer"
104
  msgstr ""
105
 
106
- #: admin/class-social-popup-admin.php:557
107
  #: admin/views/metaboxes/metabox-rules.php:33
108
  #: admin/views/metaboxes/metabox-rules.php:106
109
  msgid "or"
110
  msgstr ""
111
 
112
- #: admin/class-social-popup-admin.php:584
113
  msgid "Add a Popup"
114
  msgstr ""
115
 
116
- #: admin/class-social-popup-admin.php:708
117
  msgid "User"
118
  msgstr ""
119
 
120
- #: admin/class-social-popup-admin.php:709
121
  msgid "User role"
122
  msgstr ""
123
 
124
- #: admin/class-social-popup-admin.php:710
125
  msgid "User is logged"
126
  msgstr ""
127
 
128
- #: admin/class-social-popup-admin.php:711
129
  msgid "User never left a comment"
130
  msgstr ""
131
 
132
- #: admin/class-social-popup-admin.php:712
133
  msgid "User came via a search engine"
134
  msgstr ""
135
 
136
- #: admin/class-social-popup-admin.php:713
137
  msgid "User did not arrive via another page on your site"
138
  msgstr ""
139
 
140
- #: admin/class-social-popup-admin.php:715
141
- #: admin/class-social-popup-admin.php:716
142
  msgid "Post"
143
  msgstr ""
144
 
145
- #: admin/class-social-popup-admin.php:717
146
  msgid "Post ID"
147
  msgstr ""
148
 
149
- #: admin/class-social-popup-admin.php:718
150
  msgid "Post Type"
151
  msgstr ""
152
 
153
- #: admin/class-social-popup-admin.php:719
154
  msgid "Post Category"
155
  msgstr ""
156
 
157
- #: admin/class-social-popup-admin.php:720
158
  msgid "Post Format"
159
  msgstr ""
160
 
161
- #: admin/class-social-popup-admin.php:721
162
  msgid "Post Status"
163
  msgstr ""
164
 
165
- #: admin/class-social-popup-admin.php:722
166
  msgid "Post Taxonomy"
167
  msgstr ""
168
 
169
- #: admin/class-social-popup-admin.php:724
170
- #: admin/class-social-popup-admin.php:725
171
  msgid "Page"
172
  msgstr ""
173
 
174
- #: admin/class-social-popup-admin.php:726
175
  msgid "Page Type"
176
  msgstr ""
177
 
178
- #: admin/class-social-popup-admin.php:727
179
  msgid "Page Parent"
180
  msgstr ""
181
 
182
- #: admin/class-social-popup-admin.php:728
183
  msgid "Page Template"
184
  msgstr ""
185
 
186
- #: admin/class-social-popup-admin.php:730
187
  msgid "Other"
188
  msgstr ""
189
 
190
- #: admin/class-social-popup-admin.php:731
191
  msgid "Referrer"
192
  msgstr ""
193
 
194
- #: admin/class-social-popup-admin.php:732
195
  msgid "Mobile Phone"
196
  msgstr ""
197
 
198
- #: admin/class-social-popup-admin.php:733
199
  msgid "Tablet"
200
  msgstr ""
201
 
 
 
 
 
202
  #: admin/includes/class-spu-notices.php:30
203
  #, php-format
204
  msgid ""
@@ -218,6 +231,34 @@ msgstr ""
218
  msgid "<a href=\"%s\">No, thanks</a>"
219
  msgstr ""
220
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
221
  #: admin/views/metaboxes/metabox-donate.php:6
222
  msgid "If you like this plugin, consider supporting it by donating."
223
  msgstr ""
@@ -248,18 +289,22 @@ msgstr ""
248
 
249
  #: admin/views/metaboxes/metabox-help.php:6
250
  msgid ""
251
- "You have three social shortcodes to use that will print a Facebook like, a "
252
  "Google+ Follow and a Twitter follow. Check the available options and "
253
  "<strong>configure them with your social accounts</strong>:"
254
  msgstr ""
255
 
 
 
 
 
256
  #: admin/views/metaboxes/metabox-help.php:12
257
  msgid "View Facebook Page Options"
258
  msgstr ""
259
 
260
  #: admin/views/metaboxes/metabox-help.php:14
261
  #: admin/views/metaboxes/metabox-help.php:27
262
- msgid "Your facebook page url"
263
  msgstr ""
264
 
265
  #: admin/views/metaboxes/metabox-help.php:15
@@ -274,6 +319,14 @@ msgstr ""
274
  msgid "true|false <b>Default value:</b> false"
275
  msgstr ""
276
 
 
 
 
 
 
 
 
 
277
  #: admin/views/metaboxes/metabox-help.php:25
278
  msgid "View Facebook Options"
279
  msgstr ""
@@ -291,6 +344,14 @@ msgstr ""
291
  msgid "recommend <b>Default value:</b> like"
292
  msgstr ""
293
 
 
 
 
 
 
 
 
 
294
  #: admin/views/metaboxes/metabox-help.php:38
295
  msgid "View Google+ Options"
296
  msgstr ""
@@ -307,12 +368,16 @@ msgstr ""
307
  msgid "inline, none <b>Default value:</b> bubble"
308
  msgstr ""
309
 
 
 
 
 
310
  #: admin/views/metaboxes/metabox-help.php:48
311
  msgid "View Twitter Options"
312
  msgstr ""
313
 
314
  #: admin/views/metaboxes/metabox-help.php:50
315
- msgid "Your Twitter user <b>Default chifli</b>iiii"
316
  msgstr ""
317
 
318
  #: admin/views/metaboxes/metabox-help.php:51
@@ -327,6 +392,10 @@ msgstr ""
327
  msgid "Other available Shortcodes:"
328
  msgstr ""
329
 
 
 
 
 
330
  #: admin/views/metaboxes/metabox-help.php:60
331
  msgid "View Close shortcode Options"
332
  msgstr ""
@@ -429,10 +498,7 @@ msgid "No"
429
  msgstr ""
430
 
431
  #: admin/views/metaboxes/metabox-options.php:42
432
- #, php-format
433
- msgid ""
434
- "Hide box again when visitors scroll back up? Only works when Trigger action "
435
- "is set to % of page height"
436
  msgstr ""
437
 
438
  #: admin/views/metaboxes/metabox-options.php:46
@@ -490,38 +556,6 @@ msgid ""
490
  "in the <a href=\"%s\">settings</a>, it will be used."
491
  msgstr ""
492
 
493
- #: admin/views/metaboxes/metabox-options.php:91
494
- msgid "Appearance"
495
- msgstr ""
496
-
497
- #: admin/views/metaboxes/metabox-options.php:95
498
- msgid "Background opacity"
499
- msgstr ""
500
-
501
- #: admin/views/metaboxes/metabox-options.php:98
502
- msgid "Leave at 0 for no background. Max value is 1"
503
- msgstr ""
504
-
505
- #: admin/views/metaboxes/metabox-options.php:104
506
- msgid "Background color"
507
- msgstr ""
508
-
509
- #: admin/views/metaboxes/metabox-options.php:108
510
- msgid "Text color"
511
- msgstr ""
512
-
513
- #: admin/views/metaboxes/metabox-options.php:112
514
- msgid "Box width"
515
- msgstr ""
516
-
517
- #: admin/views/metaboxes/metabox-options.php:118
518
- msgid "Border color"
519
- msgstr ""
520
-
521
- #: admin/views/metaboxes/metabox-options.php:122
522
- msgid "Border width"
523
- msgstr ""
524
-
525
  #: admin/views/metaboxes/metabox-premium.php:16
526
  msgid ""
527
  "Take the best WordPress Popups plugin to the next level with Popups Premium "
@@ -698,78 +732,92 @@ msgstr ""
698
  msgid "If you use your own Twitter script, check this"
699
  msgstr ""
700
 
701
- #: admin/views/settings-page.php:80
 
 
 
 
 
 
 
 
 
 
702
  msgid "Save settings"
703
  msgstr ""
704
 
705
- #: includes/class-spu-helper.php:133
706
  msgid "All Pages"
707
  msgstr ""
708
 
709
- #: includes/class-spu-helper.php:134
710
  msgid "Front Page"
711
  msgstr ""
712
 
713
- #: includes/class-spu-helper.php:135
714
  msgid "Posts Page"
715
  msgstr ""
716
 
717
- #: includes/class-spu-helper.php:136
718
  msgid "Category Page"
719
  msgstr ""
720
 
721
- #: includes/class-spu-helper.php:137
 
 
 
 
722
  msgid "Archives Page"
723
  msgstr ""
724
 
725
- #: includes/class-spu-helper.php:138
726
  msgid "Top Level Page (parent of 0)"
727
  msgstr ""
728
 
729
- #: includes/class-spu-helper.php:139
730
  msgid "Parent Page (has children)"
731
  msgstr ""
732
 
733
- #: includes/class-spu-helper.php:140
734
  msgid "Child Page (has parent)"
735
  msgstr ""
736
 
737
- #: includes/class-spu-helper.php:148
738
  msgid "Default Template"
739
  msgstr ""
740
 
741
- #: includes/class-spu-helper.php:221
742
  msgid "Publish"
743
  msgstr ""
744
 
745
- #: includes/class-spu-helper.php:222
746
  msgid "Pending Review"
747
  msgstr ""
748
 
749
- #: includes/class-spu-helper.php:223
750
  msgid "Draft"
751
  msgstr ""
752
 
753
- #: includes/class-spu-helper.php:224
754
  msgid "Future"
755
  msgstr ""
756
 
757
- #: includes/class-spu-helper.php:225
758
  msgid "Private"
759
  msgstr ""
760
 
761
- #: includes/class-spu-helper.php:226
762
  msgid "Revision"
763
  msgstr ""
764
 
765
- #: includes/class-spu-helper.php:227
766
  msgid "Trash"
767
  msgstr ""
768
 
769
- #: includes/class-spu-helper.php:240
770
  msgid "Super Admin"
771
  msgstr ""
772
 
773
- #: includes/class-spu-helper.php:260
774
  msgid "True"
775
  msgstr ""
1
  # Copyright (C) 2013 TODO
2
  # This file is distributed under the same license as the TODO package.
3
+ #, fuzzy
4
  msgid ""
5
  msgstr ""
6
  "Project-Id-Version: Popups\n"
7
  "Report-Msgid-Bugs-To: http://wordpress.org/plugins/plugin-name\n"
8
+ "POT-Creation-Date: 2016-02-04 13:02+0100\n"
9
  "PO-Revision-Date: 2015-06-14 00:02-0300\n"
10
  "Last-Translator: Damian Logghe <info@timersys.com>\n"
11
  "Language-Team: Timersys <info@timersys.com>\n"
13
  "MIME-Version: 1.0\n"
14
  "Content-Type: text/plain; charset=UTF-8\n"
15
  "Content-Transfer-Encoding: 8bit\n"
16
+ "X-Generator: Poedit 1.8.5\n"
17
  "X-Poedit-KeywordsList: __;_e;_n;_x;esc_html_e;esc_html__;esc_attr_e;"
18
  "esc_attr__;_ex:1,2c;_nx:4c,1,2;_nx_noop:4c,1,2;_x:1,2c;_n:1,2\n"
19
+ "X-Poedit-Basepath: ..\n"
20
  "Plural-Forms: nplurals=2; plural=n != 1;\n"
21
  "X-Poedit-SearchPath-0: .\n"
22
 
23
+ #: admin/class-social-popup-admin.php:159
24
  msgctxt "post type singular name"
25
  msgid "Popups"
26
  msgstr ""
27
 
28
+ #: admin/class-social-popup-admin.php:160
29
  msgctxt "admin menu"
30
  msgid "Popups"
31
  msgstr ""
32
 
33
+ #: admin/class-social-popup-admin.php:161
34
  msgctxt "add new on admin bar"
35
  msgid "Popups"
36
  msgstr ""
37
 
38
+ #: admin/class-social-popup-admin.php:162
39
  msgctxt "Popups"
40
  msgid "Add New"
41
  msgstr ""
42
 
43
+ #: admin/class-social-popup-admin.php:163
44
  msgid "Add New Popups"
45
  msgstr ""
46
 
47
+ #: admin/class-social-popup-admin.php:164
48
  msgid "New Popups"
49
  msgstr ""
50
 
51
+ #: admin/class-social-popup-admin.php:165
52
  msgid "Edit Popups"
53
  msgstr ""
54
 
55
+ #: admin/class-social-popup-admin.php:166
56
  msgid "View Popups"
57
  msgstr ""
58
 
59
+ #: admin/class-social-popup-admin.php:167
60
  msgid "All Popups"
61
  msgstr ""
62
 
63
+ #: admin/class-social-popup-admin.php:168
64
  msgid "Search Popups"
65
  msgstr ""
66
 
67
+ #: admin/class-social-popup-admin.php:169
68
  msgid "Parent Popups:"
69
  msgstr ""
70
 
71
+ #: admin/class-social-popup-admin.php:170
72
  msgid "No Popups found."
73
  msgstr ""
74
 
75
+ #: admin/class-social-popup-admin.php:171
76
  msgid "No Popups found in Trash."
77
  msgstr ""
78
 
79
+ #: admin/class-social-popup-admin.php:212
80
+ msgid "Settings"
81
+ msgstr ""
82
+
83
+ #: admin/class-social-popup-admin.php:260
84
  msgid "Popups Premium"
85
  msgstr ""
86
 
87
+ #: admin/class-social-popup-admin.php:271
88
  msgid "PopUp Shortcodes"
89
  msgstr ""
90
 
91
+ #: admin/class-social-popup-admin.php:280
92
+ msgid "PopUp Appearance"
93
+ msgstr ""
94
+
95
+ #: admin/class-social-popup-admin.php:289
96
  msgid "PopUp Display Rules"
97
  msgstr ""
98
 
99
+ #: admin/class-social-popup-admin.php:298
100
  msgid "Display Options"
101
  msgstr ""
102
 
103
+ #: admin/class-social-popup-admin.php:307
104
  msgid "Need support?"
105
  msgstr ""
106
 
107
+ #: admin/class-social-popup-admin.php:315
108
  msgid "Donate & support"
109
  msgstr ""
110
 
111
+ #: admin/class-social-popup-admin.php:323
112
  msgid "About the developer"
113
  msgstr ""
114
 
115
+ #: admin/class-social-popup-admin.php:589
116
  #: admin/views/metaboxes/metabox-rules.php:33
117
  #: admin/views/metaboxes/metabox-rules.php:106
118
  msgid "or"
119
  msgstr ""
120
 
121
+ #: admin/class-social-popup-admin.php:616
122
  msgid "Add a Popup"
123
  msgstr ""
124
 
125
+ #: admin/class-social-popup-admin.php:740
126
  msgid "User"
127
  msgstr ""
128
 
129
+ #: admin/class-social-popup-admin.php:741
130
  msgid "User role"
131
  msgstr ""
132
 
133
+ #: admin/class-social-popup-admin.php:742
134
  msgid "User is logged"
135
  msgstr ""
136
 
137
+ #: admin/class-social-popup-admin.php:743
138
  msgid "User never left a comment"
139
  msgstr ""
140
 
141
+ #: admin/class-social-popup-admin.php:744
142
  msgid "User came via a search engine"
143
  msgstr ""
144
 
145
+ #: admin/class-social-popup-admin.php:745
146
  msgid "User did not arrive via another page on your site"
147
  msgstr ""
148
 
149
+ #: admin/class-social-popup-admin.php:747
150
+ #: admin/class-social-popup-admin.php:748
151
  msgid "Post"
152
  msgstr ""
153
 
154
+ #: admin/class-social-popup-admin.php:749
155
  msgid "Post ID"
156
  msgstr ""
157
 
158
+ #: admin/class-social-popup-admin.php:750
159
  msgid "Post Type"
160
  msgstr ""
161
 
162
+ #: admin/class-social-popup-admin.php:751
163
  msgid "Post Category"
164
  msgstr ""
165
 
166
+ #: admin/class-social-popup-admin.php:752
167
  msgid "Post Format"
168
  msgstr ""
169
 
170
+ #: admin/class-social-popup-admin.php:753
171
  msgid "Post Status"
172
  msgstr ""
173
 
174
+ #: admin/class-social-popup-admin.php:754
175
  msgid "Post Taxonomy"
176
  msgstr ""
177
 
178
+ #: admin/class-social-popup-admin.php:756
179
+ #: admin/class-social-popup-admin.php:757
180
  msgid "Page"
181
  msgstr ""
182
 
183
+ #: admin/class-social-popup-admin.php:758
184
  msgid "Page Type"
185
  msgstr ""
186
 
187
+ #: admin/class-social-popup-admin.php:759
188
  msgid "Page Parent"
189
  msgstr ""
190
 
191
+ #: admin/class-social-popup-admin.php:760
192
  msgid "Page Template"
193
  msgstr ""
194
 
195
+ #: admin/class-social-popup-admin.php:762
196
  msgid "Other"
197
  msgstr ""
198
 
199
+ #: admin/class-social-popup-admin.php:763
200
  msgid "Referrer"
201
  msgstr ""
202
 
203
+ #: admin/class-social-popup-admin.php:764
204
  msgid "Mobile Phone"
205
  msgstr ""
206
 
207
+ #: admin/class-social-popup-admin.php:765
208
  msgid "Tablet"
209
  msgstr ""
210
 
211
+ #: admin/class-social-popup-admin.php:813
212
+ msgid "ID"
213
+ msgstr ""
214
+
215
  #: admin/includes/class-spu-notices.php:30
216
  #, php-format
217
  msgid ""
231
  msgid "<a href=\"%s\">No, thanks</a>"
232
  msgstr ""
233
 
234
+ #: admin/views/metaboxes/metabox-appearance.php:10
235
+ msgid "Background opacity"
236
+ msgstr ""
237
+
238
+ #: admin/views/metaboxes/metabox-appearance.php:12
239
+ msgid "Leave at 0 for no background. Max value is 1"
240
+ msgstr ""
241
+
242
+ #: admin/views/metaboxes/metabox-appearance.php:18
243
+ msgid "Background color"
244
+ msgstr ""
245
+
246
+ #: admin/views/metaboxes/metabox-appearance.php:22
247
+ msgid "Text color"
248
+ msgstr ""
249
+
250
+ #: admin/views/metaboxes/metabox-appearance.php:26
251
+ msgid "Box width"
252
+ msgstr ""
253
+
254
+ #: admin/views/metaboxes/metabox-appearance.php:32
255
+ msgid "Border color"
256
+ msgstr ""
257
+
258
+ #: admin/views/metaboxes/metabox-appearance.php:36
259
+ msgid "Border width"
260
+ msgstr ""
261
+
262
  #: admin/views/metaboxes/metabox-donate.php:6
263
  msgid "If you like this plugin, consider supporting it by donating."
264
  msgstr ""
289
 
290
  #: admin/views/metaboxes/metabox-help.php:6
291
  msgid ""
292
+ "You have some social shortcodes to use that will print a Facebook like, a "
293
  "Google+ Follow and a Twitter follow. Check the available options and "
294
  "<strong>configure them with your social accounts</strong>:"
295
  msgstr ""
296
 
297
+ #: admin/views/metaboxes/metabox-help.php:8
298
+ msgid "Facebook Page"
299
+ msgstr ""
300
+
301
  #: admin/views/metaboxes/metabox-help.php:12
302
  msgid "View Facebook Page Options"
303
  msgstr ""
304
 
305
  #: admin/views/metaboxes/metabox-help.php:14
306
  #: admin/views/metaboxes/metabox-help.php:27
307
+ msgid "Your Facebook page url"
308
  msgstr ""
309
 
310
  #: admin/views/metaboxes/metabox-help.php:15
319
  msgid "true|false <b>Default value:</b> false"
320
  msgstr ""
321
 
322
+ #: admin/views/metaboxes/metabox-help.php:18
323
+ msgid "number <b>Default value:</b> 500"
324
+ msgstr ""
325
+
326
+ #: admin/views/metaboxes/metabox-help.php:21
327
+ msgid "Facebook Button"
328
+ msgstr ""
329
+
330
  #: admin/views/metaboxes/metabox-help.php:25
331
  msgid "View Facebook Options"
332
  msgstr ""
344
  msgid "recommend <b>Default value:</b> like"
345
  msgstr ""
346
 
347
+ #: admin/views/metaboxes/metabox-help.php:32
348
+ msgid "number <b>Default value:</b>"
349
+ msgstr ""
350
+
351
+ #: admin/views/metaboxes/metabox-help.php:34
352
+ msgid "Google+ Button"
353
+ msgstr ""
354
+
355
  #: admin/views/metaboxes/metabox-help.php:38
356
  msgid "View Google+ Options"
357
  msgstr ""
368
  msgid "inline, none <b>Default value:</b> bubble"
369
  msgstr ""
370
 
371
+ #: admin/views/metaboxes/metabox-help.php:44
372
+ msgid "Twitter Button"
373
+ msgstr ""
374
+
375
  #: admin/views/metaboxes/metabox-help.php:48
376
  msgid "View Twitter Options"
377
  msgstr ""
378
 
379
  #: admin/views/metaboxes/metabox-help.php:50
380
+ msgid "Your Twitter user <b>Default chifliiiii</b>"
381
  msgstr ""
382
 
383
  #: admin/views/metaboxes/metabox-help.php:51
392
  msgid "Other available Shortcodes:"
393
  msgstr ""
394
 
395
+ #: admin/views/metaboxes/metabox-help.php:56
396
+ msgid "Close Button"
397
+ msgstr ""
398
+
399
  #: admin/views/metaboxes/metabox-help.php:60
400
  msgid "View Close shortcode Options"
401
  msgstr ""
498
  msgstr ""
499
 
500
  #: admin/views/metaboxes/metabox-options.php:42
501
+ msgid "Hide box again when visitors scroll back up?"
 
 
 
502
  msgstr ""
503
 
504
  #: admin/views/metaboxes/metabox-options.php:46
556
  "in the <a href=\"%s\">settings</a>, it will be used."
557
  msgstr ""
558
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
559
  #: admin/views/metaboxes/metabox-premium.php:16
560
  msgid ""
561
  "Take the best WordPress Popups plugin to the next level with Popups Premium "
732
  msgid "If you use your own Twitter script, check this"
733
  msgstr ""
734
 
735
+ #: admin/views/settings-page.php:82
736
+ msgid "Delete all data on Uninstall"
737
+ msgstr ""
738
+
739
+ #: admin/views/settings-page.php:85
740
+ msgid ""
741
+ "When you uninstall the plugin all popups, settings and stats will be deleted "
742
+ "from your db"
743
+ msgstr ""
744
+
745
+ #: admin/views/settings-page.php:89
746
  msgid "Save settings"
747
  msgstr ""
748
 
749
+ #: includes/class-spu-helper.php:131
750
  msgid "All Pages"
751
  msgstr ""
752
 
753
+ #: includes/class-spu-helper.php:132
754
  msgid "Front Page"
755
  msgstr ""
756
 
757
+ #: includes/class-spu-helper.php:133
758
  msgid "Posts Page"
759
  msgstr ""
760
 
761
+ #: includes/class-spu-helper.php:134
762
  msgid "Category Page"
763
  msgstr ""
764
 
765
+ #: includes/class-spu-helper.php:135
766
+ msgid "Search Page"
767
+ msgstr ""
768
+
769
+ #: includes/class-spu-helper.php:136
770
  msgid "Archives Page"
771
  msgstr ""
772
 
773
+ #: includes/class-spu-helper.php:137
774
  msgid "Top Level Page (parent of 0)"
775
  msgstr ""
776
 
777
+ #: includes/class-spu-helper.php:138
778
  msgid "Parent Page (has children)"
779
  msgstr ""
780
 
781
+ #: includes/class-spu-helper.php:139
782
  msgid "Child Page (has parent)"
783
  msgstr ""
784
 
785
+ #: includes/class-spu-helper.php:147
786
  msgid "Default Template"
787
  msgstr ""
788
 
789
+ #: includes/class-spu-helper.php:220
790
  msgid "Publish"
791
  msgstr ""
792
 
793
+ #: includes/class-spu-helper.php:221
794
  msgid "Pending Review"
795
  msgstr ""
796
 
797
+ #: includes/class-spu-helper.php:222
798
  msgid "Draft"
799
  msgstr ""
800
 
801
+ #: includes/class-spu-helper.php:223
802
  msgid "Future"
803
  msgstr ""
804
 
805
+ #: includes/class-spu-helper.php:224
806
  msgid "Private"
807
  msgstr ""
808
 
809
+ #: includes/class-spu-helper.php:225
810
  msgid "Revision"
811
  msgstr ""
812
 
813
+ #: includes/class-spu-helper.php:226
814
  msgid "Trash"
815
  msgstr ""
816
 
817
+ #: includes/class-spu-helper.php:239
818
  msgid "Super Admin"
819
  msgstr ""
820
 
821
+ #: includes/class-spu-helper.php:259
822
  msgid "True"
823
  msgstr ""
popups.php CHANGED
@@ -11,7 +11,7 @@
11
  * @socialpopup
12
  * Plugin Name: Popups - WordPress Popup
13
  * Plugin URI: http://www.timersys.com/free-plugins/social-popup/
14
- * Version: 1.4.4
15
  * Description: Most complete free Popups plugin, scroll triggered popups, compatible with social networks, Gravity Forms, Ninja Forms, Contact form 7, Mailpoet, Mailchimp for WP, Postmatic, etc
16
  * Author: Damian Logghe
17
  * Author URI: http://wp.timersys.com
@@ -30,7 +30,7 @@ if ( ! defined( 'WPINC' ) ) {
30
  * Public-Facing Functionality
31
  *----------------------------------------------------------------------------*/
32
 
33
- define( 'SPU_VERSION' , '1.4.4' );
34
  define( 'SPU_PLUGIN_DIR' , plugin_dir_path(__FILE__) );
35
  define( 'SPU_PLUGIN_URL' , plugin_dir_url(__FILE__) );
36
  define( 'SPU_PLUGIN_HOOK' , basename( dirname( __FILE__ ) ) . '/' . basename( __FILE__ ) );
11
  * @socialpopup
12
  * Plugin Name: Popups - WordPress Popup
13
  * Plugin URI: http://www.timersys.com/free-plugins/social-popup/
14
+ * Version: 1.4.5
15
  * Description: Most complete free Popups plugin, scroll triggered popups, compatible with social networks, Gravity Forms, Ninja Forms, Contact form 7, Mailpoet, Mailchimp for WP, Postmatic, etc
16
  * Author: Damian Logghe
17
  * Author URI: http://wp.timersys.com
30
  * Public-Facing Functionality
31
  *----------------------------------------------------------------------------*/
32
 
33
+ define( 'SPU_VERSION' , '1.4.5' );
34
  define( 'SPU_PLUGIN_DIR' , plugin_dir_path(__FILE__) );
35
  define( 'SPU_PLUGIN_URL' , plugin_dir_url(__FILE__) );
36
  define( 'SPU_PLUGIN_HOOK' , basename( dirname( __FILE__ ) ) . '/' . basename( __FILE__ ) );
public/assets/fonts/spufont.eot CHANGED
Binary file
public/assets/fonts/spufont.svg CHANGED
@@ -17,4 +17,6 @@
17
  <glyph unicode="&#xf106;" glyph-name="angle-up" horiz-adv-x="658" d="M614.286 274.286q0-7.429-5.714-13.143l-28.571-28.571q-5.714-5.714-13.143-5.714t-13.143 5.714l-224.571 224.571-224.571-224.571q-5.714-5.714-13.143-5.714t-13.143 5.714l-28.571 28.571q-5.714 5.714-5.714 13.143t5.714 13.143l266.286 266.286q5.714 5.714 13.143 5.714t13.143-5.714l266.286-266.286q5.714-5.714 5.714-13.143z" />
18
  <glyph unicode="&#xf107;" glyph-name="angle-down" horiz-adv-x="658" d="M614.286 530.286q0-7.429-5.714-13.143l-266.286-266.286q-5.714-5.714-13.143-5.714t-13.143 5.714l-266.286 266.286q-5.714 5.714-5.714 13.143t5.714 13.143l28.571 28.571q5.714 5.714 13.143 5.714t13.143-5.714l224.571-224.571 224.571 224.571q5.714 5.714 13.143 5.714t13.143-5.714l28.571-28.571q5.714-5.714 5.714-13.143z" />
19
  <glyph unicode="&#xf110;" glyph-name="spinner" d="M300.571 154.286q0-30.286-21.429-51.714t-51.714-21.429q-29.714 0-51.429 21.714t-21.714 51.429q0 30.286 21.429 51.714t51.714 21.429 51.714-21.429 21.429-51.714zM585.143 36.571q0-30.286-21.429-51.714t-51.714-21.429-51.714 21.429-21.429 51.714 21.429 51.714 51.714 21.429 51.714-21.429 21.429-51.714zM182.857 438.857q0-30.286-21.429-51.714t-51.714-21.429-51.714 21.429-21.429 51.714 21.429 51.714 51.714 21.429 51.714-21.429 21.429-51.714zM869.714 154.286q0-29.714-21.714-51.429t-51.429-21.714q-30.286 0-51.714 21.429t-21.429 51.714 21.429 51.714 51.714 21.429 51.714-21.429 21.429-51.714zM318.857 723.428q0-37.714-26.857-64.571t-64.571-26.857-64.571 26.857-26.857 64.571 26.857 64.571 64.571 26.857 64.571-26.857 26.857-64.571zM987.429 438.857q0-30.286-21.429-51.714t-51.714-21.429-51.714 21.429-21.429 51.714 21.429 51.714 51.714 21.429 51.714-21.429 21.429-51.714zM621.714 841.143q0-45.714-32-77.714t-77.714-32-77.714 32-32 77.714 32 77.714 77.714 32 77.714-32 32-77.714zM924.571 723.428q0-53.143-37.714-90.571t-90.286-37.429q-53.143 0-90.571 37.429t-37.429 90.571q0 52.571 37.429 90.286t90.571 37.714q52.571 0 90.286-37.714t37.714-90.286z" />
 
 
20
  </font></defs></svg>
17
  <glyph unicode="&#xf106;" glyph-name="angle-up" horiz-adv-x="658" d="M614.286 274.286q0-7.429-5.714-13.143l-28.571-28.571q-5.714-5.714-13.143-5.714t-13.143 5.714l-224.571 224.571-224.571-224.571q-5.714-5.714-13.143-5.714t-13.143 5.714l-28.571 28.571q-5.714 5.714-5.714 13.143t5.714 13.143l266.286 266.286q5.714 5.714 13.143 5.714t13.143-5.714l266.286-266.286q5.714-5.714 5.714-13.143z" />
18
  <glyph unicode="&#xf107;" glyph-name="angle-down" horiz-adv-x="658" d="M614.286 530.286q0-7.429-5.714-13.143l-266.286-266.286q-5.714-5.714-13.143-5.714t-13.143 5.714l-266.286 266.286q-5.714 5.714-5.714 13.143t5.714 13.143l28.571 28.571q5.714 5.714 13.143 5.714t13.143-5.714l224.571-224.571 224.571 224.571q5.714 5.714 13.143 5.714t13.143-5.714l28.571-28.571q5.714-5.714 5.714-13.143z" />
19
  <glyph unicode="&#xf110;" glyph-name="spinner" d="M300.571 154.286q0-30.286-21.429-51.714t-51.714-21.429q-29.714 0-51.429 21.714t-21.714 51.429q0 30.286 21.429 51.714t51.714 21.429 51.714-21.429 21.429-51.714zM585.143 36.571q0-30.286-21.429-51.714t-51.714-21.429-51.714 21.429-21.429 51.714 21.429 51.714 51.714 21.429 51.714-21.429 21.429-51.714zM182.857 438.857q0-30.286-21.429-51.714t-51.714-21.429-51.714 21.429-21.429 51.714 21.429 51.714 51.714 21.429 51.714-21.429 21.429-51.714zM869.714 154.286q0-29.714-21.714-51.429t-51.429-21.714q-30.286 0-51.714 21.429t-21.429 51.714 21.429 51.714 51.714 21.429 51.714-21.429 21.429-51.714zM318.857 723.428q0-37.714-26.857-64.571t-64.571-26.857-64.571 26.857-26.857 64.571 26.857 64.571 64.571 26.857 64.571-26.857 26.857-64.571zM987.429 438.857q0-30.286-21.429-51.714t-51.714-21.429-51.714 21.429-21.429 51.714 21.429 51.714 51.714 21.429 51.714-21.429 21.429-51.714zM621.714 841.143q0-45.714-32-77.714t-77.714-32-77.714 32-32 77.714 32 77.714 77.714 32 77.714-32 32-77.714zM924.571 723.428q0-53.143-37.714-90.571t-90.286-37.429q-53.143 0-90.571 37.429t-37.429 90.571q0 52.571 37.429 90.286t90.571 37.714q52.571 0 90.286-37.714t37.714-90.286z" />
20
+ <glyph unicode="&#xf204;" glyph-name="toggle-off" horiz-adv-x="1170" d="M658.286 438.857q0 59.429-23.143 113.429t-62.571 93.429-93.429 62.571-113.429 23.143-113.429-23.143-93.429-62.571-62.571-93.429-23.143-113.429 23.143-113.429 62.571-93.429 93.429-62.571 113.429-23.143 113.429 23.143 93.429 62.571 62.571 93.429 23.143 113.429zM1097.143 438.857q0 59.429-23.143 113.429t-62.571 93.429-93.429 62.571-113.429 23.143h-220.571q68-51.429 107.714-128t39.714-164.571-39.714-164.571-107.714-128h220.571q59.429 0 113.429 23.143t93.429 62.571 62.571 93.429 23.143 113.429zM1170.286 438.857q0-74.286-29.143-142t-78-116.571-116.571-78-142-29.143h-438.857q-74.286 0-142 29.143t-116.571 78-78 116.571-29.143 142 29.143 142 78 116.571 116.571 78 142 29.143h438.857q74.286 0 142-29.143t116.571-78 78-116.571 29.143-142z" />
21
+ <glyph unicode="&#xf205;" glyph-name="toggle-on" horiz-adv-x="1170" d="M0 438.857q0 74.286 29.143 142t78 116.571 116.571 78 142 29.143h438.857q74.286 0 142-29.143t116.571-78 78-116.571 29.143-142-29.143-142-78-116.571-116.571-78-142-29.143h-438.857q-74.286 0-142 29.143t-116.571 78-78 116.571-29.143 142zM804.571 146.286q59.429 0 113.429 23.143t93.429 62.571 62.571 93.429 23.143 113.429-23.143 113.429-62.571 93.429-93.429 62.571-113.429 23.143-113.429-23.143-93.429-62.571-62.571-93.429-23.143-113.429 23.143-113.429 62.571-93.429 93.429-62.571 113.429-23.143z" />
22
  </font></defs></svg>
public/assets/fonts/spufont.ttf CHANGED
Binary file
public/assets/fonts/spufont.woff CHANGED
Binary file
public/assets/js/min/public-min.js CHANGED
@@ -1 +1 @@
1
- (function(){function t(){}function e(t,e){for(var n=t.length;n--;)if(t[n].listener===e)return n;return-1}function n(t){return function(){return this[t].apply(this,arguments)}}var i=t.prototype,r=this,o=r.EventEmitter;i.getListeners=function(t){var e,n,i=this._getEvents();if("object"==typeof t){e={};for(n in i)i.hasOwnProperty(n)&&t.test(n)&&(e[n]=i[n])}else e=i[t]||(i[t]=[]);return e},i.flattenListeners=function(t){var e,n=[];for(e=0;t.length>e;e+=1)n.push(t[e].listener);return n},i.getListenersAsObject=function(t){var e,n=this.getListeners(t);return n instanceof Array&&(e={},e[t]=n),e||n},i.addListener=function(t,n){var i,r=this.getListenersAsObject(t),o="object"==typeof n;for(i in r)r.hasOwnProperty(i)&&-1===e(r[i],n)&&r[i].push(o?n:{listener:n,once:!1});return this},i.on=n("addListener"),i.addOnceListener=function(t,e){return this.addListener(t,{listener:e,once:!0})},i.once=n("addOnceListener"),i.defineEvent=function(t){return this.getListeners(t),this},i.defineEvents=function(t){for(var e=0;t.length>e;e+=1)this.defineEvent(t[e]);return this},i.removeListener=function(t,n){var i,r,o=this.getListenersAsObject(t);for(r in o)o.hasOwnProperty(r)&&(i=e(o[r],n),-1!==i&&o[r].splice(i,1));return this},i.off=n("removeListener"),i.addListeners=function(t,e){return this.manipulateListeners(!1,t,e)},i.removeListeners=function(t,e){return this.manipulateListeners(!0,t,e)},i.manipulateListeners=function(t,e,n){var i,r,o=t?this.removeListener:this.addListener,s=t?this.removeListeners:this.addListeners;if("object"!=typeof e||e instanceof RegExp)for(i=n.length;i--;)o.call(this,e,n[i]);else for(i in e)e.hasOwnProperty(i)&&(r=e[i])&&("function"==typeof r?o.call(this,i,r):s.call(this,i,r));return this},i.removeEvent=function(t){var e,n=typeof t,i=this._getEvents();if("string"===n)delete i[t];else if("object"===n)for(e in i)i.hasOwnProperty(e)&&t.test(e)&&delete i[e];else delete this._events;return this},i.removeAllListeners=n("removeEvent"),i.emitEvent=function(t,e){var n,i,r,o,s=this.getListenersAsObject(t);for(r in s)if(s.hasOwnProperty(r))for(i=s[r].length;i--;)n=s[r][i],n.once===!0&&this.removeListener(t,n.listener),o=n.listener.apply(this,e||[]),o===this._getOnceReturnValue()&&this.removeListener(t,n.listener);return this},i.trigger=n("emitEvent"),i.emit=function(t){var e=Array.prototype.slice.call(arguments,1);return this.emitEvent(t,e)},i.setOnceReturnValue=function(t){return this._onceReturnValue=t,this},i._getOnceReturnValue=function(){return this.hasOwnProperty("_onceReturnValue")?this._onceReturnValue:!0},i._getEvents=function(){return this._events||(this._events={})},t.noConflict=function(){return r.EventEmitter=o,t},"function"==typeof define&&define.amd?define("eventEmitter/EventEmitter",[],function(){return t}):"object"==typeof module&&module.exports?module.exports=t:this.EventEmitter=t}).call(this),function(t){function e(e){var n=t.event;return n.target=n.target||n.srcElement||e,n}var n=document.documentElement,i=function(){};n.addEventListener?i=function(t,e,n){t.addEventListener(e,n,!1)}:n.attachEvent&&(i=function(t,n,i){t[n+i]=i.handleEvent?function(){var n=e(t);i.handleEvent.call(i,n)}:function(){var n=e(t);i.call(t,n)},t.attachEvent("on"+n,t[n+i])});var r=function(){};n.removeEventListener?r=function(t,e,n){t.removeEventListener(e,n,!1)}:n.detachEvent&&(r=function(t,e,n){t.detachEvent("on"+e,t[e+n]);try{delete t[e+n]}catch(i){t[e+n]=void 0}});var o={bind:i,unbind:r};"function"==typeof define&&define.amd?define("eventie/eventie",o):t.eventie=o}(this),function(t,e){"function"==typeof define&&define.amd?define(["eventEmitter/EventEmitter","eventie/eventie"],function(n,i){return e(t,n,i)}):"object"==typeof exports?module.exports=e(t,require("wolfy87-eventemitter"),require("eventie")):t.imagesLoaded=e(t,t.EventEmitter,t.eventie)}(window,function(t,e,n){function i(t,e){for(var n in e)t[n]=e[n];return t}function r(t){return"[object Array]"===p.call(t)}function o(t){var e=[];if(r(t))e=t;else if("number"==typeof t.length)for(var n=0,i=t.length;i>n;n++)e.push(t[n]);else e.push(t);return e}function s(t,e,n){if(!(this instanceof s))return new s(t,e);"string"==typeof t&&(t=document.querySelectorAll(t)),this.elements=o(t),this.options=i({},this.options),"function"==typeof e?n=e:i(this.options,e),n&&this.on("always",n),this.getImages(),f&&(this.jqDeferred=new f.Deferred);var r=this;setTimeout(function(){r.check()})}function a(t){this.img=t}function u(t){this.src=t,h[t]=this}var f=t.jQuery,c=t.console,d=void 0!==c,p=Object.prototype.toString;s.prototype=new e,s.prototype.options={},s.prototype.getImages=function(){this.images=[];for(var t=0,e=this.elements.length;e>t;t++){var n=this.elements[t];"IMG"===n.nodeName&&this.addImage(n);var i=n.nodeType;if(i&&(1===i||9===i||11===i))for(var r=n.querySelectorAll("img"),o=0,s=r.length;s>o;o++){var a=r[o];this.addImage(a)}}},s.prototype.addImage=function(t){var e=new a(t);this.images.push(e)},s.prototype.check=function(){function t(t,r){return e.options.debug&&d&&c.log("confirm",t,r),e.progress(t),n++,n===i&&e.complete(),!0}var e=this,n=0,i=this.images.length;if(this.hasAnyBroken=!1,!i)return void this.complete();for(var r=0;i>r;r++){var o=this.images[r];o.on("confirm",t),o.check()}},s.prototype.progress=function(t){this.hasAnyBroken=this.hasAnyBroken||!t.isLoaded;var e=this;setTimeout(function(){e.emit("progress",e,t),e.jqDeferred&&e.jqDeferred.notify&&e.jqDeferred.notify(e,t)})},s.prototype.complete=function(){var t=this.hasAnyBroken?"fail":"done";this.isComplete=!0;var e=this;setTimeout(function(){if(e.emit(t,e),e.emit("always",e),e.jqDeferred){var n=e.hasAnyBroken?"reject":"resolve";e.jqDeferred[n](e)}})},f&&(f.fn.imagesLoaded=function(t,e){var n=new s(this,t,e);return n.jqDeferred.promise(f(this))}),a.prototype=new e,a.prototype.check=function(){var t=h[this.img.src]||new u(this.img.src);if(t.isConfirmed)return void this.confirm(t.isLoaded,"cached was confirmed");if(this.img.complete&&void 0!==this.img.naturalWidth)return void this.confirm(0!==this.img.naturalWidth,"naturalWidth");var e=this;t.on("confirm",function(t,n){return e.confirm(t.isLoaded,n),!0}),t.check()},a.prototype.confirm=function(t,e){this.isLoaded=t,this.emit("confirm",this,e)};var h={};return u.prototype=new e,u.prototype.check=function(){if(!this.isChecked){var t=new Image;n.bind(t,"load",this),n.bind(t,"error",this),t.src=this.src,this.isChecked=!0}},u.prototype.handleEvent=function(t){var e="on"+t.type;this[e]&&this[e](t)},u.prototype.onload=function(t){this.confirm(!0,"onload"),this.unbindProxyEvents(t)},u.prototype.onerror=function(t){this.confirm(!1,"onerror"),this.unbindProxyEvents(t)},u.prototype.confirm=function(t,e){this.isConfirmed=!0,this.isLoaded=t,this.emit("confirm",this,e)},u.prototype.unbindProxyEvents=function(t){n.unbind(t.target,"load",this),n.unbind(t.target,"error",this)},s}),function($){"use strict";function t(t,e,n,i,r){var o={url:spuvar.ajax_url,data:t,cache:!1,type:"POST",dataType:"json",timeout:3e4},r=r||!1,n=n||!1,i=i||!1;e&&(o.url=e),n&&(o.success=n),i&&(o.error=i),r&&(o.dataType=r),$.ajax(o)}function e(t,e,n){if(n){var i=new Date;i.setTime(i.getTime()+24*n*60*60*1e3);var r="; expires="+i.toGMTString()}else var r="";document.cookie=t+"="+e+r+"; path=/"}function n(t){for(var e=t+"=",n=document.cookie.split(";"),i=0;i<n.length;i++){for(var r=n[i];" "==r.charAt(0);)r=r.substring(1,r.length);if(0==r.indexOf(e))return r.substring(e.length,r.length)}return null}function i(){try{FB.Event.subscribe("edge.create",function(t,e){var n=$(e).parents(".spu-box").data("box-id");n&&SPU.hide(n,!1,!0)})}catch(t){}h=!0,clearInterval(l)}function r(t){var e=$(t.target).parents(".spu-box").data("box-id");e&&SPU.hide(e,!1,!0)}function o(t){if("on"==t.state){var e=jQuery(".spu-gogl").data("box-id");e&&SPU.hide(e,!1,!0)}}function s(t){if("confirm"==t.type){var e=jQuery(".spu-gogl").data("box-id");e&&SPU.hide(e,!1,!0)}}function a(){if(spuvar_social.facebook)try{FB.XFBML.parse()}catch(t){}if(spuvar_social.google)try{gapi.plusone.go()}catch(t){}if(spuvar_social.twitter)try{twttr.widgets.load()}catch(t){}}function u(){$(".spu-box form").each(function(){var t=$(this).attr("action");t&&$(this).attr("action",t.replace("?spu_action=spu_load",""))}),$.fn.wpcf7InitForm&&$(".spu-box div.wpcf7 > form").wpcf7InitForm()}var f=function(){function i(t){var e=c[t],n=$(window).width(),i=$(window).height(),r=e.outerHeight(),o=e.outerWidth(),s=e.data("width"),a=0,u=i/2-r/2,f="fixed",d=$(document).scrollTop();e.hasClass("spu-centered")&&(n>s&&(a=n/2-o/2),e.css({left:a,position:f,top:u})),r+50>i&&(f="absolute",u=d,e.css({position:f,top:u,bottom:"auto"}))}function r(t){var e=$(t).find(".spu-facebook");if(e.length){var n=e.find(".fb-like > span").width();if(0==n){var i=e.find(".fb-like").data("layout");"box_count"==i?e.append('<style type="text/css"> #'+$(t).attr("id")+" .fb-like iframe, #"+$(t).attr("id")+" .fb_iframe_widget span, #"+$(t).attr("id")+" .fb_iframe_widget{ height: 63px !important;width: 80px !important;}</style>"):e.append('<style type="text/css"> #'+$(t).attr("id")+" .fb-like iframe, #"+$(t).attr("id")+" .fb_iframe_widget span, #"+$(t).attr("id")+" .fb_iframe_widget{ height: 20px !important;width: 80px !important;}</style>")}}}function o(t){var e=t,n=e.data("total");if(n){a();var i=0,r=0,o=e.outerWidth(),s=e.find(".spu-content").width();!spuvar.disable_style&&$(window).width()>o&&(e.find(".spu-shortcode").wrapAll('<div class="spu_shortcodes"/>'),e.find(".spu-shortcode").each(function(){i+=$(this).outerWidth()}),r=s-i-20*n),r>0&&(e.find(".spu-shortcode").each(function(){$(this).css("margin-left",r/2)}),2==n?e.find(".spu-shortcode").last().css("margin-left",0):3==n&&e.find(".spu-shortcode").first().css("margin-left",0))}}function s(t,n,r){var s=c[t],a=$("#spu-bg-"+t),u=s.data("bgopa");if(s.is(":animated"))return!1;if(n===!0&&s.is(":visible")||n===!1&&s.is(":hidden"))return!1;if(n===!1){var f=parseInt(s.data("cookie"));f>0&&e("spu_box_"+t,!0,f),s.trigger("spu.box_close",[t])}else setTimeout(function(){o(s)},1500),s.trigger("spu.box_open",[t]),$(window).resize(function(){i(t)}),i(t);var d=s.data("spuanimation"),p=s.data("close-on-conversion");return"fade"===d?n===!0?s.fadeIn("slow"):n===!1&&(p&&r||!r)&&s.fadeOut("slow"):n===!0?s.slideDown("slow"):n===!1&&(p&&r||!r)&&s.slideUp("slow"),n===!0&&u>0?a.fadeIn():n===!1&&(p&&r||!r)&&a.fadeOut(),n}var u=$(window).height(),f=spuvar.is_admin,c=[];return $(".spu-content").children().first().css({"margin-top":0,"padding-top":0}).end().last().css({"margin-bottom":0,"padding-bottom":0}),$(".spu-box").each(function(){spuvar.safe_mode&&$(this).prependTo("body");var e=$(this),i=e.data("trigger"),o=0,a=1===parseInt(e.data("test-mode")),d=e.data("box-id"),p=1===parseInt(e.data("auto-hide")),h=parseInt(e.data("seconds-close")),l=parseInt(e.data("trigger-number"),10),m="percentage"==i?parseInt(e.data("trigger-number"),10)/100:.8,v=m*$(document).height();r(e),e.on("click",'a:not(".spu-close-popup, .flp_wrapper a, .spu-not-close")',function(){s(d,!1,!0)}),$(document).keyup(function(t){27==t.keyCode&&s(d,!1,!1)});var g=navigator.userAgent,w=g.match(/iPad/i)||g.match(/iPhone/i)?"touchstart":"click";$("body").on(w,function(t){void 0!==t.originalEvent&&s(d,!1,!1)}),$("body").on(w,".spu-box,.spu-clickable",function(t){t.stopPropagation()}),e.hide().css("left",""),c[d]=e;var y=function(){o&&clearTimeout(o),o=window.setTimeout(function(){var t=$(window).scrollTop(),e=t+u>=v;e?(p||$(window).unbind("scroll",y),s(d,!0,!1)):s(d,!1,!1)},100)},b=function(){o&&clearTimeout(o),o=window.setTimeout(function(){s(d,!0,!1)},1e3*l)},_=n("spu_box_"+d);if((void 0==_||""==_||f&&a)&&("seconds"==i&&b(),"percentage"==i&&($(window).bind("scroll",y),y()),window.location.hash&&window.location.hash.length>0)){var x=window.location.hash,E;x.substring(1)===e.attr("id")&&setTimeout(function(){s(d,!0,!1)},100)}e.on("click",".spu-close-popup",function(){s(d,!1,!1),"percentage"==i&&$(window).unbind("scroll",y)}),$('a[href="#spu-'+d+'"]').on("click",function(t){t.preventDefault(),s(d,!0,!1)}).css("cursor","pointer").addClass("spu-clickable"),e.find(".gform_wrapper form").addClass("gravity-form"),e.find(".mc4wp-form form").addClass("mc4wp-form"),e.find(".newsletter form").addClass("newsletter-form");var L=e.find("form");if(L.length){if(!L.is(".newsletter-form, .wpcf7-form, .gravity-form, .infusion-form, .widget_wysija, .ninja-forms-form")){var j=L.attr("action"),k=new RegExp(spuvar.site_url,"i");j&&j.length&&(k.test(j)||L.addClass("spu-disable-ajax"))}$(".spu-disable-ajax form").length&&$(".spu-disable-ajax form").addClass("spu-disable-ajax"),e.on("submit",'form.spu-disable-ajax:not(".flp_form")',function(){e.trigger("spu.form_submitted",[d]),s(d,!1,!0)}),e.on("submit",'form:not(".newsletter-form, .wpcf7-form, .gravity-form, .infusion-form, .spu-disable-ajax, .widget_wysija, .ninja-forms-form, .flp_form, .mc4wp-form")',function(n){n.preventDefault();var i=!0,r=$(this),o=r.serialize(),a=r.attr("action"),u=function(t,e,n){console.log("Spu Form error: "+e+" - "+n)},f=function(t){var e=$(t).filter("#spu-"+d).html();$("#spu-"+d).html(e),$("#spu-"+d).find(".mc4wp-form-error").length||setTimeout(function(){s(d,!1,!0)},1e3*spuvar.seconds_confirmation_close)};return t(o,a,f,u,"html"),e.trigger("spu.form_submitted",[d]),i}),$("body").on("mailsent.wpcf7",function(){e.trigger("spu.form_submitted",[d]),s(d,!1,!0)}),$(document).on("gform_confirmation_loaded",function(){e.trigger("spu.form_submitted",[d]),s(d,!1,!0)}),e.on("submit",".infusion-form",function(t){t.preventDefault(),e.trigger("spu.form_submitted",[d]),s(d,!1,!0),this.submit()}),e.on("submit",".newsletter-form",function(t){t.preventDefault(),e.trigger("spu.form_submitted",[d]),s(d,!1,!0),this.submit()}),$("body").on("submitResponse.default",function(){e.trigger("spu.form_submitted",[d]),s(d,!1,!0)})}}),{show:function(t){return s(t,!0,!1)},hide:function(t,e,n){return s(t,!1,n)},request:function(e,n,i,r){return t(e,n,i,r)}}};if(spuvar.ajax_mode){var c={pid:spuvar.pid,referrer:document.referrer,is_category:spuvar.is_category,is_archive:spuvar.is_archive},d=function(t){$("body").append(t),$(".spu-box").imagesLoaded(function(){window.SPU=f(),u()})},p=function(t,e,n){console.log("Problem loading popups - error: "+e+" - "+n)};t(c,spuvar.ajax_mode_url,d,p,"html")}else $(".spu-box").imagesLoaded(function(){window.SPU=f()});var h=!1,l=setInterval(function(){"undefined"==typeof FB||h||i()},1e3);if("undefined"!=typeof twttr)try{twttr.ready(function(t){t.events.bind("tweet",r),t.events.bind("follow",r)})}catch(m){}}(jQuery);
1
+ (function(){function t(){}function e(t,e){for(var n=t.length;n--;)if(t[n].listener===e)return n;return-1}function n(t){return function(){return this[t].apply(this,arguments)}}var i=t.prototype,r=this,o=r.EventEmitter;i.getListeners=function(t){var e,n,i=this._getEvents();if("object"==typeof t){e={};for(n in i)i.hasOwnProperty(n)&&t.test(n)&&(e[n]=i[n])}else e=i[t]||(i[t]=[]);return e},i.flattenListeners=function(t){var e,n=[];for(e=0;t.length>e;e+=1)n.push(t[e].listener);return n},i.getListenersAsObject=function(t){var e,n=this.getListeners(t);return n instanceof Array&&(e={},e[t]=n),e||n},i.addListener=function(t,n){var i,r=this.getListenersAsObject(t),o="object"==typeof n;for(i in r)r.hasOwnProperty(i)&&-1===e(r[i],n)&&r[i].push(o?n:{listener:n,once:!1});return this},i.on=n("addListener"),i.addOnceListener=function(t,e){return this.addListener(t,{listener:e,once:!0})},i.once=n("addOnceListener"),i.defineEvent=function(t){return this.getListeners(t),this},i.defineEvents=function(t){for(var e=0;t.length>e;e+=1)this.defineEvent(t[e]);return this},i.removeListener=function(t,n){var i,r,o=this.getListenersAsObject(t);for(r in o)o.hasOwnProperty(r)&&(i=e(o[r],n),-1!==i&&o[r].splice(i,1));return this},i.off=n("removeListener"),i.addListeners=function(t,e){return this.manipulateListeners(!1,t,e)},i.removeListeners=function(t,e){return this.manipulateListeners(!0,t,e)},i.manipulateListeners=function(t,e,n){var i,r,o=t?this.removeListener:this.addListener,s=t?this.removeListeners:this.addListeners;if("object"!=typeof e||e instanceof RegExp)for(i=n.length;i--;)o.call(this,e,n[i]);else for(i in e)e.hasOwnProperty(i)&&(r=e[i])&&("function"==typeof r?o.call(this,i,r):s.call(this,i,r));return this},i.removeEvent=function(t){var e,n=typeof t,i=this._getEvents();if("string"===n)delete i[t];else if("object"===n)for(e in i)i.hasOwnProperty(e)&&t.test(e)&&delete i[e];else delete this._events;return this},i.removeAllListeners=n("removeEvent"),i.emitEvent=function(t,e){var n,i,r,o,s=this.getListenersAsObject(t);for(r in s)if(s.hasOwnProperty(r))for(i=s[r].length;i--;)n=s[r][i],n.once===!0&&this.removeListener(t,n.listener),o=n.listener.apply(this,e||[]),o===this._getOnceReturnValue()&&this.removeListener(t,n.listener);return this},i.trigger=n("emitEvent"),i.emit=function(t){var e=Array.prototype.slice.call(arguments,1);return this.emitEvent(t,e)},i.setOnceReturnValue=function(t){return this._onceReturnValue=t,this},i._getOnceReturnValue=function(){return this.hasOwnProperty("_onceReturnValue")?this._onceReturnValue:!0},i._getEvents=function(){return this._events||(this._events={})},t.noConflict=function(){return r.EventEmitter=o,t},"function"==typeof define&&define.amd?define("eventEmitter/EventEmitter",[],function(){return t}):"object"==typeof module&&module.exports?module.exports=t:this.EventEmitter=t}).call(this),function(t){function e(e){var n=t.event;return n.target=n.target||n.srcElement||e,n}var n=document.documentElement,i=function(){};n.addEventListener?i=function(t,e,n){t.addEventListener(e,n,!1)}:n.attachEvent&&(i=function(t,n,i){t[n+i]=i.handleEvent?function(){var n=e(t);i.handleEvent.call(i,n)}:function(){var n=e(t);i.call(t,n)},t.attachEvent("on"+n,t[n+i])});var r=function(){};n.removeEventListener?r=function(t,e,n){t.removeEventListener(e,n,!1)}:n.detachEvent&&(r=function(t,e,n){t.detachEvent("on"+e,t[e+n]);try{delete t[e+n]}catch(i){t[e+n]=void 0}});var o={bind:i,unbind:r};"function"==typeof define&&define.amd?define("eventie/eventie",o):t.eventie=o}(this),function(t,e){"function"==typeof define&&define.amd?define(["eventEmitter/EventEmitter","eventie/eventie"],function(n,i){return e(t,n,i)}):"object"==typeof exports?module.exports=e(t,require("wolfy87-eventemitter"),require("eventie")):t.imagesLoaded=e(t,t.EventEmitter,t.eventie)}(window,function(t,e,n){function i(t,e){for(var n in e)t[n]=e[n];return t}function r(t){return"[object Array]"===p.call(t)}function o(t){var e=[];if(r(t))e=t;else if("number"==typeof t.length)for(var n=0,i=t.length;i>n;n++)e.push(t[n]);else e.push(t);return e}function s(t,e,n){if(!(this instanceof s))return new s(t,e);"string"==typeof t&&(t=document.querySelectorAll(t)),this.elements=o(t),this.options=i({},this.options),"function"==typeof e?n=e:i(this.options,e),n&&this.on("always",n),this.getImages(),f&&(this.jqDeferred=new f.Deferred);var r=this;setTimeout(function(){r.check()})}function a(t){this.img=t}function u(t){this.src=t,l[t]=this}var f=t.jQuery,c=t.console,d=void 0!==c,p=Object.prototype.toString;s.prototype=new e,s.prototype.options={},s.prototype.getImages=function(){this.images=[];for(var t=0,e=this.elements.length;e>t;t++){var n=this.elements[t];"IMG"===n.nodeName&&this.addImage(n);var i=n.nodeType;if(i&&(1===i||9===i||11===i))for(var r=n.querySelectorAll("img"),o=0,s=r.length;s>o;o++){var a=r[o];this.addImage(a)}}},s.prototype.addImage=function(t){var e=new a(t);this.images.push(e)},s.prototype.check=function(){function t(t,r){return e.options.debug&&d&&c.log("confirm",t,r),e.progress(t),n++,n===i&&e.complete(),!0}var e=this,n=0,i=this.images.length;if(this.hasAnyBroken=!1,!i)return void this.complete();for(var r=0;i>r;r++){var o=this.images[r];o.on("confirm",t),o.check()}},s.prototype.progress=function(t){this.hasAnyBroken=this.hasAnyBroken||!t.isLoaded;var e=this;setTimeout(function(){e.emit("progress",e,t),e.jqDeferred&&e.jqDeferred.notify&&e.jqDeferred.notify(e,t)})},s.prototype.complete=function(){var t=this.hasAnyBroken?"fail":"done";this.isComplete=!0;var e=this;setTimeout(function(){if(e.emit(t,e),e.emit("always",e),e.jqDeferred){var n=e.hasAnyBroken?"reject":"resolve";e.jqDeferred[n](e)}})},f&&(f.fn.imagesLoaded=function(t,e){var n=new s(this,t,e);return n.jqDeferred.promise(f(this))}),a.prototype=new e,a.prototype.check=function(){var t=l[this.img.src]||new u(this.img.src);if(t.isConfirmed)return void this.confirm(t.isLoaded,"cached was confirmed");if(this.img.complete&&void 0!==this.img.naturalWidth)return void this.confirm(0!==this.img.naturalWidth,"naturalWidth");var e=this;t.on("confirm",function(t,n){return e.confirm(t.isLoaded,n),!0}),t.check()},a.prototype.confirm=function(t,e){this.isLoaded=t,this.emit("confirm",this,e)};var l={};return u.prototype=new e,u.prototype.check=function(){if(!this.isChecked){var t=new Image;n.bind(t,"load",this),n.bind(t,"error",this),t.src=this.src,this.isChecked=!0}},u.prototype.handleEvent=function(t){var e="on"+t.type;this[e]&&this[e](t)},u.prototype.onload=function(t){this.confirm(!0,"onload"),this.unbindProxyEvents(t)},u.prototype.onerror=function(t){this.confirm(!1,"onerror"),this.unbindProxyEvents(t)},u.prototype.confirm=function(t,e){this.isConfirmed=!0,this.isLoaded=t,this.emit("confirm",this,e)},u.prototype.unbindProxyEvents=function(t){n.unbind(t.target,"load",this),n.unbind(t.target,"error",this)},s}),function($){"use strict";function t(t,e,n,i,r){var o={url:spuvar.ajax_url,data:t,cache:!1,type:"POST",dataType:"json",timeout:3e4},r=r||!1,n=n||!1,i=i||!1;e&&(o.url=e),n&&(o.success=n),i&&(o.error=i),r&&(o.dataType=r),$.ajax(o)}function e(t,e,n){if(n){var i=new Date;i.setTime(i.getTime()+24*n*60*60*1e3);var r="; expires="+i.toGMTString()}else var r="";document.cookie=t+"="+e+r+"; path=/"}function n(t){for(var e=t+"=",n=document.cookie.split(";"),i=0;i<n.length;i++){for(var r=n[i];" "==r.charAt(0);)r=r.substring(1,r.length);if(0==r.indexOf(e))return r.substring(e.length,r.length)}return null}function i(){try{FB.Event.subscribe("edge.create",function(t,e){var n=$(e).parents(".spu-box").data("box-id");n&&SPU.hide(n,!1,!0)})}catch(t){}l=!0,clearInterval(h)}function r(t){var e=$(t.target).parents(".spu-box").data("box-id");e&&SPU.hide(e,!1,!0)}function o(t){if("on"==t.state){var e=jQuery(".spu-gogl").data("box-id");e&&SPU.hide(e,!1,!0)}}function s(t){if("confirm"==t.type){var e=jQuery(".spu-gogl").data("box-id");e&&SPU.hide(e,!1,!0)}}function a(){if("undefined"!=typeof spuvar_social.facebook&&spuvar_social.facebook)try{FB.XFBML.parse()}catch(t){}if("undefined"!=typeof spuvar_social.google&&spuvar_social.google)try{gapi.plusone.go()}catch(t){}if("undefined"!=typeof spuvar_social.twitter&&spuvar_social.twitter)try{twttr.widgets.load()}catch(t){}}function u(){$(".spu-box form").each(function(){var t=$(this).attr("action");t&&$(this).attr("action",t.replace("?spu_action=spu_load",""))}),$.fn.wpcf7InitForm&&$(".spu-box div.wpcf7 > form").wpcf7InitForm()}var f=function(){function i(t){var e=c[t],n=$(window).width(),i=$(window).height(),r=e.outerHeight(),o=e.outerWidth(),s=e.data("width"),a=0,u=i/2-r/2,f="fixed",d=$(document).scrollTop();e.hasClass("spu-centered")&&(n>s&&(a=n/2-o/2),e.css({left:a,position:f,top:u})),r+50>i&&(f="absolute",u=d,e.css({position:f,top:u,bottom:"auto"}))}function r(t){var e=$(t).find(".spu-facebook");if(e.length){var n=e.find(".fb-like > span").width();if(0==n){var i=e.find(".fb-like").data("layout");"box_count"==i?e.append('<style type="text/css"> #'+$(t).attr("id")+" .fb-like iframe, #"+$(t).attr("id")+" .fb_iframe_widget span, #"+$(t).attr("id")+" .fb_iframe_widget{ height: 63px !important;width: 80px !important;}</style>"):"button_count"==i?e.append('<style type="text/css"> #'+$(t).attr("id")+" .fb-like iframe, #"+$(t).attr("id")+" .fb_iframe_widget span, #"+$(t).attr("id")+" .fb_iframe_widget{ height: 20px !important;min-width: 120px !important;}</style>"):e.append('<style type="text/css"> #'+$(t).attr("id")+" .fb-like iframe, #"+$(t).attr("id")+" .fb_iframe_widget span, #"+$(t).attr("id")+" .fb_iframe_widget{ height: 20px !important;width: 80px !important;}</style>")}}}function o(t){var e=t,n=e.data("total");if(n){a();var i=0,r=0,o=e.outerWidth(),s=e.find(".spu-content").width();!spuvar.disable_style&&$(window).width()>o&&(e.find(".spu-shortcode").wrapAll('<div class="spu_shortcodes"/>'),e.find(".spu-shortcode").each(function(){i+=$(this).outerWidth()}),r=s-i-20*n),r>0&&(e.find(".spu-shortcode").each(function(){$(this).css("margin-left",r/2)}),2==n?e.find(".spu-shortcode").last().css("margin-left",0):3==n&&e.find(".spu-shortcode").first().css("margin-left",0))}}function s(t,n,r){var s=c[t],a=$("#spu-bg-"+t),u=s.data("bgopa");if(s.is(":animated"))return!1;if(n===!0&&s.is(":visible")||n===!1&&s.is(":hidden"))return!1;if(n===!1){var f=parseInt(s.data("cookie"));f>0&&e("spu_box_"+t,!0,f),s.trigger("spu.box_close",[t])}else setTimeout(function(){o(s)},1500),s.trigger("spu.box_open",[t]),$(window).resize(function(){i(t)}),i(t);var d=s.data("spuanimation"),p=s.data("close-on-conversion");return"fade"===d?n===!0?s.fadeIn("slow"):n===!1&&(p&&r||!r)&&s.fadeOut("slow"):n===!0?s.slideDown("slow"):n===!1&&(p&&r||!r)&&s.slideUp("slow"),n===!0&&u>0?a.fadeIn():n===!1&&(p&&r||!r)&&a.fadeOut(),n}var u=$(window).height(),f=spuvar.is_admin,c=[];return $(".spu-content").children().first().css({"margin-top":0,"padding-top":0}).end().last().css({"margin-bottom":0,"padding-bottom":0}),$(".spu-box").each(function(){spuvar.safe_mode&&$(this).prependTo("body");var e=$(this),i=e.data("trigger"),o=0,a=1===parseInt(e.data("test-mode")),d=e.data("box-id"),p=1===parseInt(e.data("auto-hide")),l=parseInt(e.data("seconds-close")),h=parseInt(e.data("trigger-number"),10),m="percentage"==i?parseInt(e.data("trigger-number"),10)/100:.8,v=m*$(document).height();r(e),e.on("click",'a:not(".spu-close-popup, .flp_wrapper a, .spu-not-close")',function(){s(d,!1,!0)}),$(document).keyup(function(t){27==t.keyCode&&s(d,!1,!1)});var g=navigator.userAgent,y=g.match(/iPad/i)||g.match(/iPhone/i)?"touchstart":"click";$("body").on(y,function(t){void 0!==t.originalEvent&&s(d,!1,!1)}),$("body").on(y,".spu-box,.spu-clickable",function(t){t.stopPropagation()}),e.hide().css("left",""),c[d]=e;var w=function(){o&&clearTimeout(o),o=window.setTimeout(function(){var t=$(window).scrollTop(),e=t+u>=v;e?(p||$(window).unbind("scroll",w),s(d,!0,!1)):s(d,!1,!1)},100)},b=function(){o&&clearTimeout(o),o=window.setTimeout(function(){s(d,!0,!1)},1e3*h)},_=n("spu_box_"+d);if((void 0==_||""==_||f&&a)&&("seconds"==i&&b(),"percentage"==i&&($(window).bind("scroll",w),w()),window.location.hash&&window.location.hash.length>0)){var x=window.location.hash,E;x.substring(1)===e.attr("id")&&setTimeout(function(){s(d,!0,!1)},100)}e.on("click",".spu-close-popup",function(){s(d,!1,!1),"percentage"==i&&$(window).unbind("scroll",w)}),$('a[href="#spu-'+d+'"]').on("click",function(t){t.preventDefault(),s(d,!0,!1)}).css("cursor","pointer").addClass("spu-clickable"),e.find(".gform_wrapper form").addClass("gravity-form"),e.find(".mc4wp-form form").addClass("mc4wp-form"),e.find(".newsletter form").addClass("newsletter-form");var L=e.find("form");if(L.length){if(!L.is(".newsletter-form, .wpcf7-form, .gravity-form, .infusion-form, .widget_wysija, .ninja-forms-form")){var j=L.attr("action"),k=new RegExp(spuvar.site_url,"i");j&&j.length&&(k.test(j)||L.addClass("spu-disable-ajax"))}$(".spu-disable-ajax form").length&&$(".spu-disable-ajax form").addClass("spu-disable-ajax"),e.on("submit",'form.spu-disable-ajax:not(".flp_form")',function(){e.trigger("spu.form_submitted",[d]),s(d,!1,!0)}),e.on("submit",'form:not(".newsletter-form, .wpcf7-form, .gravity-form, .infusion-form, .spu-disable-ajax, .widget_wysija, .ninja-forms-form, .flp_form, .mc4wp-form")',function(n){n.preventDefault();var i=!0,r=$(this),o=r.serialize(),a=r.attr("action"),u=function(t,e,n){console.log("Spu Form error: "+e+" - "+n)},f=function(t){var e=$(t).filter("#spu-"+d).html();$("#spu-"+d).html(e),$("#spu-"+d).find(".mc4wp-form-error").length||setTimeout(function(){s(d,!1,!0)},1e3*spuvar.seconds_confirmation_close)};return t(o,a,f,u,"html"),e.trigger("spu.form_submitted",[d]),i}),$("body").on("mailsent.wpcf7",function(){e.trigger("spu.form_submitted",[d]),s(d,!1,!0)}),$(document).on("gform_confirmation_loaded",function(){e.trigger("spu.form_submitted",[d]),s(d,!1,!0)}),e.on("submit",".infusion-form",function(t){t.preventDefault(),e.trigger("spu.form_submitted",[d]),s(d,!1,!0),this.submit()}),e.on("submit",".newsletter-form",function(t){t.preventDefault(),e.trigger("spu.form_submitted",[d]),s(d,!1,!0),this.submit()}),$("body").on("submitResponse.default",function(){e.trigger("spu.form_submitted",[d]),s(d,!1,!0)})}}),{show:function(t){return s(t,!0,!1)},hide:function(t,e,n){return s(t,!1,n)},request:function(e,n,i,r){return t(e,n,i,r)}}};if(spuvar.ajax_mode){var c={pid:spuvar.pid,referrer:document.referrer,is_category:spuvar.is_category,is_archive:spuvar.is_archive},d=function(t){$("body").append(t),$(".spu-box").imagesLoaded(function(){window.SPU=f(),u()})},p=function(t,e,n){console.log("Problem loading popups - error: "+e+" - "+n)};t(c,spuvar.ajax_mode_url,d,p,"html")}else $(".spu-box").imagesLoaded(function(){window.SPU=f()});var l=!1,h=setInterval(function(){"undefined"==typeof FB||l||i()},1e3);if("undefined"!=typeof twttr)try{twttr.ready(function(t){t.events.bind("tweet",r),t.events.bind("follow",r)})}catch(m){}}(jQuery);
public/assets/js/public.js CHANGED
@@ -327,6 +327,10 @@ var SPU_master = function() {
327
 
328
  $fbbox.append('<style type="text/css"> #'+$(box).attr('id')+' .fb-like iframe, #'+$(box).attr('id')+' .fb_iframe_widget span, #'+$(box).attr('id')+' .fb_iframe_widget{ height: 63px !important;width: 80px !important;}</style>');
329
 
 
 
 
 
330
  } else {
331
 
332
  $fbbox.append('<style type="text/css"> #'+$(box).attr('id')+' .fb-like iframe, #'+$(box).attr('id')+' .fb_iframe_widget span, #'+$(box).attr('id')+' .fb_iframe_widget{ height: 20px !important;width: 80px !important;}</style>');
@@ -625,20 +629,20 @@ function closeGoogle(a){
625
  }
626
  }
627
  function SPU_reload_socials(){
628
- if( spuvar_social.facebook ) {
629
 
630
  // reload fb
631
  try{
632
  FB.XFBML.parse();
633
  }catch(ex){}
634
  }
635
- if( spuvar_social.google ){
636
  try {
637
  // reload google
638
  gapi.plusone.go();
639
  }catch(ex){}
640
  }
641
- if( spuvar_social.twitter ){
642
  try {
643
  //reload twitter
644
  twttr.widgets.load();
327
 
328
  $fbbox.append('<style type="text/css"> #'+$(box).attr('id')+' .fb-like iframe, #'+$(box).attr('id')+' .fb_iframe_widget span, #'+$(box).attr('id')+' .fb_iframe_widget{ height: 63px !important;width: 80px !important;}</style>');
329
 
330
+ } else if( $fblayout == 'button_count' ) {
331
+
332
+ $fbbox.append('<style type="text/css"> #'+$(box).attr('id')+' .fb-like iframe, #'+$(box).attr('id')+' .fb_iframe_widget span, #'+$(box).attr('id')+' .fb_iframe_widget{ height: 20px !important;min-width: 120px !important;}</style>');
333
+
334
  } else {
335
 
336
  $fbbox.append('<style type="text/css"> #'+$(box).attr('id')+' .fb-like iframe, #'+$(box).attr('id')+' .fb_iframe_widget span, #'+$(box).attr('id')+' .fb_iframe_widget{ height: 20px !important;width: 80px !important;}</style>');
629
  }
630
  }
631
  function SPU_reload_socials(){
632
+ if( typeof spuvar_social.facebook != 'undefined' && spuvar_social.facebook) {
633
 
634
  // reload fb
635
  try{
636
  FB.XFBML.parse();
637
  }catch(ex){}
638
  }
639
+ if( typeof spuvar_social.google != 'undefined' && spuvar_social.google){
640
  try {
641
  // reload google
642
  gapi.plusone.go();
643
  }catch(ex){}
644
  }
645
+ if( typeof spuvar_social.twitter != 'undefined' && spuvar_social.twitter ) {
646
  try {
647
  //reload twitter
648
  twttr.widgets.load();
public/class-social-popup.php CHANGED
@@ -421,7 +421,7 @@ class SocialPopup {
421
  wp_enqueue_style('spu-public-css');
422
  wp_localize_script( $handle, 'spuvar',
423
  array(
424
- 'is_admin' => current_user_can( 'administrator' ),
425
  'disable_style' => isset( $this->spu_settings['shortcodes_style'] ) ? esc_attr( $this->spu_settings['shortcodes_style'] ) : '',
426
  'safe_mode' => isset( $this->spu_settings['safe'] ) ? esc_attr( $this->spu_settings['safe'] ) : '',
427
  'ajax_mode' => isset( $this->spu_settings['ajax_mode'] ) ? esc_attr( $this->spu_settings['ajax_mode'] ) :'',
@@ -503,7 +503,7 @@ class SocialPopup {
503
  function facebook_shortcode( $atts, $content ) {
504
 
505
  extract( shortcode_atts( array(
506
- 'href' => 'https://www.facebook.com/pages/Timersys/146687622031640',
507
  'layout' => 'button_count', // standard, box_count, button_count, button
508
  'show_faces' => 'false', // true
509
  'share' => 'false', // true
@@ -539,8 +539,8 @@ class SocialPopup {
539
  function facebook_page_shortcode( $atts, $content ) {
540
 
541
  extract( shortcode_atts( array(
542
- 'href' => 'https://www.facebook.com/pages/Timersys/146687622031640',
543
- 'name' => 'Timersys',
544
  'show_faces' => 'true', // false
545
  'hide_cover' => 'false', // true
546
  'width' => '500',
@@ -559,7 +559,7 @@ class SocialPopup {
559
  function twitter_shortcode( $atts, $content ) {
560
 
561
  extract( shortcode_atts( array(
562
- 'user' => 'chifliiiii',
563
  'show_count' => 'true', // false
564
  'size' => '', // large
565
  'lang' => '',
@@ -579,7 +579,7 @@ class SocialPopup {
579
  extract( shortcode_atts( array(
580
  'size' => 'medium', //small standard tall
581
  'annotation' => 'bubble', //inline none
582
- 'url' => 'https://plus.google.com/u/0/103508783120806246698/posts', //inline none
583
  ), $atts ) );
584
 
585
  $size = strtolower( trim( $size ) );
421
  wp_enqueue_style('spu-public-css');
422
  wp_localize_script( $handle, 'spuvar',
423
  array(
424
+ 'is_admin' => current_user_can( apply_filters( 'spu/capabilities/testmode', 'administrator' ) ),
425
  'disable_style' => isset( $this->spu_settings['shortcodes_style'] ) ? esc_attr( $this->spu_settings['shortcodes_style'] ) : '',
426
  'safe_mode' => isset( $this->spu_settings['safe'] ) ? esc_attr( $this->spu_settings['safe'] ) : '',
427
  'ajax_mode' => isset( $this->spu_settings['ajax_mode'] ) ? esc_attr( $this->spu_settings['ajax_mode'] ) :'',
503
  function facebook_shortcode( $atts, $content ) {
504
 
505
  extract( shortcode_atts( array(
506
+ 'href' => apply_filters( 'spu/social/fb_href', 'https://www.facebook.com/pages/Timersys/146687622031640' ),
507
  'layout' => 'button_count', // standard, box_count, button_count, button
508
  'show_faces' => 'false', // true
509
  'share' => 'false', // true
539
  function facebook_page_shortcode( $atts, $content ) {
540
 
541
  extract( shortcode_atts( array(
542
+ 'href' => apply_filters( 'spu/social/fb_href', 'https://www.facebook.com/pages/Timersys/146687622031640' ),
543
+ 'name' => apply_filters( 'spu/social/fb_name', 'Timersys' ),
544
  'show_faces' => 'true', // false
545
  'hide_cover' => 'false', // true
546
  'width' => '500',
559
  function twitter_shortcode( $atts, $content ) {
560
 
561
  extract( shortcode_atts( array(
562
+ 'user' => apply_filters( 'spu/social/tw_user', 'chifliiiii' ),
563
  'show_count' => 'true', // false
564
  'size' => '', // large
565
  'lang' => '',
579
  extract( shortcode_atts( array(
580
  'size' => 'medium', //small standard tall
581
  'annotation' => 'bubble', //inline none
582
+ 'url' => apply_filters( 'spu/social/gp_url', 'https://plus.google.com/u/0/103508783120806246698/posts' ),
583
  ), $atts ) );
584
 
585
  $size = strtolower( trim( $size ) );
public/includes/Mobile_Detect.php CHANGED
@@ -8,7 +8,9 @@
8
  * Mobile_Detect is a lightweight PHP class for detecting mobile devices (including tablets).
9
  * It uses the User-Agent string combined with specific HTTP headers to detect the mobile environment.
10
  *
11
- * @author Current authors: Serban Ghita <serbanghita@gmail.com>, Nick Ilyin <nick.ilyin@gmail.com>
 
 
12
  * Original author: Victor Stanciu <vic.stanciu@gmail.com>
13
  *
14
  * @license Code and contributions have 'MIT License'
@@ -20,99 +22,126 @@
20
  * README: https://github.com/serbanghita/Mobile-Detect/blob/master/README.md
21
  * HOWTO: https://github.com/serbanghita/Mobile-Detect/wiki/Code-examples
22
  *
23
- * @version 2.8.4
24
  */
25
-
26
- class Mobile_Detect
27
- {
28
- /**
29
- * Mobile detection type.
30
- *
31
- * @deprecated since version 2.6.9
32
- */
33
- const DETECTION_TYPE_MOBILE = 'mobile';
34
-
35
- /**
36
- * Extended detection type.
37
- *
38
- * @deprecated since version 2.6.9
39
- */
40
- const DETECTION_TYPE_EXTENDED = 'extended';
41
-
42
- /**
43
- * A frequently used regular expression to extract version #s.
44
- *
45
- * @deprecated since version 2.6.9
46
- */
47
- const VER = '([\w._\+]+)';
48
-
49
- /**
50
- * Top-level device.
51
- */
52
- const MOBILE_GRADE_A = 'A';
53
-
54
- /**
55
- * Mid-level device.
56
- */
57
- const MOBILE_GRADE_B = 'B';
58
-
59
- /**
60
- * Low-level device.
61
- */
62
- const MOBILE_GRADE_C = 'C';
63
-
64
- /**
65
- * Stores the version number of the current release.
66
- */
67
- const VERSION = '2.8.4';
68
-
69
- /**
70
- * A type for the version() method indicating a string return value.
71
- */
72
- const VERSION_TYPE_STRING = 'text';
73
-
74
- /**
75
- * A type for the version() method indicating a float return value.
76
- */
77
- const VERSION_TYPE_FLOAT = 'float';
78
-
79
- /**
80
- * The User-Agent HTTP header is stored in here.
81
- * @var string
82
- */
83
- protected $userAgent = null;
84
-
85
- /**
86
- * HTTP headers in the PHP-flavor. So HTTP_USER_AGENT and SERVER_SOFTWARE.
87
- * @var array
88
- */
89
- protected $httpHeaders = array();
90
-
91
- /**
92
- * The detection type, using self::DETECTION_TYPE_MOBILE or self::DETECTION_TYPE_EXTENDED.
93
- *
94
- * @deprecated since version 2.6.9
95
- *
96
- * @var string
97
- */
98
- protected $detectionType = self::DETECTION_TYPE_MOBILE;
99
-
100
- /**
101
- * HTTP headers that trigger the 'isMobile' detection
102
- * to be true.
103
- *
104
- * @var array
105
- */
106
- protected static $mobileHeaders = array(
107
-
108
- 'HTTP_ACCEPT' => array('matches' => array(
109
- // Opera Mini; @reference: http://dev.opera.com/articles/view/opera-binary-markup-language/
110
- 'application/x-obml2d',
111
- // BlackBerry devices.
112
- 'application/vnd.rim.html',
113
- 'text/vnd.wap.wml',
114
- 'application/vnd.wap.xhtml+xml'
115
- )),
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
116
  'HTTP_X_WAP_PROFILE' => null,
117
  'HTTP_X_WAP_CLIENTID' => null,
118
  'HTTP_WAP_CONNECTION' => null,
@@ -127,1159 +156,1265 @@ class Mobile_Detect
127
  'HTTP_UA_OS' => null,
128
  // Reported by Verizon, Vodafone proxy system.
129
  'HTTP_X_MOBILE_GATEWAY' => null,
130
- // Seend this on HTC Sensation. @ref: SensationXE_Beats_Z715e.
131
  'HTTP_X_ATT_DEVICEID' => null,
132
  // Seen this on a HTC.
133
- 'HTTP_UA_CPU' => array('matches' => array('ARM')),
134
- );
135
-
136
- /**
137
- * List of mobile devices (phones).
138
- *
139
- * @var array
140
- */
141
- protected static $phoneDevices = array(
142
- 'iPhone' => '\biPhone\b|\biPod\b', // |\biTunes
143
- 'BlackBerry' => 'BlackBerry|\bBB10\b|rim[0-9]+',
144
- 'HTC' => 'HTC|HTC.*(Sensation|Evo|Vision|Explorer|6800|8100|8900|A7272|S510e|C110e|Legend|Desire|T8282)|APX515CKT|Qtek9090|APA9292KT|HD_mini|Sensation.*Z710e|PG86100|Z715e|Desire.*(A8181|HD)|ADR6200|ADR6400L|ADR6425|001HT|Inspire 4G|Android.*\bEVO\b|T-Mobile G1|Z520m',
145
- 'Nexus' => 'Nexus One|Nexus S|Galaxy.*Nexus|Android.*Nexus.*Mobile',
146
- // @todo: Is 'Dell Streak' a tablet or a phone? ;)
147
- 'Dell' => 'Dell.*Streak|Dell.*Aero|Dell.*Venue|DELL.*Venue Pro|Dell Flash|Dell Smoke|Dell Mini 3iX|XCD28|XCD35|\b001DL\b|\b101DL\b|\bGS01\b',
148
- 'Motorola' => 'Motorola|DROIDX|DROID BIONIC|\bDroid\b.*Build|Android.*Xoom|HRI39|MOT-|A1260|A1680|A555|A853|A855|A953|A955|A956|Motorola.*ELECTRIFY|Motorola.*i1|i867|i940|MB200|MB300|MB501|MB502|MB508|MB511|MB520|MB525|MB526|MB611|MB612|MB632|MB810|MB855|MB860|MB861|MB865|MB870|ME501|ME502|ME511|ME525|ME600|ME632|ME722|ME811|ME860|ME863|ME865|MT620|MT710|MT716|MT720|MT810|MT870|MT917|Motorola.*TITANIUM|WX435|WX445|XT300|XT301|XT311|XT316|XT317|XT319|XT320|XT390|XT502|XT530|XT531|XT532|XT535|XT603|XT610|XT611|XT615|XT681|XT701|XT702|XT711|XT720|XT800|XT806|XT860|XT862|XT875|XT882|XT883|XT894|XT901|XT907|XT909|XT910|XT912|XT928|XT926|XT915|XT919|XT925',
149
- 'Samsung' => 'Samsung|SGH-I337|BGT-S5230|GT-B2100|GT-B2700|GT-B2710|GT-B3210|GT-B3310|GT-B3410|GT-B3730|GT-B3740|GT-B5510|GT-B5512|GT-B5722|GT-B6520|GT-B7300|GT-B7320|GT-B7330|GT-B7350|GT-B7510|GT-B7722|GT-B7800|GT-C3010|GT-C3011|GT-C3060|GT-C3200|GT-C3212|GT-C3212I|GT-C3262|GT-C3222|GT-C3300|GT-C3300K|GT-C3303|GT-C3303K|GT-C3310|GT-C3322|GT-C3330|GT-C3350|GT-C3500|GT-C3510|GT-C3530|GT-C3630|GT-C3780|GT-C5010|GT-C5212|GT-C6620|GT-C6625|GT-C6712|GT-E1050|GT-E1070|GT-E1075|GT-E1080|GT-E1081|GT-E1085|GT-E1087|GT-E1100|GT-E1107|GT-E1110|GT-E1120|GT-E1125|GT-E1130|GT-E1160|GT-E1170|GT-E1175|GT-E1180|GT-E1182|GT-E1200|GT-E1210|GT-E1225|GT-E1230|GT-E1390|GT-E2100|GT-E2120|GT-E2121|GT-E2152|GT-E2220|GT-E2222|GT-E2230|GT-E2232|GT-E2250|GT-E2370|GT-E2550|GT-E2652|GT-E3210|GT-E3213|GT-I5500|GT-I5503|GT-I5700|GT-I5800|GT-I5801|GT-I6410|GT-I6420|GT-I7110|GT-I7410|GT-I7500|GT-I8000|GT-I8150|GT-I8160|GT-I8190|GT-I8320|GT-I8330|GT-I8350|GT-I8530|GT-I8700|GT-I8703|GT-I8910|GT-I9000|GT-I9001|GT-I9003|GT-I9010|GT-I9020|GT-I9023|GT-I9070|GT-I9082|GT-I9100|GT-I9103|GT-I9220|GT-I9250|GT-I9300|GT-I9305|GT-I9500|GT-I9505|GT-M3510|GT-M5650|GT-M7500|GT-M7600|GT-M7603|GT-M8800|GT-M8910|GT-N7000|GT-S3110|GT-S3310|GT-S3350|GT-S3353|GT-S3370|GT-S3650|GT-S3653|GT-S3770|GT-S3850|GT-S5210|GT-S5220|GT-S5229|GT-S5230|GT-S5233|GT-S5250|GT-S5253|GT-S5260|GT-S5263|GT-S5270|GT-S5300|GT-S5330|GT-S5350|GT-S5360|GT-S5363|GT-S5369|GT-S5380|GT-S5380D|GT-S5560|GT-S5570|GT-S5600|GT-S5603|GT-S5610|GT-S5620|GT-S5660|GT-S5670|GT-S5690|GT-S5750|GT-S5780|GT-S5830|GT-S5839|GT-S6102|GT-S6500|GT-S7070|GT-S7200|GT-S7220|GT-S7230|GT-S7233|GT-S7250|GT-S7500|GT-S7530|GT-S7550|GT-S7562|GT-S7710|GT-S8000|GT-S8003|GT-S8500|GT-S8530|GT-S8600|SCH-A310|SCH-A530|SCH-A570|SCH-A610|SCH-A630|SCH-A650|SCH-A790|SCH-A795|SCH-A850|SCH-A870|SCH-A890|SCH-A930|SCH-A950|SCH-A970|SCH-A990|SCH-I100|SCH-I110|SCH-I400|SCH-I405|SCH-I500|SCH-I510|SCH-I515|SCH-I600|SCH-I730|SCH-I760|SCH-I770|SCH-I830|SCH-I910|SCH-I920|SCH-I959|SCH-LC11|SCH-N150|SCH-N300|SCH-R100|SCH-R300|SCH-R351|SCH-R400|SCH-R410|SCH-T300|SCH-U310|SCH-U320|SCH-U350|SCH-U360|SCH-U365|SCH-U370|SCH-U380|SCH-U410|SCH-U430|SCH-U450|SCH-U460|SCH-U470|SCH-U490|SCH-U540|SCH-U550|SCH-U620|SCH-U640|SCH-U650|SCH-U660|SCH-U700|SCH-U740|SCH-U750|SCH-U810|SCH-U820|SCH-U900|SCH-U940|SCH-U960|SCS-26UC|SGH-A107|SGH-A117|SGH-A127|SGH-A137|SGH-A157|SGH-A167|SGH-A177|SGH-A187|SGH-A197|SGH-A227|SGH-A237|SGH-A257|SGH-A437|SGH-A517|SGH-A597|SGH-A637|SGH-A657|SGH-A667|SGH-A687|SGH-A697|SGH-A707|SGH-A717|SGH-A727|SGH-A737|SGH-A747|SGH-A767|SGH-A777|SGH-A797|SGH-A817|SGH-A827|SGH-A837|SGH-A847|SGH-A867|SGH-A877|SGH-A887|SGH-A897|SGH-A927|SGH-B100|SGH-B130|SGH-B200|SGH-B220|SGH-C100|SGH-C110|SGH-C120|SGH-C130|SGH-C140|SGH-C160|SGH-C170|SGH-C180|SGH-C200|SGH-C207|SGH-C210|SGH-C225|SGH-C230|SGH-C417|SGH-C450|SGH-D307|SGH-D347|SGH-D357|SGH-D407|SGH-D415|SGH-D780|SGH-D807|SGH-D980|SGH-E105|SGH-E200|SGH-E315|SGH-E316|SGH-E317|SGH-E335|SGH-E590|SGH-E635|SGH-E715|SGH-E890|SGH-F300|SGH-F480|SGH-I200|SGH-I300|SGH-I320|SGH-I550|SGH-I577|SGH-I600|SGH-I607|SGH-I617|SGH-I627|SGH-I637|SGH-I677|SGH-I700|SGH-I717|SGH-I727|SGH-i747M|SGH-I777|SGH-I780|SGH-I827|SGH-I847|SGH-I857|SGH-I896|SGH-I897|SGH-I900|SGH-I907|SGH-I917|SGH-I927|SGH-I937|SGH-I997|SGH-J150|SGH-J200|SGH-L170|SGH-L700|SGH-M110|SGH-M150|SGH-M200|SGH-N105|SGH-N500|SGH-N600|SGH-N620|SGH-N625|SGH-N700|SGH-N710|SGH-P107|SGH-P207|SGH-P300|SGH-P310|SGH-P520|SGH-P735|SGH-P777|SGH-Q105|SGH-R210|SGH-R220|SGH-R225|SGH-S105|SGH-S307|SGH-T109|SGH-T119|SGH-T139|SGH-T209|SGH-T219|SGH-T229|SGH-T239|SGH-T249|SGH-T259|SGH-T309|SGH-T319|SGH-T329|SGH-T339|SGH-T349|SGH-T359|SGH-T369|SGH-T379|SGH-T409|SGH-T429|SGH-T439|SGH-T459|SGH-T469|SGH-T479|SGH-T499|SGH-T509|SGH-T519|SGH-T539|SGH-T559|SGH-T589|SGH-T609|SGH-T619|SGH-T629|SGH-T639|SGH-T659|SGH-T669|SGH-T679|SGH-T709|SGH-T719|SGH-T729|SGH-T739|SGH-T746|SGH-T749|SGH-T759|SGH-T769|SGH-T809|SGH-T819|SGH-T839|SGH-T919|SGH-T929|SGH-T939|SGH-T959|SGH-T989|SGH-U100|SGH-U200|SGH-U800|SGH-V205|SGH-V206|SGH-X100|SGH-X105|SGH-X120|SGH-X140|SGH-X426|SGH-X427|SGH-X475|SGH-X495|SGH-X497|SGH-X507|SGH-X600|SGH-X610|SGH-X620|SGH-X630|SGH-X700|SGH-X820|SGH-X890|SGH-Z130|SGH-Z150|SGH-Z170|SGH-ZX10|SGH-ZX20|SHW-M110|SPH-A120|SPH-A400|SPH-A420|SPH-A460|SPH-A500|SPH-A560|SPH-A600|SPH-A620|SPH-A660|SPH-A700|SPH-A740|SPH-A760|SPH-A790|SPH-A800|SPH-A820|SPH-A840|SPH-A880|SPH-A900|SPH-A940|SPH-A960|SPH-D600|SPH-D700|SPH-D710|SPH-D720|SPH-I300|SPH-I325|SPH-I330|SPH-I350|SPH-I500|SPH-I600|SPH-I700|SPH-L700|SPH-M100|SPH-M220|SPH-M240|SPH-M300|SPH-M305|SPH-M320|SPH-M330|SPH-M350|SPH-M360|SPH-M370|SPH-M380|SPH-M510|SPH-M540|SPH-M550|SPH-M560|SPH-M570|SPH-M580|SPH-M610|SPH-M620|SPH-M630|SPH-M800|SPH-M810|SPH-M850|SPH-M900|SPH-M910|SPH-M920|SPH-M930|SPH-N100|SPH-N200|SPH-N240|SPH-N300|SPH-N400|SPH-Z400|SWC-E100|SCH-i909|GT-N7100|GT-N7105|SCH-I535|SM-N900A|SGH-I317|SGH-T999L|GT-S5360B|GT-I8262|GT-S6802|GT-S6312|GT-S6310|GT-S5312|GT-S5310|GT-I9105|GT-I8510|GT-S6790N|SM-G7105|SM-N9005|GT-S5301|GT-I9295|GT-I9195|SM-C101|GT-S7392|GT-S7560|GT-B7610|GT-I5510|GT-S7582|GT-S7530E|GT-I8750',
150
- 'LG' => '\bLG\b;|LG[- ]?(C800|C900|E400|E610|E900|E-900|F160|F180K|F180L|F180S|730|855|L160|LS840|LS970|LU6200|MS690|MS695|MS770|MS840|MS870|MS910|P500|P700|P705|VM696|AS680|AS695|AX840|C729|E970|GS505|272|C395|E739BK|E960|L55C|L75C|LS696|LS860|P769BK|P350|P500|P509|P870|UN272|US730|VS840|VS950|LN272|LN510|LS670|LS855|LW690|MN270|MN510|P509|P769|P930|UN200|UN270|UN510|UN610|US670|US740|US760|UX265|UX840|VN271|VN530|VS660|VS700|VS740|VS750|VS910|VS920|VS930|VX9200|VX11000|AX840A|LW770|P506|P925|P999|E612|D955|D802)',
151
- 'Sony' => 'SonyST|SonyLT|SonyEricsson|SonyEricssonLT15iv|LT18i|E10i|LT28h|LT26w|SonyEricssonMT27i|C6902|C6903|C6906|C6943',
152
- 'Asus' => 'Asus.*Galaxy|PadFone.*Mobile',
153
- // @ref: http://www.micromaxinfo.com/mobiles/smartphones
154
- // Added because the codes might conflict with Acer Tablets.
155
- 'Micromax' => 'Micromax.*\b(A210|A92|A88|A72|A111|A110Q|A115|A116|A110|A90S|A26|A51|A35|A54|A25|A27|A89|A68|A65|A57|A90)\b',
156
- 'Palm' => 'PalmSource|Palm', // avantgo|blazer|elaine|hiptop|plucker|xiino ; @todo - complete the regex.
157
- 'Vertu' => 'Vertu|Vertu.*Ltd|Vertu.*Ascent|Vertu.*Ayxta|Vertu.*Constellation(F|Quest)?|Vertu.*Monika|Vertu.*Signature', // Just for fun ;)
158
- // @ref: http://www.pantech.co.kr/en/prod/prodList.do?gbrand=VEGA (PANTECH)
159
- // Most of the VEGA devices are legacy. PANTECH seem to be newer devices based on Android.
160
- 'Pantech' => 'PANTECH|IM-A850S|IM-A840S|IM-A830L|IM-A830K|IM-A830S|IM-A820L|IM-A810K|IM-A810S|IM-A800S|IM-T100K|IM-A725L|IM-A780L|IM-A775C|IM-A770K|IM-A760S|IM-A750K|IM-A740S|IM-A730S|IM-A720L|IM-A710K|IM-A690L|IM-A690S|IM-A650S|IM-A630K|IM-A600S|VEGA PTL21|PT003|P8010|ADR910L|P6030|P6020|P9070|P4100|P9060|P5000|CDM8992|TXT8045|ADR8995|IS11PT|P2030|P6010|P8000|PT002|IS06|CDM8999|P9050|PT001|TXT8040|P2020|P9020|P2000|P7040|P7000|C790',
161
- // @ref: http://www.fly-phone.com/devices/smartphones/ ; Included only smartphones.
162
- 'Fly' => 'IQ230|IQ444|IQ450|IQ440|IQ442|IQ441|IQ245|IQ256|IQ236|IQ255|IQ235|IQ245|IQ275|IQ240|IQ285|IQ280|IQ270|IQ260|IQ250',
163
- 'iMobile' => 'i-mobile (IQ|i-STYLE|idea|ZAA|Hitz)',
164
- // Added simvalley mobile just for fun. They have some interesting devices.
165
- // @ref: http://www.simvalley.fr/telephonie---gps-_22_telephonie-mobile_telephones_.html
166
- 'SimValley' => '\b(SP-80|XT-930|SX-340|XT-930|SX-310|SP-360|SP60|SPT-800|SP-120|SPT-800|SP-140|SPX-5|SPX-8|SP-100|SPX-8|SPX-12)\b',
167
- // Wolfgang - a brand that is sold by Aldi supermarkets
168
- // http://www.wolfgangmobile.com/
169
- 'Wolfgang' => 'AT-B24D|AT-AS50HD|AT-AS40W|AT-AS55HD|AT-AS45q2|AT-B26D|AT-AS50Q',
170
- 'Alcatel' => 'Alcatel',
171
- // @ref: http://en.wikipedia.org/wiki/Amoi
172
- 'Amoi' => 'Amoi',
173
- // @ref: http://en.wikipedia.org/wiki/INQ
174
- 'INQ' => 'INQ',
175
- // @Tapatalk is a mobile app; @ref: http://support.tapatalk.com/threads/smf-2-0-2-os-and-browser-detection-plugin-and-tapatalk.15565/#post-79039
176
- 'GenericPhone' => 'Tapatalk|PDA;|SAGEM|\bmmp\b|pocket|\bpsp\b|symbian|Smartphone|smartfon|treo|up.browser|up.link|vodafone|\bwap\b|nokia|Series40|Series60|S60|SonyEricsson|N900|MAUI.*WAP.*Browser',
177
- );
178
-
179
- /**
180
- * List of tablet devices.
181
- *
182
- * @var array
183
- */
184
- protected static $tabletDevices = array(
185
- 'iPad' => 'iPad|iPad.*Mobile', // @todo: check for mobile friendly emails topic.
186
- 'NexusTablet' => 'Android.*Nexus[\s]+(7|10)|^.*Android.*Nexus(?:(?!Mobile).)*$',
187
- 'SamsungTablet' => 'SAMSUNG.*Tablet|Galaxy.*Tab|SC-01C|GT-P1000|GT-P1003|GT-P1010|GT-P3105|GT-P6210|GT-P6800|GT-P6810|GT-P7100|GT-P7300|GT-P7310|GT-P7500|GT-P7510|SCH-I800|SCH-I815|SCH-I905|SGH-I957|SGH-I987|SGH-T849|SGH-T859|SGH-T869|SPH-P100|GT-P3100|GT-P3108|GT-P3110|GT-P5100|GT-P5110|GT-P6200|GT-P7320|GT-P7511|GT-N8000|GT-P8510|SGH-I497|SPH-P500|SGH-T779|SCH-I705|SCH-I915|GT-N8013|GT-P3113|GT-P5113|GT-P8110|GT-N8010|GT-N8005|GT-N8020|GT-P1013|GT-P6201|GT-P7501|GT-N5100|GT-N5105|GT-N5110|SHV-E140K|SHV-E140L|SHV-E140S|SHV-E150S|SHV-E230K|SHV-E230L|SHV-E230S|SHW-M180K|SHW-M180L|SHW-M180S|SHW-M180W|SHW-M300W|SHW-M305W|SHW-M380K|SHW-M380S|SHW-M380W|SHW-M430W|SHW-M480K|SHW-M480S|SHW-M480W|SHW-M485W|SHW-M486W|SHW-M500W|GT-I9228|SCH-P739|SCH-I925|GT-I9200|GT-I9205|GT-P5200|GT-P5210|GT-P5210X|SM-T311|SM-T310|SM-T310X|SM-T210|SM-T210R|SM-T211|SM-P600|SM-P601|SM-P605|SM-P900|SM-P901|SM-T217|SM-T217A|SM-T217S|SM-P6000|SM-T3100|SGH-I467|XE500|SM-T110|GT-P5220|GT-I9200X|GT-N5110X|GT-N5120|SM-P905|SM-T111|SM-T2105|SM-T315|SM-T320|SM-T320X|SM-T321|SM-T520|SM-T525|SM-T530NU|SM-T230NU|SM-T330NU|SM-T900|XE500T1C|SM-P605V|SM-P905V|SM-P600X|SM-P900X|SM-T210X|SM-T230|SM-T230X|SM-T325|GT-P7503|SM-T531|SM-T330|SM-T530|SM-T705C|SM-T535|SM-T331|SM-T800|SM-T700', // SCH-P709|SCH-P729|SM-T2558 - Samsung Mega - treat them like a regular phone.
188
- // @reference: http://www.labnol.org/software/kindle-user-agent-string/20378/
189
- 'Kindle' => 'Kindle|Silk.*Accelerated|Android.*\b(KFOT|KFTT|KFJWI|KFJWA|KFOTE|KFSOWI|KFTHWI|KFTHWA|KFAPWI|KFAPWA|WFJWAE)\b',
190
- // Only the Surface tablets with Windows RT are considered mobile.
191
- // @ref: http://msdn.microsoft.com/en-us/library/ie/hh920767(v=vs.85).aspx
192
- 'SurfaceTablet' => 'Windows NT [0-9.]+; ARM;.*(Tablet|ARMBJS)',
193
- // @ref: http://shopping1.hp.com/is-bin/INTERSHOP.enfinity/WFS/WW-USSMBPublicStore-Site/en_US/-/USD/ViewStandardCatalog-Browse?CatalogCategoryID=JfIQ7EN5lqMAAAEyDcJUDwMT
194
- 'HPTablet' => 'HP Slate (7|8|10)|HP ElitePad 900|hp-tablet|EliteBook.*Touch|HP 8|Slate 21|HP SlateBook 10',
195
- // @note: watch out for PadFone, see #132
196
- // http://www.asus.com/de/Tablets_Mobile/Memo_Pad_Products/
197
- 'AsusTablet' => '^.*PadFone((?!Mobile).)*$|Transformer|TF101|TF101G|TF300T|TF300TG|TF300TL|TF700T|TF700KL|TF701T|TF810C|ME171|ME301T|ME302C|ME371MG|ME370T|ME372MG|ME172V|ME173X|ME400C|Slider SL101|\bK00F\b|\bK00C\b|\bK00E\b|\bK00L\b|TX201LA|ME176C|ME102A|\bM80TA\b|ME372CL|ME560CG|ME372CG',
198
- 'BlackBerryTablet' => 'PlayBook|RIM Tablet',
199
- 'HTCtablet' => 'HTC Flyer|HTC Jetstream|HTC-P715a|HTC EVO View 4G|PG41200|PG09410',
200
- 'MotorolaTablet' => 'xoom|sholest|MZ615|MZ605|MZ505|MZ601|MZ602|MZ603|MZ604|MZ606|MZ607|MZ608|MZ609|MZ615|MZ616|MZ617',
201
- 'NookTablet' => 'Android.*Nook|NookColor|nook browser|BNRV200|BNRV200A|BNTV250|BNTV250A|BNTV400|BNTV600|LogicPD Zoom2',
202
- // @ref: http://www.acer.ro/ac/ro/RO/content/drivers
203
- // @ref: http://www.packardbell.co.uk/pb/en/GB/content/download (Packard Bell is part of Acer)
204
- // @ref: http://us.acer.com/ac/en/US/content/group/tablets
205
- // @note: Can conflict with Micromax and Motorola phones codes.
206
- 'AcerTablet' => 'Android.*; \b(A100|A101|A110|A200|A210|A211|A500|A501|A510|A511|A700|A701|W500|W500P|W501|W501P|W510|W511|W700|G100|G100W|B1-A71|B1-710|B1-711|A1-810|A1-811|A1-830)\b|W3-810|\bA3-A10\b',
207
- // @ref: http://eu.computers.toshiba-europe.com/innovation/family/Tablets/1098744/banner_id/tablet_footerlink/
208
- // @ref: http://us.toshiba.com/tablets/tablet-finder
209
- // @ref: http://www.toshiba.co.jp/regza/tablet/
210
- 'ToshibaTablet' => 'Android.*(AT100|AT105|AT200|AT205|AT270|AT275|AT300|AT305|AT1S5|AT500|AT570|AT700|AT830)|TOSHIBA.*FOLIO',
211
- // @ref: http://www.nttdocomo.co.jp/english/service/developer/smart_phone/technical_info/spec/index.html
212
- // @ref: http://www.lg.com/us/tablets
213
- 'LGTablet' => '\bL-06C|LG-V900|LG-V500|LG-V909|LG-V500|LG-V510|LG-VK810\b',
214
- 'FujitsuTablet' => 'Android.*\b(F-01D|F-02F|F-05E|F-10D|M532|Q572)\b',
215
- // Prestigio Tablets http://www.prestigio.com/support
216
- 'PrestigioTablet' => 'PMP3170B|PMP3270B|PMP3470B|PMP7170B|PMP3370B|PMP3570C|PMP5870C|PMP3670B|PMP5570C|PMP5770D|PMP3970B|PMP3870C|PMP5580C|PMP5880D|PMP5780D|PMP5588C|PMP7280C|PMP7280C3G|PMP7280|PMP7880D|PMP5597D|PMP5597|PMP7100D|PER3464|PER3274|PER3574|PER3884|PER5274|PER5474|PMP5097CPRO|PMP5097|PMP7380D|PMP5297C|PMP5297C_QUAD',
217
- // @ref: http://support.lenovo.com/en_GB/downloads/default.page?#
218
- 'LenovoTablet' => 'Idea(Tab|Pad)( A1|A10| K1|)|ThinkPad([ ]+)?Tablet|Lenovo.*(S2109|S2110|S5000|S6000|K3011|A3000|A3500|A1000|A2107|A2109|A1107|A5500|A7600|B6000|B8000|B8080)(-|)(FL|F|HV|H|)',
219
- // @ref: http://www.yarvik.com/en/matrix/tablets/
220
- 'YarvikTablet' => 'Android.*\b(TAB210|TAB211|TAB224|TAB250|TAB260|TAB264|TAB310|TAB360|TAB364|TAB410|TAB411|TAB420|TAB424|TAB450|TAB460|TAB461|TAB464|TAB465|TAB467|TAB468|TAB07-100|TAB07-101|TAB07-150|TAB07-151|TAB07-152|TAB07-200|TAB07-201-3G|TAB07-210|TAB07-211|TAB07-212|TAB07-214|TAB07-220|TAB07-400|TAB07-485|TAB08-150|TAB08-200|TAB08-201-3G|TAB08-201-30|TAB09-100|TAB09-211|TAB09-410|TAB10-150|TAB10-201|TAB10-211|TAB10-400|TAB10-410|TAB13-201|TAB274EUK|TAB275EUK|TAB374EUK|TAB462EUK|TAB474EUK|TAB9-200)\b',
221
- 'MedionTablet' => 'Android.*\bOYO\b|LIFE.*(P9212|P9514|P9516|S9512)|LIFETAB',
222
- 'ArnovaTablet' => 'AN10G2|AN7bG3|AN7fG3|AN8G3|AN8cG3|AN7G3|AN9G3|AN7dG3|AN7dG3ST|AN7dG3ChildPad|AN10bG3|AN10bG3DT',
223
- // http://www.intenso.de/kategorie_en.php?kategorie=33
224
- // @todo: http://www.nbhkdz.com/read/b8e64202f92a2df129126bff.html - investigate
225
- 'IntensoTablet' => 'INM8002KP|INM1010FP|INM805ND|Intenso Tab|TAB1004',
226
- // IRU.ru Tablets http://www.iru.ru/catalog/soho/planetable/
227
- 'IRUTablet' => 'M702pro',
228
- 'MegafonTablet' => 'MegaFon V9|\bZTE V9\b|Android.*\bMT7A\b',
229
- // @ref: http://www.e-boda.ro/tablete-pc.html
230
- 'EbodaTablet' => 'E-Boda (Supreme|Impresspeed|Izzycomm|Essential)',
231
- // @ref: http://www.allview.ro/produse/droseries/lista-tablete-pc/
232
- 'AllViewTablet' => 'Allview.*(Viva|Alldro|City|Speed|All TV|Frenzy|Quasar|Shine|TX1|AX1|AX2)',
233
- // @reference: http://wiki.archosfans.com/index.php?title=Main_Page
234
- 'ArchosTablet' => '\b(101G9|80G9|A101IT)\b|Qilive 97R|Archos5|\bARCHOS (70|79|80|90|97|101|FAMILYPAD|)(b|)(G10| Cobalt| TITANIUM(HD|)| Xenon| Neon|XSK| 2| XS 2| PLATINUM| CARBON|GAMEPAD)\b',
235
- // @ref: http://www.ainol.com/plugin.php?identifier=ainol&module=product
236
- 'AinolTablet' => 'NOVO7|NOVO8|NOVO10|Novo7Aurora|Novo7Basic|NOVO7PALADIN|novo9-Spark',
237
- // @todo: inspect http://esupport.sony.com/US/p/select-system.pl?DIRECTOR=DRIVER
238
- // @ref: Readers http://www.atsuhiro-me.net/ebook/sony-reader/sony-reader-web-browser
239
- // @ref: http://www.sony.jp/support/tablet/
240
- 'SonyTablet' => 'Sony.*Tablet|Xperia Tablet|Sony Tablet S|SO-03E|SGPT12|SGPT13|SGPT114|SGPT121|SGPT122|SGPT123|SGPT111|SGPT112|SGPT113|SGPT131|SGPT132|SGPT133|SGPT211|SGPT212|SGPT213|SGP311|SGP312|SGP321|EBRD1101|EBRD1102|EBRD1201|SGP351|SGP341|SGP511|SGP512|SGP521|SGP541|SGP551',
241
- // http://www.support.philips.com/support/catalog/worldproducts.jsp?userLanguage=en&userCountry=cn&categoryid=3G_LTE_TABLET_SU_CN_CARE&title=3G%20tablets%20/%20LTE%20range&_dyncharset=UTF-8
242
- 'PhilipsTablet' => '\b(PI2010|PI3000|PI3100|PI3105|PI3110|PI3205|PI3210|PI3900|PI4010|PI7000|PI7100)\b',
243
- // @ref: db + http://www.cube-tablet.com/buy-products.html
244
- 'CubeTablet' => 'Android.*(K8GT|U9GT|U10GT|U16GT|U17GT|U18GT|U19GT|U20GT|U23GT|U30GT)|CUBE U8GT',
245
- // @ref: http://www.cobyusa.com/?p=pcat&pcat_id=3001
246
- 'CobyTablet' => 'MID1042|MID1045|MID1125|MID1126|MID7012|MID7014|MID7015|MID7034|MID7035|MID7036|MID7042|MID7048|MID7127|MID8042|MID8048|MID8127|MID9042|MID9740|MID9742|MID7022|MID7010',
247
- // @ref: http://www.match.net.cn/products.asp
248
- 'MIDTablet' => 'M9701|M9000|M9100|M806|M1052|M806|T703|MID701|MID713|MID710|MID727|MID760|MID830|MID728|MID933|MID125|MID810|MID732|MID120|MID930|MID800|MID731|MID900|MID100|MID820|MID735|MID980|MID130|MID833|MID737|MID960|MID135|MID860|MID736|MID140|MID930|MID835|MID733',
249
- // http://www.msi.com/support
250
- // @todo Research the Windows Tablets.
251
- 'MSITablet' => 'MSI \b(Primo 73K|Primo 73L|Primo 81L|Primo 77|Primo 93|Primo 75|Primo 76|Primo 73|Primo 81|Primo 91|Primo 90|Enjoy 71|Enjoy 7|Enjoy 10)\b',
252
- // @ref: http://pdadb.net/index.php?m=pdalist&list=SMiT (NoName Chinese Tablets)
253
- // @ref: http://www.imp3.net/14/show.php?itemid=20454
254
- 'SMiTTablet' => 'Android.*(\bMID\b|MID-560|MTV-T1200|MTV-PND531|MTV-P1101|MTV-PND530)',
255
- // @ref: http://www.rock-chips.com/index.php?do=prod&pid=2
256
- 'RockChipTablet' => 'Android.*(RK2818|RK2808A|RK2918|RK3066)|RK2738|RK2808A',
257
- // @ref: http://www.fly-phone.com/devices/tablets/ ; http://www.fly-phone.com/service/
258
- 'FlyTablet' => 'IQ310|Fly Vision',
259
- // @ref: http://www.bqreaders.com/gb/tablets-prices-sale.html
260
- 'bqTablet' => 'bq.*(Elcano|Curie|Edison|Maxwell|Kepler|Pascal|Tesla|Hypatia|Platon|Newton|Livingstone|Cervantes|Avant)|Maxwell.*Lite|Maxwell.*Plus',
261
- // @ref: http://www.huaweidevice.com/worldwide/productFamily.do?method=index&directoryId=5011&treeId=3290
262
- // @ref: http://www.huaweidevice.com/worldwide/downloadCenter.do?method=index&directoryId=3372&treeId=0&tb=1&type=software (including legacy tablets)
263
- 'HuaweiTablet' => 'MediaPad|MediaPad 7 Youth|IDEOS S7|S7-201c|S7-202u|S7-101|S7-103|S7-104|S7-105|S7-106|S7-201|S7-Slim',
264
- // Nec or Medias Tab
265
- 'NecTablet' => '\bN-06D|\bN-08D',
266
- // Pantech Tablets: http://www.pantechusa.com/phones/
267
- 'PantechTablet' => 'Pantech.*P4100',
268
- // Broncho Tablets: http://www.broncho.cn/ (hard to find)
269
- 'BronchoTablet' => 'Broncho.*(N701|N708|N802|a710)',
270
- // @ref: http://versusuk.com/support.html
271
- 'VersusTablet' => 'TOUCHPAD.*[78910]|\bTOUCHTAB\b',
272
- // @ref: http://www.zync.in/index.php/our-products/tablet-phablets
273
- 'ZyncTablet' => 'z1000|Z99 2G|z99|z930|z999|z990|z909|Z919|z900',
274
- // @ref: http://www.positivoinformatica.com.br/www/pessoal/tablet-ypy/
275
- 'PositivoTablet' => 'TB07STA|TB10STA|TB07FTA|TB10FTA',
276
- // @ref: https://www.nabitablet.com/
277
- 'NabiTablet' => 'Android.*\bNabi',
278
- 'KoboTablet' => 'Kobo Touch|\bK080\b|\bVox\b Build|\bArc\b Build',
279
- // French Danew Tablets http://www.danew.com/produits-tablette.php
280
- 'DanewTablet' => 'DSlide.*\b(700|701R|702|703R|704|802|970|971|972|973|974|1010|1012)\b',
281
- // Texet Tablets and Readers http://www.texet.ru/tablet/
282
- 'TexetTablet' => 'NaviPad|TB-772A|TM-7045|TM-7055|TM-9750|TM-7016|TM-7024|TM-7026|TM-7041|TM-7043|TM-7047|TM-8041|TM-9741|TM-9747|TM-9748|TM-9751|TM-7022|TM-7021|TM-7020|TM-7011|TM-7010|TM-7023|TM-7025|TM-7037W|TM-7038W|TM-7027W|TM-9720|TM-9725|TM-9737W|TM-1020|TM-9738W|TM-9740|TM-9743W|TB-807A|TB-771A|TB-727A|TB-725A|TB-719A|TB-823A|TB-805A|TB-723A|TB-715A|TB-707A|TB-705A|TB-709A|TB-711A|TB-890HD|TB-880HD|TB-790HD|TB-780HD|TB-770HD|TB-721HD|TB-710HD|TB-434HD|TB-860HD|TB-840HD|TB-760HD|TB-750HD|TB-740HD|TB-730HD|TB-722HD|TB-720HD|TB-700HD|TB-500HD|TB-470HD|TB-431HD|TB-430HD|TB-506|TB-504|TB-446|TB-436|TB-416|TB-146SE|TB-126SE',
283
- // @note: Avoid detecting 'PLAYSTATION 3' as mobile.
284
- 'PlaystationTablet' => 'Playstation.*(Portable|Vita)',
285
- // @ref: http://www.trekstor.de/surftabs.html
286
- 'TrekstorTablet' => 'ST10416-1|VT10416-1|ST70408-1|ST702xx-1|ST702xx-2|ST80208|ST97216|ST70104-2|VT10416-2|ST10216-2A|SurfTab',
287
- // @ref: http://www.pyleaudio.com/Products.aspx?%2fproducts%2fPersonal-Electronics%2fTablets
288
- 'PyleAudioTablet' => '\b(PTBL10CEU|PTBL10C|PTBL72BC|PTBL72BCEU|PTBL7CEU|PTBL7C|PTBL92BC|PTBL92BCEU|PTBL9CEU|PTBL9CUK|PTBL9C)\b',
289
- // @ref: http://www.advandigital.com/index.php?link=content-product&jns=JP001
290
- // @Note: because of the short codenames we have to include whitespaces to reduce the possible conflicts.
291
- 'AdvanTablet' => 'Android.* \b(E3A|T3X|T5C|T5B|T3E|T3C|T3B|T1J|T1F|T2A|T1H|T1i|E1C|T1-E|T5-A|T4|E1-B|T2Ci|T1-B|T1-D|O1-A|E1-A|T1-A|T3A|T4i)\b ',
292
- // @ref: http://www.danytech.com/category/tablet-pc
293
- 'DanyTechTablet' => 'Genius Tab G3|Genius Tab S2|Genius Tab Q3|Genius Tab G4|Genius Tab Q4|Genius Tab G-II|Genius TAB GII|Genius TAB GIII|Genius Tab S1',
294
- // @ref: http://www.galapad.net/product.html
295
- 'GalapadTablet' => 'Android.*\bG1\b',
296
- // @ref: http://www.micromaxinfo.com/tablet/funbook
297
- 'MicromaxTablet' => 'Funbook|Micromax.*\b(P250|P560|P360|P362|P600|P300|P350|P500|P275)\b',
298
- // http://www.karbonnmobiles.com/products_tablet.php
299
- 'KarbonnTablet' => 'Android.*\b(A39|A37|A34|ST8|ST10|ST7|Smart Tab3|Smart Tab2)\b',
300
- // @ref: http://www.myallfine.com/Products.asp
301
- 'AllFineTablet' => 'Fine7 Genius|Fine7 Shine|Fine7 Air|Fine8 Style|Fine9 More|Fine10 Joy|Fine11 Wide',
302
- // @ref: http://www.proscanvideo.com/products-search.asp?itemClass=TABLET&itemnmbr=
303
- 'PROSCANTablet' => '\b(PEM63|PLT1023G|PLT1041|PLT1044|PLT1044G|PLT1091|PLT4311|PLT4311PL|PLT4315|PLT7030|PLT7033|PLT7033D|PLT7035|PLT7035D|PLT7044K|PLT7045K|PLT7045KB|PLT7071KG|PLT7072|PLT7223G|PLT7225G|PLT7777G|PLT7810K|PLT7849G|PLT7851G|PLT7852G|PLT8015|PLT8031|PLT8034|PLT8036|PLT8080K|PLT8082|PLT8088|PLT8223G|PLT8234G|PLT8235G|PLT8816K|PLT9011|PLT9045K|PLT9233G|PLT9735|PLT9760G|PLT9770G)\b',
304
- // @ref: http://www.yonesnav.com/products/products.php
305
- 'YONESTablet' => 'BQ1078|BC1003|BC1077|RK9702|BC9730|BC9001|IT9001|BC7008|BC7010|BC708|BC728|BC7012|BC7030|BC7027|BC7026',
306
- // @ref: http://www.cjshowroom.com/eproducts.aspx?classcode=004001001
307
- // China manufacturer makes tablets for different small brands (eg. http://www.zeepad.net/index.html)
308
- 'ChangJiaTablet' => 'TPC7102|TPC7103|TPC7105|TPC7106|TPC7107|TPC7201|TPC7203|TPC7205|TPC7210|TPC7708|TPC7709|TPC7712|TPC7110|TPC8101|TPC8103|TPC8105|TPC8106|TPC8203|TPC8205|TPC8503|TPC9106|TPC9701|TPC97101|TPC97103|TPC97105|TPC97106|TPC97111|TPC97113|TPC97203|TPC97603|TPC97809|TPC97205|TPC10101|TPC10103|TPC10106|TPC10111|TPC10203|TPC10205|TPC10503',
309
- // @ref: http://www.gloryunion.cn/products.asp
310
- // @ref: http://www.allwinnertech.com/en/apply/mobile.html
311
- // @ref: http://www.ptcl.com.pk/pd_content.php?pd_id=284 (EVOTAB)
312
- // @todo: Softwiner tablets?
313
- // aka. Cute or Cool tablets. Not sure yet, must research to avoid collisions.
314
- 'GUTablet' => 'TX-A1301|TX-M9002|Q702|kf026', // A12R|D75A|D77|D79|R83|A95|A106C|R15|A75|A76|D71|D72|R71|R73|R77|D82|R85|D92|A97|D92|R91|A10F|A77F|W71F|A78F|W78F|W81F|A97F|W91F|W97F|R16G|C72|C73E|K72|K73|R96G
315
- // @ref: http://www.pointofview-online.com/showroom.php?shop_mode=product_listing&category_id=118
316
- 'PointOfViewTablet' => 'TAB-P506|TAB-navi-7-3G-M|TAB-P517|TAB-P-527|TAB-P701|TAB-P703|TAB-P721|TAB-P731N|TAB-P741|TAB-P825|TAB-P905|TAB-P925|TAB-PR945|TAB-PL1015|TAB-P1025|TAB-PI1045|TAB-P1325|TAB-PROTAB[0-9]+|TAB-PROTAB25|TAB-PROTAB26|TAB-PROTAB27|TAB-PROTAB26XL|TAB-PROTAB2-IPS9|TAB-PROTAB30-IPS9|TAB-PROTAB25XXL|TAB-PROTAB26-IPS10|TAB-PROTAB30-IPS10',
317
- // @ref: http://www.overmax.pl/pl/katalog-produktow,p8/tablety,c14/
318
- // @todo: add more tests.
319
- 'OvermaxTablet' => 'OV-(SteelCore|NewBase|Basecore|Baseone|Exellen|Quattor|EduTab|Solution|ACTION|BasicTab|TeddyTab|MagicTab|Stream|TB-08|TB-09)',
320
- // @ref: http://hclmetablet.com/India/index.php
321
- 'HCLTablet' => 'HCL.*Tablet|Connect-3G-2.0|Connect-2G-2.0|ME Tablet U1|ME Tablet U2|ME Tablet G1|ME Tablet X1|ME Tablet Y2|ME Tablet Sync',
322
- // @ref: http://www.edigital.hu/Tablet_es_e-book_olvaso/Tablet-c18385.html
323
- 'DPSTablet' => 'DPS Dream 9|DPS Dual 7',
324
- // @ref: http://www.visture.com/index.asp
325
- 'VistureTablet' => 'V97 HD|i75 3G|Visture V4( HD)?|Visture V5( HD)?|Visture V10',
326
- // @ref: http://www.mijncresta.nl/tablet
327
- 'CrestaTablet' => 'CTP(-)?810|CTP(-)?818|CTP(-)?828|CTP(-)?838|CTP(-)?888|CTP(-)?978|CTP(-)?980|CTP(-)?987|CTP(-)?988|CTP(-)?989',
328
- // MediaTek - http://www.mediatek.com/_en/01_products/02_proSys.php?cata_sn=1&cata1_sn=1&cata2_sn=309
329
- 'MediatekTablet' => '\bMT8125|MT8389|MT8135|MT8377\b',
330
- // Concorde tab
331
- 'ConcordeTablet' => 'Concorde([ ]+)?Tab|ConCorde ReadMan',
332
- // GoClever Tablets - http://www.goclever.com/uk/products,c1/tablet,c5/
333
- 'GoCleverTablet' => 'GOCLEVER TAB|A7GOCLEVER|M1042|M7841|M742|R1042BK|R1041|TAB A975|TAB A7842|TAB A741|TAB A741L|TAB M723G|TAB M721|TAB A1021|TAB I921|TAB R721|TAB I720|TAB T76|TAB R70|TAB R76.2|TAB R106|TAB R83.2|TAB M813G|TAB I721|GCTA722|TAB I70|TAB I71|TAB S73|TAB R73|TAB R74|TAB R93|TAB R75|TAB R76.1|TAB A73|TAB A93|TAB A93.2|TAB T72|TAB R83|TAB R974|TAB R973|TAB A101|TAB A103|TAB A104|TAB A104.2|R105BK|M713G|A972BK|TAB A971|TAB R974.2|TAB R104|TAB R83.3|TAB A1042',
334
- // Modecom Tablets - http://www.modecom.eu/tablets/portal/
335
- 'ModecomTablet' => 'FreeTAB 9000|FreeTAB 7.4|FreeTAB 7004|FreeTAB 7800|FreeTAB 2096|FreeTAB 7.5|FreeTAB 1014|FreeTAB 1001 |FreeTAB 8001|FreeTAB 9706|FreeTAB 9702|FreeTAB 7003|FreeTAB 7002|FreeTAB 1002|FreeTAB 7801|FreeTAB 1331|FreeTAB 1004|FreeTAB 8002|FreeTAB 8014|FreeTAB 9704|FreeTAB 1003',
336
- // Vonino Tablets - http://www.vonino.eu/tablets
337
- 'VoninoTablet' => '\b(Argus[ _]?S|Diamond[ _]?79HD|Emerald[ _]?78E|Luna[ _]?70C|Onyx[ _]?S|Onyx[ _]?Z|Orin[ _]?HD|Orin[ _]?S|Otis[ _]?S|SpeedStar[ _]?S|Magnet[ _]?M9|Primus[ _]?94[ _]?3G|Primus[ _]?94HD|Primus[ _]?QS|Android.*\bQ8\b|Sirius[ _]?EVO[ _]?QS|Sirius[ _]?QS|Spirit[ _]?S)\b',
338
- // ECS Tablets - http://www.ecs.com.tw/ECSWebSite/Product/Product_Tablet_List.aspx?CategoryID=14&MenuID=107&childid=M_107&LanID=0
339
- 'ECSTablet' => 'V07OT2|TM105A|S10OT1|TR10CS1',
340
- // Storex Tablets - http://storex.fr/espace_client/support.html
341
- // @note: no need to add all the tablet codes since they are guided by the first regex.
342
- 'StorexTablet' => 'eZee[_\']?(Tab|Go)[0-9]+|TabLC7|Looney Tunes Tab',
343
- // Generic Vodafone tablets.
344
- 'VodafoneTablet' => 'SmartTab([ ]+)?[0-9]+|SmartTabII10|SmartTabII7',
345
- // French tablets - Essentiel B http://www.boulanger.fr/tablette_tactile_e-book/tablette_tactile_essentiel_b/cl_68908.htm?multiChoiceToDelete=brand&mc_brand=essentielb
346
- // Aka: http://www.essentielb.fr/
347
- 'EssentielBTablet' => 'Smart[ \']?TAB[ ]+?[0-9]+|Family[ \']?TAB2',
348
- // Ross & Moor - http://ross-moor.ru/
349
- 'RossMoorTablet' => 'RM-790|RM-997|RMD-878G|RMD-974R|RMT-705A|RMT-701|RME-601|RMT-501|RMT-711',
350
- // i-mobile http://product.i-mobilephone.com/Mobile_Device
351
- 'iMobileTablet' => 'i-mobile i-note',
352
- // @ref: http://www.tolino.de/de/vergleichen/
353
- 'TolinoTablet' => 'tolino tab [0-9.]+|tolino shine',
354
- // AudioSonic - a Kmart brand
355
- // http://www.kmart.com.au/webapp/wcs/stores/servlet/Search?langId=-1&storeId=10701&catalogId=10001&categoryId=193001&pageSize=72&currentPage=1&searchCategory=193001%2b4294965664&sortBy=p_MaxPrice%7c1
356
- 'AudioSonicTablet' => '\bC-22Q|T7-QC|T-17B|T-17P\b',
357
- // AMPE Tablets - http://www.ampe.com.my/product-category/tablets/
358
- // @todo: add them gradually to avoid conflicts.
359
- 'AMPETablet' => 'Android.* A78 ',
360
- // Skk Mobile - http://skkmobile.com.ph/product_tablets.php
361
- 'SkkTablet' => 'Android.* (SKYPAD|PHOENIX|CYCLOPS)',
362
- // Tecno Mobile (only tablet) - http://www.tecno-mobile.com/index.php/product?filterby=smart&list_order=all&page=1
363
- 'TecnoTablet' => 'TECNO P9',
364
- // JXD (consoles & tablets) - http://jxd.hk/products.asp?selectclassid=009008&clsid=3
365
- 'JXDTablet' => 'Android.*\b(F3000|A3300|JXD5000|JXD3000|JXD2000|JXD300B|JXD300|S5800|S7800|S602b|S5110b|S7300|S5300|S602|S603|S5100|S5110|S601|S7100a|P3000F|P3000s|P101|P200s|P1000m|P200m|P9100|P1000s|S6600b|S908|P1000|P300|S18|S6600|S9100)\b',
366
- // i-Joy tablets - http://www.i-joy.es/en/cat/products/tablets/
367
- 'iJoyTablet' => 'Tablet (Spirit 7|Essentia|Galatea|Fusion|Onix 7|Landa|Titan|Scooby|Deox|Stella|Themis|Argon|Unique 7|Sygnus|Hexen|Finity 7|Cream|Cream X2|Jade|Neon 7|Neron 7|Kandy|Scape|Saphyr 7|Rebel|Biox|Rebel|Rebel 8GB|Myst|Draco 7|Myst|Tab7-004|Myst|Tadeo Jones|Tablet Boing|Arrow|Draco Dual Cam|Aurix|Mint|Amity|Revolution|Finity 9|Neon 9|T9w|Amity 4GB Dual Cam|Stone 4GB|Stone 8GB|Andromeda|Silken|X2|Andromeda II|Halley|Flame|Saphyr 9,7|Touch 8|Planet|Triton|Unique 10|Hexen 10|Memphis 4GB|Memphis 8GB|Onix 10)',
368
- // http://www.intracon.eu/tablet
369
- 'FX2Tablet' => 'FX2 PAD7|FX2 PAD10',
370
- // http://www.xoro.de/produkte/
371
- // @note: Might be the same brand with 'Simply tablets'
372
- 'XoroTablet' => 'KidsPAD 701|PAD[ ]?712|PAD[ ]?714|PAD[ ]?716|PAD[ ]?717|PAD[ ]?718|PAD[ ]?720|PAD[ ]?721|PAD[ ]?722|PAD[ ]?790|PAD[ ]?792|PAD[ ]?900|PAD[ ]?9715D|PAD[ ]?9716DR|PAD[ ]?9718DR|PAD[ ]?9719QR|PAD[ ]?9720QR|TelePAD1030|Telepad1032|TelePAD730|TelePAD731|TelePAD732|TelePAD735Q|TelePAD830|TelePAD9730|TelePAD795|MegaPAD 1331|MegaPAD 1851|MegaPAD 2151',
373
- // http://www1.viewsonic.com/products/computing/tablets/
374
- 'ViewsonicTablet' => 'ViewPad 10pi|ViewPad 10e|ViewPad 10s|ViewPad E72|ViewPad7|ViewPad E100|ViewPad 7e|ViewSonic VB733|VB100a',
375
- // http://www.odys.de/web/internet-tablet_en.html
376
- 'OdysTablet' => 'LOOX|XENO10|ODYS[ -](Space|EVO|Xpress|NOON)|\bXELIO\b|Xelio10Pro|XELIO7PHONETAB|XELIO10EXTREME|XELIOPT2|NEO_QUAD10',
377
- // http://www.captiva-power.de/products.html#tablets-en
378
- 'CaptivaTablet' => 'CAPTIVA PAD',
379
- // IconBIT - http://www.iconbit.com/products/tablets/
380
- 'IconbitTablet' => 'NetTAB|NT-3702|NT-3702S|NT-3702S|NT-3603P|NT-3603P|NT-0704S|NT-0704S|NT-3805C|NT-3805C|NT-0806C|NT-0806C|NT-0909T|NT-0909T|NT-0907S|NT-0907S|NT-0902S|NT-0902S',
381
- // @ref: http://www.teclast.com/topic.php?channelID=70&topicID=140&pid=63
382
- 'TeclastTablet' => '\(Linux;\sAndroid\s[\d\.]+;\s[PXGAT]\d{2,}.*\sBuild/.*?\)',
383
- 'JaytechTablet' => 'TPC-PA762',
384
- 'BlaupunktTablet' => 'Endeavour 800NG|Endeavour 1010',
385
- // @ref: http://www.digma.ru/support/download/
386
- // @todo: Ebooks also (if requested)
387
- 'DigmaTablet' => '\b(iDx10|iDx9|iDx8|iDx7|iDxD7|iDxD8|iDsQ8|iDsQ7|iDsQ8|iDsD10|iDnD7|3TS804H|iDsQ11|iDj7|iDs10)\b',
388
- // http://www.evolioshop.com/ro/tablete-pc.html
389
- // http://www.evolio.ro/support/downloads_static.html?cat=2
390
- // @todo: Research some more
391
- 'EvolioTablet' => 'ARIA_Mini_wifi|Aria[ _]Mini|Evolio X10|Evolio X7|Evolio X8|\bEvotab\b|\bNeura\b',
392
- // http://www.pocketbook-int.com/ru/support
393
- 'PocketBookTablet' => 'Pocketbook',
394
- // @ref: http://www.tesco.com/direct/hudl/
395
- 'Hudl' => 'Hudl HT7S3',
396
- // @ref: http://www.telstra.com.au/home-phone/thub-2/
397
- 'TelstraTablet' => 'T-Hub2',
398
- 'GenericTablet' => 'Android.*\b97D\b|Tablet(?!.*PC)|BNTV250A|MID-WCDMA|LogicPD Zoom2|\bA7EB\b|CatNova8|A1_07|CT704|CT1002|\bM721\b|rk30sdk|\bEVOTAB\b|M758A|ET904|ALUMIUM10|Smartfren Tab|Endeavour 1010|Tablet-PC-4|Tagi Tab|\bM6pro\b|CT1020W'
399
- );
400
-
401
- /**
402
- * List of mobile Operating Systems.
403
- *
404
- * @var array
405
- */
406
- protected static $operatingSystems = array(
407
- 'AndroidOS' => 'Android',
408
- 'BlackBerryOS' => 'blackberry|\bBB10\b|rim tablet os',
409
- 'PalmOS' => 'PalmOS|avantgo|blazer|elaine|hiptop|palm|plucker|xiino',
410
- 'SymbianOS' => 'Symbian|SymbOS|Series60|Series40|SYB-[0-9]+|\bS60\b',
411
- // @reference: http://en.wikipedia.org/wiki/Windows_Mobile
412
- 'WindowsMobileOS' => 'Windows CE.*(PPC|Smartphone|Mobile|[0-9]{3}x[0-9]{3})|Window Mobile|Windows Phone [0-9.]+|WCE;',
413
- // @reference: http://en.wikipedia.org/wiki/Windows_Phone
414
- // http://wifeng.cn/?r=blog&a=view&id=106
415
- // http://nicksnettravels.builttoroam.com/post/2011/01/10/Bogus-Windows-Phone-7-User-Agent-String.aspx
416
- // http://msdn.microsoft.com/library/ms537503.aspx
417
- 'WindowsPhoneOS' => 'Windows Phone 8.0|Windows Phone OS|XBLWP7|ZuneWP7|Windows NT 6.[23]; ARM;',
418
- 'iOS' => '\biPhone.*Mobile|\biPod|\biPad',
419
- // http://en.wikipedia.org/wiki/MeeGo
420
- // @todo: research MeeGo in UAs
421
- 'MeeGoOS' => 'MeeGo',
422
- // http://en.wikipedia.org/wiki/Maemo
423
- // @todo: research Maemo in UAs
424
- 'MaemoOS' => 'Maemo',
425
- 'JavaOS' => 'J2ME/|\bMIDP\b|\bCLDC\b', // '|Java/' produces bug #135
426
- 'webOS' => 'webOS|hpwOS',
427
- 'badaOS' => '\bBada\b',
428
- 'BREWOS' => 'BREW',
429
- );
430
-
431
- /**
432
- * List of mobile User Agents.
433
- *
434
- * @var array
435
- */
436
- protected static $browsers = array(
437
- // @reference: https://developers.google.com/chrome/mobile/docs/user-agent
438
- 'Chrome' => '\bCrMo\b|CriOS|Android.*Chrome/[.0-9]* (Mobile)?',
439
- 'Dolfin' => '\bDolfin\b',
440
- 'Opera' => 'Opera.*Mini|Opera.*Mobi|Android.*Opera|Mobile.*OPR/[0-9.]+|Coast/[0-9.]+',
441
- 'Skyfire' => 'Skyfire',
442
- 'IE' => 'IEMobile|MSIEMobile', // |Trident/[.0-9]+
443
- 'Firefox' => 'fennec|firefox.*maemo|(Mobile|Tablet).*Firefox|Firefox.*Mobile',
444
- 'Bolt' => 'bolt',
445
- 'TeaShark' => 'teashark',
446
- 'Blazer' => 'Blazer',
447
- // @reference: http://developer.apple.com/library/safari/#documentation/AppleApplications/Reference/SafariWebContent/OptimizingforSafarioniPhone/OptimizingforSafarioniPhone.html#//apple_ref/doc/uid/TP40006517-SW3
448
- 'Safari' => 'Version.*Mobile.*Safari|Safari.*Mobile|MobileSafari',
449
- // @ref: http://en.wikipedia.org/wiki/Midori_(web_browser)
450
- //'Midori' => 'midori',
451
- 'Tizen' => 'Tizen',
452
- 'UCBrowser' => 'UC.*Browser|UCWEB',
453
- 'baiduboxapp' => 'baiduboxapp',
454
- 'baidubrowser' => 'baidubrowser',
455
- // @ref: https://github.com/serbanghita/Mobile-Detect/issues/7
456
- 'DiigoBrowser' => 'DiigoBrowser',
457
- // http://www.puffinbrowser.com/index.php
458
- 'Puffin' => 'Puffin',
459
- // @ref: http://mercury-browser.com/index.html
460
- 'Mercury' => '\bMercury\b',
461
- // @ref: http://en.wikipedia.org/wiki/Obigo_Browser
462
- 'ObigoBrowser' => 'Obigo',
463
- // @ref: http://en.wikipedia.org/wiki/NetFront
464
- 'NetFront' => 'NF-Browser',
465
- // @reference: http://en.wikipedia.org/wiki/Minimo
466
- // http://en.wikipedia.org/wiki/Vision_Mobile_Browser
467
- 'GenericBrowser' => 'NokiaBrowser|OviBrowser|OneBrowser|TwonkyBeamBrowser|SEMC.*Browser|FlyFlow|Minimo|NetFront|Novarra-Vision|MQQBrowser|MicroMessenger',
468
- );
469
-
470
- /**
471
- * Utilities.
472
- *
473
- * @var array
474
- */
475
- protected static $utilities = array(
476
- // Experimental. When a mobile device wants to switch to 'Desktop Mode'.
477
- // @ref: http://scottcate.com/technology/windows-phone-8-ie10-desktop-or-mobile/
478
- // @ref: https://github.com/serbanghita/Mobile-Detect/issues/57#issuecomment-15024011
479
- 'DesktopMode' => 'WPDesktop',
480
- 'TV' => 'SonyDTV|HbbTV', // experimental
481
- 'WebKit' => '(webkit)[ /]([\w.]+)',
482
- 'Bot' => 'Googlebot|DoCoMo|YandexBot|bingbot|ia_archiver|AhrefsBot|Ezooms|GSLFbot|WBSearchBot|Twitterbot|TweetmemeBot|Twikle|PaperLiBot|Wotbox|UnwindFetchor|facebookexternalhit',
483
- 'MobileBot' => 'Googlebot-Mobile|DoCoMo|YahooSeeker/M1A1-R2D2',
484
- // @todo: Include JXD consoles.
485
- 'Console' => '\b(Nintendo|Nintendo WiiU|PLAYSTATION|Xbox)\b',
486
- 'Watch' => 'SM-V700',
487
- );
488
-
489
- /**
490
- * All possible HTTP headers that represent the
491
- * User-Agent string.
492
- *
493
- * @var array
494
- */
495
- protected static $uaHttpHeaders = array(
496
- // The default User-Agent string.
497
- 'HTTP_USER_AGENT',
498
- // Header can occur on devices using Opera Mini.
499
- 'HTTP_X_OPERAMINI_PHONE_UA',
500
- // Vodafone specific header: http://www.seoprinciple.com/mobile-web-community-still-angry-at-vodafone/24/
501
- 'HTTP_X_DEVICE_USER_AGENT',
502
- 'HTTP_X_ORIGINAL_USER_AGENT',
503
- 'HTTP_X_SKYFIRE_PHONE',
504
- 'HTTP_X_BOLT_PHONE_UA',
505
- 'HTTP_DEVICE_STOCK_UA',
506
- 'HTTP_X_UCBROWSER_DEVICE_UA'
507
- );
508
-
509
- /**
510
- * The individual segments that could exist in a User-Agent string. VER refers to the regular
511
- * expression defined in the constant self::VER.
512
- *
513
- * @var array
514
- */
515
- protected static $properties = array(
516
-
517
- // Build
518
- 'Mobile' => 'Mobile/[VER]',
519
- 'Build' => 'Build/[VER]',
520
- 'Version' => 'Version/[VER]',
521
- 'VendorID' => 'VendorID/[VER]',
522
-
523
- // Devices
524
- 'iPad' => 'iPad.*CPU[a-z ]+[VER]',
525
- 'iPhone' => 'iPhone.*CPU[a-z ]+[VER]',
526
- 'iPod' => 'iPod.*CPU[a-z ]+[VER]',
527
- //'BlackBerry' => array('BlackBerry[VER]', 'BlackBerry [VER];'),
528
- 'Kindle' => 'Kindle/[VER]',
529
-
530
- // Browser
531
- 'Chrome' => array('Chrome/[VER]', 'CriOS/[VER]', 'CrMo/[VER]'),
532
- 'Coast' => array('Coast/[VER]'),
533
- 'Dolfin' => 'Dolfin/[VER]',
534
- // @reference: https://developer.mozilla.org/en-US/docs/User_Agent_Strings_Reference
535
- 'Firefox' => 'Firefox/[VER]',
536
- 'Fennec' => 'Fennec/[VER]',
537
- // @reference: http://msdn.microsoft.com/en-us/library/ms537503(v=vs.85).aspx
538
- 'IE' => array('IEMobile/[VER];', 'IEMobile [VER]', 'MSIE [VER];'),
539
- // http://en.wikipedia.org/wiki/NetFront
540
- 'NetFront' => 'NetFront/[VER]',
541
- 'NokiaBrowser' => 'NokiaBrowser/[VER]',
542
- 'Opera' => array( ' OPR/[VER]', 'Opera Mini/[VER]', 'Version/[VER]' ),
543
- 'Opera Mini' => 'Opera Mini/[VER]',
544
- 'Opera Mobi' => 'Version/[VER]',
545
- 'UC Browser' => 'UC Browser[VER]',
546
- 'MQQBrowser' => 'MQQBrowser/[VER]',
547
- 'MicroMessenger' => 'MicroMessenger/[VER]',
548
- 'baiduboxapp' => 'baiduboxapp/[VER]',
549
- 'baidubrowser' => 'baidubrowser/[VER]',
550
- // @note: Safari 7534.48.3 is actually Version 5.1.
551
- // @note: On BlackBerry the Version is overwriten by the OS.
552
- 'Safari' => array( 'Version/[VER]', 'Safari/[VER]' ),
553
- 'Skyfire' => 'Skyfire/[VER]',
554
- 'Tizen' => 'Tizen/[VER]',
555
- 'Webkit' => 'webkit[ /][VER]',
556
-
557
- // Engine
558
- 'Gecko' => 'Gecko/[VER]',
559
- 'Trident' => 'Trident/[VER]',
560
- 'Presto' => 'Presto/[VER]',
561
-
562
- // OS
563
- 'iOS' => ' \bOS\b [VER] ',
564
- 'Android' => 'Android [VER]',
565
- 'BlackBerry' => array('BlackBerry[\w]+/[VER]', 'BlackBerry.*Version/[VER]', 'Version/[VER]'),
566
- 'BREW' => 'BREW [VER]',
567
- 'Java' => 'Java/[VER]',
568
- // @reference: http://windowsteamblog.com/windows_phone/b/wpdev/archive/2011/08/29/introducing-the-ie9-on-windows-phone-mango-user-agent-string.aspx
569
- // @reference: http://en.wikipedia.org/wiki/Windows_NT#Releases
570
- 'Windows Phone OS' => array( 'Windows Phone OS [VER]', 'Windows Phone [VER]'),
571
- 'Windows Phone' => 'Windows Phone [VER]',
572
- 'Windows CE' => 'Windows CE/[VER]',
573
- // http://social.msdn.microsoft.com/Forums/en-US/windowsdeveloperpreviewgeneral/thread/6be392da-4d2f-41b4-8354-8dcee20c85cd
574
- 'Windows NT' => 'Windows NT [VER]',
575
- 'Symbian' => array('SymbianOS/[VER]', 'Symbian/[VER]'),
576
- 'webOS' => array('webOS/[VER]', 'hpwOS/[VER];'),
577
- );
578
-
579
- /**
580
- * Construct an instance of this class.
581
- *
582
- * @param array $headers Specify the headers as injection. Should be PHP _SERVER flavored.
583
- * If left empty, will use the global _SERVER['HTTP_*'] vars instead.
584
- * @param string $userAgent Inject the User-Agent header. If null, will use HTTP_USER_AGENT
585
- * from the $headers array instead.
586
- */
587
- public function __construct(
588
- array $headers = null,
589
- $userAgent = null
590
- ) {
591
- $this->setHttpHeaders($headers);
592
- $this->setUserAgent($userAgent);
593
- }
594
-
595
- /**
596
- * Get the current script version.
597
- * This is useful for the demo.php file,
598
- * so people can check on what version they are testing
599
- * for mobile devices.
600
- *
601
- * @return string The version number in semantic version format.
602
- */
603
- public static function getScriptVersion()
604
- {
605
- return self::VERSION;
606
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
607
 
608
- /**
609
- * Set the HTTP Headers. Must be PHP-flavored. This method will reset existing headers.
610
- *
611
- * @param array $httpHeaders The headers to set. If null, then using PHP's _SERVER to extract
612
- * the headers. The default null is left for backwards compatibilty.
613
- */
614
- public function setHttpHeaders($httpHeaders = null)
615
- {
616
- //use global _SERVER if $httpHeaders aren't defined
617
- if (!is_array($httpHeaders) || !count($httpHeaders)) {
618
- $httpHeaders = $_SERVER;
619
  }
620
 
621
- //clear existing headers
622
- $this->httpHeaders = array();
 
 
 
 
 
 
 
 
 
 
 
 
623
 
624
- //Only save HTTP headers. In PHP land, that means only _SERVER vars that
625
- //start with HTTP_.
626
- foreach ($httpHeaders as $key => $value) {
627
- if (substr($key,0,5) == 'HTTP_') {
628
- $this->httpHeaders[$key] = $value;
 
629
  }
 
 
 
630
  }
631
- }
632
 
633
- /**
634
- * Retrieves the HTTP headers.
635
- *
636
- * @return array
637
- */
638
- public function getHttpHeaders()
639
- {
640
- return $this->httpHeaders;
641
- }
642
 
643
- /**
644
- * Retrieves a particular header. If it doesn't exist, no exception/error is caused.
645
- * Simply null is returned.
646
- *
647
- * @param string $header The name of the header to retrieve. Can be HTTP compliant such as
648
- * "User-Agent" or "X-Device-User-Agent" or can be php-esque with the
649
- * all-caps, HTTP_ prefixed, underscore seperated awesomeness.
650
- *
651
- * @return string|null The value of the header.
652
- */
653
- public function getHttpHeader($header)
654
- {
655
- //are we using PHP-flavored headers?
656
- if (strpos($header, '_') === false) {
657
- $header = str_replace('-', '_', $header);
658
- $header = strtoupper($header);
 
 
 
 
 
 
 
 
 
 
 
 
659
  }
660
 
661
- //test the alternate, too
662
- $altHeader = 'HTTP_' . $header;
 
663
 
664
- //Test both the regular and the HTTP_ prefix
665
- if (isset($this->httpHeaders[$header])) {
666
- return $this->httpHeaders[$header];
667
- } elseif (isset($this->httpHeaders[$altHeader])) {
668
- return $this->httpHeaders[$altHeader];
 
 
 
669
  }
670
 
671
- return null;
672
- }
673
 
674
- public function getMobileHeaders()
675
- {
676
- return self::$mobileHeaders;
677
- }
 
 
 
 
 
 
 
 
 
678
 
679
- /**
680
- * Get all possible HTTP headers that
681
- * can contain the User-Agent string.
682
- *
683
- * @return array List of HTTP headers.
684
- */
685
- public function getUaHttpHeaders()
686
- {
687
- return self::$uaHttpHeaders;
688
- }
689
 
690
- /**
691
- * Set the User-Agent to be used.
692
- *
693
- * @param string $userAgent The user agent string to set.
694
- *
695
- * @return string|null
696
- */
697
- public function setUserAgent($userAgent = null)
698
- {
699
- if (!empty($userAgent)) {
700
- return $this->userAgent = $userAgent;
701
- } else {
702
-
703
- $this->userAgent = null;
704
-
705
- foreach ($this->getUaHttpHeaders() as $altHeader) {
706
- if (!empty($this->httpHeaders[$altHeader])) { // @todo: should use getHttpHeader(), but it would be slow. (Serban)
707
- $this->userAgent .= $this->httpHeaders[$altHeader] . " ";
708
  }
709
  }
710
 
711
- return $this->userAgent = (!empty($this->userAgent) ? trim($this->userAgent) : null);
 
712
 
 
 
 
 
 
 
 
713
  }
714
- }
715
 
716
- /**
717
- * Retrieve the User-Agent.
718
- *
719
- * @return string|null The user agent if it's set.
720
- */
721
- public function getUserAgent()
722
- {
723
- return $this->userAgent;
724
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
725
 
726
- /**
727
- * Set the detection type. Must be one of self::DETECTION_TYPE_MOBILE or
728
- * self::DETECTION_TYPE_EXTENDED. Otherwise, nothing is set.
729
- *
730
- * @deprecated since version 2.6.9
731
- *
732
- * @param string $type The type. Must be a self::DETECTION_TYPE_* constant. The default
733
- * parameter is null which will default to self::DETECTION_TYPE_MOBILE.
734
- */
735
- public function setDetectionType($type = null)
736
- {
737
- if ($type === null) {
738
- $type = self::DETECTION_TYPE_MOBILE;
739
  }
740
 
741
- if ($type != self::DETECTION_TYPE_MOBILE && $type != self::DETECTION_TYPE_EXTENDED) {
742
- return;
 
 
 
 
 
743
  }
744
 
745
- $this->detectionType = $type;
746
- }
 
 
 
 
 
 
 
 
 
 
 
747
 
748
- /**
749
- * Retrieve the list of known phone devices.
750
- *
751
- * @return array List of phone devices.
752
- */
753
- public static function getPhoneDevices()
754
- {
755
- return self::$phoneDevices;
756
- }
757
 
758
- /**
759
- * Retrieve the list of known tablet devices.
760
- *
761
- * @return array List of tablet devices.
762
- */
763
- public static function getTabletDevices()
764
- {
765
- return self::$tabletDevices;
766
- }
767
 
768
- /**
769
- * Alias for getBrowsers() method.
770
- *
771
- * @return array List of user agents.
772
- */
773
- public static function getUserAgents()
774
- {
775
- return self::getBrowsers();
776
- }
777
 
778
- /**
779
- * Retrieve the list of known browsers. Specifically, the user agents.
780
- *
781
- * @return array List of browsers / user agents.
782
- */
783
- public static function getBrowsers()
784
- {
785
- return self::$browsers;
786
- }
787
 
788
- /**
789
- * Retrieve the list of known utilities.
790
- *
791
- * @return array List of utilities.
792
- */
793
- public static function getUtilities()
794
- {
795
- return self::$utilities;
796
- }
797
 
798
- /**
799
- * Method gets the mobile detection rules. This method is used for the magic methods $detect->is*().
800
- *
801
- * @deprecated since version 2.6.9
802
- *
803
- * @return array All the rules (but not extended).
804
- */
805
- public static function getMobileDetectionRules()
806
- {
807
- static $rules;
808
-
809
- if (!$rules) {
810
- $rules = array_merge(
811
- self::$phoneDevices,
812
- self::$tabletDevices,
813
- self::$operatingSystems,
814
- self::$browsers
815
- );
816
  }
817
 
818
- return $rules;
 
 
 
 
 
 
 
819
 
820
- }
 
 
 
 
 
 
 
821
 
822
- /**
823
- * Method gets the mobile detection rules + utilities.
824
- * The reason this is separate is because utilities rules
825
- * don't necessary imply mobile. This method is used inside
826
- * the new $detect->is('stuff') method.
827
- *
828
- * @deprecated since version 2.6.9
829
- *
830
- * @return array All the rules + extended.
831
- */
832
- public function getMobileDetectionRulesExtended()
833
- {
834
- static $rules;
835
-
836
- if (!$rules) {
837
- // Merge all rules together.
838
- $rules = array_merge(
839
- self::$phoneDevices,
840
- self::$tabletDevices,
841
- self::$operatingSystems,
842
- self::$browsers,
843
- self::$utilities
844
- );
845
  }
846
 
847
- return $rules;
848
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
849
 
850
- /**
851
- * Retrieve the current set of rules.
852
- *
853
- * @deprecated since version 2.6.9
854
- *
855
- * @return array
856
- */
857
- public function getRules()
858
- {
859
- if ($this->detectionType == self::DETECTION_TYPE_EXTENDED) {
860
- return self::getMobileDetectionRulesExtended();
861
- } else {
862
- return self::getMobileDetectionRules();
863
  }
864
- }
865
 
866
- /**
867
- * Retrieve the list of mobile operating systems.
868
- *
869
- * @return array The list of mobile operating systems.
870
- */
871
- public static function getOperatingSystems()
872
- {
873
- return self::$operatingSystems;
874
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
875
 
876
- /**
877
- * Check the HTTP headers for signs of mobile.
878
- * This is the fastest mobile check possible; it's used
879
- * inside isMobile() method.
880
- *
881
- * @return bool
882
- */
883
- public function checkHttpHeadersForMobile()
884
- {
885
-
886
- foreach ($this->getMobileHeaders() as $mobileHeader => $matchType) {
887
- if ( isset($this->httpHeaders[$mobileHeader]) ) {
888
- if ( is_array($matchType['matches']) ) {
889
- foreach ($matchType['matches'] as $_match) {
890
- if ( strpos($this->httpHeaders[$mobileHeader], $_match) !== false ) {
891
- return true;
892
- }
893
- }
894
 
895
- return false;
896
- } else {
897
- return true;
898
- }
 
 
 
 
 
 
 
 
899
  }
900
  }
901
 
902
- return false;
 
 
 
 
 
 
 
903
 
904
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
905
 
906
- /**
907
- * Magic overloading method.
908
- *
909
- * @method boolean is[...]()
910
- * @param string $name
911
- * @param array $arguments
912
- * @return mixed
913
- * @throws BadMethodCallException when the method doesn't exist and doesn't start with 'is'
914
- */
915
- public function __call($name, $arguments)
916
- {
917
- //make sure the name starts with 'is', otherwise
918
- if (substr($name, 0, 2) != 'is') {
919
- throw new BadMethodCallException("No such method exists: $name");
920
  }
921
 
922
- $this->setDetectionType(self::DETECTION_TYPE_MOBILE);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
923
 
924
- $key = substr($name, 2);
925
 
926
- return $this->matchUAAgainstKey($key);
927
- }
928
 
929
- /**
930
- * Find a detection rule that matches the current User-agent.
931
- *
932
- * @param null $userAgent deprecated
933
- * @return boolean
934
- */
935
- protected function matchDetectionRulesAgainstUA($userAgent = null)
936
- {
937
- // Begin general search.
938
- foreach ($this->getRules() as $_regex) {
939
- if (empty($_regex)) {
940
- continue;
941
- }
942
- if ($this->match($_regex, $userAgent)) {
943
- return true;
944
- }
945
  }
946
 
947
- return false;
948
- }
 
 
 
 
 
 
 
 
 
 
 
949
 
950
- /**
951
- * Search for a certain key in the rules array.
952
- * If the key is found the try to match the corresponding
953
- * regex agains the User-Agent.
954
- *
955
- * @param string $key
956
- * @param null $userAgent deprecated
957
- * @return mixed
958
- */
959
- protected function matchUAAgainstKey($key, $userAgent = null)
960
- {
961
- // Make the keys lowercase so we can match: isIphone(), isiPhone(), isiphone(), etc.
962
- $key = strtolower($key);
963
-
964
- //change the keys to lower case
965
- $_rules = array_change_key_case($this->getRules());
966
-
967
- if (array_key_exists($key, $_rules)) {
968
- if (empty($_rules[$key])) {
969
- return null;
970
  }
971
 
972
- return $this->match($_rules[$key], $userAgent);
973
  }
974
 
975
- return false;
976
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
977
 
978
- /**
979
- * Check if the device is mobile.
980
- * Returns true if any type of mobile device detected, including special ones
981
- * @param null $userAgent deprecated
982
- * @param null $httpHeaders deprecated
983
- * @return bool
984
- */
985
- public function isMobile($userAgent = null, $httpHeaders = null)
986
- {
987
-
988
- if ($httpHeaders) {
989
- $this->setHttpHeaders($httpHeaders);
990
- }
991
 
992
- if ($userAgent) {
993
- $this->setUserAgent($userAgent);
994
  }
995
 
996
- $this->setDetectionType(self::DETECTION_TYPE_MOBILE);
 
 
 
 
 
 
 
 
 
 
 
 
 
997
 
998
- if ($this->checkHttpHeadersForMobile()) {
999
- return true;
1000
- } else {
1001
- return $this->matchDetectionRulesAgainstUA();
1002
- }
1003
 
1004
- }
 
 
 
 
 
 
1005
 
1006
- /**
1007
- * Check if the device is a tablet.
1008
- * Return true if any type of tablet device is detected.
1009
- *
1010
- * @param string $userAgent deprecated
1011
- * @param array $httpHeaders deprecated
1012
- * @return bool
1013
- */
1014
- public function isTablet($userAgent = null, $httpHeaders = null)
1015
- {
1016
- $this->setDetectionType(self::DETECTION_TYPE_MOBILE);
1017
-
1018
- foreach (self::$tabletDevices as $_regex) {
1019
- if ($this->match($_regex, $userAgent)) {
1020
  return true;
 
 
1021
  }
 
1022
  }
1023
 
1024
- return false;
1025
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1026
 
1027
- /**
1028
- * This method checks for a certain property in the
1029
- * userAgent.
1030
- * @todo: The httpHeaders part is not yet used.
1031
- *
1032
- * @param string $key
1033
- * @param string $userAgent deprecated
1034
- * @param string $httpHeaders deprecated
1035
- * @return bool|int|null
1036
- */
1037
- public function is($key, $userAgent = null, $httpHeaders = null)
1038
- {
1039
- // Set the UA and HTTP headers only if needed (eg. batch mode).
1040
- if ($httpHeaders) {
1041
- $this->setHttpHeaders($httpHeaders);
1042
- }
1043
 
1044
- if ($userAgent) {
1045
- $this->setUserAgent($userAgent);
1046
- }
 
 
1047
 
1048
- $this->setDetectionType(self::DETECTION_TYPE_EXTENDED);
 
1049
 
1050
- return $this->matchUAAgainstKey($key);
1051
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1052
 
1053
- /**
1054
- * Some detection rules are relative (not standard),
1055
- * because of the diversity of devices, vendors and
1056
- * their conventions in representing the User-Agent or
1057
- * the HTTP headers.
1058
- *
1059
- * This method will be used to check custom regexes against
1060
- * the User-Agent string.
1061
- *
1062
- * @param $regex
1063
- * @param string $userAgent
1064
- * @return bool
1065
- *
1066
- * @todo: search in the HTTP headers too.
1067
- */
1068
- public function match($regex, $userAgent = null)
1069
- {
1070
- // Escape the special character which is the delimiter.
1071
- $regex = str_replace('/', '\/', $regex);
1072
-
1073
- return (bool) preg_match('/'.$regex.'/is', (!empty($userAgent) ? $userAgent : $this->userAgent));
1074
- }
1075
 
1076
- /**
1077
- * Get the properties array.
1078
- *
1079
- * @return array
1080
- */
1081
- public static function getProperties()
1082
- {
1083
- return self::$properties;
1084
- }
1085
 
1086
- /**
1087
- * Prepare the version number.
1088
- *
1089
- * @todo Remove the error supression from str_replace() call.
1090
- *
1091
- * @param string $ver The string version, like "2.6.21.2152";
1092
- *
1093
- * @return float
1094
- */
1095
- public function prepareVersionNo($ver)
1096
- {
1097
- $ver = str_replace(array('_', ' ', '/'), '.', $ver);
1098
- $arrVer = explode('.', $ver, 2);
1099
-
1100
- if (isset($arrVer[1])) {
1101
- $arrVer[1] = @str_replace('.', '', $arrVer[1]); // @todo: treat strings versions.
1102
  }
1103
 
1104
- return (float) implode('.', $arrVer);
1105
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1106
 
1107
- /**
1108
- * Check the version of the given property in the User-Agent.
1109
- * Will return a float number. (eg. 2_0 will return 2.0, 4.3.1 will return 4.31)
1110
- *
1111
- * @param string $propertyName The name of the property. See self::getProperties() array
1112
- * keys for all possible properties.
1113
- * @param string $type Either self::VERSION_TYPE_STRING to get a string value or
1114
- * self::VERSION_TYPE_FLOAT indicating a float value. This parameter
1115
- * is optional and defaults to self::VERSION_TYPE_STRING. Passing an
1116
- * invalid parameter will default to the this type as well.
1117
- *
1118
- * @return string|float The version of the property we are trying to extract.
1119
- */
1120
- public function version($propertyName, $type = self::VERSION_TYPE_STRING)
1121
- {
1122
- if (empty($propertyName)) {
1123
- return false;
1124
  }
1125
 
1126
- //set the $type to the default if we don't recognize the type
1127
- if ($type != self::VERSION_TYPE_STRING && $type != self::VERSION_TYPE_FLOAT) {
1128
- $type = self::VERSION_TYPE_STRING;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1129
  }
1130
 
1131
- $properties = self::getProperties();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1132
 
1133
- // Check if the property exists in the properties array.
1134
- if (array_key_exists($propertyName, $properties)) {
1135
 
1136
- // Prepare the pattern to be matched.
1137
- // Make sure we always deal with an array (string is converted).
1138
- $properties[$propertyName] = (array) $properties[$propertyName];
1139
 
1140
- foreach ($properties[$propertyName] as $propertyMatchString) {
1141
 
1142
- $propertyPattern = str_replace('[VER]', self::VER, $propertyMatchString);
1143
 
1144
- // Escape the special character which is the delimiter.
1145
- $propertyPattern = str_replace('/', '\/', $propertyPattern);
1146
 
1147
- // Identify and extract the version.
1148
- preg_match('/'.$propertyPattern.'/is', $this->userAgent, $match);
1149
 
1150
- if (!empty($match[1])) {
1151
- $version = ( $type == self::VERSION_TYPE_FLOAT ? $this->prepareVersionNo($match[1]) : $match[1] );
1152
 
1153
- return $version;
1154
  }
1155
 
1156
  }
1157
 
 
1158
  }
1159
 
1160
- return false;
1161
- }
1162
-
1163
- /**
1164
- * Retrieve the mobile grading, using self::MOBILE_GRADE_* constants.
1165
- *
1166
- * @return string One of the self::MOBILE_GRADE_* constants.
1167
- */
1168
- public function mobileGrade()
1169
- {
1170
- $isMobile = $this->isMobile();
1171
-
1172
- if (
1173
- // Apple iOS 3.2-5.1 - Tested on the original iPad (4.3 / 5.0), iPad 2 (4.3), iPad 3 (5.1), original iPhone (3.1), iPhone 3 (3.2), 3GS (4.3), 4 (4.3 / 5.0), and 4S (5.1)
1174
- $this->isIOS() && $this->version('iPad', self::VERSION_TYPE_FLOAT)>=4.3 ||
1175
- $this->isIOS() && $this->version('iPhone', self::VERSION_TYPE_FLOAT)>=3.1 ||
1176
- $this->isIOS() && $this->version('iPod', self::VERSION_TYPE_FLOAT)>=3.1 ||
1177
 
1178
- // Android 2.1-2.3 - Tested on the HTC Incredible (2.2), original Droid (2.2), HTC Aria (2.1), Google Nexus S (2.3). Functional on 1.5 & 1.6 but performance may be sluggish, tested on Google G1 (1.5)
1179
- // Android 3.1 (Honeycomb) - Tested on the Samsung Galaxy Tab 10.1 and Motorola XOOM
1180
- // Android 4.0 (ICS) - Tested on a Galaxy Nexus. Note: transition performance can be poor on upgraded devices
1181
- // Android 4.1 (Jelly Bean) - Tested on a Galaxy Nexus and Galaxy 7
1182
- ( $this->version('Android', self::VERSION_TYPE_FLOAT)>2.1 && $this->is('Webkit') ) ||
1183
 
1184
- // Windows Phone 7-7.5 - Tested on the HTC Surround (7.0) HTC Trophy (7.5), LG-E900 (7.5), Nokia Lumia 800
1185
- $this->version('Windows Phone OS', self::VERSION_TYPE_FLOAT)>=7.0 ||
 
 
 
1186
 
1187
- // Blackberry 7 - Tested on BlackBerry Torch 9810
1188
- // Blackberry 6.0 - Tested on the Torch 9800 and Style 9670
1189
- $this->is('BlackBerry') && $this->version('BlackBerry', self::VERSION_TYPE_FLOAT)>=6.0 ||
1190
- // Blackberry Playbook (1.0-2.0) - Tested on PlayBook
1191
- $this->match('Playbook.*Tablet') ||
1192
 
1193
- // Palm WebOS (1.4-2.0) - Tested on the Palm Pixi (1.4), Pre (1.4), Pre 2 (2.0)
1194
- ( $this->version('webOS', self::VERSION_TYPE_FLOAT)>=1.4 && $this->match('Palm|Pre|Pixi') ) ||
1195
- // Palm WebOS 3.0 - Tested on HP TouchPad
1196
- $this->match('hp.*TouchPad') ||
1197
 
1198
- // Firefox Mobile (12 Beta) - Tested on Android 2.3 device
1199
- ( $this->is('Firefox') && $this->version('Firefox', self::VERSION_TYPE_FLOAT)>=12 ) ||
 
 
1200
 
1201
- // Chrome for Android - Tested on Android 4.0, 4.1 device
1202
- ( $this->is('Chrome') && $this->is('AndroidOS') && $this->version('Android', self::VERSION_TYPE_FLOAT)>=4.0 ) ||
1203
 
1204
- // Skyfire 4.1 - Tested on Android 2.3 device
1205
- ( $this->is('Skyfire') && $this->version('Skyfire', self::VERSION_TYPE_FLOAT)>=4.1 && $this->is('AndroidOS') && $this->version('Android', self::VERSION_TYPE_FLOAT)>=2.3 ) ||
1206
 
1207
- // Opera Mobile 11.5-12: Tested on Android 2.3
1208
- ( $this->is('Opera') && $this->version('Opera Mobi', self::VERSION_TYPE_FLOAT)>11 && $this->is('AndroidOS') ) ||
1209
 
1210
- // Meego 1.2 - Tested on Nokia 950 and N9
1211
- $this->is('MeeGoOS') ||
1212
 
1213
- // Tizen (pre-release) - Tested on early hardware
1214
- $this->is('Tizen') ||
1215
 
1216
- // Samsung Bada 2.0 - Tested on a Samsung Wave 3, Dolphin browser
1217
- // @todo: more tests here!
1218
- $this->is('Dolfin') && $this->version('Bada', self::VERSION_TYPE_FLOAT)>=2.0 ||
1219
 
1220
- // UC Browser - Tested on Android 2.3 device
1221
- ( ($this->is('UC Browser') || $this->is('Dolfin')) && $this->version('Android', self::VERSION_TYPE_FLOAT)>=2.3 ) ||
 
1222
 
1223
- // Kindle 3 and Fire - Tested on the built-in WebKit browser for each
1224
- ( $this->match('Kindle Fire') ||
1225
- $this->is('Kindle') && $this->version('Kindle', self::VERSION_TYPE_FLOAT)>=3.0 ) ||
1226
 
1227
- // Nook Color 1.4.1 - Tested on original Nook Color, not Nook Tablet
1228
- $this->is('AndroidOS') && $this->is('NookTablet') ||
 
1229
 
1230
- // Chrome Desktop 11-21 - Tested on OS X 10.7 and Windows 7
1231
- $this->version('Chrome', self::VERSION_TYPE_FLOAT)>=11 && !$isMobile ||
1232
 
1233
- // Safari Desktop 4-5 - Tested on OS X 10.7 and Windows 7
1234
- $this->version('Safari', self::VERSION_TYPE_FLOAT)>=5.0 && !$isMobile ||
1235
 
1236
- // Firefox Desktop 4-13 - Tested on OS X 10.7 and Windows 7
1237
- $this->version('Firefox', self::VERSION_TYPE_FLOAT)>=4.0 && !$isMobile ||
1238
 
1239
- // Internet Explorer 7-9 - Tested on Windows XP, Vista and 7
1240
- $this->version('MSIE', self::VERSION_TYPE_FLOAT)>=7.0 && !$isMobile ||
1241
 
1242
- // Opera Desktop 10-12 - Tested on OS X 10.7 and Windows 7
1243
- // @reference: http://my.opera.com/community/openweb/idopera/
1244
- $this->version('Opera', self::VERSION_TYPE_FLOAT)>=10 && !$isMobile
1245
 
1246
- ){
1247
- return self::MOBILE_GRADE_A;
1248
- }
 
 
1249
 
1250
- if (
1251
- $this->isIOS() && $this->version('iPad', self::VERSION_TYPE_FLOAT)<4.3 ||
1252
- $this->isIOS() && $this->version('iPhone', self::VERSION_TYPE_FLOAT)<3.1 ||
1253
- $this->isIOS() && $this->version('iPod', self::VERSION_TYPE_FLOAT)<3.1 ||
1254
 
1255
- // Blackberry 5.0: Tested on the Storm 2 9550, Bold 9770
1256
- $this->is('Blackberry') && $this->version('BlackBerry', self::VERSION_TYPE_FLOAT)>=5 && $this->version('BlackBerry', self::VERSION_TYPE_FLOAT)<6 ||
1257
 
1258
- //Opera Mini (5.0-6.5) - Tested on iOS 3.2/4.3 and Android 2.3
1259
- ( $this->version('Opera Mini', self::VERSION_TYPE_FLOAT)>=5.0 && $this->version('Opera Mini', self::VERSION_TYPE_FLOAT)<=6.5 &&
1260
- ($this->version('Android', self::VERSION_TYPE_FLOAT)>=2.3 || $this->is('iOS')) ) ||
1261
 
1262
- // Nokia Symbian^3 - Tested on Nokia N8 (Symbian^3), C7 (Symbian^3), also works on N97 (Symbian^1)
1263
- $this->match('NokiaN8|NokiaC7|N97.*Series60|Symbian/3') ||
1264
 
1265
- // @todo: report this (tested on Nokia N71)
1266
- $this->version('Opera Mobi', self::VERSION_TYPE_FLOAT)>=11 && $this->is('SymbianOS')
1267
- ){
1268
- return self::MOBILE_GRADE_B;
1269
- }
1270
 
1271
- if (
1272
- // Blackberry 4.x - Tested on the Curve 8330
1273
- $this->version('BlackBerry', self::VERSION_TYPE_FLOAT)<5.0 ||
1274
- // Windows Mobile - Tested on the HTC Leo (WinMo 5.2)
1275
- $this->match('MSIEMobile|Windows CE.*Mobile') || $this->version('Windows Mobile', self::VERSION_TYPE_FLOAT)<=5.2
 
 
 
 
 
 
 
 
 
 
 
1276
 
1277
- ){
 
1278
  return self::MOBILE_GRADE_C;
1279
  }
1280
-
1281
- //All older smartphone platforms and featurephones - Any device that doesn't support media queries
1282
- //will receive the basic, C grade experience.
1283
- return self::MOBILE_GRADE_C;
1284
  }
1285
  }
8
  * Mobile_Detect is a lightweight PHP class for detecting mobile devices (including tablets).
9
  * It uses the User-Agent string combined with specific HTTP headers to detect the mobile environment.
10
  *
11
+ * @author Current authors: Serban Ghita <serbanghita@gmail.com>
12
+ * Nick Ilyin <nick.ilyin@gmail.com>
13
+ *
14
  * Original author: Victor Stanciu <vic.stanciu@gmail.com>
15
  *
16
  * @license Code and contributions have 'MIT License'
22
  * README: https://github.com/serbanghita/Mobile-Detect/blob/master/README.md
23
  * HOWTO: https://github.com/serbanghita/Mobile-Detect/wiki/Code-examples
24
  *
25
+ * @version 2.8.19
26
  */
27
+ if( ! class_exists('Mobile_Detect') ) {
28
+ class Mobile_Detect {
29
+ /**
30
+ * Mobile detection type.
31
+ *
32
+ * @deprecated since version 2.6.9
33
+ */
34
+ const DETECTION_TYPE_MOBILE = 'mobile';
35
+
36
+ /**
37
+ * Extended detection type.
38
+ *
39
+ * @deprecated since version 2.6.9
40
+ */
41
+ const DETECTION_TYPE_EXTENDED = 'extended';
42
+
43
+ /**
44
+ * A frequently used regular expression to extract version #s.
45
+ *
46
+ * @deprecated since version 2.6.9
47
+ */
48
+ const VER = '([\w._\+]+)';
49
+
50
+ /**
51
+ * Top-level device.
52
+ */
53
+ const MOBILE_GRADE_A = 'A';
54
+
55
+ /**
56
+ * Mid-level device.
57
+ */
58
+ const MOBILE_GRADE_B = 'B';
59
+
60
+ /**
61
+ * Low-level device.
62
+ */
63
+ const MOBILE_GRADE_C = 'C';
64
+
65
+ /**
66
+ * Stores the version number of the current release.
67
+ */
68
+ const VERSION = '2.8.19';
69
+
70
+ /**
71
+ * A type for the version() method indicating a string return value.
72
+ */
73
+ const VERSION_TYPE_STRING = 'text';
74
+
75
+ /**
76
+ * A type for the version() method indicating a float return value.
77
+ */
78
+ const VERSION_TYPE_FLOAT = 'float';
79
+
80
+ /**
81
+ * A cache for resolved matches
82
+ * @var array
83
+ */
84
+ protected $cache = array();
85
+
86
+ /**
87
+ * The User-Agent HTTP header is stored in here.
88
+ * @var string
89
+ */
90
+ protected $userAgent = null;
91
+
92
+ /**
93
+ * HTTP headers in the PHP-flavor. So HTTP_USER_AGENT and SERVER_SOFTWARE.
94
+ * @var array
95
+ */
96
+ protected $httpHeaders = array();
97
+
98
+ /**
99
+ * CloudFront headers. E.g. CloudFront-Is-Desktop-Viewer, CloudFront-Is-Mobile-Viewer & CloudFront-Is-Tablet-Viewer.
100
+ * @var array
101
+ */
102
+ protected $cloudfrontHeaders = array();
103
+
104
+ /**
105
+ * The matching Regex.
106
+ * This is good for debug.
107
+ * @var string
108
+ */
109
+ protected $matchingRegex = null;
110
+
111
+ /**
112
+ * The matches extracted from the regex expression.
113
+ * This is good for debug.
114
+ * @var string
115
+ */
116
+ protected $matchesArray = null;
117
+
118
+ /**
119
+ * The detection type, using self::DETECTION_TYPE_MOBILE or self::DETECTION_TYPE_EXTENDED.
120
+ *
121
+ * @deprecated since version 2.6.9
122
+ *
123
+ * @var string
124
+ */
125
+ protected $detectionType = self::DETECTION_TYPE_MOBILE;
126
+
127
+ /**
128
+ * HTTP headers that trigger the 'isMobile' detection
129
+ * to be true.
130
+ *
131
+ * @var array
132
+ */
133
+ protected static $mobileHeaders = array(
134
+
135
+ 'HTTP_ACCEPT' => array(
136
+ 'matches' => array(
137
+ // Opera Mini; @reference: http://dev.opera.com/articles/view/opera-binary-markup-language/
138
+ 'application/x-obml2d',
139
+ // BlackBerry devices.
140
+ 'application/vnd.rim.html',
141
+ 'text/vnd.wap.wml',
142
+ 'application/vnd.wap.xhtml+xml'
143
+ )
144
+ ),
145
  'HTTP_X_WAP_PROFILE' => null,
146
  'HTTP_X_WAP_CLIENTID' => null,
147
  'HTTP_WAP_CONNECTION' => null,
156
  'HTTP_UA_OS' => null,
157
  // Reported by Verizon, Vodafone proxy system.
158
  'HTTP_X_MOBILE_GATEWAY' => null,
159
+ // Seen this on HTC Sensation. SensationXE_Beats_Z715e.
160
  'HTTP_X_ATT_DEVICEID' => null,
161
  // Seen this on a HTC.
162
+ 'HTTP_UA_CPU' => array( 'matches' => array( 'ARM' ) ),
163
+ );
164
+
165
+ /**
166
+ * List of mobile devices (phones).
167
+ *
168
+ * @var array
169
+ */
170
+ protected static $phoneDevices = array(
171
+ 'iPhone' => '\biPhone\b|\biPod\b',
172
+ // |\biTunes
173
+ 'BlackBerry' => 'BlackBerry|\bBB10\b|rim[0-9]+',
174
+ 'HTC' => 'HTC|HTC.*(Sensation|Evo|Vision|Explorer|6800|8100|8900|A7272|S510e|C110e|Legend|Desire|T8282)|APX515CKT|Qtek9090|APA9292KT|HD_mini|Sensation.*Z710e|PG86100|Z715e|Desire.*(A8181|HD)|ADR6200|ADR6400L|ADR6425|001HT|Inspire 4G|Android.*\bEVO\b|T-Mobile G1|Z520m',
175
+ 'Nexus' => 'Nexus One|Nexus S|Galaxy.*Nexus|Android.*Nexus.*Mobile|Nexus 4|Nexus 5|Nexus 6',
176
+ // @todo: Is 'Dell Streak' a tablet or a phone? ;)
177
+ 'Dell' => 'Dell.*Streak|Dell.*Aero|Dell.*Venue|DELL.*Venue Pro|Dell Flash|Dell Smoke|Dell Mini 3iX|XCD28|XCD35|\b001DL\b|\b101DL\b|\bGS01\b',
178
+ 'Motorola' => 'Motorola|DROIDX|DROID BIONIC|\bDroid\b.*Build|Android.*Xoom|HRI39|MOT-|A1260|A1680|A555|A853|A855|A953|A955|A956|Motorola.*ELECTRIFY|Motorola.*i1|i867|i940|MB200|MB300|MB501|MB502|MB508|MB511|MB520|MB525|MB526|MB611|MB612|MB632|MB810|MB855|MB860|MB861|MB865|MB870|ME501|ME502|ME511|ME525|ME600|ME632|ME722|ME811|ME860|ME863|ME865|MT620|MT710|MT716|MT720|MT810|MT870|MT917|Motorola.*TITANIUM|WX435|WX445|XT300|XT301|XT311|XT316|XT317|XT319|XT320|XT390|XT502|XT530|XT531|XT532|XT535|XT603|XT610|XT611|XT615|XT681|XT701|XT702|XT711|XT720|XT800|XT806|XT860|XT862|XT875|XT882|XT883|XT894|XT901|XT907|XT909|XT910|XT912|XT928|XT926|XT915|XT919|XT925|XT1021|\bMoto E\b',
179
+ 'Samsung' => 'Samsung|SM-G9250|GT-19300|SGH-I337|BGT-S5230|GT-B2100|GT-B2700|GT-B2710|GT-B3210|GT-B3310|GT-B3410|GT-B3730|GT-B3740|GT-B5510|GT-B5512|GT-B5722|GT-B6520|GT-B7300|GT-B7320|GT-B7330|GT-B7350|GT-B7510|GT-B7722|GT-B7800|GT-C3010|GT-C3011|GT-C3060|GT-C3200|GT-C3212|GT-C3212I|GT-C3262|GT-C3222|GT-C3300|GT-C3300K|GT-C3303|GT-C3303K|GT-C3310|GT-C3322|GT-C3330|GT-C3350|GT-C3500|GT-C3510|GT-C3530|GT-C3630|GT-C3780|GT-C5010|GT-C5212|GT-C6620|GT-C6625|GT-C6712|GT-E1050|GT-E1070|GT-E1075|GT-E1080|GT-E1081|GT-E1085|GT-E1087|GT-E1100|GT-E1107|GT-E1110|GT-E1120|GT-E1125|GT-E1130|GT-E1160|GT-E1170|GT-E1175|GT-E1180|GT-E1182|GT-E1200|GT-E1210|GT-E1225|GT-E1230|GT-E1390|GT-E2100|GT-E2120|GT-E2121|GT-E2152|GT-E2220|GT-E2222|GT-E2230|GT-E2232|GT-E2250|GT-E2370|GT-E2550|GT-E2652|GT-E3210|GT-E3213|GT-I5500|GT-I5503|GT-I5700|GT-I5800|GT-I5801|GT-I6410|GT-I6420|GT-I7110|GT-I7410|GT-I7500|GT-I8000|GT-I8150|GT-I8160|GT-I8190|GT-I8320|GT-I8330|GT-I8350|GT-I8530|GT-I8700|GT-I8703|GT-I8910|GT-I9000|GT-I9001|GT-I9003|GT-I9010|GT-I9020|GT-I9023|GT-I9070|GT-I9082|GT-I9100|GT-I9103|GT-I9220|GT-I9250|GT-I9300|GT-I9305|GT-I9500|GT-I9505|GT-M3510|GT-M5650|GT-M7500|GT-M7600|GT-M7603|GT-M8800|GT-M8910|GT-N7000|GT-S3110|GT-S3310|GT-S3350|GT-S3353|GT-S3370|GT-S3650|GT-S3653|GT-S3770|GT-S3850|GT-S5210|GT-S5220|GT-S5229|GT-S5230|GT-S5233|GT-S5250|GT-S5253|GT-S5260|GT-S5263|GT-S5270|GT-S5300|GT-S5330|GT-S5350|GT-S5360|GT-S5363|GT-S5369|GT-S5380|GT-S5380D|GT-S5560|GT-S5570|GT-S5600|GT-S5603|GT-S5610|GT-S5620|GT-S5660|GT-S5670|GT-S5690|GT-S5750|GT-S5780|GT-S5830|GT-S5839|GT-S6102|GT-S6500|GT-S7070|GT-S7200|GT-S7220|GT-S7230|GT-S7233|GT-S7250|GT-S7500|GT-S7530|GT-S7550|GT-S7562|GT-S7710|GT-S8000|GT-S8003|GT-S8500|GT-S8530|GT-S8600|SCH-A310|SCH-A530|SCH-A570|SCH-A610|SCH-A630|SCH-A650|SCH-A790|SCH-A795|SCH-A850|SCH-A870|SCH-A890|SCH-A930|SCH-A950|SCH-A970|SCH-A990|SCH-I100|SCH-I110|SCH-I400|SCH-I405|SCH-I500|SCH-I510|SCH-I515|SCH-I600|SCH-I730|SCH-I760|SCH-I770|SCH-I830|SCH-I910|SCH-I920|SCH-I959|SCH-LC11|SCH-N150|SCH-N300|SCH-R100|SCH-R300|SCH-R351|SCH-R400|SCH-R410|SCH-T300|SCH-U310|SCH-U320|SCH-U350|SCH-U360|SCH-U365|SCH-U370|SCH-U380|SCH-U410|SCH-U430|SCH-U450|SCH-U460|SCH-U470|SCH-U490|SCH-U540|SCH-U550|SCH-U620|SCH-U640|SCH-U650|SCH-U660|SCH-U700|SCH-U740|SCH-U750|SCH-U810|SCH-U820|SCH-U900|SCH-U940|SCH-U960|SCS-26UC|SGH-A107|SGH-A117|SGH-A127|SGH-A137|SGH-A157|SGH-A167|SGH-A177|SGH-A187|SGH-A197|SGH-A227|SGH-A237|SGH-A257|SGH-A437|SGH-A517|SGH-A597|SGH-A637|SGH-A657|SGH-A667|SGH-A687|SGH-A697|SGH-A707|SGH-A717|SGH-A727|SGH-A737|SGH-A747|SGH-A767|SGH-A777|SGH-A797|SGH-A817|SGH-A827|SGH-A837|SGH-A847|SGH-A867|SGH-A877|SGH-A887|SGH-A897|SGH-A927|SGH-B100|SGH-B130|SGH-B200|SGH-B220|SGH-C100|SGH-C110|SGH-C120|SGH-C130|SGH-C140|SGH-C160|SGH-C170|SGH-C180|SGH-C200|SGH-C207|SGH-C210|SGH-C225|SGH-C230|SGH-C417|SGH-C450|SGH-D307|SGH-D347|SGH-D357|SGH-D407|SGH-D415|SGH-D780|SGH-D807|SGH-D980|SGH-E105|SGH-E200|SGH-E315|SGH-E316|SGH-E317|SGH-E335|SGH-E590|SGH-E635|SGH-E715|SGH-E890|SGH-F300|SGH-F480|SGH-I200|SGH-I300|SGH-I320|SGH-I550|SGH-I577|SGH-I600|SGH-I607|SGH-I617|SGH-I627|SGH-I637|SGH-I677|SGH-I700|SGH-I717|SGH-I727|SGH-i747M|SGH-I777|SGH-I780|SGH-I827|SGH-I847|SGH-I857|SGH-I896|SGH-I897|SGH-I900|SGH-I907|SGH-I917|SGH-I927|SGH-I937|SGH-I997|SGH-J150|SGH-J200|SGH-L170|SGH-L700|SGH-M110|SGH-M150|SGH-M200|SGH-N105|SGH-N500|SGH-N600|SGH-N620|SGH-N625|SGH-N700|SGH-N710|SGH-P107|SGH-P207|SGH-P300|SGH-P310|SGH-P520|SGH-P735|SGH-P777|SGH-Q105|SGH-R210|SGH-R220|SGH-R225|SGH-S105|SGH-S307|SGH-T109|SGH-T119|SGH-T139|SGH-T209|SGH-T219|SGH-T229|SGH-T239|SGH-T249|SGH-T259|SGH-T309|SGH-T319|SGH-T329|SGH-T339|SGH-T349|SGH-T359|SGH-T369|SGH-T379|SGH-T409|SGH-T429|SGH-T439|SGH-T459|SGH-T469|SGH-T479|SGH-T499|SGH-T509|SGH-T519|SGH-T539|SGH-T559|SGH-T589|SGH-T609|SGH-T619|SGH-T629|SGH-T639|SGH-T659|SGH-T669|SGH-T679|SGH-T709|SGH-T719|SGH-T729|SGH-T739|SGH-T746|SGH-T749|SGH-T759|SGH-T769|SGH-T809|SGH-T819|SGH-T839|SGH-T919|SGH-T929|SGH-T939|SGH-T959|SGH-T989|SGH-U100|SGH-U200|SGH-U800|SGH-V205|SGH-V206|SGH-X100|SGH-X105|SGH-X120|SGH-X140|SGH-X426|SGH-X427|SGH-X475|SGH-X495|SGH-X497|SGH-X507|SGH-X600|SGH-X610|SGH-X620|SGH-X630|SGH-X700|SGH-X820|SGH-X890|SGH-Z130|SGH-Z150|SGH-Z170|SGH-ZX10|SGH-ZX20|SHW-M110|SPH-A120|SPH-A400|SPH-A420|SPH-A460|SPH-A500|SPH-A560|SPH-A600|SPH-A620|SPH-A660|SPH-A700|SPH-A740|SPH-A760|SPH-A790|SPH-A800|SPH-A820|SPH-A840|SPH-A880|SPH-A900|SPH-A940|SPH-A960|SPH-D600|SPH-D700|SPH-D710|SPH-D720|SPH-I300|SPH-I325|SPH-I330|SPH-I350|SPH-I500|SPH-I600|SPH-I700|SPH-L700|SPH-M100|SPH-M220|SPH-M240|SPH-M300|SPH-M305|SPH-M320|SPH-M330|SPH-M350|SPH-M360|SPH-M370|SPH-M380|SPH-M510|SPH-M540|SPH-M550|SPH-M560|SPH-M570|SPH-M580|SPH-M610|SPH-M620|SPH-M630|SPH-M800|SPH-M810|SPH-M850|SPH-M900|SPH-M910|SPH-M920|SPH-M930|SPH-N100|SPH-N200|SPH-N240|SPH-N300|SPH-N400|SPH-Z400|SWC-E100|SCH-i909|GT-N7100|GT-N7105|SCH-I535|SM-N900A|SGH-I317|SGH-T999L|GT-S5360B|GT-I8262|GT-S6802|GT-S6312|GT-S6310|GT-S5312|GT-S5310|GT-I9105|GT-I8510|GT-S6790N|SM-G7105|SM-N9005|GT-S5301|GT-I9295|GT-I9195|SM-C101|GT-S7392|GT-S7560|GT-B7610|GT-I5510|GT-S7582|GT-S7530E|GT-I8750|SM-G9006V|SM-G9008V|SM-G9009D|SM-G900A|SM-G900D|SM-G900F|SM-G900H|SM-G900I|SM-G900J|SM-G900K|SM-G900L|SM-G900M|SM-G900P|SM-G900R4|SM-G900S|SM-G900T|SM-G900V|SM-G900W8|SHV-E160K|SCH-P709|SCH-P729|SM-T2558|GT-I9205',
180
+ 'LG' => '\bLG\b;|LG[- ]?(C800|C900|E400|E610|E900|E-900|F160|F180K|F180L|F180S|730|855|L160|LS740|LS840|LS970|LU6200|MS690|MS695|MS770|MS840|MS870|MS910|P500|P700|P705|VM696|AS680|AS695|AX840|C729|E970|GS505|272|C395|E739BK|E960|L55C|L75C|LS696|LS860|P769BK|P350|P500|P509|P870|UN272|US730|VS840|VS950|LN272|LN510|LS670|LS855|LW690|MN270|MN510|P509|P769|P930|UN200|UN270|UN510|UN610|US670|US740|US760|UX265|UX840|VN271|VN530|VS660|VS700|VS740|VS750|VS910|VS920|VS930|VX9200|VX11000|AX840A|LW770|P506|P925|P999|E612|D955|D802|MS323)',
181
+ 'Sony' => 'SonyST|SonyLT|SonyEricsson|SonyEricssonLT15iv|LT18i|E10i|LT28h|LT26w|SonyEricssonMT27i|C5303|C6902|C6903|C6906|C6943|D2533',
182
+ 'Asus' => 'Asus.*Galaxy|PadFone.*Mobile',
183
+ // http://www.micromaxinfo.com/mobiles/smartphones
184
+ // Added because the codes might conflict with Acer Tablets.
185
+ 'Micromax' => 'Micromax.*\b(A210|A92|A88|A72|A111|A110Q|A115|A116|A110|A90S|A26|A51|A35|A54|A25|A27|A89|A68|A65|A57|A90)\b',
186
+ // @todo Complete the regex.
187
+ 'Palm' => 'PalmSource|Palm',
188
+ // avantgo|blazer|elaine|hiptop|plucker|xiino ;
189
+ 'Vertu' => 'Vertu|Vertu.*Ltd|Vertu.*Ascent|Vertu.*Ayxta|Vertu.*Constellation(F|Quest)?|Vertu.*Monika|Vertu.*Signature',
190
+ // Just for fun ;)
191
+ // http://www.pantech.co.kr/en/prod/prodList.do?gbrand=VEGA (PANTECH)
192
+ // Most of the VEGA devices are legacy. PANTECH seem to be newer devices based on Android.
193
+ 'Pantech' => 'PANTECH|IM-A850S|IM-A840S|IM-A830L|IM-A830K|IM-A830S|IM-A820L|IM-A810K|IM-A810S|IM-A800S|IM-T100K|IM-A725L|IM-A780L|IM-A775C|IM-A770K|IM-A760S|IM-A750K|IM-A740S|IM-A730S|IM-A720L|IM-A710K|IM-A690L|IM-A690S|IM-A650S|IM-A630K|IM-A600S|VEGA PTL21|PT003|P8010|ADR910L|P6030|P6020|P9070|P4100|P9060|P5000|CDM8992|TXT8045|ADR8995|IS11PT|P2030|P6010|P8000|PT002|IS06|CDM8999|P9050|PT001|TXT8040|P2020|P9020|P2000|P7040|P7000|C790',
194
+ // http://www.fly-phone.com/devices/smartphones/ ; Included only smartphones.
195
+ 'Fly' => 'IQ230|IQ444|IQ450|IQ440|IQ442|IQ441|IQ245|IQ256|IQ236|IQ255|IQ235|IQ245|IQ275|IQ240|IQ285|IQ280|IQ270|IQ260|IQ250',
196
+ // http://fr.wikomobile.com
197
+ 'Wiko' => 'KITE 4G|HIGHWAY|GETAWAY|STAIRWAY|DARKSIDE|DARKFULL|DARKNIGHT|DARKMOON|SLIDE|WAX 4G|RAINBOW|BLOOM|SUNSET|GOA|LENNY|BARRY|IGGY|OZZY|CINK FIVE|CINK PEAX|CINK PEAX 2|CINK SLIM|CINK SLIM 2|CINK +|CINK KING|CINK PEAX|CINK SLIM|SUBLIM',
198
+ 'iMobile' => 'i-mobile (IQ|i-STYLE|idea|ZAA|Hitz)',
199
+ // Added simvalley mobile just for fun. They have some interesting devices.
200
+ // http://www.simvalley.fr/telephonie---gps-_22_telephonie-mobile_telephones_.html
201
+ 'SimValley' => '\b(SP-80|XT-930|SX-340|XT-930|SX-310|SP-360|SP60|SPT-800|SP-120|SPT-800|SP-140|SPX-5|SPX-8|SP-100|SPX-8|SPX-12)\b',
202
+ // Wolfgang - a brand that is sold by Aldi supermarkets.
203
+ // http://www.wolfgangmobile.com/
204
+ 'Wolfgang' => 'AT-B24D|AT-AS50HD|AT-AS40W|AT-AS55HD|AT-AS45q2|AT-B26D|AT-AS50Q',
205
+ 'Alcatel' => 'Alcatel',
206
+ 'Nintendo' => 'Nintendo 3DS',
207
+ // http://en.wikipedia.org/wiki/Amoi
208
+ 'Amoi' => 'Amoi',
209
+ // http://en.wikipedia.org/wiki/INQ
210
+ 'INQ' => 'INQ',
211
+ // @Tapatalk is a mobile app; http://support.tapatalk.com/threads/smf-2-0-2-os-and-browser-detection-plugin-and-tapatalk.15565/#post-79039
212
+ 'GenericPhone' => 'Tapatalk|PDA;|SAGEM|\bmmp\b|pocket|\bpsp\b|symbian|Smartphone|smartfon|treo|up.browser|up.link|vodafone|\bwap\b|nokia|Series40|Series60|S60|SonyEricsson|N900|MAUI.*WAP.*Browser',
213
+ );
214
+
215
+ /**
216
+ * List of tablet devices.
217
+ *
218
+ * @var array
219
+ */
220
+ protected static $tabletDevices = array(
221
+ // @todo: check for mobile friendly emails topic.
222
+ 'iPad' => 'iPad|iPad.*Mobile',
223
+ // Removed |^.*Android.*Nexus(?!(?:Mobile).)*$
224
+ // @see #442
225
+ 'NexusTablet' => 'Android.*Nexus[\s]+(7|9|10)',
226
+ 'SamsungTablet' => 'SAMSUNG.*Tablet|Galaxy.*Tab|SC-01C|GT-P1000|GT-P1003|GT-P1010|GT-P3105|GT-P6210|GT-P6800|GT-P6810|GT-P7100|GT-P7300|GT-P7310|GT-P7500|GT-P7510|SCH-I800|SCH-I815|SCH-I905|SGH-I957|SGH-I987|SGH-T849|SGH-T859|SGH-T869|SPH-P100|GT-P3100|GT-P3108|GT-P3110|GT-P5100|GT-P5110|GT-P6200|GT-P7320|GT-P7511|GT-N8000|GT-P8510|SGH-I497|SPH-P500|SGH-T779|SCH-I705|SCH-I915|GT-N8013|GT-P3113|GT-P5113|GT-P8110|GT-N8010|GT-N8005|GT-N8020|GT-P1013|GT-P6201|GT-P7501|GT-N5100|GT-N5105|GT-N5110|SHV-E140K|SHV-E140L|SHV-E140S|SHV-E150S|SHV-E230K|SHV-E230L|SHV-E230S|SHW-M180K|SHW-M180L|SHW-M180S|SHW-M180W|SHW-M300W|SHW-M305W|SHW-M380K|SHW-M380S|SHW-M380W|SHW-M430W|SHW-M480K|SHW-M480S|SHW-M480W|SHW-M485W|SHW-M486W|SHW-M500W|GT-I9228|SCH-P739|SCH-I925|GT-I9200|GT-P5200|GT-P5210|GT-P5210X|SM-T311|SM-T310|SM-T310X|SM-T210|SM-T210R|SM-T211|SM-P600|SM-P601|SM-P605|SM-P900|SM-P901|SM-T217|SM-T217A|SM-T217S|SM-P6000|SM-T3100|SGH-I467|XE500|SM-T110|GT-P5220|GT-I9200X|GT-N5110X|GT-N5120|SM-P905|SM-T111|SM-T2105|SM-T315|SM-T320|SM-T320X|SM-T321|SM-T520|SM-T525|SM-T530NU|SM-T230NU|SM-T330NU|SM-T900|XE500T1C|SM-P605V|SM-P905V|SM-T337V|SM-T537V|SM-T707V|SM-T807V|SM-P600X|SM-P900X|SM-T210X|SM-T230|SM-T230X|SM-T325|GT-P7503|SM-T531|SM-T330|SM-T530|SM-T705|SM-T705C|SM-T535|SM-T331|SM-T800|SM-T700|SM-T537|SM-T807|SM-P907A|SM-T337A|SM-T537A|SM-T707A|SM-T807A|SM-T237|SM-T807P|SM-P607T|SM-T217T|SM-T337T|SM-T807T|SM-T116NQ|SM-P550|SM-T350|SM-T550|SM-T9000|SM-P9000|SM-T705Y|SM-T805|GT-P3113|SM-T710|SM-T810|SM-T360|SM-T533|SM-T113|SM-T335|SM-T715',
227
+ // SCH-P709|SCH-P729|SM-T2558|GT-I9205 - Samsung Mega - treat them like a regular phone.
228
+ // http://docs.aws.amazon.com/silk/latest/developerguide/user-agent.html
229
+ 'Kindle' => 'Kindle|Silk.*Accelerated|Android.*\b(KFOT|KFTT|KFJWI|KFJWA|KFOTE|KFSOWI|KFTHWI|KFTHWA|KFAPWI|KFAPWA|WFJWAE|KFSAWA|KFSAWI|KFASWI)\b',
230
+ // Only the Surface tablets with Windows RT are considered mobile.
231
+ // http://msdn.microsoft.com/en-us/library/ie/hh920767(v=vs.85).aspx
232
+ 'SurfaceTablet' => 'Windows NT [0-9.]+; ARM;.*(Tablet|ARMBJS)',
233
+ // http://shopping1.hp.com/is-bin/INTERSHOP.enfinity/WFS/WW-USSMBPublicStore-Site/en_US/-/USD/ViewStandardCatalog-Browse?CatalogCategoryID=JfIQ7EN5lqMAAAEyDcJUDwMT
234
+ 'HPTablet' => 'HP Slate (7|8|10)|HP ElitePad 900|hp-tablet|EliteBook.*Touch|HP 8|Slate 21|HP SlateBook 10',
235
+ // Watch out for PadFone, see #132.
236
+ // http://www.asus.com/de/Tablets_Mobile/Memo_Pad_Products/
237
+ 'AsusTablet' => '^.*PadFone((?!Mobile).)*$|Transformer|TF101|TF101G|TF300T|TF300TG|TF300TL|TF700T|TF700KL|TF701T|TF810C|ME171|ME301T|ME302C|ME371MG|ME370T|ME372MG|ME172V|ME173X|ME400C|Slider SL101|\bK00F\b|\bK00C\b|\bK00E\b|\bK00L\b|TX201LA|ME176C|ME102A|\bM80TA\b|ME372CL|ME560CG|ME372CG|ME302KL| K010 | K017 |ME572C|ME103K|ME170C|ME171C|\bME70C\b|ME581C|ME581CL|ME8510C|ME181C',
238
+ 'BlackBerryTablet' => 'PlayBook|RIM Tablet',
239
+ 'HTCtablet' => 'HTC_Flyer_P512|HTC Flyer|HTC Jetstream|HTC-P715a|HTC EVO View 4G|PG41200|PG09410',
240
+ 'MotorolaTablet' => 'xoom|sholest|MZ615|MZ605|MZ505|MZ601|MZ602|MZ603|MZ604|MZ606|MZ607|MZ608|MZ609|MZ615|MZ616|MZ617',
241
+ 'NookTablet' => 'Android.*Nook|NookColor|nook browser|BNRV200|BNRV200A|BNTV250|BNTV250A|BNTV400|BNTV600|LogicPD Zoom2',
242
+ // http://www.acer.ro/ac/ro/RO/content/drivers
243
+ // http://www.packardbell.co.uk/pb/en/GB/content/download (Packard Bell is part of Acer)
244
+ // http://us.acer.com/ac/en/US/content/group/tablets
245
+ // http://www.acer.de/ac/de/DE/content/models/tablets/
246
+ // Can conflict with Micromax and Motorola phones codes.
247
+ 'AcerTablet' => 'Android.*; \b(A100|A101|A110|A200|A210|A211|A500|A501|A510|A511|A700|A701|W500|W500P|W501|W501P|W510|W511|W700|G100|G100W|B1-A71|B1-710|B1-711|A1-810|A1-811|A1-830)\b|W3-810|\bA3-A10\b|\bA3-A11\b',
248
+ // http://eu.computers.toshiba-europe.com/innovation/family/Tablets/1098744/banner_id/tablet_footerlink/
249
+ // http://us.toshiba.com/tablets/tablet-finder
250
+ // http://www.toshiba.co.jp/regza/tablet/
251
+ 'ToshibaTablet' => 'Android.*(AT100|AT105|AT200|AT205|AT270|AT275|AT300|AT305|AT1S5|AT500|AT570|AT700|AT830)|TOSHIBA.*FOLIO',
252
+ // http://www.nttdocomo.co.jp/english/service/developer/smart_phone/technical_info/spec/index.html
253
+ // http://www.lg.com/us/tablets
254
+ 'LGTablet' => '\bL-06C|LG-V909|LG-V900|LG-V700|LG-V510|LG-V500|LG-V410|LG-V400|LG-VK810\b',
255
+ 'FujitsuTablet' => 'Android.*\b(F-01D|F-02F|F-05E|F-10D|M532|Q572)\b',
256
+ // Prestigio Tablets http://www.prestigio.com/support
257
+ 'PrestigioTablet' => 'PMP3170B|PMP3270B|PMP3470B|PMP7170B|PMP3370B|PMP3570C|PMP5870C|PMP3670B|PMP5570C|PMP5770D|PMP3970B|PMP3870C|PMP5580C|PMP5880D|PMP5780D|PMP5588C|PMP7280C|PMP7280C3G|PMP7280|PMP7880D|PMP5597D|PMP5597|PMP7100D|PER3464|PER3274|PER3574|PER3884|PER5274|PER5474|PMP5097CPRO|PMP5097|PMP7380D|PMP5297C|PMP5297C_QUAD|PMP812E|PMP812E3G|PMP812F|PMP810E|PMP880TD|PMT3017|PMT3037|PMT3047|PMT3057|PMT7008|PMT5887|PMT5001|PMT5002',
258
+ // http://support.lenovo.com/en_GB/downloads/default.page?#
259
+ 'LenovoTablet' => 'Idea(Tab|Pad)( A1|A10| K1|)|ThinkPad([ ]+)?Tablet|Lenovo.*(S2109|S2110|S5000|S6000|K3011|A3000|A3500|A1000|A2107|A2109|A1107|A5500|A7600|B6000|B8000|B8080)(-|)(FL|F|HV|H|)',
260
+ // http://www.dell.com/support/home/us/en/04/Products/tab_mob/tablets
261
+ 'DellTablet' => 'Venue 11|Venue 8|Venue 7|Dell Streak 10|Dell Streak 7',
262
+ // http://www.yarvik.com/en/matrix/tablets/
263
+ 'YarvikTablet' => 'Android.*\b(TAB210|TAB211|TAB224|TAB250|TAB260|TAB264|TAB310|TAB360|TAB364|TAB410|TAB411|TAB420|TAB424|TAB450|TAB460|TAB461|TAB464|TAB465|TAB467|TAB468|TAB07-100|TAB07-101|TAB07-150|TAB07-151|TAB07-152|TAB07-200|TAB07-201-3G|TAB07-210|TAB07-211|TAB07-212|TAB07-214|TAB07-220|TAB07-400|TAB07-485|TAB08-150|TAB08-200|TAB08-201-3G|TAB08-201-30|TAB09-100|TAB09-211|TAB09-410|TAB10-150|TAB10-201|TAB10-211|TAB10-400|TAB10-410|TAB13-201|TAB274EUK|TAB275EUK|TAB374EUK|TAB462EUK|TAB474EUK|TAB9-200)\b',
264
+ 'MedionTablet' => 'Android.*\bOYO\b|LIFE.*(P9212|P9514|P9516|S9512)|LIFETAB',
265
+ 'ArnovaTablet' => 'AN10G2|AN7bG3|AN7fG3|AN8G3|AN8cG3|AN7G3|AN9G3|AN7dG3|AN7dG3ST|AN7dG3ChildPad|AN10bG3|AN10bG3DT|AN9G2',
266
+ // http://www.intenso.de/kategorie_en.php?kategorie=33
267
+ // @todo: http://www.nbhkdz.com/read/b8e64202f92a2df129126bff.html - investigate
268
+ 'IntensoTablet' => 'INM8002KP|INM1010FP|INM805ND|Intenso Tab|TAB1004',
269
+ // IRU.ru Tablets http://www.iru.ru/catalog/soho/planetable/
270
+ 'IRUTablet' => 'M702pro',
271
+ 'MegafonTablet' => 'MegaFon V9|\bZTE V9\b|Android.*\bMT7A\b',
272
+ // http://www.e-boda.ro/tablete-pc.html
273
+ 'EbodaTablet' => 'E-Boda (Supreme|Impresspeed|Izzycomm|Essential)',
274
+ // http://www.allview.ro/produse/droseries/lista-tablete-pc/
275
+ 'AllViewTablet' => 'Allview.*(Viva|Alldro|City|Speed|All TV|Frenzy|Quasar|Shine|TX1|AX1|AX2)',
276
+ // http://wiki.archosfans.com/index.php?title=Main_Page
277
+ 'ArchosTablet' => '\b(101G9|80G9|A101IT)\b|Qilive 97R|Archos5|\bARCHOS (70|79|80|90|97|101|FAMILYPAD|)(b|)(G10| Cobalt| TITANIUM(HD|)| Xenon| Neon|XSK| 2| XS 2| PLATINUM| CARBON|GAMEPAD)\b',
278
+ // http://www.ainol.com/plugin.php?identifier=ainol&module=product
279
+ 'AinolTablet' => 'NOVO7|NOVO8|NOVO10|Novo7Aurora|Novo7Basic|NOVO7PALADIN|novo9-Spark',
280
+ // @todo: inspect http://esupport.sony.com/US/p/select-system.pl?DIRECTOR=DRIVER
281
+ // Readers http://www.atsuhiro-me.net/ebook/sony-reader/sony-reader-web-browser
282
+ // http://www.sony.jp/support/tablet/
283
+ 'SonyTablet' => 'Sony.*Tablet|Xperia Tablet|Sony Tablet S|SO-03E|SGPT12|SGPT13|SGPT114|SGPT121|SGPT122|SGPT123|SGPT111|SGPT112|SGPT113|SGPT131|SGPT132|SGPT133|SGPT211|SGPT212|SGPT213|SGP311|SGP312|SGP321|EBRD1101|EBRD1102|EBRD1201|SGP351|SGP341|SGP511|SGP512|SGP521|SGP541|SGP551|SGP621|SGP612|SOT31',
284
+ // http://www.support.philips.com/support/catalog/worldproducts.jsp?userLanguage=en&userCountry=cn&categoryid=3G_LTE_TABLET_SU_CN_CARE&title=3G%20tablets%20/%20LTE%20range&_dyncharset=UTF-8
285
+ 'PhilipsTablet' => '\b(PI2010|PI3000|PI3100|PI3105|PI3110|PI3205|PI3210|PI3900|PI4010|PI7000|PI7100)\b',
286
+ // db + http://www.cube-tablet.com/buy-products.html
287
+ 'CubeTablet' => 'Android.*(K8GT|U9GT|U10GT|U16GT|U17GT|U18GT|U19GT|U20GT|U23GT|U30GT)|CUBE U8GT',
288
+ // http://www.cobyusa.com/?p=pcat&pcat_id=3001
289
+ 'CobyTablet' => 'MID1042|MID1045|MID1125|MID1126|MID7012|MID7014|MID7015|MID7034|MID7035|MID7036|MID7042|MID7048|MID7127|MID8042|MID8048|MID8127|MID9042|MID9740|MID9742|MID7022|MID7010',
290
+ // http://www.match.net.cn/products.asp
291
+ 'MIDTablet' => 'M9701|M9000|M9100|M806|M1052|M806|T703|MID701|MID713|MID710|MID727|MID760|MID830|MID728|MID933|MID125|MID810|MID732|MID120|MID930|MID800|MID731|MID900|MID100|MID820|MID735|MID980|MID130|MID833|MID737|MID960|MID135|MID860|MID736|MID140|MID930|MID835|MID733',
292
+ // http://www.msi.com/support
293
+ // @todo Research the Windows Tablets.
294
+ 'MSITablet' => 'MSI \b(Primo 73K|Primo 73L|Primo 81L|Primo 77|Primo 93|Primo 75|Primo 76|Primo 73|Primo 81|Primo 91|Primo 90|Enjoy 71|Enjoy 7|Enjoy 10)\b',
295
+ // @todo http://www.kyoceramobile.com/support/drivers/
296
+ // 'KyoceraTablet' => null,
297
+ // @todo http://intexuae.com/index.php/category/mobile-devices/tablets-products/
298
+ // 'IntextTablet' => null,
299
+ // http://pdadb.net/index.php?m=pdalist&list=SMiT (NoName Chinese Tablets)
300
+ // http://www.imp3.net/14/show.php?itemid=20454
301
+ 'SMiTTablet' => 'Android.*(\bMID\b|MID-560|MTV-T1200|MTV-PND531|MTV-P1101|MTV-PND530)',
302
+ // http://www.rock-chips.com/index.php?do=prod&pid=2
303
+ 'RockChipTablet' => 'Android.*(RK2818|RK2808A|RK2918|RK3066)|RK2738|RK2808A',
304
+ // http://www.fly-phone.com/devices/tablets/ ; http://www.fly-phone.com/service/
305
+ 'FlyTablet' => 'IQ310|Fly Vision',
306
+ // http://www.bqreaders.com/gb/tablets-prices-sale.html
307
+ 'bqTablet' => 'Android.*(bq)?.*(Elcano|Curie|Edison|Maxwell|Kepler|Pascal|Tesla|Hypatia|Platon|Newton|Livingstone|Cervantes|Avant|Aquaris E10)|Maxwell.*Lite|Maxwell.*Plus',
308
+ // http://www.huaweidevice.com/worldwide/productFamily.do?method=index&directoryId=5011&treeId=3290
309
+ // http://www.huaweidevice.com/worldwide/downloadCenter.do?method=index&directoryId=3372&treeId=0&tb=1&type=software (including legacy tablets)
310
+ 'HuaweiTablet' => 'MediaPad|MediaPad 7 Youth|IDEOS S7|S7-201c|S7-202u|S7-101|S7-103|S7-104|S7-105|S7-106|S7-201|S7-Slim',
311
+ // Nec or Medias Tab
312
+ 'NecTablet' => '\bN-06D|\bN-08D',
313
+ // Pantech Tablets: http://www.pantechusa.com/phones/
314
+ 'PantechTablet' => 'Pantech.*P4100',
315
+ // Broncho Tablets: http://www.broncho.cn/ (hard to find)
316
+ 'BronchoTablet' => 'Broncho.*(N701|N708|N802|a710)',
317
+ // http://versusuk.com/support.html
318
+ 'VersusTablet' => 'TOUCHPAD.*[78910]|\bTOUCHTAB\b',
319
+ // http://www.zync.in/index.php/our-products/tablet-phablets
320
+ 'ZyncTablet' => 'z1000|Z99 2G|z99|z930|z999|z990|z909|Z919|z900',
321
+ // http://www.positivoinformatica.com.br/www/pessoal/tablet-ypy/
322
+ 'PositivoTablet' => 'TB07STA|TB10STA|TB07FTA|TB10FTA',
323
+ // https://www.nabitablet.com/
324
+ 'NabiTablet' => 'Android.*\bNabi',
325
+ 'KoboTablet' => 'Kobo Touch|\bK080\b|\bVox\b Build|\bArc\b Build',
326
+ // French Danew Tablets http://www.danew.com/produits-tablette.php
327
+ 'DanewTablet' => 'DSlide.*\b(700|701R|702|703R|704|802|970|971|972|973|974|1010|1012)\b',
328
+ // Texet Tablets and Readers http://www.texet.ru/tablet/
329
+ 'TexetTablet' => 'NaviPad|TB-772A|TM-7045|TM-7055|TM-9750|TM-7016|TM-7024|TM-7026|TM-7041|TM-7043|TM-7047|TM-8041|TM-9741|TM-9747|TM-9748|TM-9751|TM-7022|TM-7021|TM-7020|TM-7011|TM-7010|TM-7023|TM-7025|TM-7037W|TM-7038W|TM-7027W|TM-9720|TM-9725|TM-9737W|TM-1020|TM-9738W|TM-9740|TM-9743W|TB-807A|TB-771A|TB-727A|TB-725A|TB-719A|TB-823A|TB-805A|TB-723A|TB-715A|TB-707A|TB-705A|TB-709A|TB-711A|TB-890HD|TB-880HD|TB-790HD|TB-780HD|TB-770HD|TB-721HD|TB-710HD|TB-434HD|TB-860HD|TB-840HD|TB-760HD|TB-750HD|TB-740HD|TB-730HD|TB-722HD|TB-720HD|TB-700HD|TB-500HD|TB-470HD|TB-431HD|TB-430HD|TB-506|TB-504|TB-446|TB-436|TB-416|TB-146SE|TB-126SE',
330
+ // Avoid detecting 'PLAYSTATION 3' as mobile.
331
+ 'PlaystationTablet' => 'Playstation.*(Portable|Vita)',
332
+ // http://www.trekstor.de/surftabs.html
333
+ 'TrekstorTablet' => 'ST10416-1|VT10416-1|ST70408-1|ST702xx-1|ST702xx-2|ST80208|ST97216|ST70104-2|VT10416-2|ST10216-2A|SurfTab',
334
+ // http://www.pyleaudio.com/Products.aspx?%2fproducts%2fPersonal-Electronics%2fTablets
335
+ 'PyleAudioTablet' => '\b(PTBL10CEU|PTBL10C|PTBL72BC|PTBL72BCEU|PTBL7CEU|PTBL7C|PTBL92BC|PTBL92BCEU|PTBL9CEU|PTBL9CUK|PTBL9C)\b',
336
+ // http://www.advandigital.com/index.php?link=content-product&jns=JP001
337
+ // because of the short codenames we have to include whitespaces to reduce the possible conflicts.
338
+ 'AdvanTablet' => 'Android.* \b(E3A|T3X|T5C|T5B|T3E|T3C|T3B|T1J|T1F|T2A|T1H|T1i|E1C|T1-E|T5-A|T4|E1-B|T2Ci|T1-B|T1-D|O1-A|E1-A|T1-A|T3A|T4i)\b ',
339
+ // http://www.danytech.com/category/tablet-pc
340
+ 'DanyTechTablet' => 'Genius Tab G3|Genius Tab S2|Genius Tab Q3|Genius Tab G4|Genius Tab Q4|Genius Tab G-II|Genius TAB GII|Genius TAB GIII|Genius Tab S1',
341
+ // http://www.galapad.net/product.html
342
+ 'GalapadTablet' => 'Android.*\bG1\b',
343
+ // http://www.micromaxinfo.com/tablet/funbook
344
+ 'MicromaxTablet' => 'Funbook|Micromax.*\b(P250|P560|P360|P362|P600|P300|P350|P500|P275)\b',
345
+ // http://www.karbonnmobiles.com/products_tablet.php
346
+ 'KarbonnTablet' => 'Android.*\b(A39|A37|A34|ST8|ST10|ST7|Smart Tab3|Smart Tab2)\b',
347
+ // http://www.myallfine.com/Products.asp
348
+ 'AllFineTablet' => 'Fine7 Genius|Fine7 Shine|Fine7 Air|Fine8 Style|Fine9 More|Fine10 Joy|Fine11 Wide',
349
+ // http://www.proscanvideo.com/products-search.asp?itemClass=TABLET&itemnmbr=
350
+ 'PROSCANTablet' => '\b(PEM63|PLT1023G|PLT1041|PLT1044|PLT1044G|PLT1091|PLT4311|PLT4311PL|PLT4315|PLT7030|PLT7033|PLT7033D|PLT7035|PLT7035D|PLT7044K|PLT7045K|PLT7045KB|PLT7071KG|PLT7072|PLT7223G|PLT7225G|PLT7777G|PLT7810K|PLT7849G|PLT7851G|PLT7852G|PLT8015|PLT8031|PLT8034|PLT8036|PLT8080K|PLT8082|PLT8088|PLT8223G|PLT8234G|PLT8235G|PLT8816K|PLT9011|PLT9045K|PLT9233G|PLT9735|PLT9760G|PLT9770G)\b',
351
+ // http://www.yonesnav.com/products/products.php
352
+ 'YONESTablet' => 'BQ1078|BC1003|BC1077|RK9702|BC9730|BC9001|IT9001|BC7008|BC7010|BC708|BC728|BC7012|BC7030|BC7027|BC7026',
353
+ // http://www.cjshowroom.com/eproducts.aspx?classcode=004001001
354
+ // China manufacturer makes tablets for different small brands (eg. http://www.zeepad.net/index.html)
355
+ 'ChangJiaTablet' => 'TPC7102|TPC7103|TPC7105|TPC7106|TPC7107|TPC7201|TPC7203|TPC7205|TPC7210|TPC7708|TPC7709|TPC7712|TPC7110|TPC8101|TPC8103|TPC8105|TPC8106|TPC8203|TPC8205|TPC8503|TPC9106|TPC9701|TPC97101|TPC97103|TPC97105|TPC97106|TPC97111|TPC97113|TPC97203|TPC97603|TPC97809|TPC97205|TPC10101|TPC10103|TPC10106|TPC10111|TPC10203|TPC10205|TPC10503',
356
+ // http://www.gloryunion.cn/products.asp
357
+ // http://www.allwinnertech.com/en/apply/mobile.html
358
+ // http://www.ptcl.com.pk/pd_content.php?pd_id=284 (EVOTAB)
359
+ // @todo: Softwiner tablets?
360
+ // aka. Cute or Cool tablets. Not sure yet, must research to avoid collisions.
361
+ 'GUTablet' => 'TX-A1301|TX-M9002|Q702|kf026',
362
+ // A12R|D75A|D77|D79|R83|A95|A106C|R15|A75|A76|D71|D72|R71|R73|R77|D82|R85|D92|A97|D92|R91|A10F|A77F|W71F|A78F|W78F|W81F|A97F|W91F|W97F|R16G|C72|C73E|K72|K73|R96G
363
+ // http://www.pointofview-online.com/showroom.php?shop_mode=product_listing&category_id=118
364
+ 'PointOfViewTablet' => 'TAB-P506|TAB-navi-7-3G-M|TAB-P517|TAB-P-527|TAB-P701|TAB-P703|TAB-P721|TAB-P731N|TAB-P741|TAB-P825|TAB-P905|TAB-P925|TAB-PR945|TAB-PL1015|TAB-P1025|TAB-PI1045|TAB-P1325|TAB-PROTAB[0-9]+|TAB-PROTAB25|TAB-PROTAB26|TAB-PROTAB27|TAB-PROTAB26XL|TAB-PROTAB2-IPS9|TAB-PROTAB30-IPS9|TAB-PROTAB25XXL|TAB-PROTAB26-IPS10|TAB-PROTAB30-IPS10',
365
+ // http://www.overmax.pl/pl/katalog-produktow,p8/tablety,c14/
366
+ // @todo: add more tests.
367
+ 'OvermaxTablet' => 'OV-(SteelCore|NewBase|Basecore|Baseone|Exellen|Quattor|EduTab|Solution|ACTION|BasicTab|TeddyTab|MagicTab|Stream|TB-08|TB-09)',
368
+ // http://hclmetablet.com/India/index.php
369
+ 'HCLTablet' => 'HCL.*Tablet|Connect-3G-2.0|Connect-2G-2.0|ME Tablet U1|ME Tablet U2|ME Tablet G1|ME Tablet X1|ME Tablet Y2|ME Tablet Sync',
370
+ // http://www.edigital.hu/Tablet_es_e-book_olvaso/Tablet-c18385.html
371
+ 'DPSTablet' => 'DPS Dream 9|DPS Dual 7',
372
+ // http://www.visture.com/index.asp
373
+ 'VistureTablet' => 'V97 HD|i75 3G|Visture V4( HD)?|Visture V5( HD)?|Visture V10',
374
+ // http://www.mijncresta.nl/tablet
375
+ 'CrestaTablet' => 'CTP(-)?810|CTP(-)?818|CTP(-)?828|CTP(-)?838|CTP(-)?888|CTP(-)?978|CTP(-)?980|CTP(-)?987|CTP(-)?988|CTP(-)?989',
376
+ // MediaTek - http://www.mediatek.com/_en/01_products/02_proSys.php?cata_sn=1&cata1_sn=1&cata2_sn=309
377
+ 'MediatekTablet' => '\bMT8125|MT8389|MT8135|MT8377\b',
378
+ // Concorde tab
379
+ 'ConcordeTablet' => 'Concorde([ ]+)?Tab|ConCorde ReadMan',
380
+ // GoClever Tablets - http://www.goclever.com/uk/products,c1/tablet,c5/
381
+ 'GoCleverTablet' => 'GOCLEVER TAB|A7GOCLEVER|M1042|M7841|M742|R1042BK|R1041|TAB A975|TAB A7842|TAB A741|TAB A741L|TAB M723G|TAB M721|TAB A1021|TAB I921|TAB R721|TAB I720|TAB T76|TAB R70|TAB R76.2|TAB R106|TAB R83.2|TAB M813G|TAB I721|GCTA722|TAB I70|TAB I71|TAB S73|TAB R73|TAB R74|TAB R93|TAB R75|TAB R76.1|TAB A73|TAB A93|TAB A93.2|TAB T72|TAB R83|TAB R974|TAB R973|TAB A101|TAB A103|TAB A104|TAB A104.2|R105BK|M713G|A972BK|TAB A971|TAB R974.2|TAB R104|TAB R83.3|TAB A1042',
382
+ // Modecom Tablets - http://www.modecom.eu/tablets/portal/
383
+ 'ModecomTablet' => 'FreeTAB 9000|FreeTAB 7.4|FreeTAB 7004|FreeTAB 7800|FreeTAB 2096|FreeTAB 7.5|FreeTAB 1014|FreeTAB 1001 |FreeTAB 8001|FreeTAB 9706|FreeTAB 9702|FreeTAB 7003|FreeTAB 7002|FreeTAB 1002|FreeTAB 7801|FreeTAB 1331|FreeTAB 1004|FreeTAB 8002|FreeTAB 8014|FreeTAB 9704|FreeTAB 1003',
384
+ // Vonino Tablets - http://www.vonino.eu/tablets
385
+ 'VoninoTablet' => '\b(Argus[ _]?S|Diamond[ _]?79HD|Emerald[ _]?78E|Luna[ _]?70C|Onyx[ _]?S|Onyx[ _]?Z|Orin[ _]?HD|Orin[ _]?S|Otis[ _]?S|SpeedStar[ _]?S|Magnet[ _]?M9|Primus[ _]?94[ _]?3G|Primus[ _]?94HD|Primus[ _]?QS|Android.*\bQ8\b|Sirius[ _]?EVO[ _]?QS|Sirius[ _]?QS|Spirit[ _]?S)\b',
386
+ // ECS Tablets - http://www.ecs.com.tw/ECSWebSite/Product/Product_Tablet_List.aspx?CategoryID=14&MenuID=107&childid=M_107&LanID=0
387
+ 'ECSTablet' => 'V07OT2|TM105A|S10OT1|TR10CS1',
388
+ // Storex Tablets - http://storex.fr/espace_client/support.html
389
+ // @note: no need to add all the tablet codes since they are guided by the first regex.
390
+ 'StorexTablet' => 'eZee[_\']?(Tab|Go)[0-9]+|TabLC7|Looney Tunes Tab',
391
+ // Generic Vodafone tablets.
392
+ 'VodafoneTablet' => 'SmartTab([ ]+)?[0-9]+|SmartTabII10|SmartTabII7',
393
+ // French tablets - Essentiel B http://www.boulanger.fr/tablette_tactile_e-book/tablette_tactile_essentiel_b/cl_68908.htm?multiChoiceToDelete=brand&mc_brand=essentielb
394
+ // Aka: http://www.essentielb.fr/
395
+ 'EssentielBTablet' => 'Smart[ \']?TAB[ ]+?[0-9]+|Family[ \']?TAB2',
396
+ // Ross & Moor - http://ross-moor.ru/
397
+ 'RossMoorTablet' => 'RM-790|RM-997|RMD-878G|RMD-974R|RMT-705A|RMT-701|RME-601|RMT-501|RMT-711',
398
+ // i-mobile http://product.i-mobilephone.com/Mobile_Device
399
+ 'iMobileTablet' => 'i-mobile i-note',
400
+ // http://www.tolino.de/de/vergleichen/
401
+ 'TolinoTablet' => 'tolino tab [0-9.]+|tolino shine',
402
+ // AudioSonic - a Kmart brand
403
+ // http://www.kmart.com.au/webapp/wcs/stores/servlet/Search?langId=-1&storeId=10701&catalogId=10001&categoryId=193001&pageSize=72&currentPage=1&searchCategory=193001%2b4294965664&sortBy=p_MaxPrice%7c1
404
+ 'AudioSonicTablet' => '\bC-22Q|T7-QC|T-17B|T-17P\b',
405
+ // AMPE Tablets - http://www.ampe.com.my/product-category/tablets/
406
+ // @todo: add them gradually to avoid conflicts.
407
+ 'AMPETablet' => 'Android.* A78 ',
408
+ // Skk Mobile - http://skkmobile.com.ph/product_tablets.php
409
+ 'SkkTablet' => 'Android.* (SKYPAD|PHOENIX|CYCLOPS)',
410
+ // Tecno Mobile (only tablet) - http://www.tecno-mobile.com/index.php/product?filterby=smart&list_order=all&page=1
411
+ 'TecnoTablet' => 'TECNO P9',
412
+ // JXD (consoles & tablets) - http://jxd.hk/products.asp?selectclassid=009008&clsid=3
413
+ 'JXDTablet' => 'Android.*\b(F3000|A3300|JXD5000|JXD3000|JXD2000|JXD300B|JXD300|S5800|S7800|S602b|S5110b|S7300|S5300|S602|S603|S5100|S5110|S601|S7100a|P3000F|P3000s|P101|P200s|P1000m|P200m|P9100|P1000s|S6600b|S908|P1000|P300|S18|S6600|S9100)\b',
414
+ // i-Joy tablets - http://www.i-joy.es/en/cat/products/tablets/
415
+ 'iJoyTablet' => 'Tablet (Spirit 7|Essentia|Galatea|Fusion|Onix 7|Landa|Titan|Scooby|Deox|Stella|Themis|Argon|Unique 7|Sygnus|Hexen|Finity 7|Cream|Cream X2|Jade|Neon 7|Neron 7|Kandy|Scape|Saphyr 7|Rebel|Biox|Rebel|Rebel 8GB|Myst|Draco 7|Myst|Tab7-004|Myst|Tadeo Jones|Tablet Boing|Arrow|Draco Dual Cam|Aurix|Mint|Amity|Revolution|Finity 9|Neon 9|T9w|Amity 4GB Dual Cam|Stone 4GB|Stone 8GB|Andromeda|Silken|X2|Andromeda II|Halley|Flame|Saphyr 9,7|Touch 8|Planet|Triton|Unique 10|Hexen 10|Memphis 4GB|Memphis 8GB|Onix 10)',
416
+ // http://www.intracon.eu/tablet
417
+ 'FX2Tablet' => 'FX2 PAD7|FX2 PAD10',
418
+ // http://www.xoro.de/produkte/
419
+ // @note: Might be the same brand with 'Simply tablets'
420
+ 'XoroTablet' => 'KidsPAD 701|PAD[ ]?712|PAD[ ]?714|PAD[ ]?716|PAD[ ]?717|PAD[ ]?718|PAD[ ]?720|PAD[ ]?721|PAD[ ]?722|PAD[ ]?790|PAD[ ]?792|PAD[ ]?900|PAD[ ]?9715D|PAD[ ]?9716DR|PAD[ ]?9718DR|PAD[ ]?9719QR|PAD[ ]?9720QR|TelePAD1030|Telepad1032|TelePAD730|TelePAD731|TelePAD732|TelePAD735Q|TelePAD830|TelePAD9730|TelePAD795|MegaPAD 1331|MegaPAD 1851|MegaPAD 2151',
421
+ // http://www1.viewsonic.com/products/computing/tablets/
422
+ 'ViewsonicTablet' => 'ViewPad 10pi|ViewPad 10e|ViewPad 10s|ViewPad E72|ViewPad7|ViewPad E100|ViewPad 7e|ViewSonic VB733|VB100a',
423
+ // http://www.odys.de/web/internet-tablet_en.html
424
+ 'OdysTablet' => 'LOOX|XENO10|ODYS[ -](Space|EVO|Xpress|NOON)|\bXELIO\b|Xelio10Pro|XELIO7PHONETAB|XELIO10EXTREME|XELIOPT2|NEO_QUAD10',
425
+ // http://www.captiva-power.de/products.html#tablets-en
426
+ 'CaptivaTablet' => 'CAPTIVA PAD',
427
+ // IconBIT - http://www.iconbit.com/products/tablets/
428
+ 'IconbitTablet' => 'NetTAB|NT-3702|NT-3702S|NT-3702S|NT-3603P|NT-3603P|NT-0704S|NT-0704S|NT-3805C|NT-3805C|NT-0806C|NT-0806C|NT-0909T|NT-0909T|NT-0907S|NT-0907S|NT-0902S|NT-0902S',
429
+ // http://www.teclast.com/topic.php?channelID=70&topicID=140&pid=63
430
+ 'TeclastTablet' => 'T98 4G|\bP80\b|\bX90HD\b|X98 Air|X98 Air 3G|\bX89\b|P80 3G|\bX80h\b|P98 Air|\bX89HD\b|P98 3G|\bP90HD\b|P89 3G|X98 3G|\bP70h\b|P79HD 3G|G18d 3G|\bP79HD\b|\bP89s\b|\bA88\b|\bP10HD\b|\bP19HD\b|G18 3G|\bP78HD\b|\bA78\b|\bP75\b|G17s 3G|G17h 3G|\bP85t\b|\bP90\b|\bP11\b|\bP98t\b|\bP98HD\b|\bG18d\b|\bP85s\b|\bP11HD\b|\bP88s\b|\bA80HD\b|\bA80se\b|\bA10h\b|\bP89\b|\bP78s\b|\bG18\b|\bP85\b|\bA70h\b|\bA70\b|\bG17\b|\bP18\b|\bA80s\b|\bA11s\b|\bP88HD\b|\bA80h\b|\bP76s\b|\bP76h\b|\bP98\b|\bA10HD\b|\bP78\b|\bP88\b|\bA11\b|\bA10t\b|\bP76a\b|\bP76t\b|\bP76e\b|\bP85HD\b|\bP85a\b|\bP86\b|\bP75HD\b|\bP76v\b|\bA12\b|\bP75a\b|\bA15\b|\bP76Ti\b|\bP81HD\b|\bA10\b|\bT760VE\b|\bT720HD\b|\bP76\b|\bP73\b|\bP71\b|\bP72\b|\bT720SE\b|\bC520Ti\b|\bT760\b|\bT720VE\b|T720-3GE|T720-WiFi',
431
+ // Onda - http://www.onda-tablet.com/buy-android-onda.html?dir=desc&limit=all&order=price
432
+ 'OndaTablet' => '\b(V975i|Vi30|VX530|V701|Vi60|V701s|Vi50|V801s|V719|Vx610w|VX610W|V819i|Vi10|VX580W|Vi10|V711s|V813|V811|V820w|V820|Vi20|V711|VI30W|V712|V891w|V972|V819w|V820w|Vi60|V820w|V711|V813s|V801|V819|V975s|V801|V819|V819|V818|V811|V712|V975m|V101w|V961w|V812|V818|V971|V971s|V919|V989|V116w|V102w|V973|Vi40)\b[\s]+',
433
+ 'JaytechTablet' => 'TPC-PA762',
434
+ 'BlaupunktTablet' => 'Endeavour 800NG|Endeavour 1010',
435
+ // http://www.digma.ru/support/download/
436
+ // @todo: Ebooks also (if requested)
437
+ 'DigmaTablet' => '\b(iDx10|iDx9|iDx8|iDx7|iDxD7|iDxD8|iDsQ8|iDsQ7|iDsQ8|iDsD10|iDnD7|3TS804H|iDsQ11|iDj7|iDs10)\b',
438
+ // http://www.evolioshop.com/ro/tablete-pc.html
439
+ // http://www.evolio.ro/support/downloads_static.html?cat=2
440
+ // @todo: Research some more
441
+ 'EvolioTablet' => 'ARIA_Mini_wifi|Aria[ _]Mini|Evolio X10|Evolio X7|Evolio X8|\bEvotab\b|\bNeura\b',
442
+ // @todo http://www.lavamobiles.com/tablets-data-cards
443
+ 'LavaTablet' => 'QPAD E704|\bIvoryS\b|E-TAB IVORY|\bE-TAB\b',
444
+ 'AocTablet' => 'MW0811|MW0812|MW0922|MTK8382',
445
+ // https://www.celkonmobiles.com/?_a=categoryphones&sid=2
446
+ 'CelkonTablet' => 'CT695|CT888|CT[\s]?910|CT7 Tab|CT9 Tab|CT3 Tab|CT2 Tab|CT1 Tab|C820|C720|\bCT-1\b',
447
+ // http://www.wolderelectronics.com/productos/manuales-y-guias-rapidas/categoria-2-miTab
448
+ 'WolderTablet' => 'miTab \b(DIAMOND|SPACE|BROOKLYN|NEO|FLY|MANHATTAN|FUNK|EVOLUTION|SKY|GOCAR|IRON|GENIUS|POP|MINT|EPSILON|BROADWAY|JUMP|HOP|LEGEND|NEW AGE|LINE|ADVANCE|FEEL|FOLLOW|LIKE|LINK|LIVE|THINK|FREEDOM|CHICAGO|CLEVELAND|BALTIMORE-GH|IOWA|BOSTON|SEATTLE|PHOENIX|DALLAS|IN 101|MasterChef)\b',
449
+ // http://www.mi.com/en
450
+ 'MiTablet' => '\bMI PAD\b|\bHM NOTE 1W\b',
451
+ // http://www.nbru.cn/index.html
452
+ 'NibiruTablet' => 'Nibiru M1|Nibiru Jupiter One',
453
+ // http://navroad.com/products/produkty/tablety/
454
+ 'NexoTablet' => 'NEXO NOVA|NEXO 10|NEXO AVIO|NEXO FREE|NEXO GO|NEXO EVO|NEXO 3G|NEXO SMART|NEXO KIDDO|NEXO MOBI',
455
+ // http://leader-online.com/new_site/product-category/tablets/
456
+ // http://www.leader-online.net.au/List/Tablet
457
+ 'LeaderTablet' => 'TBLT10Q|TBLT10I|TBL-10WDKB|TBL-10WDKBO2013|TBL-W230V2|TBL-W450|TBL-W500|SV572|TBLT7I|TBA-AC7-8G|TBLT79|TBL-8W16|TBL-10W32|TBL-10WKB|TBL-W100',
458
+ // http://www.datawind.com/ubislate/
459
+ 'UbislateTablet' => 'UbiSlate[\s]?7C',
460
+ // http://www.pocketbook-int.com/ru/support
461
+ 'PocketBookTablet' => 'Pocketbook',
462
+ // http://www.tesco.com/direct/hudl/
463
+ 'Hudl' => 'Hudl HT7S3|Hudl 2',
464
+ // http://www.telstra.com.au/home-phone/thub-2/
465
+ 'TelstraTablet' => 'T-Hub2',
466
+ 'GenericTablet' => 'Android.*\b97D\b|Tablet(?!.*PC)|BNTV250A|MID-WCDMA|LogicPD Zoom2|\bA7EB\b|CatNova8|A1_07|CT704|CT1002|\bM721\b|rk30sdk|\bEVOTAB\b|M758A|ET904|ALUMIUM10|Smartfren Tab|Endeavour 1010|Tablet-PC-4|Tagi Tab|\bM6pro\b|CT1020W|arc 10HD|\bJolla\b|\bTP750\b'
467
+ );
468
+
469
+ /**
470
+ * List of mobile Operating Systems.
471
+ *
472
+ * @var array
473
+ */
474
+ protected static $operatingSystems = array(
475
+ 'AndroidOS' => 'Android',
476
+ 'BlackBerryOS' => 'blackberry|\bBB10\b|rim tablet os',
477
+ 'PalmOS' => 'PalmOS|avantgo|blazer|elaine|hiptop|palm|plucker|xiino',
478
+ 'SymbianOS' => 'Symbian|SymbOS|Series60|Series40|SYB-[0-9]+|\bS60\b',
479
+ // @reference: http://en.wikipedia.org/wiki/Windows_Mobile
480
+ 'WindowsMobileOS' => 'Windows CE.*(PPC|Smartphone|Mobile|[0-9]{3}x[0-9]{3})|Window Mobile|Windows Phone [0-9.]+|WCE;',
481
+ // @reference: http://en.wikipedia.org/wiki/Windows_Phone
482
+ // http://wifeng.cn/?r=blog&a=view&id=106
483
+ // http://nicksnettravels.builttoroam.com/post/2011/01/10/Bogus-Windows-Phone-7-User-Agent-String.aspx
484
+ // http://msdn.microsoft.com/library/ms537503.aspx
485
+ // https://msdn.microsoft.com/en-us/library/hh869301(v=vs.85).aspx
486
+ 'WindowsPhoneOS' => 'Windows Phone 10.0|Windows Phone 8.1|Windows Phone 8.0|Windows Phone OS|XBLWP7|ZuneWP7|Windows NT 6.[23]; ARM;',
487
+ 'iOS' => '\biPhone.*Mobile|\biPod|\biPad',
488
+ // http://en.wikipedia.org/wiki/MeeGo
489
+ // @todo: research MeeGo in UAs
490
+ 'MeeGoOS' => 'MeeGo',
491
+ // http://en.wikipedia.org/wiki/Maemo
492
+ // @todo: research Maemo in UAs
493
+ 'MaemoOS' => 'Maemo',
494
+ 'JavaOS' => 'J2ME/|\bMIDP\b|\bCLDC\b', // '|Java/' produces bug #135
495
+ 'webOS' => 'webOS|hpwOS',
496
+ 'badaOS' => '\bBada\b',
497
+ 'BREWOS' => 'BREW',
498
+ );
499
+
500
+ /**
501
+ * List of mobile User Agents.
502
+ *
503
+ * @var array
504
+ */
505
+ protected static $browsers = array(
506
+ // @reference: https://developers.google.com/chrome/mobile/docs/user-agent
507
+ 'Chrome' => '\bCrMo\b|CriOS|Android.*Chrome/[.0-9]* (Mobile)?',
508
+ 'Dolfin' => '\bDolfin\b',
509
+ 'Opera' => 'Opera.*Mini|Opera.*Mobi|Android.*Opera|Mobile.*OPR/[0-9.]+|Coast/[0-9.]+',
510
+ 'Skyfire' => 'Skyfire',
511
+ 'IE' => 'IEMobile|MSIEMobile',
512
+ // |Trident/[.0-9]+
513
+ 'Firefox' => 'fennec|firefox.*maemo|(Mobile|Tablet).*Firefox|Firefox.*Mobile',
514
+ 'Bolt' => 'bolt',
515
+ 'TeaShark' => 'teashark',
516
+ 'Blazer' => 'Blazer',
517
+ // @reference: http://developer.apple.com/library/safari/#documentation/AppleApplications/Reference/SafariWebContent/OptimizingforSafarioniPhone/OptimizingforSafarioniPhone.html#//apple_ref/doc/uid/TP40006517-SW3
518
+ 'Safari' => 'Version.*Mobile.*Safari|Safari.*Mobile|MobileSafari',
519
+ // http://en.wikipedia.org/wiki/Midori_(web_browser)
520
+ //'Midori' => 'midori',
521
+ 'Tizen' => 'Tizen',
522
+ 'UCBrowser' => 'UC.*Browser|UCWEB',
523
+ 'baiduboxapp' => 'baiduboxapp',
524
+ 'baidubrowser' => 'baidubrowser',
525
+ // https://github.com/serbanghita/Mobile-Detect/issues/7
526
+ 'DiigoBrowser' => 'DiigoBrowser',
527
+ // http://www.puffinbrowser.com/index.php
528
+ 'Puffin' => 'Puffin',
529
+ // http://mercury-browser.com/index.html
530
+ 'Mercury' => '\bMercury\b',
531
+ // http://en.wikipedia.org/wiki/Obigo_Browser
532
+ 'ObigoBrowser' => 'Obigo',
533
+ // http://en.wikipedia.org/wiki/NetFront
534
+ 'NetFront' => 'NF-Browser',
535
+ // @reference: http://en.wikipedia.org/wiki/Minimo
536
+ // http://en.wikipedia.org/wiki/Vision_Mobile_Browser
537
+ 'GenericBrowser' => 'NokiaBrowser|OviBrowser|OneBrowser|TwonkyBeamBrowser|SEMC.*Browser|FlyFlow|Minimo|NetFront|Novarra-Vision|MQQBrowser|MicroMessenger',
538
+ );
539
+
540
+ /**
541
+ * Utilities.
542
+ *
543
+ * @var array
544
+ */
545
+ protected static $utilities = array(
546
+ // Experimental. When a mobile device wants to switch to 'Desktop Mode'.
547
+ // http://scottcate.com/technology/windows-phone-8-ie10-desktop-or-mobile/
548
+ // https://github.com/serbanghita/Mobile-Detect/issues/57#issuecomment-15024011
549
+ // https://developers.facebook.com/docs/sharing/best-practices
550
+ 'Bot' => 'Googlebot|facebookexternalhit|AdsBot-Google|Google Keyword Suggestion|Facebot|YandexBot|bingbot|ia_archiver|AhrefsBot|Ezooms|GSLFbot|WBSearchBot|Twitterbot|TweetmemeBot|Twikle|PaperLiBot|Wotbox|UnwindFetchor|Exabot|MJ12bot|YandexImages|TurnitinBot|Pingdom',
551
+ 'MobileBot' => 'Googlebot-Mobile|AdsBot-Google-Mobile|YahooSeeker/M1A1-R2D2',
552
+ 'DesktopMode' => 'WPDesktop',
553
+ 'TV' => 'SonyDTV|HbbTV', // experimental
554
+ 'WebKit' => '(webkit)[ /]([\w.]+)',
555
+ // @todo: Include JXD consoles.
556
+ 'Console' => '\b(Nintendo|Nintendo WiiU|Nintendo 3DS|PLAYSTATION|Xbox)\b',
557
+ 'Watch' => 'SM-V700',
558
+ );
559
+
560
+ /**
561
+ * All possible HTTP headers that represent the
562
+ * User-Agent string.
563
+ *
564
+ * @var array
565
+ */
566
+ protected static $uaHttpHeaders = array(
567
+ // The default User-Agent string.
568
+ 'HTTP_USER_AGENT',
569
+ // Header can occur on devices using Opera Mini.
570
+ 'HTTP_X_OPERAMINI_PHONE_UA',
571
+ // Vodafone specific header: http://www.seoprinciple.com/mobile-web-community-still-angry-at-vodafone/24/
572
+ 'HTTP_X_DEVICE_USER_AGENT',
573
+ 'HTTP_X_ORIGINAL_USER_AGENT',
574
+ 'HTTP_X_SKYFIRE_PHONE',
575
+ 'HTTP_X_BOLT_PHONE_UA',
576
+ 'HTTP_DEVICE_STOCK_UA',
577
+ 'HTTP_X_UCBROWSER_DEVICE_UA'
578
+ );
579
+
580
+ /**
581
+ * The individual segments that could exist in a User-Agent string. VER refers to the regular
582
+ * expression defined in the constant self::VER.
583
+ *
584
+ * @var array
585
+ */
586
+ protected static $properties = array(
587
+
588
+ // Build
589
+ 'Mobile' => 'Mobile/[VER]',
590
+ 'Build' => 'Build/[VER]',
591
+ 'Version' => 'Version/[VER]',
592
+ 'VendorID' => 'VendorID/[VER]',
593
+ // Devices
594
+ 'iPad' => 'iPad.*CPU[a-z ]+[VER]',
595
+ 'iPhone' => 'iPhone.*CPU[a-z ]+[VER]',
596
+ 'iPod' => 'iPod.*CPU[a-z ]+[VER]',
597
+ //'BlackBerry' => array('BlackBerry[VER]', 'BlackBerry [VER];'),
598
+ 'Kindle' => 'Kindle/[VER]',
599
+ // Browser
600
+ 'Chrome' => array( 'Chrome/[VER]', 'CriOS/[VER]', 'CrMo/[VER]' ),
601
+ 'Coast' => array( 'Coast/[VER]' ),
602
+ 'Dolfin' => 'Dolfin/[VER]',
603
+ // @reference: https://developer.mozilla.org/en-US/docs/User_Agent_Strings_Reference
604
+ 'Firefox' => 'Firefox/[VER]',
605
+ 'Fennec' => 'Fennec/[VER]',
606
+ // http://msdn.microsoft.com/en-us/library/ms537503(v=vs.85).aspx
607
+ // https://msdn.microsoft.com/en-us/library/ie/hh869301(v=vs.85).aspx
608
+ 'IE' => array(
609
+ 'IEMobile/[VER];',
610
+ 'IEMobile [VER]',
611
+ 'MSIE [VER];',
612
+ 'Trident/[0-9.]+;.*rv:[VER]'
613
+ ),
614
+ // http://en.wikipedia.org/wiki/NetFront
615
+ 'NetFront' => 'NetFront/[VER]',
616
+ 'NokiaBrowser' => 'NokiaBrowser/[VER]',
617
+ 'Opera' => array( ' OPR/[VER]', 'Opera Mini/[VER]', 'Version/[VER]' ),
618
+ 'Opera Mini' => 'Opera Mini/[VER]',
619
+ 'Opera Mobi' => 'Version/[VER]',
620
+ 'UC Browser' => 'UC Browser[VER]',
621
+ 'MQQBrowser' => 'MQQBrowser/[VER]',
622
+ 'MicroMessenger' => 'MicroMessenger/[VER]',
623
+ 'baiduboxapp' => 'baiduboxapp/[VER]',
624
+ 'baidubrowser' => 'baidubrowser/[VER]',
625
+ 'Iron' => 'Iron/[VER]',
626
+ // @note: Safari 7534.48.3 is actually Version 5.1.
627
+ // @note: On BlackBerry the Version is overwriten by the OS.
628
+ 'Safari' => array( 'Version/[VER]', 'Safari/[VER]' ),
629
+ 'Skyfire' => 'Skyfire/[VER]',
630
+ 'Tizen' => 'Tizen/[VER]',
631
+ 'Webkit' => 'webkit[ /][VER]',
632
+ // Engine
633
+ 'Gecko' => 'Gecko/[VER]',
634
+ 'Trident' => 'Trident/[VER]',
635
+ 'Presto' => 'Presto/[VER]',
636
+ // OS
637
+ 'iOS' => ' \bi?OS\b [VER][ ;]{1}',
638
+ 'Android' => 'Android [VER]',
639
+ 'BlackBerry' => array( 'BlackBerry[\w]+/[VER]', 'BlackBerry.*Version/[VER]', 'Version/[VER]' ),
640
+ 'BREW' => 'BREW [VER]',
641
+ 'Java' => 'Java/[VER]',
642
+ // @reference: http://windowsteamblog.com/windows_phone/b/wpdev/archive/2011/08/29/introducing-the-ie9-on-windows-phone-mango-user-agent-string.aspx
643
+ // @reference: http://en.wikipedia.org/wiki/Windows_NT#Releases
644
+ 'Windows Phone OS' => array( 'Windows Phone OS [VER]', 'Windows Phone [VER]' ),
645
+ 'Windows Phone' => 'Windows Phone [VER]',
646
+ 'Windows CE' => 'Windows CE/[VER]',
647
+ // http://social.msdn.microsoft.com/Forums/en-US/windowsdeveloperpreviewgeneral/thread/6be392da-4d2f-41b4-8354-8dcee20c85cd
648
+ 'Windows NT' => 'Windows NT [VER]',
649
+ 'Symbian' => array( 'SymbianOS/[VER]', 'Symbian/[VER]' ),
650
+ 'webOS' => array( 'webOS/[VER]', 'hpwOS/[VER];' ),
651
+ );
652
+
653
+ /**
654
+ * Construct an instance of this class.
655
+ *
656
+ * @param array $headers Specify the headers as injection. Should be PHP _SERVER flavored.
657
+ * If left empty, will use the global _SERVER['HTTP_*'] vars instead.
658
+ * @param string $userAgent Inject the User-Agent header. If null, will use HTTP_USER_AGENT
659
+ * from the $headers array instead.
660
+ */
661
+ public function __construct(
662
+ array $headers = null,
663
+ $userAgent = null
664
+ ) {
665
+ $this->setHttpHeaders( $headers );
666
+ $this->setUserAgent( $userAgent );
667
+ }
668
 
669
+ /**
670
+ * Get the current script version.
671
+ * This is useful for the demo.php file,
672
+ * so people can check on what version they are testing
673
+ * for mobile devices.
674
+ *
675
+ * @return string The version number in semantic version format.
676
+ */
677
+ public static function getScriptVersion() {
678
+ return self::VERSION;
 
679
  }
680
 
681
+ /**
682
+ * Set the HTTP Headers. Must be PHP-flavored. This method will reset existing headers.
683
+ *
684
+ * @param array $httpHeaders The headers to set. If null, then using PHP's _SERVER to extract
685
+ * the headers. The default null is left for backwards compatibilty.
686
+ */
687
+ public function setHttpHeaders( $httpHeaders = null ) {
688
+ // use global _SERVER if $httpHeaders aren't defined
689
+ if ( ! is_array( $httpHeaders ) || ! count( $httpHeaders ) ) {
690
+ $httpHeaders = $_SERVER;
691
+ }
692
+
693
+ // clear existing headers
694
+ $this->httpHeaders = array();
695
 
696
+ // Only save HTTP headers. In PHP land, that means only _SERVER vars that
697
+ // start with HTTP_.
698
+ foreach ( $httpHeaders as $key => $value ) {
699
+ if ( substr( $key, 0, 5 ) === 'HTTP_' ) {
700
+ $this->httpHeaders[ $key ] = $value;
701
+ }
702
  }
703
+
704
+ // In case we're dealing with CloudFront, we need to know.
705
+ $this->setCfHeaders( $httpHeaders );
706
  }
 
707
 
708
+ /**
709
+ * Retrieves the HTTP headers.
710
+ *
711
+ * @return array
712
+ */
713
+ public function getHttpHeaders() {
714
+ return $this->httpHeaders;
715
+ }
 
716
 
717
+ /**
718
+ * Retrieves a particular header. If it doesn't exist, no exception/error is caused.
719
+ * Simply null is returned.
720
+ *
721
+ * @param string $header The name of the header to retrieve. Can be HTTP compliant such as
722
+ * "User-Agent" or "X-Device-User-Agent" or can be php-esque with the
723
+ * all-caps, HTTP_ prefixed, underscore seperated awesomeness.
724
+ *
725
+ * @return string|null The value of the header.
726
+ */
727
+ public function getHttpHeader( $header ) {
728
+ // are we using PHP-flavored headers?
729
+ if ( strpos( $header, '_' ) === false ) {
730
+ $header = str_replace( '-', '_', $header );
731
+ $header = strtoupper( $header );
732
+ }
733
+
734
+ // test the alternate, too
735
+ $altHeader = 'HTTP_' . $header;
736
+
737
+ //Test both the regular and the HTTP_ prefix
738
+ if ( isset( $this->httpHeaders[ $header ] ) ) {
739
+ return $this->httpHeaders[ $header ];
740
+ } elseif ( isset( $this->httpHeaders[ $altHeader ] ) ) {
741
+ return $this->httpHeaders[ $altHeader ];
742
+ }
743
+
744
+ return null;
745
  }
746
 
747
+ public function getMobileHeaders() {
748
+ return self::$mobileHeaders;
749
+ }
750
 
751
+ /**
752
+ * Get all possible HTTP headers that
753
+ * can contain the User-Agent string.
754
+ *
755
+ * @return array List of HTTP headers.
756
+ */
757
+ public function getUaHttpHeaders() {
758
+ return self::$uaHttpHeaders;
759
  }
760
 
 
 
761
 
762
+ /**
763
+ * Set CloudFront headers
764
+ * http://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/header-caching.html#header-caching-web-device
765
+ *
766
+ * @param array $cfHeaders List of HTTP headers
767
+ *
768
+ * @return boolean If there were CloudFront headers to be set
769
+ */
770
+ public function setCfHeaders( $cfHeaders = null ) {
771
+ // use global _SERVER if $cfHeaders aren't defined
772
+ if ( ! is_array( $cfHeaders ) || ! count( $cfHeaders ) ) {
773
+ $cfHeaders = $_SERVER;
774
+ }
775
 
776
+ // clear existing headers
777
+ $this->cloudfrontHeaders = array();
 
 
 
 
 
 
 
 
778
 
779
+ // Only save CLOUDFRONT headers. In PHP land, that means only _SERVER vars that
780
+ // start with cloudfront-.
781
+ $response = false;
782
+ foreach ( $cfHeaders as $key => $value ) {
783
+ if ( substr( strtolower( $key ), 0, 16 ) === 'http_cloudfront_' ) {
784
+ $this->cloudfrontHeaders[ strtoupper( $key ) ] = $value;
785
+ $response = true;
 
 
 
 
 
 
 
 
 
 
 
786
  }
787
  }
788
 
789
+ return $response;
790
+ }
791
 
792
+ /**
793
+ * Retrieves the cloudfront headers.
794
+ *
795
+ * @return array
796
+ */
797
+ public function getCfHeaders() {
798
+ return $this->cloudfrontHeaders;
799
  }
 
800
 
801
+ /**
802
+ * Set the User-Agent to be used.
803
+ *
804
+ * @param string $userAgent The user agent string to set.
805
+ *
806
+ * @return string|null
807
+ */
808
+ public function setUserAgent( $userAgent = null ) {
809
+ // Invalidate cache due to #375
810
+ $this->cache = array();
811
+
812
+ if ( false === empty( $userAgent ) ) {
813
+ return $this->userAgent = $userAgent;
814
+ } else {
815
+ $this->userAgent = null;
816
+ foreach ( $this->getUaHttpHeaders() as $altHeader ) {
817
+ if ( false === empty( $this->httpHeaders[ $altHeader ] ) ) { // @todo: should use getHttpHeader(), but it would be slow. (Serban)
818
+ $this->userAgent .= $this->httpHeaders[ $altHeader ] . " ";
819
+ }
820
+ }
821
+
822
+ if ( ! empty( $this->userAgent ) ) {
823
+ return $this->userAgent = trim( $this->userAgent );
824
+ }
825
+ }
826
+
827
+ if ( count( $this->getCfHeaders() ) > 0 ) {
828
+ return $this->userAgent = 'Amazon CloudFront';
829
+ }
830
 
831
+ return $this->userAgent = null;
 
 
 
 
 
 
 
 
 
 
 
 
832
  }
833
 
834
+ /**
835
+ * Retrieve the User-Agent.
836
+ *
837
+ * @return string|null The user agent if it's set.
838
+ */
839
+ public function getUserAgent() {
840
+ return $this->userAgent;
841
  }
842
 
843
+ /**
844
+ * Set the detection type. Must be one of self::DETECTION_TYPE_MOBILE or
845
+ * self::DETECTION_TYPE_EXTENDED. Otherwise, nothing is set.
846
+ *
847
+ * @deprecated since version 2.6.9
848
+ *
849
+ * @param string $type The type. Must be a self::DETECTION_TYPE_* constant. The default
850
+ * parameter is null which will default to self::DETECTION_TYPE_MOBILE.
851
+ */
852
+ public function setDetectionType( $type = null ) {
853
+ if ( $type === null ) {
854
+ $type = self::DETECTION_TYPE_MOBILE;
855
+ }
856
 
857
+ if ( $type !== self::DETECTION_TYPE_MOBILE && $type !== self::DETECTION_TYPE_EXTENDED ) {
858
+ return;
859
+ }
 
 
 
 
 
 
860
 
861
+ $this->detectionType = $type;
862
+ }
 
 
 
 
 
 
 
863
 
864
+ public function getMatchingRegex() {
865
+ return $this->matchingRegex;
866
+ }
 
 
 
 
 
 
867
 
868
+ public function getMatchesArray() {
869
+ return $this->matchesArray;
870
+ }
 
 
 
 
 
 
871
 
872
+ /**
873
+ * Retrieve the list of known phone devices.
874
+ *
875
+ * @return array List of phone devices.
876
+ */
877
+ public static function getPhoneDevices() {
878
+ return self::$phoneDevices;
879
+ }
 
880
 
881
+ /**
882
+ * Retrieve the list of known tablet devices.
883
+ *
884
+ * @return array List of tablet devices.
885
+ */
886
+ public static function getTabletDevices() {
887
+ return self::$tabletDevices;
 
 
 
 
 
 
 
 
 
 
 
888
  }
889
 
890
+ /**
891
+ * Alias for getBrowsers() method.
892
+ *
893
+ * @return array List of user agents.
894
+ */
895
+ public static function getUserAgents() {
896
+ return self::getBrowsers();
897
+ }
898
 
899
+ /**
900
+ * Retrieve the list of known browsers. Specifically, the user agents.
901
+ *
902
+ * @return array List of browsers / user agents.
903
+ */
904
+ public static function getBrowsers() {
905
+ return self::$browsers;
906
+ }
907
 
908
+ /**
909
+ * Retrieve the list of known utilities.
910
+ *
911
+ * @return array List of utilities.
912
+ */
913
+ public static function getUtilities() {
914
+ return self::$utilities;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
915
  }
916
 
917
+ /**
918
+ * Method gets the mobile detection rules. This method is used for the magic methods $detect->is*().
919
+ *
920
+ * @deprecated since version 2.6.9
921
+ *
922
+ * @return array All the rules (but not extended).
923
+ */
924
+ public static function getMobileDetectionRules() {
925
+ static $rules;
926
+
927
+ if ( ! $rules ) {
928
+ $rules = array_merge(
929
+ self::$phoneDevices,
930
+ self::$tabletDevices,
931
+ self::$operatingSystems,
932
+ self::$browsers
933
+ );
934
+ }
935
+
936
+ return $rules;
937
 
 
 
 
 
 
 
 
 
 
 
 
 
 
938
  }
 
939
 
940
+ /**
941
+ * Method gets the mobile detection rules + utilities.
942
+ * The reason this is separate is because utilities rules
943
+ * don't necessary imply mobile. This method is used inside
944
+ * the new $detect->is('stuff') method.
945
+ *
946
+ * @deprecated since version 2.6.9
947
+ *
948
+ * @return array All the rules + extended.
949
+ */
950
+ public function getMobileDetectionRulesExtended() {
951
+ static $rules;
952
+
953
+ if ( ! $rules ) {
954
+ // Merge all rules together.
955
+ $rules = array_merge(
956
+ self::$phoneDevices,
957
+ self::$tabletDevices,
958
+ self::$operatingSystems,
959
+ self::$browsers,
960
+ self::$utilities
961
+ );
962
+ }
963
 
964
+ return $rules;
965
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
966
 
967
+ /**
968
+ * Retrieve the current set of rules.
969
+ *
970
+ * @deprecated since version 2.6.9
971
+ *
972
+ * @return array
973
+ */
974
+ public function getRules() {
975
+ if ( $this->detectionType == self::DETECTION_TYPE_EXTENDED ) {
976
+ return self::getMobileDetectionRulesExtended();
977
+ } else {
978
+ return self::getMobileDetectionRules();
979
  }
980
  }
981
 
982
+ /**
983
+ * Retrieve the list of mobile operating systems.
984
+ *
985
+ * @return array The list of mobile operating systems.
986
+ */
987
+ public static function getOperatingSystems() {
988
+ return self::$operatingSystems;
989
+ }
990
 
991
+ /**
992
+ * Check the HTTP headers for signs of mobile.
993
+ * This is the fastest mobile check possible; it's used
994
+ * inside isMobile() method.
995
+ *
996
+ * @return bool
997
+ */
998
+ public function checkHttpHeadersForMobile() {
999
+
1000
+ foreach ( $this->getMobileHeaders() as $mobileHeader => $matchType ) {
1001
+ if ( isset( $this->httpHeaders[ $mobileHeader ] ) ) {
1002
+ if ( is_array( $matchType['matches'] ) ) {
1003
+ foreach ( $matchType['matches'] as $_match ) {
1004
+ if ( strpos( $this->httpHeaders[ $mobileHeader ], $_match ) !== false ) {
1005
+ return true;
1006
+ }
1007
+ }
1008
+
1009
+ return false;
1010
+ } else {
1011
+ return true;
1012
+ }
1013
+ }
1014
+ }
1015
+
1016
+ return false;
1017
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1018
  }
1019
 
1020
+ /**
1021
+ * Magic overloading method.
1022
+ *
1023
+ * @method boolean is[...]()
1024
+ * @param string $name
1025
+ * @param array $arguments
1026
+ *
1027
+ * @return mixed
1028
+ * @throws BadMethodCallException when the method doesn't exist and doesn't start with 'is'
1029
+ */
1030
+ public function __call( $name, $arguments ) {
1031
+ // make sure the name starts with 'is', otherwise
1032
+ if ( substr( $name, 0, 2 ) !== 'is' ) {
1033
+ throw new BadMethodCallException( "No such method exists: $name" );
1034
+ }
1035
 
1036
+ $this->setDetectionType( self::DETECTION_TYPE_MOBILE );
1037
 
1038
+ $key = substr( $name, 2 );
 
1039
 
1040
+ return $this->matchUAAgainstKey( $key );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1041
  }
1042
 
1043
+ /**
1044
+ * Find a detection rule that matches the current User-agent.
1045
+ *
1046
+ * @param null $userAgent deprecated
1047
+ *
1048
+ * @return boolean
1049
+ */
1050
+ protected function matchDetectionRulesAgainstUA( $userAgent = null ) {
1051
+ // Begin general search.
1052
+ foreach ( $this->getRules() as $_regex ) {
1053
+ if ( empty( $_regex ) ) {
1054
+ continue;
1055
+ }
1056
 
1057
+ if ( $this->match( $_regex, $userAgent ) ) {
1058
+ return true;
1059
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1060
  }
1061
 
1062
+ return false;
1063
  }
1064
 
1065
+ /**
1066
+ * Search for a certain key in the rules array.
1067
+ * If the key is found then try to match the corresponding
1068
+ * regex against the User-Agent.
1069
+ *
1070
+ * @param string $key
1071
+ *
1072
+ * @return boolean
1073
+ */
1074
+ protected function matchUAAgainstKey( $key ) {
1075
+ // Make the keys lowercase so we can match: isIphone(), isiPhone(), isiphone(), etc.
1076
+ $key = strtolower( $key );
1077
+ if ( false === isset( $this->cache[ $key ] ) ) {
1078
+
1079
+ // change the keys to lower case
1080
+ $_rules = array_change_key_case( $this->getRules() );
1081
+
1082
+ if ( false === empty( $_rules[ $key ] ) ) {
1083
+ $this->cache[ $key ] = $this->match( $_rules[ $key ] );
1084
+ }
1085
 
1086
+ if ( false === isset( $this->cache[ $key ] ) ) {
1087
+ $this->cache[ $key ] = false;
1088
+ }
1089
+ }
 
 
 
 
 
 
 
 
 
1090
 
1091
+ return $this->cache[ $key ];
 
1092
  }
1093
 
1094
+ /**
1095
+ * Check if the device is mobile.
1096
+ * Returns true if any type of mobile device detected, including special ones
1097
+ *
1098
+ * @param null $userAgent deprecated
1099
+ * @param null $httpHeaders deprecated
1100
+ *
1101
+ * @return bool
1102
+ */
1103
+ public function isMobile( $userAgent = null, $httpHeaders = null ) {
1104
+
1105
+ if ( $httpHeaders ) {
1106
+ $this->setHttpHeaders( $httpHeaders );
1107
+ }
1108
 
1109
+ if ( $userAgent ) {
1110
+ $this->setUserAgent( $userAgent );
1111
+ }
 
 
1112
 
1113
+ // Check specifically for cloudfront headers if the useragent === 'Amazon CloudFront'
1114
+ if ( $this->getUserAgent() === 'Amazon CloudFront' ) {
1115
+ $cfHeaders = $this->getCfHeaders();
1116
+ if ( array_key_exists( 'HTTP_CLOUDFRONT_IS_MOBILE_VIEWER', $cfHeaders ) && $cfHeaders['HTTP_CLOUDFRONT_IS_MOBILE_VIEWER'] === 'true' ) {
1117
+ return true;
1118
+ }
1119
+ }
1120
 
1121
+ $this->setDetectionType( self::DETECTION_TYPE_MOBILE );
1122
+
1123
+ if ( $this->checkHttpHeadersForMobile() ) {
 
 
 
 
 
 
 
 
 
 
 
1124
  return true;
1125
+ } else {
1126
+ return $this->matchDetectionRulesAgainstUA();
1127
  }
1128
+
1129
  }
1130
 
1131
+ /**
1132
+ * Check if the device is a tablet.
1133
+ * Return true if any type of tablet device is detected.
1134
+ *
1135
+ * @param string $userAgent deprecated
1136
+ * @param array $httpHeaders deprecated
1137
+ *
1138
+ * @return bool
1139
+ */
1140
+ public function isTablet( $userAgent = null, $httpHeaders = null ) {
1141
+ // Check specifically for cloudfront headers if the useragent === 'Amazon CloudFront'
1142
+ if ( $this->getUserAgent() === 'Amazon CloudFront' ) {
1143
+ $cfHeaders = $this->getCfHeaders();
1144
+ if ( array_key_exists( 'HTTP_CLOUDFRONT_IS_TABLET_VIEWER', $cfHeaders ) && $cfHeaders['HTTP_CLOUDFRONT_IS_TABLET_VIEWER'] === 'true' ) {
1145
+ return true;
1146
+ }
1147
+ }
1148
 
1149
+ $this->setDetectionType( self::DETECTION_TYPE_MOBILE );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1150
 
1151
+ foreach ( self::$tabletDevices as $_regex ) {
1152
+ if ( $this->match( $_regex, $userAgent ) ) {
1153
+ return true;
1154
+ }
1155
+ }
1156
 
1157
+ return false;
1158
+ }
1159
 
1160
+ /**
1161
+ * This method checks for a certain property in the
1162
+ * userAgent.
1163
+ * @todo: The httpHeaders part is not yet used.
1164
+ *
1165
+ * @param string $key
1166
+ * @param string $userAgent deprecated
1167
+ * @param string $httpHeaders deprecated
1168
+ *
1169
+ * @return bool|int|null
1170
+ */
1171
+ public function is( $key, $userAgent = null, $httpHeaders = null ) {
1172
+ // Set the UA and HTTP headers only if needed (eg. batch mode).
1173
+ if ( $httpHeaders ) {
1174
+ $this->setHttpHeaders( $httpHeaders );
1175
+ }
1176
 
1177
+ if ( $userAgent ) {
1178
+ $this->setUserAgent( $userAgent );
1179
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1180
 
1181
+ $this->setDetectionType( self::DETECTION_TYPE_EXTENDED );
 
 
 
 
 
 
 
 
1182
 
1183
+ return $this->matchUAAgainstKey( $key );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1184
  }
1185
 
1186
+ /**
1187
+ * Some detection rules are relative (not standard),
1188
+ * because of the diversity of devices, vendors and
1189
+ * their conventions in representing the User-Agent or
1190
+ * the HTTP headers.
1191
+ *
1192
+ * This method will be used to check custom regexes against
1193
+ * the User-Agent string.
1194
+ *
1195
+ * @param $regex
1196
+ * @param string $userAgent
1197
+ *
1198
+ * @return bool
1199
+ *
1200
+ * @todo: search in the HTTP headers too.
1201
+ */
1202
+ public function match( $regex, $userAgent = null ) {
1203
+ $match = (bool) preg_match( sprintf( '#%s#is', $regex ), ( false === empty( $userAgent ) ? $userAgent : $this->userAgent ), $matches );
1204
+ // If positive match is found, store the results for debug.
1205
+ if ( $match ) {
1206
+ $this->matchingRegex = $regex;
1207
+ $this->matchesArray = $matches;
1208
+ }
1209
 
1210
+ return $match;
1211
+ }
1212
+
1213
+ /**
1214
+ * Get the properties array.
1215
+ *
1216
+ * @return array
1217
+ */
1218
+ public static function getProperties() {
1219
+ return self::$properties;
 
 
 
 
 
 
 
1220
  }
1221
 
1222
+ /**
1223
+ * Prepare the version number.
1224
+ *
1225
+ * @todo Remove the error supression from str_replace() call.
1226
+ *
1227
+ * @param string $ver The string version, like "2.6.21.2152";
1228
+ *
1229
+ * @return float
1230
+ */
1231
+ public function prepareVersionNo( $ver ) {
1232
+ $ver = str_replace( array( '_', ' ', '/' ), '.', $ver );
1233
+ $arrVer = explode( '.', $ver, 2 );
1234
+
1235
+ if ( isset( $arrVer[1] ) ) {
1236
+ $arrVer[1] = @str_replace( '.', '', $arrVer[1] ); // @todo: treat strings versions.
1237
+ }
1238
+
1239
+ return (float) implode( '.', $arrVer );
1240
  }
1241
 
1242
+ /**
1243
+ * Check the version of the given property in the User-Agent.
1244
+ * Will return a float number. (eg. 2_0 will return 2.0, 4.3.1 will return 4.31)
1245
+ *
1246
+ * @param string $propertyName The name of the property. See self::getProperties() array
1247
+ * keys for all possible properties.
1248
+ * @param string $type Either self::VERSION_TYPE_STRING to get a string value or
1249
+ * self::VERSION_TYPE_FLOAT indicating a float value. This parameter
1250
+ * is optional and defaults to self::VERSION_TYPE_STRING. Passing an
1251
+ * invalid parameter will default to the this type as well.
1252
+ *
1253
+ * @return string|float The version of the property we are trying to extract.
1254
+ */
1255
+ public function version( $propertyName, $type = self::VERSION_TYPE_STRING ) {
1256
+ if ( empty( $propertyName ) ) {
1257
+ return false;
1258
+ }
1259
+
1260
+ // set the $type to the default if we don't recognize the type
1261
+ if ( $type !== self::VERSION_TYPE_STRING && $type !== self::VERSION_TYPE_FLOAT ) {
1262
+ $type = self::VERSION_TYPE_STRING;
1263
+ }
1264
+
1265
+ $properties = self::getProperties();
1266
 
1267
+ // Check if the property exists in the properties array.
1268
+ if ( true === isset( $properties[ $propertyName ] ) ) {
1269
 
1270
+ // Prepare the pattern to be matched.
1271
+ // Make sure we always deal with an array (string is converted).
1272
+ $properties[ $propertyName ] = (array) $properties[ $propertyName ];
1273
 
1274
+ foreach ( $properties[ $propertyName ] as $propertyMatchString ) {
1275
 
1276
+ $propertyPattern = str_replace( '[VER]', self::VER, $propertyMatchString );
1277
 
1278
+ // Identify and extract the version.
1279
+ preg_match( sprintf( '#%s#is', $propertyPattern ), $this->userAgent, $match );
1280
 
1281
+ if ( false === empty( $match[1] ) ) {
1282
+ $version = ( $type == self::VERSION_TYPE_FLOAT ? $this->prepareVersionNo( $match[1] ) : $match[1] );
1283
 
1284
+ return $version;
1285
+ }
1286
 
 
1287
  }
1288
 
1289
  }
1290
 
1291
+ return false;
1292
  }
1293
 
1294
+ /**
1295
+ * Retrieve the mobile grading, using self::MOBILE_GRADE_* constants.
1296
+ *
1297
+ * @return string One of the self::MOBILE_GRADE_* constants.
1298
+ */
1299
+ public function mobileGrade() {
1300
+ $isMobile = $this->isMobile();
 
 
 
 
 
 
 
 
 
 
1301
 
1302
+ if (
1303
+ // Apple iOS 4-7.0 – Tested on the original iPad (4.3 / 5.0), iPad 2 (4.3 / 5.1 / 6.1), iPad 3 (5.1 / 6.0), iPad Mini (6.1), iPad Retina (7.0), iPhone 3GS (4.3), iPhone 4 (4.3 / 5.1), iPhone 4S (5.1 / 6.0), iPhone 5 (6.0), and iPhone 5S (7.0)
1304
+ $this->is( 'iOS' ) && $this->version( 'iPad', self::VERSION_TYPE_FLOAT ) >= 4.3 ||
1305
+ $this->is( 'iOS' ) && $this->version( 'iPhone', self::VERSION_TYPE_FLOAT ) >= 4.3 ||
1306
+ $this->is( 'iOS' ) && $this->version( 'iPod', self::VERSION_TYPE_FLOAT ) >= 4.3 ||
1307
 
1308
+ // Android 2.1-2.3 - Tested on the HTC Incredible (2.2), original Droid (2.2), HTC Aria (2.1), Google Nexus S (2.3). Functional on 1.5 & 1.6 but performance may be sluggish, tested on Google G1 (1.5)
1309
+ // Android 3.1 (Honeycomb) - Tested on the Samsung Galaxy Tab 10.1 and Motorola XOOM
1310
+ // Android 4.0 (ICS) - Tested on a Galaxy Nexus. Note: transition performance can be poor on upgraded devices
1311
+ // Android 4.1 (Jelly Bean) - Tested on a Galaxy Nexus and Galaxy 7
1312
+ ( $this->version( 'Android', self::VERSION_TYPE_FLOAT ) > 2.1 && $this->is( 'Webkit' ) ) ||
1313
 
1314
+ // Windows Phone 7.5-8 - Tested on the HTC Surround (7.5), HTC Trophy (7.5), LG-E900 (7.5), Nokia 800 (7.8), HTC Mazaa (7.8), Nokia Lumia 520 (8), Nokia Lumia 920 (8), HTC 8x (8)
1315
+ $this->version( 'Windows Phone OS', self::VERSION_TYPE_FLOAT ) >= 7.5 ||
 
 
 
1316
 
1317
+ // Tested on the Torch 9800 (6) and Style 9670 (6), BlackBerry® Torch 9810 (7), BlackBerry Z10 (10)
1318
+ $this->is( 'BlackBerry' ) && $this->version( 'BlackBerry', self::VERSION_TYPE_FLOAT ) >= 6.0 ||
1319
+ // Blackberry Playbook (1.0-2.0) - Tested on PlayBook
1320
+ $this->match( 'Playbook.*Tablet' ) ||
1321
 
1322
+ // Palm WebOS (1.4-3.0) - Tested on the Palm Pixi (1.4), Pre (1.4), Pre 2 (2.0), HP TouchPad (3.0)
1323
+ ( $this->version( 'webOS', self::VERSION_TYPE_FLOAT ) >= 1.4 && $this->match( 'Palm|Pre|Pixi' ) ) ||
1324
+ // Palm WebOS 3.0 - Tested on HP TouchPad
1325
+ $this->match( 'hp.*TouchPad' ) ||
1326
 
1327
+ // Firefox Mobile 18 - Tested on Android 2.3 and 4.1 devices
1328
+ ( $this->is( 'Firefox' ) && $this->version( 'Firefox', self::VERSION_TYPE_FLOAT ) >= 18 ) ||
1329
 
1330
+ // Chrome for Android - Tested on Android 4.0, 4.1 device
1331
+ ( $this->is( 'Chrome' ) && $this->is( 'AndroidOS' ) && $this->version( 'Android', self::VERSION_TYPE_FLOAT ) >= 4.0 ) ||
1332
 
1333
+ // Skyfire 4.1 - Tested on Android 2.3 device
1334
+ ( $this->is( 'Skyfire' ) && $this->version( 'Skyfire', self::VERSION_TYPE_FLOAT ) >= 4.1 && $this->is( 'AndroidOS' ) && $this->version( 'Android', self::VERSION_TYPE_FLOAT ) >= 2.3 ) ||
1335
 
1336
+ // Opera Mobile 11.5-12: Tested on Android 2.3
1337
+ ( $this->is( 'Opera' ) && $this->version( 'Opera Mobi', self::VERSION_TYPE_FLOAT ) >= 11.5 && $this->is( 'AndroidOS' ) ) ||
1338
 
1339
+ // Meego 1.2 - Tested on Nokia 950 and N9
1340
+ $this->is( 'MeeGoOS' ) ||
1341
 
1342
+ // Tizen (pre-release) - Tested on early hardware
1343
+ $this->is( 'Tizen' ) ||
 
1344
 
1345
+ // Samsung Bada 2.0 - Tested on a Samsung Wave 3, Dolphin browser
1346
+ // @todo: more tests here!
1347
+ $this->is( 'Dolfin' ) && $this->version( 'Bada', self::VERSION_TYPE_FLOAT ) >= 2.0 ||
1348
 
1349
+ // UC Browser - Tested on Android 2.3 device
1350
+ ( ( $this->is( 'UC Browser' ) || $this->is( 'Dolfin' ) ) && $this->version( 'Android', self::VERSION_TYPE_FLOAT ) >= 2.3 ) ||
 
1351
 
1352
+ // Kindle 3 and Fire - Tested on the built-in WebKit browser for each
1353
+ ( $this->match( 'Kindle Fire' ) ||
1354
+ $this->is( 'Kindle' ) && $this->version( 'Kindle', self::VERSION_TYPE_FLOAT ) >= 3.0 ) ||
1355
 
1356
+ // Nook Color 1.4.1 - Tested on original Nook Color, not Nook Tablet
1357
+ $this->is( 'AndroidOS' ) && $this->is( 'NookTablet' ) ||
1358
 
1359
+ // Chrome Desktop 16-24 - Tested on OS X 10.7 and Windows 7
1360
+ $this->version( 'Chrome', self::VERSION_TYPE_FLOAT ) >= 16 && ! $isMobile ||
1361
 
1362
+ // Safari Desktop 5-6 - Tested on OS X 10.7 and Windows 7
1363
+ $this->version( 'Safari', self::VERSION_TYPE_FLOAT ) >= 5.0 && ! $isMobile ||
1364
 
1365
+ // Firefox Desktop 10-18 - Tested on OS X 10.7 and Windows 7
1366
+ $this->version( 'Firefox', self::VERSION_TYPE_FLOAT ) >= 10.0 && ! $isMobile ||
1367
 
1368
+ // Internet Explorer 7-9 - Tested on Windows XP, Vista and 7
1369
+ $this->version( 'IE', self::VERSION_TYPE_FLOAT ) >= 7.0 && ! $isMobile ||
 
1370
 
1371
+ // Opera Desktop 10-12 - Tested on OS X 10.7 and Windows 7
1372
+ $this->version( 'Opera', self::VERSION_TYPE_FLOAT ) >= 10 && ! $isMobile
1373
+ ) {
1374
+ return self::MOBILE_GRADE_A;
1375
+ }
1376
 
1377
+ if (
1378
+ $this->is( 'iOS' ) && $this->version( 'iPad', self::VERSION_TYPE_FLOAT ) < 4.3 ||
1379
+ $this->is( 'iOS' ) && $this->version( 'iPhone', self::VERSION_TYPE_FLOAT ) < 4.3 ||
1380
+ $this->is( 'iOS' ) && $this->version( 'iPod', self::VERSION_TYPE_FLOAT ) < 4.3 ||
1381
 
1382
+ // Blackberry 5.0: Tested on the Storm 2 9550, Bold 9770
1383
+ $this->is( 'Blackberry' ) && $this->version( 'BlackBerry', self::VERSION_TYPE_FLOAT ) >= 5 && $this->version( 'BlackBerry', self::VERSION_TYPE_FLOAT ) < 6 ||
1384
 
1385
+ //Opera Mini (5.0-6.5) - Tested on iOS 3.2/4.3 and Android 2.3
1386
+ ( $this->version( 'Opera Mini', self::VERSION_TYPE_FLOAT ) >= 5.0 && $this->version( 'Opera Mini', self::VERSION_TYPE_FLOAT ) <= 7.0 &&
1387
+ ( $this->version( 'Android', self::VERSION_TYPE_FLOAT ) >= 2.3 || $this->is( 'iOS' ) ) ) ||
1388
 
1389
+ // Nokia Symbian^3 - Tested on Nokia N8 (Symbian^3), C7 (Symbian^3), also works on N97 (Symbian^1)
1390
+ $this->match( 'NokiaN8|NokiaC7|N97.*Series60|Symbian/3' ) ||
1391
 
1392
+ // @todo: report this (tested on Nokia N71)
1393
+ $this->version( 'Opera Mobi', self::VERSION_TYPE_FLOAT ) >= 11 && $this->is( 'SymbianOS' )
1394
+ ) {
1395
+ return self::MOBILE_GRADE_B;
1396
+ }
1397
 
1398
+ if (
1399
+ // Blackberry 4.x - Tested on the Curve 8330
1400
+ $this->version( 'BlackBerry', self::VERSION_TYPE_FLOAT ) <= 5.0 ||
1401
+ // Windows Mobile - Tested on the HTC Leo (WinMo 5.2)
1402
+ $this->match( 'MSIEMobile|Windows CE.*Mobile' ) || $this->version( 'Windows Mobile', self::VERSION_TYPE_FLOAT ) <= 5.2 ||
1403
+
1404
+ // Tested on original iPhone (3.1), iPhone 3 (3.2)
1405
+ $this->is( 'iOS' ) && $this->version( 'iPad', self::VERSION_TYPE_FLOAT ) <= 3.2 ||
1406
+ $this->is( 'iOS' ) && $this->version( 'iPhone', self::VERSION_TYPE_FLOAT ) <= 3.2 ||
1407
+ $this->is( 'iOS' ) && $this->version( 'iPod', self::VERSION_TYPE_FLOAT ) <= 3.2 ||
1408
+
1409
+ // Internet Explorer 7 and older - Tested on Windows XP
1410
+ $this->version( 'IE', self::VERSION_TYPE_FLOAT ) <= 7.0 && ! $isMobile
1411
+ ) {
1412
+ return self::MOBILE_GRADE_C;
1413
+ }
1414
 
1415
+ // All older smartphone platforms and featurephones - Any device that doesn't support media queries
1416
+ // will receive the basic, C grade experience.
1417
  return self::MOBILE_GRADE_C;
1418
  }
 
 
 
 
1419
  }
1420
  }
public/includes/class-spu-rules.php CHANGED
@@ -5,7 +5,10 @@
5
  * Class that will compare rules and determine if popup needs to show
6
  * @since: 2.0
7
  */
8
-
 
 
 
9
  class Spu_Rules
10
  {
11
  /**
@@ -74,9 +77,9 @@ class Spu_Rules
74
  add_filter('spu/rules/rule_match/tablets', array($this, 'rule_match_tablets'), 10, 2);
75
  add_filter('spu/rules/rule_match/referrer', array($this, 'rule_match_referrer'), 10, 2);
76
 
77
- $this->post_id = isset( $post->ID ) ? $post->ID : '';
78
- $this->referrer = isset($_SERVER['HTTP_REFERRER']) ? $_SERVER['HTTP_REFERRER'] : '';
79
-
80
  if( defined('DOING_AJAX') ) {
81
 
82
  if( isset( $_REQUEST['pid'] ) ) {
@@ -304,7 +307,6 @@ class Spu_Rules
304
 
305
  }
306
 
307
-
308
  /*
309
  * rule_match_post_type
310
  *
@@ -989,6 +991,4 @@ class Spu_Rules
989
  return $post_type;
990
  }
991
 
992
- }
993
-
994
- ?>
5
  * Class that will compare rules and determine if popup needs to show
6
  * @since: 2.0
7
  */
8
+ if(!isset($_SESSION) )
9
+ {
10
+ session_start();
11
+ }
12
  class Spu_Rules
13
  {
14
  /**
77
  add_filter('spu/rules/rule_match/tablets', array($this, 'rule_match_tablets'), 10, 2);
78
  add_filter('spu/rules/rule_match/referrer', array($this, 'rule_match_referrer'), 10, 2);
79
 
80
+ $this->post_id = isset( $post->ID ) ? $post->ID : '';
81
+ $this->referrer = isset($_SERVER['HTTP_REFERRER']) ? $_SERVER['HTTP_REFERRER'] : '';
82
+
83
  if( defined('DOING_AJAX') ) {
84
 
85
  if( isset( $_REQUEST['pid'] ) ) {
307
 
308
  }
309
 
 
310
  /*
311
  * rule_match_post_type
312
  *
991
  return $post_type;
992
  }
993
 
994
+ }