ua-browser 1.3.0 → 1.4.0-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.en.md +226 -0
- package/README.md +93 -85
- package/dist/index.cjs +306 -60
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +83 -17
- package/dist/index.d.ts +83 -17
- package/dist/index.min.js +2 -2
- package/dist/index.min.js.map +1 -1
- package/dist/index.mjs +304 -61
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
- package/README.zh-CN.md +0 -200
package/dist/index.mjs
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
// package.json
|
|
2
2
|
var package_default = {
|
|
3
|
-
version: "1.
|
|
3
|
+
version: "1.4.0-beta.0"};
|
|
4
4
|
|
|
5
5
|
// src/constants/browsers.ts
|
|
6
6
|
var BROWSER_DEFS = [
|
|
7
7
|
// ── Generic / low-priority base browsers ──────────────────────────────────
|
|
8
8
|
{ name: "Safari", priority: 10, detect: /Safari/, versionPattern: /Version\/([\d.]+)/ },
|
|
9
9
|
{ name: "Chrome", priority: 20, detect: /(Chrome|CriOS)/, versionPattern: [/Chrome\/([\d.]+)/, /CriOS\/([\d.]+)/] },
|
|
10
|
+
{ name: "Arc", priority: 35, detect: /Arc\//, versionPattern: /Arc\/([\d.]+)/ },
|
|
10
11
|
{ name: "IE", priority: 30, detect: /(MSIE|Trident)/, versionPattern: [/MSIE ([\d.]+)/, /rv:([\d.]+)/] },
|
|
11
12
|
{ name: "Edge", priority: 40, detect: /(Edge|Edg\/|EdgA|EdgiOS)/, versionPattern: [/Edge\/([\d.]+)/, /Edg\/([\d.]+)/, /EdgA\/([\d.]+)/, /EdgiOS\/([\d.]+)/] },
|
|
12
13
|
{ name: "Firefox", priority: 50, detect: /(Firefox|FxiOS)/, versionPattern: [/Firefox\/([\d.]+)/, /FxiOS\/([\d.]+)/] },
|
|
@@ -16,7 +17,7 @@ var BROWSER_DEFS = [
|
|
|
16
17
|
{ name: "Vivaldi", priority: 80, detect: /Vivaldi/, versionPattern: /Vivaldi\/([\d.]+)/ },
|
|
17
18
|
{ name: "Yandex", priority: 90, detect: /YaBrowser/, versionPattern: /YaBrowser\/([\d.]+)/ },
|
|
18
19
|
{ name: "Samsung Internet", priority: 92, detect: /SamsungBrowser/, versionPattern: /SamsungBrowser\/([\d.]+)/ },
|
|
19
|
-
{ name: "DuckDuckGo", priority: 94, detect: /DuckDuckGo\//, versionPattern: /DuckDuckGo\/([\d.]+)/ },
|
|
20
|
+
{ name: "DuckDuckGo", priority: 94, detect: /(DuckDuckGo|Ddg)\//, versionPattern: [/DuckDuckGo\/([\d.]+)/, /Ddg\/([\d.]+)/] },
|
|
20
21
|
{ name: "Puffin", priority: 96, detect: /Puffin\//, versionPattern: /Puffin\/([\d.]+)/ },
|
|
21
22
|
{ name: "Coc Coc", priority: 130, detect: /coc_coc_browser/, versionPattern: /coc_coc_browser\/([\d.]+)/ },
|
|
22
23
|
{ name: "Kindle", priority: 140, detect: /(Kindle|Silk\/)/, versionPattern: /Version\/([\d.]+)/ },
|
|
@@ -60,7 +61,7 @@ var BROWSER_DEFS = [
|
|
|
60
61
|
}
|
|
61
62
|
},
|
|
62
63
|
{ name: "UC", priority: 330, detect: /(UCBrowser|UBrowser|UCWEB)/, versionPattern: /UC?Browser\/([\d.]+)/ },
|
|
63
|
-
{ name: "QQBrowser", priority: 340, detect: /QQBrowser/, versionPattern: /QQBrowser\/([\d.]+)/ },
|
|
64
|
+
{ name: "QQBrowser", priority: 340, detect: /(MQQBrowser|QQBrowser)/, versionPattern: [/MQQBrowser\/([\d.]+)/, /QQBrowser\/([\d.]+)/] },
|
|
64
65
|
{ name: "QQ", priority: 345, detect: /QQ\//, versionPattern: /QQ\/([\d.]+)/ },
|
|
65
66
|
{ name: "Baidu", priority: 350, detect: /(Baidu|BIDUBrowser|baidubrowser|baiduboxapp|BaiduHD)/, versionPattern: [/BIDUBrowser[\s/]([\d.]+)/, /baiduboxapp\/([\d.]+)/] },
|
|
66
67
|
{ name: "Sogou", priority: 360, detect: /(MetaSr|Sogou)/, versionPattern: [/SE ([\d.X]+)/, /SogouMobileBrowser\/([\d.]+)/] },
|
|
@@ -208,6 +209,10 @@ var OS_DEFS = [
|
|
|
208
209
|
{ name: "Tizen", detect: /Tizen/, versionPattern: /Tizen ([\d.]+)/ },
|
|
209
210
|
{ name: "iOS", detect: /like Mac OS X/, versionPattern: /OS ([\d_]+) like/ },
|
|
210
211
|
{ name: "MacOS", detect: /Macintosh/, versionPattern: /Mac OS X -?([\d_.]+)/ },
|
|
212
|
+
// visionOS / tvOS must come AFTER iOS: their UAs also contain "like Mac OS X",
|
|
213
|
+
// so they need to override iOS via the last-match-wins iteration.
|
|
214
|
+
{ name: "visionOS", detect: /visionOS/, versionPattern: /visionOS ([\d_]+)/ },
|
|
215
|
+
{ name: "tvOS", detect: /Apple TV/, versionPattern: /OS ([\d_]+) like/ },
|
|
211
216
|
{ name: "Android", detect: /(Android|Adr)/, versionPattern: /(?:Android|Adr) ([\d.]+)/ },
|
|
212
217
|
// HarmonyOS must come after Android: HarmonyOS UAs include "Android", so Android matches
|
|
213
218
|
// first, then HarmonyOS overrides it. versionPattern tries direct extraction first (5.0+
|
|
@@ -285,24 +290,59 @@ var DEVICE_DEFS = [
|
|
|
285
290
|
|
|
286
291
|
// src/detectors/device.ts
|
|
287
292
|
function detectDevice(ua, nav) {
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
return "
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
return
|
|
293
|
+
var _a, _b;
|
|
294
|
+
function uaDetect() {
|
|
295
|
+
if (/PlayStation|Xbox|Nintendo/.test(ua)) return "Console";
|
|
296
|
+
if (/visionOS|Quest/.test(ua)) return "XR";
|
|
297
|
+
if (/(SMART-TV|HbbTV|SmartTV|TV Safari|Android TV|GoogleTV)/.test(ua)) return "TV";
|
|
298
|
+
if (/iPad/.test(ua)) return "Tablet";
|
|
299
|
+
if (/Android/.test(ua) && !/Mobile/.test(ua)) return "Tablet";
|
|
300
|
+
for (const def of DEVICE_DEFS) {
|
|
301
|
+
if (def.detect.test(ua)) return def.name;
|
|
302
|
+
}
|
|
303
|
+
return null;
|
|
299
304
|
}
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
305
|
+
function hwDetect() {
|
|
306
|
+
var _a2, _b2, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p;
|
|
307
|
+
if (!nav) return null;
|
|
308
|
+
if (nav.webglRenderer) {
|
|
309
|
+
if (/^ANGLE\b/.test(nav.webglRenderer)) return "PC";
|
|
310
|
+
if (/Adreno/i.test(nav.webglRenderer) || /Mali[-\s]/i.test(nav.webglRenderer)) {
|
|
311
|
+
return ((_a2 = nav.screenWidth) != null ? _a2 : 0) >= 768 ? "Tablet" : "Mobile";
|
|
312
|
+
}
|
|
313
|
+
if (/Apple GPU/i.test(nav.webglRenderer)) {
|
|
314
|
+
const w = (_b2 = nav.screenWidth) != null ? _b2 : 0;
|
|
315
|
+
if (w <= 1366) return w >= 768 ? "Tablet" : "Mobile";
|
|
316
|
+
return "PC";
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
if (nav.platform === "MacIntel" && ((_c = nav.maxTouchPoints) != null ? _c : 0) > 1) {
|
|
320
|
+
return nav.screenWidth !== void 0 && nav.screenWidth < 768 ? "Mobile" : "Tablet";
|
|
321
|
+
}
|
|
322
|
+
if (nav.webglMaxTextureSize !== void 0 && nav.webglMaxTextureSize <= 8192 && ((_d = nav.maxTouchPoints) != null ? _d : 0) > 1 && ((_e = nav.screenWidth) != null ? _e : 9999) < 1367) {
|
|
323
|
+
return ((_f = nav.screenWidth) != null ? _f : 0) >= 768 ? "Tablet" : "Mobile";
|
|
324
|
+
}
|
|
325
|
+
if (((_g = nav.webglCompressedFormats) == null ? void 0 : _g.pvrtc) && !nav.webglCompressedFormats.s3tc) {
|
|
326
|
+
return ((_h = nav.screenWidth) != null ? _h : 0) >= 768 ? "Tablet" : "Mobile";
|
|
303
327
|
}
|
|
328
|
+
if (nav.safeAreaInsetTop !== void 0 && nav.safeAreaInsetTop > 0) {
|
|
329
|
+
return ((_i = nav.screenWidth) != null ? _i : 0) >= 768 ? "Tablet" : "Mobile";
|
|
330
|
+
}
|
|
331
|
+
if (nav.hasVibration || nav.hasDeviceMotion) {
|
|
332
|
+
return ((_j = nav.screenWidth) != null ? _j : 0) >= 768 ? "Tablet" : "Mobile";
|
|
333
|
+
}
|
|
334
|
+
if (((_k = nav.connection) == null ? void 0 : _k.effectiveType) && ["2g", "3g", "slow-2g"].includes(nav.connection.effectiveType)) {
|
|
335
|
+
return ((_l = nav.screenWidth) != null ? _l : 0) >= 768 ? "Tablet" : "Mobile";
|
|
336
|
+
}
|
|
337
|
+
if (((_m = nav.devicePixelRatio) != null ? _m : 0) > 2 && ((_n = nav.maxTouchPoints) != null ? _n : 0) > 1) {
|
|
338
|
+
return ((_o = nav.screenWidth) != null ? _o : 0) >= 768 ? "Tablet" : "Mobile";
|
|
339
|
+
}
|
|
340
|
+
if (nav.pointerType === "coarse" && nav.hoverCapability === false) {
|
|
341
|
+
return ((_p = nav.screenWidth) != null ? _p : 0) >= 768 ? "Tablet" : "Mobile";
|
|
342
|
+
}
|
|
343
|
+
return null;
|
|
304
344
|
}
|
|
305
|
-
return "PC";
|
|
345
|
+
return (_b = (_a = hwDetect()) != null ? _a : uaDetect()) != null ? _b : "PC";
|
|
306
346
|
}
|
|
307
347
|
|
|
308
348
|
// src/constants/bots.ts
|
|
@@ -318,28 +358,49 @@ var BOT_DEFS = [
|
|
|
318
358
|
{ name: "Sogou", detect: /(Sogou|sogou).*[Ss]pider/ },
|
|
319
359
|
{ name: "360Spider", detect: /360Spider/ },
|
|
320
360
|
{ name: "PetalBot", detect: /PetalBot/ },
|
|
361
|
+
{ name: "Applebot-Extended", detect: /Applebot-Extended/ },
|
|
321
362
|
{ name: "Applebot", detect: /Applebot/ },
|
|
322
|
-
// Social
|
|
363
|
+
// Social media crawlers
|
|
323
364
|
{ name: "Facebookbot", detect: /(facebookexternalhit|FacebookBot)/ },
|
|
324
365
|
{ name: "Twitterbot", detect: /Twitterbot/ },
|
|
325
366
|
{ name: "LinkedInBot", detect: /LinkedInBot/ },
|
|
367
|
+
{ name: "PinterestBot", detect: /Pinterest/ },
|
|
368
|
+
// Messaging link preview bots
|
|
369
|
+
{ name: "Slackbot", detect: /Slackbot/ },
|
|
370
|
+
{ name: "Discordbot", detect: /Discordbot/ },
|
|
371
|
+
{ name: "TelegramBot", detect: /TelegramBot/ },
|
|
372
|
+
{ name: "WhatsApp", detect: /WhatsApp/ },
|
|
326
373
|
// SEO tools
|
|
327
374
|
{ name: "SemrushBot", detect: /SemrushBot/ },
|
|
328
375
|
{ name: "AhrefsBot", detect: /AhrefsBot/ },
|
|
329
376
|
{ name: "MJ12bot", detect: /MJ12bot/ },
|
|
377
|
+
{ name: "ScreamingFrog", detect: /Screaming Frog/ },
|
|
378
|
+
{ name: "DataForSeoBot", detect: /DataForSeoBot/ },
|
|
330
379
|
// AI / LLM crawlers
|
|
331
380
|
{ name: "GPTBot", detect: /GPTBot/ },
|
|
381
|
+
{ name: "OAI-SearchBot", detect: /OAI-SearchBot/ },
|
|
382
|
+
{ name: "ChatGPT-User", detect: /ChatGPT-User/ },
|
|
332
383
|
{ name: "ClaudeBot", detect: /ClaudeBot/ },
|
|
333
384
|
{ name: "PerplexityBot", detect: /PerplexityBot/ },
|
|
334
385
|
{ name: "CCBot", detect: /CCBot/ },
|
|
335
386
|
{ name: "AdsBot", detect: /AdsBot-Google/ },
|
|
387
|
+
{ name: "Google-Extended", detect: /Google-Extended/ },
|
|
388
|
+
{ name: "Meta-ExternalAgent", detect: /meta-externalagent/i },
|
|
389
|
+
{ name: "Amazonbot", detect: /Amazonbot/ },
|
|
390
|
+
{ name: "Diffbot", detect: /Diffbot/ },
|
|
391
|
+
{ name: "cohere-ai", detect: /cohere-ai/ },
|
|
392
|
+
{ name: "YouBot", detect: /YouBot/ },
|
|
393
|
+
// Monitoring / archiving
|
|
394
|
+
{ name: "UptimeRobot", detect: /UptimeRobot/ },
|
|
395
|
+
{ name: "ia_archiver", detect: /ia_archiver/ },
|
|
336
396
|
// Generic catch-all (must be last)
|
|
337
397
|
{ name: "GenericBot", detect: /(bot|crawler|spider|crawling|scraper)/i }
|
|
338
398
|
];
|
|
339
399
|
|
|
340
400
|
// src/detectors/bot.ts
|
|
341
|
-
function detectBot(ua) {
|
|
342
|
-
|
|
401
|
+
function detectBot(ua, customDefs) {
|
|
402
|
+
const defs = customDefs ? [...BOT_DEFS.slice(0, -1), ...customDefs, BOT_DEFS[BOT_DEFS.length - 1]] : BOT_DEFS;
|
|
403
|
+
for (const def of defs) {
|
|
343
404
|
if (def.detect.test(ua)) {
|
|
344
405
|
return { isBot: true, botName: def.name };
|
|
345
406
|
}
|
|
@@ -349,7 +410,8 @@ function detectBot(ua) {
|
|
|
349
410
|
|
|
350
411
|
// src/constants/arch.ts
|
|
351
412
|
var ARCH_DEFS = [
|
|
352
|
-
|
|
413
|
+
// aarch64/arm64 explicit tokens + iOS devices (iPhone 5S+/iPad Air+ are exclusively arm64)
|
|
414
|
+
{ name: "arm64", detect: /(aarch64|arm64|ARM64|iPhone|iPad|iPod)/ },
|
|
353
415
|
{ name: "arm", detect: /\bARM\b/ },
|
|
354
416
|
{ name: "x86_64", detect: /(x86_64|Win64|WOW64|x64;|amd64)/i },
|
|
355
417
|
{ name: "x86", detect: /(i[36]86|i686|x86;)/ }
|
|
@@ -368,7 +430,7 @@ function detectArch(ua, ctx) {
|
|
|
368
430
|
}
|
|
369
431
|
const renderer = ctx == null ? void 0 : ctx.webglRenderer;
|
|
370
432
|
if (renderer) {
|
|
371
|
-
if (/Apple\s+(M\d|A\d{1,2}[A-Z]?)\b/i.test(renderer) || /APPLE M\d/i.test(renderer)) {
|
|
433
|
+
if (/Apple\s+(M\d|A\d{1,2}[A-Z]?)\b/i.test(renderer) || /APPLE M\d/i.test(renderer) || /^Apple GPU$/i.test(renderer)) {
|
|
372
434
|
return "arm64";
|
|
373
435
|
}
|
|
374
436
|
if (/\b(Intel|AMD|NVIDIA|Radeon)\b/i.test(renderer)) {
|
|
@@ -427,22 +489,95 @@ function getLanguage(nav) {
|
|
|
427
489
|
}
|
|
428
490
|
|
|
429
491
|
// src/parse.ts
|
|
492
|
+
var BRAND_TO_BROWSER = [
|
|
493
|
+
["Microsoft Edge", "Edge"],
|
|
494
|
+
["Opera", "Opera"],
|
|
495
|
+
["Vivaldi", "Vivaldi"],
|
|
496
|
+
["Google Chrome", "Chrome"],
|
|
497
|
+
["Chromium", "Chromium"]
|
|
498
|
+
];
|
|
499
|
+
function osFromHardware(ctx) {
|
|
500
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
501
|
+
const p = ((_a = ctx.platform) != null ? _a : "").toLowerCase();
|
|
502
|
+
const chPlatform = (_b = ctx.userAgentData) == null ? void 0 : _b.platform;
|
|
503
|
+
const platformVersion = (_c = ctx.highEntropyData) == null ? void 0 : _c.platformVersion;
|
|
504
|
+
const hasPlatformVersion = !!(platformVersion && platformVersion !== "0.0.0");
|
|
505
|
+
if (((_d = ctx.webglCompressedFormats) == null ? void 0 : _d.pvrtc) && !ctx.webglCompressedFormats.s3tc) return "iOS";
|
|
506
|
+
if (ctx.webglRenderer && /^ANGLE\b/.test(ctx.webglRenderer)) {
|
|
507
|
+
if (p.startsWith("mac") || chPlatform === "macOS") return "MacOS";
|
|
508
|
+
if (p.startsWith("win") || chPlatform === "Windows") return "Windows";
|
|
509
|
+
if (chPlatform === "Chrome OS") return "Chrome OS";
|
|
510
|
+
return null;
|
|
511
|
+
}
|
|
512
|
+
if (ctx.webglRenderer && (/Adreno/i.test(ctx.webglRenderer) || /Mali[-\s]/i.test(ctx.webglRenderer))) {
|
|
513
|
+
return "Android";
|
|
514
|
+
}
|
|
515
|
+
if (chPlatform && hasPlatformVersion) {
|
|
516
|
+
const chMap = {
|
|
517
|
+
Windows: "Windows",
|
|
518
|
+
macOS: "MacOS",
|
|
519
|
+
Android: "Android",
|
|
520
|
+
iOS: "iOS",
|
|
521
|
+
"Chrome OS": "Chrome OS"
|
|
522
|
+
};
|
|
523
|
+
const mapped = chMap[chPlatform];
|
|
524
|
+
if (mapped) return mapped;
|
|
525
|
+
}
|
|
526
|
+
if (p.startsWith("mac")) return "MacOS";
|
|
527
|
+
if (p.startsWith("win")) return "Windows";
|
|
528
|
+
if (p === "iphone" || p === "ipad" || p === "ipod") return "iOS";
|
|
529
|
+
if (((_e = ctx.safeAreaInsetTop) != null ? _e : 0) > 0) return "iOS";
|
|
530
|
+
if (chPlatform === "Chrome OS") return "Chrome OS";
|
|
531
|
+
if (chPlatform === "Android" && (p.includes("android") || /^linux arm/i.test((_f = ctx.platform) != null ? _f : ""))) {
|
|
532
|
+
return "Android";
|
|
533
|
+
}
|
|
534
|
+
if (p.includes("android") || /^linux arm/i.test((_g = ctx.platform) != null ? _g : "")) return "Android";
|
|
535
|
+
return null;
|
|
536
|
+
}
|
|
537
|
+
function platformFromUA(ua) {
|
|
538
|
+
if (/iPhone/.test(ua)) return "iPhone";
|
|
539
|
+
if (/iPad/.test(ua)) return "iPad";
|
|
540
|
+
if (/iPod/.test(ua)) return "iPod";
|
|
541
|
+
if (/Macintosh/.test(ua)) return "MacIntel";
|
|
542
|
+
if (/Windows NT/.test(ua)) return /Win64|WOW64/i.test(ua) ? "Win64" : "Win32";
|
|
543
|
+
if (/CrOS/.test(ua)) return "Linux x86_64";
|
|
544
|
+
if (/Android/.test(ua)) return /aarch64|arm64/i.test(ua) ? "Linux aarch64" : "Linux armv8l";
|
|
545
|
+
if (/Linux/.test(ua)) {
|
|
546
|
+
if (/x86_64/i.test(ua)) return "Linux x86_64";
|
|
547
|
+
if (/aarch64|arm64/i.test(ua)) return "Linux aarch64";
|
|
548
|
+
return "Linux";
|
|
549
|
+
}
|
|
550
|
+
return "unknown";
|
|
551
|
+
}
|
|
552
|
+
function languageFromUA(ua) {
|
|
553
|
+
const re = /[;(]\s*([a-z]{2,3}(?:[-_][A-Za-z]{2,4})+)\s*[;)]/g;
|
|
554
|
+
let m;
|
|
555
|
+
while ((m = re.exec(ua)) !== null) {
|
|
556
|
+
const parts = m[1].replace(/_/g, "-").split("-");
|
|
557
|
+
if (parts.length >= 2) {
|
|
558
|
+
return `${parts[0].toLowerCase()}-${parts.slice(1).map((p) => p.toUpperCase()).join("-")}`;
|
|
559
|
+
}
|
|
560
|
+
}
|
|
561
|
+
return "unknown";
|
|
562
|
+
}
|
|
430
563
|
function parseUA(ua, options = {}) {
|
|
431
|
-
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
564
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p;
|
|
432
565
|
const effectiveNav = (_a = options.ctx) != null ? _a : options.nav;
|
|
433
566
|
const effectiveWindowsVersion = (_c = (_b = options.ctx) == null ? void 0 : _b.windowsVersion) != null ? _c : options.windowsVersion;
|
|
434
567
|
const { browser: rawBrowser, version: rawVersion } = detectBrowser(ua);
|
|
435
|
-
const { os, osVersion: rawOsVersion } = detectOs(ua, effectiveWindowsVersion);
|
|
568
|
+
const { os: rawOs, osVersion: rawOsVersion } = detectOs(ua, effectiveWindowsVersion);
|
|
569
|
+
let os = rawOs;
|
|
436
570
|
let osVersion = rawOsVersion;
|
|
437
571
|
const device = detectDevice(ua, effectiveNav);
|
|
438
|
-
const arch = detectArch(ua, options.ctx);
|
|
572
|
+
const arch = detectArch(ua, (_d = options.ctx) != null ? _d : effectiveNav);
|
|
439
573
|
const nav = effectiveNav;
|
|
440
|
-
const { isBot, botName } = detectBot(ua);
|
|
574
|
+
const { isBot, botName } = detectBot(ua, options.customBotDefs);
|
|
441
575
|
const isHeadless = detectHeadless(ua);
|
|
442
|
-
const language = nav ? getLanguage(nav) : "
|
|
443
|
-
const platform = (
|
|
576
|
+
const language = options.language || ((nav == null ? void 0 : nav.language) || (nav == null ? void 0 : nav.browserLanguage) ? getLanguage(nav) : "") || languageFromUA(ua);
|
|
577
|
+
const platform = (nav == null ? void 0 : nav.platform) || platformFromUA(ua);
|
|
444
578
|
let browser = rawBrowser;
|
|
445
579
|
let version = rawVersion;
|
|
580
|
+
if ((_e = options.ctx) == null ? void 0 : _e.hasBrave) browser = "Brave";
|
|
446
581
|
if (nav) {
|
|
447
582
|
const chromeGlobal = typeof chrome !== "undefined" ? chrome : void 0;
|
|
448
583
|
const chromeMatch = /Chrome\/([\d]+)/.exec(ua);
|
|
@@ -462,7 +597,7 @@ function parseUA(ua, options = {}) {
|
|
|
462
597
|
}
|
|
463
598
|
}
|
|
464
599
|
if (is360) {
|
|
465
|
-
const saveDataEnabled = ((
|
|
600
|
+
const saveDataEnabled = ((_f = nav.connection) == null ? void 0 : _f.saveData) === true;
|
|
466
601
|
if (getMimeType(nav, "application/gameplugin") || !saveDataEnabled) {
|
|
467
602
|
browser = "360SE";
|
|
468
603
|
} else {
|
|
@@ -475,8 +610,8 @@ function parseUA(ua, options = {}) {
|
|
|
475
610
|
}
|
|
476
611
|
if (browser === "Baidu" && /(Opera|OPR|OPT)/.test(ua)) {
|
|
477
612
|
browser = "Opera";
|
|
478
|
-
const opVer = (
|
|
479
|
-
version = (
|
|
613
|
+
const opVer = (_h = (_g = /OPR\/([\d.]+)/.exec(ua)) != null ? _g : /OPT\/([\d.]+)/.exec(ua)) != null ? _h : /Opera\/([\d.]+)/.exec(ua);
|
|
614
|
+
version = (_i = opVer == null ? void 0 : opVer[1]) != null ? _i : "unknown";
|
|
480
615
|
}
|
|
481
616
|
if (browser === "Chrome" && /\S+Browser\//.test(ua)) {
|
|
482
617
|
const m = /(\S+Browser)\/([\d.]+)/.exec(ua);
|
|
@@ -499,10 +634,47 @@ function parseUA(ua, options = {}) {
|
|
|
499
634
|
osVersion = m[1];
|
|
500
635
|
}
|
|
501
636
|
}
|
|
637
|
+
if (os === "MacOS" && browser === "Safari") {
|
|
638
|
+
const m = /Version\/([\d.]+)/.exec(ua);
|
|
639
|
+
if (m && parseInt(m[1], 10) >= 26) {
|
|
640
|
+
osVersion = m[1];
|
|
641
|
+
}
|
|
642
|
+
}
|
|
643
|
+
if (options.ctx) {
|
|
644
|
+
const hwOs = osFromHardware(options.ctx);
|
|
645
|
+
if (hwOs !== null) {
|
|
646
|
+
if (hwOs !== rawOs) {
|
|
647
|
+
os = hwOs;
|
|
648
|
+
osVersion = "unknown";
|
|
649
|
+
}
|
|
650
|
+
if (os !== "Windows") {
|
|
651
|
+
const pv = (_j = options.ctx.highEntropyData) == null ? void 0 : _j.platformVersion;
|
|
652
|
+
if (pv && pv !== "0.0.0") {
|
|
653
|
+
const parts = pv.split(".").map(Number);
|
|
654
|
+
while (parts.length > 1 && parts[parts.length - 1] === 0) parts.pop();
|
|
655
|
+
if (parts[0]) osVersion = parts.join(".");
|
|
656
|
+
}
|
|
657
|
+
}
|
|
658
|
+
}
|
|
659
|
+
const fullVersionList = (_k = options.ctx.highEntropyData) == null ? void 0 : _k.fullVersionList;
|
|
660
|
+
if (fullVersionList) {
|
|
661
|
+
for (const [brand, browserName] of BRAND_TO_BROWSER) {
|
|
662
|
+
const entry = fullVersionList.find((e) => e.brand === brand);
|
|
663
|
+
if (entry == null ? void 0 : entry.version) {
|
|
664
|
+
browser = browserName;
|
|
665
|
+
version = entry.version;
|
|
666
|
+
break;
|
|
667
|
+
}
|
|
668
|
+
}
|
|
669
|
+
}
|
|
670
|
+
}
|
|
502
671
|
const engine = detectEngine(ua, browser, version);
|
|
672
|
+
const versionMajor = parseInt((_l = version.split(".")[0]) != null ? _l : "0", 10) || 0;
|
|
673
|
+
const connectionType = (_p = (_o = (_n = (_m = options.ctx) != null ? _m : options.nav) == null ? void 0 : _n.connection) == null ? void 0 : _o.effectiveType) != null ? _p : "unknown";
|
|
503
674
|
return {
|
|
504
675
|
browser,
|
|
505
676
|
version,
|
|
677
|
+
versionMajor,
|
|
506
678
|
engine,
|
|
507
679
|
os,
|
|
508
680
|
osVersion,
|
|
@@ -513,25 +685,11 @@ function parseUA(ua, options = {}) {
|
|
|
513
685
|
isBot,
|
|
514
686
|
botName,
|
|
515
687
|
language,
|
|
516
|
-
platform
|
|
688
|
+
platform,
|
|
689
|
+
connectionType
|
|
517
690
|
};
|
|
518
691
|
}
|
|
519
692
|
|
|
520
|
-
// src/utils/windows-version.ts
|
|
521
|
-
async function getWindowsVersion(nav) {
|
|
522
|
-
var _a;
|
|
523
|
-
if (!nav.userAgentData || nav.userAgentData.platform !== "Windows") {
|
|
524
|
-
return null;
|
|
525
|
-
}
|
|
526
|
-
try {
|
|
527
|
-
const data = await nav.userAgentData.getHighEntropyValues(["platformVersion"]);
|
|
528
|
-
const major = parseInt(((_a = data["platformVersion"]) == null ? void 0 : _a.split(".")[0]) || "0", 10);
|
|
529
|
-
return major >= 13 ? "11" : "10";
|
|
530
|
-
} catch (e) {
|
|
531
|
-
return null;
|
|
532
|
-
}
|
|
533
|
-
}
|
|
534
|
-
|
|
535
693
|
// src/utils/env-context.ts
|
|
536
694
|
var OS_FONTS = [
|
|
537
695
|
".AppleSystemUIFont",
|
|
@@ -559,21 +717,56 @@ function probeFonts() {
|
|
|
559
717
|
}
|
|
560
718
|
}
|
|
561
719
|
function getWebGLInfo() {
|
|
562
|
-
var _a;
|
|
720
|
+
var _a, _b;
|
|
563
721
|
try {
|
|
564
722
|
const canvas = document.createElement("canvas");
|
|
565
723
|
const gl = (_a = canvas.getContext("webgl")) != null ? _a : canvas.getContext("experimental-webgl");
|
|
566
724
|
if (!gl) return {};
|
|
567
725
|
const ext = gl.getExtension("WEBGL_debug_renderer_info");
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
726
|
+
const result = {
|
|
727
|
+
maxTextureSize: gl.getParameter(gl.MAX_TEXTURE_SIZE),
|
|
728
|
+
fragPrecision: (_b = gl.getShaderPrecisionFormat(gl.FRAGMENT_SHADER, gl.HIGH_FLOAT)) == null ? void 0 : _b.rangeMax,
|
|
729
|
+
compressedFormats: {
|
|
730
|
+
s3tc: !!gl.getExtension("WEBGL_compressed_texture_s3tc"),
|
|
731
|
+
pvrtc: !!gl.getExtension("WEBGL_compressed_texture_pvrtc"),
|
|
732
|
+
etc2: !!gl.getExtension("WEBGL_compressed_texture_etc"),
|
|
733
|
+
astc: !!gl.getExtension("WEBGL_compressed_texture_astc_ldr")
|
|
734
|
+
}
|
|
572
735
|
};
|
|
736
|
+
if (ext) {
|
|
737
|
+
result.renderer = gl.getParameter(ext.UNMASKED_RENDERER_WEBGL);
|
|
738
|
+
result.vendor = gl.getParameter(ext.UNMASKED_VENDOR_WEBGL);
|
|
739
|
+
}
|
|
740
|
+
return result;
|
|
573
741
|
} catch (e) {
|
|
574
742
|
return {};
|
|
575
743
|
}
|
|
576
744
|
}
|
|
745
|
+
function getSafeAreaInsetTop() {
|
|
746
|
+
try {
|
|
747
|
+
const el = document.createElement("div");
|
|
748
|
+
el.style.cssText = "position:fixed;top:env(safe-area-inset-top,0px);visibility:hidden;pointer-events:none";
|
|
749
|
+
document.body.appendChild(el);
|
|
750
|
+
const top = parseFloat(getComputedStyle(el).top);
|
|
751
|
+
document.body.removeChild(el);
|
|
752
|
+
return isNaN(top) ? 0 : top;
|
|
753
|
+
} catch (e) {
|
|
754
|
+
return 0;
|
|
755
|
+
}
|
|
756
|
+
}
|
|
757
|
+
function getAudioSampleRate() {
|
|
758
|
+
var _a;
|
|
759
|
+
try {
|
|
760
|
+
const AC = (_a = window.AudioContext) != null ? _a : window.webkitAudioContext;
|
|
761
|
+
if (!AC) return void 0;
|
|
762
|
+
const ac = new AC();
|
|
763
|
+
const rate = ac.sampleRate;
|
|
764
|
+
void ac.close();
|
|
765
|
+
return rate;
|
|
766
|
+
} catch (e) {
|
|
767
|
+
return void 0;
|
|
768
|
+
}
|
|
769
|
+
}
|
|
577
770
|
function getPointerType() {
|
|
578
771
|
try {
|
|
579
772
|
if (window.matchMedia("(pointer: coarse)").matches) return "coarse";
|
|
@@ -597,20 +790,44 @@ function deriveWindowsVersion(platformVersion) {
|
|
|
597
790
|
return isNaN(major) ? null : major >= 13 ? "11" : "10";
|
|
598
791
|
}
|
|
599
792
|
async function getEnvContext() {
|
|
793
|
+
var _a, _b, _c, _d, _e;
|
|
600
794
|
const base = getNavContext();
|
|
601
|
-
const ctx = {
|
|
795
|
+
const ctx = {
|
|
796
|
+
userAgent: base.userAgent,
|
|
797
|
+
platform: base.platform,
|
|
798
|
+
language: base.language,
|
|
799
|
+
maxTouchPoints: base.maxTouchPoints
|
|
800
|
+
};
|
|
801
|
+
if (base.browserLanguage !== void 0) ctx.browserLanguage = base.browserLanguage;
|
|
802
|
+
if (base.mimeTypes !== void 0) ctx.mimeTypes = base.mimeTypes;
|
|
803
|
+
if (base.connection !== void 0) ctx.connection = base.connection;
|
|
804
|
+
if (base.userAgentData !== void 0) ctx.userAgentData = base.userAgentData;
|
|
602
805
|
if (typeof navigator !== "undefined") {
|
|
603
806
|
ctx.hardwareConcurrency = navigator.hardwareConcurrency;
|
|
604
807
|
ctx.deviceMemory = navigator.deviceMemory;
|
|
605
808
|
}
|
|
606
809
|
if (typeof window !== "undefined") {
|
|
607
810
|
ctx.devicePixelRatio = window.devicePixelRatio;
|
|
811
|
+
ctx.screenWidth = (_a = window.screen) == null ? void 0 : _a.width;
|
|
812
|
+
ctx.screenHeight = (_b = window.screen) == null ? void 0 : _b.height;
|
|
813
|
+
ctx.safeAreaInsetTop = getSafeAreaInsetTop();
|
|
608
814
|
ctx.pointerType = getPointerType();
|
|
609
815
|
ctx.hoverCapability = getHoverCapability();
|
|
610
816
|
ctx.fontProbes = probeFonts();
|
|
611
|
-
|
|
817
|
+
ctx.audioSampleRate = getAudioSampleRate();
|
|
818
|
+
ctx.hasVibration = "vibrate" in navigator;
|
|
819
|
+
ctx.hasDeviceMotion = "DeviceMotionEvent" in window;
|
|
820
|
+
try {
|
|
821
|
+
ctx.hasBrave = (_e = await ((_d = (_c = navigator.brave) == null ? void 0 : _c.isBrave) == null ? void 0 : _d.call(_c))) != null ? _e : false;
|
|
822
|
+
} catch (e) {
|
|
823
|
+
ctx.hasBrave = false;
|
|
824
|
+
}
|
|
825
|
+
const { renderer, vendor, maxTextureSize, fragPrecision, compressedFormats } = getWebGLInfo();
|
|
612
826
|
if (renderer !== void 0) ctx.webglRenderer = renderer;
|
|
613
827
|
if (vendor !== void 0) ctx.webglVendor = vendor;
|
|
828
|
+
if (maxTextureSize !== void 0) ctx.webglMaxTextureSize = maxTextureSize;
|
|
829
|
+
if (fragPrecision !== void 0) ctx.webglFragPrecision = fragPrecision;
|
|
830
|
+
if (compressedFormats !== void 0) ctx.webglCompressedFormats = compressedFormats;
|
|
614
831
|
}
|
|
615
832
|
if (base.userAgentData) {
|
|
616
833
|
try {
|
|
@@ -637,6 +854,26 @@ async function getEnvContext() {
|
|
|
637
854
|
return ctx;
|
|
638
855
|
}
|
|
639
856
|
|
|
857
|
+
// src/utils/windows-version.ts
|
|
858
|
+
async function getWindowsVersion(nav) {
|
|
859
|
+
var _a;
|
|
860
|
+
if (!nav.userAgentData || nav.userAgentData.platform !== "Windows") {
|
|
861
|
+
return null;
|
|
862
|
+
}
|
|
863
|
+
try {
|
|
864
|
+
const data = await nav.userAgentData.getHighEntropyValues(["platformVersion"]);
|
|
865
|
+
const major = parseInt(((_a = data["platformVersion"]) == null ? void 0 : _a.split(".")[0]) || "0", 10);
|
|
866
|
+
return major >= 13 ? "11" : "10";
|
|
867
|
+
} catch (e) {
|
|
868
|
+
return null;
|
|
869
|
+
}
|
|
870
|
+
}
|
|
871
|
+
|
|
872
|
+
// src/utils/satisfies.ts
|
|
873
|
+
function satisfies(info, criteria) {
|
|
874
|
+
return Object.keys(criteria).every((key) => info[key] === criteria[key]);
|
|
875
|
+
}
|
|
876
|
+
|
|
640
877
|
// src/parse-headers.ts
|
|
641
878
|
var ACCEPT_CH = [
|
|
642
879
|
"Sec-CH-UA-Arch",
|
|
@@ -656,7 +893,7 @@ function deriveWindowsVersion2(platformVersion) {
|
|
|
656
893
|
return isNaN(major) ? null : major >= 13 ? "11" : "10";
|
|
657
894
|
}
|
|
658
895
|
function parseHeaders(headers) {
|
|
659
|
-
var _a, _b;
|
|
896
|
+
var _a, _b, _c, _d, _e;
|
|
660
897
|
const normalised = {};
|
|
661
898
|
for (const key of Object.keys(headers)) {
|
|
662
899
|
normalised[key.toLowerCase()] = headers[key];
|
|
@@ -666,11 +903,13 @@ function parseHeaders(headers) {
|
|
|
666
903
|
return Array.isArray(v) ? v[0] : v;
|
|
667
904
|
};
|
|
668
905
|
const ua = (_a = get("user-agent")) != null ? _a : "";
|
|
906
|
+
const rawLang = get("accept-language");
|
|
907
|
+
const language = rawLang ? (_d = (_c = (_b = rawLang.split(",")[0]) == null ? void 0 : _b.split(";")[0]) == null ? void 0 : _c.trim()) != null ? _d : "" : "";
|
|
669
908
|
const architecture = unquote(get("sec-ch-ua-arch"));
|
|
670
909
|
const bitness = unquote(get("sec-ch-ua-bitness"));
|
|
671
910
|
const model = unquote(get("sec-ch-ua-model"));
|
|
672
911
|
const platformVersion = unquote(get("sec-ch-ua-platform-version"));
|
|
673
|
-
const platform = (
|
|
912
|
+
const platform = (_e = unquote(get("sec-ch-ua-platform"))) != null ? _e : "";
|
|
674
913
|
const highEntropyData = {};
|
|
675
914
|
if (architecture !== void 0) highEntropyData.architecture = architecture;
|
|
676
915
|
if (bitness !== void 0) highEntropyData.bitness = bitness;
|
|
@@ -681,7 +920,7 @@ function parseHeaders(headers) {
|
|
|
681
920
|
const ctx = {
|
|
682
921
|
userAgent: ua,
|
|
683
922
|
platform,
|
|
684
|
-
language
|
|
923
|
+
language,
|
|
685
924
|
maxTouchPoints: isMobile ? 1 : 0,
|
|
686
925
|
highEntropyData: Object.keys(highEntropyData).length > 0 ? highEntropyData : void 0,
|
|
687
926
|
windowsVersion
|
|
@@ -691,15 +930,19 @@ function parseHeaders(headers) {
|
|
|
691
930
|
|
|
692
931
|
// src/index.ts
|
|
693
932
|
var { version: VERSION } = package_default;
|
|
694
|
-
function uaBrowser(
|
|
933
|
+
function uaBrowser() {
|
|
695
934
|
const nav = getNavContext();
|
|
696
|
-
return parseUA(
|
|
935
|
+
return parseUA(nav.userAgent, { nav });
|
|
697
936
|
}
|
|
937
|
+
uaBrowser.detect = async (ua) => {
|
|
938
|
+
const ctx = await getEnvContext();
|
|
939
|
+
return parseUA(ua != null ? ua : ctx.userAgent, { ctx });
|
|
940
|
+
};
|
|
698
941
|
uaBrowser.isWebview = isWebview;
|
|
699
942
|
uaBrowser.getLanguage = () => getLanguage(getNavContext());
|
|
700
943
|
uaBrowser.VERSION = VERSION;
|
|
701
944
|
var src_default = uaBrowser;
|
|
702
945
|
|
|
703
|
-
export { ACCEPT_CH, VERSION, src_default as default, detectArch, detectBot, detectHeadless, getEnvContext, getLanguage, getNavContext, getWindowsVersion, isWebview, parseHeaders, parseUA };
|
|
946
|
+
export { ACCEPT_CH, VERSION, src_default as default, detectArch, detectBot, detectBrowser, detectHeadless, detectOs as detectOS, getEnvContext, getLanguage, getNavContext, getWindowsVersion, isWebview, parseHeaders, parseUA, satisfies };
|
|
704
947
|
//# sourceMappingURL=index.mjs.map
|
|
705
948
|
//# sourceMappingURL=index.mjs.map
|