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