Compare commits

...

27 Commits

Author SHA1 Message Date
Faisal Salman
ee51caf422 Update version to 2.0.0-rc.3 2024-11-13 17:47:44 +07:00
Faisal Salman
84c4613145 Add new device vendors: Advan, IMO, Smartfren 2024-11-12 16:07:06 +07:00
Faisal Salman
6b8920c700 Add new device vendors: Cat, Energizer, Micromax
- https://www.catphones.com
- https://www.energizeyourdevice.com
- https://micromaxinfo.com/
2024-11-11 22:16:39 +07:00
Faisal Salman
49151e478c Add new browser engine: Servo 2024-11-11 19:55:40 +07:00
Faisal Salman
cbe06acaf2 [submodule:extensions] Add email clients: Evolution, KMail, Kontact 2024-11-10 19:32:37 +07:00
Faisal Salman
a0e11b701e [submodule:extensions] Add some new bots: 360Spider, Archive.org Bots, CCBot, DataForSeoBot, DuckAssistBot, Exabot, Google Bots, Meta Bots, MojeekBot, PerplexityBot, PetalBot, TurnitinBot, Yeti, YisouSpider 2024-11-10 13:08:21 +07:00
Faisal Salman
3b3361fe53 [submodule:extensions] Breaking change: rename module to library 2024-11-10 08:16:24 +07:00
Faisal Salman
19e5d322e2 [submodule:helpers] Add an optional parameter in isAppleSilicon() that flags the use of feature detection 2024-11-09 20:53:20 +07:00
Faisal Salman
75690f16cc Merge remote-tracking branch 'origin/develop' 2024-11-09 10:50:44 +07:00
Faisal Salman
d5edcbae12 Fix #763 - Add support for Headers object 2024-11-09 10:21:36 +07:00
Aiyush
be2f167f90 Added support for honor separated from Huawei (#749)
* Added support for honor separated from Huawei

* Revert "Added support for honor separated from Huawei"

This reverts commit 28bde1c0b4.

* Added changes wrt comments

* Added another change
2024-11-09 10:20:45 +07:00
Faisal Salman
a1644b6775 Update version to 2.0.0-rc.2 2024-11-07 21:00:04 +07:00
Faisal Salman
0808d1d940 Fix #759 - Incorrect import path for ESM files in build script 2024-11-07 18:38:17 +07:00
Faisal Salman
e954f19b5c Move isFrozenUA() & isStandalonePWA() to its own npm module 2024-11-05 19:57:08 +07:00
Faisal Salman
5097b8093e [submodule:enums] Add some of Chromecast OS variants 2024-11-04 11:10:44 +07:00
Faisal Salman
2223a2b2d4 Add new browser: LibreWolf
https://librewolf.net/
2024-11-03 11:32:02 +07:00
Faisal Salman
246c038895 Improve browser detection: Maxthon 2024-11-03 11:17:30 +07:00
Faisal Salman
2dc1be1a50 Add new browser: 115 Browser
http://pc.115.com/
2024-11-03 01:35:47 +07:00
Faisal Salman
2624a92b39 Improve browser detection: 2345 & 360 2024-11-03 01:30:47 +07:00
Faisal Salman
d571859b2e Improve browser detection: Comodo Dragon, or simply Dragon 2024-11-02 20:17:50 +07:00
Faisal Salman
b7c2f541d9 Add new browsers: Slimjet & SlimBoat
https://www.slimjet.com/
2024-11-02 19:57:54 +07:00
Faisal Salman
10b81836f1 Improve browser detection: SRWare Iron 2024-11-02 18:26:35 +07:00
Faisal Salman
5a1d0319f8 Add new helper method: isBot() to detect whether current browser is a bot 2024-11-02 13:15:33 +07:00
Faisal Salman
7a754ef227 Update browser.type="inapp" for InApp browsers 2024-11-02 12:30:31 +07:00
Andreas Kogler
5948060729 Implement PlayStation app WebMAF detection (#649)
* Add support for `WebMAF` detection on Playstation

* Extend `WebMAF` support for PlayStation 5

* Update changelog
2023-08-20 14:25:56 +07:00
chenyuan-new
420bf1066c fix: remove duplicated BRANDS input when call setProps in UACHData func (#663) 2023-08-08 15:22:10 +07:00
Runar Heggset
b20d09655c Fix Amazon Fire TV device detection 2023-05-11 12:04:56 +07:00
31 changed files with 1428 additions and 293 deletions

View File

@@ -10,8 +10,6 @@ assignees: ''
**Library version** **Library version**
Which version of the library that you use, eg: v0.7.35 or v2.0.0-alpha.3 Which version of the library that you use, eg: v0.7.35 or v2.0.0-alpha.3
For the issue related with detection result, you can use the demo section in https://uaparser.dev to confirm
**Describe the bug** **Describe the bug**
A clear and concise description of what the bug is. A clear and concise description of what the bug is.
@@ -23,11 +21,13 @@ Steps to reproduce the behavior:
4. See error 4. See error
**Expected behavior** **Expected behavior**
A clear and concise description of what you expected to happen. A clear and concise description of what you expected to happen, or what's referred in the docs https://docs.uaparser.dev/
**Screenshots** **Screenshots**
If applicable, add screenshots to help explain your problem. If applicable, add screenshots to help explain your problem.
For issues related to detection results, you can send the screenshots of the demo section at https://uaparser.dev/#demo to confirm.
**Desktop (please complete the following information):** **Desktop (please complete the following information):**
- OS: [e.g. iOS] - OS: [e.g. iOS]
- Browser [e.g. chrome, safari] - Browser [e.g. chrome, safari]
@@ -40,4 +40,4 @@ If applicable, add screenshots to help explain your problem.
- Version [e.g. 22] - Version [e.g. 22]
**Additional context** **Additional context**
Add any other context about the problem here. Add any other context about the problem here.

View File

@@ -1,5 +1,57 @@
# UAParser.js Changelog # UAParser.js Changelog
# Version 2.0
## Migrating from v1 to v2
- What's breaking:
- Licensed under AGPLv3 (open-source) or PRO License (commercial)
- Browser detection on mobile device: `"Chrome" => "Mobile Chrome"`, `"Firefox" => "Mobile Firefox"`
- OS detection: `"Mac OS" => "macOS"`, `"Chromium OS" => "Chrome OS"`
- What's new:
- New device type: `xr`, to identify AR/VR devices
- New browser property: `browser.type`, to identify the type of the browser: `crawler`, `cli`, `email`, `fetcher`, `inapp`, `library`, `mediaplayer`
- New methods in result object (all of `get*()` return value):
- Enhance detection using client hints: `withClientHints()`
- Enhance detection using feature check: `withFeatureCheck()`
- Utility for easy comparison: `is()`
- Utility to print full-name: `toString()`
- Parse user-agent directly from command line using `npx ua-parser-js "[User-Agent]"`
- Extensions can be passed as a list to `UAParser()`
- Support for ES module & TypeScript `import { UAParser } from 'ua-parser-js'`
- Provided Enums submodule `'ua-parser-js/enums'`
- Provided Extensions submodule `'ua-parser-js/extensions'`
- Provided Helpers submodule `'ua-parser-js/helpers'`:
- `getDeviceVendor()`: guess for a device vendor based on its model name
- `isAppleSilicon()`: check if the device has Apple Silicon Mac device properties
- `isBot()`: check if the browser is identified as a bot
- `isChromeFamily()`: check if the browser is Chrome-based (has Blink engine, i.e: New Opera, New Edge, Vivaldi, Brave, Arc, etc.)
- `isElectron()`: check if current window is running inside Electron
- `isFromEU()`: check if current window is from an EU (European Union) country
- `isFrozenUA()`: check if a user-agent string match with the reduced/frozen user-agent pattern
- `isStandalonePWA()`: check if current window is a standalone PWA
---
## Version 2.0.0-rc.3
- Add support for Headers object
- Add new device: Advan, Cat, Energizer, Honor, IMO, Micromax, Smartfren
- Add new engine: Servo
- `ua-parser-js/extensions` submodule:
- Breaking change: rename `module` to `library`
- Add new email clients: Evolution, KMail, Kontact
- Add new bots: 360Spider, Archive.org Bots, CCBot, DataForSeoBot, DuckAssistBot, Exabot, Google Bots, Meta Bots, MojeekBot, PerplexityBot, PetalBot, TurnitinBot, Yeti, YisouSpider
## Version 2.0.0-rc.2
- Fix incorrect import path in ESM files
- Add new browser: 115, SlimBoat, Slimjet, LibreWolf
- Improve browser detection: 2345, 360, Dragon, Iron, Maxthon
- `ua-parser-js/enums` submodule:
- Add Chromecast OS variants: Android/Fuchsia/Linux/SmartSpeaker
- `ua-parser-js/helpers` submodule:
- Add new method: `isBot()` to check if the browser is identified as a bot
## Version 2.0.0-rc.1 ## Version 2.0.0-rc.1
- Fix Python Request mistakenly identified as Meta Quest - Fix Python Request mistakenly identified as Meta Quest
@@ -18,7 +70,7 @@
- Rename `isChromiumBased()` to `isChromeFamily()` - Rename `isChromiumBased()` to `isChromeFamily()`
- Update `isAppleSilicon()` to also checks for WebGL renderer info - Update `isAppleSilicon()` to also checks for WebGL renderer info
- `ua-parser-js/extensions` submodule: - `ua-parser-js/extensions` submodule:
- Restore `bots` as a compilation of all these browser types: `clis`, `crawlers`, `fetchers`, and `modules` - Restore `Bots` as a compilation of all these browser types: `cli`, `crawler`, `fetcher`, and `library`
## Version 2.0.0-beta.3 ## Version 2.0.0-beta.3
@@ -68,27 +120,6 @@
- Initial work on new major version - Initial work on new major version
## Version 2.0
- What's breaking:
- Dual-licensed under AGPLv3 or PRO License
- Browser detection on mobile device: `"Chrome" => "Mobile Chrome"`, `"Firefox" => "Mobile Firefox"`
- OS detection: `"Mac OS" => "macOS"`, `"Chromium OS" => "Chrome OS"`
- AR/VR devices moved to new device type: `xr`
- New property in `browser`: `type`
- What's new:
- Some new methods in result object:
- Support for client hints: `withClientHints()`
- Support for feature detection: `withFeatureCheck()`
- Utility for easy comparison: `is()`
- Utility to print full-name: `toString()`
- Parse directly from command line using `npx ua-parser-js`
- Extensions can be passed as a list to `UAParser()`
- Support for ES module `import { UAParser } from 'ua-parser-js'`
- Provided Enums submodule `'ua-parser-js/enums'`
- Provided Extensions submodule `'ua-parser-js/extensions'`
- Provided Helpers submodule `'ua-parser-js/helpers'`
--- ---
## Version 0.7.38 / 1.0.38 ## Version 0.7.38 / 1.0.38

View File

@@ -44,15 +44,15 @@ see what's new & breaking.
<tbody> <tbody>
<tr> <tr>
<td>License options</td> <td>License options</td>
<td>MIT (v1.x)</td> <td>MIT (v0.7~v1.0)</td>
<td>AGPL (v2.x)</td> <td>AGPL (&gt;=v2.0)</td>
<td>PRO Personal</td> <td>PRO Personal</td>
<td>PRO Business</td> <td>PRO Business</td>
<td>PRO Enterprise</td> <td>PRO Enterprise</td>
</tr> </tr>
<tr> <tr>
<td>Browser detection</td> <td>Browser detection</td>
<td><strong title="Basic detection">⚠️</strong></td> <td><a href="#demo" title="Basic detection">⚠️</a></td>
<td></td> <td></td>
<td></td> <td></td>
<td></td> <td></td>
@@ -60,7 +60,7 @@ see what's new & breaking.
</tr> </tr>
<tr> <tr>
<td>CPU detection</td> <td>CPU detection</td>
<td><strong title="Basic detection">⚠️</strong></td> <td><a href="#demo" title="Basic detection">⚠️</a></td>
<td></td> <td></td>
<td></td> <td></td>
<td></td> <td></td>
@@ -68,7 +68,7 @@ see what's new & breaking.
</tr> </tr>
<tr> <tr>
<td>Device detection</td> <td>Device detection</td>
<td><strong title="Basic detection">⚠️</strong></td> <td><a href="#demo" title="Basic detection">⚠️</a></td>
<td></td> <td></td>
<td></td> <td></td>
<td></td> <td></td>
@@ -76,7 +76,7 @@ see what's new & breaking.
</tr> </tr>
<tr> <tr>
<td>Engine detection</td> <td>Engine detection</td>
<td><strong title="Basic detection">⚠️</strong></td> <td><a href="#demo" title="Basic detection">⚠️</a></td>
<td></td> <td></td>
<td></td> <td></td>
<td></td> <td></td>
@@ -84,15 +84,31 @@ see what's new & breaking.
</tr> </tr>
<tr> <tr>
<td>OS detection</td> <td>OS detection</td>
<td><strong title="Basic detection">⚠️</strong></td> <td><a href="#demo" title="Basic detection">⚠️</a></td>
<td></td> <td></td>
<td></td> <td></td>
<td></td> <td></td>
<td></td> <td></td>
</tr> </tr>
<tr> <tr>
<td>Enhanced detection</td> <td>Bot detection</td>
<td>⛔️</td> <td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td>Extras (Apps, Libs, Emails, Media Players, etc)</td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td>Enhanced detection result</td>
<td></td>
<td></td> <td></td>
<td></td> <td></td>
<td></td> <td></td>
@@ -100,15 +116,7 @@ see what's new & breaking.
</tr> </tr>
<tr> <tr>
<td>Client Hints support</td> <td>Client Hints support</td>
<td>⛔️</td> <td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td>Extras (Apps, Bots, Libs, Emails, Media Players, etc)</td>
<td>⛔️</td>
<td></td> <td></td>
<td></td> <td></td>
<td></td> <td></td>
@@ -124,14 +132,14 @@ see what's new & breaking.
</tr> </tr>
<tr> <tr>
<td>ES modules support</td> <td>ES modules support</td>
<td>⛔️</td> <td></td>
<td></td> <td></td>
<td></td> <td></td>
<td></td> <td></td>
<td></td> <td></td>
</tr> </tr>
<tr> <tr>
<td>npm module available</td> <td>npm module</td>
<td></td> <td></td>
<td></td> <td></td>
<td></td> <td></td>
@@ -139,25 +147,25 @@ see what's new & breaking.
<td></td> <td></td>
</tr> </tr>
<tr> <tr>
<td>TypeScript declarations available</td> <td>TypeScript declarations</td>
<td><strong title="Community version">⚠️</strong></td> <td><a href="#demo" title="Community version">⚠️</a></td>
<td></td> <td></td>
<td></td> <td></td>
<td></td> <td></td>
<td></td> <td></td>
</tr> </tr>
<tr> <tr>
<td>Allowed for commercial use</td> <td>Allows commercial use</td>
<td></td> <td></td>
<td></td> <td></td>
<td>⛔️</td> <td></td>
<td></td> <td></td>
<td></td> <td></td>
</tr> </tr>
<tr> <tr>
<td>Permissive (non-copyleft) license</td> <td>Permissive (non-copyleft) license</td>
<td></td> <td></td>
<td><strong title="Copyleft license">⛔️</strong></td> <td><strong title="Copyleft license"></strong></td>
<td></td> <td></td>
<td></td> <td></td>
<td></td> <td></td>
@@ -167,13 +175,13 @@ see what's new & breaking.
<td></td> <td></td>
<td></td> <td></td>
<td></td> <td></td>
<td><strong title="1 project per 1 license">⛔️</strong></td> <td><strong title="1 project per 1 license"></strong></td>
<td></td> <td></td>
</tr> </tr>
<tr> <tr>
<td>1-year support</td> <td>1-year product support</td>
<td>⛔️</td> <td></td>
<td>⛔️</td> <td></td>
<td></td> <td></td>
<td></td> <td></td>
<td></td> <td></td>
@@ -192,13 +200,13 @@ see what's new & breaking.
<td><strong title="Pay as you want">FREE (<a target="_blank" href="https://raw.githubusercontent.com/faisalman/ua-parser-js/master/LICENSE.md">License</a>)</strong></td> <td><strong title="Pay as you want">FREE (<a target="_blank" href="https://raw.githubusercontent.com/faisalman/ua-parser-js/master/LICENSE.md">License</a>)</strong></td>
<td><strong title="$14 (one-time fee)">$14 (<a target="_blank" href="https://raw.githubusercontent.com/faisalman/ua-parser-js/pro-personal/LICENSE.md">License</a>)</strong></td> <td><strong title="$14 (one-time fee)">$14 (<a target="_blank" href="https://raw.githubusercontent.com/faisalman/ua-parser-js/pro-personal/LICENSE.md">License</a>)</strong></td>
<td><strong title="$29 (one-time fee)">$29 (<a target="_blank" href="https://raw.githubusercontent.com/faisalman/ua-parser-js/pro-business/LICENSE.md">License</a>)</strong></td> <td><strong title="$29 (one-time fee)">$29 (<a target="_blank" href="https://raw.githubusercontent.com/faisalman/ua-parser-js/pro-business/LICENSE.md">License</a>)</strong></td>
<td><strong title="$588 (one-time fee)">$588 (<a target="_blank" href="https://raw.githubusercontent.com/faisalman/ua-parser-js/pro-enterprise/LICENSE.md">License</a>)</strong></td> <td><strong title="$599 (one-time fee)">$599 (<a target="_blank" href="https://raw.githubusercontent.com/faisalman/ua-parser-js/pro-enterprise/LICENSE.md">License</a>)</strong></td>
</tr> </tr>
</tbody> </tbody>
<tfoot> <tfoot>
<tr> <tr>
<th align="right" colspan="6"> <th align="right" colspan="6">
<a target="_blank" href="https://store.faisalman.com/checkout/buy/e236ea87-9b2b-400e-9683-24367f731b35"> GET THE PRO PACKAGES 📥</a> <h3><a target="_blank" href="https://store.faisalman.com/checkout/buy/e236ea87-9b2b-400e-9683-24367f731b35"> GET THE PRO PACKAGES 📥</a></h3>
</th> </th>
</tr> </tr>
</tfoot> </tfoot>
@@ -221,4 +229,4 @@ Made with [contributors-img](https://contrib.rocks).
<a href="https://opencollective.com/ua-parser-js"><img src="https://opencollective.com/ua-parser-js/organizations.svg?avatarHeight=64"></a> <a href="https://opencollective.com/ua-parser-js"><img src="https://opencollective.com/ua-parser-js/organizations.svg?avatarHeight=64"></a>
<a href="https://opencollective.com/ua-parser-js"><img src="https://opencollective.com/ua-parser-js/individuals.svg?avatarHeight=64"></a> <a href="https://opencollective.com/ua-parser-js"><img src="https://opencollective.com/ua-parser-js/individuals.svg?avatarHeight=64"></a>
Support the open-source versions of UAParser.js on [OpenCollective](https://opencollective.com/ua-parser-js) or [GitHub Sponsors](https://github.com/sponsors/faisalman). Support the open-source editions of UAParser.js on [OpenCollective](https://opencollective.com/ua-parser-js) or [GitHub Sponsors](https://github.com/sponsors/faisalman).

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

52
package-lock.json generated
View File

@@ -1,12 +1,12 @@
{ {
"name": "ua-parser-js", "name": "ua-parser-js",
"version": "2.0.0-rc.1", "version": "2.0.0-rc.3",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "ua-parser-js", "name": "ua-parser-js",
"version": "2.0.0-rc.1", "version": "2.0.0-rc.3",
"funding": [ "funding": [
{ {
"type": "opencollective", "type": "opencollective",
@@ -23,7 +23,9 @@
], ],
"license": "AGPL-3.0-or-later", "license": "AGPL-3.0-or-later",
"dependencies": { "dependencies": {
"detect-europe-js": "^0.1.1" "detect-europe-js": "^0.1.2",
"is-standalone-pwa": "^0.1.1",
"ua-is-frozen": "^0.1.2"
}, },
"bin": { "bin": {
"ua-parser-js": "script/cli.js" "ua-parser-js": "script/cli.js"
@@ -1668,9 +1670,9 @@
"dev": true "dev": true
}, },
"node_modules/detect-europe-js": { "node_modules/detect-europe-js": {
"version": "0.1.1", "version": "0.1.2",
"resolved": "https://registry.npmjs.org/detect-europe-js/-/detect-europe-js-0.1.1.tgz", "resolved": "https://registry.npmjs.org/detect-europe-js/-/detect-europe-js-0.1.2.tgz",
"integrity": "sha512-+bUXDf+tI3L4dcEuRdAFa44Amx9aEaJzoZssx7Xis4H1bXWc5fAcOP850BOj0wJPRzOdovOuOVEvrg6T+GflZA==", "integrity": "sha512-lgdERlL3u0aUdHocoouzT10d9I89VVhk0qNRmll7mXdGfJT1/wqZ2ZLA4oJAjeACPY5fT1wsbq2AT+GkuInsow==",
"funding": [ "funding": [
{ {
"type": "github", "type": "github",
@@ -2609,6 +2611,25 @@
"node": ">=8" "node": ">=8"
} }
}, },
"node_modules/is-standalone-pwa": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/is-standalone-pwa/-/is-standalone-pwa-0.1.1.tgz",
"integrity": "sha512-9Cbovsa52vNQCjdXOzeQq5CnCbAcRk05aU62K20WO372NrTv0NxibLFCK6lQ4/iZEFdEA3p3t2VNOn8AJ53F5g==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/faisalman"
},
{
"type": "opencollective",
"url": "https://opencollective.com/ua-parser-js"
},
{
"type": "paypal",
"url": "https://paypal.me/faisalman"
}
]
},
"node_modules/isarray": { "node_modules/isarray": {
"version": "0.0.1", "version": "0.0.1",
"resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
@@ -4597,6 +4618,25 @@
"node": "*" "node": "*"
} }
}, },
"node_modules/ua-is-frozen": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/ua-is-frozen/-/ua-is-frozen-0.1.2.tgz",
"integrity": "sha512-RwKDW2p3iyWn4UbaxpP2+VxwqXh0jpvdxsYpZ5j/MLLiQOfbsV5shpgQiw93+KMYQPcteeMQ289MaAFzs3G9pw==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/faisalman"
},
{
"type": "opencollective",
"url": "https://opencollective.com/ua-parser-js"
},
{
"type": "paypal",
"url": "https://paypal.me/faisalman"
}
]
},
"node_modules/uglify-js": { "node_modules/uglify-js": {
"version": "3.12.8", "version": "3.12.8",
"resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.12.8.tgz", "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.12.8.tgz",

View File

@@ -1,7 +1,7 @@
{ {
"title": "UAParser.js", "title": "UAParser.js",
"name": "ua-parser-js", "name": "ua-parser-js",
"version": "2.0.0-rc.1", "version": "2.0.0-rc.3",
"author": "Faisal Salman <f@faisalman.com> (http://faisalman.com)", "author": "Faisal Salman <f@faisalman.com> (http://faisalman.com)",
"description": "Detect Browser, Engine, OS, CPU, and Device type/model from User-Agent & Client Hints data. Supports browser & node.js environment", "description": "Detect Browser, Engine, OS, CPU, and Device type/model from User-Agent & Client Hints data. Supports browser & node.js environment",
"keywords": [ "keywords": [
@@ -211,7 +211,9 @@
"test:playwright": "playwright test" "test:playwright": "playwright test"
}, },
"dependencies": { "dependencies": {
"detect-europe-js": "^0.1.1" "detect-europe-js": "^0.1.2",
"is-standalone-pwa": "^0.1.1",
"ua-is-frozen": "^0.1.2"
}, },
"devDependencies": { "devDependencies": {
"@babel/parser": "7.15.8", "@babel/parser": "7.15.8",

View File

@@ -7,7 +7,7 @@ const generateMJS = (module) => {
let text = fs.readFileSync(src, 'utf-8'); let text = fs.readFileSync(src, 'utf-8');
replacements.push( replacements.push(
[/const (.+?)\s*=\s*require\(\'\.(.+)\'\)/ig, 'import $1 from \'$2.mjs\''], [/const (.+?)\s*=\s*require\(\'\.(.+)\'\)/ig, 'import $1 from \'\.$2.mjs\''],
[/const (.+?)\s*=\s*require\(\'(.+)\'\)/ig, 'import $1 from \'$2\''], [/const (.+?)\s*=\s*require\(\'(.+)\'\)/ig, 'import $1 from \'$2\''],
[/module\.exports =/ig, 'export'] [/module\.exports =/ig, 'export']
); );

View File

@@ -1,5 +1,5 @@
/////////////////////////////////////////////// ///////////////////////////////////////////////
/* Enums for UAParser.js v2.0.0-rc.1 /* Enums for UAParser.js v2.0.0-rc.3
https://github.com/faisalman/ua-parser-js https://github.com/faisalman/ua-parser-js
Author: Faisal Salman <f@faisalman.com> Author: Faisal Salman <f@faisalman.com>
AGPLv3 License */ AGPLv3 License */
@@ -8,8 +8,9 @@
/*jshint esversion: 6 */ /*jshint esversion: 6 */
const Browser = Object.freeze({ const Browser = Object.freeze({
'2345_EXPLORER': '2345Explorer', '115': '115',
'360': '360 Browser', '2345': '2345',
'360': '360',
ALIPAY: 'Alipay', ALIPAY: 'Alipay',
AMAYA: 'Amaya', AMAYA: 'Amaya',
ANDROID: 'Android Browser', ANDROID: 'Android Browser',
@@ -32,11 +33,11 @@ const Browser = Object.freeze({
CHROMIUM: 'Chromium', CHROMIUM: 'Chromium',
COBALT: 'Cobalt', COBALT: 'Cobalt',
COC_COC: 'Coc Coc', COC_COC: 'Coc Coc',
COMODO_DRAGON: 'Comodo Dragon',
CONKEROR: 'Conkeror', CONKEROR: 'Conkeror',
DILLO: 'Dillo', DILLO: 'Dillo',
DOLPHIN: 'Dolphin', DOLPHIN: 'Dolphin',
DORIS: 'Doris', DORIS: 'Doris',
DRAGON: 'Dragon',
DUCKDUCKGO: 'DuckDuckGo', DUCKDUCKGO: 'DuckDuckGo',
EDGE: 'Edge', EDGE: 'Edge',
EPIPHANY: 'Epiphany', EPIPHANY: 'Epiphany',
@@ -54,6 +55,7 @@ const Browser = Object.freeze({
GOOGLE_SEARCH: 'GSA', GOOGLE_SEARCH: 'GSA',
HELIO: 'Helio', HELIO: 'Helio',
HEYTAP: 'HeyTap', HEYTAP: 'HeyTap',
HONOR: 'Honor',
HUAWEI: 'Huawei Browser', HUAWEI: 'Huawei Browser',
ICAB: 'iCab', ICAB: 'iCab',
ICE: 'ICE Browser', ICE: 'ICE Browser',
@@ -74,6 +76,7 @@ const Browser = Object.freeze({
KLARNA: 'Klarna', KLARNA: 'Klarna',
KINDLE: 'Kindle', KINDLE: 'Kindle',
LENOVO: 'Smart Lenovo Browser', LENOVO: 'Smart Lenovo Browser',
LIBREWOLF: 'LibreWolf',
LIEBAO: 'LBBROWSER', LIEBAO: 'LBBROWSER',
LINE: 'Line', LINE: 'Line',
LINKEDIN: 'LinkedIn', LINKEDIN: 'LinkedIn',
@@ -122,7 +125,9 @@ const Browser = Object.freeze({
SILK: 'Silk', SILK: 'Silk',
SKYFIRE: 'Skyfire', SKYFIRE: 'Skyfire',
SLEIPNIR: 'Sleipnir', SLEIPNIR: 'Sleipnir',
SLIMBOAT: 'SlimBoat',
SLIMBROWSER: 'SlimBrowser', SLIMBROWSER: 'SlimBrowser',
SLIMJET: 'Slimjet',
SNAPCHAT: 'Snapchat', SNAPCHAT: 'Snapchat',
SOGOU_EXPLORER: 'Sogou Explorer', SOGOU_EXPLORER: 'Sogou Explorer',
SOGOU_MOBILE: 'Sogou Mobile', SOGOU_MOBILE: 'Sogou Mobile',
@@ -154,7 +159,7 @@ const BrowserType = Object.freeze({
FETCHER: 'fetcher', FETCHER: 'fetcher',
INAPP: 'inapp', INAPP: 'inapp',
MEDIAPLAYER: 'mediaplayer', MEDIAPLAYER: 'mediaplayer',
MODULE: 'module' LIBRARY: 'library'
}); });
const CPU = Object.freeze({ const CPU = Object.freeze({
@@ -190,6 +195,7 @@ const Device = Object.freeze({
const Vendor = Object.freeze({ const Vendor = Object.freeze({
ACER: 'Acer', ACER: 'Acer',
ADVAN: 'Advan',
ALCATEL: 'Alcatel', ALCATEL: 'Alcatel',
APPLE: 'Apple', APPLE: 'Apple',
AMAZON: 'Amazon', AMAZON: 'Amazon',
@@ -198,7 +204,9 @@ const Vendor = Object.freeze({
ATT: 'AT&T', ATT: 'AT&T',
BENQ: 'BenQ', BENQ: 'BenQ',
BLACKBERRY: 'BlackBerry', BLACKBERRY: 'BlackBerry',
CAT: 'Cat',
DELL: 'Dell', DELL: 'Dell',
ENERGIZER: 'Energizer',
ESSENTIAL: 'Essential', ESSENTIAL: 'Essential',
FACEBOOK: 'Facebook', FACEBOOK: 'Facebook',
FAIRPHONE: 'Fairphone', FAIRPHONE: 'Fairphone',
@@ -208,6 +216,7 @@ const Vendor = Object.freeze({
HP: 'HP', HP: 'HP',
HTC: 'HTC', HTC: 'HTC',
HUAWEI: 'Huawei', HUAWEI: 'Huawei',
IMO: 'IMO',
INFINIX: 'Infinix', INFINIX: 'Infinix',
ITEL: 'itel', ITEL: 'itel',
JOLLA: 'Jolla', JOLLA: 'Jolla',
@@ -215,6 +224,7 @@ const Vendor = Object.freeze({
LENOVO: 'Lenovo', LENOVO: 'Lenovo',
LG: 'LG', LG: 'LG',
MEIZU: 'Meizu', MEIZU: 'Meizu',
MICROMAX: 'Micromax',
MICROSOFT: 'Microsoft', MICROSOFT: 'Microsoft',
MOTOROLA: 'Motorola', MOTOROLA: 'Motorola',
NEXIAN: 'Nexian', NEXIAN: 'Nexian',
@@ -236,6 +246,7 @@ const Vendor = Object.freeze({
SAMSUNG: 'Samsung', SAMSUNG: 'Samsung',
SHARP: 'Sharp', SHARP: 'Sharp',
SIEMENS: 'Siemens', SIEMENS: 'Siemens',
SMARTFREN: 'Smartfren',
SONY: 'Sony', SONY: 'Sony',
SPRINT: 'Sprint', SPRINT: 'Sprint',
TCL: 'TCL', TCL: 'TCL',
@@ -269,6 +280,7 @@ const Engine = Object.freeze({
NETFRONT: 'NetFront', NETFRONT: 'NetFront',
NETSURF: 'NetSurf', NETSURF: 'NetSurf',
PRESTO: 'Presto', PRESTO: 'Presto',
SERVO: 'Servo',
TASMAN: 'Tasman', TASMAN: 'Tasman',
TRIDENT: 'Trident', TRIDENT: 'Trident',
W3M: 'w3m', W3M: 'w3m',
@@ -287,6 +299,10 @@ const OS = Object.freeze({
CENTOS: 'CentOS', CENTOS: 'CentOS',
CHROME_OS: 'Chrome OS', CHROME_OS: 'Chrome OS',
CHROMECAST: 'Chromecast', CHROMECAST: 'Chromecast',
CHROMECAST_ANDROID: 'Chromecast Android',
CHROMECAST_FUCHSIA: 'Chromecast Fuchsia',
CHROMECAST_LINUX: 'Chromecast Linux',
CHROMECAST_SMARTSPEAKER: 'Chromecast SmartSpeaker',
CONTIKI: 'Contiki', CONTIKI: 'Contiki',
DEBIAN: 'Debian', DEBIAN: 'Debian',
DEEPIN: 'Deepin', DEEPIN: 'Deepin',

View File

@@ -3,7 +3,7 @@
// Source: /src/enums/ua-parser-enums.js // Source: /src/enums/ua-parser-enums.js
/////////////////////////////////////////////// ///////////////////////////////////////////////
/* Enums for UAParser.js v2.0.0-rc.1 /* Enums for UAParser.js v2.0.0-rc.3
https://github.com/faisalman/ua-parser-js https://github.com/faisalman/ua-parser-js
Author: Faisal Salman <f@faisalman.com> Author: Faisal Salman <f@faisalman.com>
AGPLv3 License */ AGPLv3 License */
@@ -12,8 +12,9 @@
/*jshint esversion: 6 */ /*jshint esversion: 6 */
const Browser = Object.freeze({ const Browser = Object.freeze({
'2345_EXPLORER': '2345Explorer', '115': '115',
'360': '360 Browser', '2345': '2345',
'360': '360',
ALIPAY: 'Alipay', ALIPAY: 'Alipay',
AMAYA: 'Amaya', AMAYA: 'Amaya',
ANDROID: 'Android Browser', ANDROID: 'Android Browser',
@@ -36,11 +37,11 @@ const Browser = Object.freeze({
CHROMIUM: 'Chromium', CHROMIUM: 'Chromium',
COBALT: 'Cobalt', COBALT: 'Cobalt',
COC_COC: 'Coc Coc', COC_COC: 'Coc Coc',
COMODO_DRAGON: 'Comodo Dragon',
CONKEROR: 'Conkeror', CONKEROR: 'Conkeror',
DILLO: 'Dillo', DILLO: 'Dillo',
DOLPHIN: 'Dolphin', DOLPHIN: 'Dolphin',
DORIS: 'Doris', DORIS: 'Doris',
DRAGON: 'Dragon',
DUCKDUCKGO: 'DuckDuckGo', DUCKDUCKGO: 'DuckDuckGo',
EDGE: 'Edge', EDGE: 'Edge',
EPIPHANY: 'Epiphany', EPIPHANY: 'Epiphany',
@@ -58,6 +59,7 @@ const Browser = Object.freeze({
GOOGLE_SEARCH: 'GSA', GOOGLE_SEARCH: 'GSA',
HELIO: 'Helio', HELIO: 'Helio',
HEYTAP: 'HeyTap', HEYTAP: 'HeyTap',
HONOR: 'Honor',
HUAWEI: 'Huawei Browser', HUAWEI: 'Huawei Browser',
ICAB: 'iCab', ICAB: 'iCab',
ICE: 'ICE Browser', ICE: 'ICE Browser',
@@ -78,6 +80,7 @@ const Browser = Object.freeze({
KLARNA: 'Klarna', KLARNA: 'Klarna',
KINDLE: 'Kindle', KINDLE: 'Kindle',
LENOVO: 'Smart Lenovo Browser', LENOVO: 'Smart Lenovo Browser',
LIBREWOLF: 'LibreWolf',
LIEBAO: 'LBBROWSER', LIEBAO: 'LBBROWSER',
LINE: 'Line', LINE: 'Line',
LINKEDIN: 'LinkedIn', LINKEDIN: 'LinkedIn',
@@ -126,7 +129,9 @@ const Browser = Object.freeze({
SILK: 'Silk', SILK: 'Silk',
SKYFIRE: 'Skyfire', SKYFIRE: 'Skyfire',
SLEIPNIR: 'Sleipnir', SLEIPNIR: 'Sleipnir',
SLIMBOAT: 'SlimBoat',
SLIMBROWSER: 'SlimBrowser', SLIMBROWSER: 'SlimBrowser',
SLIMJET: 'Slimjet',
SNAPCHAT: 'Snapchat', SNAPCHAT: 'Snapchat',
SOGOU_EXPLORER: 'Sogou Explorer', SOGOU_EXPLORER: 'Sogou Explorer',
SOGOU_MOBILE: 'Sogou Mobile', SOGOU_MOBILE: 'Sogou Mobile',
@@ -158,7 +163,7 @@ const BrowserType = Object.freeze({
FETCHER: 'fetcher', FETCHER: 'fetcher',
INAPP: 'inapp', INAPP: 'inapp',
MEDIAPLAYER: 'mediaplayer', MEDIAPLAYER: 'mediaplayer',
MODULE: 'module' LIBRARY: 'library'
}); });
const CPU = Object.freeze({ const CPU = Object.freeze({
@@ -194,6 +199,7 @@ const Device = Object.freeze({
const Vendor = Object.freeze({ const Vendor = Object.freeze({
ACER: 'Acer', ACER: 'Acer',
ADVAN: 'Advan',
ALCATEL: 'Alcatel', ALCATEL: 'Alcatel',
APPLE: 'Apple', APPLE: 'Apple',
AMAZON: 'Amazon', AMAZON: 'Amazon',
@@ -202,7 +208,9 @@ const Vendor = Object.freeze({
ATT: 'AT&T', ATT: 'AT&T',
BENQ: 'BenQ', BENQ: 'BenQ',
BLACKBERRY: 'BlackBerry', BLACKBERRY: 'BlackBerry',
CAT: 'Cat',
DELL: 'Dell', DELL: 'Dell',
ENERGIZER: 'Energizer',
ESSENTIAL: 'Essential', ESSENTIAL: 'Essential',
FACEBOOK: 'Facebook', FACEBOOK: 'Facebook',
FAIRPHONE: 'Fairphone', FAIRPHONE: 'Fairphone',
@@ -212,6 +220,7 @@ const Vendor = Object.freeze({
HP: 'HP', HP: 'HP',
HTC: 'HTC', HTC: 'HTC',
HUAWEI: 'Huawei', HUAWEI: 'Huawei',
IMO: 'IMO',
INFINIX: 'Infinix', INFINIX: 'Infinix',
ITEL: 'itel', ITEL: 'itel',
JOLLA: 'Jolla', JOLLA: 'Jolla',
@@ -219,6 +228,7 @@ const Vendor = Object.freeze({
LENOVO: 'Lenovo', LENOVO: 'Lenovo',
LG: 'LG', LG: 'LG',
MEIZU: 'Meizu', MEIZU: 'Meizu',
MICROMAX: 'Micromax',
MICROSOFT: 'Microsoft', MICROSOFT: 'Microsoft',
MOTOROLA: 'Motorola', MOTOROLA: 'Motorola',
NEXIAN: 'Nexian', NEXIAN: 'Nexian',
@@ -240,6 +250,7 @@ const Vendor = Object.freeze({
SAMSUNG: 'Samsung', SAMSUNG: 'Samsung',
SHARP: 'Sharp', SHARP: 'Sharp',
SIEMENS: 'Siemens', SIEMENS: 'Siemens',
SMARTFREN: 'Smartfren',
SONY: 'Sony', SONY: 'Sony',
SPRINT: 'Sprint', SPRINT: 'Sprint',
TCL: 'TCL', TCL: 'TCL',
@@ -273,6 +284,7 @@ const Engine = Object.freeze({
NETFRONT: 'NetFront', NETFRONT: 'NetFront',
NETSURF: 'NetSurf', NETSURF: 'NetSurf',
PRESTO: 'Presto', PRESTO: 'Presto',
SERVO: 'Servo',
TASMAN: 'Tasman', TASMAN: 'Tasman',
TRIDENT: 'Trident', TRIDENT: 'Trident',
W3M: 'w3m', W3M: 'w3m',
@@ -291,6 +303,10 @@ const OS = Object.freeze({
CENTOS: 'CentOS', CENTOS: 'CentOS',
CHROME_OS: 'Chrome OS', CHROME_OS: 'Chrome OS',
CHROMECAST: 'Chromecast', CHROMECAST: 'Chromecast',
CHROMECAST_ANDROID: 'Chromecast Android',
CHROMECAST_FUCHSIA: 'Chromecast Fuchsia',
CHROMECAST_LINUX: 'Chromecast Linux',
CHROMECAST_SMARTSPEAKER: 'Chromecast SmartSpeaker',
CONTIKI: 'Contiki', CONTIKI: 'Contiki',
DEBIAN: 'Debian', DEBIAN: 'Debian',
DEEPIN: 'Deepin', DEEPIN: 'Deepin',

View File

@@ -1,4 +1,4 @@
// Type definitions for Helpers submodule of UAParser.js v2.0.0-beta.3 // Type definitions for Helpers submodule of UAParser.js v2.0.0-rc.3
// Project: https://github.com/faisalman/ua-parser-js // Project: https://github.com/faisalman/ua-parser-js
// Definitions by: Faisal Salman <https://github.com/faisalman> // Definitions by: Faisal Salman <https://github.com/faisalman>
@@ -11,5 +11,5 @@ export const ExtraDevices: UAParserExt;
export const Emails: UAParserExt; export const Emails: UAParserExt;
export const Fetchers: UAParserExt; export const Fetchers: UAParserExt;
export const InApps: UAParserExt; export const InApps: UAParserExt;
export const MediaPlayers: UAParserExt; export const Libraries: UAParserExt;
export const Modules: UAParserExt; export const MediaPlayers: UAParserExt;

View File

@@ -1,5 +1,5 @@
/////////////////////////////////////////////// ///////////////////////////////////////////////
/* Extensions for UAParser.js v2.0.0-rc.1 /* Extensions for UAParser.js v2.0.0-rc.3
https://github.com/faisalman/ua-parser-js https://github.com/faisalman/ua-parser-js
Author: Faisal Salman <f@faisalman.com> Author: Faisal Salman <f@faisalman.com>
AGPLv3 License */ AGPLv3 License */
@@ -20,7 +20,7 @@ const EMAIL = 'email';
const FETCHER = 'fetcher'; const FETCHER = 'fetcher';
const INAPP = 'inapp'; const INAPP = 'inapp';
const MEDIAPLAYER = 'mediaplayer'; const MEDIAPLAYER = 'mediaplayer';
const MODULE = 'module'; const LIBRARY = 'library';
////////////////////// //////////////////////
// COMMAND LINE APPS // COMMAND LINE APPS
@@ -44,26 +44,36 @@ const Crawlers = Object.freeze({
// Amazonbot - https://developer.amazon.com/amazonbot // Amazonbot - https://developer.amazon.com/amazonbot
// Applebot - http://apple.com/go/applebot // Applebot - http://apple.com/go/applebot
// Bingbot - http://www.bing.com/bingbot.htm // Bingbot - http://www.bing.com/bingbot.htm
// CCBot - https://commoncrawl.org/faq
// Dotbot - https://moz.com/help/moz-procedures/crawlers/dotbot // Dotbot - https://moz.com/help/moz-procedures/crawlers/dotbot
// DuckDuckBot - http://duckduckgo.com/duckduckbot.html // DuckDuckBot - http://duckduckgo.com/duckduckbot.html
// FacebookBot - https://developers.facebook.com/docs/sharing/bot/ // FacebookBot - https://developers.facebook.com/docs/sharing/bot/
// GPTBot - https://platform.openai.com/docs/gptbot // GPTBot - https://platform.openai.com/docs/gptbot
// MJ12bot - https://mj12bot.com/ // MJ12bot - https://mj12bot.com/
// OpenAI Search - https://platform.openai.com/docs/bots // MojeekBot - https://www.mojeek.com/bot.html
// OpenAI's SearchGPT - https://platform.openai.com/docs/bots
// PerplexityBot - https://perplexity.ai/perplexitybot
// SemrushBot - http://www.semrush.com/bot.html // SemrushBot - http://www.semrush.com/bot.html
/((?:ahrefs|amazon|apple|bing|dot|duckduck|facebook|gpt|mj12|oai-search|semrush)bot)\/([\w\.]+)/i, /((?:ahrefs|amazon|apple|bing|cc|dot|duckduck|exa|facebook|gpt|mj12|mojeek|oai-search|perplexity|semrush)bot)\/([\w\.]+)/i,
// Baiduspider https://help.baidu.com/question?prod_id=99&class=0&id=3001 // Baiduspider https://help.baidu.com/question?prod_id=99&class=0&id=3001
/(baiduspider)[-imagevdonsfcpr]{0,6}\/([\w\.]+)/i, /(baiduspider)[-imagevdonsfcpr]{0,6}\/([\w\.]+)/i,
// ClaudeBot // ClaudeBot (Anthropic)
/(claude(?:bot|-web))\/([\w\.]+)/i, /(claude(?:bot|-web))\/([\w\.]+)/i,
// Coc Coc Bot - https://help.coccoc.com/en/search-engine // Coc Coc Bot - https://help.coccoc.com/en/search-engine
/(coccocbot-(?:image|web))\/([\w\.]+)/i, /(coccocbot-(?:image|web))\/([\w\.]+)/i,
// Facebook / Meta
// https://developers.facebook.com/docs/sharing/webmasters/web-crawlers
/(facebook(?:externalhit|catalog)|meta-externalagent)\/([\w\.]+)/i,
// Googlebot - http://www.google.com/bot.html // Googlebot - http://www.google.com/bot.html
/(google(?:bot|other)(?:-image|-video|-news|-extended)?|(?:storebot-)?google(?:-inspectiontool)?)\/?([\w\.]*)/i, /(google(?:bot|other|-inspectiontool)(?:-image|-video|-news)?|storebot-google)\/?([\w\.]*)/i,
// Internet Archive (archive.org)
/(ia_archiver|archive\.org_bot)\/?([\w\.]*)/i,
// Sogou Spider // Sogou Spider
/(sogou (?:pic|head|web|orion|news) spider)\/([\w\.]+)/i, /(sogou (?:pic|head|web|orion|news) spider)\/([\w\.]+)/i,
@@ -72,14 +82,29 @@ const Crawlers = Object.freeze({
/(y!?j-(?:asr|br[uw]|dscv|mmp|vsidx|wsc))\/([\w\.]+)/i, /(y!?j-(?:asr|br[uw]|dscv|mmp|vsidx|wsc))\/([\w\.]+)/i,
// Yandex Bots - https://yandex.com/bots // Yandex Bots - https://yandex.com/bots
/(yandex(?:(?:mobile)?(?:accessibility|additional|renderresources|screenshot|sprav)?bot|image(?:s|resizer)|video(?:parser)?|blogs|adnet|favicons|fordomain|market|media|metrika|news|ontodb(?:api)?|pagechecker|partner|rca|tracker|turbo|vertis|webmaster|antivirus))\/([\w\.]+)/i /(yandex(?:(?:mobile)?(?:accessibility|additional|renderresources|screenshot|sprav)?bot|image(?:s|resizer)|video(?:parser)?|blogs|adnet|favicons|fordomain|market|media|metrika|news|ontodb(?:api)?|pagechecker|partner|rca|tracker|turbo|vertis|webmaster|antivirus))\/([\w\.]+)/i,
// Yeti (Naver)
/(yeti)\/([\w\.]+)/i,
// YisouSpider
/(yisouspider)\/?([\w\.]*)/i
], ],
[NAME, VERSION, [TYPE, CRAWLER]], [NAME, VERSION, [TYPE, CRAWLER]],
// Bytespider [
// Yahoo! Slurp - http://help.yahoo.com/help/us/ysearch/slurp // Google Bots
[/((?:bytespider|(?=yahoo! )slurp))/i], /((?:adsbot|apis|mediapartners)-google(?:-mobile)?|google-?(?:other|cloudvertexbot|extended|safety))/i,
// Bytespider
// DataForSeoBot - https://dataforseo.com/dataforseo-bot
// Huawei AspiegelBot / PetalBot https://aspiegel.com/petalbot
// Qihoo 360Spider
// TurnitinBot - https://www.turnitin.com/robot/crawlerinfo.html
// Yahoo! Slurp - http://help.yahoo.com/help/us/ysearch/slurp
/(360spider-?(?:image|video)?|bytespider|(?:aspiegel|dataforseo|petal|turnitin)bot|(?=yahoo! )slurp)/i
],
[NAME, [TYPE, CRAWLER]] [NAME, [TYPE, CRAWLER]]
] ]
}); });
@@ -170,8 +195,8 @@ const ExtraDevices = Object.freeze({
const Emails = Object.freeze({ const Emails = Object.freeze({
browser : [ browser : [
// Microsoft Outlook / Thunderbird // Evolution / Kontact/KMail / [Microsoft/Mac] Outlook / Thunderbird
[/(microsoft outlook|thunderbird)[\s\/]([\w\.]+)/i], [NAME, VERSION, [TYPE, EMAIL]] [/(evolution|kmail2?|kontact|(?:microsoft |mac)outlook|thunderbird)[\s\/]([\w\.]+)/i], [NAME, VERSION, [TYPE, EMAIL]]
] ]
}); });
@@ -184,8 +209,15 @@ const Fetchers = Object.freeze({
[ [
// AhrefsSiteAudit - https://ahrefs.com/robot/site-audit // AhrefsSiteAudit - https://ahrefs.com/robot/site-audit
// ChatGPT-User - https://platform.openai.com/docs/plugins/bot // ChatGPT-User - https://platform.openai.com/docs/plugins/bot
// DuckAssistBot - https://duckduckgo.com/duckassistbot/
// BingPreview / Mastodon / Pinterestbot / Redditbot / Rogerbot / Telegrambot / Twitterbot / UptimeRobot // BingPreview / Mastodon / Pinterestbot / Redditbot / Rogerbot / Telegrambot / Twitterbot / UptimeRobot
/(ahrefssiteaudit|bingpreview|chatgpt-user|mastodon|(?:discord|linkedin|pinterest|reddit|roger|telegram|twitter|uptimero)bot)\/([\w\.]+)/i, /(ahrefssiteaudit|bingpreview|chatgpt-user|mastodon|(?:discord|duckassist|linkedin|pinterest|reddit|roger|telegram|twitter|uptimero)bot)\/([\w\.]+)/i,
// Google Site Verifier
/(google-site-verification)\/([\w\.]+)/i,
// Meta
/(meta-externalfetcher)\/([\w\.]+)/i,
// Slackbot - https://api.slack.com/robots // Slackbot - https://api.slack.com/robots
/(slack(?:bot)?(?:-imgproxy|-linkexpanding)?) ([\w\.]+)/i, /(slack(?:bot)?(?:-imgproxy|-linkexpanding)?) ([\w\.]+)/i,
@@ -203,7 +235,7 @@ const Fetchers = Object.freeze({
[NAME, VERSION, [TYPE, FETCHER]], [NAME, VERSION, [TYPE, FETCHER]],
// Google Bots / Snapchat // Google Bots / Snapchat
[/(feedfetcher-google|google-read-aloud|(?=bot; )snapchat)/i], [/(feedfetcher-google|google(?:-read-aloud|producer)|(?=bot; )snapchat)/i],
[NAME, [TYPE, FETCHER]], [NAME, [TYPE, FETCHER]],
] ]
}); });
@@ -252,8 +284,8 @@ const MediaPlayers = Object.freeze({
/(flrp)\/([\w\.-]+)/i // Flip Player /(flrp)\/([\w\.-]+)/i // Flip Player
], [[NAME, 'Flip Player'], VERSION, [TYPE, MEDIAPLAYER]], [ ], [[NAME, 'Flip Player'], VERSION, [TYPE, MEDIAPLAYER]], [
/(fstream|nativehost|queryseekspider|ia-archiver|facebookexternalhit)/i /(fstream|nativehost|queryseekspider)/i
// FStream/NativeHost/QuerySeekSpider/IA Archiver/facebookexternalhit // FStream/NativeHost/QuerySeekSpider
], [NAME, [TYPE, MEDIAPLAYER]], [ ], [NAME, [TYPE, MEDIAPLAYER]], [
/(gstreamer) souphttpsrc.+libsoup\/([\w\.-]+)/i /(gstreamer) souphttpsrc.+libsoup\/([\w\.-]+)/i
@@ -332,14 +364,14 @@ const MediaPlayers = Object.freeze({
] ]
}); });
//////////////////////// /////////////
// MODULES / LIBRARIES // LIBRARIES
/////////////////////// //////////////
const Modules = Object.freeze({ const Libraries = Object.freeze({
browser : [ browser : [
// Axios/jsdom/Scrapy // Axios/jsdom/Scrapy
[/\b(axios|jsdom|scrapy)\/([\w\.]+)/i], [NAME, VERSION, [TYPE, MODULE]] [/\b(axios|jsdom|scrapy)\/([\w\.]+)/i], [NAME, VERSION, [TYPE, LIBRARY]]
] ]
}); });
@@ -352,7 +384,7 @@ const Bots = Object.freeze({
...CLIs.browser, ...CLIs.browser,
...Crawlers.browser, ...Crawlers.browser,
...Fetchers.browser, ...Fetchers.browser,
...Modules.browser ...Libraries.browser
] ]
}); });
@@ -364,6 +396,6 @@ module.exports = {
Emails, Emails,
Fetchers, Fetchers,
InApps, InApps,
MediaPlayers, Libraries,
Modules MediaPlayers
}; };

View File

@@ -3,7 +3,7 @@
// Source: /src/extensions/ua-parser-extensions.js // Source: /src/extensions/ua-parser-extensions.js
/////////////////////////////////////////////// ///////////////////////////////////////////////
/* Extensions for UAParser.js v2.0.0-rc.1 /* Extensions for UAParser.js v2.0.0-rc.3
https://github.com/faisalman/ua-parser-js https://github.com/faisalman/ua-parser-js
Author: Faisal Salman <f@faisalman.com> Author: Faisal Salman <f@faisalman.com>
AGPLv3 License */ AGPLv3 License */
@@ -24,7 +24,7 @@ const EMAIL = 'email';
const FETCHER = 'fetcher'; const FETCHER = 'fetcher';
const INAPP = 'inapp'; const INAPP = 'inapp';
const MEDIAPLAYER = 'mediaplayer'; const MEDIAPLAYER = 'mediaplayer';
const MODULE = 'module'; const LIBRARY = 'library';
////////////////////// //////////////////////
// COMMAND LINE APPS // COMMAND LINE APPS
@@ -48,26 +48,36 @@ const Crawlers = Object.freeze({
// Amazonbot - https://developer.amazon.com/amazonbot // Amazonbot - https://developer.amazon.com/amazonbot
// Applebot - http://apple.com/go/applebot // Applebot - http://apple.com/go/applebot
// Bingbot - http://www.bing.com/bingbot.htm // Bingbot - http://www.bing.com/bingbot.htm
// CCBot - https://commoncrawl.org/faq
// Dotbot - https://moz.com/help/moz-procedures/crawlers/dotbot // Dotbot - https://moz.com/help/moz-procedures/crawlers/dotbot
// DuckDuckBot - http://duckduckgo.com/duckduckbot.html // DuckDuckBot - http://duckduckgo.com/duckduckbot.html
// FacebookBot - https://developers.facebook.com/docs/sharing/bot/ // FacebookBot - https://developers.facebook.com/docs/sharing/bot/
// GPTBot - https://platform.openai.com/docs/gptbot // GPTBot - https://platform.openai.com/docs/gptbot
// MJ12bot - https://mj12bot.com/ // MJ12bot - https://mj12bot.com/
// OpenAI Search - https://platform.openai.com/docs/bots // MojeekBot - https://www.mojeek.com/bot.html
// OpenAI's SearchGPT - https://platform.openai.com/docs/bots
// PerplexityBot - https://perplexity.ai/perplexitybot
// SemrushBot - http://www.semrush.com/bot.html // SemrushBot - http://www.semrush.com/bot.html
/((?:ahrefs|amazon|apple|bing|dot|duckduck|facebook|gpt|mj12|oai-search|semrush)bot)\/([\w\.]+)/i, /((?:ahrefs|amazon|apple|bing|cc|dot|duckduck|exa|facebook|gpt|mj12|mojeek|oai-search|perplexity|semrush)bot)\/([\w\.]+)/i,
// Baiduspider https://help.baidu.com/question?prod_id=99&class=0&id=3001 // Baiduspider https://help.baidu.com/question?prod_id=99&class=0&id=3001
/(baiduspider)[-imagevdonsfcpr]{0,6}\/([\w\.]+)/i, /(baiduspider)[-imagevdonsfcpr]{0,6}\/([\w\.]+)/i,
// ClaudeBot // ClaudeBot (Anthropic)
/(claude(?:bot|-web))\/([\w\.]+)/i, /(claude(?:bot|-web))\/([\w\.]+)/i,
// Coc Coc Bot - https://help.coccoc.com/en/search-engine // Coc Coc Bot - https://help.coccoc.com/en/search-engine
/(coccocbot-(?:image|web))\/([\w\.]+)/i, /(coccocbot-(?:image|web))\/([\w\.]+)/i,
// Facebook / Meta
// https://developers.facebook.com/docs/sharing/webmasters/web-crawlers
/(facebook(?:externalhit|catalog)|meta-externalagent)\/([\w\.]+)/i,
// Googlebot - http://www.google.com/bot.html // Googlebot - http://www.google.com/bot.html
/(google(?:bot|other)(?:-image|-video|-news|-extended)?|(?:storebot-)?google(?:-inspectiontool)?)\/?([\w\.]*)/i, /(google(?:bot|other|-inspectiontool)(?:-image|-video|-news)?|storebot-google)\/?([\w\.]*)/i,
// Internet Archive (archive.org)
/(ia_archiver|archive\.org_bot)\/?([\w\.]*)/i,
// Sogou Spider // Sogou Spider
/(sogou (?:pic|head|web|orion|news) spider)\/([\w\.]+)/i, /(sogou (?:pic|head|web|orion|news) spider)\/([\w\.]+)/i,
@@ -76,14 +86,29 @@ const Crawlers = Object.freeze({
/(y!?j-(?:asr|br[uw]|dscv|mmp|vsidx|wsc))\/([\w\.]+)/i, /(y!?j-(?:asr|br[uw]|dscv|mmp|vsidx|wsc))\/([\w\.]+)/i,
// Yandex Bots - https://yandex.com/bots // Yandex Bots - https://yandex.com/bots
/(yandex(?:(?:mobile)?(?:accessibility|additional|renderresources|screenshot|sprav)?bot|image(?:s|resizer)|video(?:parser)?|blogs|adnet|favicons|fordomain|market|media|metrika|news|ontodb(?:api)?|pagechecker|partner|rca|tracker|turbo|vertis|webmaster|antivirus))\/([\w\.]+)/i /(yandex(?:(?:mobile)?(?:accessibility|additional|renderresources|screenshot|sprav)?bot|image(?:s|resizer)|video(?:parser)?|blogs|adnet|favicons|fordomain|market|media|metrika|news|ontodb(?:api)?|pagechecker|partner|rca|tracker|turbo|vertis|webmaster|antivirus))\/([\w\.]+)/i,
// Yeti (Naver)
/(yeti)\/([\w\.]+)/i,
// YisouSpider
/(yisouspider)\/?([\w\.]*)/i
], ],
[NAME, VERSION, [TYPE, CRAWLER]], [NAME, VERSION, [TYPE, CRAWLER]],
// Bytespider [
// Yahoo! Slurp - http://help.yahoo.com/help/us/ysearch/slurp // Google Bots
[/((?:bytespider|(?=yahoo! )slurp))/i], /((?:adsbot|apis|mediapartners)-google(?:-mobile)?|google-?(?:other|cloudvertexbot|extended|safety))/i,
// Bytespider
// DataForSeoBot - https://dataforseo.com/dataforseo-bot
// Huawei AspiegelBot / PetalBot https://aspiegel.com/petalbot
// Qihoo 360Spider
// TurnitinBot - https://www.turnitin.com/robot/crawlerinfo.html
// Yahoo! Slurp - http://help.yahoo.com/help/us/ysearch/slurp
/(360spider-?(?:image|video)?|bytespider|(?:aspiegel|dataforseo|petal|turnitin)bot|(?=yahoo! )slurp)/i
],
[NAME, [TYPE, CRAWLER]] [NAME, [TYPE, CRAWLER]]
] ]
}); });
@@ -174,8 +199,8 @@ const ExtraDevices = Object.freeze({
const Emails = Object.freeze({ const Emails = Object.freeze({
browser : [ browser : [
// Microsoft Outlook / Thunderbird // Evolution / Kontact/KMail / [Microsoft/Mac] Outlook / Thunderbird
[/(microsoft outlook|thunderbird)[\s\/]([\w\.]+)/i], [NAME, VERSION, [TYPE, EMAIL]] [/(evolution|kmail2?|kontact|(?:microsoft |mac)outlook|thunderbird)[\s\/]([\w\.]+)/i], [NAME, VERSION, [TYPE, EMAIL]]
] ]
}); });
@@ -188,8 +213,15 @@ const Fetchers = Object.freeze({
[ [
// AhrefsSiteAudit - https://ahrefs.com/robot/site-audit // AhrefsSiteAudit - https://ahrefs.com/robot/site-audit
// ChatGPT-User - https://platform.openai.com/docs/plugins/bot // ChatGPT-User - https://platform.openai.com/docs/plugins/bot
// DuckAssistBot - https://duckduckgo.com/duckassistbot/
// BingPreview / Mastodon / Pinterestbot / Redditbot / Rogerbot / Telegrambot / Twitterbot / UptimeRobot // BingPreview / Mastodon / Pinterestbot / Redditbot / Rogerbot / Telegrambot / Twitterbot / UptimeRobot
/(ahrefssiteaudit|bingpreview|chatgpt-user|mastodon|(?:discord|linkedin|pinterest|reddit|roger|telegram|twitter|uptimero)bot)\/([\w\.]+)/i, /(ahrefssiteaudit|bingpreview|chatgpt-user|mastodon|(?:discord|duckassist|linkedin|pinterest|reddit|roger|telegram|twitter|uptimero)bot)\/([\w\.]+)/i,
// Google Site Verifier
/(google-site-verification)\/([\w\.]+)/i,
// Meta
/(meta-externalfetcher)\/([\w\.]+)/i,
// Slackbot - https://api.slack.com/robots // Slackbot - https://api.slack.com/robots
/(slack(?:bot)?(?:-imgproxy|-linkexpanding)?) ([\w\.]+)/i, /(slack(?:bot)?(?:-imgproxy|-linkexpanding)?) ([\w\.]+)/i,
@@ -207,7 +239,7 @@ const Fetchers = Object.freeze({
[NAME, VERSION, [TYPE, FETCHER]], [NAME, VERSION, [TYPE, FETCHER]],
// Google Bots / Snapchat // Google Bots / Snapchat
[/(feedfetcher-google|google-read-aloud|(?=bot; )snapchat)/i], [/(feedfetcher-google|google(?:-read-aloud|producer)|(?=bot; )snapchat)/i],
[NAME, [TYPE, FETCHER]], [NAME, [TYPE, FETCHER]],
] ]
}); });
@@ -256,8 +288,8 @@ const MediaPlayers = Object.freeze({
/(flrp)\/([\w\.-]+)/i // Flip Player /(flrp)\/([\w\.-]+)/i // Flip Player
], [[NAME, 'Flip Player'], VERSION, [TYPE, MEDIAPLAYER]], [ ], [[NAME, 'Flip Player'], VERSION, [TYPE, MEDIAPLAYER]], [
/(fstream|nativehost|queryseekspider|ia-archiver|facebookexternalhit)/i /(fstream|nativehost|queryseekspider)/i
// FStream/NativeHost/QuerySeekSpider/IA Archiver/facebookexternalhit // FStream/NativeHost/QuerySeekSpider
], [NAME, [TYPE, MEDIAPLAYER]], [ ], [NAME, [TYPE, MEDIAPLAYER]], [
/(gstreamer) souphttpsrc.+libsoup\/([\w\.-]+)/i /(gstreamer) souphttpsrc.+libsoup\/([\w\.-]+)/i
@@ -336,14 +368,14 @@ const MediaPlayers = Object.freeze({
] ]
}); });
//////////////////////// /////////////
// MODULES / LIBRARIES // LIBRARIES
/////////////////////// //////////////
const Modules = Object.freeze({ const Libraries = Object.freeze({
browser : [ browser : [
// Axios/jsdom/Scrapy // Axios/jsdom/Scrapy
[/\b(axios|jsdom|scrapy)\/([\w\.]+)/i], [NAME, VERSION, [TYPE, MODULE]] [/\b(axios|jsdom|scrapy)\/([\w\.]+)/i], [NAME, VERSION, [TYPE, LIBRARY]]
] ]
}); });
@@ -356,7 +388,7 @@ const Bots = Object.freeze({
...CLIs.browser, ...CLIs.browser,
...Crawlers.browser, ...Crawlers.browser,
...Fetchers.browser, ...Fetchers.browser,
...Modules.browser ...Libraries.browser
] ]
}); });
@@ -368,6 +400,6 @@ export {
Emails, Emails,
Fetchers, Fetchers,
InApps, InApps,
MediaPlayers, Libraries,
Modules MediaPlayers
}; };

View File

@@ -1,11 +1,12 @@
// Type definitions for Helpers submodule of UAParser.js v2.0.0-beta.3 // Type definitions for Helpers submodule of UAParser.js v2.0.0-rc.3
// Project: https://github.com/faisalman/ua-parser-js // Project: https://github.com/faisalman/ua-parser-js
// Definitions by: Faisal Salman <https://github.com/faisalman> // Definitions by: Faisal Salman <https://github.com/faisalman>
import { IResult } from "../main/ua-parser"; import { IResult } from "../main/ua-parser";
declare function getDeviceVendor(model: string): string | undefined; declare function getDeviceVendor(model: string): string | undefined;
declare function isAppleSilicon(res: IResult): boolean; declare function isAppleSilicon(res: IResult, useFeatureDetection?: boolean): boolean;
declare function isBot(res: IResult): boolean;
declare function isChromeFamily(res: IResult): boolean; declare function isChromeFamily(res: IResult): boolean;
declare function isElectron(): boolean; declare function isElectron(): boolean;
declare function isFromEU(): boolean; declare function isFromEU(): boolean;
@@ -15,6 +16,7 @@ declare function isStandalonePWA(): boolean;
export { export {
getDeviceVendor, getDeviceVendor,
isAppleSilicon, isAppleSilicon,
isBot,
isChromeFamily, isChromeFamily,
isElectron, isElectron,
isFromEU, isFromEU,

View File

@@ -1,5 +1,5 @@
/////////////////////////////////////////////// ///////////////////////////////////////////////
/* Helpers for UAParser.js v2.0.0-rc.1 /* Helpers for UAParser.js v2.0.0-rc.3
https://github.com/faisalman/ua-parser-js https://github.com/faisalman/ua-parser-js
Author: Faisal Salman <f@faisalman.com> Author: Faisal Salman <f@faisalman.com>
AGPLv3 License */ AGPLv3 License */
@@ -7,52 +7,47 @@
/*jshint esversion: 6 */ /*jshint esversion: 6 */
const { CPU, OS, Engine } = require('../enums/ua-parser-enums');
const { UAParser } = require('../main/ua-parser'); const { UAParser } = require('../main/ua-parser');
const { CPU, OS, Engine } = require('../enums/ua-parser-enums');
const { isFromEU } = require('detect-europe-js'); const { isFromEU } = require('detect-europe-js');
const { isFrozenUA } = require('ua-is-frozen');
const { isStandalonePWA } = require('is-standalone-pwa');
const getDeviceVendor = (model) => UAParser(`Mozilla/5.0 (Linux; Android 10; ${model}) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.0.0 Safari/537.36`).device.vendor; const getDeviceVendor = (model) => UAParser(`Mozilla/5.0 (Linux; Android 10; ${model}) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.0.0 Safari/537.36`).device.vendor;
const isAppleSilicon = (res) => { const isAppleSilicon = (res, useFeatureDetection) => {
if (res.os.is(OS.MACOS)) { if (res.os.is(OS.MACOS)) {
if (res.cpu.is(CPU.ARM)) { if (res.cpu.is(CPU.ARM)) {
return true; return true;
} }
try { if (useFeatureDetection) {
const canvas = document.createElement('canvas'); try {
const webgl = canvas.getContext('webgl2') || canvas.getContext('webgl') || canvas.getContext('experimental-webgl'); const canvas = document.createElement('canvas');
const debug = webgl.getExtension('WEBGL_debug_renderer_info'); const webgl = canvas.getContext('webgl2') || canvas.getContext('webgl') || canvas.getContext('experimental-webgl');
const renderer = webgl.getParameter(debug.UNMASKED_RENDERER_WEBGL); const debug = webgl.getExtension('WEBGL_debug_renderer_info');
if (renderer.match(/apple m\d/i)) { const renderer = webgl.getParameter(debug.UNMASKED_RENDERER_WEBGL);
return true; if (renderer.match(/apple m\d/i)) {
return true;
}
} catch {
return false;
} }
} catch {
return false;
} }
} }
return false; return false;
} }
const isBot = (res) => ['cli', 'crawler', 'fetcher', 'library'].includes(res.browser.type);
const isChromeFamily = (res) => res.engine.is(Engine.BLINK); const isChromeFamily = (res) => res.engine.is(Engine.BLINK);
const isElectron = () => !!(process?.versions?.hasOwnProperty('electron') || // node.js const isElectron = () => !!(process?.versions?.hasOwnProperty('electron') || // node.js
/ electron\//i.test(navigator?.userAgent)); // browser / electron\//i.test(navigator?.userAgent)); // browser
const isFrozenUA = (ua) => /^Mozilla\/5\.0 \((Windows NT 10\.0; Win64; x64|Macintosh; Intel Mac OS X 10_15_7|X11; Linux x86_64|X11; CrOS x86_64 14541\.0\.0|Fuchsia|Linux; Android 10; K)\) AppleWebKit\/537\.36 \(KHTML, like Gecko\) Chrome\/\d+\.0\.0\.0 (Mobile )?Safari\/537\.36/.test(ua);
const isStandalonePWA = () => window && (window.matchMedia('(display-mode: standalone)').matches ||
// iOS
navigator.standalone ||
// Android
document.referrer.startsWith('android-app://') ||
// Windows
window.Windows ||
/trident.+(msapphost|webview)\//i.test(navigator.userAgent) ||
document.referrer.startsWith('app-info://platform/microsoft-store'));
module.exports = { module.exports = {
getDeviceVendor, getDeviceVendor,
isAppleSilicon, isAppleSilicon,
isBot,
isChromeFamily, isChromeFamily,
isElectron, isElectron,
isFromEU, isFromEU,

View File

@@ -3,7 +3,7 @@
// Source: /src/helpers/ua-parser-helpers.js // Source: /src/helpers/ua-parser-helpers.js
/////////////////////////////////////////////// ///////////////////////////////////////////////
/* Helpers for UAParser.js v2.0.0-rc.1 /* Helpers for UAParser.js v2.0.0-rc.3
https://github.com/faisalman/ua-parser-js https://github.com/faisalman/ua-parser-js
Author: Faisal Salman <f@faisalman.com> Author: Faisal Salman <f@faisalman.com>
AGPLv3 License */ AGPLv3 License */
@@ -11,52 +11,47 @@
/*jshint esversion: 6 */ /*jshint esversion: 6 */
import { CPU, OS, Engine } from './enums/ua-parser-enums.mjs'; import { UAParser } from '../main/ua-parser.mjs';
import { UAParser } from './main/ua-parser.mjs'; import { CPU, OS, Engine } from '../enums/ua-parser-enums.mjs';
import { isFromEU } from 'detect-europe-js'; import { isFromEU } from 'detect-europe-js';
import { isFrozenUA } from 'ua-is-frozen';
import { isStandalonePWA } from 'is-standalone-pwa';
const getDeviceVendor = (model) => UAParser(`Mozilla/5.0 (Linux; Android 10; ${model}) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.0.0 Safari/537.36`).device.vendor; const getDeviceVendor = (model) => UAParser(`Mozilla/5.0 (Linux; Android 10; ${model}) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.0.0 Safari/537.36`).device.vendor;
const isAppleSilicon = (res) => { const isAppleSilicon = (res, useFeatureDetection) => {
if (res.os.is(OS.MACOS)) { if (res.os.is(OS.MACOS)) {
if (res.cpu.is(CPU.ARM)) { if (res.cpu.is(CPU.ARM)) {
return true; return true;
} }
try { if (useFeatureDetection) {
const canvas = document.createElement('canvas'); try {
const webgl = canvas.getContext('webgl2') || canvas.getContext('webgl') || canvas.getContext('experimental-webgl'); const canvas = document.createElement('canvas');
const debug = webgl.getExtension('WEBGL_debug_renderer_info'); const webgl = canvas.getContext('webgl2') || canvas.getContext('webgl') || canvas.getContext('experimental-webgl');
const renderer = webgl.getParameter(debug.UNMASKED_RENDERER_WEBGL); const debug = webgl.getExtension('WEBGL_debug_renderer_info');
if (renderer.match(/apple m\d/i)) { const renderer = webgl.getParameter(debug.UNMASKED_RENDERER_WEBGL);
return true; if (renderer.match(/apple m\d/i)) {
return true;
}
} catch {
return false;
} }
} catch {
return false;
} }
} }
return false; return false;
} }
const isBot = (res) => ['cli', 'crawler', 'fetcher', 'library'].includes(res.browser.type);
const isChromeFamily = (res) => res.engine.is(Engine.BLINK); const isChromeFamily = (res) => res.engine.is(Engine.BLINK);
const isElectron = () => !!(process?.versions?.hasOwnProperty('electron') || // node.js const isElectron = () => !!(process?.versions?.hasOwnProperty('electron') || // node.js
/ electron\//i.test(navigator?.userAgent)); // browser / electron\//i.test(navigator?.userAgent)); // browser
const isFrozenUA = (ua) => /^Mozilla\/5\.0 \((Windows NT 10\.0; Win64; x64|Macintosh; Intel Mac OS X 10_15_7|X11; Linux x86_64|X11; CrOS x86_64 14541\.0\.0|Fuchsia|Linux; Android 10; K)\) AppleWebKit\/537\.36 \(KHTML, like Gecko\) Chrome\/\d+\.0\.0\.0 (Mobile )?Safari\/537\.36/.test(ua);
const isStandalonePWA = () => window && (window.matchMedia('(display-mode: standalone)').matches ||
// iOS
navigator.standalone ||
// Android
document.referrer.startsWith('android-app://') ||
// Windows
window.Windows ||
/trident.+(msapphost|webview)\//i.test(navigator.userAgent) ||
document.referrer.startsWith('app-info://platform/microsoft-store'));
export { export {
getDeviceVendor, getDeviceVendor,
isAppleSilicon, isAppleSilicon,
isBot,
isChromeFamily, isChromeFamily,
isElectron, isElectron,
isFromEU, isFromEU,

View File

@@ -1,4 +1,4 @@
// Type definitions for UAParser.js v2.0.0-beta.3 // Type definitions for UAParser.js v2.0.0-rc.3
// Project: https://github.com/faisalman/ua-parser-js // Project: https://github.com/faisalman/ua-parser-js
// Definitions by: Faisal Salman <https://github.com/faisalman> // Definitions by: Faisal Salman <https://github.com/faisalman>
@@ -15,11 +15,11 @@ declare namespace UAParser {
name?: string; name?: string;
version?: string; version?: string;
major?: string; major?: string;
type?: 'crawler' | 'cli' | 'email' | 'fetcher' | 'inapp' | 'mediaplayer' | 'module'; type?: 'crawler' | 'cli' | 'email' | 'fetcher' | 'inapp' | 'mediaplayer' | 'library';
} }
interface ICPU extends IData<ICPU> { interface ICPU extends IData<ICPU> {
architecture?: 'ia32' | 'ia64' | 'amd64' | 'arm' | 'arm64' | 'armhf' | 'avr' | 'irix' | 'irix64' | 'mips' | 'mips64' | '68k' | 'ppc' | 'sparc' | 'sparc64'; architecture?: 'ia32' | 'ia64' | 'amd64' | 'arm' | 'arm64' | 'armhf' | 'avr' | 'avr32' | 'irix' | 'irix64' | 'mips' | 'mips64' | '68k' | 'pa-risc' | 'ppc' | 'sparc' | 'sparc64';
} }
interface IDevice extends IData<IDevice> { interface IDevice extends IData<IDevice> {
@@ -29,7 +29,7 @@ declare namespace UAParser {
} }
interface IEngine extends IData<IEngine> { interface IEngine extends IData<IEngine> {
name?: 'Amaya' | 'Blink' | 'EdgeHTML' | 'Flow' | 'Gecko' | 'Goanna' | 'iCab' | 'KHTML' | 'LibWeb' | 'Links' | 'Lynx' | 'NetFront' | 'NetSurf' | 'Presto' | 'Tasman' | 'Trident' | 'w3m' | 'WebKit'; name?: 'Amaya' | 'ArkWeb' | 'Blink' | 'EdgeHTML' | 'Flow' | 'Gecko' | 'Goanna' | 'iCab' | 'KHTML' | 'LibWeb' | 'Links' | 'Lynx' | 'NetFront' | 'NetSurf' | 'Presto' | 'Servo' | 'Tasman' | 'Trident' | 'w3m' | 'WebKit';
version?: string; version?: string;
} }

View File

@@ -1,5 +1,5 @@
///////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////
/* UAParser.js v2.0.0-rc.1 /* UAParser.js v2.0.0-rc.3
Copyright © 2012-2024 Faisal Salman <f@faisalman.com> Copyright © 2012-2024 Faisal Salman <f@faisalman.com>
AGPLv3 License *//* AGPLv3 License *//*
Detect Browser, Engine, OS, CPU, and Device type/model from User-Agent data. Detect Browser, Engine, OS, CPU, and Device type/model from User-Agent data.
@@ -19,7 +19,7 @@
// Constants // Constants
///////////// /////////////
var LIBVERSION = '2.0.0-rc.1', var LIBVERSION = '2.0.0-rc.3',
EMPTY = '', EMPTY = '',
UNKNOWN = '?', UNKNOWN = '?',
FUNC_TYPE = 'function', FUNC_TYPE = 'function',
@@ -40,6 +40,7 @@
WEARABLE = 'wearable', WEARABLE = 'wearable',
XR = 'xr', XR = 'xr',
EMBEDDED = 'embedded', EMBEDDED = 'embedded',
INAPP = 'inapp',
USER_AGENT = 'user-agent', USER_AGENT = 'user-agent',
UA_MAX_LENGTH = 500, UA_MAX_LENGTH = 500,
BRANDS = 'brands', BRANDS = 'brands',
@@ -71,6 +72,7 @@
GOOGLE = 'Google', GOOGLE = 'Google',
HUAWEI = 'Huawei', HUAWEI = 'Huawei',
LENOVO = 'Lenovo', LENOVO = 'Lenovo',
HONOR = 'Honor',
LG = 'LG', LG = 'LG',
MICROSOFT = 'Microsoft', MICROSOFT = 'Microsoft',
MOTOROLA = 'Motorola', MOTOROLA = 'Motorola',
@@ -320,17 +322,19 @@
// Mixed // Mixed
/\bb[ai]*d(?:uhd|[ub]*[aekoprswx]{5,6})[\/ ]?([\w\.]+)/i // Baidu /\bb[ai]*d(?:uhd|[ub]*[aekoprswx]{5,6})[\/ ]?([\w\.]+)/i // Baidu
], [VERSION, [NAME, 'Baidu']], [ ], [VERSION, [NAME, 'Baidu']], [
/\b(?:mxbrowser|mxios|myie2)\/?([-\w\.]*)\b/i // Maxthon
], [VERSION, [NAME, 'Maxthon']], [
/(kindle)\/([\w\.]+)/i, // Kindle /(kindle)\/([\w\.]+)/i, // Kindle
/(lunascape|maxthon|netfront|jasmine|blazer|sleipnir)[\/ ]?([\w\.]*)/i, /(lunascape|maxthon|netfront|jasmine|blazer|sleipnir)[\/ ]?([\w\.]*)/i,
// Lunascape/Maxthon/Netfront/Jasmine/Blazer/Sleipnir // Lunascape/Maxthon/Netfront/Jasmine/Blazer/Sleipnir
// Trident based // Trident based
/(avant|iemobile|slim)\s?(?:browser)?[\/ ]?([\w\.]*)/i, // Avant/IEMobile/SlimBrowser /(avant|iemobile|slim(?:browser|boat|jet))[\/ ]?([\d\.]*)/i, // Avant/IEMobile/SlimBrowser/SlimBoat/Slimjet
/(?:ms|\()(ie) ([\w\.]+)/i, // Internet Explorer /(?:ms|\()(ie) ([\w\.]+)/i, // Internet Explorer
// Webkit/KHTML based // Flock/RockMelt/Midori/Epiphany/Silk/Skyfire/Bolt/Iron/Iridium/PhantomJS/Bowser/QupZilla/Falkon // Blink/Webkit/KHTML based // Flock/RockMelt/Midori/Epiphany/Silk/Skyfire/Bolt/Iron/Iridium/PhantomJS/Bowser/QupZilla/Falkon
/(flock|rockmelt|midori|epiphany|silk|skyfire|ovibrowser|bolt|iron|vivaldi|iridium|phantomjs|bowser|qupzilla|falkon|rekonq|puffin|brave|whale(?!.+naver)|qqbrowserlite|duckduckgo|klar|helio)\/([-\w\.]+)/i, /(flock|rockmelt|midori|epiphany|silk|skyfire|ovibrowser|bolt|iron|vivaldi|iridium|phantomjs|bowser|qupzilla|falkon|rekonq|puffin|brave|whale(?!.+naver)|qqbrowserlite|duckduckgo|klar|helio|(?=comodo_)?dragon)\/([-\w\.]+)/i,
// Rekonq/Puffin/Brave/Whale/QQBrowserLite/QQ//Vivaldi/DuckDuckGo/Klar/Helio // Rekonq/Puffin/Brave/Whale/QQBrowserLite/QQ//Vivaldi/DuckDuckGo/Klar/Helio/Dragon
/(heytap|ovi)browser\/([\d\.]+)/i, // HeyTap/Ovi /(heytap|ovi|115)browser\/([\d\.]+)/i, // HeyTap/Ovi/115
/(weibo)__([\d\.]+)/i // Weibo /(weibo)__([\d\.]+)/i // Weibo
], [NAME, VERSION], [ ], [NAME, VERSION], [
/quark(?:pc)?\/([-\w\.]+)/i // Quark /quark(?:pc)?\/([-\w\.]+)/i // Quark
@@ -367,31 +371,31 @@
], [VERSION, [NAME, 'MIUI' + SUFFIX_BROWSER]], [ ], [VERSION, [NAME, 'MIUI' + SUFFIX_BROWSER]], [
/fxios\/([\w\.-]+)/i // Firefox for iOS /fxios\/([\w\.-]+)/i // Firefox for iOS
], [VERSION, [NAME, PREFIX_MOBILE + FIREFOX]], [ ], [VERSION, [NAME, PREFIX_MOBILE + FIREFOX]], [
/\bqihu|(qi?ho?o?|360)browser/i // 360 /\bqihoobrowser\/?([\w\.]*)/i // 360
], [[NAME, '360' + SUFFIX_BROWSER]], [ ], [VERSION, [NAME, '360']], [
/\b(qq)\/([\w\.]+)/i // QQ /\b(qq)\/([\w\.]+)/i // QQ
], [[NAME, /(.+)/, '$1Browser'], VERSION], [ ], [[NAME, /(.+)/, '$1Browser'], VERSION], [
/(oculus|sailfish|huawei|vivo|pico)browser\/([\w\.]+)/i /(oculus|sailfish|huawei|vivo|pico)browser\/([\w\.]+)/i
], [[NAME, /(.+)/, '$1' + SUFFIX_BROWSER], VERSION], [ // Oculus/Sailfish/HuaweiBrowser/VivoBrowser/PicoBrowser ], [[NAME, /(.+)/, '$1' + SUFFIX_BROWSER], VERSION], [ // Oculus/Sailfish/HuaweiBrowser/VivoBrowser/PicoBrowser
/samsungbrowser\/([\w\.]+)/i // Samsung Internet /samsungbrowser\/([\w\.]+)/i // Samsung Internet
], [VERSION, [NAME, SAMSUNG + ' Internet']], [ ], [VERSION, [NAME, SAMSUNG + ' Internet']], [
/(comodo_dragon)\/([\w\.]+)/i // Comodo Dragon
], [[NAME, /_/g, ' '], VERSION], [
/metasr[\/ ]?([\d\.]+)/i // Sogou Explorer /metasr[\/ ]?([\d\.]+)/i // Sogou Explorer
], [VERSION, [NAME, SOGOU + ' Explorer']], [ ], [VERSION, [NAME, SOGOU + ' Explorer']], [
/(sogou)mo\w+\/([\d\.]+)/i // Sogou Mobile /(sogou)mo\w+\/([\d\.]+)/i // Sogou Mobile
], [[NAME, SOGOU + ' Mobile'], VERSION], [ ], [[NAME, SOGOU + ' Mobile'], VERSION], [
/(electron)\/([\w\.]+) safari/i, // Electron-based App /(electron)\/([\w\.]+) safari/i, // Electron-based App
/(tesla)(?: qtcarbrowser|\/(20\d\d\.[-\w\.]+))/i, // Tesla /(tesla)(?: qtcarbrowser|\/(20\d\d\.[-\w\.]+))/i, // Tesla
/m?(qqbrowser|2345Explorer)[\/ ]?([\w\.]+)/i // QQBrowser/2345 Browser /m?(qqbrowser|2345(?=browser|chrome|explorer))\w*[\/ ]?v?([\w\.]+)/i // QQ/2345
], [NAME, VERSION], [ ], [NAME, VERSION], [
/(lbbrowser|rekonq)/i, // LieBao Browser/Rekonq /(lbbrowser|rekonq)/i // LieBao Browser/Rekonq
/\[(linkedin)app\]/i // LinkedIn App for iOS & Android
], [NAME], [ ], [NAME], [
/ome\/([\w\.]+) \w* ?(iron) saf/i, // Iron
/ome\/([\w\.]+).+qihu (360)[es]e/i // 360
], [VERSION, NAME], [
// WebView // WebView
/((?:fban\/fbios|fb_iab\/fb4a)(?!.+fbav)|;fbav\/([\w\.]+);)/i // Facebook App for iOS & Android /((?:fban\/fbios|fb_iab\/fb4a)(?!.+fbav)|;fbav\/([\w\.]+);)/i // Facebook App for iOS & Android
], [[NAME, FACEBOOK], VERSION], [ ], [[NAME, FACEBOOK], VERSION, [TYPE, INAPP]], [
/(Klarna)\/([\w\.]+)/i, // Klarna Shopping Browser for iOS & Android /(Klarna)\/([\w\.]+)/i, // Klarna Shopping Browser for iOS & Android
/(kakao(?:talk|story))[\/ ]([\w\.]+)/i, // Kakao App /(kakao(?:talk|story))[\/ ]([\w\.]+)/i, // Kakao App
/(naver)\(.*?(\d+\.[\w\.]+).*\)/i, // Naver InApp /(naver)\(.*?(\d+\.[\w\.]+).*\)/i, // Naver InApp
@@ -399,12 +403,17 @@
/\b(line)\/([\w\.]+)\/iab/i, // Line App for Android /\b(line)\/([\w\.]+)\/iab/i, // Line App for Android
/(alipay)client\/([\w\.]+)/i, // Alipay /(alipay)client\/([\w\.]+)/i, // Alipay
/(twitter)(?:and| f.+e\/([\w\.]+))/i, // Twitter /(twitter)(?:and| f.+e\/([\w\.]+))/i, // Twitter
/(chromium|instagram|snapchat)[\/ ]([-\w\.]+)/i // Chromium/Instagram/Snapchat /(instagram|snapchat)[\/ ]([-\w\.]+)/i // Instagram/Snapchat
], [NAME, VERSION], [ ], [NAME, VERSION, [TYPE, INAPP]], [
/\bgsa\/([\w\.]+) .*safari\//i // Google Search Appliance on iOS /\bgsa\/([\w\.]+) .*safari\//i // Google Search Appliance on iOS
], [VERSION, [NAME, 'GSA']], [ ], [VERSION, [NAME, 'GSA'], [TYPE, INAPP]], [
/musical_ly(?:.+app_?version\/|_)([\w\.]+)/i // TikTok /musical_ly(?:.+app_?version\/|_)([\w\.]+)/i // TikTok
], [VERSION, [NAME, 'TikTok']], [ ], [VERSION, [NAME, 'TikTok'], [TYPE, INAPP]], [
/\[(linkedin)app\]/i // LinkedIn App for iOS & Android
], [NAME, [TYPE, INAPP]], [
/(chromium)[\/ ]([-\w\.]+)/i // Chromium
], [NAME, VERSION], [
/headlesschrome(?:\/([\w\.]+)| )/i // Chrome Headless /headlesschrome(?:\/([\w\.]+)| )/i // Chrome Headless
], [VERSION, [NAME, CHROME+' Headless']], [ ], [VERSION, [NAME, CHROME+' Headless']], [
@@ -438,7 +447,7 @@
], [[NAME, PREFIX_MOBILE + FIREFOX], VERSION], [ ], [[NAME, PREFIX_MOBILE + FIREFOX], VERSION], [
/(navigator|netscape\d?)\/([-\w\.]+)/i // Netscape /(navigator|netscape\d?)\/([-\w\.]+)/i // Netscape
], [[NAME, 'Netscape'], VERSION], [ ], [[NAME, 'Netscape'], VERSION], [
/(wolvic)\/([\w\.]+)/i // Wolvic /(wolvic|librewolf)\/([\w\.]+)/i // Wolvic/LibreWolf
], [NAME, VERSION], [ ], [NAME, VERSION], [
/mobile vr; rv:([\w\.]+)\).+firefox/i // Firefox Reality /mobile vr; rv:([\w\.]+)\).+firefox/i // Firefox Reality
], [VERSION, [NAME, FIREFOX+' Reality']], [ ], [VERSION, [NAME, FIREFOX+' Reality']], [
@@ -519,10 +528,14 @@
/\b(sh-?[altvz]?\d\d[a-ekm]?)/i /\b(sh-?[altvz]?\d\d[a-ekm]?)/i
], [MODEL, [VENDOR, SHARP], [TYPE, MOBILE]], [ ], [MODEL, [VENDOR, SHARP], [TYPE, MOBILE]], [
// Honor
/(?:honor)([-\w ]+)[;\)]/i
], [MODEL, [VENDOR, HONOR], [TYPE, MOBILE]], [
// Huawei // Huawei
/\b((?:ag[rs][23]?|bah2?|sht?|btv)-a?[lw]\d{2})\b(?!.+d\/s)/i /\b((?:ag[rs][23]?|bah2?|sht?|btv)-a?[lw]\d{2})\b(?!.+d\/s)/i
], [MODEL, [VENDOR, HUAWEI], [TYPE, TABLET]], [ ], [MODEL, [VENDOR, HUAWEI], [TYPE, TABLET]], [
/(?:huawei|honor)([-\w ]+)[;\)]/i, /(?:huawei)([-\w ]+)[;\)]/i,
/\b(nexus 6p|\w{2,4}e?-[atu]?[ln][\dx][012359c][adn]?)\b(?!.+d\/s)/i /\b(nexus 6p|\w{2,4}e?-[atu]?[ln][\dx][012359c][adn]?)\b(?!.+d\/s)/i
], [MODEL, [VENDOR, HUAWEI], [TYPE, MOBILE]], [ ], [MODEL, [VENDOR, HUAWEI], [TYPE, MOBILE]], [
@@ -587,7 +600,7 @@
], [MODEL, [VENDOR, GOOGLE], [TYPE, MOBILE]], [ ], [MODEL, [VENDOR, GOOGLE], [TYPE, MOBILE]], [
// Sony // Sony
/droid.+ (a?\d[0-2]{2}so|[c-g]\d{4}|so[-gl]\w+|xq-a\w[4-7][12])(?= bui|\).+chrome\/(?![1-6]{0,1}\d\.))/i /droid.+; (a?\d[0-2]{2}so|[c-g]\d{4}|so[-gl]\w+|xq-a\w[4-7][12])(?= bui|\).+chrome\/(?![1-6]{0,1}\d\.))/i
], [MODEL, [VENDOR, SONY], [TYPE, MOBILE]], [ ], [MODEL, [VENDOR, SONY], [TYPE, MOBILE]], [
/sony tablet [ps]/i, /sony tablet [ps]/i,
/\b(?:sony)?sgp\w+(?: bui|\))/i /\b(?:sony)?sgp\w+(?: bui|\))/i
@@ -653,13 +666,28 @@
/; ((?:power )?armor(?:[\w ]{0,8}))(?: bui|\))/i /; ((?:power )?armor(?:[\w ]{0,8}))(?: bui|\))/i
], [MODEL, [VENDOR, 'Ulefone'], [TYPE, MOBILE]], [ ], [MODEL, [VENDOR, 'Ulefone'], [TYPE, MOBILE]], [
// Energizer
/; (energy ?\w+)(?: bui|\))/i,
/; energizer ([\w ]+)(?: bui|\))/i
], [MODEL, [VENDOR, 'Energizer'], [TYPE, MOBILE]], [
// Cat
/; cat (b35);/i,
/; (b15q?|s22 flip|s48c|s62 pro)(?: bui|\))/i
], [MODEL, [VENDOR, 'Cat'], [TYPE, MOBILE]], [
// Smartfren
/((?:new )?andromax[\w- ]+)(?: bui|\))/i
], [MODEL, [VENDOR, 'Smartfren'], [TYPE, MOBILE]], [
// Nothing // Nothing
/droid.+; (a(?:015|06[35]|142p?))/i /droid.+; (a(?:015|06[35]|142p?))/i
], [MODEL, [VENDOR, 'Nothing'], [TYPE, MOBILE]], [ ], [MODEL, [VENDOR, 'Nothing'], [TYPE, MOBILE]], [
// MIXED // MIXED
/(blackberry|benq|palm(?=\-)|sonyericsson|acer|asus|dell|meizu|motorola|polytron|infinix|tecno)[-_ ]?([-\w]*)/i, /(blackberry|benq|palm(?=\-)|sonyericsson|acer|asus|dell|meizu|motorola|polytron|infinix|tecno|micromax|advan)[-_ ]?([-\w]*)/i,
// BlackBerry/BenQ/Palm/Sony-Ericsson/Acer/Asus/Dell/Meizu/Motorola/Polytron // BlackBerry/BenQ/Palm/Sony-Ericsson/Acer/Asus/Dell/Meizu/Motorola/Polytron/Infinix/Tecno/Micromax/Advan
/; (imo) ((?!tab)[\w ]+?)(?: bui|\))/i, // IMO
/(hp) ([\w ]+\w)/i, // HP iPAQ /(hp) ([\w ]+\w)/i, // HP iPAQ
/(asus)-?(\w+)/i, // Asus /(asus)-?(\w+)/i, // Asus
/(microsoft); (lumia[\w ]+)/i, // Microsoft Lumia /(microsoft); (lumia[\w ]+)/i, // Microsoft Lumia
@@ -668,6 +696,7 @@
/(oppo) ?([\w ]+) bui/i // OPPO /(oppo) ?([\w ]+) bui/i // OPPO
], [VENDOR, MODEL, [TYPE, MOBILE]], [ ], [VENDOR, MODEL, [TYPE, MOBILE]], [
/(imo) (tab \w+)/i, // IMO
/(kobo)\s(ereader|touch)/i, // Kobo /(kobo)\s(ereader|touch)/i, // Kobo
/(archos) (gamepad2?)/i, // Archos /(archos) (gamepad2?)/i, // Archos
/(hp).+(touchpad(?!.+tablet)|tablet)/i, // HP TouchPad /(hp).+(touchpad(?!.+tablet)|tablet)/i, // HP TouchPad
@@ -801,7 +830,7 @@
], [VERSION, [NAME, 'Blink']], [ ], [VERSION, [NAME, 'Blink']], [
/(presto)\/([\w\.]+)/i, // Presto /(presto)\/([\w\.]+)/i, // Presto
/(webkit|trident|netfront|netsurf|amaya|lynx|w3m|goanna)\/([\w\.]+)/i, // WebKit/Trident/NetFront/NetSurf/Amaya/Lynx/w3m/Goanna /(webkit|trident|netfront|netsurf|amaya|lynx|w3m|goanna|servo)\/([\w\.]+)/i, // WebKit/Trident/NetFront/NetSurf/Amaya/Lynx/w3m/Goanna/Servo
/ekioh(flow)\/([\w\.]+)/i, // Flow /ekioh(flow)\/([\w\.]+)/i, // Flow
/(khtml|tasman|links)[\/ ]\(?([\w\.]+)/i, // KHTML/Tasman/Links /(khtml|tasman|links)[\/ ]\(?([\w\.]+)/i, // KHTML/Tasman/Links
/(icab)[\/ ]([23]\.[\d\.]+)/i, // iCab /(icab)[\/ ]([23]\.[\d\.]+)/i, // iCab
@@ -1228,14 +1257,21 @@
headers = extensions; // case UAParser(ua, headers) headers = extensions; // case UAParser(ua, headers)
extensions = undefined; extensions = undefined;
} }
// Convert Headers object into a plain object
if (headers && typeof headers.append === FUNC_TYPE) {
var kv = {};
headers.forEach(function (v, k) { kv[k] = v; });
headers = kv;
}
if (!(this instanceof UAParser)) { if (!(this instanceof UAParser)) {
return new UAParser(ua, extensions, headers).getResult(); return new UAParser(ua, extensions, headers).getResult();
} }
var userAgent = typeof ua === STR_TYPE ? ua : // Passed user-agent string var userAgent = typeof ua === STR_TYPE ? ua : // Passed user-agent string
((NAVIGATOR && NAVIGATOR.userAgent) ? NAVIGATOR.userAgent : // navigator.userAgent
(headers && headers[USER_AGENT] ? headers[USER_AGENT] : // User-Agent from passed headers (headers && headers[USER_AGENT] ? headers[USER_AGENT] : // User-Agent from passed headers
((NAVIGATOR && NAVIGATOR.userAgent) ? NAVIGATOR.userAgent : // navigator.userAgent
EMPTY)), // empty string EMPTY)), // empty string
httpUACH = new UACHData(headers, true), httpUACH = new UACHData(headers, true),

View File

@@ -3,7 +3,7 @@
// Source: /src/main/ua-parser.js // Source: /src/main/ua-parser.js
///////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////
/* UAParser.js v2.0.0-rc.1 /* UAParser.js v2.0.0-rc.3
Copyright © 2012-2024 Faisal Salman <f@faisalman.com> Copyright © 2012-2024 Faisal Salman <f@faisalman.com>
AGPLv3 License *//* AGPLv3 License *//*
Detect Browser, Engine, OS, CPU, and Device type/model from User-Agent data. Detect Browser, Engine, OS, CPU, and Device type/model from User-Agent data.
@@ -21,7 +21,7 @@
// Constants // Constants
///////////// /////////////
var LIBVERSION = '2.0.0-rc.1', var LIBVERSION = '2.0.0-rc.3',
EMPTY = '', EMPTY = '',
UNKNOWN = '?', UNKNOWN = '?',
FUNC_TYPE = 'function', FUNC_TYPE = 'function',
@@ -42,6 +42,7 @@
WEARABLE = 'wearable', WEARABLE = 'wearable',
XR = 'xr', XR = 'xr',
EMBEDDED = 'embedded', EMBEDDED = 'embedded',
INAPP = 'inapp',
USER_AGENT = 'user-agent', USER_AGENT = 'user-agent',
UA_MAX_LENGTH = 500, UA_MAX_LENGTH = 500,
BRANDS = 'brands', BRANDS = 'brands',
@@ -73,6 +74,7 @@
GOOGLE = 'Google', GOOGLE = 'Google',
HUAWEI = 'Huawei', HUAWEI = 'Huawei',
LENOVO = 'Lenovo', LENOVO = 'Lenovo',
HONOR = 'Honor',
LG = 'LG', LG = 'LG',
MICROSOFT = 'Microsoft', MICROSOFT = 'Microsoft',
MOTOROLA = 'Motorola', MOTOROLA = 'Motorola',
@@ -322,17 +324,19 @@
// Mixed // Mixed
/\bb[ai]*d(?:uhd|[ub]*[aekoprswx]{5,6})[\/ ]?([\w\.]+)/i // Baidu /\bb[ai]*d(?:uhd|[ub]*[aekoprswx]{5,6})[\/ ]?([\w\.]+)/i // Baidu
], [VERSION, [NAME, 'Baidu']], [ ], [VERSION, [NAME, 'Baidu']], [
/\b(?:mxbrowser|mxios|myie2)\/?([-\w\.]*)\b/i // Maxthon
], [VERSION, [NAME, 'Maxthon']], [
/(kindle)\/([\w\.]+)/i, // Kindle /(kindle)\/([\w\.]+)/i, // Kindle
/(lunascape|maxthon|netfront|jasmine|blazer|sleipnir)[\/ ]?([\w\.]*)/i, /(lunascape|maxthon|netfront|jasmine|blazer|sleipnir)[\/ ]?([\w\.]*)/i,
// Lunascape/Maxthon/Netfront/Jasmine/Blazer/Sleipnir // Lunascape/Maxthon/Netfront/Jasmine/Blazer/Sleipnir
// Trident based // Trident based
/(avant|iemobile|slim)\s?(?:browser)?[\/ ]?([\w\.]*)/i, // Avant/IEMobile/SlimBrowser /(avant|iemobile|slim(?:browser|boat|jet))[\/ ]?([\d\.]*)/i, // Avant/IEMobile/SlimBrowser/SlimBoat/Slimjet
/(?:ms|\()(ie) ([\w\.]+)/i, // Internet Explorer /(?:ms|\()(ie) ([\w\.]+)/i, // Internet Explorer
// Webkit/KHTML based // Flock/RockMelt/Midori/Epiphany/Silk/Skyfire/Bolt/Iron/Iridium/PhantomJS/Bowser/QupZilla/Falkon // Blink/Webkit/KHTML based // Flock/RockMelt/Midori/Epiphany/Silk/Skyfire/Bolt/Iron/Iridium/PhantomJS/Bowser/QupZilla/Falkon
/(flock|rockmelt|midori|epiphany|silk|skyfire|ovibrowser|bolt|iron|vivaldi|iridium|phantomjs|bowser|qupzilla|falkon|rekonq|puffin|brave|whale(?!.+naver)|qqbrowserlite|duckduckgo|klar|helio)\/([-\w\.]+)/i, /(flock|rockmelt|midori|epiphany|silk|skyfire|ovibrowser|bolt|iron|vivaldi|iridium|phantomjs|bowser|qupzilla|falkon|rekonq|puffin|brave|whale(?!.+naver)|qqbrowserlite|duckduckgo|klar|helio|(?=comodo_)?dragon)\/([-\w\.]+)/i,
// Rekonq/Puffin/Brave/Whale/QQBrowserLite/QQ//Vivaldi/DuckDuckGo/Klar/Helio // Rekonq/Puffin/Brave/Whale/QQBrowserLite/QQ//Vivaldi/DuckDuckGo/Klar/Helio/Dragon
/(heytap|ovi)browser\/([\d\.]+)/i, // HeyTap/Ovi /(heytap|ovi|115)browser\/([\d\.]+)/i, // HeyTap/Ovi/115
/(weibo)__([\d\.]+)/i // Weibo /(weibo)__([\d\.]+)/i // Weibo
], [NAME, VERSION], [ ], [NAME, VERSION], [
/quark(?:pc)?\/([-\w\.]+)/i // Quark /quark(?:pc)?\/([-\w\.]+)/i // Quark
@@ -369,31 +373,31 @@
], [VERSION, [NAME, 'MIUI' + SUFFIX_BROWSER]], [ ], [VERSION, [NAME, 'MIUI' + SUFFIX_BROWSER]], [
/fxios\/([\w\.-]+)/i // Firefox for iOS /fxios\/([\w\.-]+)/i // Firefox for iOS
], [VERSION, [NAME, PREFIX_MOBILE + FIREFOX]], [ ], [VERSION, [NAME, PREFIX_MOBILE + FIREFOX]], [
/\bqihu|(qi?ho?o?|360)browser/i // 360 /\bqihoobrowser\/?([\w\.]*)/i // 360
], [[NAME, '360' + SUFFIX_BROWSER]], [ ], [VERSION, [NAME, '360']], [
/\b(qq)\/([\w\.]+)/i // QQ /\b(qq)\/([\w\.]+)/i // QQ
], [[NAME, /(.+)/, '$1Browser'], VERSION], [ ], [[NAME, /(.+)/, '$1Browser'], VERSION], [
/(oculus|sailfish|huawei|vivo|pico)browser\/([\w\.]+)/i /(oculus|sailfish|huawei|vivo|pico)browser\/([\w\.]+)/i
], [[NAME, /(.+)/, '$1' + SUFFIX_BROWSER], VERSION], [ // Oculus/Sailfish/HuaweiBrowser/VivoBrowser/PicoBrowser ], [[NAME, /(.+)/, '$1' + SUFFIX_BROWSER], VERSION], [ // Oculus/Sailfish/HuaweiBrowser/VivoBrowser/PicoBrowser
/samsungbrowser\/([\w\.]+)/i // Samsung Internet /samsungbrowser\/([\w\.]+)/i // Samsung Internet
], [VERSION, [NAME, SAMSUNG + ' Internet']], [ ], [VERSION, [NAME, SAMSUNG + ' Internet']], [
/(comodo_dragon)\/([\w\.]+)/i // Comodo Dragon
], [[NAME, /_/g, ' '], VERSION], [
/metasr[\/ ]?([\d\.]+)/i // Sogou Explorer /metasr[\/ ]?([\d\.]+)/i // Sogou Explorer
], [VERSION, [NAME, SOGOU + ' Explorer']], [ ], [VERSION, [NAME, SOGOU + ' Explorer']], [
/(sogou)mo\w+\/([\d\.]+)/i // Sogou Mobile /(sogou)mo\w+\/([\d\.]+)/i // Sogou Mobile
], [[NAME, SOGOU + ' Mobile'], VERSION], [ ], [[NAME, SOGOU + ' Mobile'], VERSION], [
/(electron)\/([\w\.]+) safari/i, // Electron-based App /(electron)\/([\w\.]+) safari/i, // Electron-based App
/(tesla)(?: qtcarbrowser|\/(20\d\d\.[-\w\.]+))/i, // Tesla /(tesla)(?: qtcarbrowser|\/(20\d\d\.[-\w\.]+))/i, // Tesla
/m?(qqbrowser|2345Explorer)[\/ ]?([\w\.]+)/i // QQBrowser/2345 Browser /m?(qqbrowser|2345(?=browser|chrome|explorer))\w*[\/ ]?v?([\w\.]+)/i // QQ/2345
], [NAME, VERSION], [ ], [NAME, VERSION], [
/(lbbrowser|rekonq)/i, // LieBao Browser/Rekonq /(lbbrowser|rekonq)/i // LieBao Browser/Rekonq
/\[(linkedin)app\]/i // LinkedIn App for iOS & Android
], [NAME], [ ], [NAME], [
/ome\/([\w\.]+) \w* ?(iron) saf/i, // Iron
/ome\/([\w\.]+).+qihu (360)[es]e/i // 360
], [VERSION, NAME], [
// WebView // WebView
/((?:fban\/fbios|fb_iab\/fb4a)(?!.+fbav)|;fbav\/([\w\.]+);)/i // Facebook App for iOS & Android /((?:fban\/fbios|fb_iab\/fb4a)(?!.+fbav)|;fbav\/([\w\.]+);)/i // Facebook App for iOS & Android
], [[NAME, FACEBOOK], VERSION], [ ], [[NAME, FACEBOOK], VERSION, [TYPE, INAPP]], [
/(Klarna)\/([\w\.]+)/i, // Klarna Shopping Browser for iOS & Android /(Klarna)\/([\w\.]+)/i, // Klarna Shopping Browser for iOS & Android
/(kakao(?:talk|story))[\/ ]([\w\.]+)/i, // Kakao App /(kakao(?:talk|story))[\/ ]([\w\.]+)/i, // Kakao App
/(naver)\(.*?(\d+\.[\w\.]+).*\)/i, // Naver InApp /(naver)\(.*?(\d+\.[\w\.]+).*\)/i, // Naver InApp
@@ -401,12 +405,17 @@
/\b(line)\/([\w\.]+)\/iab/i, // Line App for Android /\b(line)\/([\w\.]+)\/iab/i, // Line App for Android
/(alipay)client\/([\w\.]+)/i, // Alipay /(alipay)client\/([\w\.]+)/i, // Alipay
/(twitter)(?:and| f.+e\/([\w\.]+))/i, // Twitter /(twitter)(?:and| f.+e\/([\w\.]+))/i, // Twitter
/(chromium|instagram|snapchat)[\/ ]([-\w\.]+)/i // Chromium/Instagram/Snapchat /(instagram|snapchat)[\/ ]([-\w\.]+)/i // Instagram/Snapchat
], [NAME, VERSION], [ ], [NAME, VERSION, [TYPE, INAPP]], [
/\bgsa\/([\w\.]+) .*safari\//i // Google Search Appliance on iOS /\bgsa\/([\w\.]+) .*safari\//i // Google Search Appliance on iOS
], [VERSION, [NAME, 'GSA']], [ ], [VERSION, [NAME, 'GSA'], [TYPE, INAPP]], [
/musical_ly(?:.+app_?version\/|_)([\w\.]+)/i // TikTok /musical_ly(?:.+app_?version\/|_)([\w\.]+)/i // TikTok
], [VERSION, [NAME, 'TikTok']], [ ], [VERSION, [NAME, 'TikTok'], [TYPE, INAPP]], [
/\[(linkedin)app\]/i // LinkedIn App for iOS & Android
], [NAME, [TYPE, INAPP]], [
/(chromium)[\/ ]([-\w\.]+)/i // Chromium
], [NAME, VERSION], [
/headlesschrome(?:\/([\w\.]+)| )/i // Chrome Headless /headlesschrome(?:\/([\w\.]+)| )/i // Chrome Headless
], [VERSION, [NAME, CHROME+' Headless']], [ ], [VERSION, [NAME, CHROME+' Headless']], [
@@ -440,7 +449,7 @@
], [[NAME, PREFIX_MOBILE + FIREFOX], VERSION], [ ], [[NAME, PREFIX_MOBILE + FIREFOX], VERSION], [
/(navigator|netscape\d?)\/([-\w\.]+)/i // Netscape /(navigator|netscape\d?)\/([-\w\.]+)/i // Netscape
], [[NAME, 'Netscape'], VERSION], [ ], [[NAME, 'Netscape'], VERSION], [
/(wolvic)\/([\w\.]+)/i // Wolvic /(wolvic|librewolf)\/([\w\.]+)/i // Wolvic/LibreWolf
], [NAME, VERSION], [ ], [NAME, VERSION], [
/mobile vr; rv:([\w\.]+)\).+firefox/i // Firefox Reality /mobile vr; rv:([\w\.]+)\).+firefox/i // Firefox Reality
], [VERSION, [NAME, FIREFOX+' Reality']], [ ], [VERSION, [NAME, FIREFOX+' Reality']], [
@@ -521,10 +530,14 @@
/\b(sh-?[altvz]?\d\d[a-ekm]?)/i /\b(sh-?[altvz]?\d\d[a-ekm]?)/i
], [MODEL, [VENDOR, SHARP], [TYPE, MOBILE]], [ ], [MODEL, [VENDOR, SHARP], [TYPE, MOBILE]], [
// Honor
/(?:honor)([-\w ]+)[;\)]/i
], [MODEL, [VENDOR, HONOR], [TYPE, MOBILE]], [
// Huawei // Huawei
/\b((?:ag[rs][23]?|bah2?|sht?|btv)-a?[lw]\d{2})\b(?!.+d\/s)/i /\b((?:ag[rs][23]?|bah2?|sht?|btv)-a?[lw]\d{2})\b(?!.+d\/s)/i
], [MODEL, [VENDOR, HUAWEI], [TYPE, TABLET]], [ ], [MODEL, [VENDOR, HUAWEI], [TYPE, TABLET]], [
/(?:huawei|honor)([-\w ]+)[;\)]/i, /(?:huawei)([-\w ]+)[;\)]/i,
/\b(nexus 6p|\w{2,4}e?-[atu]?[ln][\dx][012359c][adn]?)\b(?!.+d\/s)/i /\b(nexus 6p|\w{2,4}e?-[atu]?[ln][\dx][012359c][adn]?)\b(?!.+d\/s)/i
], [MODEL, [VENDOR, HUAWEI], [TYPE, MOBILE]], [ ], [MODEL, [VENDOR, HUAWEI], [TYPE, MOBILE]], [
@@ -589,7 +602,7 @@
], [MODEL, [VENDOR, GOOGLE], [TYPE, MOBILE]], [ ], [MODEL, [VENDOR, GOOGLE], [TYPE, MOBILE]], [
// Sony // Sony
/droid.+ (a?\d[0-2]{2}so|[c-g]\d{4}|so[-gl]\w+|xq-a\w[4-7][12])(?= bui|\).+chrome\/(?![1-6]{0,1}\d\.))/i /droid.+; (a?\d[0-2]{2}so|[c-g]\d{4}|so[-gl]\w+|xq-a\w[4-7][12])(?= bui|\).+chrome\/(?![1-6]{0,1}\d\.))/i
], [MODEL, [VENDOR, SONY], [TYPE, MOBILE]], [ ], [MODEL, [VENDOR, SONY], [TYPE, MOBILE]], [
/sony tablet [ps]/i, /sony tablet [ps]/i,
/\b(?:sony)?sgp\w+(?: bui|\))/i /\b(?:sony)?sgp\w+(?: bui|\))/i
@@ -655,13 +668,28 @@
/; ((?:power )?armor(?:[\w ]{0,8}))(?: bui|\))/i /; ((?:power )?armor(?:[\w ]{0,8}))(?: bui|\))/i
], [MODEL, [VENDOR, 'Ulefone'], [TYPE, MOBILE]], [ ], [MODEL, [VENDOR, 'Ulefone'], [TYPE, MOBILE]], [
// Energizer
/; (energy ?\w+)(?: bui|\))/i,
/; energizer ([\w ]+)(?: bui|\))/i
], [MODEL, [VENDOR, 'Energizer'], [TYPE, MOBILE]], [
// Cat
/; cat (b35);/i,
/; (b15q?|s22 flip|s48c|s62 pro)(?: bui|\))/i
], [MODEL, [VENDOR, 'Cat'], [TYPE, MOBILE]], [
// Smartfren
/((?:new )?andromax[\w- ]+)(?: bui|\))/i
], [MODEL, [VENDOR, 'Smartfren'], [TYPE, MOBILE]], [
// Nothing // Nothing
/droid.+; (a(?:015|06[35]|142p?))/i /droid.+; (a(?:015|06[35]|142p?))/i
], [MODEL, [VENDOR, 'Nothing'], [TYPE, MOBILE]], [ ], [MODEL, [VENDOR, 'Nothing'], [TYPE, MOBILE]], [
// MIXED // MIXED
/(blackberry|benq|palm(?=\-)|sonyericsson|acer|asus|dell|meizu|motorola|polytron|infinix|tecno)[-_ ]?([-\w]*)/i, /(blackberry|benq|palm(?=\-)|sonyericsson|acer|asus|dell|meizu|motorola|polytron|infinix|tecno|micromax|advan)[-_ ]?([-\w]*)/i,
// BlackBerry/BenQ/Palm/Sony-Ericsson/Acer/Asus/Dell/Meizu/Motorola/Polytron // BlackBerry/BenQ/Palm/Sony-Ericsson/Acer/Asus/Dell/Meizu/Motorola/Polytron/Infinix/Tecno/Micromax/Advan
/; (imo) ((?!tab)[\w ]+?)(?: bui|\))/i, // IMO
/(hp) ([\w ]+\w)/i, // HP iPAQ /(hp) ([\w ]+\w)/i, // HP iPAQ
/(asus)-?(\w+)/i, // Asus /(asus)-?(\w+)/i, // Asus
/(microsoft); (lumia[\w ]+)/i, // Microsoft Lumia /(microsoft); (lumia[\w ]+)/i, // Microsoft Lumia
@@ -670,6 +698,7 @@
/(oppo) ?([\w ]+) bui/i // OPPO /(oppo) ?([\w ]+) bui/i // OPPO
], [VENDOR, MODEL, [TYPE, MOBILE]], [ ], [VENDOR, MODEL, [TYPE, MOBILE]], [
/(imo) (tab \w+)/i, // IMO
/(kobo)\s(ereader|touch)/i, // Kobo /(kobo)\s(ereader|touch)/i, // Kobo
/(archos) (gamepad2?)/i, // Archos /(archos) (gamepad2?)/i, // Archos
/(hp).+(touchpad(?!.+tablet)|tablet)/i, // HP TouchPad /(hp).+(touchpad(?!.+tablet)|tablet)/i, // HP TouchPad
@@ -803,7 +832,7 @@
], [VERSION, [NAME, 'Blink']], [ ], [VERSION, [NAME, 'Blink']], [
/(presto)\/([\w\.]+)/i, // Presto /(presto)\/([\w\.]+)/i, // Presto
/(webkit|trident|netfront|netsurf|amaya|lynx|w3m|goanna)\/([\w\.]+)/i, // WebKit/Trident/NetFront/NetSurf/Amaya/Lynx/w3m/Goanna /(webkit|trident|netfront|netsurf|amaya|lynx|w3m|goanna|servo)\/([\w\.]+)/i, // WebKit/Trident/NetFront/NetSurf/Amaya/Lynx/w3m/Goanna/Servo
/ekioh(flow)\/([\w\.]+)/i, // Flow /ekioh(flow)\/([\w\.]+)/i, // Flow
/(khtml|tasman|links)[\/ ]\(?([\w\.]+)/i, // KHTML/Tasman/Links /(khtml|tasman|links)[\/ ]\(?([\w\.]+)/i, // KHTML/Tasman/Links
/(icab)[\/ ]([23]\.[\d\.]+)/i, // iCab /(icab)[\/ ]([23]\.[\d\.]+)/i, // iCab
@@ -1230,14 +1259,21 @@
headers = extensions; // case UAParser(ua, headers) headers = extensions; // case UAParser(ua, headers)
extensions = undefined; extensions = undefined;
} }
// Convert Headers object into a plain object
if (headers && typeof headers.append === FUNC_TYPE) {
var kv = {};
headers.forEach(function (v, k) { kv[k] = v; });
headers = kv;
}
if (!(this instanceof UAParser)) { if (!(this instanceof UAParser)) {
return new UAParser(ua, extensions, headers).getResult(); return new UAParser(ua, extensions, headers).getResult();
} }
var userAgent = typeof ua === STR_TYPE ? ua : // Passed user-agent string var userAgent = typeof ua === STR_TYPE ? ua : // Passed user-agent string
((NAVIGATOR && NAVIGATOR.userAgent) ? NAVIGATOR.userAgent : // navigator.userAgent
(headers && headers[USER_AGENT] ? headers[USER_AGENT] : // User-Agent from passed headers (headers && headers[USER_AGENT] ? headers[USER_AGENT] : // User-Agent from passed headers
((NAVIGATOR && NAVIGATOR.userAgent) ? NAVIGATOR.userAgent : // navigator.userAgent
EMPTY)), // empty string EMPTY)), // empty string
httpUACH = new UACHData(headers, true), httpUACH = new UACHData(headers, true),

View File

@@ -28,7 +28,7 @@ expectType<IBrowser>(browser);
expectType<string | undefined>(browser.name); expectType<string | undefined>(browser.name);
expectType<string | undefined>(browser.version); expectType<string | undefined>(browser.version);
expectType<string | undefined>(browser.major); expectType<string | undefined>(browser.major);
expectType<'crawler' | 'cli' | 'email' | 'fetcher' | 'inapp' | 'mediaplayer' | 'module' | undefined>(browser.type); expectType<'crawler' | 'cli' | 'email' | 'fetcher' | 'inapp' | 'mediaplayer' | 'library' | undefined>(browser.type);
expectType<boolean>(browser.is('')); expectType<boolean>(browser.is(''));
expectType<string>(browser.toString()); expectType<string>(browser.toString());
expectType<IBrowser | PromiseLike<IBrowser>>(browser.withClientHints()); expectType<IBrowser | PromiseLike<IBrowser>>(browser.withClientHints());

View File

@@ -8,8 +8,8 @@ const clis = require('./specs/browser-clis.json');
const crawlers = require('./specs/browser-crawlers.json'); const crawlers = require('./specs/browser-crawlers.json');
const emails = require('./specs/browser-emails.json'); const emails = require('./specs/browser-emails.json');
const fetchers = require('./specs/browser-fetchers.json'); const fetchers = require('./specs/browser-fetchers.json');
const modules = require('./specs/browser-modules.json'); const libraries = require('./specs/browser-libraries.json');
const { Bots, CLIs, Crawlers, Emails, Fetchers, Modules } = require('../src/extensions/ua-parser-extensions'); const { Bots, CLIs, Crawlers, Emails, Fetchers, Libraries } = require('../src/extensions/ua-parser-extensions');
describe('Extensions', () => { describe('Extensions', () => {
[ [
@@ -17,7 +17,7 @@ describe('Extensions', () => {
['Crawlers', crawlers, Crawlers], ['Crawlers', crawlers, Crawlers],
['Emails', emails, Emails], ['Emails', emails, Emails],
['Fetchers', fetchers, Fetchers], ['Fetchers', fetchers, Fetchers],
['Modules', modules, Modules] ['Libraries', libraries, Libraries]
] ]
.forEach((list) => { .forEach((list) => {
describe(list[0], () => { describe(list[0], () => {
@@ -44,10 +44,10 @@ describe('Extensions', () => {
assert.deepEqual(emailParser.setUA(outlook).getBrowser(), {name: "Microsoft Outlook", version: "16.0.9126", major: "16", type: "email"}); assert.deepEqual(emailParser.setUA(outlook).getBrowser(), {name: "Microsoft Outlook", version: "16.0.9126", major: "16", type: "email"});
assert.deepEqual(emailParser.setUA(thunderbird).getBrowser(), {name: "Thunderbird", version: "78.13.0", major: "78", type: "email"}); assert.deepEqual(emailParser.setUA(thunderbird).getBrowser(), {name: "Thunderbird", version: "78.13.0", major: "78", type: "email"});
const moduleParser = new UAParser(Modules); const libraryParser = new UAParser(Libraries);
assert.deepEqual(moduleParser.setUA(axios).getBrowser(), {name: "axios", version: "1.3.5", major: "1", type: "module"}); assert.deepEqual(libraryParser.setUA(axios).getBrowser(), {name: "axios", version: "1.3.5", major: "1", type: "library"});
assert.deepEqual(moduleParser.setUA(jsdom).getBrowser(), {name: "jsdom", version: "20.0.3", major: "20", type: "module"}); assert.deepEqual(libraryParser.setUA(jsdom).getBrowser(), {name: "jsdom", version: "20.0.3", major: "20", type: "library"});
assert.deepEqual(moduleParser.setUA(scrapy).getBrowser(), {name: "Scrapy", version: "1.5.0", major: "1", type: "module"}); assert.deepEqual(libraryParser.setUA(scrapy).getBrowser(), {name: "Scrapy", version: "1.5.0", major: "1", type: "library"});
}); });
describe('Merge', () => { describe('Merge', () => {

View File

@@ -1,6 +1,7 @@
const assert = require('assert'); const assert = require('assert');
const { UAParser } = require('../src/main/ua-parser'); const { UAParser } = require('../src/main/ua-parser');
const { getDeviceVendor, isAppleSilicon, isChromeFamily } = require('../src/helpers/ua-parser-helpers'); const { getDeviceVendor, isAppleSilicon, isBot, isChromeFamily } = require('../src/helpers/ua-parser-helpers');
const { Bots, Emails } = require('../src/extensions/ua-parser-extensions');
describe('getDeviceVendor', () => { describe('getDeviceVendor', () => {
it('Can guess the device vendor from a model name', () => { it('Can guess the device vendor from a model name', () => {
@@ -31,6 +32,23 @@ describe('isAppleSilicon', () => {
}); });
}); });
describe('isBot', () => {
it('Can detect Bots', () => {
// non-real ua
const ahrefsBot = 'Mozilla/5.0 (compatible; AhrefsBot/7.0; +http://ahrefs.com/robot/)';
const firefox = 'Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/111.0';
const scrapy = 'Scrapy/1.5.0 (+https://scrapy.org)';
const thunderbird = 'Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Thunderbird/78.13.0';
const botParser = new UAParser(firefox, { Bots, Emails });
assert.equal(isBot(botParser.getResult()), false);
assert.equal(isBot(botParser.setUA(ahrefsBot).getResult()), true);
assert.equal(isBot(botParser.setUA(scrapy).getResult()), true);
assert.equal(isBot(botParser.setUA(thunderbird).getResult()), false);
});
});
describe('isChromeFamily', () => { describe('isChromeFamily', () => {
it('Can detect Chromium-based browser', () => { it('Can detect Chromium-based browser', () => {

View File

@@ -17,7 +17,7 @@ var methods = [
title : 'getBrowser', title : 'getBrowser',
label : 'browser', label : 'browser',
list : browsers, list : browsers,
properties : ['name', 'major', 'version'] properties : ['name', 'major', 'version', 'type']
}, },
{ {
title : 'getCPU', title : 'getCPU',

View File

@@ -123,4 +123,21 @@ test.describe('withFeatureCheck() tests', () => {
expect(uap).toHaveProperty('device.model', 'iPad'); expect(uap).toHaveProperty('device.model', 'iPad');
expect(uap).toHaveProperty('device.type', 'tablet'); expect(uap).toHaveProperty('device.type', 'tablet');
}); });
}); });
test.describe('request.headers can be passed in form of a Headers object', () => {
test('Headers automatically converted into a plain key-value object', async ({ page }) => {
await page.addInitScript(() => {
Object.defineProperty(window, 'req', {
value : {
headers: new Headers([["User-Agent", "myBrowser/1.0"]])
}
});
});
await page.goto(localHtml);
// @ts-ignore
const uap = await page.evaluate(() => UAParser(req.headers));
expect(uap.ua).toBe('myBrowser/1.0');
});
});

View File

@@ -1,12 +1,72 @@
[ [
{
"desc" : "115 Browser",
"ua" : "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_16_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.61 Safari/537.36 115Browser/24.3.0.3",
"expect" :
{
"name" : "115",
"version" : "24.3.0.3",
"major" : "24"
}
},
{
"desc" : "2345 Browser",
"ua" : "Mozilla/5.0 (Linux; Android 7.0; MI NOTE Pro Build/NRD90M; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/61.0.3163.98 Mobile Safari/537.36 Mb2345Browser/15.6.2",
"expect" :
{
"name" : "2345",
"version" : "15.6.2",
"major" : "15"
}
},
{
"desc" : "2345 Chrome",
"ua" : "Mozilla/5.0 (Windows NT 6.3) AppleWebKit/537.36 (KHTML like Gecko) Chrome/39.0.2171.99 Safari/537.36 2345chrome v3.0.0.9739",
"expect" :
{
"name" : "2345",
"version" : "3.0.0.9739",
"major" : "3"
}
},
{
"desc" : "2345 Explorer",
"ua" : "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.90 Safari/537.36 2345Explorer/9.2.1.17116",
"expect" :
{
"name" : "2345",
"version" : "9.2.1.17116",
"major" : "9"
}
},
{ {
"desc" : "360 Browser on iOS", "desc" : "360 Browser on iOS",
"ua" : "Mozilla/5.0 (iPhone; CPU iPhone OS 12_4_1 like Mac OS X) AppleWebKit/607.3.9 (KHTML, like Gecko) Mobile/16G102 QHBrowser/317 QihooBrowser/4.0.10", "ua" : "Mozilla/5.0 (iPhone; CPU iPhone OS 12_4_1 like Mac OS X) AppleWebKit/607.3.9 (KHTML, like Gecko) Mobile/16G102 QHBrowser/317 QihooBrowser/4.0.10",
"expect" : "expect" :
{ {
"name" : "360 Browser", "name" : "360",
"version" : "undefined", "version" : "4.0.10",
"major" : "undefined" "major" : "4"
}
},
{
"desc" : "360 Secure Browser on Windows 10",
"ua" : "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36 QIHU 360SE",
"expect" :
{
"name" : "360",
"version" : "86.0.4240.198",
"major" : "86"
}
},
{
"desc" : "360 Speed Browser on Windows 10",
"ua" : "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36 QIHU 360EE",
"expect" :
{
"name" : "360",
"version" : "86.0.4240.198",
"major" : "86"
} }
}, },
{ {
@@ -16,7 +76,8 @@
{ {
"name" : "Alipay", "name" : "Alipay",
"version" : "10.2.51.7100", "version" : "10.2.51.7100",
"major" : "10" "major" : "10",
"type" : "inapp"
} }
}, },
{ {
@@ -26,7 +87,8 @@
{ {
"name" : "Alipay", "name" : "Alipay",
"version" : "10.3.50.9999", "version" : "10.3.50.9999",
"major" : "10" "major" : "10",
"type" : "inapp"
} }
}, },
{ {
@@ -404,11 +466,21 @@
"ua" : "Mozilla/5.0 (Windows NT 6.2) AppleWebKit/535.7 (KHTML, like Gecko) Comodo_Dragon/16.1.1.0 Chrome/16.0.912.63 Safari/535.7", "ua" : "Mozilla/5.0 (Windows NT 6.2) AppleWebKit/535.7 (KHTML, like Gecko) Comodo_Dragon/16.1.1.0 Chrome/16.0.912.63 Safari/535.7",
"expect" : "expect" :
{ {
"name" : "Comodo Dragon", "name" : "Dragon",
"version" : "16.1.1.0", "version" : "16.1.1.0",
"major" : "16" "major" : "16"
} }
}, },
{
"desc" : "Comodo Dragon",
"ua" : "Mozilla/5.0 (Windows NT 10.0) AppleWebKit/537.36 (KHTML, like Gecko) Dragon/98.0.4758.102 Chrome/98.0.4758.102 Safari/537.36",
"expect" :
{
"name" : "Dragon",
"version" : "98.0.4758.102",
"major" : "98"
}
},
{ {
"desc" : "Conkeror", "desc" : "Conkeror",
"ua" : "Mozilla/5.0 (X11; Linux x86_64; rv:6.0.1) Gecko/20110831 conkeror/0.9.3", "ua" : "Mozilla/5.0 (X11; Linux x86_64; rv:6.0.1) Gecko/20110831 conkeror/0.9.3",
@@ -536,7 +608,8 @@
{ {
"name" : "Facebook", "name" : "Facebook",
"version" : "35.0.0.48.273", "version" : "35.0.0.48.273",
"major" : "35" "major" : "35",
"type" : "inapp"
} }
}, },
{ {
@@ -546,7 +619,8 @@
{ {
"name" : "Facebook", "name" : "Facebook",
"version" : "91.0.0.41.73", "version" : "91.0.0.41.73",
"major" : "91" "major" : "91",
"type" : "inapp"
} }
}, },
{ {
@@ -556,7 +630,8 @@
{ {
"name" : "Facebook", "name" : "Facebook",
"version" : "undefined", "version" : "undefined",
"major" : "undefined" "major" : "undefined",
"type" : "inapp"
} }
}, },
{ {
@@ -566,7 +641,8 @@
{ {
"name" : "Klarna", "name" : "Klarna",
"version" : "23.36.223", "version" : "23.36.223",
"major" : "23" "major" : "23",
"type" : "inapp"
} }
}, },
{ {
@@ -576,7 +652,8 @@
{ {
"name" : "Klarna", "name" : "Klarna",
"version" : "23.36.215", "version" : "23.36.215",
"major" : "23" "major" : "23",
"type" : "inapp"
} }
}, },
{ {
@@ -586,7 +663,8 @@
{ {
"name" : "Instagram", "name" : "Instagram",
"version" : "142.0.0.22.109", "version" : "142.0.0.22.109",
"major" : "142" "major" : "142",
"type" : "inapp"
} }
}, },
{ {
@@ -848,6 +926,26 @@
"major" : "22" "major" : "22"
} }
}, },
{
"desc" : "Iron",
"ua" : "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Iron Safari/537.36",
"expect" :
{
"name" : "Iron",
"version" : "129.0.0.0",
"major" : "129"
}
},
{
"desc" : "Iron",
"ua" : "Mozilla/5.0 (Linux; Android 11; Pixel 4 XL) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Mobile Iron Safari/537.36",
"expect" :
{
"name" : "Iron",
"version" : "113.0.0.0",
"major" : "113"
}
},
{ {
"desc" : "Jasmine", "desc" : "Jasmine",
"ua" : "SAMSUNG-S8000/S8000XXIF3 SHP/VPP/R5 Jasmine/1.0 Nextreaming SMM-MMS/1.2.0 profile/MIDP-2.1 configuration/CLDC-1.1", "ua" : "SAMSUNG-S8000/S8000XXIF3 SHP/VPP/R5 Jasmine/1.0 Nextreaming SMM-MMS/1.2.0 profile/MIDP-2.1 configuration/CLDC-1.1",
@@ -968,6 +1066,26 @@
"major" : "9" "major" : "9"
} }
}, },
{
"desc" : "LibreWolf",
"ua" : "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:91.0) Gecko/20100101 LibreWolf/91.0",
"expect" :
{
"name" : "LibreWolf",
"version" : "91.0",
"major" : "91"
}
},
{
"desc" : "LibreWolf",
"ua" : "Mozilla/5.0 (X11; Linux x86_64; rv:97.0) Gecko/20100101 Firefox/97.0 LibreWolf/97.0.1",
"expect" :
{
"name" : "LibreWolf",
"version" : "97.0.1",
"major" : "97"
}
},
{ {
"desc" : "LINE on Android", "desc" : "LINE on Android",
"ua" : "Mozilla/5.0 (Linux; Android 5.0; ASUS_Z00AD Build/LRX21V; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/51.0.2704.81 Mobile Safari/537.36 Line/6.5.1/IAB", "ua" : "Mozilla/5.0 (Linux; Android 5.0; ASUS_Z00AD Build/LRX21V; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/51.0.2704.81 Mobile Safari/537.36 Line/6.5.1/IAB",
@@ -975,7 +1093,8 @@
{ {
"name" : "Line", "name" : "Line",
"version" : "6.5.1", "version" : "6.5.1",
"major" : "6" "major" : "6",
"type" : "inapp"
} }
}, },
{ {
@@ -985,7 +1104,8 @@
{ {
"name" : "Line", "name" : "Line",
"version" : "8.4.1", "version" : "8.4.1",
"major" : "8" "major" : "8",
"type" : "inapp"
} }
}, },
{ {
@@ -1019,7 +1139,57 @@
} }
}, },
{ {
"desc" : "Maxthon", "desc" : "Maxthon on Android",
"ua" : "Mozilla/5.0 (Linux; Android 5.1.1; KFAUWI Build/LVY48F; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/100.0.4896.127 Safari/537.36 MxBrowser/4.3.5.2000",
"expect" :
{
"name" : "Maxthon",
"version" : "4.3.5.2000",
"major" : "4"
}
},
{
"desc" : "Maxthon on iOS",
"ua" : "Mozilla/5.0 (iPad; CPU OS 13_6 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/10.0 Mobile/15E148 Safari/602.1 MXiOS/5.4.5.2",
"expect" :
{
"name" : "Maxthon",
"version" : "5.4.5.2",
"major" : "5"
}
},
{
"desc" : "Maxthon on Linux",
"ua" : "Mozilla/5.0 (X11; Linux i686; Ubuntu 14.04.3 LTS) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.0 Maxthon/1.0.5.3 Safari/537.36",
"expect" :
{
"name" : "Maxthon",
"version" : "1.0.5.3",
"major" : "1"
}
},
{
"desc" : "Maxthon on macOS",
"ua" : "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/604.5.6 (KHTML, like Gecko) Version/11.0.3 Safari/604.5.6 Maxthon/5.1.102",
"expect" :
{
"name" : "Maxthon",
"version" : "5.1.102",
"major" : "5"
}
},
{
"desc" : "Maxthon on Windows Server 2003",
"ua" : "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; MyIE2; .NET CLR 1.1.4322)",
"expect" :
{
"name" : "Maxthon",
"version" : "undefined",
"major" : "undefined"
}
},
{
"desc" : "Maxthon on Windows XP",
"ua" : "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; SV1; Maxthon; .NET CLR 1.1.4322)", "ua" : "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; SV1; Maxthon; .NET CLR 1.1.4322)",
"expect" : "expect" :
{ {
@@ -1028,6 +1198,16 @@
"major" : "undefined" "major" : "undefined"
} }
}, },
{
"desc" : "Maxthon on Windows 10",
"ua" : "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.79 Safari/537.36 Maxthon/5.2.7.2000",
"expect" :
{
"name" : "Maxthon",
"version" : "5.2.7.2000",
"major" : "5"
}
},
{ {
"desc" : "Midori", "desc" : "Midori",
"ua" : "Midori/0.2.2 (X11; Linux i686; U; en-us) WebKit/531.2+", "ua" : "Midori/0.2.2 (X11; Linux i686; U; en-us) WebKit/531.2+",
@@ -1599,16 +1779,36 @@
"major" : "2" "major" : "2"
} }
}, },
{
"desc" : "SlimBoat",
"ua" : "Mozilla/5.0 (Windows NT 5.2) AppleWebKit/534.34 (KHTML, like Gecko) SlimBoat/1.1.23 Chrome/11.0.696.7 Version/5.1 Safari/534.34",
"expect" :
{
"name" : "SlimBoat",
"version" : "1.1.23",
"major" : "1"
}
},
{ {
"desc" : "SlimBrowser", "desc" : "SlimBrowser",
"ua" : "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; Trident/4.0; SlimBrowser)", "ua" : "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; Trident/4.0; SlimBrowser)",
"expect" : "expect" :
{ {
"name" : "Slim", "name" : "SlimBrowser",
"version" : "undefined", "version" : "undefined",
"major" : "undefined" "major" : "undefined"
} }
}, },
{
"desc" : "Slimjet",
"ua" : "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.75 Safari/537.36 Slimjet/20.0.2.0",
"expect" :
{
"name" : "Slimjet",
"version" : "20.0.2.0",
"major" : "20"
}
},
{ {
"desc" : "Swiftfox", "desc" : "Swiftfox",
"ua" : "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.1) Gecko/20061024 Firefox/2.0 (Swiftfox)", "ua" : "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.1) Gecko/20061024 Firefox/2.0 (Swiftfox)",
@@ -2056,7 +2256,8 @@
{ {
"name" : "GSA", "name" : "GSA",
"version" : "30.1.161623614", "version" : "30.1.161623614",
"major" : "30" "major" : "30",
"type" : "inapp"
} }
}, },
{ {
@@ -2087,16 +2288,6 @@
"name" : "LBBROWSER" "name" : "LBBROWSER"
} }
}, },
{
"desc" : "2345 Browser",
"ua" : "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.90 Safari/537.36 2345Explorer/9.2.1.17116",
"expect" :
{
"name" : "2345Explorer",
"version" : "9.2.1.17116",
"major" : "9"
}
},
{ {
"desc" : "QQBrowserLite", "desc" : "QQBrowserLite",
"ua" : "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_1) AppleWebKit/602.2.14 (KHTML, like Gecko) Version/10.0.1 Safari/602.2.14 QQBrowserLite/1.1.0", "ua" : "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_1) AppleWebKit/602.2.14 (KHTML, like Gecko) Version/10.0.1 Safari/602.2.14 QQBrowserLite/1.1.0",
@@ -2152,7 +2343,8 @@
"ua" : "Mozilla/5.0 (iPhone; CPU iPhone OS 15_4_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 [LinkedInApp]", "ua" : "Mozilla/5.0 (iPhone; CPU iPhone OS 15_4_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 [LinkedInApp]",
"expect" : "expect" :
{ {
"name" : "LinkedIn" "name" : "LinkedIn",
"type" : "inapp"
} }
}, },
{ {
@@ -2257,7 +2449,8 @@
"expect" : { "expect" : {
"name" : "KAKAOTALK", "name" : "KAKAOTALK",
"version": "2409760", "version": "2409760",
"major" : "2409760" "major" : "2409760",
"type" : "inapp"
} }
}, },
{ {
@@ -2266,7 +2459,8 @@
"expect" : { "expect" : {
"name" : "KAKAOSTORY", "name" : "KAKAOSTORY",
"version": "6.8.3_21046", "version": "6.8.3_21046",
"major" : "6" "major" : "6",
"type" : "inapp"
} }
}, },
{ {
@@ -2275,7 +2469,8 @@
"expect" : { "expect" : {
"name" : "KAKAOTALK", "name" : "KAKAOTALK",
"version": "9.7.6", "version": "9.7.6",
"major" : "9" "major" : "9",
"type" : "inapp"
} }
}, },
{ {
@@ -2284,7 +2479,8 @@
"expect" : { "expect" : {
"name" : "NAVER", "name" : "NAVER",
"version": "11.11.2", "version": "11.11.2",
"major" : "11" "major" : "11",
"type" : "inapp"
} }
}, },
{ {
@@ -2293,7 +2489,8 @@
"expect" : { "expect" : {
"name" : "NAVER", "name" : "NAVER",
"version": "10.25.0", "version": "10.25.0",
"major" : "10" "major" : "10",
"type" : "inapp"
} }
}, },
{ {
@@ -2302,7 +2499,8 @@
"expect" : { "expect" : {
"name" : "TikTok", "name" : "TikTok",
"version": "21.9.4", "version": "21.9.4",
"major" : "21" "major" : "21",
"type" : "inapp"
} }
}, },
{ {
@@ -2311,7 +2509,8 @@
"expect" : { "expect" : {
"name" : "TikTok", "name" : "TikTok",
"version": "21.1.0", "version": "21.1.0",
"major" : "21" "major" : "21",
"type" : "inapp"
} }
}, },
{ {
@@ -2320,7 +2519,8 @@
"expect" : { "expect" : {
"name" : "TikTok", "name" : "TikTok",
"version": "28.3.4", "version": "28.3.4",
"major" : "28" "major" : "28",
"type" : "inapp"
} }
}, },
{ {
@@ -2360,7 +2560,8 @@
{ {
"name" : "Snapchat", "name" : "Snapchat",
"version" : "12.33.0.36", "version" : "12.33.0.36",
"major" : "12" "major" : "12",
"type" : "inapp"
} }
}, },
{ {
@@ -2370,7 +2571,8 @@
{ {
"name" : "Twitter", "name" : "Twitter",
"version" : "undefined", "version" : "undefined",
"major" : "undefined" "major" : "undefined",
"type" : "inapp"
} }
}, },
{ {
@@ -2380,7 +2582,8 @@
{ {
"name" : "Twitter", "name" : "Twitter",
"version" : "10.34", "version" : "10.34",
"major" : "10" "major" : "10",
"type" : "inapp"
} }
} }
] ]

View File

@@ -1,4 +1,44 @@
[ [
{
"desc" : "360Spider",
"ua" : "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0); 360Spider",
"expect" :
{
"name" : "360Spider",
"version" : "undefined",
"type" : "crawler"
}
},
{
"desc" : "AdsBot Mobile Web",
"ua" : "AdsBot-Google (+http://www.google.com/adsbot.html)",
"expect" :
{
"name" : "AdsBot-Google",
"version" : "undefined",
"type" : "crawler"
}
},
{
"desc" : "AdsBot Mobile Web",
"ua" : "Mozilla/5.0 (Linux; Android 6.0.1; Nexus 5X Build/MMB29P) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.96 Mobile Safari/537.36 (compatible; AdsBot-Google-Mobile; +http://www.google.com/mobile/adsbot.html)",
"expect" :
{
"name" : "AdsBot-Google-Mobile",
"version" : "undefined",
"type" : "crawler"
}
},
{
"desc" : "AdSense",
"ua" : "Mediapartners-Google",
"expect" :
{
"name" : "Mediapartners-Google",
"version" : "undefined",
"type" : "crawler"
}
},
{ {
"desc" : "AhrefsBot", "desc" : "AhrefsBot",
"ua" : "Mozilla/5.0 (compatible; AhrefsBot/7.0; +http://ahrefs.com/robot/)", "ua" : "Mozilla/5.0 (compatible; AhrefsBot/7.0; +http://ahrefs.com/robot/)",
@@ -49,6 +89,16 @@
"type" : "crawler" "type" : "crawler"
} }
}, },
{
"desc" : "CCBot",
"ua" : "CCBot/1.0 (+https://commoncrawl.org/bot.html)",
"expect" :
{
"name" : "CCBot",
"version" : "1.0",
"type" : "crawler"
}
},
{ {
"desc" : "Coc Coc Bot (web)", "desc" : "Coc Coc Bot (web)",
"ua" : "Mozilla/5.0 (compatible; coccocbot-web/1.0; +http://help.coccoc.com/searchengine)", "ua" : "Mozilla/5.0 (compatible; coccocbot-web/1.0; +http://help.coccoc.com/searchengine)",
@@ -79,6 +129,16 @@
"type" : "crawler" "type" : "crawler"
} }
}, },
{
"desc" : "DataForSEO",
"ua" : "Mozilla/5.0 (compatible; DataForSeoBot; +https://dataforseo.com/dataforseo-bot) ",
"expect" :
{
"name" : "DataForSeoBot",
"version" : "undefined",
"type" : "crawler"
}
},
{ {
"desc" : "Dotbot", "desc" : "Dotbot",
"ua" : "Mozilla/5.0 (compatible; DotBot/1.2; +https://opensiteexplorer.org/dotbot; help@moz.com)", "ua" : "Mozilla/5.0 (compatible; DotBot/1.2; +https://opensiteexplorer.org/dotbot; help@moz.com)",
@@ -89,6 +149,16 @@
"type" : "crawler" "type" : "crawler"
} }
}, },
{
"desc" : "Exabot",
"ua" : "Mozilla/5.0 (compatible; Exabot/3.0; +http://www.exabot.com/go/robot)",
"expect" :
{
"name" : "Exabot",
"version" : "3.0",
"type" : "crawler"
}
},
{ {
"desc" : "FacebookBot", "desc" : "FacebookBot",
"ua" : "Mozilla/5.0 (compatible; FacebookBot/1.0; +https://developers.facebook.com/docs/sharing/webmasters/facebookbot/", "ua" : "Mozilla/5.0 (compatible; FacebookBot/1.0; +https://developers.facebook.com/docs/sharing/webmasters/facebookbot/",
@@ -99,6 +169,26 @@
"type" : "crawler" "type" : "crawler"
} }
}, },
{
"desc" : "FacebookExternalHit",
"ua" : "facebookexternalhit/1.1 (+http://www.facebook.com/externalhit_uatext.php)",
"expect" :
{
"name" : "facebookexternalhit",
"version" : "1.1",
"type" : "crawler"
}
},
{
"desc" : "FacebookExternalHit",
"ua" : "facebookcatalog/1.0",
"expect" :
{
"name" : "facebookcatalog",
"version" : "1.0",
"type" : "crawler"
}
},
{ {
"desc" : "Googlebot-Video", "desc" : "Googlebot-Video",
"ua" : "Googlebot-Video/1.0", "ua" : "Googlebot-Video/1.0",
@@ -109,6 +199,106 @@
"type" : "crawler" "type" : "crawler"
} }
}, },
{
"desc" : "Googlebot",
"ua" : "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)",
"expect" :
{
"name" : "Googlebot",
"version" : "2.1",
"type" : "crawler"
}
},
{
"desc" : "Googlebot Image",
"ua" : "Googlebot-Image/1.0",
"expect" :
{
"name" : "Googlebot-Image",
"version" : "1.0",
"type" : "crawler"
}
},
{
"desc" : "Googlebot Video",
"ua" : "Googlebot-Video/1.0",
"expect" :
{
"name" : "Googlebot-Video",
"version" : "1.0",
"type" : "crawler"
}
},
{
"desc" : "Googlebot News",
"ua" : "Googlebot-News/1.0",
"expect" :
{
"name" : "Googlebot-News",
"version" : "1.0",
"type" : "crawler"
}
},
{
"desc" : "Google Storebot",
"ua" : "Storebot-Google/1.0",
"expect" :
{
"name" : "Storebot-Google",
"version" : "1.0",
"type" : "crawler"
}
},
{
"desc" : "Google InspectionTool",
"ua" : "Mozilla/5.0 (compatible; Google-InspectionTool/1.0;)",
"expect" :
{
"name" : "Google-InspectionTool",
"version" : "1.0",
"type" : "crawler"
}
},
{
"desc" : "GoogleOther",
"ua" : "Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; GoogleOther) Chrome/41.0.2272.96 Safari/537.36",
"expect" :
{
"name" : "GoogleOther",
"version" : "undefined",
"type" : "crawler"
}
},
{
"desc" : "GoogleOther-Image",
"ua" : "GoogleOther-Image/1.0",
"expect" :
{
"name" : "GoogleOther-Image",
"version" : "1.0",
"type" : "crawler"
}
},
{
"desc" : "GoogleOther-Video",
"ua" : "GoogleOther-Video/1.0",
"expect" :
{
"name" : "GoogleOther-Video",
"version" : "1.0",
"type" : "crawler"
}
},
{
"desc" : "Google-Safety",
"ua" : "Google-Safety",
"expect" :
{
"name" : "Google-Safety",
"version" : "undefined",
"type" : "crawler"
}
},
{ {
"desc" : "GPTBot", "desc" : "GPTBot",
"ua" : "Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; GPTBot/1.0; +https://openai.com/gptbot)", "ua" : "Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; GPTBot/1.0; +https://openai.com/gptbot)",
@@ -119,6 +309,36 @@
"type" : "crawler" "type" : "crawler"
} }
}, },
{
"desc" : "Archive.org Bot",
"ua" : "ia_archiver/8.1 (Windows 2000 1.9; en-US;)",
"expect" :
{
"name" : "ia_archiver",
"version" : "8.1",
"type" : "crawler"
}
},
{
"desc" : "Archive.org Bot",
"ua" : "Mozilla/5.0 (compatible; archive.org_bot/3.3.0 +https://archive.org/details/archive.org_bot)",
"expect" :
{
"name" : "archive.org_bot",
"version" : "3.3.0",
"type" : "crawler"
}
},
{
"desc" : "Meta-ExternalAgent",
"ua" : "meta-externalagent/1.1 (+https://developers.facebook.com/docs/sharing/webmasters/crawler)",
"expect" :
{
"name" : "meta-externalagent",
"version" : "1.1",
"type" : "crawler"
}
},
{ {
"desc" : "MJ12bot", "desc" : "MJ12bot",
"ua" : "Mozilla/5.0 (compatible; MJ12bot/v1.4.8; http://mj12bot.com/)", "ua" : "Mozilla/5.0 (compatible; MJ12bot/v1.4.8; http://mj12bot.com/)",
@@ -126,6 +346,17 @@
{ {
"name" : "MJ12bot", "name" : "MJ12bot",
"version" : "v1.4.8", "version" : "v1.4.8",
"major" : "1",
"type" : "crawler"
}
},
{
"desc" : "MojeekBot",
"ua" : "Mozilla/5.0 (compatible; MojeekBot/0.11; +https://www.mojeek.com/bot.html)",
"expect" :
{
"name" : "MojeekBot",
"version" : "0.11",
"type" : "crawler" "type" : "crawler"
} }
}, },
@@ -139,6 +370,36 @@
"type" : "crawler" "type" : "crawler"
} }
}, },
{
"desc" : "PerplexityBot",
"ua" : "Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; PerplexityBot/1.0; +https://perplexity.ai/perplexitybot)",
"expect" :
{
"name" : "PerplexityBot",
"version" : "1.0",
"type" : "crawler"
}
},
{
"desc" : "PetalBot",
"ua" : "Mozilla/5.0 (compatible;PetalBot; +https://webmaster.petalsearch.com/site/petalbot) ",
"expect" :
{
"name" : "PetalBot",
"version" : "undefined",
"type" : "crawler"
}
},
{
"desc" : "PetalBot",
"ua" : "Mozilla/5.0 (Linux; Android 7.0;) AppleWebKit/537.36 (KHTML, like Gecko) Mobile Safari/537.36 (compatible; PetalBot;+https://webmaster.petalsearch.com/site/petalbot) ",
"expect" :
{
"name" : "PetalBot",
"version" : "undefined",
"type" : "crawler"
}
},
{ {
"desc" : "SemrushBot", "desc" : "SemrushBot",
"ua" : "Mozilla/5.0 (compatible; SemrushBot/7~bl; +http://www.semrush.com/bot.html)", "ua" : "Mozilla/5.0 (compatible; SemrushBot/7~bl; +http://www.semrush.com/bot.html)",
@@ -149,6 +410,16 @@
"type" : "crawler" "type" : "crawler"
} }
}, },
{
"desc" : "TurnitinBot",
"ua" : "TurnitinBot (https://turnitin.com/robot/crawlerinfo.html)",
"expect" :
{
"name" : "TurnitinBot",
"version" : "undefined",
"type" : "crawler"
}
},
{ {
"desc" : "Yahoo! Japan", "desc" : "Yahoo! Japan",
"ua" : "Y!J-BRW/1.0 (https://www.yahoo-help.jp/app/answers/detail/p/595/a_id/42716)", "ua" : "Y!J-BRW/1.0 (https://www.yahoo-help.jp/app/answers/detail/p/595/a_id/42716)",
@@ -168,5 +439,35 @@
"version" : "3.0", "version" : "3.0",
"type" : "crawler" "type" : "crawler"
} }
},
{
"desc" : "Yeti",
"ua" : "Mozilla/5.0 (compatible; Yeti/1.1; +http://naver.me/spd)",
"expect" :
{
"name" : "Yeti",
"version" : "1.1",
"type" : "crawler"
}
},
{
"desc" : "YisouSpider",
"ua" : "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.81 YisouSpider/5.0 Safari/537.36",
"expect" :
{
"name" : "YisouSpider",
"version" : "5.0",
"type" : "crawler"
}
},
{
"desc" : "YisouSpider",
"ua" : "YisouSpider",
"expect" :
{
"name" : "YisouSpider",
"version" : "undefined",
"type" : "crawler"
}
} }
] ]

View File

@@ -1,4 +1,64 @@
[ [
{
"desc" : "Evolution",
"ua" : "Evolution/3.52.3",
"expect" :
{
"name" : "Evolution",
"version" : "3.52.3",
"type" : "email"
}
},
{
"desc" : "KMail",
"ua" : "KMail/4.14.10 (FreeBSD/12.0-CURRENT; KDE/4.14.10; amd64; ; )",
"expect" :
{
"name" : "KMail",
"version" : "4.14.10",
"type" : "email"
}
},
{
"desc" : "KMail2",
"ua" : "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/534.34 (KHTML, like Gecko) kmail2/5.7.3 Safari/534.34",
"expect" :
{
"name" : "kmail2",
"version" : "5.7.3",
"type" : "email"
}
},
{
"desc" : "Kontact",
"ua" : "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/534.34 (KHTML, like Gecko) kontact/4.13.3 Safari/534.34",
"expect" :
{
"name" : "kontact",
"version" : "4.13.3",
"type" : "email"
}
},
{
"desc" : "Microsoft Outlook",
"ua" : "Microsoft Office/16.0 (Windows NT 10.0; Microsoft Outlook 16.0.5431; Pro)",
"expect" :
{
"name" : "Microsoft Outlook",
"version" : "16.0.5431",
"type" : "email"
}
},
{
"desc" : "Microsoft Outlook for Mac",
"ua" : "MacOutlook/14.7.1.161129 (Intel Mac OS X 10.9.6)",
"expect" :
{
"name" : "MacOutlook",
"version" : "14.7.1.161129",
"type" : "email"
}
},
{ {
"desc" : "Thunderbird", "desc" : "Thunderbird",
"ua" : "Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Thunderbird/78.13.0", "ua" : "Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Thunderbird/78.13.0",

View File

@@ -29,6 +29,76 @@
"type" : "fetcher" "type" : "fetcher"
} }
}, },
{
"desc" : "DuckAssistBot",
"ua" : "DuckAssistBot/1.2; (+http://duckduckgo.com/duckassistbot.html)",
"expect" :
{
"name" : "DuckAssistBot",
"version" : "1.2",
"type" : "fetcher"
}
},
{
"desc" : "Google FeedFetcher",
"ua" : "FeedFetcher-Google; (+http://www.google.com/feedfetcher.html)",
"expect" :
{
"name" : "FeedFetcher-Google",
"version" : "undefined",
"type" : "fetcher"
}
},
{
"desc" : "Google Read Aloud - Mobile agent",
"ua" : "Mozilla/5.0 (Linux; Android 7.0; SM-G930V Build/NRD90M) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.125 Mobile Safari/537.36 (compatible; Google-Read-Aloud; +https://support.google.com/webmasters/answer/1061943)",
"expect" :
{
"name" : "Google-Read-Aloud",
"version" : "undefined",
"type" : "fetcher"
}
},
{
"desc" : "Google Read Aloud - Desktop agent",
"ua" : "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.118 Safari/537.36 (compatible; Google-Read-Aloud; +https://support.google.com/webmasters/answer/1061943)",
"expect" :
{
"name" : "Google-Read-Aloud",
"version" : "undefined",
"type" : "fetcher"
}
},
{
"desc" : "Google Publisher Center",
"ua" : "GoogleProducer; (+https://developers.google.com/search/docs/crawling-indexing/google-producer)",
"expect" :
{
"name" : "GoogleProducer",
"version" : "undefined",
"type" : "fetcher"
}
},
{
"desc" : "Google Site Verifier",
"ua" : "Mozilla/5.0 (compatible; Google-Site-Verification/1.0)",
"expect" :
{
"name" : "Google-Site-Verification",
"version" : "1.0",
"type" : "fetcher"
}
},
{
"desc" : "Meta-ExternalFetcher",
"ua" : "meta-externalfetcher/1.1 (+https://developers.facebook.com/docs/sharing/webmasters/crawler)",
"expect" :
{
"name" : "meta-externalfetcher",
"version" : "1.1",
"type" : "fetcher"
}
},
{ {
"desc" : "Rogerbot", "desc" : "Rogerbot",
"ua" : "Mozilla/5.0 (compatible; rogerBot/1.0; UrlCrawler; http://www.seomoz.org/dp/rogerbot)", "ua" : "Mozilla/5.0 (compatible; rogerBot/1.0; UrlCrawler; http://www.seomoz.org/dp/rogerbot)",

View File

@@ -6,7 +6,7 @@
{ {
"name" : "Scrapy", "name" : "Scrapy",
"version" : "1.5.0", "version" : "1.5.0",
"type" : "module" "type" : "library"
} }
} }
] ]

View File

@@ -8,6 +8,33 @@
"type": "mobile" "type": "mobile"
} }
}, },
{
"desc": "Advan M4",
"ua": "Mozilla/5.0 (Linux; U; Android 6.0; ADVAN M4 Build/MRA58K; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/44.0.2403.119 Mobile Safari/537.36 OPR/28.0.2254.119214",
"expect": {
"vendor": "ADVAN",
"model": "M4",
"type": "mobile"
}
},
{
"desc": "Advan S40",
"ua": "Mozilla/5.0 (Linux; Android 7.0; ADVAN S40 Build/NRD90M) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Mobile Safari/537.36 EdgA/79.0.309.58",
"expect": {
"vendor": "ADVAN",
"model": "S40",
"type": "mobile"
}
},
{
"desc": "Advan Sketsa 2",
"ua": "Mozilla/5.0 (Linux; Android 11; ADVAN 1011) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.101 Safari/537.36",
"expect": {
"vendor": "ADVAN",
"model": "1011",
"type": "mobile"
}
},
{ {
"desc": "ASUS Nexus 7", "desc": "ASUS Nexus 7",
"ua": "Mozilla/5.0 (Linux; Android 4.4.2; Nexus 7 Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.99 Safari/537.36", "ua": "Mozilla/5.0 (Linux; Android 4.4.2; Nexus 7 Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.99 Safari/537.36",
@@ -215,6 +242,42 @@
"type": "mobile" "type": "mobile"
} }
}, },
{
"desc": "Cat B15Q",
"ua": "Mozilla/5.0 (Linux; Android 4.4.2; B15Q) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.80 Mobile Safari/537.36",
"expect": {
"vendor": "Cat",
"model": "B15Q",
"type": "mobile"
}
},
{
"desc": "Cat B35",
"ua": "Mozilla/5.0 (Mobile; CAT B35; rv:48.0) Gecko/48.0 Firefox/48.0 KAIOS/2.5.1",
"expect": {
"vendor": "Cat",
"model": "B35",
"type": "mobile"
}
},
{
"desc": "Cat S22 Flip",
"ua": "Mozilla/5.0 (Linux; Android 11; S22 FLIP Build/RKQ1.210416.002) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.6422.165 Mobile Safari/537.36",
"expect": {
"vendor": "Cat",
"model": "S22 FLIP",
"type": "mobile"
}
},
{
"desc": "Cat S62 Pro",
"ua": "Mozilla/5.0 (Linux; Android 11; S62 Pro Build/RKQ1.210406.002; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/94.0.4606.85 Mobile Safari/537.36 GSA/12.34.17.23.arm64",
"expect": {
"vendor": "Cat",
"model": "S62 Pro",
"type": "mobile"
}
},
{ {
"desc": "Desktop (IE11 with Tablet string)", "desc": "Desktop (IE11 with Tablet string)",
"ua": "Mozilla/5.0 (Windows NT 6.3; WOW64; Trident/7.0; .NET4.0E; .NET4.0C; .NET CLR 3.5.30729; .NET CLR 2.0.50727; .NET CLR 3.0.30729; Tablet PC 2.0; GWX:MANAGED; rv:11.0) like Gecko", "ua": "Mozilla/5.0 (Windows NT 6.3; WOW64; Trident/7.0; .NET4.0E; .NET4.0C; .NET CLR 3.5.30729; .NET CLR 2.0.50727; .NET CLR 3.0.30729; Tablet PC 2.0; GWX:MANAGED; rv:11.0) like Gecko",
@@ -233,6 +296,33 @@
"type": "mobile" "type": "mobile"
} }
}, },
{
"desc": "Energizer Energy 400",
"ua": "Mozilla/5.0 (Linux; Android 6.0; Energy400 Build/MRA58K test-keys; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/66.0.3359.158 Mobile Safari/537.36 [FB_IAB/FB4A;FBAV/172.0.0.66.93;]",
"expect": {
"vendor": "Energizer",
"model": "Energy400",
"type": "mobile"
}
},
{
"desc": "Energizer Energy 400S",
"ua": "Mozilla/5.0 (Linux; Android 6.0; Energy 400S Build/MRA58K; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/68.0.3440.85 Mobile Safari/537.36",
"expect": {
"vendor": "Energizer",
"model": "Energy 400S",
"type": "mobile"
}
},
{
"desc": "Energizer Ultimate 65G",
"ua": "Mozilla/5.0 (Linux; Android 14; Energizer Ultimate 65G) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Mobile Safari/537.36",
"expect": {
"vendor": "Energizer",
"model": "Ultimate 65G",
"type": "mobile"
}
},
{ {
"desc": "Fairphone 1U", "desc": "Fairphone 1U",
"ua": "Mozilla/5.0 (Linux; U; Android 4.2.2; FP1U Build/JDQ39) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30", "ua": "Mozilla/5.0 (Linux; U; Android 4.2.2; FP1U Build/JDQ39) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30",
@@ -669,7 +759,7 @@
"desc": "Huawei Honor 6A", "desc": "Huawei Honor 6A",
"ua": "Mozilla/5.0 (Linux; Android 7.0; DLI-L22 Build/HONORDLI-L22; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/79.0.3945.116 Mobile Safari/537.36 [FB_IAB/FB4A;FBAV/252.0.0.22.355;]", "ua": "Mozilla/5.0 (Linux; Android 7.0; DLI-L22 Build/HONORDLI-L22; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/79.0.3945.116 Mobile Safari/537.36 [FB_IAB/FB4A;FBAV/252.0.0.22.355;]",
"expect": { "expect": {
"vendor": "Huawei", "vendor": "Honor",
"model": "DLI-L22", "model": "DLI-L22",
"type": "mobile" "type": "mobile"
} }
@@ -678,7 +768,7 @@
"desc": "Huawei Honor 7", "desc": "Huawei Honor 7",
"ua": "Mozilla/5.0 (Linux; Android 6.0; PLK-L01 Build/HONORPLK-L01; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/79.0.3945.116 Mobile Safari/537.36", "ua": "Mozilla/5.0 (Linux; Android 6.0; PLK-L01 Build/HONORPLK-L01; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/79.0.3945.116 Mobile Safari/537.36",
"expect": { "expect": {
"vendor": "Huawei", "vendor": "Honor",
"model": "PLK-L01", "model": "PLK-L01",
"type": "mobile" "type": "mobile"
} }
@@ -687,7 +777,7 @@
"desc": "Huawei 10 Lite", "desc": "Huawei 10 Lite",
"ua": "Mozilla/5.0 (Linux; Android 9; HRY-LX1 Build/HONORHRY-LX1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.91 Mobile Safari/537.36", "ua": "Mozilla/5.0 (Linux; Android 9; HRY-LX1 Build/HONORHRY-LX1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.91 Mobile Safari/537.36",
"expect": { "expect": {
"vendor": "Huawei", "vendor": "Honor",
"model": "HRY-LX1", "model": "HRY-LX1",
"type": "mobile" "type": "mobile"
} }
@@ -782,6 +872,42 @@
"type": "mobile" "type": "mobile"
} }
}, },
{
"desc": "IMO FEEL A2",
"ua": "Mozilla/5.0 (Linux; Android 5.1; IMO FEEL A2 Build/LMY47I; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/49.0.2623.105 Mobile Safari/537.36",
"expect": {
"vendor": "IMO",
"model": "FEEL A2",
"type": "mobile"
}
},
{
"desc": "IMO Q2",
"ua": "Mozilla/5.0 (Linux; Android 5.1; IMO Q2 Build/LMY47D; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/65.0.3325.109 Mobile Safari/537.36 GSA/7.22.24.21.arm",
"expect": {
"vendor": "IMO",
"model": "Q2",
"type": "mobile"
}
},
{
"desc": "IMO S2",
"ua": "Mozilla/5.0 (Linux; Android 8.1.0; IMO S2 Build/O11019; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/80.0.3987.162 Mobile Safari/537.36",
"expect": {
"vendor": "IMO",
"model": "S2",
"type": "mobile"
}
},
{
"desc": "IMO Tab X9",
"ua": "Mozilla/5.0 (Linux; U; Android 4.0.3; id-id; IMO TAB X9 Build/IML74K) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Safari/534.30",
"expect": {
"vendor": "IMO",
"model": "TAB X9",
"type": "tablet"
}
},
{ {
"desc": "Infinix Hot 7 Pro", "desc": "Infinix Hot 7 Pro",
"ua": "Mozilla/5.0 (Linux; Android 9; Infinix X625C) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Mobile Safari/537.36", "ua": "Mozilla/5.0 (Linux; Android 9; Infinix X625C) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Mobile Safari/537.36",
@@ -1151,6 +1277,33 @@
"type": "mobile" "type": "mobile"
} }
}, },
{
"desc": "Micromax Bharat 2 Plus",
"ua": "Mozilla/5.0 (Linux; U; Android 7.0; en-US; Micromax Q402Plus Build/NRD90M) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/57.0.2987.108 UCBrowser/12.12.9.1226 Mobile Safari/537.36",
"expect": {
"vendor": "Micromax",
"model": "Q402Plus",
"type": "mobile"
}
},
{
"desc": "Micromax Canvas Infinity",
"ua": "Mozilla/5.0 (Linux; U; Android 7.1.2; en-US; Micromax HS2 Build/N2G47H) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 UCBrowser/13.2.0.1296 (SpeedMode) U4/1.0 UCWEB/2.0 Mobile Safari/534.30",
"expect": {
"vendor": "Micromax",
"model": "HS2",
"type": "mobile"
}
},
{
"desc": "Micromax In 1b",
"ua": "Mozilla/5.0 (Linux; U; Android 10; Micromax E7533 Build/QP1A.190711.020; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/87.0.4280.101 Mobile Safari/537.36 OPR/54.0.2254.56148",
"expect": {
"vendor": "Micromax",
"model": "E7533",
"type": "mobile"
}
},
{ {
"desc": "Microsoft Lumia 950", "desc": "Microsoft Lumia 950",
"ua": "Mozilla/5.0 (Windows Phone 10.0; Android 4.2.1; Microsoft; Lumia 950) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2486.0 Mobile Safari/537.36 Edge/13.10586", "ua": "Mozilla/5.0 (Windows Phone 10.0; Android 4.2.1; Microsoft; Lumia 950) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2486.0 Mobile Safari/537.36 Edge/13.10586",
@@ -1907,6 +2060,42 @@
"type": "xr" "type": "xr"
} }
}, },
{
"desc": "Polytron Prime 7 Pro",
"ua": "Mozilla/5.0 (Linux; U; Android 7.0; POLYTRON_P552 Build/NRD90M; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/64.0.3282.137 Mobile Safari/537.36 OPR/50.0.2254.149182",
"expect": {
"vendor": "POLYTRON",
"model": "P552",
"type": "mobile"
}
},
{
"desc": "Polytron Rocket T1",
"ua": "Mozilla/5.0 (Linux; U; Android 5.0; en-US; POLYTRON R2501 Build/LRX21M) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/57.0.2987.108 UCBrowser/13.1.2.1293 Mobile Safari/537.36",
"expect": {
"vendor": "POLYTRON",
"model": "R2501",
"type": "mobile"
}
},
{
"desc": "Polytron Rocket T6",
"ua": "Mozilla/5.0 (Linux; Android 7.0; POLYTRON R2509) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.92 Mobile Safari/537.36",
"expect": {
"vendor": "POLYTRON",
"model": "R2509",
"type": "mobile"
}
},
{
"desc": "Polytron Zap 6 Posh",
"ua": "Mozilla/5.0 (Linux; U; Android 5.1; in-ID; POLYTRON_4G501 Build/LMY47D) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/57.0.2987.108 UCBrowser/12.10.0.1163 UCTurbo/1.9.9.900 Mobile Safari/537.36",
"expect": {
"vendor": "POLYTRON",
"model": "4G501",
"type": "mobile"
}
},
{ {
"desc": "Roku", "desc": "Roku",
"ua": "Mozilla/5.0 (Roku) AppleWebKit/537.36 (KHTML, like Gecko) Web/1.1 Safari/537.36", "ua": "Mozilla/5.0 (Roku) AppleWebKit/537.36 (KHTML, like Gecko) Web/1.1 Safari/537.36",
@@ -2357,6 +2546,33 @@
"type": "mobile" "type": "mobile"
} }
}, },
{
"desc": "Smartfren Andromax L",
"ua": "Mozilla/5.0 (Linux; Android 6.0.1; Andromax B26D2H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.127 Mobile Safari/537.36",
"expect": {
"vendor": "Smartfren",
"model": "Andromax B26D2H",
"type": "mobile"
}
},
{
"desc": "Smartfren Andromax G2",
"ua": "Mozilla/5.0 (Linux; Android 4.4.2; Smartfren Andromax AD9A1H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.83 Mobile Safari/537.36",
"expect": {
"vendor": "Smartfren",
"model": "Andromax AD9A1H",
"type": "mobile"
}
},
{
"desc": "Smartfren New Andromax I",
"ua": "Mozilla/5.0 (Linux; U; Android 4.1.2; id-id; New Andromax-i Build/JZO54K) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30",
"expect": {
"vendor": "Smartfren",
"model": "New Andromax-i",
"type": "mobile"
}
},
{ {
"desc": "SONY Xperia 1 III", "desc": "SONY Xperia 1 III",
"ua": "Mozilla/5.0 (Linux; Android 11; A101SO) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.45 Mobile Safari/537.36", "ua": "Mozilla/5.0 (Linux; Android 11; A101SO) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.45 Mobile Safari/537.36",

View File

@@ -89,6 +89,15 @@
"version" : "2.8.149" "version" : "2.8.149"
} }
}, },
{
"desc" : "Servo",
"ua" : "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:109.0) Servo/1.0 Firefox/111.0",
"expect" :
{
"name" : "Servo",
"version" : "1.0"
}
},
{ {
"desc" : "Tasman", "desc" : "Tasman",
"ua" : "Mozilla/4.0 (compatible; MSIE 6.0; PPC Mac OS X 10.4.7; Tasman 1.0)", "ua" : "Mozilla/4.0 (compatible; MSIE 6.0; PPC Mac OS X 10.4.7; Tasman 1.0)",