Animate It! - Version 2.0.0

Version Description

Download this release

Release Info

Developer eleopard
Plugin Icon 128x128 Animate It!
Version 2.0.0
Comparing to
See all releases

Code changes from version 2.1.5 to 2.0.0

assets/css/animate-animo.css CHANGED
@@ -24,12 +24,6 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
24
  opacity:1;
25
  }
26
 
27
- .animated {
28
- -webkit-animation-duration: 1s;
29
- -moz-animation-duration: 1s;
30
- -ms-animation-duration: 1s;
31
- -o-animation-duration: 1s;
32
- }
33
 
34
  /*Delay classes*/
35
  .delay1 {
@@ -281,11 +275,6 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
281
  -webkit-perspective: 1000;
282
  }
283
 
284
- .animated.infinite {
285
- -webkit-animation-iteration-count: infinite;
286
- animation-iteration-count: infinite;
287
- }
288
-
289
  @-webkit-keyframes flash {
290
  0%, 50%, 100% {opacity: 1;}
291
  25%, 75% {opacity: 0;}
@@ -4475,8 +4464,4 @@ Daniel Raftery <@ThirvingKings>
4475
  100% { transform: rotate3d( 80,70,10,180deg ); }
4476
  }
4477
 
4478
- .eds-animation-paused {
4479
- -webkit-animation-play-state: paused;
4480
- animation-play-state: paused;
4481
- }
4482
-
24
  opacity:1;
25
  }
26
 
 
 
 
 
 
 
27
 
28
  /*Delay classes*/
29
  .delay1 {
275
  -webkit-perspective: 1000;
276
  }
277
 
 
 
 
 
 
278
  @-webkit-keyframes flash {
279
  0%, 50%, 100% {opacity: 1;}
280
  25%, 75% {opacity: 0;}
4464
  100% { transform: rotate3d( 80,70,10,180deg ); }
4465
  }
4466
 
4467
+
 
 
 
 
assets/helper/class-eds-mobile-detect.php CHANGED
@@ -8,9 +8,7 @@
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,1429 +20,1231 @@
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.22
26
  */
27
  if ( !class_exists( 'EDS_Mobile_Detect' ) ):
28
 
29
- class EDS_Mobile_Detect
30
- {
31
- /**
32
- * Mobile detection type.
33
- *
34
- * @deprecated since version 2.6.9
35
- */
36
- const DETECTION_TYPE_MOBILE = 'mobile';
37
-
38
- /**
39
- * Extended detection type.
40
- *
41
- * @deprecated since version 2.6.9
42
- */
43
- const DETECTION_TYPE_EXTENDED = 'extended';
44
-
45
- /**
46
- * A frequently used regular expression to extract version #s.
47
- *
48
- * @deprecated since version 2.6.9
49
- */
50
- const VER = '([\w._\+]+)';
51
-
52
- /**
53
- * Top-level device.
54
- */
55
- const MOBILE_GRADE_A = 'A';
56
-
57
- /**
58
- * Mid-level device.
59
- */
60
- const MOBILE_GRADE_B = 'B';
61
-
62
- /**
63
- * Low-level device.
64
- */
65
- const MOBILE_GRADE_C = 'C';
66
-
67
- /**
68
- * Stores the version number of the current release.
69
- */
70
- const VERSION = '2.8.22';
71
-
72
- /**
73
- * A type for the version() method indicating a string return value.
74
- */
75
- const VERSION_TYPE_STRING = 'text';
76
-
77
- /**
78
- * A type for the version() method indicating a float return value.
79
- */
80
- const VERSION_TYPE_FLOAT = 'float';
81
-
82
- /**
83
- * A cache for resolved matches
84
- * @var array
85
- */
86
- protected $cache = array();
87
-
88
- /**
89
- * The User-Agent HTTP header is stored in here.
90
- * @var string
91
- */
92
- protected $userAgent = null;
93
-
94
- /**
95
- * HTTP headers in the PHP-flavor. So HTTP_USER_AGENT and SERVER_SOFTWARE.
96
- * @var array
97
- */
98
- protected $httpHeaders = array();
99
-
100
- /**
101
- * CloudFront headers. E.g. CloudFront-Is-Desktop-Viewer, CloudFront-Is-Mobile-Viewer & CloudFront-Is-Tablet-Viewer.
102
- * @var array
103
- */
104
- protected $cloudfrontHeaders = array();
105
-
106
- /**
107
- * The matching Regex.
108
- * This is good for debug.
109
- * @var string
110
- */
111
- protected $matchingRegex = null;
112
-
113
- /**
114
- * The matches extracted from the regex expression.
115
- * This is good for debug.
116
- * @var string
117
- */
118
- protected $matchesArray = null;
119
-
120
- /**
121
- * The detection type, using self::DETECTION_TYPE_MOBILE or self::DETECTION_TYPE_EXTENDED.
122
- *
123
- * @deprecated since version 2.6.9
124
- *
125
- * @var string
126
- */
127
- protected $detectionType = self::DETECTION_TYPE_MOBILE;
128
-
129
- /**
130
- * HTTP headers that trigger the 'isMobile' detection
131
- * to be true.
132
- *
133
- * @var array
134
- */
135
- protected static $mobileHeaders = array(
136
-
137
- 'HTTP_ACCEPT' => array('matches' => array(
138
- // Opera Mini; @reference: http://dev.opera.com/articles/view/opera-binary-markup-language/
139
- 'application/x-obml2d',
140
- // BlackBerry devices.
141
- 'application/vnd.rim.html',
142
- 'text/vnd.wap.wml',
143
- 'application/vnd.wap.xhtml+xml'
144
- )),
145
- 'HTTP_X_WAP_PROFILE' => null,
146
- 'HTTP_X_WAP_CLIENTID' => null,
147
- 'HTTP_WAP_CONNECTION' => null,
148
- 'HTTP_PROFILE' => null,
149
- // Reported by Opera on Nokia devices (eg. C3).
150
- 'HTTP_X_OPERAMINI_PHONE_UA' => null,
151
- 'HTTP_X_NOKIA_GATEWAY_ID' => null,
152
- 'HTTP_X_ORANGE_ID' => null,
153
- 'HTTP_X_VODAFONE_3GPDPCONTEXT' => null,
154
- 'HTTP_X_HUAWEI_USERID' => null,
155
- // Reported by Windows Smartphones.
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', // |\biTunes
172
- 'BlackBerry' => 'BlackBerry|\bBB10\b|rim[0-9]+',
173
- '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',
174
- 'Nexus' => 'Nexus One|Nexus S|Galaxy.*Nexus|Android.*Nexus.*Mobile|Nexus 4|Nexus 5|Nexus 6',
175
- // @todo: Is 'Dell Streak' a tablet or a phone? ;)
176
- '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',
177
- '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',
178
- '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|SM-G9350|SM-J120F',
179
- '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)',
180
- 'Sony' => 'SonyST|SonyLT|SonyEricsson|SonyEricssonLT15iv|LT18i|E10i|LT28h|LT26w|SonyEricssonMT27i|C5303|C6902|C6903|C6906|C6943|D2533',
181
- 'Asus' => 'Asus.*Galaxy|PadFone.*Mobile',
182
- 'NokiaLumia' => 'Lumia [0-9]{3,4}',
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', // avantgo|blazer|elaine|hiptop|plucker|xiino ;
188
- 'Vertu' => 'Vertu|Vertu.*Ltd|Vertu.*Ascent|Vertu.*Ayxta|Vertu.*Constellation(F|Quest)?|Vertu.*Monika|Vertu.*Signature', // Just for fun ;)
189
- // http://www.pantech.co.kr/en/prod/prodList.do?gbrand=VEGA (PANTECH)
190
- // Most of the VEGA devices are legacy. PANTECH seem to be newer devices based on Android.
191
- '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',
192
- // http://www.fly-phone.com/devices/smartphones/ ; Included only smartphones.
193
- 'Fly' => 'IQ230|IQ444|IQ450|IQ440|IQ442|IQ441|IQ245|IQ256|IQ236|IQ255|IQ235|IQ245|IQ275|IQ240|IQ285|IQ280|IQ270|IQ260|IQ250',
194
- // http://fr.wikomobile.com
195
- 'Wiko' => 'KITE 4G|HIGHWAY|GETAWAY|STAIRWAY|DARKSIDE|DARKFULL|DARKNIGHT|DARKMOON|SLIDE|WAX 4G|RAINBOW|BLOOM|SUNSET|GOA(?!nna)|LENNY|BARRY|IGGY|OZZY|CINK FIVE|CINK PEAX|CINK PEAX 2|CINK SLIM|CINK SLIM 2|CINK +|CINK KING|CINK PEAX|CINK SLIM|SUBLIM',
196
- 'iMobile' => 'i-mobile (IQ|i-STYLE|idea|ZAA|Hitz)',
197
- // Added simvalley mobile just for fun. They have some interesting devices.
198
- // http://www.simvalley.fr/telephonie---gps-_22_telephonie-mobile_telephones_.html
199
- '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',
200
- // Wolfgang - a brand that is sold by Aldi supermarkets.
201
- // http://www.wolfgangmobile.com/
202
- 'Wolfgang' => 'AT-B24D|AT-AS50HD|AT-AS40W|AT-AS55HD|AT-AS45q2|AT-B26D|AT-AS50Q',
203
- 'Alcatel' => 'Alcatel',
204
- 'Nintendo' => 'Nintendo 3DS',
205
- // http://en.wikipedia.org/wiki/Amoi
206
- 'Amoi' => 'Amoi',
207
- // http://en.wikipedia.org/wiki/INQ
208
- 'INQ' => 'INQ',
209
- // @Tapatalk is a mobile app; http://support.tapatalk.com/threads/smf-2-0-2-os-and-browser-detection-plugin-and-tapatalk.15565/#post-79039
210
- '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',
211
- );
212
-
213
- /**
214
- * List of tablet devices.
215
- *
216
- * @var array
217
- */
218
- protected static $tabletDevices = array(
219
- // @todo: check for mobile friendly emails topic.
220
- 'iPad' => 'iPad|iPad.*Mobile',
221
- // Removed |^.*Android.*Nexus(?!(?:Mobile).)*$
222
- // @see #442
223
- 'NexusTablet' => 'Android.*Nexus[\s]+(7|9|10)',
224
- '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-T815|SM-T360|SM-T533|SM-T113|SM-T335|SM-T715|SM-T560|SM-T670|SM-T677|SM-T377|SM-T567|SM-T357T|SM-T555|SM-T561', // SCH-P709|SCH-P729|SM-T2558|GT-I9205 - Samsung Mega - treat them like a regular phone.
225
- // http://docs.aws.amazon.com/silk/latest/developerguide/user-agent.html
226
- 'Kindle' => 'Kindle|Silk.*Accelerated|Android.*\b(KFOT|KFTT|KFJWI|KFJWA|KFOTE|KFSOWI|KFTHWI|KFTHWA|KFAPWI|KFAPWA|WFJWAE|KFSAWA|KFSAWI|KFASWI|KFARWI)\b',
227
- // Only the Surface tablets with Windows RT are considered mobile.
228
- // http://msdn.microsoft.com/en-us/library/ie/hh920767(v=vs.85).aspx
229
- 'SurfaceTablet' => 'Windows NT [0-9.]+; ARM;.*(Tablet|ARMBJS)',
230
- // http://shopping1.hp.com/is-bin/INTERSHOP.enfinity/WFS/WW-USSMBPublicStore-Site/en_US/-/USD/ViewStandardCatalog-Browse?CatalogCategoryID=JfIQ7EN5lqMAAAEyDcJUDwMT
231
- 'HPTablet' => 'HP Slate (7|8|10)|HP ElitePad 900|hp-tablet|EliteBook.*Touch|HP 8|Slate 21|HP SlateBook 10',
232
- // Watch out for PadFone, see #132.
233
- // http://www.asus.com/de/Tablets_Mobile/Memo_Pad_Products/
234
- '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|P01Y|PO1MA',
235
- 'BlackBerryTablet' => 'PlayBook|RIM Tablet',
236
- 'HTCtablet' => 'HTC_Flyer_P512|HTC Flyer|HTC Jetstream|HTC-P715a|HTC EVO View 4G|PG41200|PG09410',
237
- 'MotorolaTablet' => 'xoom|sholest|MZ615|MZ605|MZ505|MZ601|MZ602|MZ603|MZ604|MZ606|MZ607|MZ608|MZ609|MZ615|MZ616|MZ617',
238
- 'NookTablet' => 'Android.*Nook|NookColor|nook browser|BNRV200|BNRV200A|BNTV250|BNTV250A|BNTV400|BNTV600|LogicPD Zoom2',
239
- // http://www.acer.ro/ac/ro/RO/content/drivers
240
- // http://www.packardbell.co.uk/pb/en/GB/content/download (Packard Bell is part of Acer)
241
- // http://us.acer.com/ac/en/US/content/group/tablets
242
- // http://www.acer.de/ac/de/DE/content/models/tablets/
243
- // Can conflict with Micromax and Motorola phones codes.
244
- '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|\bA3-A20',
245
- // http://eu.computers.toshiba-europe.com/innovation/family/Tablets/1098744/banner_id/tablet_footerlink/
246
- // http://us.toshiba.com/tablets/tablet-finder
247
- // http://www.toshiba.co.jp/regza/tablet/
248
- 'ToshibaTablet' => 'Android.*(AT100|AT105|AT200|AT205|AT270|AT275|AT300|AT305|AT1S5|AT500|AT570|AT700|AT830)|TOSHIBA.*FOLIO',
249
- // http://www.nttdocomo.co.jp/english/service/developer/smart_phone/technical_info/spec/index.html
250
- // http://www.lg.com/us/tablets
251
- 'LGTablet' => '\bL-06C|LG-V909|LG-V900|LG-V700|LG-V510|LG-V500|LG-V410|LG-V400|LG-VK810\b',
252
- 'FujitsuTablet' => 'Android.*\b(F-01D|F-02F|F-05E|F-10D|M532|Q572)\b',
253
- // Prestigio Tablets http://www.prestigio.com/support
254
- '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',
255
- // http://support.lenovo.com/en_GB/downloads/default.page?#
256
- 'LenovoTablet' => 'Lenovo TAB|Idea(Tab|Pad)( A1|A10| K1|)|ThinkPad([ ]+)?Tablet|YT3-X90L|YT3-X90F|YT3-X90X|Lenovo.*(S2109|S2110|S5000|S6000|K3011|A3000|A3500|A1000|A2107|A2109|A1107|A5500|A7600|B6000|B8000|B8080)(-|)(FL|F|HV|H|)',
257
- // http://www.dell.com/support/home/us/en/04/Products/tab_mob/tablets
258
- 'DellTablet' => 'Venue 11|Venue 8|Venue 7|Dell Streak 10|Dell Streak 7',
259
- // http://www.yarvik.com/en/matrix/tablets/
260
- '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',
261
- 'MedionTablet' => 'Android.*\bOYO\b|LIFE.*(P9212|P9514|P9516|S9512)|LIFETAB',
262
- 'ArnovaTablet' => 'AN10G2|AN7bG3|AN7fG3|AN8G3|AN8cG3|AN7G3|AN9G3|AN7dG3|AN7dG3ST|AN7dG3ChildPad|AN10bG3|AN10bG3DT|AN9G2',
263
- // http://www.intenso.de/kategorie_en.php?kategorie=33
264
- // @todo: http://www.nbhkdz.com/read/b8e64202f92a2df129126bff.html - investigate
265
- 'IntensoTablet' => 'INM8002KP|INM1010FP|INM805ND|Intenso Tab|TAB1004',
266
- // IRU.ru Tablets http://www.iru.ru/catalog/soho/planetable/
267
- 'IRUTablet' => 'M702pro',
268
- 'MegafonTablet' => 'MegaFon V9|\bZTE V9\b|Android.*\bMT7A\b',
269
- // http://www.e-boda.ro/tablete-pc.html
270
- 'EbodaTablet' => 'E-Boda (Supreme|Impresspeed|Izzycomm|Essential)',
271
- // http://www.allview.ro/produse/droseries/lista-tablete-pc/
272
- 'AllViewTablet' => 'Allview.*(Viva|Alldro|City|Speed|All TV|Frenzy|Quasar|Shine|TX1|AX1|AX2)',
273
- // http://wiki.archosfans.com/index.php?title=Main_Page
274
- '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',
275
- // http://www.ainol.com/plugin.php?identifier=ainol&module=product
276
- 'AinolTablet' => 'NOVO7|NOVO8|NOVO10|Novo7Aurora|Novo7Basic|NOVO7PALADIN|novo9-Spark',
277
- 'NokiaLumiaTablet' => 'Lumia 2520',
278
- // @todo: inspect http://esupport.sony.com/US/p/select-system.pl?DIRECTOR=DRIVER
279
- // Readers http://www.atsuhiro-me.net/ebook/sony-reader/sony-reader-web-browser
280
- // http://www.sony.jp/support/tablet/
281
- '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',
282
- // 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
283
- 'PhilipsTablet' => '\b(PI2010|PI3000|PI3100|PI3105|PI3110|PI3205|PI3210|PI3900|PI4010|PI7000|PI7100)\b',
284
- // db + http://www.cube-tablet.com/buy-products.html
285
- 'CubeTablet' => 'Android.*(K8GT|U9GT|U10GT|U16GT|U17GT|U18GT|U19GT|U20GT|U23GT|U30GT)|CUBE U8GT',
286
- // http://www.cobyusa.com/?p=pcat&pcat_id=3001
287
- 'CobyTablet' => 'MID1042|MID1045|MID1125|MID1126|MID7012|MID7014|MID7015|MID7034|MID7035|MID7036|MID7042|MID7048|MID7127|MID8042|MID8048|MID8127|MID9042|MID9740|MID9742|MID7022|MID7010',
288
- // http://www.match.net.cn/products.asp
289
- '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|MID4X10',
290
- // http://www.msi.com/support
291
- // @todo Research the Windows Tablets.
292
- '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',
293
- // @todo http://www.kyoceramobile.com/support/drivers/
294
- // 'KyoceraTablet' => null,
295
- // @todo http://intexuae.com/index.php/category/mobile-devices/tablets-products/
296
- // 'IntextTablet' => null,
297
- // http://pdadb.net/index.php?m=pdalist&list=SMiT (NoName Chinese Tablets)
298
- // http://www.imp3.net/14/show.php?itemid=20454
299
- 'SMiTTablet' => 'Android.*(\bMID\b|MID-560|MTV-T1200|MTV-PND531|MTV-P1101|MTV-PND530)',
300
- // http://www.rock-chips.com/index.php?do=prod&pid=2
301
- 'RockChipTablet' => 'Android.*(RK2818|RK2808A|RK2918|RK3066)|RK2738|RK2808A',
302
- // http://www.fly-phone.com/devices/tablets/ ; http://www.fly-phone.com/service/
303
- 'FlyTablet' => 'IQ310|Fly Vision',
304
- // http://www.bqreaders.com/gb/tablets-prices-sale.html
305
- 'bqTablet' => 'Android.*(bq)?.*(Elcano|Curie|Edison|Maxwell|Kepler|Pascal|Tesla|Hypatia|Platon|Newton|Livingstone|Cervantes|Avant|Aquaris E10)|Maxwell.*Lite|Maxwell.*Plus',
306
- // http://www.huaweidevice.com/worldwide/productFamily.do?method=index&directoryId=5011&treeId=3290
307
- // http://www.huaweidevice.com/worldwide/downloadCenter.do?method=index&directoryId=3372&treeId=0&tb=1&type=software (including legacy tablets)
308
- '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',
309
- // Nec or Medias Tab
310
- 'NecTablet' => '\bN-06D|\bN-08D',
311
- // Pantech Tablets: http://www.pantechusa.com/phones/
312
- 'PantechTablet' => 'Pantech.*P4100',
313
- // Broncho Tablets: http://www.broncho.cn/ (hard to find)
314
- 'BronchoTablet' => 'Broncho.*(N701|N708|N802|a710)',
315
- // http://versusuk.com/support.html
316
- 'VersusTablet' => 'TOUCHPAD.*[78910]|\bTOUCHTAB\b',
317
- // http://www.zync.in/index.php/our-products/tablet-phablets
318
- 'ZyncTablet' => 'z1000|Z99 2G|z99|z930|z999|z990|z909|Z919|z900',
319
- // http://www.positivoinformatica.com.br/www/pessoal/tablet-ypy/
320
- 'PositivoTablet' => 'TB07STA|TB10STA|TB07FTA|TB10FTA',
321
- // https://www.nabitablet.com/
322
- 'NabiTablet' => 'Android.*\bNabi',
323
- 'KoboTablet' => 'Kobo Touch|\bK080\b|\bVox\b Build|\bArc\b Build',
324
- // French Danew Tablets http://www.danew.com/produits-tablette.php
325
- 'DanewTablet' => 'DSlide.*\b(700|701R|702|703R|704|802|970|971|972|973|974|1010|1012)\b',
326
- // Texet Tablets and Readers http://www.texet.ru/tablet/
327
- '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',
328
- // Avoid detecting 'PLAYSTATION 3' as mobile.
329
- 'PlaystationTablet' => 'Playstation.*(Portable|Vita)',
330
- // http://www.trekstor.de/surftabs.html
331
- 'TrekstorTablet' => 'ST10416-1|VT10416-1|ST70408-1|ST702xx-1|ST702xx-2|ST80208|ST97216|ST70104-2|VT10416-2|ST10216-2A|SurfTab',
332
- // http://www.pyleaudio.com/Products.aspx?%2fproducts%2fPersonal-Electronics%2fTablets
333
- 'PyleAudioTablet' => '\b(PTBL10CEU|PTBL10C|PTBL72BC|PTBL72BCEU|PTBL7CEU|PTBL7C|PTBL92BC|PTBL92BCEU|PTBL9CEU|PTBL9CUK|PTBL9C)\b',
334
- // http://www.advandigital.com/index.php?link=content-product&jns=JP001
335
- // because of the short codenames we have to include whitespaces to reduce the possible conflicts.
336
- '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 ',
337
- // http://www.danytech.com/category/tablet-pc
338
- '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',
339
- // http://www.galapad.net/product.html
340
- 'GalapadTablet' => 'Android.*\bG1\b',
341
- // http://www.micromaxinfo.com/tablet/funbook
342
- 'MicromaxTablet' => 'Funbook|Micromax.*\b(P250|P560|P360|P362|P600|P300|P350|P500|P275)\b',
343
- // http://www.karbonnmobiles.com/products_tablet.php
344
- 'KarbonnTablet' => 'Android.*\b(A39|A37|A34|ST8|ST10|ST7|Smart Tab3|Smart Tab2)\b',
345
- // http://www.myallfine.com/Products.asp
346
- 'AllFineTablet' => 'Fine7 Genius|Fine7 Shine|Fine7 Air|Fine8 Style|Fine9 More|Fine10 Joy|Fine11 Wide',
347
- // http://www.proscanvideo.com/products-search.asp?itemClass=TABLET&itemnmbr=
348
- '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',
349
- // http://www.yonesnav.com/products/products.php
350
- 'YONESTablet' => 'BQ1078|BC1003|BC1077|RK9702|BC9730|BC9001|IT9001|BC7008|BC7010|BC708|BC728|BC7012|BC7030|BC7027|BC7026',
351
- // http://www.cjshowroom.com/eproducts.aspx?classcode=004001001
352
- // China manufacturer makes tablets for different small brands (eg. http://www.zeepad.net/index.html)
353
- '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',
354
- // http://www.gloryunion.cn/products.asp
355
- // http://www.allwinnertech.com/en/apply/mobile.html
356
- // http://www.ptcl.com.pk/pd_content.php?pd_id=284 (EVOTAB)
357
- // @todo: Softwiner tablets?
358
- // aka. Cute or Cool tablets. Not sure yet, must research to avoid collisions.
359
- '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
360
- // http://www.pointofview-online.com/showroom.php?shop_mode=product_listing&category_id=118
361
- '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',
362
- // http://www.overmax.pl/pl/katalog-produktow,p8/tablety,c14/
363
- // @todo: add more tests.
364
- 'OvermaxTablet' => 'OV-(SteelCore|NewBase|Basecore|Baseone|Exellen|Quattor|EduTab|Solution|ACTION|BasicTab|TeddyTab|MagicTab|Stream|TB-08|TB-09)',
365
- // http://hclmetablet.com/India/index.php
366
- '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',
367
- // http://www.edigital.hu/Tablet_es_e-book_olvaso/Tablet-c18385.html
368
- 'DPSTablet' => 'DPS Dream 9|DPS Dual 7',
369
- // http://www.visture.com/index.asp
370
- 'VistureTablet' => 'V97 HD|i75 3G|Visture V4( HD)?|Visture V5( HD)?|Visture V10',
371
- // http://www.mijncresta.nl/tablet
372
- 'CrestaTablet' => 'CTP(-)?810|CTP(-)?818|CTP(-)?828|CTP(-)?838|CTP(-)?888|CTP(-)?978|CTP(-)?980|CTP(-)?987|CTP(-)?988|CTP(-)?989',
373
- // MediaTek - http://www.mediatek.com/_en/01_products/02_proSys.php?cata_sn=1&cata1_sn=1&cata2_sn=309
374
- 'MediatekTablet' => '\bMT8125|MT8389|MT8135|MT8377\b',
375
- // Concorde tab
376
- 'ConcordeTablet' => 'Concorde([ ]+)?Tab|ConCorde ReadMan',
377
- // GoClever Tablets - http://www.goclever.com/uk/products,c1/tablet,c5/
378
- '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',
379
- // Modecom Tablets - http://www.modecom.eu/tablets/portal/
380
- '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',
381
- // Vonino Tablets - http://www.vonino.eu/tablets
382
- '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',
383
- // ECS Tablets - http://www.ecs.com.tw/ECSWebSite/Product/Product_Tablet_List.aspx?CategoryID=14&MenuID=107&childid=M_107&LanID=0
384
- 'ECSTablet' => 'V07OT2|TM105A|S10OT1|TR10CS1',
385
- // Storex Tablets - http://storex.fr/espace_client/support.html
386
- // @note: no need to add all the tablet codes since they are guided by the first regex.
387
- 'StorexTablet' => 'eZee[_\']?(Tab|Go)[0-9]+|TabLC7|Looney Tunes Tab',
388
- // Generic Vodafone tablets.
389
- 'VodafoneTablet' => 'SmartTab([ ]+)?[0-9]+|SmartTabII10|SmartTabII7',
390
- // French tablets - Essentiel B http://www.boulanger.fr/tablette_tactile_e-book/tablette_tactile_essentiel_b/cl_68908.htm?multiChoiceToDelete=brand&mc_brand=essentielb
391
- // Aka: http://www.essentielb.fr/
392
- 'EssentielBTablet' => 'Smart[ \']?TAB[ ]+?[0-9]+|Family[ \']?TAB2',
393
- // Ross & Moor - http://ross-moor.ru/
394
- 'RossMoorTablet' => 'RM-790|RM-997|RMD-878G|RMD-974R|RMT-705A|RMT-701|RME-601|RMT-501|RMT-711',
395
- // i-mobile http://product.i-mobilephone.com/Mobile_Device
396
- 'iMobileTablet' => 'i-mobile i-note',
397
- // http://www.tolino.de/de/vergleichen/
398
- 'TolinoTablet' => 'tolino tab [0-9.]+|tolino shine',
399
- // AudioSonic - a Kmart brand
400
- // 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
401
- 'AudioSonicTablet' => '\bC-22Q|T7-QC|T-17B|T-17P\b',
402
- // AMPE Tablets - http://www.ampe.com.my/product-category/tablets/
403
- // @todo: add them gradually to avoid conflicts.
404
- 'AMPETablet' => 'Android.* A78 ',
405
- // Skk Mobile - http://skkmobile.com.ph/product_tablets.php
406
- 'SkkTablet' => 'Android.* (SKYPAD|PHOENIX|CYCLOPS)',
407
- // Tecno Mobile (only tablet) - http://www.tecno-mobile.com/index.php/product?filterby=smart&list_order=all&page=1
408
- 'TecnoTablet' => 'TECNO P9',
409
- // JXD (consoles & tablets) - http://jxd.hk/products.asp?selectclassid=009008&clsid=3
410
- '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',
411
- // i-Joy tablets - http://www.i-joy.es/en/cat/products/tablets/
412
- '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)',
413
- // http://www.intracon.eu/tablet
414
- 'FX2Tablet' => 'FX2 PAD7|FX2 PAD10',
415
- // http://www.xoro.de/produkte/
416
- // @note: Might be the same brand with 'Simply tablets'
417
- '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',
418
- // http://www1.viewsonic.com/products/computing/tablets/
419
- 'ViewsonicTablet' => 'ViewPad 10pi|ViewPad 10e|ViewPad 10s|ViewPad E72|ViewPad7|ViewPad E100|ViewPad 7e|ViewSonic VB733|VB100a',
420
- // http://www.odys.de/web/internet-tablet_en.html
421
- 'OdysTablet' => 'LOOX|XENO10|ODYS[ -](Space|EVO|Xpress|NOON)|\bXELIO\b|Xelio10Pro|XELIO7PHONETAB|XELIO10EXTREME|XELIOPT2|NEO_QUAD10',
422
- // http://www.captiva-power.de/products.html#tablets-en
423
- 'CaptivaTablet' => 'CAPTIVA PAD',
424
- // IconBIT - http://www.iconbit.com/products/tablets/
425
- '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',
426
- // http://www.teclast.com/topic.php?channelID=70&topicID=140&pid=63
427
- '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',
428
- // Onda - http://www.onda-tablet.com/buy-android-onda.html?dir=desc&limit=all&order=price
429
- '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]+',
430
- 'JaytechTablet' => 'TPC-PA762',
431
- 'BlaupunktTablet' => 'Endeavour 800NG|Endeavour 1010',
432
- // http://www.digma.ru/support/download/
433
- // @todo: Ebooks also (if requested)
434
- 'DigmaTablet' => '\b(iDx10|iDx9|iDx8|iDx7|iDxD7|iDxD8|iDsQ8|iDsQ7|iDsQ8|iDsD10|iDnD7|3TS804H|iDsQ11|iDj7|iDs10)\b',
435
- // http://www.evolioshop.com/ro/tablete-pc.html
436
- // http://www.evolio.ro/support/downloads_static.html?cat=2
437
- // @todo: Research some more
438
- 'EvolioTablet' => 'ARIA_Mini_wifi|Aria[ _]Mini|Evolio X10|Evolio X7|Evolio X8|\bEvotab\b|\bNeura\b',
439
- // @todo http://www.lavamobiles.com/tablets-data-cards
440
- 'LavaTablet' => 'QPAD E704|\bIvoryS\b|E-TAB IVORY|\bE-TAB\b',
441
- // http://www.breezetablet.com/
442
- 'AocTablet' => 'MW0811|MW0812|MW0922|MTK8382|MW1031|MW0831|MW0821|MW0931|MW0712',
443
- // http://www.mpmaneurope.com/en/products/internet-tablets-14/android-tablets-14/
444
- 'MpmanTablet' => 'MP11 OCTA|MP10 OCTA|MPQC1114|MPQC1004|MPQC994|MPQC974|MPQC973|MPQC804|MPQC784|MPQC780|\bMPG7\b|MPDCG75|MPDCG71|MPDC1006|MP101DC|MPDC9000|MPDC905|MPDC706HD|MPDC706|MPDC705|MPDC110|MPDC100|MPDC99|MPDC97|MPDC88|MPDC8|MPDC77|MP709|MID701|MID711|MID170|MPDC703|MPQC1010',
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.kocaso.com/product_tablet.html
463
- 'KocasoTablet' => '\b(TB-1207)\b',
464
- // http://www.tesco.com/direct/hudl/
465
- 'Hudl' => 'Hudl HT7S3|Hudl 2',
466
- // http://www.telstra.com.au/home-phone/thub-2/
467
- 'TelstraTablet' => 'T-Hub2',
468
- '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'
469
- );
470
-
471
- /**
472
- * List of mobile Operating Systems.
473
- *
474
- * @var array
475
- */
476
- protected static $operatingSystems = array(
477
- 'AndroidOS' => 'Android',
478
- 'BlackBerryOS' => 'blackberry|\bBB10\b|rim tablet os',
479
- 'PalmOS' => 'PalmOS|avantgo|blazer|elaine|hiptop|palm|plucker|xiino',
480
- 'SymbianOS' => 'Symbian|SymbOS|Series60|Series40|SYB-[0-9]+|\bS60\b',
481
- // @reference: http://en.wikipedia.org/wiki/Windows_Mobile
482
- 'WindowsMobileOS' => 'Windows CE.*(PPC|Smartphone|Mobile|[0-9]{3}x[0-9]{3})|Window Mobile|Windows Phone [0-9.]+|WCE;',
483
- // @reference: http://en.wikipedia.org/wiki/Windows_Phone
484
- // http://wifeng.cn/?r=blog&a=view&id=106
485
- // http://nicksnettravels.builttoroam.com/post/2011/01/10/Bogus-Windows-Phone-7-User-Agent-String.aspx
486
- // http://msdn.microsoft.com/library/ms537503.aspx
487
- // https://msdn.microsoft.com/en-us/library/hh869301(v=vs.85).aspx
488
- 'WindowsPhoneOS' => 'Windows Phone 10.0|Windows Phone 8.1|Windows Phone 8.0|Windows Phone OS|XBLWP7|ZuneWP7|Windows NT 6.[23]; ARM;',
489
- 'iOS' => '\biPhone.*Mobile|\biPod|\biPad',
490
- // http://en.wikipedia.org/wiki/MeeGo
491
- // @todo: research MeeGo in UAs
492
- 'MeeGoOS' => 'MeeGo',
493
- // http://en.wikipedia.org/wiki/Maemo
494
- // @todo: research Maemo in UAs
495
- 'MaemoOS' => 'Maemo',
496
- 'JavaOS' => 'J2ME/|\bMIDP\b|\bCLDC\b', // '|Java/' produces bug #135
497
- 'webOS' => 'webOS|hpwOS',
498
- 'badaOS' => '\bBada\b',
499
- 'BREWOS' => 'BREW',
500
- );
501
-
502
- /**
503
- * List of mobile User Agents.
504
- *
505
- * @var array
506
- */
507
- protected static $browsers = array(
508
- // @reference: https://developers.google.com/chrome/mobile/docs/user-agent
509
- 'Chrome' => '\bCrMo\b|CriOS|Android.*Chrome/[.0-9]* (Mobile)?',
510
- 'Dolfin' => '\bDolfin\b',
511
- 'Opera' => 'Opera.*Mini|Opera.*Mobi|Android.*Opera|Mobile.*OPR/[0-9.]+|Coast/[0-9.]+',
512
- 'Skyfire' => 'Skyfire',
513
- 'IE' => 'IEMobile|MSIEMobile', // |Trident/[.0-9]+
514
- 'Firefox' => 'fennec|firefox.*maemo|(Mobile|Tablet).*Firefox|Firefox.*Mobile',
515
- 'Bolt' => 'bolt',
516
- 'TeaShark' => 'teashark',
517
- 'Blazer' => 'Blazer',
518
- // @reference: http://developer.apple.com/library/safari/#documentation/AppleApplications/Reference/SafariWebContent/OptimizingforSafarioniPhone/OptimizingforSafarioniPhone.html#//apple_ref/doc/uid/TP40006517-SW3
519
- 'Safari' => 'Version.*Mobile.*Safari|Safari.*Mobile|MobileSafari',
520
- // http://en.wikipedia.org/wiki/Midori_(web_browser)
521
- //'Midori' => 'midori',
522
- 'Tizen' => 'Tizen',
523
- 'UCBrowser' => 'UC.*Browser|UCWEB',
524
- 'baiduboxapp' => 'baiduboxapp',
525
- 'baidubrowser' => 'baidubrowser',
526
- // https://github.com/serbanghita/Mobile-Detect/issues/7
527
- 'DiigoBrowser' => 'DiigoBrowser',
528
- // http://www.puffinbrowser.com/index.php
529
- 'Puffin' => 'Puffin',
530
- // http://mercury-browser.com/index.html
531
- 'Mercury' => '\bMercury\b',
532
- // http://en.wikipedia.org/wiki/Obigo_Browser
533
- 'ObigoBrowser' => 'Obigo',
534
- // http://en.wikipedia.org/wiki/NetFront
535
- 'NetFront' => 'NF-Browser',
536
- // @reference: http://en.wikipedia.org/wiki/Minimo
537
- // http://en.wikipedia.org/wiki/Vision_Mobile_Browser
538
- 'GenericBrowser' => 'NokiaBrowser|OviBrowser|OneBrowser|TwonkyBeamBrowser|SEMC.*Browser|FlyFlow|Minimo|NetFront|Novarra-Vision|MQQBrowser|MicroMessenger',
539
- // @reference: https://en.wikipedia.org/wiki/Pale_Moon_(web_browser)
540
- 'PaleMoon' => 'Android.*PaleMoon|Mobile.*PaleMoon',
541
- );
542
-
543
- /**
544
- * Utilities.
545
- *
546
- * @var array
547
- */
548
- protected static $utilities = array(
549
- // Experimental. When a mobile device wants to switch to 'Desktop Mode'.
550
- // http://scottcate.com/technology/windows-phone-8-ie10-desktop-or-mobile/
551
- // https://github.com/serbanghita/Mobile-Detect/issues/57#issuecomment-15024011
552
- // https://developers.facebook.com/docs/sharing/best-practices
553
- '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',
554
- 'MobileBot' => 'Googlebot-Mobile|AdsBot-Google-Mobile|YahooSeeker/M1A1-R2D2',
555
- 'DesktopMode' => 'WPDesktop',
556
- 'TV' => 'SonyDTV|HbbTV', // experimental
557
- 'WebKit' => '(webkit)[ /]([\w.]+)',
558
- // @todo: Include JXD consoles.
559
- 'Console' => '\b(Nintendo|Nintendo WiiU|Nintendo 3DS|PLAYSTATION|Xbox)\b',
560
- 'Watch' => 'SM-V700',
561
- );
562
-
563
- /**
564
- * All possible HTTP headers that represent the
565
- * User-Agent string.
566
- *
567
- * @var array
568
- */
569
- protected static $uaHttpHeaders = array(
570
- // The default User-Agent string.
571
- 'HTTP_USER_AGENT',
572
- // Header can occur on devices using Opera Mini.
573
- 'HTTP_X_OPERAMINI_PHONE_UA',
574
- // Vodafone specific header: http://www.seoprinciple.com/mobile-web-community-still-angry-at-vodafone/24/
575
- 'HTTP_X_DEVICE_USER_AGENT',
576
- 'HTTP_X_ORIGINAL_USER_AGENT',
577
- 'HTTP_X_SKYFIRE_PHONE',
578
- 'HTTP_X_BOLT_PHONE_UA',
579
- 'HTTP_DEVICE_STOCK_UA',
580
- 'HTTP_X_UCBROWSER_DEVICE_UA'
581
- );
582
-
583
- /**
584
- * The individual segments that could exist in a User-Agent string. VER refers to the regular
585
- * expression defined in the constant self::VER.
586
- *
587
- * @var array
588
- */
589
- protected static $properties = array(
590
-
591
- // Build
592
- 'Mobile' => 'Mobile/[VER]',
593
- 'Build' => 'Build/[VER]',
594
- 'Version' => 'Version/[VER]',
595
- 'VendorID' => 'VendorID/[VER]',
596
-
597
- // Devices
598
- 'iPad' => 'iPad.*CPU[a-z ]+[VER]',
599
- 'iPhone' => 'iPhone.*CPU[a-z ]+[VER]',
600
- 'iPod' => 'iPod.*CPU[a-z ]+[VER]',
601
- //'BlackBerry' => array('BlackBerry[VER]', 'BlackBerry [VER];'),
602
- 'Kindle' => 'Kindle/[VER]',
603
-
604
- // Browser
605
- 'Chrome' => array('Chrome/[VER]', 'CriOS/[VER]', 'CrMo/[VER]'),
606
- 'Coast' => array('Coast/[VER]'),
607
- 'Dolfin' => 'Dolfin/[VER]',
608
- // @reference: https://developer.mozilla.org/en-US/docs/User_Agent_Strings_Reference
609
- 'Firefox' => 'Firefox/[VER]',
610
- 'Fennec' => 'Fennec/[VER]',
611
- // http://msdn.microsoft.com/en-us/library/ms537503(v=vs.85).aspx
612
- // https://msdn.microsoft.com/en-us/library/ie/hh869301(v=vs.85).aspx
613
- 'IE' => array('IEMobile/[VER];', 'IEMobile [VER]', 'MSIE [VER];', 'Trident/[0-9.]+;.*rv:[VER]'),
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
- 'PaleMoon' => 'PaleMoon/[VER]',
633
-
634
- // Engine
635
- 'Gecko' => 'Gecko/[VER]',
636
- 'Trident' => 'Trident/[VER]',
637
- 'Presto' => 'Presto/[VER]',
638
- 'Goanna' => 'Goanna/[VER]',
639
-
640
- // OS
641
- 'iOS' => ' \bi?OS\b [VER][ ;]{1}',
642
- 'Android' => 'Android [VER]',
643
- 'BlackBerry' => array('BlackBerry[\w]+/[VER]', 'BlackBerry.*Version/[VER]', 'Version/[VER]'),
644
- 'BREW' => 'BREW [VER]',
645
- 'Java' => 'Java/[VER]',
646
- // @reference: http://windowsteamblog.com/windows_phone/b/wpdev/archive/2011/08/29/introducing-the-ie9-on-windows-phone-mango-user-agent-string.aspx
647
- // @reference: http://en.wikipedia.org/wiki/Windows_NT#Releases
648
- 'Windows Phone OS' => array( 'Windows Phone OS [VER]', 'Windows Phone [VER]'),
649
- 'Windows Phone' => 'Windows Phone [VER]',
650
- 'Windows CE' => 'Windows CE/[VER]',
651
- // http://social.msdn.microsoft.com/Forums/en-US/windowsdeveloperpreviewgeneral/thread/6be392da-4d2f-41b4-8354-8dcee20c85cd
652
- 'Windows NT' => 'Windows NT [VER]',
653
- 'Symbian' => array('SymbianOS/[VER]', 'Symbian/[VER]'),
654
- 'webOS' => array('webOS/[VER]', 'hpwOS/[VER];'),
655
- );
656
-
657
- /**
658
- * Construct an instance of this class.
659
- *
660
- * @param array $headers Specify the headers as injection. Should be PHP _SERVER flavored.
661
- * If left empty, will use the global _SERVER['HTTP_*'] vars instead.
662
- * @param string $userAgent Inject the User-Agent header. If null, will use HTTP_USER_AGENT
663
- * from the $headers array instead.
664
- */
665
- public function __construct(
666
- array $headers = null,
667
- $userAgent = null
668
- ) {
669
- $this->setHttpHeaders($headers);
670
- $this->setUserAgent($userAgent);
671
- }
672
-
673
- /**
674
- * Get the current script version.
675
- * This is useful for the demo.php file,
676
- * so people can check on what version they are testing
677
- * for mobile devices.
678
- *
679
- * @return string The version number in semantic version format.
680
- */
681
- public static function getScriptVersion()
682
- {
683
- return self::VERSION;
684
- }
685
-
686
- /**
687
- * Set the HTTP Headers. Must be PHP-flavored. This method will reset existing headers.
688
- *
689
- * @param array $httpHeaders The headers to set. If null, then using PHP's _SERVER to extract
690
- * the headers. The default null is left for backwards compatibility.
691
- */
692
- public function setHttpHeaders($httpHeaders = null)
693
- {
694
- // use global _SERVER if $httpHeaders aren't defined
695
- if (!is_array($httpHeaders) || !count($httpHeaders)) {
696
- $httpHeaders = $_SERVER;
697
- }
698
-
699
- // clear existing headers
700
- $this->httpHeaders = array();
701
-
702
- // Only save HTTP headers. In PHP land, that means only _SERVER vars that
703
- // start with HTTP_.
704
- foreach ($httpHeaders as $key => $value) {
705
- if (substr($key, 0, 5) === 'HTTP_') {
706
- $this->httpHeaders[$key] = $value;
707
- }
708
- }
709
-
710
- // In case we're dealing with CloudFront, we need to know.
711
- $this->setCfHeaders($httpHeaders);
712
- }
713
-
714
- /**
715
- * Retrieves the HTTP headers.
716
- *
717
- * @return array
718
- */
719
- public function getHttpHeaders()
720
- {
721
- return $this->httpHeaders;
722
- }
723
-
724
- /**
725
- * Retrieves a particular header. If it doesn't exist, no exception/error is caused.
726
- * Simply null is returned.
727
- *
728
- * @param string $header The name of the header to retrieve. Can be HTTP compliant such as
729
- * "User-Agent" or "X-Device-User-Agent" or can be php-esque with the
730
- * all-caps, HTTP_ prefixed, underscore seperated awesomeness.
731
- *
732
- * @return string|null The value of the header.
733
- */
734
- public function getHttpHeader($header)
735
- {
736
- // are we using PHP-flavored headers?
737
- if (strpos($header, '_') === false) {
738
- $header = str_replace('-', '_', $header);
739
- $header = strtoupper($header);
740
- }
741
-
742
- // test the alternate, too
743
- $altHeader = 'HTTP_' . $header;
744
-
745
- //Test both the regular and the HTTP_ prefix
746
- if (isset($this->httpHeaders[$header])) {
747
- return $this->httpHeaders[$header];
748
- } elseif (isset($this->httpHeaders[$altHeader])) {
749
- return $this->httpHeaders[$altHeader];
750
- }
751
-
752
- return null;
753
- }
754
-
755
- public function getMobileHeaders()
756
- {
757
- return self::$mobileHeaders;
758
- }
759
-
760
- /**
761
- * Get all possible HTTP headers that
762
- * can contain the User-Agent string.
763
- *
764
- * @return array List of HTTP headers.
765
- */
766
- public function getUaHttpHeaders()
767
- {
768
- return self::$uaHttpHeaders;
769
- }
770
-
771
-
772
- /**
773
- * Set CloudFront headers
774
- * http://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/header-caching.html#header-caching-web-device
775
- *
776
- * @param array $cfHeaders List of HTTP headers
777
- *
778
- * @return boolean If there were CloudFront headers to be set
779
- */
780
- public function setCfHeaders($cfHeaders = null) {
781
- // use global _SERVER if $cfHeaders aren't defined
782
- if (!is_array($cfHeaders) || !count($cfHeaders)) {
783
- $cfHeaders = $_SERVER;
784
- }
785
-
786
- // clear existing headers
787
- $this->cloudfrontHeaders = array();
788
-
789
- // Only save CLOUDFRONT headers. In PHP land, that means only _SERVER vars that
790
- // start with cloudfront-.
791
- $response = false;
792
- foreach ($cfHeaders as $key => $value) {
793
- if (substr(strtolower($key), 0, 16) === 'http_cloudfront_') {
794
- $this->cloudfrontHeaders[strtoupper($key)] = $value;
795
- $response = true;
796
- }
797
- }
798
-
799
- return $response;
800
- }
801
-
802
- /**
803
- * Retrieves the cloudfront headers.
804
- *
805
- * @return array
806
- */
807
- public function getCfHeaders()
808
- {
809
- return $this->cloudfrontHeaders;
810
- }
811
-
812
- /**
813
- * Set the User-Agent to be used.
814
- *
815
- * @param string $userAgent The user agent string to set.
816
- *
817
- * @return string|null
818
- */
819
- public function setUserAgent($userAgent = null)
820
- {
821
- // Invalidate cache due to #375
822
- $this->cache = array();
823
-
824
- if (false === empty($userAgent)) {
825
- return $this->userAgent = $userAgent;
826
- } else {
827
- $this->userAgent = null;
828
- foreach ($this->getUaHttpHeaders() as $altHeader) {
829
- if (false === empty($this->httpHeaders[$altHeader])) { // @todo: should use getHttpHeader(), but it would be slow. (Serban)
830
- $this->userAgent .= $this->httpHeaders[$altHeader] . " ";
831
- }
832
- }
833
-
834
- if (!empty($this->userAgent)) {
835
- return $this->userAgent = trim($this->userAgent);
836
- }
837
- }
838
-
839
- if (count($this->getCfHeaders()) > 0) {
840
- return $this->userAgent = 'Amazon CloudFront';
841
- }
842
- return $this->userAgent = null;
843
- }
844
-
845
- /**
846
- * Retrieve the User-Agent.
847
- *
848
- * @return string|null The user agent if it's set.
849
- */
850
- public function getUserAgent()
851
- {
852
- return $this->userAgent;
853
- }
854
-
855
- /**
856
- * Set the detection type. Must be one of self::DETECTION_TYPE_MOBILE or
857
- * self::DETECTION_TYPE_EXTENDED. Otherwise, nothing is set.
858
- *
859
- * @deprecated since version 2.6.9
860
- *
861
- * @param string $type The type. Must be a self::DETECTION_TYPE_* constant. The default
862
- * parameter is null which will default to self::DETECTION_TYPE_MOBILE.
863
- */
864
- public function setDetectionType($type = null)
865
- {
866
- if ($type === null) {
867
- $type = self::DETECTION_TYPE_MOBILE;
868
- }
869
-
870
- if ($type !== self::DETECTION_TYPE_MOBILE && $type !== self::DETECTION_TYPE_EXTENDED) {
871
- return;
872
- }
873
-
874
- $this->detectionType = $type;
875
- }
876
-
877
- public function getMatchingRegex()
878
- {
879
- return $this->matchingRegex;
880
- }
881
-
882
- public function getMatchesArray()
883
- {
884
- return $this->matchesArray;
885
- }
886
-
887
- /**
888
- * Retrieve the list of known phone devices.
889
- *
890
- * @return array List of phone devices.
891
- */
892
- public static function getPhoneDevices()
893
- {
894
- return self::$phoneDevices;
895
- }
896
-
897
- /**
898
- * Retrieve the list of known tablet devices.
899
- *
900
- * @return array List of tablet devices.
901
- */
902
- public static function getTabletDevices()
903
- {
904
- return self::$tabletDevices;
905
- }
906
-
907
- /**
908
- * Alias for getBrowsers() method.
909
- *
910
- * @return array List of user agents.
911
- */
912
- public static function getUserAgents()
913
- {
914
- return self::getBrowsers();
915
- }
916
-
917
- /**
918
- * Retrieve the list of known browsers. Specifically, the user agents.
919
- *
920
- * @return array List of browsers / user agents.
921
- */
922
- public static function getBrowsers()
923
- {
924
- return self::$browsers;
925
- }
926
-
927
- /**
928
- * Retrieve the list of known utilities.
929
- *
930
- * @return array List of utilities.
931
- */
932
- public static function getUtilities()
933
- {
934
- return self::$utilities;
935
- }
936
-
937
- /**
938
- * Method gets the mobile detection rules. This method is used for the magic methods $detect->is*().
939
- *
940
- * @deprecated since version 2.6.9
941
- *
942
- * @return array All the rules (but not extended).
943
- */
944
- public static function getMobileDetectionRules()
945
- {
946
- static $rules;
947
-
948
- if (!$rules) {
949
- $rules = array_merge(
950
- self::$phoneDevices,
951
- self::$tabletDevices,
952
- self::$operatingSystems,
953
- self::$browsers
954
- );
955
- }
956
-
957
- return $rules;
958
-
959
- }
960
-
961
- /**
962
- * Method gets the mobile detection rules + utilities.
963
- * The reason this is separate is because utilities rules
964
- * don't necessary imply mobile. This method is used inside
965
- * the new $detect->is('stuff') method.
966
- *
967
- * @deprecated since version 2.6.9
968
- *
969
- * @return array All the rules + extended.
970
- */
971
- public function getMobileDetectionRulesExtended()
972
- {
973
- static $rules;
974
-
975
- if (!$rules) {
976
- // Merge all rules together.
977
- $rules = array_merge(
978
- self::$phoneDevices,
979
- self::$tabletDevices,
980
- self::$operatingSystems,
981
- self::$browsers,
982
- self::$utilities
983
- );
984
- }
985
-
986
- return $rules;
987
- }
988
-
989
- /**
990
- * Retrieve the current set of rules.
991
- *
992
- * @deprecated since version 2.6.9
993
- *
994
- * @return array
995
- */
996
- public function getRules()
997
- {
998
- if ($this->detectionType == self::DETECTION_TYPE_EXTENDED) {
999
- return self::getMobileDetectionRulesExtended();
1000
- } else {
1001
- return self::getMobileDetectionRules();
1002
- }
1003
- }
1004
-
1005
- /**
1006
- * Retrieve the list of mobile operating systems.
1007
- *
1008
- * @return array The list of mobile operating systems.
1009
- */
1010
- public static function getOperatingSystems()
1011
- {
1012
- return self::$operatingSystems;
1013
- }
1014
-
1015
- /**
1016
- * Check the HTTP headers for signs of mobile.
1017
- * This is the fastest mobile check possible; it's used
1018
- * inside isMobile() method.
1019
- *
1020
- * @return bool
1021
- */
1022
- public function checkHttpHeadersForMobile()
1023
- {
1024
-
1025
- foreach ($this->getMobileHeaders() as $mobileHeader => $matchType) {
1026
- if (isset($this->httpHeaders[$mobileHeader])) {
1027
- if (is_array($matchType['matches'])) {
1028
- foreach ($matchType['matches'] as $_match) {
1029
- if (strpos($this->httpHeaders[$mobileHeader], $_match) !== false) {
1030
- return true;
1031
- }
1032
- }
1033
-
1034
- return false;
1035
- } else {
1036
- return true;
1037
- }
1038
- }
1039
- }
1040
-
1041
- return false;
1042
-
1043
- }
1044
-
1045
- /**
1046
- * Magic overloading method.
1047
- *
1048
- * @method boolean is[...]()
1049
- * @param string $name
1050
- * @param array $arguments
1051
- * @return mixed
1052
- * @throws BadMethodCallException when the method doesn't exist and doesn't start with 'is'
1053
- */
1054
- public function __call($name, $arguments)
1055
- {
1056
- // make sure the name starts with 'is', otherwise
1057
- if (substr($name, 0, 2) !== 'is') {
1058
- throw new BadMethodCallException("No such method exists: $name");
1059
- }
1060
-
1061
- $this->setDetectionType(self::DETECTION_TYPE_MOBILE);
1062
-
1063
- $key = substr($name, 2);
1064
-
1065
- return $this->matchUAAgainstKey($key);
1066
- }
1067
-
1068
- /**
1069
- * Find a detection rule that matches the current User-agent.
1070
- *
1071
- * @param null $userAgent deprecated
1072
- * @return boolean
1073
- */
1074
- protected function matchDetectionRulesAgainstUA($userAgent = null)
1075
- {
1076
- // Begin general search.
1077
- foreach ($this->getRules() as $_regex) {
1078
- if (empty($_regex)) {
1079
- continue;
1080
- }
1081
-
1082
- if ($this->match($_regex, $userAgent)) {
1083
- return true;
1084
- }
1085
- }
1086
-
1087
- return false;
1088
- }
1089
-
1090
- /**
1091
- * Search for a certain key in the rules array.
1092
- * If the key is found then try to match the corresponding
1093
- * regex against the User-Agent.
1094
- *
1095
- * @param string $key
1096
- *
1097
- * @return boolean
1098
- */
1099
- protected function matchUAAgainstKey($key)
1100
- {
1101
- // Make the keys lowercase so we can match: isIphone(), isiPhone(), isiphone(), etc.
1102
- $key = strtolower($key);
1103
- if (false === isset($this->cache[$key])) {
1104
-
1105
- // change the keys to lower case
1106
- $_rules = array_change_key_case($this->getRules());
1107
-
1108
- if (false === empty($_rules[$key])) {
1109
- $this->cache[$key] = $this->match($_rules[$key]);
1110
- }
1111
-
1112
- if (false === isset($this->cache[$key])) {
1113
- $this->cache[$key] = false;
1114
- }
1115
- }
1116
-
1117
- return $this->cache[$key];
1118
- }
1119
-
1120
- /**
1121
- * Check if the device is mobile.
1122
- * Returns true if any type of mobile device detected, including special ones
1123
- * @param null $userAgent deprecated
1124
- * @param null $httpHeaders deprecated
1125
- * @return bool
1126
- */
1127
- public function isMobile($userAgent = null, $httpHeaders = null)
1128
- {
1129
-
1130
- if ($httpHeaders) {
1131
- $this->setHttpHeaders($httpHeaders);
1132
- }
1133
-
1134
- if ($userAgent) {
1135
- $this->setUserAgent($userAgent);
1136
- }
1137
-
1138
- // Check specifically for cloudfront headers if the useragent === 'Amazon CloudFront'
1139
- if ($this->getUserAgent() === 'Amazon CloudFront') {
1140
- $cfHeaders = $this->getCfHeaders();
1141
- if(array_key_exists('HTTP_CLOUDFRONT_IS_MOBILE_VIEWER', $cfHeaders) && $cfHeaders['HTTP_CLOUDFRONT_IS_MOBILE_VIEWER'] === 'true') {
1142
- return true;
1143
- }
1144
- }
1145
-
1146
- $this->setDetectionType(self::DETECTION_TYPE_MOBILE);
1147
-
1148
- if ($this->checkHttpHeadersForMobile()) {
1149
- return true;
1150
- } else {
1151
- return $this->matchDetectionRulesAgainstUA();
1152
- }
1153
-
1154
- }
1155
-
1156
- /**
1157
- * Check if the device is a tablet.
1158
- * Return true if any type of tablet device is detected.
1159
- *
1160
- * @param string $userAgent deprecated
1161
- * @param array $httpHeaders deprecated
1162
- * @return bool
1163
- */
1164
- public function isTablet($userAgent = null, $httpHeaders = null)
1165
- {
1166
- // Check specifically for cloudfront headers if the useragent === 'Amazon CloudFront'
1167
- if ($this->getUserAgent() === 'Amazon CloudFront') {
1168
- $cfHeaders = $this->getCfHeaders();
1169
- if(array_key_exists('HTTP_CLOUDFRONT_IS_TABLET_VIEWER', $cfHeaders) && $cfHeaders['HTTP_CLOUDFRONT_IS_TABLET_VIEWER'] === 'true') {
1170
- return true;
1171
- }
1172
- }
1173
-
1174
- $this->setDetectionType(self::DETECTION_TYPE_MOBILE);
1175
-
1176
- foreach (self::$tabletDevices as $_regex) {
1177
- if ($this->match($_regex, $userAgent)) {
1178
- return true;
1179
- }
1180
- }
1181
-
1182
- return false;
1183
- }
1184
-
1185
- /**
1186
- * This method checks for a certain property in the
1187
- * userAgent.
1188
- * @todo: The httpHeaders part is not yet used.
1189
- *
1190
- * @param string $key
1191
- * @param string $userAgent deprecated
1192
- * @param string $httpHeaders deprecated
1193
- * @return bool|int|null
1194
- */
1195
- public function is($key, $userAgent = null, $httpHeaders = null)
1196
- {
1197
- // Set the UA and HTTP headers only if needed (eg. batch mode).
1198
- if ($httpHeaders) {
1199
- $this->setHttpHeaders($httpHeaders);
1200
- }
1201
-
1202
- if ($userAgent) {
1203
- $this->setUserAgent($userAgent);
1204
- }
1205
-
1206
- $this->setDetectionType(self::DETECTION_TYPE_EXTENDED);
1207
-
1208
- return $this->matchUAAgainstKey($key);
1209
- }
1210
-
1211
- /**
1212
- * Some detection rules are relative (not standard),
1213
- * because of the diversity of devices, vendors and
1214
- * their conventions in representing the User-Agent or
1215
- * the HTTP headers.
1216
- *
1217
- * This method will be used to check custom regexes against
1218
- * the User-Agent string.
1219
- *
1220
- * @param $regex
1221
- * @param string $userAgent
1222
- * @return bool
1223
- *
1224
- * @todo: search in the HTTP headers too.
1225
- */
1226
- public function match($regex, $userAgent = null)
1227
- {
1228
- $match = (bool) preg_match(sprintf('#%s#is', $regex), (false === empty($userAgent) ? $userAgent : $this->userAgent), $matches);
1229
- // If positive match is found, store the results for debug.
1230
- if ($match) {
1231
- $this->matchingRegex = $regex;
1232
- $this->matchesArray = $matches;
1233
- }
1234
-
1235
- return $match;
1236
- }
1237
-
1238
- /**
1239
- * Get the properties array.
1240
- *
1241
- * @return array
1242
- */
1243
- public static function getProperties()
1244
- {
1245
- return self::$properties;
1246
- }
1247
-
1248
- /**
1249
- * Prepare the version number.
1250
- *
1251
- * @todo Remove the error supression from str_replace() call.
1252
- *
1253
- * @param string $ver The string version, like "2.6.21.2152";
1254
- *
1255
- * @return float
1256
- */
1257
- public function prepareVersionNo($ver)
1258
- {
1259
- $ver = str_replace(array('_', ' ', '/'), '.', $ver);
1260
- $arrVer = explode('.', $ver, 2);
1261
-
1262
- if (isset($arrVer[1])) {
1263
- $arrVer[1] = @str_replace('.', '', $arrVer[1]); // @todo: treat strings versions.
1264
- }
1265
-
1266
- return (float) implode('.', $arrVer);
1267
- }
1268
-
1269
- /**
1270
- * Check the version of the given property in the User-Agent.
1271
- * Will return a float number. (eg. 2_0 will return 2.0, 4.3.1 will return 4.31)
1272
- *
1273
- * @param string $propertyName The name of the property. See self::getProperties() array
1274
- * keys for all possible properties.
1275
- * @param string $type Either self::VERSION_TYPE_STRING to get a string value or
1276
- * self::VERSION_TYPE_FLOAT indicating a float value. This parameter
1277
- * is optional and defaults to self::VERSION_TYPE_STRING. Passing an
1278
- * invalid parameter will default to the this type as well.
1279
- *
1280
- * @return string|float The version of the property we are trying to extract.
1281
- */
1282
- public function version($propertyName, $type = self::VERSION_TYPE_STRING)
1283
- {
1284
- if (empty($propertyName)) {
1285
- return false;
1286
- }
1287
-
1288
- // set the $type to the default if we don't recognize the type
1289
- if ($type !== self::VERSION_TYPE_STRING && $type !== self::VERSION_TYPE_FLOAT) {
1290
- $type = self::VERSION_TYPE_STRING;
1291
- }
1292
-
1293
- $properties = self::getProperties();
1294
-
1295
- // Check if the property exists in the properties array.
1296
- if (true === isset($properties[$propertyName])) {
1297
-
1298
- // Prepare the pattern to be matched.
1299
- // Make sure we always deal with an array (string is converted).
1300
- $properties[$propertyName] = (array) $properties[$propertyName];
1301
-
1302
- foreach ($properties[$propertyName] as $propertyMatchString) {
1303
-
1304
- $propertyPattern = str_replace('[VER]', self::VER, $propertyMatchString);
1305
-
1306
- // Identify and extract the version.
1307
- preg_match(sprintf('#%s#is', $propertyPattern), $this->userAgent, $match);
1308
-
1309
- if (false === empty($match[1])) {
1310
- $version = ($type == self::VERSION_TYPE_FLOAT ? $this->prepareVersionNo($match[1]) : $match[1]);
1311
-
1312
- return $version;
1313
- }
1314
-
1315
- }
1316
-
1317
- }
1318
-
1319
- return false;
1320
- }
1321
-
1322
- /**
1323
- * Retrieve the mobile grading, using self::MOBILE_GRADE_* constants.
1324
- *
1325
- * @return string One of the self::MOBILE_GRADE_* constants.
1326
- */
1327
- public function mobileGrade()
1328
- {
1329
- $isMobile = $this->isMobile();
1330
-
1331
- if (
1332
- // 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)
1333
- $this->is('iOS') && $this->version('iPad', self::VERSION_TYPE_FLOAT) >= 4.3 ||
1334
- $this->is('iOS') && $this->version('iPhone', self::VERSION_TYPE_FLOAT) >= 4.3 ||
1335
- $this->is('iOS') && $this->version('iPod', self::VERSION_TYPE_FLOAT) >= 4.3 ||
1336
-
1337
- // 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)
1338
- // Android 3.1 (Honeycomb) - Tested on the Samsung Galaxy Tab 10.1 and Motorola XOOM
1339
- // Android 4.0 (ICS) - Tested on a Galaxy Nexus. Note: transition performance can be poor on upgraded devices
1340
- // Android 4.1 (Jelly Bean) - Tested on a Galaxy Nexus and Galaxy 7
1341
- ( $this->version('Android', self::VERSION_TYPE_FLOAT)>2.1 && $this->is('Webkit') ) ||
1342
-
1343
- // 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)
1344
- $this->version('Windows Phone OS', self::VERSION_TYPE_FLOAT) >= 7.5 ||
1345
-
1346
- // Tested on the Torch 9800 (6) and Style 9670 (6), BlackBerry® Torch 9810 (7), BlackBerry Z10 (10)
1347
- $this->is('BlackBerry') && $this->version('BlackBerry', self::VERSION_TYPE_FLOAT) >= 6.0 ||
1348
- // Blackberry Playbook (1.0-2.0) - Tested on PlayBook
1349
- $this->match('Playbook.*Tablet') ||
1350
-
1351
- // Palm WebOS (1.4-3.0) - Tested on the Palm Pixi (1.4), Pre (1.4), Pre 2 (2.0), HP TouchPad (3.0)
1352
- ( $this->version('webOS', self::VERSION_TYPE_FLOAT) >= 1.4 && $this->match('Palm|Pre|Pixi') ) ||
1353
- // Palm WebOS 3.0 - Tested on HP TouchPad
1354
- $this->match('hp.*TouchPad') ||
1355
-
1356
- // Firefox Mobile 18 - Tested on Android 2.3 and 4.1 devices
1357
- ( $this->is('Firefox') && $this->version('Firefox', self::VERSION_TYPE_FLOAT) >= 18 ) ||
1358
-
1359
- // Chrome for Android - Tested on Android 4.0, 4.1 device
1360
- ( $this->is('Chrome') && $this->is('AndroidOS') && $this->version('Android', self::VERSION_TYPE_FLOAT) >= 4.0 ) ||
1361
-
1362
- // Skyfire 4.1 - Tested on Android 2.3 device
1363
- ( $this->is('Skyfire') && $this->version('Skyfire', self::VERSION_TYPE_FLOAT) >= 4.1 && $this->is('AndroidOS') && $this->version('Android', self::VERSION_TYPE_FLOAT) >= 2.3 ) ||
1364
-
1365
- // Opera Mobile 11.5-12: Tested on Android 2.3
1366
- ( $this->is('Opera') && $this->version('Opera Mobi', self::VERSION_TYPE_FLOAT) >= 11.5 && $this->is('AndroidOS') ) ||
1367
-
1368
- // Meego 1.2 - Tested on Nokia 950 and N9
1369
- $this->is('MeeGoOS') ||
1370
-
1371
- // Tizen (pre-release) - Tested on early hardware
1372
- $this->is('Tizen') ||
1373
-
1374
- // Samsung Bada 2.0 - Tested on a Samsung Wave 3, Dolphin browser
1375
- // @todo: more tests here!
1376
- $this->is('Dolfin') && $this->version('Bada', self::VERSION_TYPE_FLOAT) >= 2.0 ||
1377
-
1378
- // UC Browser - Tested on Android 2.3 device
1379
- ( ($this->is('UC Browser') || $this->is('Dolfin')) && $this->version('Android', self::VERSION_TYPE_FLOAT) >= 2.3 ) ||
1380
-
1381
- // Kindle 3 and Fire - Tested on the built-in WebKit browser for each
1382
- ( $this->match('Kindle Fire') ||
1383
- $this->is('Kindle') && $this->version('Kindle', self::VERSION_TYPE_FLOAT) >= 3.0 ) ||
1384
-
1385
- // Nook Color 1.4.1 - Tested on original Nook Color, not Nook Tablet
1386
- $this->is('AndroidOS') && $this->is('NookTablet') ||
1387
-
1388
- // Chrome Desktop 16-24 - Tested on OS X 10.7 and Windows 7
1389
- $this->version('Chrome', self::VERSION_TYPE_FLOAT) >= 16 && !$isMobile ||
1390
-
1391
- // Safari Desktop 5-6 - Tested on OS X 10.7 and Windows 7
1392
- $this->version('Safari', self::VERSION_TYPE_FLOAT) >= 5.0 && !$isMobile ||
1393
-
1394
- // Firefox Desktop 10-18 - Tested on OS X 10.7 and Windows 7
1395
- $this->version('Firefox', self::VERSION_TYPE_FLOAT) >= 10.0 && !$isMobile ||
1396
-
1397
- // Internet Explorer 7-9 - Tested on Windows XP, Vista and 7
1398
- $this->version('IE', self::VERSION_TYPE_FLOAT) >= 7.0 && !$isMobile ||
1399
-
1400
- // Opera Desktop 10-12 - Tested on OS X 10.7 and Windows 7
1401
- $this->version('Opera', self::VERSION_TYPE_FLOAT) >= 10 && !$isMobile
1402
- ){
1403
- return self::MOBILE_GRADE_A;
1404
- }
1405
-
1406
- if (
1407
- $this->is('iOS') && $this->version('iPad', self::VERSION_TYPE_FLOAT)<4.3 ||
1408
- $this->is('iOS') && $this->version('iPhone', self::VERSION_TYPE_FLOAT)<4.3 ||
1409
- $this->is('iOS') && $this->version('iPod', self::VERSION_TYPE_FLOAT)<4.3 ||
1410
-
1411
- // Blackberry 5.0: Tested on the Storm 2 9550, Bold 9770
1412
- $this->is('Blackberry') && $this->version('BlackBerry', self::VERSION_TYPE_FLOAT) >= 5 && $this->version('BlackBerry', self::VERSION_TYPE_FLOAT)<6 ||
1413
-
1414
- //Opera Mini (5.0-6.5) - Tested on iOS 3.2/4.3 and Android 2.3
1415
- ($this->version('Opera Mini', self::VERSION_TYPE_FLOAT) >= 5.0 && $this->version('Opera Mini', self::VERSION_TYPE_FLOAT) <= 7.0 &&
1416
- ($this->version('Android', self::VERSION_TYPE_FLOAT) >= 2.3 || $this->is('iOS')) ) ||
1417
-
1418
- // Nokia Symbian^3 - Tested on Nokia N8 (Symbian^3), C7 (Symbian^3), also works on N97 (Symbian^1)
1419
- $this->match('NokiaN8|NokiaC7|N97.*Series60|Symbian/3') ||
1420
-
1421
- // @todo: report this (tested on Nokia N71)
1422
- $this->version('Opera Mobi', self::VERSION_TYPE_FLOAT) >= 11 && $this->is('SymbianOS')
1423
- ){
1424
- return self::MOBILE_GRADE_B;
1425
- }
1426
-
1427
- if (
1428
- // Blackberry 4.x - Tested on the Curve 8330
1429
- $this->version('BlackBerry', self::VERSION_TYPE_FLOAT) <= 5.0 ||
1430
- // Windows Mobile - Tested on the HTC Leo (WinMo 5.2)
1431
- $this->match('MSIEMobile|Windows CE.*Mobile') || $this->version('Windows Mobile', self::VERSION_TYPE_FLOAT) <= 5.2 ||
1432
-
1433
- // Tested on original iPhone (3.1), iPhone 3 (3.2)
1434
- $this->is('iOS') && $this->version('iPad', self::VERSION_TYPE_FLOAT) <= 3.2 ||
1435
- $this->is('iOS') && $this->version('iPhone', self::VERSION_TYPE_FLOAT) <= 3.2 ||
1436
- $this->is('iOS') && $this->version('iPod', self::VERSION_TYPE_FLOAT) <= 3.2 ||
1437
-
1438
- // Internet Explorer 7 and older - Tested on Windows XP
1439
- $this->version('IE', self::VERSION_TYPE_FLOAT) <= 7.0 && !$isMobile
1440
- ){
1441
- return self::MOBILE_GRADE_C;
1442
- }
1443
-
1444
- // All older smartphone platforms and featurephones - Any device that doesn't support media queries
1445
- // will receive the basic, C grade experience.
1446
- return self::MOBILE_GRADE_C;
1447
- }
1448
- }
1449
-
1450
- endif;
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
  * 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.3
24
  */
25
  if ( !class_exists( 'EDS_Mobile_Detect' ) ):
26
 
27
+ class EDS_Mobile_Detect
28
+ {
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.3';
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
+ * The User-Agent HTTP header is stored in here.
82
+ * @var string
83
+ */
84
+ protected $userAgent = null;
85
+
86
+ /**
87
+ * HTTP headers in the PHP-flavor. So HTTP_USER_AGENT and SERVER_SOFTWARE.
88
+ * @var array
89
+ */
90
+ protected $httpHeaders = array();
91
+
92
+ /**
93
+ * The detection type, using self::DETECTION_TYPE_MOBILE or self::DETECTION_TYPE_EXTENDED.
94
+ *
95
+ * @deprecated since version 2.6.9
96
+ *
97
+ * @var string
98
+ */
99
+ protected $detectionType = self::DETECTION_TYPE_MOBILE;
100
+
101
+ /**
102
+ * HTTP headers that trigger the 'isMobile' detection
103
+ * to be true.
104
+ *
105
+ * @var array
106
+ */
107
+ protected static $mobileHeaders = array(
108
+
109
+ 'HTTP_ACCEPT' => array('matches' => array(
110
+ // Opera Mini; @reference: http://dev.opera.com/articles/view/opera-binary-markup-language/
111
+ 'application/x-obml2d',
112
+ // BlackBerry devices.
113
+ 'application/vnd.rim.html',
114
+ 'text/vnd.wap.wml',
115
+ 'application/vnd.wap.xhtml+xml'
116
+ )),
117
+ 'HTTP_X_WAP_PROFILE' => null,
118
+ 'HTTP_X_WAP_CLIENTID' => null,
119
+ 'HTTP_WAP_CONNECTION' => null,
120
+ 'HTTP_PROFILE' => null,
121
+ // Reported by Opera on Nokia devices (eg. C3).
122
+ 'HTTP_X_OPERAMINI_PHONE_UA' => null,
123
+ 'HTTP_X_NOKIA_GATEWAY_ID' => null,
124
+ 'HTTP_X_ORANGE_ID' => null,
125
+ 'HTTP_X_VODAFONE_3GPDPCONTEXT' => null,
126
+ 'HTTP_X_HUAWEI_USERID' => null,
127
+ // Reported by Windows Smartphones.
128
+ 'HTTP_UA_OS' => null,
129
+ // Reported by Verizon, Vodafone proxy system.
130
+ 'HTTP_X_MOBILE_GATEWAY' => null,
131
+ // Seend this on HTC Sensation. @ref: SensationXE_Beats_Z715e.
132
+ 'HTTP_X_ATT_DEVICEID' => null,
133
+ // Seen this on a HTC.
134
+ 'HTTP_UA_CPU' => array('matches' => array('ARM')),
135
+ );
136
+
137
+ /**
138
+ * List of mobile devices (phones).
139
+ *
140
+ * @var array
141
+ */
142
+ protected static $phoneDevices = array(
143
+ 'iPhone' => '\biPhone.*(Mobile|PhoneGap)|\biPod', // |\biTunes
144
+ 'BlackBerry' => 'BlackBerry|\bBB10\b|rim[0-9]+',
145
+ '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',
146
+ 'Nexus' => 'Nexus One|Nexus S|Galaxy.*Nexus|Android.*Nexus.*Mobile',
147
+ // @todo: Is 'Dell Streak' a tablet or a phone? ;)
148
+ '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',
149
+ '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',
150
+ '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',
151
+ '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)',
152
+ 'Sony' => 'SonyST|SonyLT|SonyEricsson|SonyEricssonLT15iv|LT18i|E10i|LT28h|LT26w|SonyEricssonMT27i',
153
+ 'Asus' => 'Asus.*Galaxy|PadFone.*Mobile',
154
+ // @ref: http://www.micromaxinfo.com/mobiles/smartphones
155
+ // Added because the codes might conflict with Acer Tablets.
156
+ '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',
157
+ 'Palm' => 'PalmSource|Palm', // avantgo|blazer|elaine|hiptop|plucker|xiino ; @todo - complete the regex.
158
+ 'Vertu' => 'Vertu|Vertu.*Ltd|Vertu.*Ascent|Vertu.*Ayxta|Vertu.*Constellation(F|Quest)?|Vertu.*Monika|Vertu.*Signature', // Just for fun ;)
159
+ // @ref: http://www.pantech.co.kr/en/prod/prodList.do?gbrand=VEGA (PANTECH)
160
+ // Most of the VEGA devices are legacy. PANTECH seem to be newer devices based on Android.
161
+ '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',
162
+ // @ref: http://www.fly-phone.com/devices/smartphones/ ; Included only smartphones.
163
+ 'Fly' => 'IQ230|IQ444|IQ450|IQ440|IQ442|IQ441|IQ245|IQ256|IQ236|IQ255|IQ235|IQ245|IQ275|IQ240|IQ285|IQ280|IQ270|IQ260|IQ250',
164
+ 'iMobile' => 'i-mobile (IQ|i-STYLE|idea|ZAA|Hitz)',
165
+ // Added simvalley mobile just for fun. They have some interesting devices.
166
+ // @ref: http://www.simvalley.fr/telephonie---gps-_22_telephonie-mobile_telephones_.html
167
+ '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',
168
+ // @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
169
+ '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'
170
+ );
171
+
172
+ /**
173
+ * List of tablet devices.
174
+ *
175
+ * @var array
176
+ */
177
+ protected static $tabletDevices = array(
178
+ 'iPad' => 'iPad|iPad.*Mobile', // @todo: check for mobile friendly emails topic.
179
+ 'NexusTablet' => 'Android.*Nexus[\s]+(7|10)|^.*Android.*Nexus(?:(?!Mobile).)*$',
180
+ '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', // SCH-P709|SCH-P729|SM-T2558 - Samsung Mega - treat them like a regular phone.
181
+ // @reference: http://www.labnol.org/software/kindle-user-agent-string/20378/
182
+ 'Kindle' => 'Kindle|Silk.*Accelerated|Android.*\b(KFOT|KFTT|KFJWI|KFJWA|KFOTE|KFSOWI|KFTHWI|KFTHWA|KFAPWI|KFAPWA|WFJWAE)\b',
183
+ // Only the Surface tablets with Windows RT are considered mobile.
184
+ // @ref: http://msdn.microsoft.com/en-us/library/ie/hh920767(v=vs.85).aspx
185
+ 'SurfaceTablet' => 'Windows NT [0-9.]+; ARM;',
186
+ // @ref: http://shopping1.hp.com/is-bin/INTERSHOP.enfinity/WFS/WW-USSMBPublicStore-Site/en_US/-/USD/ViewStandardCatalog-Browse?CatalogCategoryID=JfIQ7EN5lqMAAAEyDcJUDwMT
187
+ 'HPTablet' => 'HP Slate 7|HP ElitePad 900|hp-tablet|EliteBook.*Touch|HP 8',
188
+ // @note: watch out for PadFone, see #132
189
+ '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|TX201LA',
190
+ 'BlackBerryTablet' => 'PlayBook|RIM Tablet',
191
+ 'HTCtablet' => 'HTC Flyer|HTC Jetstream|HTC-P715a|HTC EVO View 4G|PG41200',
192
+ 'MotorolaTablet' => 'xoom|sholest|MZ615|MZ605|MZ505|MZ601|MZ602|MZ603|MZ604|MZ606|MZ607|MZ608|MZ609|MZ615|MZ616|MZ617',
193
+ 'NookTablet' => 'Android.*Nook|NookColor|nook browser|BNRV200|BNRV200A|BNTV250|BNTV250A|BNTV400|BNTV600|LogicPD Zoom2',
194
+ // @ref: http://www.acer.ro/ac/ro/RO/content/drivers
195
+ // @ref: http://www.packardbell.co.uk/pb/en/GB/content/download (Packard Bell is part of Acer)
196
+ // @ref: http://us.acer.com/ac/en/US/content/group/tablets
197
+ // @note: Can conflict with Micromax and Motorola phones codes.
198
+ '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-830)\b|W3-810|\bA3-A10\b',
199
+ // @ref: http://eu.computers.toshiba-europe.com/innovation/family/Tablets/1098744/banner_id/tablet_footerlink/
200
+ // @ref: http://us.toshiba.com/tablets/tablet-finder
201
+ // @ref: http://www.toshiba.co.jp/regza/tablet/
202
+ 'ToshibaTablet' => 'Android.*(AT100|AT105|AT200|AT205|AT270|AT275|AT300|AT305|AT1S5|AT500|AT570|AT700|AT830)|TOSHIBA.*FOLIO',
203
+ // @ref: http://www.nttdocomo.co.jp/english/service/developer/smart_phone/technical_info/spec/index.html
204
+ // @ref: http://www.lg.com/us/tablets
205
+ 'LGTablet' => '\bL-06C|LG-V900|LG-V500|LG-V909|LG-V500|LG-V510|LG-VK810\b',
206
+ 'FujitsuTablet' => 'Android.*\b(F-01D|F-02F|F-05E|F-10D|M532|Q572)\b',
207
+ // Prestigio Tablets http://www.prestigio.com/support
208
+ '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',
209
+ // @ref: http://support.lenovo.com/en_GB/downloads/default.page?#
210
+ 'LenovoTablet' => 'IdeaTab|ThinkPad([ ]+)?Tablet|Lenovo.*(S2109|S2110|S5000|S6000|K3011|A3000|A1000|A2107|A2109|A1107|B6000|B8000|B8080-F)',
211
+ // @ref: http://www.yarvik.com/en/matrix/tablets/
212
+ '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',
213
+ 'MedionTablet' => 'Android.*\bOYO\b|LIFE.*(P9212|P9514|P9516|S9512)|LIFETAB',
214
+ 'ArnovaTablet' => 'AN10G2|AN7bG3|AN7fG3|AN8G3|AN8cG3|AN7G3|AN9G3|AN7dG3|AN7dG3ST|AN7dG3ChildPad|AN10bG3|AN10bG3DT',
215
+ // http://www.intenso.de/kategorie_en.php?kategorie=33
216
+ // @todo: http://www.nbhkdz.com/read/b8e64202f92a2df129126bff.html - investigate
217
+ 'IntensoTablet' => 'INM8002KP|INM1010FP|INM805ND|Intenso Tab',
218
+ // IRU.ru Tablets http://www.iru.ru/catalog/soho/planetable/
219
+ 'IRUTablet' => 'M702pro',
220
+ 'MegafonTablet' => 'MegaFon V9|\bZTE V9\b|Android.*\bMT7A\b',
221
+ // @ref: http://www.e-boda.ro/tablete-pc.html
222
+ 'EbodaTablet' => 'E-Boda (Supreme|Impresspeed|Izzycomm|Essential)',
223
+ // @ref: http://www.allview.ro/produse/droseries/lista-tablete-pc/
224
+ 'AllViewTablet' => 'Allview.*(Viva|Alldro|City|Speed|All TV|Frenzy|Quasar|Shine|TX1|AX1|AX2)',
225
+ // @reference: http://wiki.archosfans.com/index.php?title=Main_Page
226
+ 'ArchosTablet' => '\b(101G9|80G9|A101IT)\b|Qilive 97R|ARCHOS 101G10|Archos 101 Neon',
227
+ // @ref: http://www.ainol.com/plugin.php?identifier=ainol&module=product
228
+ 'AinolTablet' => 'NOVO7|NOVO8|NOVO10|Novo7Aurora|Novo7Basic|NOVO7PALADIN|novo9-Spark',
229
+ // @todo: inspect http://esupport.sony.com/US/p/select-system.pl?DIRECTOR=DRIVER
230
+ // @ref: Readers http://www.atsuhiro-me.net/ebook/sony-reader/sony-reader-web-browser
231
+ // @ref: http://www.sony.jp/support/tablet/
232
+ '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',
233
+ // @ref: db + http://www.cube-tablet.com/buy-products.html
234
+ 'CubeTablet' => 'Android.*(K8GT|U9GT|U10GT|U16GT|U17GT|U18GT|U19GT|U20GT|U23GT|U30GT)|CUBE U8GT',
235
+ // @ref: http://www.cobyusa.com/?p=pcat&pcat_id=3001
236
+ 'CobyTablet' => 'MID1042|MID1045|MID1125|MID1126|MID7012|MID7014|MID7015|MID7034|MID7035|MID7036|MID7042|MID7048|MID7127|MID8042|MID8048|MID8127|MID9042|MID9740|MID9742|MID7022|MID7010',
237
+ // @ref: http://www.match.net.cn/products.asp
238
+ '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',
239
+ // @ref: http://pdadb.net/index.php?m=pdalist&list=SMiT (NoName Chinese Tablets)
240
+ // @ref: http://www.imp3.net/14/show.php?itemid=20454
241
+ 'SMiTTablet' => 'Android.*(\bMID\b|MID-560|MTV-T1200|MTV-PND531|MTV-P1101|MTV-PND530)',
242
+ // @ref: http://www.rock-chips.com/index.php?do=prod&pid=2
243
+ 'RockChipTablet' => 'Android.*(RK2818|RK2808A|RK2918|RK3066)|RK2738|RK2808A',
244
+ // @ref: http://www.fly-phone.com/devices/tablets/ ; http://www.fly-phone.com/service/
245
+ 'FlyTablet' => 'IQ310|Fly Vision',
246
+ // @ref: http://www.bqreaders.com/gb/tablets-prices-sale.html
247
+ 'bqTablet' => 'bq.*(Elcano|Curie|Edison|Maxwell|Kepler|Pascal|Tesla|Hypatia|Platon|Newton|Livingstone|Cervantes|Avant)|Maxwell.*Lite|Maxwell.*Plus',
248
+ // @ref: http://www.huaweidevice.com/worldwide/productFamily.do?method=index&directoryId=5011&treeId=3290
249
+ // @ref: http://www.huaweidevice.com/worldwide/downloadCenter.do?method=index&directoryId=3372&treeId=0&tb=1&type=software (including legacy tablets)
250
+ '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',
251
+ // Nec or Medias Tab
252
+ 'NecTablet' => '\bN-06D|\bN-08D',
253
+ // Pantech Tablets: http://www.pantechusa.com/phones/
254
+ 'PantechTablet' => 'Pantech.*P4100',
255
+ // Broncho Tablets: http://www.broncho.cn/ (hard to find)
256
+ 'BronchoTablet' => 'Broncho.*(N701|N708|N802|a710)',
257
+ // @ref: http://versusuk.com/support.html
258
+ 'VersusTablet' => 'TOUCHPAD.*[78910]|\bTOUCHTAB\b',
259
+ // @ref: http://www.zync.in/index.php/our-products/tablet-phablets
260
+ 'ZyncTablet' => 'z1000|Z99 2G|z99|z930|z999|z990|z909|Z919|z900',
261
+ // @ref: http://www.positivoinformatica.com.br/www/pessoal/tablet-ypy/
262
+ 'PositivoTablet' => 'TB07STA|TB10STA|TB07FTA|TB10FTA',
263
+ // @ref: https://www.nabitablet.com/
264
+ 'NabiTablet' => 'Android.*\bNabi',
265
+ 'KoboTablet' => 'Kobo Touch|\bK080\b|\bVox\b Build|\bArc\b Build',
266
+ // French Danew Tablets http://www.danew.com/produits-tablette.php
267
+ 'DanewTablet' => 'DSlide.*\b(700|701R|702|703R|704|802|970|971|972|973|974|1010|1012)\b',
268
+ // Texet Tablets and Readers http://www.texet.ru/tablet/
269
+ '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',
270
+ // @note: Avoid detecting 'PLAYSTATION 3' as mobile.
271
+ 'PlaystationTablet' => 'Playstation.*(Portable|Vita)',
272
+ // @ref: http://www.trekstor.de/surftabs.html
273
+ 'TrekstorTablet' => 'ST10416-1|VT10416-1|ST70408-1|ST702xx-1|ST702xx-2|ST80208|ST97216|ST70104-2|VT10416-2|ST10216-2A',
274
+ // @ref: http://www.pyleaudio.com/Products.aspx?%2fproducts%2fPersonal-Electronics%2fTablets
275
+ 'PyleAudioTablet' => '\b(PTBL10CEU|PTBL10C|PTBL72BC|PTBL72BCEU|PTBL7CEU|PTBL7C|PTBL92BC|PTBL92BCEU|PTBL9CEU|PTBL9CUK|PTBL9C)\b',
276
+ // @ref: http://www.advandigital.com/index.php?link=content-product&jns=JP001
277
+ // @Note: because of the short codenames we have to include whitespaces to reduce the possible conflicts.
278
+ '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 ',
279
+ // @ref: http://www.danytech.com/category/tablet-pc
280
+ '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',
281
+ // @ref: http://www.galapad.net/product.html
282
+ 'GalapadTablet' => 'Android.*\bG1\b',
283
+ // @ref: http://www.micromaxinfo.com/tablet/funbook
284
+ 'MicromaxTablet' => 'Funbook|Micromax.*\b(P250|P560|P360|P362|P600|P300|P350|P500|P275)\b',
285
+ // http://www.karbonnmobiles.com/products_tablet.php
286
+ 'KarbonnTablet' => 'Android.*\b(A39|A37|A34|ST8|ST10|ST7|Smart Tab3|Smart Tab2)\b',
287
+ // @ref: http://www.myallfine.com/Products.asp
288
+ 'AllFineTablet' => 'Fine7 Genius|Fine7 Shine|Fine7 Air|Fine8 Style|Fine9 More|Fine10 Joy|Fine11 Wide',
289
+ // @ref: http://www.proscanvideo.com/products-search.asp?itemClass=TABLET&itemnmbr=
290
+ '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',
291
+ // @ref: http://www.yonesnav.com/products/products.php
292
+ 'YONESTablet' => 'BQ1078|BC1003|BC1077|RK9702|BC9730|BC9001|IT9001|BC7008|BC7010|BC708|BC728|BC7012|BC7030|BC7027|BC7026',
293
+ // @ref: http://www.cjshowroom.com/eproducts.aspx?classcode=004001001
294
+ // China manufacturer makes tablets for different small brands (eg. http://www.zeepad.net/index.html)
295
+ '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',
296
+ // @ref: http://www.gloryunion.cn/products.asp
297
+ // @ref: http://www.allwinnertech.com/en/apply/mobile.html
298
+ // @ref: http://www.ptcl.com.pk/pd_content.php?pd_id=284 (EVOTAB)
299
+ // @todo: Softwiner tablets?
300
+ // aka. Cute or Cool tablets. Not sure yet, must research to avoid collisions.
301
+ '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
302
+ // @ref: http://www.pointofview-online.com/showroom.php?shop_mode=product_listing&category_id=118
303
+ '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',
304
+ // @ref: http://www.overmax.pl/pl/katalog-produktow,p8/tablety,c14/
305
+ // @todo: add more tests.
306
+ 'OvermaxTablet' => 'OV-(SteelCore|NewBase|Basecore|Baseone|Exellen|Quattor|EduTab|Solution|ACTION|BasicTab|TeddyTab|MagicTab|Stream|TB-08|TB-09)',
307
+ // @ref: http://hclmetablet.com/India/index.php
308
+ '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',
309
+ // @ref: http://www.edigital.hu/Tablet_es_e-book_olvaso/Tablet-c18385.html
310
+ 'DPSTablet' => 'DPS Dream 9|DPS Dual 7',
311
+ // @ref: http://www.visture.com/index.asp
312
+ 'VistureTablet' => 'V97 HD|i75 3G|Visture V4( HD)?|Visture V5( HD)?|Visture V10',
313
+ // @ref: http://www.mijncresta.nl/tablet
314
+ 'CrestaTablet' => 'CTP(-)?810|CTP(-)?818|CTP(-)?828|CTP(-)?838|CTP(-)?888|CTP(-)?978|CTP(-)?980|CTP(-)?987|CTP(-)?988|CTP(-)?989',
315
+ // MediaTek - http://www.mediatek.com/_en/01_products/02_proSys.php?cata_sn=1&cata1_sn=1&cata2_sn=309
316
+ 'MediatekTablet' => '\bMT8125|MT8389|MT8135|MT8377\b',
317
+ // Concorde tab
318
+ 'ConcordeTablet' => 'Concorde([ ]+)?Tab|ConCorde ReadMan',
319
+ // GoClever Tablets - http://www.goclever.com/uk/products,c1/tablet,c5/
320
+ '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',
321
+ // Modecom Tablets - http://www.modecom.eu/tablets/portal/
322
+ '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',
323
+ // Vonino Tablets - http://www.vonino.eu/tablets
324
+ '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',
325
+ // ECS Tablets - http://www.ecs.com.tw/ECSWebSite/Product/Product_Tablet_List.aspx?CategoryID=14&MenuID=107&childid=M_107&LanID=0
326
+ 'ECSTablet' => 'V07OT2|TM105A|S10OT1|TR10CS1',
327
+ // Storex Tablets - http://storex.fr/espace_client/support.html
328
+ // @note: no need to add all the tablet codes since they are guided by the first regex.
329
+ 'StorexTablet' => 'eZee[_\']?(Tab|Go)[0-9]+|TabLC7|Looney Tunes Tab',
330
+ // Generic Vodafone tablets.
331
+ 'VodafoneTablet' => 'SmartTab([ ]+)?[0-9]+|SmartTabII10',
332
+ // French tablets - Essentiel B http://www.boulanger.fr/tablette_tactile_e-book/tablette_tactile_essentiel_b/cl_68908.htm?multiChoiceToDelete=brand&mc_brand=essentielb
333
+ // Aka: http://www.essentielb.fr/
334
+ 'EssentielBTablet' => 'Smart[ \']?TAB[ ]+?[0-9]+|Family[ \']?TAB2',
335
+ // Ross & Moor - http://ross-moor.ru/
336
+ 'RossMoorTablet' => 'RM-790|RM-997|RMD-878G|RMD-974R|RMT-705A|RMT-701|RME-601|RMT-501|RMT-711',
337
+ // i-mobile http://product.i-mobilephone.com/Mobile_Device
338
+ 'iMobileTablet' => 'i-mobile i-note',
339
+ // @ref: http://www.tolino.de/de/vergleichen/
340
+ 'TolinoTablet' => 'tolino tab [0-9.]+|tolino shine',
341
+ // AudioSonic - a Kmart brand
342
+ // 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
343
+ 'AudioSonicTablet' => '\bC-22Q|T7-QC|T-17B|T-17P\b',
344
+ // AMPE Tablets - http://www.ampe.com.my/product-category/tablets/
345
+ // @todo: add them gradually to avoid conflicts.
346
+ 'AMPETablet' => 'Android.* A78 ',
347
+ // Skk Mobile - http://skkmobile.com.ph/product_tablets.php
348
+ 'SkkTablet' => 'Android.* (SKYPAD|PHOENIX|CYCLOPS)',
349
+ // Tecno Mobile (only tablet) - http://www.tecno-mobile.com/index.php/product?filterby=smart&list_order=all&page=1
350
+ 'TecnoTablet' => 'TECNO P9',
351
+ // JXD (consoles & tablets) - http://jxd.hk/products.asp?selectclassid=009008&clsid=3
352
+ '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',
353
+ // i-Joy tablets - http://www.i-joy.es/en/cat/products/tablets/
354
+ '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)',
355
+ // http://www.intracon.eu/tablet
356
+ 'FX2Tablet' => 'FX2 PAD7|FX2 PAD10',
357
+ // http://www.xoro.de/produkte/
358
+ // @note: Might be the same brand with 'Simply tablets'
359
+ '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',
360
+ // http://www1.viewsonic.com/products/computing/tablets/
361
+ 'ViewsonicTablet' => 'ViewPad 10pi|ViewPad 10e|ViewPad 10s|ViewPad E72|ViewPad7|ViewPad E100|ViewPad 7e|ViewSonic VB733|VB100a',
362
+ // http://www.odys.de/web/internet-tablet_en.html
363
+ 'OdysTablet' => 'LOOX|XENO10|ODYS Space',
364
+ // http://www.captiva-power.de/products.html#tablets-en
365
+ 'CaptivaTablet' => 'CAPTIVA PAD',
366
+ // IconBIT - http://www.iconbit.com/products/tablets/
367
+ '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',
368
+ // @ref: http://www.tesco.com/direct/hudl/
369
+ 'Hudl' => 'Hudl HT7S3',
370
+ // @ref: http://www.telstra.com.au/home-phone/thub-2/
371
+ 'TelstraTablet' => 'T-Hub2',
372
+ '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',
373
+ );
374
+
375
+ /**
376
+ * List of mobile Operating Systems.
377
+ *
378
+ * @var array
379
+ */
380
+ protected static $operatingSystems = array(
381
+ 'AndroidOS' => 'Android',
382
+ 'BlackBerryOS' => 'blackberry|\bBB10\b|rim tablet os',
383
+ 'PalmOS' => 'PalmOS|avantgo|blazer|elaine|hiptop|palm|plucker|xiino',
384
+ 'SymbianOS' => 'Symbian|SymbOS|Series60|Series40|SYB-[0-9]+|\bS60\b',
385
+ // @reference: http://en.wikipedia.org/wiki/Windows_Mobile
386
+ 'WindowsMobileOS' => 'Windows CE.*(PPC|Smartphone|Mobile|[0-9]{3}x[0-9]{3})|Window Mobile|Windows Phone [0-9.]+|WCE;',
387
+ // @reference: http://en.wikipedia.org/wiki/Windows_Phone
388
+ // http://wifeng.cn/?r=blog&a=view&id=106
389
+ // http://nicksnettravels.builttoroam.com/post/2011/01/10/Bogus-Windows-Phone-7-User-Agent-String.aspx
390
+ 'WindowsPhoneOS' => 'Windows Phone 8.0|Windows Phone OS|XBLWP7|ZuneWP7',
391
+ 'iOS' => '\biPhone.*Mobile|\biPod|\biPad',
392
+ // http://en.wikipedia.org/wiki/MeeGo
393
+ // @todo: research MeeGo in UAs
394
+ 'MeeGoOS' => 'MeeGo',
395
+ // http://en.wikipedia.org/wiki/Maemo
396
+ // @todo: research Maemo in UAs
397
+ 'MaemoOS' => 'Maemo',
398
+ 'JavaOS' => 'J2ME/|\bMIDP\b|\bCLDC\b', // '|Java/' produces bug #135
399
+ 'webOS' => 'webOS|hpwOS',
400
+ 'badaOS' => '\bBada\b',
401
+ 'BREWOS' => 'BREW',
402
+ );
403
+
404
+ /**
405
+ * List of mobile User Agents.
406
+ *
407
+ * @var array
408
+ */
409
+ protected static $browsers = array(
410
+ // @reference: https://developers.google.com/chrome/mobile/docs/user-agent
411
+ 'Chrome' => '\bCrMo\b|CriOS|Android.*Chrome/[.0-9]* (Mobile)?',
412
+ 'Dolfin' => '\bDolfin\b',
413
+ 'Opera' => 'Opera.*Mini|Opera.*Mobi|Android.*Opera|Mobile.*OPR/[0-9.]+|Coast/[0-9.]+',
414
+ 'Skyfire' => 'Skyfire',
415
+ 'IE' => 'IEMobile|MSIEMobile', // |Trident/[.0-9]+
416
+ 'Firefox' => 'fennec|firefox.*maemo|(Mobile|Tablet).*Firefox|Firefox.*Mobile',
417
+ 'Bolt' => 'bolt',
418
+ 'TeaShark' => 'teashark',
419
+ 'Blazer' => 'Blazer',
420
+ // @reference: http://developer.apple.com/library/safari/#documentation/AppleApplications/Reference/SafariWebContent/OptimizingforSafarioniPhone/OptimizingforSafarioniPhone.html#//apple_ref/doc/uid/TP40006517-SW3
421
+ 'Safari' => 'Version.*Mobile.*Safari|Safari.*Mobile',
422
+ // @ref: http://en.wikipedia.org/wiki/Midori_(web_browser)
423
+ //'Midori' => 'midori',
424
+ 'Tizen' => 'Tizen',
425
+ 'UCBrowser' => 'UC.*Browser|UCWEB',
426
+ // @ref: https://github.com/serbanghita/Mobile-Detect/issues/7
427
+ 'DiigoBrowser' => 'DiigoBrowser',
428
+ // http://www.puffinbrowser.com/index.php
429
+ 'Puffin' => 'Puffin',
430
+ // @ref: http://mercury-browser.com/index.html
431
+ 'Mercury' => '\bMercury\b',
432
+ // @reference: http://en.wikipedia.org/wiki/Minimo
433
+ // http://en.wikipedia.org/wiki/Vision_Mobile_Browser
434
+ 'GenericBrowser' => 'NokiaBrowser|OviBrowser|OneBrowser|TwonkyBeamBrowser|SEMC.*Browser|FlyFlow|Minimo|NetFront|Novarra-Vision|MQQBrowser|MicroMessenger'
435
+ );
436
+
437
+ /**
438
+ * Utilities.
439
+ *
440
+ * @var array
441
+ */
442
+ protected static $utilities = array(
443
+ // Experimental. When a mobile device wants to switch to 'Desktop Mode'.
444
+ // @ref: http://scottcate.com/technology/windows-phone-8-ie10-desktop-or-mobile/
445
+ // @ref: https://github.com/serbanghita/Mobile-Detect/issues/57#issuecomment-15024011
446
+ 'DesktopMode' => 'WPDesktop',
447
+ 'TV' => 'SonyDTV|HbbTV', // experimental
448
+ 'WebKit' => '(webkit)[ /]([\w.]+)',
449
+ 'Bot' => 'Googlebot|DoCoMo|YandexBot|bingbot|ia_archiver|AhrefsBot|Ezooms|GSLFbot|WBSearchBot|Twitterbot|TweetmemeBot|Twikle|PaperLiBot|Wotbox|UnwindFetchor|facebookexternalhit',
450
+ 'MobileBot' => 'Googlebot-Mobile|DoCoMo|YahooSeeker/M1A1-R2D2',
451
+ // @todo: Include JXD consoles.
452
+ 'Console' => '\b(Nintendo|Nintendo WiiU|PLAYSTATION|Xbox)\b',
453
+ 'Watch' => 'SM-V700',
454
+ );
455
+
456
+ /**
457
+ * All possible HTTP headers that represent the
458
+ * User-Agent string.
459
+ *
460
+ * @var array
461
+ */
462
+ protected static $uaHttpHeaders = array(
463
+ // The default User-Agent string.
464
+ 'HTTP_USER_AGENT',
465
+ // Header can occur on devices using Opera Mini.
466
+ 'HTTP_X_OPERAMINI_PHONE_UA',
467
+ // Vodafone specific header: http://www.seoprinciple.com/mobile-web-community-still-angry-at-vodafone/24/
468
+ 'HTTP_X_DEVICE_USER_AGENT',
469
+ 'HTTP_X_ORIGINAL_USER_AGENT',
470
+ 'HTTP_X_SKYFIRE_PHONE',
471
+ 'HTTP_X_BOLT_PHONE_UA',
472
+ 'HTTP_DEVICE_STOCK_UA',
473
+ 'HTTP_X_UCBROWSER_DEVICE_UA'
474
+ );
475
+
476
+ /**
477
+ * The individual segments that could exist in a User-Agent string. VER refers to the regular
478
+ * expression defined in the constant self::VER.
479
+ *
480
+ * @var array
481
+ */
482
+ protected static $properties = array(
483
+
484
+ // Build
485
+ 'Mobile' => 'Mobile/[VER]',
486
+ 'Build' => 'Build/[VER]',
487
+ 'Version' => 'Version/[VER]',
488
+ 'VendorID' => 'VendorID/[VER]',
489
+
490
+ // Devices
491
+ 'iPad' => 'iPad.*CPU[a-z ]+[VER]',
492
+ 'iPhone' => 'iPhone.*CPU[a-z ]+[VER]',
493
+ 'iPod' => 'iPod.*CPU[a-z ]+[VER]',
494
+ //'BlackBerry' => array('BlackBerry[VER]', 'BlackBerry [VER];'),
495
+ 'Kindle' => 'Kindle/[VER]',
496
+
497
+ // Browser
498
+ 'Chrome' => array('Chrome/[VER]', 'CriOS/[VER]', 'CrMo/[VER]'),
499
+ 'Coast' => array('Coast/[VER]'),
500
+ 'Dolfin' => 'Dolfin/[VER]',
501
+ // @reference: https://developer.mozilla.org/en-US/docs/User_Agent_Strings_Reference
502
+ 'Firefox' => 'Firefox/[VER]',
503
+ 'Fennec' => 'Fennec/[VER]',
504
+ // @reference: http://msdn.microsoft.com/en-us/library/ms537503(v=vs.85).aspx
505
+ 'IE' => array('IEMobile/[VER];', 'IEMobile [VER]', 'MSIE [VER];'),
506
+ // http://en.wikipedia.org/wiki/NetFront
507
+ 'NetFront' => 'NetFront/[VER]',
508
+ 'NokiaBrowser' => 'NokiaBrowser/[VER]',
509
+ 'Opera' => array( ' OPR/[VER]', 'Opera Mini/[VER]', 'Version/[VER]' ),
510
+ 'Opera Mini' => 'Opera Mini/[VER]',
511
+ 'Opera Mobi' => 'Version/[VER]',
512
+ 'UC Browser' => 'UC Browser[VER]',
513
+ 'MQQBrowser' => 'MQQBrowser/[VER]',
514
+ 'MicroMessenger' => 'MicroMessenger/[VER]',
515
+ // @note: Safari 7534.48.3 is actually Version 5.1.
516
+ // @note: On BlackBerry the Version is overwriten by the OS.
517
+ 'Safari' => array( 'Version/[VER]', 'Safari/[VER]' ),
518
+ 'Skyfire' => 'Skyfire/[VER]',
519
+ 'Tizen' => 'Tizen/[VER]',
520
+ 'Webkit' => 'webkit[ /][VER]',
521
+
522
+ // Engine
523
+ 'Gecko' => 'Gecko/[VER]',
524
+ 'Trident' => 'Trident/[VER]',
525
+ 'Presto' => 'Presto/[VER]',
526
+
527
+ // OS
528
+ 'iOS' => ' \bOS\b [VER] ',
529
+ 'Android' => 'Android [VER]',
530
+ 'BlackBerry' => array('BlackBerry[\w]+/[VER]', 'BlackBerry.*Version/[VER]', 'Version/[VER]'),
531
+ 'BREW' => 'BREW [VER]',
532
+ 'Java' => 'Java/[VER]',
533
+ // @reference: http://windowsteamblog.com/windows_phone/b/wpdev/archive/2011/08/29/introducing-the-ie9-on-windows-phone-mango-user-agent-string.aspx
534
+ // @reference: http://en.wikipedia.org/wiki/Windows_NT#Releases
535
+ 'Windows Phone OS' => array( 'Windows Phone OS [VER]', 'Windows Phone [VER]'),
536
+ 'Windows Phone' => 'Windows Phone [VER]',
537
+ 'Windows CE' => 'Windows CE/[VER]',
538
+ // http://social.msdn.microsoft.com/Forums/en-US/windowsdeveloperpreviewgeneral/thread/6be392da-4d2f-41b4-8354-8dcee20c85cd
539
+ 'Windows NT' => 'Windows NT [VER]',
540
+ 'Symbian' => array('SymbianOS/[VER]', 'Symbian/[VER]'),
541
+ 'webOS' => array('webOS/[VER]', 'hpwOS/[VER];'),
542
+ );
543
+
544
+ /**
545
+ * Construct an instance of this class.
546
+ *
547
+ * @param array $headers Specify the headers as injection. Should be PHP _SERVER flavored.
548
+ * If left empty, will use the global _SERVER['HTTP_*'] vars instead.
549
+ * @param string $userAgent Inject the User-Agent header. If null, will use HTTP_USER_AGENT
550
+ * from the $headers array instead.
551
+ */
552
+ public function __construct(
553
+ array $headers = null,
554
+ $userAgent = null
555
+ ){
556
+ $this->setHttpHeaders($headers);
557
+ $this->setUserAgent($userAgent);
558
+ }
559
+
560
+ /**
561
+ * Get the current script version.
562
+ * This is useful for the demo.php file,
563
+ * so people can check on what version they are testing
564
+ * for mobile devices.
565
+ *
566
+ * @return string The version number in semantic version format.
567
+ */
568
+ public static function getScriptVersion()
569
+ {
570
+ return self::VERSION;
571
+ }
572
+
573
+ /**
574
+ * Set the HTTP Headers. Must be PHP-flavored. This method will reset existing headers.
575
+ *
576
+ * @param array $httpHeaders The headers to set. If null, then using PHP's _SERVER to extract
577
+ * the headers. The default null is left for backwards compatibilty.
578
+ */
579
+ public function setHttpHeaders($httpHeaders = null)
580
+ {
581
+ //use global _SERVER if $httpHeaders aren't defined
582
+ if (!is_array($httpHeaders) || !count($httpHeaders)) {
583
+ $httpHeaders = $_SERVER;
584
+ }
585
+
586
+ //clear existing headers
587
+ $this->httpHeaders = array();
588
+
589
+ //Only save HTTP headers. In PHP land, that means only _SERVER vars that
590
+ //start with HTTP_.
591
+ foreach ($httpHeaders as $key => $value) {
592
+ if (substr($key,0,5) == 'HTTP_') {
593
+ $this->httpHeaders[$key] = $value;
594
+ }
595
+ }
596
+ }
597
+
598
+ /**
599
+ * Retrieves the HTTP headers.
600
+ *
601
+ * @return array
602
+ */
603
+ public function getHttpHeaders()
604
+ {
605
+ return $this->httpHeaders;
606
+ }
607
+
608
+ /**
609
+ * Retrieves a particular header. If it doesn't exist, no exception/error is caused.
610
+ * Simply null is returned.
611
+ *
612
+ * @param string $header The name of the header to retrieve. Can be HTTP compliant such as
613
+ * "User-Agent" or "X-Device-User-Agent" or can be php-esque with the
614
+ * all-caps, HTTP_ prefixed, underscore seperated awesomeness.
615
+ *
616
+ * @return string|null The value of the header.
617
+ */
618
+ public function getHttpHeader($header)
619
+ {
620
+ //are we using PHP-flavored headers?
621
+ if (strpos($header, '_') === false) {
622
+ $header = str_replace('-', '_', $header);
623
+ $header = strtoupper($header);
624
+ }
625
+
626
+ //test the alternate, too
627
+ $altHeader = 'HTTP_' . $header;
628
+
629
+ //Test both the regular and the HTTP_ prefix
630
+ if (isset($this->httpHeaders[$header])) {
631
+ return $this->httpHeaders[$header];
632
+ } elseif (isset($this->httpHeaders[$altHeader])) {
633
+ return $this->httpHeaders[$altHeader];
634
+ }
635
+
636
+ return null;
637
+ }
638
+
639
+ public function getMobileHeaders()
640
+ {
641
+ return self::$mobileHeaders;
642
+ }
643
+
644
+ /**
645
+ * Get all possible HTTP headers that
646
+ * can contain the User-Agent string.
647
+ *
648
+ * @return array List of HTTP headers.
649
+ */
650
+ public function getUaHttpHeaders()
651
+ {
652
+ return self::$uaHttpHeaders;
653
+ }
654
+
655
+ /**
656
+ * Set the User-Agent to be used.
657
+ *
658
+ * @param string $userAgent The user agent string to set.
659
+ *
660
+ * @return string|null
661
+ */
662
+ public function setUserAgent($userAgent = null)
663
+ {
664
+ if (!empty($userAgent)) {
665
+ return $this->userAgent = $userAgent;
666
+ } else {
667
+
668
+ $this->userAgent = null;
669
+
670
+ foreach($this->getUaHttpHeaders() as $altHeader){
671
+ if(!empty($this->httpHeaders[$altHeader])){ // @todo: should use getHttpHeader(), but it would be slow. (Serban)
672
+ $this->userAgent .= $this->httpHeaders[$altHeader] . " ";
673
+ }
674
+ }
675
+
676
+ return $this->userAgent = (!empty($this->userAgent) ? trim($this->userAgent) : null);
677
+
678
+ }
679
+ }
680
+
681
+ /**
682
+ * Retrieve the User-Agent.
683
+ *
684
+ * @return string|null The user agent if it's set.
685
+ */
686
+ public function getUserAgent()
687
+ {
688
+ return $this->userAgent;
689
+ }
690
+
691
+ /**
692
+ * Set the detection type. Must be one of self::DETECTION_TYPE_MOBILE or
693
+ * self::DETECTION_TYPE_EXTENDED. Otherwise, nothing is set.
694
+ *
695
+ * @deprecated since version 2.6.9
696
+ *
697
+ * @param string $type The type. Must be a self::DETECTION_TYPE_* constant. The default
698
+ * parameter is null which will default to self::DETECTION_TYPE_MOBILE.
699
+ */
700
+ public function setDetectionType($type = null)
701
+ {
702
+ if ($type === null) {
703
+ $type = self::DETECTION_TYPE_MOBILE;
704
+ }
705
+
706
+ if ($type != self::DETECTION_TYPE_MOBILE && $type != self::DETECTION_TYPE_EXTENDED) {
707
+ return;
708
+ }
709
+
710
+ $this->detectionType = $type;
711
+ }
712
+
713
+ /**
714
+ * Retrieve the list of known phone devices.
715
+ *
716
+ * @return array List of phone devices.
717
+ */
718
+ public static function getPhoneDevices()
719
+ {
720
+ return self::$phoneDevices;
721
+ }
722
+
723
+ /**
724
+ * Retrieve the list of known tablet devices.
725
+ *
726
+ * @return array List of tablet devices.
727
+ */
728
+ public static function getTabletDevices()
729
+ {
730
+ return self::$tabletDevices;
731
+ }
732
+
733
+ /**
734
+ * Alias for getBrowsers() method.
735
+ *
736
+ * @return array List of user agents.
737
+ */
738
+ public static function getUserAgents()
739
+ {
740
+ return self::getBrowsers();
741
+ }
742
+
743
+ /**
744
+ * Retrieve the list of known browsers. Specifically, the user agents.
745
+ *
746
+ * @return array List of browsers / user agents.
747
+ */
748
+ public static function getBrowsers()
749
+ {
750
+ return self::$browsers;
751
+ }
752
+
753
+ /**
754
+ * Retrieve the list of known utilities.
755
+ *
756
+ * @return array List of utilities.
757
+ */
758
+ public static function getUtilities()
759
+ {
760
+ return self::$utilities;
761
+ }
762
+
763
+ /**
764
+ * Method gets the mobile detection rules. This method is used for the magic methods $detect->is*().
765
+ *
766
+ * @deprecated since version 2.6.9
767
+ *
768
+ * @return array All the rules (but not extended).
769
+ */
770
+ public static function getMobileDetectionRules()
771
+ {
772
+ static $rules;
773
+
774
+ if (!$rules) {
775
+ $rules = array_merge(
776
+ self::$phoneDevices,
777
+ self::$tabletDevices,
778
+ self::$operatingSystems,
779
+ self::$browsers
780
+ );
781
+ }
782
+
783
+ return $rules;
784
+
785
+ }
786
+
787
+ /**
788
+ * Method gets the mobile detection rules + utilities.
789
+ * The reason this is separate is because utilities rules
790
+ * don't necessary imply mobile. This method is used inside
791
+ * the new $detect->is('stuff') method.
792
+ *
793
+ * @deprecated since version 2.6.9
794
+ *
795
+ * @return array All the rules + extended.
796
+ */
797
+ public function getMobileDetectionRulesExtended()
798
+ {
799
+ static $rules;
800
+
801
+ if (!$rules) {
802
+ // Merge all rules together.
803
+ $rules = array_merge(
804
+ self::$phoneDevices,
805
+ self::$tabletDevices,
806
+ self::$operatingSystems,
807
+ self::$browsers,
808
+ self::$utilities
809
+ );
810
+ }
811
+
812
+ return $rules;
813
+ }
814
+
815
+ /**
816
+ * Retrieve the current set of rules.
817
+ *
818
+ * @deprecated since version 2.6.9
819
+ *
820
+ * @return array
821
+ */
822
+ public function getRules()
823
+ {
824
+ if ($this->detectionType == self::DETECTION_TYPE_EXTENDED) {
825
+ return self::getMobileDetectionRulesExtended();
826
+ } else {
827
+ return self::getMobileDetectionRules();
828
+ }
829
+ }
830
+
831
+ /**
832
+ * Retrieve the list of mobile operating systems.
833
+ *
834
+ * @return array The list of mobile operating systems.
835
+ */
836
+ public static function getOperatingSystems()
837
+ {
838
+ return self::$operatingSystems;
839
+ }
840
+
841
+ /**
842
+ * Check the HTTP headers for signs of mobile.
843
+ * This is the fastest mobile check possible; it's used
844
+ * inside isMobile() method.
845
+ *
846
+ * @return bool
847
+ */
848
+ public function checkHttpHeadersForMobile()
849
+ {
850
+
851
+ foreach($this->getMobileHeaders() as $mobileHeader => $matchType){
852
+ if( isset($this->httpHeaders[$mobileHeader]) ){
853
+ if( is_array($matchType['matches']) ){
854
+ foreach($matchType['matches'] as $_match){
855
+ if( strpos($this->httpHeaders[$mobileHeader], $_match) !== false ){
856
+ return true;
857
+ }
858
+ }
859
+ return false;
860
+ } else {
861
+ return true;
862
+ }
863
+ }
864
+ }
865
+
866
+ return false;
867
+
868
+ }
869
+
870
+ /**
871
+ * Magic overloading method.
872
+ *
873
+ * @method boolean is[...]()
874
+ * @param string $name
875
+ * @param array $arguments
876
+ * @return mixed
877
+ * @throws BadMethodCallException when the method doesn't exist and doesn't start with 'is'
878
+ */
879
+ public function __call($name, $arguments)
880
+ {
881
+ //make sure the name starts with 'is', otherwise
882
+ if (substr($name, 0, 2) != 'is') {
883
+ throw new BadMethodCallException("No such method exists: $name");
884
+ }
885
+
886
+ $this->setDetectionType(self::DETECTION_TYPE_MOBILE);
887
+
888
+ $key = substr($name, 2);
889
+
890
+ return $this->matchUAAgainstKey($key);
891
+ }
892
+
893
+ /**
894
+ * Find a detection rule that matches the current User-agent.
895
+ *
896
+ * @param null $userAgent deprecated
897
+ * @return boolean
898
+ */
899
+ protected function matchDetectionRulesAgainstUA($userAgent = null)
900
+ {
901
+ // Begin general search.
902
+ foreach ($this->getRules() as $_regex) {
903
+ if (empty($_regex)) {
904
+ continue;
905
+ }
906
+ if ($this->match($_regex, $userAgent)) {
907
+ return true;
908
+ }
909
+ }
910
+
911
+ return false;
912
+ }
913
+
914
+ /**
915
+ * Search for a certain key in the rules array.
916
+ * If the key is found the try to match the corresponding
917
+ * regex agains the User-Agent.
918
+ *
919
+ * @param string $key
920
+ * @param null $userAgent deprecated
921
+ * @return mixed
922
+ */
923
+ protected function matchUAAgainstKey($key, $userAgent = null)
924
+ {
925
+ // Make the keys lowercase so we can match: isIphone(), isiPhone(), isiphone(), etc.
926
+ $key = strtolower($key);
927
+
928
+ //change the keys to lower case
929
+ $_rules = array_change_key_case($this->getRules());
930
+
931
+ if (array_key_exists($key, $_rules)) {
932
+ if (empty($_rules[$key])) {
933
+ return null;
934
+ }
935
+
936
+ return $this->match($_rules[$key], $userAgent);
937
+ }
938
+
939
+ return false;
940
+ }
941
+
942
+ /**
943
+ * Check if the device is mobile.
944
+ * Returns true if any type of mobile device detected, including special ones
945
+ * @param null $userAgent deprecated
946
+ * @param null $httpHeaders deprecated
947
+ * @return bool
948
+ */
949
+ public function isMobile($userAgent = null, $httpHeaders = null)
950
+ {
951
+
952
+ if ($httpHeaders) {
953
+ $this->setHttpHeaders($httpHeaders);
954
+ }
955
+
956
+ if ($userAgent) {
957
+ $this->setUserAgent($userAgent);
958
+ }
959
+
960
+ $this->setDetectionType(self::DETECTION_TYPE_MOBILE);
961
+
962
+ if ($this->checkHttpHeadersForMobile()) {
963
+ return true;
964
+ } else {
965
+ return $this->matchDetectionRulesAgainstUA();
966
+ }
967
+
968
+ }
969
+
970
+ /**
971
+ * Check if the device is a tablet.
972
+ * Return true if any type of tablet device is detected.
973
+ *
974
+ * @param string $userAgent deprecated
975
+ * @param array $httpHeaders deprecated
976
+ * @return bool
977
+ */
978
+ public function isTablet($userAgent = null, $httpHeaders = null)
979
+ {
980
+ $this->setDetectionType(self::DETECTION_TYPE_MOBILE);
981
+
982
+ foreach (self::$tabletDevices as $_regex) {
983
+ if ($this->match($_regex, $userAgent)) {
984
+ return true;
985
+ }
986
+ }
987
+
988
+ return false;
989
+ }
990
+
991
+ /**
992
+ * This method checks for a certain property in the
993
+ * userAgent.
994
+ * @todo: The httpHeaders part is not yet used.
995
+ *
996
+ * @param string $key
997
+ * @param string $userAgent deprecated
998
+ * @param string $httpHeaders deprecated
999
+ * @return bool|int|null
1000
+ */
1001
+ public function is($key, $userAgent = null, $httpHeaders = null)
1002
+ {
1003
+ // Set the UA and HTTP headers only if needed (eg. batch mode).
1004
+ if ($httpHeaders) {
1005
+ $this->setHttpHeaders($httpHeaders);
1006
+ }
1007
+
1008
+ if ($userAgent) {
1009
+ $this->setUserAgent($userAgent);
1010
+ }
1011
+
1012
+ $this->setDetectionType(self::DETECTION_TYPE_EXTENDED);
1013
+
1014
+ return $this->matchUAAgainstKey($key);
1015
+ }
1016
+
1017
+ /**
1018
+ * Some detection rules are relative (not standard),
1019
+ * because of the diversity of devices, vendors and
1020
+ * their conventions in representing the User-Agent or
1021
+ * the HTTP headers.
1022
+ *
1023
+ * This method will be used to check custom regexes against
1024
+ * the User-Agent string.
1025
+ *
1026
+ * @param $regex
1027
+ * @param string $userAgent
1028
+ * @return bool
1029
+ *
1030
+ * @todo: search in the HTTP headers too.
1031
+ */
1032
+ public function match($regex, $userAgent = null)
1033
+ {
1034
+ // Escape the special character which is the delimiter.
1035
+ $regex = str_replace('/', '\/', $regex);
1036
+
1037
+ return (bool) preg_match('/'.$regex.'/is', (!empty($userAgent) ? $userAgent : $this->userAgent));
1038
+ }
1039
+
1040
+ /**
1041
+ * Get the properties array.
1042
+ *
1043
+ * @return array
1044
+ */
1045
+ public static function getProperties()
1046
+ {
1047
+ return self::$properties;
1048
+ }
1049
+
1050
+ /**
1051
+ * Prepare the version number.
1052
+ *
1053
+ * @todo Remove the error supression from str_replace() call.
1054
+ *
1055
+ * @param string $ver The string version, like "2.6.21.2152";
1056
+ *
1057
+ * @return float
1058
+ */
1059
+ public function prepareVersionNo($ver)
1060
+ {
1061
+ $ver = str_replace(array('_', ' ', '/'), '.', $ver);
1062
+ $arrVer = explode('.', $ver, 2);
1063
+
1064
+ if (isset($arrVer[1])) {
1065
+ $arrVer[1] = @str_replace('.', '', $arrVer[1]); // @todo: treat strings versions.
1066
+ }
1067
+
1068
+ return (float) implode('.', $arrVer);
1069
+ }
1070
+
1071
+ /**
1072
+ * Check the version of the given property in the User-Agent.
1073
+ * Will return a float number. (eg. 2_0 will return 2.0, 4.3.1 will return 4.31)
1074
+ *
1075
+ * @param string $propertyName The name of the property. See self::getProperties() array
1076
+ * keys for all possible properties.
1077
+ * @param string $type Either self::VERSION_TYPE_STRING to get a string value or
1078
+ * self::VERSION_TYPE_FLOAT indicating a float value. This parameter
1079
+ * is optional and defaults to self::VERSION_TYPE_STRING. Passing an
1080
+ * invalid parameter will default to the this type as well.
1081
+ *
1082
+ * @return string|float The version of the property we are trying to extract.
1083
+ */
1084
+ public function version($propertyName, $type = self::VERSION_TYPE_STRING)
1085
+ {
1086
+ if (empty($propertyName)) {
1087
+ return false;
1088
+ }
1089
+
1090
+ //set the $type to the default if we don't recognize the type
1091
+ if ($type != self::VERSION_TYPE_STRING && $type != self::VERSION_TYPE_FLOAT) {
1092
+ $type = self::VERSION_TYPE_STRING;
1093
+ }
1094
+
1095
+ $properties = self::getProperties();
1096
+
1097
+ // Check if the property exists in the properties array.
1098
+ if (array_key_exists($propertyName, $properties)) {
1099
+
1100
+ // Prepare the pattern to be matched.
1101
+ // Make sure we always deal with an array (string is converted).
1102
+ $properties[$propertyName] = (array) $properties[$propertyName];
1103
+
1104
+ foreach ($properties[$propertyName] as $propertyMatchString) {
1105
+
1106
+ $propertyPattern = str_replace('[VER]', self::VER, $propertyMatchString);
1107
+
1108
+ // Escape the special character which is the delimiter.
1109
+ $propertyPattern = str_replace('/', '\/', $propertyPattern);
1110
+
1111
+ // Identify and extract the version.
1112
+ preg_match('/'.$propertyPattern.'/is', $this->userAgent, $match);
1113
+
1114
+ if (!empty($match[1])) {
1115
+ $version = ( $type == self::VERSION_TYPE_FLOAT ? $this->prepareVersionNo($match[1]) : $match[1] );
1116
+
1117
+ return $version;
1118
+ }
1119
+
1120
+ }
1121
+
1122
+ }
1123
+
1124
+ return false;
1125
+ }
1126
+
1127
+ /**
1128
+ * Retrieve the mobile grading, using self::MOBILE_GRADE_* constants.
1129
+ *
1130
+ * @return string One of the self::MOBILE_GRADE_* constants.
1131
+ */
1132
+ public function mobileGrade()
1133
+ {
1134
+ $isMobile = $this->isMobile();
1135
+
1136
+ if (
1137
+ // 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)
1138
+ $this->isIOS() && $this->version('iPad', self::VERSION_TYPE_FLOAT)>=4.3 ||
1139
+ $this->isIOS() && $this->version('iPhone', self::VERSION_TYPE_FLOAT)>=3.1 ||
1140
+ $this->isIOS() && $this->version('iPod', self::VERSION_TYPE_FLOAT)>=3.1 ||
1141
+
1142
+ // 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)
1143
+ // Android 3.1 (Honeycomb) - Tested on the Samsung Galaxy Tab 10.1 and Motorola XOOM
1144
+ // Android 4.0 (ICS) - Tested on a Galaxy Nexus. Note: transition performance can be poor on upgraded devices
1145
+ // Android 4.1 (Jelly Bean) - Tested on a Galaxy Nexus and Galaxy 7
1146
+ ( $this->version('Android', self::VERSION_TYPE_FLOAT)>2.1 && $this->is('Webkit') ) ||
1147
+
1148
+ // Windows Phone 7-7.5 - Tested on the HTC Surround (7.0) HTC Trophy (7.5), LG-E900 (7.5), Nokia Lumia 800
1149
+ $this->version('Windows Phone OS', self::VERSION_TYPE_FLOAT)>=7.0 ||
1150
+
1151
+ // Blackberry 7 - Tested on BlackBerry Torch 9810
1152
+ // Blackberry 6.0 - Tested on the Torch 9800 and Style 9670
1153
+ $this->is('BlackBerry') && $this->version('BlackBerry', self::VERSION_TYPE_FLOAT)>=6.0 ||
1154
+ // Blackberry Playbook (1.0-2.0) - Tested on PlayBook
1155
+ $this->match('Playbook.*Tablet') ||
1156
+
1157
+ // Palm WebOS (1.4-2.0) - Tested on the Palm Pixi (1.4), Pre (1.4), Pre 2 (2.0)
1158
+ ( $this->version('webOS', self::VERSION_TYPE_FLOAT)>=1.4 && $this->match('Palm|Pre|Pixi') ) ||
1159
+ // Palm WebOS 3.0 - Tested on HP TouchPad
1160
+ $this->match('hp.*TouchPad') ||
1161
+
1162
+ // Firefox Mobile (12 Beta) - Tested on Android 2.3 device
1163
+ ( $this->is('Firefox') && $this->version('Firefox', self::VERSION_TYPE_FLOAT)>=12 ) ||
1164
+
1165
+ // Chrome for Android - Tested on Android 4.0, 4.1 device
1166
+ ( $this->is('Chrome') && $this->is('AndroidOS') && $this->version('Android', self::VERSION_TYPE_FLOAT)>=4.0 ) ||
1167
+
1168
+ // Skyfire 4.1 - Tested on Android 2.3 device
1169
+ ( $this->is('Skyfire') && $this->version('Skyfire', self::VERSION_TYPE_FLOAT)>=4.1 && $this->is('AndroidOS') && $this->version('Android', self::VERSION_TYPE_FLOAT)>=2.3 ) ||
1170
+
1171
+ // Opera Mobile 11.5-12: Tested on Android 2.3
1172
+ ( $this->is('Opera') && $this->version('Opera Mobi', self::VERSION_TYPE_FLOAT)>11 && $this->is('AndroidOS') ) ||
1173
+
1174
+ // Meego 1.2 - Tested on Nokia 950 and N9
1175
+ $this->is('MeeGoOS') ||
1176
+
1177
+ // Tizen (pre-release) - Tested on early hardware
1178
+ $this->is('Tizen') ||
1179
+
1180
+ // Samsung Bada 2.0 - Tested on a Samsung Wave 3, Dolphin browser
1181
+ // @todo: more tests here!
1182
+ $this->is('Dolfin') && $this->version('Bada', self::VERSION_TYPE_FLOAT)>=2.0 ||
1183
+
1184
+ // UC Browser - Tested on Android 2.3 device
1185
+ ( ($this->is('UC Browser') || $this->is('Dolfin')) && $this->version('Android', self::VERSION_TYPE_FLOAT)>=2.3 ) ||
1186
+
1187
+ // Kindle 3 and Fire - Tested on the built-in WebKit browser for each
1188
+ ( $this->match('Kindle Fire') ||
1189
+ $this->is('Kindle') && $this->version('Kindle', self::VERSION_TYPE_FLOAT)>=3.0 ) ||
1190
+
1191
+ // Nook Color 1.4.1 - Tested on original Nook Color, not Nook Tablet
1192
+ $this->is('AndroidOS') && $this->is('NookTablet') ||
1193
+
1194
+ // Chrome Desktop 11-21 - Tested on OS X 10.7 and Windows 7
1195
+ $this->version('Chrome', self::VERSION_TYPE_FLOAT)>=11 && !$isMobile ||
1196
+
1197
+ // Safari Desktop 4-5 - Tested on OS X 10.7 and Windows 7
1198
+ $this->version('Safari', self::VERSION_TYPE_FLOAT)>=5.0 && !$isMobile ||
1199
+
1200
+ // Firefox Desktop 4-13 - Tested on OS X 10.7 and Windows 7
1201
+ $this->version('Firefox', self::VERSION_TYPE_FLOAT)>=4.0 && !$isMobile ||
1202
+
1203
+ // Internet Explorer 7-9 - Tested on Windows XP, Vista and 7
1204
+ $this->version('MSIE', self::VERSION_TYPE_FLOAT)>=7.0 && !$isMobile ||
1205
+
1206
+ // Opera Desktop 10-12 - Tested on OS X 10.7 and Windows 7
1207
+ // @reference: http://my.opera.com/community/openweb/idopera/
1208
+ $this->version('Opera', self::VERSION_TYPE_FLOAT)>=10 && !$isMobile
1209
+
1210
+ ){
1211
+ return self::MOBILE_GRADE_A;
1212
+ }
1213
+
1214
+ if (
1215
+ $this->isIOS() && $this->version('iPad', self::VERSION_TYPE_FLOAT)<4.3 ||
1216
+ $this->isIOS() && $this->version('iPhone', self::VERSION_TYPE_FLOAT)<3.1 ||
1217
+ $this->isIOS() && $this->version('iPod', self::VERSION_TYPE_FLOAT)<3.1 ||
1218
+
1219
+ // Blackberry 5.0: Tested on the Storm 2 9550, Bold 9770
1220
+ $this->is('Blackberry') && $this->version('BlackBerry', self::VERSION_TYPE_FLOAT)>=5 && $this->version('BlackBerry', self::VERSION_TYPE_FLOAT)<6 ||
1221
+
1222
+ //Opera Mini (5.0-6.5) - Tested on iOS 3.2/4.3 and Android 2.3
1223
+ ( $this->version('Opera Mini', self::VERSION_TYPE_FLOAT)>=5.0 && $this->version('Opera Mini', self::VERSION_TYPE_FLOAT)<=6.5 &&
1224
+ ($this->version('Android', self::VERSION_TYPE_FLOAT)>=2.3 || $this->is('iOS')) ) ||
1225
+
1226
+ // Nokia Symbian^3 - Tested on Nokia N8 (Symbian^3), C7 (Symbian^3), also works on N97 (Symbian^1)
1227
+ $this->match('NokiaN8|NokiaC7|N97.*Series60|Symbian/3') ||
1228
+
1229
+ // @todo: report this (tested on Nokia N71)
1230
+ $this->version('Opera Mobi', self::VERSION_TYPE_FLOAT)>=11 && $this->is('SymbianOS')
1231
+ ){
1232
+ return self::MOBILE_GRADE_B;
1233
+ }
1234
+
1235
+ if (
1236
+ // Blackberry 4.x - Tested on the Curve 8330
1237
+ $this->version('BlackBerry', self::VERSION_TYPE_FLOAT)<5.0 ||
1238
+ // Windows Mobile - Tested on the HTC Leo (WinMo 5.2)
1239
+ $this->match('MSIEMobile|Windows CE.*Mobile') || $this->version('Windows Mobile', self::VERSION_TYPE_FLOAT)<=5.2
1240
+
1241
+ ){
1242
+ return self::MOBILE_GRADE_C;
1243
+ }
1244
+
1245
+ //All older smartphone platforms and featurephones - Any device that doesn't support media queries
1246
+ //will receive the basic, C grade experience.
1247
+ return self::MOBILE_GRADE_C;
1248
+ }
1249
+ }
1250
+ endif;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
assets/helper/edsanimate-tinymce-popup.php CHANGED
@@ -5,7 +5,7 @@ $scroll_offset = get_option ( 'eds_scroll_offset', '75' );
5
  <html lang="en">
6
  <head>
7
  <meta charset="utf-8">
8
- <title><?php _e( 'Select your Animation Style', 'eds-animate' ); ?>:</title>
9
  <meta name="viewport"
10
  content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
11
  <link rel="stylesheet"
@@ -27,19 +27,19 @@ $scroll_offset = get_option ( 'eds_scroll_offset', '75' );
27
  <div class="edsai-form-wrapper">
28
  <div class="edsai-tabs">
29
  <div class="edsai-tab edsai-tab-active">
30
- <a class="edsai-tab-handler" href="#tab-entry"><?php _e( 'Entry', 'eds-animate' ); ?></a>
31
  </div>
32
  <div class="edsai-tab">
33
- <a class="edsai-tab-handler" href="#tab-exit"><?php _e( 'Exit', 'eds-animate' ); ?></a>
34
  </div>
35
  <div class="edsai-tab">
36
- <a class="edsai-tab-handler" href="#tab-options"><?php _e( 'Options', 'eds-animate' ); ?></a>
37
  </div>
38
  </div>
39
  <div id="tab-entry" class="edsai-tab-content edsai-entry"
40
  style="display: block;">
41
  <div class="edsai-form-control-wrapper">
42
- <label for="entry-animation-type"><?php _e( 'Animation', 'eds-animate' ); ?>:</label>
43
  <div class="edsai-form-control">
44
  <select id="entry-animation-type" name="entry-animation-type"
45
  class="full-size">
@@ -110,7 +110,7 @@ $scroll_offset = get_option ( 'eds_scroll_offset', '75' );
110
  </div>
111
  </div>
112
  <div class="edsai-form-control-wrapper">
113
- <label for="entry-delay"><?php _e( 'Delay (in seconds)', 'eds-animate' ); ?>:</label>
114
  <div class="edsai-form-control">
115
  <select id="entry-delay" name="entry-delay"
116
  class="half-size has-custom">
@@ -134,7 +134,7 @@ $scroll_offset = get_option ( 'eds_scroll_offset', '75' );
134
  </div>
135
  </div>
136
  <div class="edsai-form-control-wrapper">
137
- <label for="entry-duration"><?php _e( 'Duration (in seconds)', 'eds-animate' ); ?>:</label>
138
  <div class="edsai-form-control">
139
  <select id="entry-duration" name="entry-duration"
140
  class="half-size has-custom">
@@ -157,7 +157,7 @@ $scroll_offset = get_option ( 'eds_scroll_offset', '75' );
157
  </div>
158
  </div>
159
  <div class="edsai-form-control-wrapper">
160
- <label for="entry-timing"><?php _e( 'Timing', 'eds-animate' ); ?>:</label>
161
  <div class="edsai-form-control">
162
  <select id="entry-timing" name="entry-timing"
163
  class="half-size">
@@ -196,7 +196,7 @@ $scroll_offset = get_option ( 'eds_scroll_offset', '75' );
196
  </div>
197
  <div id="tab-exit" class="edsai-tab-content edsai-exit">
198
  <div class="edsai-form-control-wrapper">
199
- <label for="exit-animation-type"><?php _e( 'Animation', 'eds-animate' ); ?>:</label>
200
  <div class="edsai-form-control">
201
  <select id="exit-animation-type" name="exit-animation-type"
202
  class="full-size">
@@ -267,7 +267,7 @@ $scroll_offset = get_option ( 'eds_scroll_offset', '75' );
267
  </div>
268
  </div>
269
  <div class="edsai-form-control-wrapper">
270
- <label for="exit-delay"><?php _e( 'Delay (in seconds)', 'eds-animate' ); ?>:</label>
271
  <div class="edsai-form-control">
272
  <select id="exit-delay" name="exit-delay"
273
  class="half-size has-custom">
@@ -291,7 +291,7 @@ $scroll_offset = get_option ( 'eds_scroll_offset', '75' );
291
  </div>
292
  </div>
293
  <div class="edsai-form-control-wrapper">
294
- <label for="exit-duration"><?php _e( 'Duration (in seconds)', 'eds-animate' ); ?>:</label>
295
  <div class="edsai-form-control">
296
  <select id="exit-duration" name="exit-duration"
297
  class="half-size has-custom">
@@ -314,7 +314,7 @@ $scroll_offset = get_option ( 'eds_scroll_offset', '75' );
314
  </div>
315
  </div>
316
  <div class="edsai-form-control-wrapper">
317
- <label for="exit-timing"><?php _e( 'Timing', 'eds-animate' ); ?>:</label>
318
  <div class="edsai-form-control">
319
  <select id="exit-timing" name="exit-timing"
320
  class="half-size">
@@ -353,7 +353,7 @@ $scroll_offset = get_option ( 'eds_scroll_offset', '75' );
353
  </div>
354
  <div id="tab-options" class="edsai-tab-content edsai-options">
355
  <div class="edsai-form-control-wrapper">
356
- <label for="options-animation-repeat"><?php _e( 'Animation Repeat', 'eds-animate' ); ?>:</label>
357
  <div class="edsai-form-control">
358
  <select id="options-animation-repeat"
359
  name="options-animation-repeat" class="half-size has-custom">
@@ -368,7 +368,7 @@ $scroll_offset = get_option ( 'eds_scroll_offset', '75' );
368
  </div>
369
  </div>
370
  <div class="edsai-form-control-wrapper">
371
- <label for="options-keep"><?php _e( 'Keep Element Final State', 'eds-animate' ); ?>:</label>
372
  <div class="edsai-form-control">
373
  <input id="keep-yes" type="radio" name="options-keep"
374
  value="yes" checked> <label for="keep-yes">Yes</label> <input
@@ -377,7 +377,7 @@ $scroll_offset = get_option ( 'eds_scroll_offset', '75' );
377
  </div>
378
  </div>
379
  <div class="edsai-form-control-wrapper">
380
- <label for="options-custom-css-class"><?php _e( 'Custom CSS Class', 'eds-animate' ); ?>:</label>
381
  <div class="edsai-form-control">
382
  <input id="options-custom-css-class"
383
  name="options-custom-css-class" class="half-size"
@@ -385,7 +385,7 @@ $scroll_offset = get_option ( 'eds_scroll_offset', '75' );
385
  </div>
386
  </div>
387
  <div class="edsai-form-control-wrapper">
388
- <label for="options-animate-on"><?php _e( 'Animate On', 'eds-animate' ); ?>:</label>
389
  <div class="edsai-form-control">
390
  <input type="radio" id="on-load" name="options-animate-on"
391
  value="load" checked> <label for="on-load">Load</label> <input
@@ -399,7 +399,7 @@ $scroll_offset = get_option ( 'eds_scroll_offset', '75' );
399
  </div>
400
  <div
401
  class="edsai-form-control-wrapper options-scroll-settings-wrapper">
402
- <label for="options-scroll-offset"><?php _e( 'Scroll Offset (in %)', 'eds-animate' ); ?>:</label>
403
  <div class="edsai-form-control">
404
  <input id="options-scroll-offset" name="options-scroll-offset"
405
  class="half-size" placeholder="Custom Offset % e.g. 20.7"
@@ -411,19 +411,20 @@ $scroll_offset = get_option ( 'eds_scroll_offset', '75' );
411
  <div class="edsai-footer-wrapper">
412
  <div class="edsai-footer">
413
  <div class="edsai-footer-left">
414
- <?php _e( 'Powered by', 'eds-animate' ); ?> <a href="http://www.eleopard.in" target="_blank">eLEOPARD</a>
415
  | <a
416
  href="https://wordpress.org/support/view/plugin-reviews/animate-it"
417
- target="_blank"><?php _e( 'Review Plugin', 'eds-animate' ); ?></a>
418
  | <a
419
  href="http://www.downloads.eleopard.in/animate-it-documentation-wordpress"
420
- target="_blank"><?php _e( 'Documentation', 'eds-animate' ); ?></a>
421
  </div>
422
  <div class="edsai-footer-right">
423
  <button type="button" class="btn-stop-infinite-animation"
424
- style="display: none;"><?php _e( 'Stop Animation', 'eds-animate' ); ?></button>
425
- <button type="button" class="edsai-animate-it btn-animate-it"><?php _e( 'Animate It!', 'eds-animate' ); ?></button>
426
- <button type="button" class="edsai-insert btn-insert"><?php _e( 'Insert', 'eds-animate' ); ?></button>
 
427
  </div>
428
  </div>
429
  </div>
@@ -618,7 +619,7 @@ $scroll_offset = get_option ( 'eds_scroll_offset', '75' );
618
  }
619
 
620
 
621
- function eds_animate( animations, counter, iteration ) {
622
 
623
  $.find('.animateit-icon').animo( animations[ counter ].animoSettings, function() {
624
  counter++
5
  <html lang="en">
6
  <head>
7
  <meta charset="utf-8">
8
+ <title>Select your Animation Style:</title>
9
  <meta name="viewport"
10
  content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
11
  <link rel="stylesheet"
27
  <div class="edsai-form-wrapper">
28
  <div class="edsai-tabs">
29
  <div class="edsai-tab edsai-tab-active">
30
+ <a class="edsai-tab-handler" href="#tab-entry">Entry</a>
31
  </div>
32
  <div class="edsai-tab">
33
+ <a class="edsai-tab-handler" href="#tab-exit">Exit</a>
34
  </div>
35
  <div class="edsai-tab">
36
+ <a class="edsai-tab-handler" href="#tab-options">Options</a>
37
  </div>
38
  </div>
39
  <div id="tab-entry" class="edsai-tab-content edsai-entry"
40
  style="display: block;">
41
  <div class="edsai-form-control-wrapper">
42
+ <label for="entry-animation-type">Animation:</label>
43
  <div class="edsai-form-control">
44
  <select id="entry-animation-type" name="entry-animation-type"
45
  class="full-size">
110
  </div>
111
  </div>
112
  <div class="edsai-form-control-wrapper">
113
+ <label for="entry-delay">Delay (in seconds):</label>
114
  <div class="edsai-form-control">
115
  <select id="entry-delay" name="entry-delay"
116
  class="half-size has-custom">
134
  </div>
135
  </div>
136
  <div class="edsai-form-control-wrapper">
137
+ <label for="entry-duration">Duration (in seconds):</label>
138
  <div class="edsai-form-control">
139
  <select id="entry-duration" name="entry-duration"
140
  class="half-size has-custom">
157
  </div>
158
  </div>
159
  <div class="edsai-form-control-wrapper">
160
+ <label for="entry-timing">Timing:</label>
161
  <div class="edsai-form-control">
162
  <select id="entry-timing" name="entry-timing"
163
  class="half-size">
196
  </div>
197
  <div id="tab-exit" class="edsai-tab-content edsai-exit">
198
  <div class="edsai-form-control-wrapper">
199
+ <label for="exit-animation-type">Animation:</label>
200
  <div class="edsai-form-control">
201
  <select id="exit-animation-type" name="exit-animation-type"
202
  class="full-size">
267
  </div>
268
  </div>
269
  <div class="edsai-form-control-wrapper">
270
+ <label for="exit-delay">Delay (in seconds):</label>
271
  <div class="edsai-form-control">
272
  <select id="exit-delay" name="exit-delay"
273
  class="half-size has-custom">
291
  </div>
292
  </div>
293
  <div class="edsai-form-control-wrapper">
294
+ <label for="exit-duration">Duration (in seconds):</label>
295
  <div class="edsai-form-control">
296
  <select id="exit-duration" name="exit-duration"
297
  class="half-size has-custom">
314
  </div>
315
  </div>
316
  <div class="edsai-form-control-wrapper">
317
+ <label for="exit-timing">Timing:</label>
318
  <div class="edsai-form-control">
319
  <select id="exit-timing" name="exit-timing"
320
  class="half-size">
353
  </div>
354
  <div id="tab-options" class="edsai-tab-content edsai-options">
355
  <div class="edsai-form-control-wrapper">
356
+ <label for="options-animation-repeat">Animation Repeat:</label>
357
  <div class="edsai-form-control">
358
  <select id="options-animation-repeat"
359
  name="options-animation-repeat" class="half-size has-custom">
368
  </div>
369
  </div>
370
  <div class="edsai-form-control-wrapper">
371
+ <label for="options-keep">Keep Element Final State:</label>
372
  <div class="edsai-form-control">
373
  <input id="keep-yes" type="radio" name="options-keep"
374
  value="yes" checked> <label for="keep-yes">Yes</label> <input
377
  </div>
378
  </div>
379
  <div class="edsai-form-control-wrapper">
380
+ <label for="options-custom-css-class">Custom CSS Class:</label>
381
  <div class="edsai-form-control">
382
  <input id="options-custom-css-class"
383
  name="options-custom-css-class" class="half-size"
385
  </div>
386
  </div>
387
  <div class="edsai-form-control-wrapper">
388
+ <label for="options-animate-on">Animate On:</label>
389
  <div class="edsai-form-control">
390
  <input type="radio" id="on-load" name="options-animate-on"
391
  value="load" checked> <label for="on-load">Load</label> <input
399
  </div>
400
  <div
401
  class="edsai-form-control-wrapper options-scroll-settings-wrapper">
402
+ <label for="options-scroll-offset">Scroll Offset (in %):</label>
403
  <div class="edsai-form-control">
404
  <input id="options-scroll-offset" name="options-scroll-offset"
405
  class="half-size" placeholder="Custom Offset % e.g. 20.7"
411
  <div class="edsai-footer-wrapper">
412
  <div class="edsai-footer">
413
  <div class="edsai-footer-left">
414
+ Powered by <a href="http://www.eleopard.in" target="_blank">eLEOPARD</a>
415
  | <a
416
  href="https://wordpress.org/support/view/plugin-reviews/animate-it"
417
+ target="_blank">Review Plugin</a>
418
  | <a
419
  href="http://www.downloads.eleopard.in/animate-it-documentation-wordpress"
420
+ target="_blank">Documentation</a>
421
  </div>
422
  <div class="edsai-footer-right">
423
  <button type="button" class="btn-stop-infinite-animation"
424
+ style="display: none;">Stop Animation</button>
425
+ <button type="button" class="edsai-animate-it btn-animate-it">Animate
426
+ It!</button>
427
+ <button type="button" class="edsai-insert btn-insert">Insert</button>
428
  </div>
429
  </div>
430
  </div>
619
  }
620
 
621
 
622
+ function eds_animate( animations, counter, iteration ) {
623
 
624
  $.find('.animateit-icon').animo( animations[ counter ].animoSettings, function() {
625
  counter++
assets/js/edsanimate.js CHANGED
@@ -3,10 +3,8 @@
3
  var animationStyleClasses = ["animated","infinite", "bounce", "flash", "pulse", "rubberBand", "shake", "swing", "tada", "wobble", "bounceIn", "bounceInDown", "bounceInLeft", "bounceInRight", "bounceInUp", "bounceOut", "bounceOutDown", "bounceOutLeft", "bounceOutRight", "bounceOutUp", "fadeIn", "fadeInDown", "fadeInDownBig", "fadeInLeft", "fadeInLeftBig", "fadeInRight", "fadeInRightBig", "fadeInUp", "fadeInUpBig", "fadeOut", "fadeOutDown", "fadeOutDownBig", "fadeOutLeft", "fadeOutLeftBig", "fadeOutRight", "fadeOutRightBig", "fadeOutUp", "fadeOutUpBig", "flip", "flipInX", "flipInY", "flipOutX", "flipOutY", "lightSpeedIn", "lightSpeedOut", "rotateIn", "rotateInDownLeft", "rotateInDownRight", "rotateInUpLeft", "rotateInUpRight", "rotateOut", "rotateOutDownLeft", "rotateOutDownRight", "rotateOutUpLeft", "rotateOutUpRight", "hinge", "rollIn", "rollOut", "zoomIn", "zoomInDown", "zoomInLeft", "zoomInRight", "zoomInUp", "zoomOut", "zoomOutDown", "zoomOutLeft", "zoomOutRight", "zoomOutUp"];
4
  var delayClasses = ["delay1", "delay2", "delay3", "delay4", "delay5", "delay6", "delay7", "delay8", "delay9", "delay10", "delay11", "delay12"];
5
  var durationClasses = ["duration1", "duration2", "duration3", "duration4", "duration5", "duration6", "duration7", "duration8", "duration9", "duration10", "duration11", "duration12", "duration13", "duration14", "duration15", "duration16", "duration17", "duration18", "duration19", "duration20"];
6
- var scrollOffset = edsanimate_options.offset;
7
-
8
- $('.eds-animation-paused').removeClass('eds-animation-paused');
9
-
10
  $('.eds-on-scroll').each(function(){
11
  var $module = $(this);
12
 
@@ -99,7 +97,7 @@
99
  }
100
  );
101
 
102
- });
103
 
104
 
105
  });
3
  var animationStyleClasses = ["animated","infinite", "bounce", "flash", "pulse", "rubberBand", "shake", "swing", "tada", "wobble", "bounceIn", "bounceInDown", "bounceInLeft", "bounceInRight", "bounceInUp", "bounceOut", "bounceOutDown", "bounceOutLeft", "bounceOutRight", "bounceOutUp", "fadeIn", "fadeInDown", "fadeInDownBig", "fadeInLeft", "fadeInLeftBig", "fadeInRight", "fadeInRightBig", "fadeInUp", "fadeInUpBig", "fadeOut", "fadeOutDown", "fadeOutDownBig", "fadeOutLeft", "fadeOutLeftBig", "fadeOutRight", "fadeOutRightBig", "fadeOutUp", "fadeOutUpBig", "flip", "flipInX", "flipInY", "flipOutX", "flipOutY", "lightSpeedIn", "lightSpeedOut", "rotateIn", "rotateInDownLeft", "rotateInDownRight", "rotateInUpLeft", "rotateInUpRight", "rotateOut", "rotateOutDownLeft", "rotateOutDownRight", "rotateOutUpLeft", "rotateOutUpRight", "hinge", "rollIn", "rollOut", "zoomIn", "zoomInDown", "zoomInLeft", "zoomInRight", "zoomInUp", "zoomOut", "zoomOutDown", "zoomOutLeft", "zoomOutRight", "zoomOutUp"];
4
  var delayClasses = ["delay1", "delay2", "delay3", "delay4", "delay5", "delay6", "delay7", "delay8", "delay9", "delay10", "delay11", "delay12"];
5
  var durationClasses = ["duration1", "duration2", "duration3", "duration4", "duration5", "duration6", "duration7", "duration8", "duration9", "duration10", "duration11", "duration12", "duration13", "duration14", "duration15", "duration16", "duration17", "duration18", "duration19", "duration20"];
6
+ var scrollOffset = edsanimate_options.offset;
7
+
 
 
8
  $('.eds-on-scroll').each(function(){
9
  var $module = $(this);
10
 
97
  }
98
  );
99
 
100
+ });
101
 
102
 
103
  });
assets/js/edsanimate.site.js CHANGED
@@ -1,5 +1,13 @@
1
  ( function( $, document, window){
2
 
 
 
 
 
 
 
 
 
3
  var edsWObj = $(window);
4
  $.fn.initEDSAnimateBlock = function() {
5
 
@@ -107,12 +115,13 @@
107
  if( "load" == this.data('edsAnimateOn') ) {
108
  this.edsInit();
109
  } else if( "scroll" == this.data('edsAnimateOn') ) {
 
110
  this.edsScrollOffset = this.data('edsScrollOffset');
111
  edsWObj.on("scroll", $.throttle( 250, this.checkPosition ) );
112
  this.checkPosition();
113
 
114
  } else if( "hover" == this.data('edsAnimateOn') ) {
115
- this.on("mouseenter", function (){
116
  if( !obj.edsElemAnimating ){
117
  obj.animo("cleanse");
118
  obj.edsElemAnimating = true;
@@ -140,9 +149,6 @@
140
  ( '1' == edsanimate_options.hide_vl_scrollbar ) ? $('body').css('overflow-y', 'hidden'): '';
141
  }
142
  }
143
-
144
- $('.eds-animation-paused').removeClass('eds-animation-paused');
145
-
146
  $('.eds-animate').each( function(){
147
  $(this).initEDSAnimateBlock();
148
  });
1
  ( function( $, document, window){
2
 
3
+ var inAnimations = ["bounceIn","bounceInDown","bounceInLeft","bounceInRight",
4
+ "bounceInUp","fadeIn","fadeInDown","fadeInDownBig","fadeInLeft",
5
+ "fadeInLeftBig","fadeInRight","fadeInRightBig","fadeInUp","fadeInUpBig",
6
+ "rotateIn","rotateInDownLeft","rotateInDownRight","rotateInUpLeft",
7
+ "rotateInUpRight","slideInUp","slideInDown","slideInLeft","slideInRight",
8
+ "zoomIn","zoomInDown","zoomInLeft","zoomInRight","zoomInUp","flipInX",
9
+ "flipInY","lightSpeedIn","rollIn"];
10
+
11
  var edsWObj = $(window);
12
  $.fn.initEDSAnimateBlock = function() {
13
 
115
  if( "load" == this.data('edsAnimateOn') ) {
116
  this.edsInit();
117
  } else if( "scroll" == this.data('edsAnimateOn') ) {
118
+ ( inAnimations.indexOf( this.data('edsEntryAnimation') ) != -1 ) ? this.addClass( 'edsanimate-sis-hidden' ) : '';
119
  this.edsScrollOffset = this.data('edsScrollOffset');
120
  edsWObj.on("scroll", $.throttle( 250, this.checkPosition ) );
121
  this.checkPosition();
122
 
123
  } else if( "hover" == this.data('edsAnimateOn') ) {
124
+ this.on("hover", function (){
125
  if( !obj.edsElemAnimating ){
126
  obj.animo("cleanse");
127
  obj.edsElemAnimating = true;
149
  ( '1' == edsanimate_options.hide_vl_scrollbar ) ? $('body').css('overflow-y', 'hidden'): '';
150
  }
151
  }
 
 
 
152
  $('.eds-animate').each( function(){
153
  $(this).initEDSAnimateBlock();
154
  });
edsanimate.php CHANGED
@@ -1,11 +1,9 @@
1
  <?php
2
  /**
3
  * Plugin Name: Animate It!
4
- * Text Domain: eds-animate
5
- * Domain Path: /lang
6
  * Plugin URI: http://www.eleopard.in
7
- * Description: Add cool CSS3 animations to your content.
8
- * Version: 2.1.5
9
  * Author: eLEOPARD Design Studios
10
  * Author URI: http://www.eleopard.in
11
  * License: GNU General Public License version 2 or later; see LICENSE.txt
@@ -36,14 +34,6 @@ class EDS_Animate {
36
 
37
  public static $abs_file = null;
38
 
39
- var $in_animations = array("bounceIn","bounceInDown","bounceInLeft","bounceInRight",
40
- "bounceInUp","fadeIn","fadeInDown","fadeInDownBig","fadeInLeft",
41
- "fadeInLeftBig","fadeInRight","fadeInRightBig","fadeInUp","fadeInUpBig",
42
- "rotateIn","rotateInDownLeft","rotateInDownRight","rotateInUpLeft",
43
- "rotateInUpRight","slideInUp","slideInDown","slideInLeft","slideInRight",
44
- "zoomIn","zoomInDown","zoomInLeft","zoomInRight","zoomInUp","flipInX",
45
- "flipInY","lightSpeedIn","rollIn");
46
-
47
  public function __construct( $file_loc ) {
48
 
49
  self::$abs_file = $file_loc;
@@ -52,11 +42,8 @@ class EDS_Animate {
52
 
53
  register_activation_hook( self::$abs_file, array( $this, 'set_edsanimate_options' ) );
54
 
55
- /*Load Text Domain for translation */
56
- add_action('plugins_loaded', array($this, 'plugin_textdomain'));
57
-
58
  /*checking for version updates*/
59
- add_action( 'plugins_loaded', array( $this, 'update_plugin' ) );
60
 
61
  /* Adding Settings Menu */
62
  add_action('admin_menu', array( $this, 'modify_menu' ) );
@@ -89,14 +76,10 @@ class EDS_Animate {
89
 
90
  }
91
 
92
- function plugin_textdomain() {
93
- load_plugin_textdomain('eds-animate', false, dirname( plugin_basename( self::$abs_file ) ) . '/lang');
94
- }
95
-
96
  function modify_menu(){
97
 
98
- add_options_page( __( 'Animate It! Options', 'eds-animate' )
99
- , __( 'Animate It!', 'eds-animate' )
100
  , 'manage_options'
101
  , self::$abs_file
102
  , array( $this, 'admin_edsanimate_options' ) );
@@ -162,7 +145,7 @@ class EDS_Animate {
162
 
163
  function admin_edsanimate_options(){
164
  ?>
165
- <div class="wrap"><h2><?php _e( 'Animate It! Options', 'eds-animate' ); ?></h2></div>
166
  <?php
167
  if(isset($_REQUEST['submit'])){
168
  $this->update_edsanimate_options();
@@ -189,13 +172,13 @@ class EDS_Animate {
189
 
190
  if($ok){?>
191
  <div id="message" class="updated fade">
192
- <p><?php _e( 'Options saved.', 'eds-animate' ); ?></p>
193
  </div>
194
  <?php
195
 
196
  }else{?>
197
  <div id="message" class="error fade">
198
- <p><?php _e( 'Failed to save options.', 'eds-animate' ); ?></p>
199
  </div>
200
  <?php
201
  }
@@ -211,7 +194,7 @@ class EDS_Animate {
211
  <table cellspacing="10" cellpadding="10">
212
  <tr>
213
  <td style="vertical-align: top;">
214
- <label for="eds_scroll_offset"><?php _e( 'Scroll Offset (in percentage)', 'eds-animate' ); ?>:</label>
215
  </td>
216
  <td colspan="2">
217
  <input type="text" name="eds_scroll_offset" value="<?php echo get_option('eds_scroll_offset', '75'); ?>" />
@@ -220,59 +203,59 @@ class EDS_Animate {
220
  </tr>
221
  <tr>
222
  <td style="vertical-align: top;">
223
- <label for="eds_enable_on_phone"><?php _e( 'Enable on Smartphones', 'eds-animate' ); ?>:</label>
224
  </td>
225
  <td>
226
  <select name="eds_enable_on_phone">
227
- <option value="1" <?php echo (get_option('eds_enable_on_phone')=='1')?'selected="selected"':'';?>><?php _e( 'Yes', 'eds-animate' ); ?></option>
228
- <option value="0" <?php echo (get_option('eds_enable_on_phone')=='0')?'selected="selected"':'';?>><?php _e( 'No', 'eds-animate' ); ?></option>
229
  </select>
230
  </td>
231
  </tr>
232
  <tr>
233
  <td style="vertical-align: top;">
234
- <label for="eds_enable_on_tab"><?php _e( 'Enable on Tablets', 'eds-animate' ); ?>:</label>
235
  </td>
236
  <td>
237
  <select name="eds_enable_on_tab">
238
- <option value="1" <?php echo (get_option('eds_enable_on_tab')=='1')?'selected="selected"':'';?>><?php _e( 'Yes', 'eds-animate' ); ?></option>
239
- <option value="0" <?php echo (get_option('eds_enable_on_tab')=='0')?'selected="selected"':'';?>><?php _e( 'No', 'eds-animate' ); ?></option>
240
  </select>
241
  </td>
242
  </tr>
243
  <tr>
244
  <td style="vertical-align: top;">
245
- <label for="eds_hide_overflow_x"><?php _e( 'Hide Horizontal Scrollbar', 'eds-animate' ); ?>:</label>
246
  </td>
247
  <td>
248
  <select name="eds_hide_overflow_x">
249
- <option value="1" <?php echo (get_option('eds_hide_overflow_x')=='1')?'selected="selected"':'';?>><?php _e( 'Yes', 'eds-animate' ); ?></option>
250
- <option value="0" <?php echo (get_option('eds_hide_overflow_x')=='0')?'selected="selected"':'';?>><?php _e( 'No', 'eds-animate' ); ?></option>
251
  </select>
252
  </td>
253
  </tr>
254
  <tr>
255
  <td style="vertical-align: top;">
256
- <label for="eds_hide_overflow_y"><?php _e( 'Hide Vertical Scrollbar', 'eds-animate' ); ?>:</label>
257
  </td>
258
  <td>
259
  <select name="eds_hide_overflow_y">
260
- <option value="1" <?php echo (get_option('eds_hide_overflow_y')=='1')?'selected="selected"':'';?>><?php _e( 'Yes', 'eds-animate' ); ?></option>
261
- <option value="0" <?php echo (get_option('eds_hide_overflow_y')=='0')?'selected="selected"':'';?>><?php _e( 'No', 'eds-animate' ); ?></option>
262
  </select>
263
  </td>
264
  </tr>
265
  <tr>
266
  <td style="vertical-align: top;">
267
- <label for="eds_custom_css"><?php _e( 'Custom CSS', 'eds-animate' ); ?>:</label>
268
  </td>
269
  <td>
270
- <textarea name="eds_custom_css" id="eds_custom_css" cols="25" rows="10"><?php echo get_option('eds_custom_css'); ?></textarea>
271
  </td>
272
  </tr>
273
  <tr>
274
  <td colspan="2">
275
- <input class="button button-primary" type="submit" name="submit" value="<?php _e( 'Submit', 'eds-animate' ); ?>" />
276
  </td>
277
  </tr>
278
  </table>
@@ -387,8 +370,6 @@ class EDS_Animate {
387
 
388
  if($duration!= '' && is_int((int)$duration) && $duration>=0) {
389
  $classString .= " duration" . $duration;
390
- } else {
391
- $classString .= " duration2";
392
  }
393
 
394
  if(strcasecmp($animate_on, 'scroll')==0) {
@@ -428,17 +409,11 @@ class EDS_Animate {
428
 
429
  if( !$enable ) {
430
  return '';
431
- }
432
-
433
- $hide_on_load_css_class = '';
434
- $entry_animation = isset( $attributes['entry_animation_type'] ) ? $attributes['entry_animation_type']: '';
435
-
436
- if( 'scroll' == $attributes['animate_on'] || 'load' == $attributes['animate_on'] ) {
437
- $hide_on_load_css_class = ( in_array( $entry_animation, $this->in_animations ) ) ? 'edsanimate-sis-hidden' : '';
438
- }
439
  $content = array(
440
- '<div class="eds-animate ', $hide_on_load_css_class, ' ', isset( $attributes['custom_css_class'] ) ? $attributes['custom_css_class'] : '', '"',
441
- ' data-eds-entry-animation="', $entry_animation, '"',
442
  ' data-eds-entry-delay="', isset( $attributes['entry_delay'] ) ? $attributes['entry_delay'] : '', '"',
443
  ' data-eds-entry-duration="', isset( $attributes['entry_duration'] ) ? $attributes['entry_duration'] : '', '"',
444
  ' data-eds-entry-timing="', isset( $attributes['entry_timing'] ) ? $attributes['entry_timing'] : '', '"',
@@ -481,7 +456,7 @@ class EDS_Animate {
481
  $instance['eds_animation_class'] = null;
482
  ?>
483
  <p>
484
- <label for="<?php echo $t->get_field_id('eds_animation_class'); ?>"><?php _e( 'Animate It Classes', 'eds-animate' ); ?></label>
485
  <input type="text" name="<?php echo $t->get_field_name('eds_animation_class'); ?>" id="<?php echo $t->get_field_id('eds_animation_class'); ?>" value="<?php echo $instance['eds_animation_class'];?>" />
486
  </p>
487
  <?php
@@ -516,6 +491,6 @@ if( !defined( 'WPINC' ) ) {
516
 
517
  global $eds_animate_it_version;
518
 
519
- $eds_animate_it_version = '2.1.0';
520
 
521
  new EDS_Animate( __FILE__ );
1
  <?php
2
  /**
3
  * Plugin Name: Animate It!
 
 
4
  * Plugin URI: http://www.eleopard.in
5
+ * Description: It will allow user to add CSS Animations
6
+ * Version: 2.0.0
7
  * Author: eLEOPARD Design Studios
8
  * Author URI: http://www.eleopard.in
9
  * License: GNU General Public License version 2 or later; see LICENSE.txt
34
 
35
  public static $abs_file = null;
36
 
 
 
 
 
 
 
 
 
37
  public function __construct( $file_loc ) {
38
 
39
  self::$abs_file = $file_loc;
42
 
43
  register_activation_hook( self::$abs_file, array( $this, 'set_edsanimate_options' ) );
44
 
 
 
 
45
  /*checking for version updates*/
46
+ add_action( 'plugins_loaded', array( $this, 'update_plugin' ) );
47
 
48
  /* Adding Settings Menu */
49
  add_action('admin_menu', array( $this, 'modify_menu' ) );
76
 
77
  }
78
 
 
 
 
 
79
  function modify_menu(){
80
 
81
+ add_options_page('Animate It! Options'
82
+ , 'Animate It!'
83
  , 'manage_options'
84
  , self::$abs_file
85
  , array( $this, 'admin_edsanimate_options' ) );
145
 
146
  function admin_edsanimate_options(){
147
  ?>
148
+ <div class="wrap"><h2>Animate It! Options</h2></div>
149
  <?php
150
  if(isset($_REQUEST['submit'])){
151
  $this->update_edsanimate_options();
172
 
173
  if($ok){?>
174
  <div id="message" class="updated fade">
175
+ <p>Options saved.</p>
176
  </div>
177
  <?php
178
 
179
  }else{?>
180
  <div id="message" class="error fade">
181
+ <p>Failed to save options.</p>
182
  </div>
183
  <?php
184
  }
194
  <table cellspacing="10" cellpadding="10">
195
  <tr>
196
  <td style="vertical-align: top;">
197
+ <label for="eds_scroll_offset">Scroll Offset (in percentage):</label>
198
  </td>
199
  <td colspan="2">
200
  <input type="text" name="eds_scroll_offset" value="<?php echo get_option('eds_scroll_offset', '75'); ?>" />
203
  </tr>
204
  <tr>
205
  <td style="vertical-align: top;">
206
+ <label for="eds_enable_on_phone">Enable on Smartphones:</label>
207
  </td>
208
  <td>
209
  <select name="eds_enable_on_phone">
210
+ <option value="1" <?php echo (get_option('eds_enable_on_phone')=='1')?'selected="selected"':'';?>>Yes</option>
211
+ <option value="0" <?php echo (get_option('eds_enable_on_phone')=='0')?'selected="selected"':'';?>>No</option>
212
  </select>
213
  </td>
214
  </tr>
215
  <tr>
216
  <td style="vertical-align: top;">
217
+ <label for="eds_enable_on_tab">Enable on Tablets:</label>
218
  </td>
219
  <td>
220
  <select name="eds_enable_on_tab">
221
+ <option value="1" <?php echo (get_option('eds_enable_on_tab')=='1')?'selected="selected"':'';?>>Yes</option>
222
+ <option value="0" <?php echo (get_option('eds_enable_on_tab')=='0')?'selected="selected"':'';?>>No</option>
223
  </select>
224
  </td>
225
  </tr>
226
  <tr>
227
  <td style="vertical-align: top;">
228
+ <label for="eds_hide_overflow_x">Hide Horizontal Scrollbar:</label>
229
  </td>
230
  <td>
231
  <select name="eds_hide_overflow_x">
232
+ <option value="1" <?php echo (get_option('eds_hide_overflow_x')=='1')?'selected="selected"':'';?>>Yes</option>
233
+ <option value="0" <?php echo (get_option('eds_hide_overflow_x')=='0')?'selected="selected"':'';?>>No</option>
234
  </select>
235
  </td>
236
  </tr>
237
  <tr>
238
  <td style="vertical-align: top;">
239
+ <label for="eds_hide_overflow_y">Hide Vertical Scrollbar:</label>
240
  </td>
241
  <td>
242
  <select name="eds_hide_overflow_y">
243
+ <option value="1" <?php echo (get_option('eds_hide_overflow_y')=='1')?'selected="selected"':'';?>>Yes</option>
244
+ <option value="0" <?php echo (get_option('eds_hide_overflow_y')=='0')?'selected="selected"':'';?>>No</option>
245
  </select>
246
  </td>
247
  </tr>
248
  <tr>
249
  <td style="vertical-align: top;">
250
+ <label for="eds_custom_css">Custom CSS:</label>
251
  </td>
252
  <td>
253
+ <textarea name="eds_custom_css" id="eds_custom_css" cols="25" rows="10"><?php echo get_option('eds_custom_css');?></textarea>
254
  </td>
255
  </tr>
256
  <tr>
257
  <td colspan="2">
258
+ <input class="button button-primary" type="submit" name="submit" value="Submit" />
259
  </td>
260
  </tr>
261
  </table>
370
 
371
  if($duration!= '' && is_int((int)$duration) && $duration>=0) {
372
  $classString .= " duration" . $duration;
 
 
373
  }
374
 
375
  if(strcasecmp($animate_on, 'scroll')==0) {
409
 
410
  if( !$enable ) {
411
  return '';
412
+ }
413
+
 
 
 
 
 
 
414
  $content = array(
415
+ '<div class="eds-animate ', isset( $attributes['custom_css_class'] ) ? $attributes['custom_css_class'] : '', '"',
416
+ ' data-eds-entry-animation="', isset( $attributes['entry_animation_type'] ) ? $attributes['entry_animation_type']: '', '"',
417
  ' data-eds-entry-delay="', isset( $attributes['entry_delay'] ) ? $attributes['entry_delay'] : '', '"',
418
  ' data-eds-entry-duration="', isset( $attributes['entry_duration'] ) ? $attributes['entry_duration'] : '', '"',
419
  ' data-eds-entry-timing="', isset( $attributes['entry_timing'] ) ? $attributes['entry_timing'] : '', '"',
456
  $instance['eds_animation_class'] = null;
457
  ?>
458
  <p>
459
+ <label for="<?php echo $t->get_field_id('eds_animation_class'); ?>">Animate It Classes</label>
460
  <input type="text" name="<?php echo $t->get_field_name('eds_animation_class'); ?>" id="<?php echo $t->get_field_id('eds_animation_class'); ?>" value="<?php echo $instance['eds_animation_class'];?>" />
461
  </p>
462
  <?php
491
 
492
  global $eds_animate_it_version;
493
 
494
+ $eds_animate_it_version = '2.0.0';
495
 
496
  new EDS_Animate( __FILE__ );
lang/eds-animate-en_GB.mo DELETED
Binary file
lang/eds-animate-en_GB.po DELETED
@@ -1,149 +0,0 @@
1
- msgid ""
2
- msgstr ""
3
- "Project-Id-Version: Animate It! 2.0.4\n"
4
- "POT-Creation-Date: 2016-04-09 12:47+0530\n"
5
- "PO-Revision-Date: 2016-04-09 12:48+0530\n"
6
- "Last-Translator: \n"
7
- "Language-Team: Eleopard Design Studios <contact@eleopard.in>\n"
8
- "Language: en_GB\n"
9
- "MIME-Version: 1.0\n"
10
- "Content-Type: text/plain; charset=UTF-8\n"
11
- "Content-Transfer-Encoding: 8bit\n"
12
- "X-Generator: Poedit 1.8.4\n"
13
- "X-Poedit-Basepath: ..\n"
14
- "Plural-Forms: nplurals=2; plural=(n != 1);\n"
15
- "X-Poedit-SourceCharset: UTF-8\n"
16
- "X-Poedit-KeywordsList: _e;__\n"
17
- "X-Poedit-SearchPath-0: .\n"
18
-
19
- #: assets/helper/edsanimate-tinymce-popup.php:8
20
- msgid "Select your Animation Style"
21
- msgstr "Select your Animation Style"
22
-
23
- #: assets/helper/edsanimate-tinymce-popup.php:30
24
- msgid "Entry"
25
- msgstr "Entry"
26
-
27
- #: assets/helper/edsanimate-tinymce-popup.php:33
28
- msgid "Exit"
29
- msgstr "Exit"
30
-
31
- #: assets/helper/edsanimate-tinymce-popup.php:36
32
- msgid "Options"
33
- msgstr "Options"
34
-
35
- #: assets/helper/edsanimate-tinymce-popup.php:42
36
- #: assets/helper/edsanimate-tinymce-popup.php:199
37
- msgid "Animation"
38
- msgstr "Animation"
39
-
40
- #: assets/helper/edsanimate-tinymce-popup.php:113
41
- #: assets/helper/edsanimate-tinymce-popup.php:270
42
- msgid "Delay (in seconds)"
43
- msgstr "Delay (in seconds)"
44
-
45
- #: assets/helper/edsanimate-tinymce-popup.php:137
46
- #: assets/helper/edsanimate-tinymce-popup.php:294
47
- msgid "Duration (in seconds)"
48
- msgstr "Duration (in seconds)"
49
-
50
- #: assets/helper/edsanimate-tinymce-popup.php:160
51
- #: assets/helper/edsanimate-tinymce-popup.php:317
52
- msgid "Timing"
53
- msgstr "Timing"
54
-
55
- #: assets/helper/edsanimate-tinymce-popup.php:356
56
- msgid "Animation Repeat"
57
- msgstr "Animation Repeat"
58
-
59
- #: assets/helper/edsanimate-tinymce-popup.php:371
60
- msgid "Keep Element Final State"
61
- msgstr "Keep Element Final State"
62
-
63
- #: assets/helper/edsanimate-tinymce-popup.php:380
64
- msgid "Custom CSS Class"
65
- msgstr "Custom CSS Class"
66
-
67
- #: assets/helper/edsanimate-tinymce-popup.php:388
68
- msgid "Animate On"
69
- msgstr "Animate On"
70
-
71
- #: assets/helper/edsanimate-tinymce-popup.php:402
72
- msgid "Scroll Offset (in %)"
73
- msgstr "Scroll Offset (in %)"
74
-
75
- #: assets/helper/edsanimate-tinymce-popup.php:414
76
- msgid "Powered by"
77
- msgstr "Powered by"
78
-
79
- #: assets/helper/edsanimate-tinymce-popup.php:417
80
- msgid "Review Plugin"
81
- msgstr "Review Plugin"
82
-
83
- #: assets/helper/edsanimate-tinymce-popup.php:420
84
- msgid "Documentation"
85
- msgstr "Documentation"
86
-
87
- #: assets/helper/edsanimate-tinymce-popup.php:424
88
- msgid "Stop Animation"
89
- msgstr "Stop Animation"
90
-
91
- #: assets/helper/edsanimate-tinymce-popup.php:425 edsanimate.php:99
92
- msgid "Animate It!"
93
- msgstr "Animate It!"
94
-
95
- #: assets/helper/edsanimate-tinymce-popup.php:426
96
- msgid "Insert"
97
- msgstr "Insert"
98
-
99
- #: edsanimate.php:98 edsanimate.php:165
100
- msgid "Animate It! Options"
101
- msgstr "Animate It! Options"
102
-
103
- #: edsanimate.php:192
104
- msgid "Options saved."
105
- msgstr "Options saved."
106
-
107
- #: edsanimate.php:198
108
- msgid "Failed to save options."
109
- msgstr "Failed to save options."
110
-
111
- #: edsanimate.php:214
112
- msgid "Scroll Offset (in percentage)"
113
- msgstr "Scroll Offset (in percentage)"
114
-
115
- #: edsanimate.php:223
116
- msgid "Enable on Smartphones"
117
- msgstr "Enable on Smartphones"
118
-
119
- #: edsanimate.php:227 edsanimate.php:238 edsanimate.php:249 edsanimate.php:260
120
- msgid "Yes"
121
- msgstr "Yes"
122
-
123
- #: edsanimate.php:228 edsanimate.php:239 edsanimate.php:250 edsanimate.php:261
124
- msgid "No"
125
- msgstr "No"
126
-
127
- #: edsanimate.php:234
128
- msgid "Enable on Tablets"
129
- msgstr "Enable on Tablets"
130
-
131
- #: edsanimate.php:245
132
- msgid "Hide Horizontal Scrollbar"
133
- msgstr "Hide Horizontal Scrollbar"
134
-
135
- #: edsanimate.php:256
136
- msgid "Hide Vertical Scrollbar"
137
- msgstr "Hide Vertical Scrollbar"
138
-
139
- #: edsanimate.php:267
140
- msgid "Custom CSS"
141
- msgstr "Custom CSS"
142
-
143
- #: edsanimate.php:275
144
- msgid "Submit"
145
- msgstr "Submit"
146
-
147
- #: edsanimate.php:484
148
- msgid "Animate It Classes"
149
- msgstr "Animate It Classes"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lang/eds-animate-en_US.mo DELETED
Binary file
lang/eds-animate-en_US.po DELETED
@@ -1,149 +0,0 @@
1
- msgid ""
2
- msgstr ""
3
- "Project-Id-Version: Animate It! 2.0.4\n"
4
- "POT-Creation-Date: 2016-04-09 12:33+0530\n"
5
- "PO-Revision-Date: 2016-04-09 12:33+0530\n"
6
- "Last-Translator: \n"
7
- "Language-Team: Eleopard Design Studios <contact@eleopard.in>\n"
8
- "Language: en_US\n"
9
- "MIME-Version: 1.0\n"
10
- "Content-Type: text/plain; charset=UTF-8\n"
11
- "Content-Transfer-Encoding: 8bit\n"
12
- "X-Generator: Poedit 1.8.4\n"
13
- "X-Poedit-Basepath: ..\n"
14
- "Plural-Forms: nplurals=2; plural=(n != 1);\n"
15
- "X-Poedit-SourceCharset: UTF-8\n"
16
- "X-Poedit-KeywordsList: _e;__\n"
17
- "X-Poedit-SearchPath-0: .\n"
18
-
19
- #: assets/helper/edsanimate-tinymce-popup.php:8
20
- msgid "Select your Animation Style"
21
- msgstr "Select your Animation Style"
22
-
23
- #: assets/helper/edsanimate-tinymce-popup.php:30
24
- msgid "Entry"
25
- msgstr "Entry"
26
-
27
- #: assets/helper/edsanimate-tinymce-popup.php:33
28
- msgid "Exit"
29
- msgstr "Exit"
30
-
31
- #: assets/helper/edsanimate-tinymce-popup.php:36
32
- msgid "Options"
33
- msgstr "Options"
34
-
35
- #: assets/helper/edsanimate-tinymce-popup.php:42
36
- #: assets/helper/edsanimate-tinymce-popup.php:199
37
- msgid "Animation"
38
- msgstr "Animation"
39
-
40
- #: assets/helper/edsanimate-tinymce-popup.php:113
41
- #: assets/helper/edsanimate-tinymce-popup.php:270
42
- msgid "Delay (in seconds)"
43
- msgstr "Delay (in seconds)"
44
-
45
- #: assets/helper/edsanimate-tinymce-popup.php:137
46
- #: assets/helper/edsanimate-tinymce-popup.php:294
47
- msgid "Duration (in seconds)"
48
- msgstr "Duration (in seconds)"
49
-
50
- #: assets/helper/edsanimate-tinymce-popup.php:160
51
- #: assets/helper/edsanimate-tinymce-popup.php:317
52
- msgid "Timing"
53
- msgstr "Timing"
54
-
55
- #: assets/helper/edsanimate-tinymce-popup.php:356
56
- msgid "Animation Repeat"
57
- msgstr "Animation Repeat"
58
-
59
- #: assets/helper/edsanimate-tinymce-popup.php:371
60
- msgid "Keep Element Final State"
61
- msgstr "Keep Element Final State"
62
-
63
- #: assets/helper/edsanimate-tinymce-popup.php:380
64
- msgid "Custom CSS Class"
65
- msgstr "Custom CSS Class"
66
-
67
- #: assets/helper/edsanimate-tinymce-popup.php:388
68
- msgid "Animate On"
69
- msgstr "Animate On"
70
-
71
- #: assets/helper/edsanimate-tinymce-popup.php:402
72
- msgid "Scroll Offset (in %)"
73
- msgstr "Scroll Offset (in %)"
74
-
75
- #: assets/helper/edsanimate-tinymce-popup.php:414
76
- msgid "Powered by"
77
- msgstr "Powered by"
78
-
79
- #: assets/helper/edsanimate-tinymce-popup.php:417
80
- msgid "Review Plugin"
81
- msgstr "Review Plugin"
82
-
83
- #: assets/helper/edsanimate-tinymce-popup.php:420
84
- msgid "Documentation"
85
- msgstr "Documentation"
86
-
87
- #: assets/helper/edsanimate-tinymce-popup.php:424
88
- msgid "Stop Animation"
89
- msgstr "Stop Animation"
90
-
91
- #: assets/helper/edsanimate-tinymce-popup.php:425 edsanimate.php:99
92
- msgid "Animate It!"
93
- msgstr "Animate It!"
94
-
95
- #: assets/helper/edsanimate-tinymce-popup.php:426
96
- msgid "Insert"
97
- msgstr "Insert"
98
-
99
- #: edsanimate.php:98 edsanimate.php:165
100
- msgid "Animate It! Options"
101
- msgstr "Animate It! Options"
102
-
103
- #: edsanimate.php:192
104
- msgid "Options saved."
105
- msgstr "Options saved."
106
-
107
- #: edsanimate.php:198
108
- msgid "Failed to save options."
109
- msgstr "Failed to save options."
110
-
111
- #: edsanimate.php:214
112
- msgid "Scroll Offset (in percentage)"
113
- msgstr "Scroll Offset (in percentage)"
114
-
115
- #: edsanimate.php:223
116
- msgid "Enable on Smartphones"
117
- msgstr "Enable on Smartphones"
118
-
119
- #: edsanimate.php:227 edsanimate.php:238 edsanimate.php:249 edsanimate.php:260
120
- msgid "Yes"
121
- msgstr "Yes"
122
-
123
- #: edsanimate.php:228 edsanimate.php:239 edsanimate.php:250 edsanimate.php:261
124
- msgid "No"
125
- msgstr "No"
126
-
127
- #: edsanimate.php:234
128
- msgid "Enable on Tablets"
129
- msgstr "Enable on Tablets"
130
-
131
- #: edsanimate.php:245
132
- msgid "Hide Horizontal Scrollbar"
133
- msgstr "Hide Horizontal Scrollbar"
134
-
135
- #: edsanimate.php:256
136
- msgid "Hide Vertical Scrollbar"
137
- msgstr "Hide Vertical Scrollbar"
138
-
139
- #: edsanimate.php:267
140
- msgid "Custom CSS"
141
- msgstr "Custom CSS"
142
-
143
- #: edsanimate.php:275
144
- msgid "Submit"
145
- msgstr "Submit"
146
-
147
- #: edsanimate.php:484
148
- msgid "Animate It Classes"
149
- msgstr "Animate It Classes"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
readme.txt CHANGED
@@ -2,8 +2,8 @@
2
  Contributors: eleopard
3
  Tags: css3 animation, animate.css, jquery, on scroll animation, delay, infinite, entry exit, iteration
4
  Requires at least: 3.9
5
- Tested up to: 4.5.1
6
- Stable tag: 2.1.5
7
  License: GNU General Public License version 2 or later
8
  License URI: http://www.gnu.org/copyleft/gpl.html
9
 
@@ -48,10 +48,6 @@ Alternatively:
48
  5. Set your options from the Settings -> Animate It! admin area
49
 
50
  == Frequently Asked Questions ==
51
-
52
- = Animation flicker or occur twice at load time while using animation classes? =
53
- Please add CSS class "eds-animation-paused" along with the other animation classes generated using class generator
54
-
55
  = Setting the scroll offset for on scroll functionality? =
56
  Percentage scroll offset can be set from Settings-> Animate It! menu in the admin area.
57
 
@@ -61,10 +57,10 @@ Settings to show or hide vertical or horizontal scroll bar are available at Set
61
  = Animation applied using older plugin and class generator won't work? =
62
  If animation applied using class generator or older plugin wont work, Please do the following:
63
  If using shortcode:
64
- Add duration="1" (you can add 1 to 20) as one of the attribute of the shortcode.
65
 
66
  If using class generator:
67
- Add duration class ( duration1 to duration20 ) along with the other classes. or use the class generator one more time to generate same animation classes.
68
 
69
  == Screenshots ==
70
 
@@ -81,38 +77,6 @@ Add duration class ( duration1 to duration20 ) along with the other classes. or
81
 
82
  == Changelog ==
83
 
84
- = Version 2.1.5 =
85
- * Minor bug fixes.
86
-
87
- = Version 2.1.4 =
88
- * Changes to avoid conflict with other animation scripts
89
-
90
- = Version 2.1.3 =
91
- * Minor Bug Fixes related to on scroll animation
92
-
93
- = Version 2.1.2 =
94
- * Minor Bug Fixes
95
-
96
- = Version 2.1.1 =
97
- * Minor changes to handle load time delay
98
- * Description updated
99
-
100
- = Version 2.1.0 =
101
- * Text domain added
102
- * Mobile_Detect class updated
103
-
104
- = Version 2.0.4 =
105
- * Minor fixes to support older version and classes added using class generator
106
-
107
- = Version 2.0.3 =
108
- * Minor fixes to support older version
109
-
110
- = Version 2.0.2 =
111
- * Minor fixes to support infinite animation added using older version
112
-
113
- = Version 2.0.1 =
114
- * Minor changes to handle higher load time
115
-
116
  = Version 2.0.0 =
117
  * New Feature to create Entry Exit Animation sequence
118
  * New Feature to provide custom delay and durations while generating shortcode
2
  Contributors: eleopard
3
  Tags: css3 animation, animate.css, jquery, on scroll animation, delay, infinite, entry exit, iteration
4
  Requires at least: 3.9
5
+ Tested up to: 4.4.2
6
+ Stable tag: 2.0.0
7
  License: GNU General Public License version 2 or later
8
  License URI: http://www.gnu.org/copyleft/gpl.html
9
 
48
  5. Set your options from the Settings -> Animate It! admin area
49
 
50
  == Frequently Asked Questions ==
 
 
 
 
51
  = Setting the scroll offset for on scroll functionality? =
52
  Percentage scroll offset can be set from Settings-> Animate It! menu in the admin area.
53
 
57
  = Animation applied using older plugin and class generator won't work? =
58
  If animation applied using class generator or older plugin wont work, Please do the following:
59
  If using shortcode:
60
+ Add duration="1" (you can add 1 to 12) as one of the attribute of the shortcode.
61
 
62
  If using class generator:
63
+ Add duration class ( duration1 to duration12 ) along with the other classes. or use the class generator one more time to generate same animation classes.
64
 
65
  == Screenshots ==
66
 
77
 
78
  == Changelog ==
79
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
80
  = Version 2.0.0 =
81
  * New Feature to create Entry Exit Animation sequence
82
  * New Feature to provide custom delay and durations while generating shortcode
readme.txt~ ADDED
@@ -0,0 +1,124 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ === Animate It! ===
2
+ Contributors: eleopard
3
+ Tags: css3 animation, animate.css, jquery, on scroll animation, delay, infinite, entry exit, iteration
4
+ Requires at least: 3.9
5
+ Tested up to: 4.4.2
6
+ Stable tag: 2.0.0
7
+ License: GNU General Public License version 2 or later
8
+ License URI: http://www.gnu.org/copyleft/gpl.html
9
+
10
+ Add cool CSS3 animations to your content.
11
+
12
+ == Description ==
13
+ Add cool CSS3 animations to your content.
14
+
15
+ [Demo](http://downloads.eleopard.in/animate-it-demo-wordpress/ "Demo") | [Documentation](http://downloads.eleopard.in/animate-it-documentation-wordpress/ "Documentation") | [Class Generator](http://downloads.eleopard.in/class-generator-wordpress/ "Class Generator")
16
+
17
+ [youtube https://www.youtube.com/watch?v=Np_t43pfrh4]
18
+
19
+ Some of the Key features Include:
20
+
21
+ * Allowing user to apply CSS3 animations on Post, Widget and Pages.
22
+ * 50+ Entry, Exit and Attention Seeker Animations.
23
+ * Capability to apply animation on Scroll.
24
+ * Capability to add different scroll offset on individual animation blocks.
25
+ * Capability to apply animation on Click.
26
+ * Capability to apply animation on Hover.
27
+ * Providing delay feature in animation to create a nice animation sequence.
28
+ * Providing feature to control the duration for a more precise animation.
29
+ * Providing a button in the editor to easily add an animation block in the article or post.
30
+ * Allow user to add animation on WordPress widgets. Use <a href="http://downloads.eleopard.in/class-generator-wordpress/" target="_blank">Class Generator</a> to generate the required animation classes.
31
+ * Allow user to apply animation infinitely or any fixed number of times.
32
+ * Option to add custom CSS classes to individual animation block.
33
+ * Options to enable or disable animations on Smartphones and Tablets.
34
+
35
+ All the CSS3 animations are from [Animate.css](http://daneden.github.io/animate.css/ "Animate.css") and [Animo.js](http://labs.bigroomstudios.com/libraries/animo-js "Animo.js")
36
+
37
+ == Installation ==
38
+ 1. Upload edsanimate to the /wp-content/plugins/ directory.
39
+ 2. Activate the plugin through the Plugins menu in WordPress.
40
+ 3. Set your options from the Settings -> Animate It! admin area.
41
+
42
+ Alternatively:
43
+
44
+ 1. Login to your WordPress admin area
45
+ 2. Search for Animate It!
46
+ 3. Click install Animate It!
47
+ 4. Activate through the Plugins menu in WordPress or when asked during installation
48
+ 5. Set your options from the Settings -> Animate It! admin area
49
+
50
+ == Frequently Asked Questions ==
51
+ = Setting the scroll offset for on scroll functionality? =
52
+ Percentage scroll offset can be set from Settings-> Animate It! menu in the admin area.
53
+
54
+ = Hiding horizontal and vertical scroll bar? =
55
+ Settings to show or hide vertical or horizontal scroll bar are available at Settings-> Animate It! menu in the admin area.
56
+
57
+ == Screenshots ==
58
+
59
+ 1. **Animate Button** - Add animation blocks in WordPress Post and Pages using the Animate It! button.
60
+ 2. **Select Animation** - After clicking Animate It! button you will get a screen to choose animation.
61
+ 3. **Entry Exit Animation** - Select and configure the entry and exit animations.
62
+ 4. **Other Options** - Select other options like iteration count etc.
63
+ 5. **Update Dummy Content** - Update the content of the block as per your requirement. You can copy and paste the same in Text Widget also.
64
+ 6. **Settings** - Options for Animate It! under Settings-> Animate It! menu in the admin area.
65
+ 7. **Class Generator** - Class Generator to generate required Animation Classes for Widgets.
66
+ 8. **Copy Generated Classes** - Copy the generated classes.
67
+ 9. **Apply on Widgets** - Apply the copied classes by pasting it in the 'Animate It! Classes' text box under the widget settings.
68
+
69
+
70
+ == Changelog ==
71
+
72
+ = Version 2.0.0 =
73
+ * New Feature to create Entry Exit Animation sequence
74
+ * New Feature to provide custom delay and durations while generating shortcode
75
+ * New Feature to apply timing functions
76
+ * New Feature to iterate the animation n number of times
77
+ * Code optimization for tinymce popup
78
+
79
+ = Version 1.4.4 =
80
+ * Bug fix related to the addition of animation classes on widgets
81
+
82
+ = Version 1.4.3 =
83
+ * Some spelling correction.
84
+
85
+ = Version 1.4.2 =
86
+ * New Feature that will allow user to add custom CSS for additional delay, duration etc.
87
+
88
+ = Version 1.4.1 =
89
+ * Resolved bug related to nested shortcodes.
90
+
91
+ = Version 1.4.0 =
92
+ * Resolved issue related to CSS.
93
+ * New feature that will allow user to add different scroll offset on individual animation blocks.
94
+
95
+ = Version 1.3.3 =
96
+ * Resolved issue related to nested shortcodes.
97
+
98
+ = Version 1.3.2 =
99
+ * Resolved issue related to infinite animation and on hover combination.
100
+
101
+ = Version 1.3.1 =
102
+ * Resolved issue related to widget content update and save.
103
+
104
+ = Version 1.3 =
105
+ * Capability to apply animation on Hover.
106
+ * Capability to apply animation on Click.
107
+ * Allow users to apply animation on WordPress Widgets.
108
+
109
+ = Version 1.2.1 =
110
+ * Resolved an issue related to multiple declaration of mobile_detect.php class.
111
+
112
+ = Version 1.2 =
113
+ * New options to add animation duration and infinite animation while applying an animation on WordPress Post, Page or widget.
114
+
115
+ = Version 1.1 =
116
+ * New options added under Settings-> Animate It! to enable or disable animations on Smartphones and Tablets.
117
+
118
+ = Version 1.0 =
119
+ * Initial public release.
120
+
121
+ == Upgrade Notice ==
122
+
123
+ = Version 1.0 =
124
+ * Initial public release.