ua-browser 1.3.1 → 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 +277 -44
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +82 -17
- package/dist/index.d.ts +82 -17
- package/dist/index.min.js +2 -2
- package/dist/index.min.js.map +1 -1
- package/dist/index.mjs +275 -45
- 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";
|
|
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";
|
|
303
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,7 +685,8 @@ 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
|
|
|
@@ -544,21 +717,56 @@ function probeFonts() {
|
|
|
544
717
|
}
|
|
545
718
|
}
|
|
546
719
|
function getWebGLInfo() {
|
|
547
|
-
var _a;
|
|
720
|
+
var _a, _b;
|
|
548
721
|
try {
|
|
549
722
|
const canvas = document.createElement("canvas");
|
|
550
723
|
const gl = (_a = canvas.getContext("webgl")) != null ? _a : canvas.getContext("experimental-webgl");
|
|
551
724
|
if (!gl) return {};
|
|
552
725
|
const ext = gl.getExtension("WEBGL_debug_renderer_info");
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
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
|
+
}
|
|
557
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;
|
|
558
741
|
} catch (e) {
|
|
559
742
|
return {};
|
|
560
743
|
}
|
|
561
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
|
+
}
|
|
562
770
|
function getPointerType() {
|
|
563
771
|
try {
|
|
564
772
|
if (window.matchMedia("(pointer: coarse)").matches) return "coarse";
|
|
@@ -582,6 +790,7 @@ function deriveWindowsVersion(platformVersion) {
|
|
|
582
790
|
return isNaN(major) ? null : major >= 13 ? "11" : "10";
|
|
583
791
|
}
|
|
584
792
|
async function getEnvContext() {
|
|
793
|
+
var _a, _b, _c, _d, _e;
|
|
585
794
|
const base = getNavContext();
|
|
586
795
|
const ctx = {
|
|
587
796
|
userAgent: base.userAgent,
|
|
@@ -599,12 +808,26 @@ async function getEnvContext() {
|
|
|
599
808
|
}
|
|
600
809
|
if (typeof window !== "undefined") {
|
|
601
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();
|
|
602
814
|
ctx.pointerType = getPointerType();
|
|
603
815
|
ctx.hoverCapability = getHoverCapability();
|
|
604
816
|
ctx.fontProbes = probeFonts();
|
|
605
|
-
|
|
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();
|
|
606
826
|
if (renderer !== void 0) ctx.webglRenderer = renderer;
|
|
607
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;
|
|
608
831
|
}
|
|
609
832
|
if (base.userAgentData) {
|
|
610
833
|
try {
|
|
@@ -646,6 +869,11 @@ async function getWindowsVersion(nav) {
|
|
|
646
869
|
}
|
|
647
870
|
}
|
|
648
871
|
|
|
872
|
+
// src/utils/satisfies.ts
|
|
873
|
+
function satisfies(info, criteria) {
|
|
874
|
+
return Object.keys(criteria).every((key) => info[key] === criteria[key]);
|
|
875
|
+
}
|
|
876
|
+
|
|
649
877
|
// src/parse-headers.ts
|
|
650
878
|
var ACCEPT_CH = [
|
|
651
879
|
"Sec-CH-UA-Arch",
|
|
@@ -665,7 +893,7 @@ function deriveWindowsVersion2(platformVersion) {
|
|
|
665
893
|
return isNaN(major) ? null : major >= 13 ? "11" : "10";
|
|
666
894
|
}
|
|
667
895
|
function parseHeaders(headers) {
|
|
668
|
-
var _a, _b;
|
|
896
|
+
var _a, _b, _c, _d, _e;
|
|
669
897
|
const normalised = {};
|
|
670
898
|
for (const key of Object.keys(headers)) {
|
|
671
899
|
normalised[key.toLowerCase()] = headers[key];
|
|
@@ -675,11 +903,13 @@ function parseHeaders(headers) {
|
|
|
675
903
|
return Array.isArray(v) ? v[0] : v;
|
|
676
904
|
};
|
|
677
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 : "" : "";
|
|
678
908
|
const architecture = unquote(get("sec-ch-ua-arch"));
|
|
679
909
|
const bitness = unquote(get("sec-ch-ua-bitness"));
|
|
680
910
|
const model = unquote(get("sec-ch-ua-model"));
|
|
681
911
|
const platformVersion = unquote(get("sec-ch-ua-platform-version"));
|
|
682
|
-
const platform = (
|
|
912
|
+
const platform = (_e = unquote(get("sec-ch-ua-platform"))) != null ? _e : "";
|
|
683
913
|
const highEntropyData = {};
|
|
684
914
|
if (architecture !== void 0) highEntropyData.architecture = architecture;
|
|
685
915
|
if (bitness !== void 0) highEntropyData.bitness = bitness;
|
|
@@ -690,7 +920,7 @@ function parseHeaders(headers) {
|
|
|
690
920
|
const ctx = {
|
|
691
921
|
userAgent: ua,
|
|
692
922
|
platform,
|
|
693
|
-
language
|
|
923
|
+
language,
|
|
694
924
|
maxTouchPoints: isMobile ? 1 : 0,
|
|
695
925
|
highEntropyData: Object.keys(highEntropyData).length > 0 ? highEntropyData : void 0,
|
|
696
926
|
windowsVersion
|
|
@@ -700,9 +930,9 @@ function parseHeaders(headers) {
|
|
|
700
930
|
|
|
701
931
|
// src/index.ts
|
|
702
932
|
var { version: VERSION } = package_default;
|
|
703
|
-
function uaBrowser(
|
|
933
|
+
function uaBrowser() {
|
|
704
934
|
const nav = getNavContext();
|
|
705
|
-
return parseUA(
|
|
935
|
+
return parseUA(nav.userAgent, { nav });
|
|
706
936
|
}
|
|
707
937
|
uaBrowser.detect = async (ua) => {
|
|
708
938
|
const ctx = await getEnvContext();
|
|
@@ -713,6 +943,6 @@ uaBrowser.getLanguage = () => getLanguage(getNavContext());
|
|
|
713
943
|
uaBrowser.VERSION = VERSION;
|
|
714
944
|
var src_default = uaBrowser;
|
|
715
945
|
|
|
716
|
-
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 };
|
|
717
947
|
//# sourceMappingURL=index.mjs.map
|
|
718
948
|
//# sourceMappingURL=index.mjs.map
|