PageSourceSearch

https://toolbreezy.com/_next/static/chunks/85261-2a713b44d9e93baf.js

js toolbreezy.com collected 2026-09-24 14:57:41 UTC 43,557 bytes, 22 lines download raw bytes

1"use strict";(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[85261],{85261:(e,r,s)=>{s.r(r),s.d(r,{default:()=>J});var t=s(95155),a=s(12115),o=s(97003),n=s(16110),i=s(27784),l=s(33789),d=s(90235),c=s(67001),m=s(33534),h=s(25016),p=s(21158),u=s(84296);let b="caniuse-lite 1.0.30001806, the browser release database bundled with this site",f=[{id:"chrome",name:"Chrome",engine:"Blink",version:"150",released:"2026-06-30",platforms:["windows","macos","linux","android","ios","ipados"]},{id:"edge",name:"Microsoft Edge",engine:"Blink",version:"150",released:"2026-07-02",platforms:["windows","macos","linux","android","ios","ipados"]},{id:"firefox",name:"Firefox",engine:"Gecko",version:"152",released:"2026-06-16",platforms:["windows","macos","linux","android","ios","ipados"]},{id:"safari",name:"Safari",engine:"WebKit",version:"26.4",released:"2026-03-24",platforms:["macos","ios","ipados"]},{id:"opera",name:"Opera",engine:"Blink",version:"131",released:"2026-04-14",platforms:["windows","macos","linux","android"],fork:!0},{id:"samsung",name:"Samsung Internet",engine:"Blink",version:"30",released:"2026-05-20",platforms:["android"],fork:!0}],g=[{id:"windows",name:"Windows",kind:"desktop"},{id:"macos",name:"macOS",kind:"desktop"},{id:"linux",name:"Linux",kind:"desktop"},{id:"android",name:"Android",kind:"mobile"},{id:"ios",name:"iPhone",kind:"mobile"},{id:"ipados",name:"iPad",kind:"tablet"}];function x(e){return f.find(r=>r.id===e)??f[0]}function w(e,r){return x(e).platforms.includes(r)}let v=["16","15","14","13"],j=["Pixel 9 Pro","Pixel 9","Pixel 8","SM-S928B","SM-S918B","SM-A546B"],y=[{label:"Windows 11",value:"15.0.0"},{label:"Windows 10",value:"10.0.0"}],k={browser:"chrome",platform:"windows",tablet:!1,reduced:!0,androidVersion:"16",androidModel:"Pixel 9",windowsHintVersion:"15.0.0",arch:"x86",bitness:"64",highEntropy:!1,greaseSeed:0,versionOverride:""};function N(e){return"android"===e.platform?e.tablet?"tablet":"mobile":g.find(r=>r.id===e.platform)?.kind??"desktop"}function S(e){return"ios"===e.platform||"ipados"===e.platform?"WebKit":x(e.browser).engine}let $=/^\d{1,3}(\.\d+)*$/;function C(e){let r=e.versionOverride.trim();if(!r)return null;let s=x(e.browser);if(!$.test(r))return`"${r}" is not a version number. A major is one to three digits, optionally followed by dotted parts, like 139 or 139.0.7258.67. If you typed a decimal comma, the box drops it and the digits run together.`;let t=Number(r.split(".")[0]),a=Number(String(s.version).split(".")[0]);return Number.isFinite(t)&&Number.isFinite(a)?t>a+8?`${s.name} ${t} does not exist. The newest this page knows about is ${a}, and a string announcing a build that has not shipped stands out more than an ordinary one. Check for a stray digit or a decimal comma.`:t<a-24?`${s.name} ${t} is years behind the current ${a}. That is fine if you meant it, and a common accident if you typed a decimal comma, which the box drops and leaves the digits running together.`:null:null}function A(e,r){let s=x(e.browser),t=e.versionOverride.trim();return t?{version:t,from:"typed"}:r?.chromiumMajor&&("chrome"===e.browser||"edge"===e.browser)?{version:r.chromiumMajor,from:"live"}:{version:s.version,from:"table"}}function M(){return x("chrome").version}function O(e,r){let s=x(e.browser);if(s.fork){if(s.chromiumMajor)return{version:s.chromiumMajor,from:"table"};let t=function(e,r,s){if(!s?.chromiumMajor)return null;let t=s.fullVersions??[],a=e.name.toLowerCase(),o=t.find(e=>String(e.brand).toLowerCase()===a);if(!o)return null;let n=String(o.version).split(".")[0]??"";return n&&n===String(r).split(".")[0]?s.chromiumMajor:null}(s,A(e,r).version,r);return t?{version:t,from:"live"}:{version:null,from:"unknown"}}return r?.chromiumMajor?{version:r.chromiumMajor,from:"live"}:{version:M(),from:"table"}}function T(e,r){let s=x(e.browser);return s.fork&&null===O(e,r).version?`This page cannot say which Chromium build ${s.name} ${A(e,r).version} is on. ${b} carries the release date of every ${s.name} version but not the Chromium major behind it, and a ${s.name} string is mostly a Chrome token, so guessing one would produce exactly the giveaway this page exists to avoid. Open this page in ${s.name} itself and it reads the real number out of that browser, or paste a genuine ${s.name} string into the box further down to check one you already have.`:null}let P="15E148",W=["Not)A;Brand","Not_A Brand","Not.A/Brand","Not/A)Brand","Not;A=Brand","Not(A:Brand","Not-A.Brand","Not=A?Brand"],H=["8","24","99"];function E(e){let r=Math.abs(Math.trunc(e));return{brand:W[r%W.length]??W[0],version:H[Math.floor(r/W.length)%H.length]??H[0]}}function V(e){return"Blink"===S(e)}let B={windows:"Windows",macos:"macOS",linux:"Linux",android:"Android",ios:"iOS",ipados:"iOS"};function L(e,r){if(null!==T(e,r))return[];let s=[{name:"User-Agent",value:function(e,r){let s=O(e,r).version;if(null===s)return"";let t=function(e,r){let s=S(e),t=x("safari").version;if("ios"===e.platform||"ipados"===e.platform){let r=t.replace(/\./g,"_");return"ipados"===e.platform?`iPad; CPU OS ${r} like Mac OS X`:`iPhone; CPU iPhone OS ${r} like Mac OS X`}if("Gecko"===s){let s=A(e,r).version;return"windows"===e.platform?`Windows NT 10.0; Win64; x64; rv:${s}.0`:"macos"===e.platform?`Macintosh; Intel Mac OS X 10.15; rv:${s}.0`:"linux"===e.platform?`X11; Linux x86_64; rv:${s}.0`:`Android ${e.androidVersion}; ${e.tablet?"Tablet":"Mobile"}`}return"windows"===e.platform?"Windows NT 10.0; Win64; x64":"macos"===e.platform?"Macintosh; Intel Mac OS X 10_15_7":"linux"===e.platform?"X11; Linux x86_64":e.reduced?"Linux; Android 10; K":`Linux; Android ${e.androidVersion}; ${e.androidModel}`}(e,r),a=A(e,r).version,o=S(e),n="mobile"===N(e)?"Mobile ":"";if("Gecko"===o)return"android"===e.platform?`Mozilla/5.0 (${t}; rv:${a}.0) Gecko/${a}.0 Firefox/${a}.0`:`Mozilla/5.0 (${t}) Gecko/20100101 Firefox/${a}.0`;if("ios"===e.platform||"ipados"===e.platform){let r=`Mozilla/5.0 (${t}) AppleWebKit/605.1.15 (KHTML, like Gecko)`;return"chrome"===e.browser?`${r} CriOS/${a}.0.0.0 Mobile/${P} Safari/604.1`:"edge"===e.browser?`${r} EdgiOS/${a}.0.0.0 Mobile/${P} Safari/605.1.15`:"firefox"===e.browser?`${r} FxiOS/${a}.0 Mobile/${P} Safari/605.1.15`:`${r} Version/${a} Mobile/${P} Safari/604.1`}if("safari"===e.browser)return`Mozilla/5.0 (${t}) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/${a} Safari/605.1.15`;let i=`Mozilla/5.0 (${t}) AppleWebKit/537.36 (KHTML, like Gecko)`;if("samsung"===e.browser)return`${i} SamsungBrowser/${a}.0 Chrome/${s}.0.0.0 ${n}Safari/537.36`;let l=`${i} Chrome/${"opera"===e.browser?s:a}.0.0.0 ${n}Safari/537.36`;return"edge"===e.browser?`${l} ${"android"===e.platform?"EdgA":"Edg"}/${a}.0.0.0`:"opera"===e.browser?`${l} OPR/${a}.0.0.0`:l}(e,r),entropy:"low"}];if(!V(e))return s;let t=function(e,r){let s=A(e,r).version,t=O(e,r).version,a=x(e.browser);return"chrome"===e.browser?[{brand:"Chromium",version:s},{brand:"Google Chrome",version:s}]:"edge"===e.browser?[{brand:"Chromium",version:s},{brand:"Microsoft Edge",version:s}]:[{brand:"Chromium",version:t??""},{brand:a.name,version:s}]}(e,r),a=E(e.greaseSeed),o=e=>e.map(e=>`"${e.brand}";v="${e.version}"`).join(", "),n=[...t];n.splice(e.greaseSeed%(t.length+1),0,a);let i="mobile"===N(e);if(s.push({name:"Sec-CH-UA",value:o(n),entropy:"low",note:`The "${a.brand}" entry is GREASE, a deliberate decoy.`},{name:"Sec-CH-UA-Mobile",value:i?"?1":"?0",entropy:"low",note:"A boolean, so it is ?1 or ?0 and never true or false."},{name:"Sec-CH-UA-Platform",value:`"${B[e.platform]}"`,entropy:"low"}),!e.highEntropy)return s;let l=r?.fullVersions?.filter(e=>!/not.?a.?brand/i.test(e.brand))??[],d=l.length>0&&("chrome"===e.browser||"edge"===e.browser)?l:t.map(e=>
1({brand:e.brand,version:`${e.version}.0.0.0`})),c=[...d];c.splice(e.greaseSeed%(d.length+1),0,{brand:a.brand,version:`${a.version}.0.0.0`});let m="android"===e.platform?e.androidModel:"",h="windows"===e.platform?e.windowsHintVersion:"macos"===e.platform?`${x("safari").version}.0`:"android"===e.platform?`${e.androidVersion}.0.0`:r&&r.platformVersion&&"linux"===e.platform?r.platformVersion:"",p="desktop"===N(e)?"Desktop":"tablet"===N(e)?"Tablet":"Mobile";return s.push({name:"Sec-CH-UA-Arch",value:`"${"android"===e.platform?"arm":e.arch}"`,entropy:"high"},{name:"Sec-CH-UA-Bitness",value:`"${e.bitness}"`,entropy:"high"},{name:"Sec-CH-UA-Model",value:`"${m}"`,entropy:"high",note:m?"The real device model, which UA reduction moved out of the string and into here.":"Empty on desktop, which is correct."},{name:"Sec-CH-UA-Platform-Version",value:`"${h}"`,entropy:"high",note:"windows"===e.platform?"This is the only reliable way to tell Windows 11 from Windows 10. Anything from 13.0.0 up is Windows 11.":void 0},{name:"Sec-CH-UA-Full-Version-List",value:o(c),entropy:"high",note:l.length&&("chrome"===e.browser||"edge"===e.browser)?"Real build and patch digits, read from your own browser.":"Build and patch positions are zeroed here because a static table cannot know them. A real browser sends actual digits."},{name:"Sec-CH-UA-Form-Factors",value:`"${p}"`,entropy:"high"}),"windows"===e.platform&&s.push({name:"Sec-CH-UA-WoW64",value:"?0",entropy:"high"}),s}let U=/(Chrome|Chromium|Edg|EdgA|EdgiOS|OPR|CriOS|SamsungBrowser|YaBrowser|Vivaldi)\//;function G(e){let r=(0,p.wX)(e);return{browser:r.name,version:r.version||"unknown",engine:(0,p.s4)(e),os:/Windows NT 10\.0/.test(e)||/Windows NT/.test(e)?"Windows":/(iPhone OS|CPU OS) [\d_]+/.test(e)||/iPhone|iPad|iPod/.test(e)?"iOS":/Mac OS X|Macintosh/.test(e)?"macOS":/Android/.test(e)?"Android":/CrOS/.test(e)?"ChromeOS":/X11|Linux/.test(e)?"Linux":"Unknown",device:/iPad|Tablet/.test(e)||/Android/.test(e)&&!/Mobile/.test(e)?"tablet":/Mobi|Mobile|iPhone|iPod/.test(e)?"mobile":"desktop"}}let F={windows:"Windows",macos:"macOS",linux:"Linux",android:"Android",ios:"iOS",ipados:"iOS"},K={desktop:"a desktop",mobile:"a phone",tablet:"a tablet"},z=[{name:"Googlebot (smartphone)",template:"Mozilla/5.0 (Linux; Android 6.0.1; Nexus 5X Build/MMB29P) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/{C}.0.0.0 Mobile Safari/537.36 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)",docs:"developers.google.com/search/docs/crawling-indexing/google-common-crawlers"},{name:"Googlebot (desktop)",template:"Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; Googlebot/2.1; +http://www.google.com/bot.html) Chrome/{C}.0.0.0 Safari/537.36",docs:"developers.google.com/search/docs/crawling-indexing/google-common-crawlers"},{name:"Bingbot",template:"Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; bingbot/2.0; +http://www.bing.com/bingbot.htm) Chrome/{C}.0.0.0 Safari/537.36",docs:"bing.com/webmasters/help/which-crawlers-does-bing-use-8c184ec0"},{name:"DuckDuckBot",template:"Mozilla/5.0 (compatible; DuckDuckBot-Https/1.1; https://duckduckgo.com/duckduckbot)",docs:"duckduckgo.com/duckduckbot"},{name:"YandexBot",template:"Mozilla/5.0 (compatible; YandexBot/3.0; +http://yandex.com/bots)",docs:"yandex.com/support/webmaster/robot-workings/check-yandex-robots.html"},{name:"GPTBot",template:"Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko); compatible; GPTBot/1.2; +https://openai.com/gptbot",docs:"platform.openai.com/docs/bots"},{name:"ClaudeBot",template:"Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko); compatible; ClaudeBot/1.0; [email protected]",docs:"support.anthropic.com"},{name:"PerplexityBot",template:"Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; PerplexityBot/1.0; +https://perplexity.ai/perplexitybot)",docs:"docs.perplexity.ai/guides/bots"},{name:"Facebook crawler",template:"facebookexternalhit/1.1 (+http://www.facebook.com/externalhit_uatext.php)",docs:"developers.facebook.com/docs/sharing/webmasters/web-crawlers"}];var D=s(14827);async function q(){let e=navigator.userAgentData;if(!e)return{state:"none",seed:null};let r=e=>{let r=(e??[]).filter(e=>e.brand&&!/not.?a.?brand/i.test(e.brand)),s=r.find(e=>/chromium/i.test(e.brand))??r[0];return s?String(s.version).split(".")[0]??"":""};if("function"!=typeof e.getHighEntropyValues)return{state:"partial",seed:{chromiumMajor:r(e.brands),fullVersions:[],platform:e.platform??"",platformVersion:"",arch:"",b
1itness:"",model:"",mobile:"boolean"==typeof e.mobile?e.mobile:null,partial:!0}};try{let s=await e.getHighEntropyValues(["architecture","bitness","model","platformVersion","fullVersionList"]),t=s.fullVersionList??e.brands??[];return{state:"live",seed:{chromiumMajor:r(t),fullVersions:t.map(e=>({brand:e.brand,version:e.version})),platform:e.platform??s.platform??"",platformVersion:s.platformVersion??"",arch:s.architecture??"",bitness:s.bitness??"",model:s.model??"",mobile:"boolean"==typeof e.mobile?e.mobile:null,partial:!1}}}catch{return{state:"partial",seed:{chromiumMajor:r(e.brands),fullVersions:[],platform:e.platform??"",platformVersion:"",arch:"",bitness:"",model:"",mobile:"boolean"==typeof e.mobile?e.mobile:null,partial:!0}}}}let R="h-9 w-full rounded-md border border-input bg-background px-3 text-sm shadow-sm focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring";function _({tone:e,children:r}){return(0,t.jsx)("span",{className:(0,h.cn)("inline-block rounded border px-1.5 py-0.5 text-[11px] font-medium leading-tight","live"===e&&"border-emerald-600/40 bg-emerald-600/10 text-emerald-700 dark:text-emerald-400","table"===e&&"border-sky-600/40 bg-sky-600/10 text-sky-700 dark:text-sky-400","warn"===e&&"border-amber-600/40 bg-amber-600/10 text-amber-700 dark:text-amber-500","note"===e&&"bg-muted text-muted-foreground"),children:r})}function I(e,r,s){let t=new Blob([r],{type:s});(0,D.WN)(t,e)}function J(){let[e,r]=(0,a.useState)(k),[s,p]=(0,a.useState)(null),[$,P]=(0,a.useState)("pending"),[W,H]=(0,a.useState)(""),[B,D]=(0,a.useState)("curl"),[J,X]=(0,a.useState)(null),[Y,Q]=(0,a.useState)(""),[Z,ee]=(0,a.useState)(["chrome","edge","firefox","safari"]),[er,es]=(0,a.useState)(["windows","macos","android","ios"]),[et,ea]=(0,a.useState)("25"),[eo,en]=(0,a.useState)(!0),[ei,el]=(0,a.useState)(null),ed=(0,a.useCallback)((e,s)=>{r(r=>({...r,[e]:s})),H("")},[]);(0,a.useEffect)(()=>{q().then(({state:e,seed:s})=>{if(P(e),p(s),!s)return;let t="arm"===s.arch?"arm":"x86"===s.arch?"x86":null,a="32"===s.bitness||"64"===s.bitness?s.bitness:null;(t||a)&&r(e=>({...e,arch:t&&e.arch===k.arch?t:e.arch,bitness:a&&e.bitness===k.bitness?a:e.bitness}))});let e=new Date;Q(e.toISOString().slice(0,10)),X(e.getTime());let s=new URLSearchParams(window.location.search),t={},a=s.get("b"),o=s.get("p");a&&f.some(e=>e.id===a)&&(t.browser=a),o&&g.some(e=>e.id===o)&&(t.platform=o),s.get("t")&&(t.tablet="1"===s.get("t")),s.get("r")&&(t.reduced="1"===s.get("r")),s.get("h")&&(t.highEntropy="1"===s.get("h"));let n=s.get("av");null!==n&&/^\d{1,3}(\.\d{1,3}){0,2}$/.test(n)&&(t.androidVersion=n);let i=s.get("am");null!==i&&i.length>0&&i.length<=40&&(t.androidModel=i);let l=s.get("wv");null!==l&&/^\d{1,3}(\.\d{1,3}){0,2}$/.test(l)&&(t.windowsHintVersion=l);let d=s.get("a");("x86"===d||"arm"===d)&&(t.arch=d);let c=Number(s.get("gs"));null!==s.get("gs")&&Number.isInteger(c)&&c>=0&&c<1e3&&(t.greaseSeed=c);let m=s.get("vo");if(null!==m&&/^\d{0,4}$/.test(m)&&(t.versionOverride=m),0===Object.keys(t).length)try{let e=localStorage.getItem("ua-generator");if(e){let r=JSON.parse(e);r.browser&&f.some(e=>e.id===r.browser)&&(t.browser=r.browser),r.platform&&g.some(e=>e.id===r.platform)&&(t.platform=r.platform)}}catch{}Object.keys(t).length>0&&r(e=>({...e,...t}))},[]),(0,i.Vd)("ua-generator",()=>JSON.stringify({browser:e.browser,platform:e.platform}),[e.browser,e.platform]),(0,a.useEffect)(()=>{if(!w(e.browser,e.platform)){let s=x(e.browser).platforms[0];s&&r(e=>({...e,platform:s}))}},[e.browser,e.platform]);let ec=(0,a.useMemo)(()=>L(e,s),[e,s]),em=ec[0]?.value??"",eh=W.trim().length>0,ep=eh?W.trim():em,eu=(0,a.useMemo)(()=>{let e=ec[0];return eh&&e?[{...e,value:ep},...ec.slice(1)]:ec},[eh,ec,ep]),eb=(0,a.useMemo)(()=>eh?eu.slice(0,1):eu,[eh,eu]),ef=(0,a.useMemo)(()=>T(e,s),[e,s]),eg=null!==ef&&!eh,ex=(0,a.useMemo)(()=>eg?[]:function(e,r,s,t=!0,a=t){let o=G(e),n=x(s.browser),i=S(s),l=N(s),d=[];if("Unknown"===o.browser&&"Unknown"===o.engine)return d.push({ok:!1,label:"This parses as a user agent",detail:"No brand or engine token was found, so nothing below could be checked. Every check that follows only runs on tokens this string does not have."}),d;if(t){let e=C(s);s.versionOverride.trim()&&d.push({ok:null===e,label:"The version you typed is a version that exists",detail
1:e??`${s.versionOverride.trim()} is a plausible ${n.name} version, within reach of the ${n.version} this page has in its table.`});let r="safari"===s.browser?"Safari":n.name;d.push({ok:o.browser===r,label:"Browser reads back correctly",detail:o.browser===r?`A server parsing this sees ${o.browser}.`:`You asked for ${r} but a parser reads ${o.browser}. The brand token is wrong or missing.`}),d.push({ok:o.os===F[s.platform],label:"Operating system reads back correctly",detail:o.os===F[s.platform]?`The platform section resolves to ${o.os}.`:`You asked for ${F[s.platform]} but a parser reads ${o.os}.`}),d.push({ok:o.device===l,label:"Device class reads back correctly",detail:o.device===l?`A server treats this as ${K[l]}.`:`You asked for ${K[l]} but a parser reads ${K[o.device]??o.device}. On Android the Mobile token is the only thing separating a phone from a tablet.`}),d.push({ok:o.engine===i,label:"Rendering engine reads back correctly",detail:o.engine===i?`Resolves to ${o.engine}.`:`Expected ${i}, a parser reads ${o.engine}.`})}if("iOS"===o.os){let r=/\bChrome\/\d/.test(e);d.push({ok:!r,label:"No desktop Chrome token on an Apple mobile platform",detail:r?"This carries a Chrome/ token on iPhone or iPad. Real Chrome there uses CriOS/, and a server parsing this reports the wrong browser.":"Correct. Apple requires WebKit there, so Chrome uses CriOS, Edge uses EdgiOS and Firefox uses FxiOS."})}if(/Edg[A]?\/\d/.test(e)){let r=e.search(/Chrome\/\d/),s=e.search(/Edg[A]?\/\d/),t=r>=0&&s>r;d.push({ok:t,label:"Edge keeps its Chrome token, in order",detail:t?"Chrome/ appears before Edg/, which is what real Edge sends.":"Edge must carry the Chrome token first and Edg/ after it. Without the Chrome token, most parsers see plain Edge or nothing."})}if("macOS"===o.os&&"Gecko"!==o.engine){let r=e.includes("Mac OS X 10_15_7");d.push({ok:r,label:"macOS version sits on the frozen value",detail:r?"Reports Mac OS X 10_15_7 with underscores, which every current Safari and Chrome sends whatever the real macOS is.":"A WebKit or Chromium string on macOS is frozen at 10_15_7, with underscores. Anything else stands out."})}if(/Windows NT/.test(e)){let r=/Windows NT 1[1-9]/.test(e);d.push({ok:!r,label:"No Windows NT 11",detail:r?"There is no Windows NT 11. Windows 10 and Windows 11 both report NT 10.0, and only Sec-CH-UA-Platform-Version separates them.":"Reports NT 10.0, which covers both Windows 10 and Windows 11."})}let c=/Version\/[\d.]+/.test(e)&&/Safari\/[\d.]+/.test(e)&&!U.test(e)&&/Windows|Android/.test(e);d.push({ok:!c,label:"No Safari on a platform Safari never shipped for",detail:c?"This is the Version/ plus Safari/ pair with no Chromium brand on Windows or Android, which is Safari claiming a platform it does not run on.":"Nothing here claims Safari on Windows or Android."});let m=a?r.find(e=>"Sec-CH-UA-Mobile"===e.name):void 0;if(a)if(m){let e="mobile"===o.device?"?1":"?0",r=m.value===e;d.push({ok:r,label:"Header set agrees with the string",detail:r?`Sec-CH-UA-Mobile is ${m.value}, which matches the device the string describes.`:`Sec-CH-UA-Mobile says ${m.value} while the string describes ${K[o.device]??o.device}. A server reading both sees a contradiction.`})}else{let e="Blink"===o.engine;d.push({ok:!e,label:"Client Hints match the browser",detail:e?"A Chromium browser sends Sec-CH-UA on every request and this set has none.":`${t?n.name:o.browser}${"iOS"===o.os?" on an Apple mobile platform":""} sends no Client Hints, so emitting none is correct.`})}return d}(ep,eb,e,!eh,!eh),[eg,ep,eb,e,eh]),ew=(0,a.useMemo)(()=>G(ep),[ep]),ev=(0,a.useMemo)(()=>(function(e,r){let s=e[0]?.value??"",t=e.slice(1),a=e.map(e=>`  -H '${e.name}: ${e.value.replace(/'/g,"'\\''")}'`).join(" \\\n"),o=t.map(e=>`    '${e.name}': '${e.value.replace(/'/g,"\\'")}',`).join("\n"),n=e.map(e=>`    "${e.name}": ${JSON.stringify(e.value)},`).join("\n");return[{id:"curl",title:"curl",code:`curl https://example.com \\
2${a}`,caveat:"Sends the whole request the way a real browser would, classic header and hints together."},{id:"chrome-flag",title:"Chrome launch flag",code:`chrome --user-agent="${s}
2"`,caveat:"Applies for that launch and that profile only. It changes the classic string and leaves the Client Hints your browser sends alone, so the two stop agreeing."},{id:"playwright",title:"Playwright",code:`const context = await browser.newContext({
3  userAgent: '${s.replace(/'/g,"\\'")}',
4});
5${t.length?`
6// The hint headers are a separate setting, not part of userAgent.
7await context.setExtraHTTPHeaders({
8${o}
9});`:""}`,caveat:"The user agent and the hint headers are set in two different places. Setting only the first is the mistake that makes a spoof fail."},{id:"puppeteer",title:"Puppeteer",code:`await page.setUserAgent('${s.replace(/'/g,"\\'")}');
10${t.length?`await page.setExtraHTTPHeaders({
11${o}
12});`:""}`,caveat:"Two calls, same reason as Playwright."},{id:"python",title:"Python requests",code:`import requests
13
14headers = {
15${n}
16}
17r = requests.get("https://example.com", headers=headers)`,caveat:"Drop the whole dict in. Leaving the default python-requests string in place is what gets a scraper blocked in the first place."},{id:"devtools",title:"Chrome DevTools",code:`1. Open DevTools, press Ctrl+Shift+P (Cmd+Shift+P on a Mac)
182. Run "Show Network conditions"
193. Untick "Use browser default" under User agent
204. Paste:
21
22${s}`,caveat:"Per tab, per session, and gone when you close it. Handy for one manual check, useless for a test suite."}]})(eu,0),[eu,e]),ej=ev.find(e=>e.id===B)??ev[0],ey=A(e,s),ek=O(e,s),eN=x(e.browser),eS=C(e),e$=ex.filter(e=>!e.ok),eC=E(e.greaseSeed),eA=function(e){let r=e.filter(e=>"high"===e.entropy).map(e=>e.name);return r.length?`Accept-CH: ${r.join(", ")}`:""}(eu),eM=null===J?null:Math.floor((J-new Date(eN.released).getTime())/864e5),eO=(0,a.useCallback)(()=>{let r=new URLSearchParams;return r.set("b",e.browser),r.set("p",e.platform),e.tablet&&r.set("t","1"),e.reduced||r.set("r","0"),e.highEntropy&&r.set("h","1"),e.androidVersion!==k.androidVersion&&r.set("av",e.androidVersion),e.androidModel!==k.androidModel&&r.set("am",e.androidModel),e.windowsHintVersion!==k.windowsHintVersion&&r.set("wv",e.windowsHintVersion),e.arch!==k.arch&&r.set("a",e.arch),e.greaseSeed!==k.greaseSeed&&r.set("gs",String(e.greaseSeed)),e.versionOverride!==k.versionOverride&&r.set("vo",e.versionOverride),r},[e]),eT=eu.map(e=>`${e.name}: ${e.value}`).join("\n"),eP=(e,r,s)=>s(e.includes(r)?e.filter(e=>e!==r):[...e,r]);return(0,t.jsxs)("div",{className:"space-y-6",children:[(0,t.jsx)("div",{className:"rounded-md border-l-4 border-l-amber-500 bg-amber-500/5 p-3 text-sm",children:(0,t.jsxs)("p",{children:[(0,t.jsx)("span",{className:"font-medium",children:"No web page can change the user agent your browser sends"}),", so there is no switch on this page that will do it. What you get instead is the exact string, the headers that have to travel with it, and the one-line command that applies both in curl, Playwright, Puppeteer, Python or DevTools."]})}),(0,t.jsxs)("div",{className:"grid gap-4 sm:grid-cols-2",children:[(0,t.jsxs)("div",{className:"space-y-1.5",children:[(0,t.jsx)(d.J,{htmlFor:"browser",children:"Browser"}),(0,t.jsx)("select",{id:"browser",className:R,value:e.browser,onChange:e=>ed("browser",e.target.value),children:f.map(e=>(0,t.jsx)("option",{value:e.id,children:e.name},e.id))})]}),(0,t.jsxs)("div",{className:"space-y-1.5",children:[(0,t.jsx)(d.J,{htmlFor:"platform",children:"Platform"}),(0,t.jsx)("select",{id:"platform",className:R,value:e.platform,onChange:e=>ed("platform",e.target.value),children:g.map(r=>(0,t.jsx)("option",{value:r.id,disabled:!w(e.browser,r.id),children:w(e.browser,r.id)?r.name:`${r.name} (not possible)`},r.id))})]})]}),g.some(r=>!w(e.browser,r.id))&&(0,t.jsx)("ul",{className:"space-y-1 text-xs text-muted-foreground",children:g.filter(r=>!w(e.browser,r.id)).map(r=>(0,t.jsxs)("li",{children:[(0,t.jsxs)("span",{className:"font-medium",children:[eN.name," on ",r.name,":"]})," ",function(e,r){if("safari"===e){if("windows"===r)return"Apple stopped shipping Safari for Windows back in 2012.";if("linux"===r)return"Safari has never shipped for Linux.";if("android"===r)return"Safari has never shipped for Android."}return"samsung"===e?"Samsung Internet ships on Samsung Android devices only.":"opera"===e&&("ios"===r||"ipados"===r)?"Opera on iPhone and iPad uses its own tokens on top of WebKit, which this builder does not cover yet.":"This browser does not ship on that platform."}(e.browser,r.id)]},r.id))}),(0,t.jsxs)("div",{className:"grid gap-4 sm:grid-cols-2",children:[(0,t.jsxs)("div",{className:"space-y-1.5",children:[(0,t.jsx)(d.J,{htmlFor:"version",children:"Version"}),(0,t.jsx)(l.p,{id:"version",value:e.versionOverride,placeholder:ey.version,inputMode:"decimal",onChange:e=>ed("versionOverride",e.target.value.replace(/[^\d.]/g,""))}),(0,t.jsxs)("div",{className:"flex flex-wrap items-center gap-1.5",children:["live"===ey.from&&(0,t.jsx)(_,{tone:"live",children:"live from your browser"}),"table"===ey.from&&(0,t.jsxs)(_,{tone:"table",children:["table, ",eN.released]}),"typed"===ey.from&&(0,t.jsx)(_,{tone:"note",children:"your number"}),eN.fork&&(null===ek.version?(0,t.jsx)(_,{tone:"warn",children:"Chromium base not known for this fork"}):"live"===ek.from?(0,t.jsxs)(_,{tone:"live",children:["Chromium base ",ek.version,", read from your own ",eN.name]}):(0,t.jsxs)(_,{tone:"table",children:["Chromium base ",ek.version,", from the table"]}))]}),null!==eS&&(0,t.jsx)("p",{className:"text-xs font-medium text-amber-700 dark:text-amber-500",children:eS})]}),"android"===e.platform&&(0,t.jsxs)("div",{className:"space-y-1.5",children:[(0,t.jsx)(d.J,{htmlFor:"device",children:"Device"}),(0,t.jsxs)("select",{id:"device",className:R,value:e.tablet?"tablet":"phone",onChange:e=>ed("tablet","tablet"===e.target.value),children:[(0,t.jsx)("option",{value:"phone",children:"Phone"}),(0,t.jsx)("option",{value:"tablet",children:"Tablet"})]}),(0,t.jsx)("p",{className:"text-xs text-muted-foreground",children:"The word Mobile is the only difference in the string itself, and dropping it is the most common mistake in hand-written Android strings. In the headers a tablet also sends Sec-CH-UA-Mobile: ?0 and a Tablet form factor, because that header asks for the phone layout and a tablet does not want one."})]}),"android"!==e.platform&&(0,t.jsxs)("div",{className:"space-y-1.5",children:[(0,t.jsx)(d.J,{htmlFor:"ua-arch",children:"Processor"}),(0,t.jsxs)("select",{id:"ua-arch",className:R,value:e.arch,onChange:e=>ed("arch","arm"===e.target.value?"arm":"x86"),children:[(0,t.jsx)("option",{value:"x86",children:"Intel or AMD (x86)"}),(0,t.jsx)("option",{value:"arm",children:"ARM (Apple Silicon, Snapdragon)"})]}),(0,t.jsx)("p",{className:"text-xs text-muted-foreground",children:"This is Sec-CH-UA-Arch, and it had no control at all until now: every header set came out claiming x86. The classic string cannot carry it, so a server that needs to tell an Apple Silicon Mac from an Intel one has only this hint to go on. It starts on whatever your own machine reported, when your browser would say."})]}),"windows"===e.platform&&(0,t.jsxs)("div",{className:"space-y-1.5",children:[(0,t.jsx)(d.J,{htmlFor:"winver",children:"Which Windows"}),(0,t.jsx)("select",{id:"winver",className:R,value:e.windowsHintVersion,onChange:e=>ed("windowsHintVersion",e.target.value),children:y.map(e=>(0,t.jsx)("option",{value:e.value,children:e.label},e.value))}),(0,t.jsx)("p",{className:"text-xs text-muted-foreground",children:"Both send NT 10.0 in the string. Only the platform version hint tells them apart."})]})]}),"android"===e.platform&&"Blink"===S(e)&&(0,t.jsxs)("div",{className:"space-y-3 rounded-lg border p-3",children:[(0,t.jsxs)("label",{className:"flex items-start gap-2 text-sm",children:[(0,t.jsx)("input",{type:"checkbox",className:"mt-0.5",checked:e.reduced,onChange:e=>ed("reduced",e.target.checked)}),(0,t.jsxs)("span",{children:[(0,t.jsx)("span",{className:"font-medium",children:"Use the reduced Android string"}),(0,t.jsx)("span",{className:"block text-xs text-muted-foreground",children:"Current Chromium reports every Android device as version 10 with the model K. The real model does not vanish, it moves to the Sec-CH-UA-Model header below. Untick this for the older shape, which real Chrome no longer sends."})]})]}),(0,t.jsxs)("div",{className:"grid gap-3 sm:grid-cols-2",children:[(0,t.jsxs)("div",{className:"space-y-1.5",children:[(0,t.jsx)(d.J,{htmlFor:"andver",children:"Android version"}),(0,t.jsx)("select",{id:"andver",className:R,value:e.androidVersion,onChange:e=>ed("androidVersion",e.target.value),children:v.map(e=>(0,t.jsxs)("option",{value:e,children:["Android ",e]},e))})]}),(0,t.jsxs)("div",{className:"space-y-1.5",children:[(0,t.jsx)(d.J,{htmlFor:"model",children:"Device model"}),(0,t.jsx)("select",{id:"model",className:R,value:e.androidModel,onChange:e=>ed("androidModel",e.target.value),children:j.map(e=>(0,t.jsx)("option",{value:e,children:e},e))})]})]})]}),(0,t.jsxs)("div",{className:"space-y-2",children:[(0,t.jsxs)("div",{className:"flex flex-wrap items-center justify-between gap-2",children:[(0,t.jsxs)("div",{className:"text-sm font-medium",children:["The request a real ",eN.name," would send"]}),(0,t.jsxs)("div",{className:"flex flex-wrap gap-2",children:[V(e)&&(0,t.jsx)(o.$,{variant:"ghost",size:"sm",onClick:()=>ed("greaseSeed",e.greaseSeed+1),children:"New GREASE"}),(0,t.jsx)(n.i,{value:ep,label:"Copy string",copiedLabel:"Copied!",describe:"the user agent string"}),(0,t.jsx)(n.i,{value:eT,label:"Copy all headers",copiedLabel:"Copied!",describe:"every header"})]})]}),eg&&(0,t.jsx)("p",{className:"rounded-md border border-amber-600/40 bg-amber-500/10 p-3 text-xs leading-relaxed",children:ef}),eu.length>0&&(0,t.jsx)("div",{className:"space-y-2 rounded-md border bg-muted/40 p-3",children:eu.map(e=>(0,t.jsxs)("div",{className:"space-y-1",children:[(0,t.jsxs)("div",{className:"flex flex-wrap items-baseline gap-2",children:[(0,t.jsxs)("span",{className:"font-mono text-xs font-semibold",children:[e.name,":"]}
22),"high"===e.entropy&&(0,t.jsx)(_,{tone:"note",children:"needs Accept-CH"})]}),(0,t.jsx)("p",{className:"break-all font-mono text-xs leading-relaxed",children:e.value}),e.note&&(0,t.jsx)("p",{className:"text-xs text-muted-foreground",children:e.note})]},e.name))}),(0,t.jsxs)("div",{className:"flex flex-wrap items-center gap-2",children:[V(e)?(0,t.jsxs)("label",{className:"flex items-center gap-2 text-sm",children:[(0,t.jsx)("input",{type:"checkbox",checked:e.highEntropy,onChange:e=>ed("highEntropy",e.target.checked)}),"Add the high-entropy hints"]}):(0,t.jsxs)("p",{className:"text-xs text-muted-foreground",children:[eN.name,"ios"===e.platform||"ipados"===e.platform?" on an Apple mobile device":""," sends no Client Hints at all, so a header set with none is the correct one here."]}),"live"===$&&(0,t.jsx)(_,{tone:"live",children:"version seeded live from your browser"}),"partial"===$&&(0,t.jsx)(_,{tone:"warn",children:"your browser refused the detailed read, using the dated table"}),"none"===$&&(0,t.jsx)(_,{tone:"table",children:"Firefox and Safari expose no live values, using the dated table"})]}),e.highEntropy&&eA&&(0,t.jsxs)("div",{className:"space-y-1 rounded-md border p-3",children:[(0,t.jsxs)("div",{className:"flex items-center justify-between gap-2",children:[(0,t.jsx)("span",{className:"text-sm font-medium",children:"Your server has to ask for those"}),(0,t.jsx)(n.i,{value:eA,copiedLabel:"Copied!",describe:"the Accept-CH header"})]}),(0,t.jsx)("p",{className:"break-all font-mono text-xs",children:eA}),(0,t.jsx)("p",{className:"text-xs text-muted-foreground",children:"Send that back as a response header once, and the browser starts including the high-entropy hints on following requests. Without it your server never sees them, however carefully you set them here."})]}),(0,t.jsxs)("p",{className:"text-xs text-muted-foreground",children:["Versions come from ",b,", newest release ","2026-07-02",".",V(e)?` GREASE brand this round is ${eC.brand}.`:""]}),("ios"===e.platform||"ipados"===e.platform)&&"safari"!==e.browser&&(0,t.jsx)("p",{className:"text-xs text-muted-foreground",children:"On iPhone and iPad the browser keeps its real build and patch digits instead of the zeros Chromium uses on every other platform, and no version table can know those. Treat the trailing zeros here as a placeholder, or paste the real number off a device into the version box."}),null!==eM&&eM>60&&(0,t.jsxs)("p",{className:"rounded-md border border-amber-600/40 bg-amber-500/10 p-2 text-xs",children:["The ",eN.name," release this page uses is dated ",eN.released,", ",eM," days ago, and a newer major has almost certainly shipped. On Chrome or Edge this page reads your own browser instead, which stays right. Everywhere else, check the version before you rely on it."]})]}),(0,t.jsxs)("div",{className:"space-y-2",children:[(0,t.jsxs)("div",{className:"flex flex-wrap items-center gap-2",children:[(0,t.jsx)("span",{className:"text-sm font-medium",children:"Read back through a parser"}),eg?(0,t.jsx)(_,{tone:"note",children:"nothing built to check"}):0===e$.length?(0,t.jsx)(_,{tone:"live",children:"consistent"}):(0,t.jsxs)(_,{tone:"warn",children:[e$.length," problem",1===e$.length?"":"s"]})]}),eh&&(0,t.jsxs)("div",{className:"flex flex-wrap gap-x-4 gap-y-1 rounded-md border bg-muted/40 p-3 text-sm",children:[(0,t.jsx)("span",{className:"text-muted-foreground",children:"A server reading this sees"}),(0,t.jsxs)("span",{children:[(0,t.jsx)("span",{className:"text-muted-foreground",children:"browser"})," ",ew.browser," ",ew.version]}),(0,t.jsxs)("span",{children:[(0,t.jsx)("span",{className:"text-muted-foreground",children:"engine"})," ",ew.engine]}),(0,t.jsxs)("span",{children:[(0,t.jsx)("span",{className:"text-muted-foreground",children:"system"})," ",ew.os]}),(0,t.jsxs)("span",{children:[(0,t.jsx)("span",{className:"text-muted-foreground",children:"device"})," ",ew.device]})]}),(0,t.jsx)("ul",{className:"space-y-2 rounded-md border p-3 text-sm",children:ex.map(e=>(0,t.jsxs)("li",{className:"flex gap-2",children:[(0,t.jsx)("span",{className:(0,h.cn)("mt-0.5 shrink-0 font-mono text-xs",e.ok?"text-emerald-600":"text-red-600"),children:e.ok?"PASS":"FAIL"}),(0,t.jsxs)("span",{children:[(0,t.jsxs)("span",{className:"font-medium",children:[e.label,"."]})," ",(0,t.jsx)("span",{className:"text-muted-foreground",children:e.detail})]})]},e.label))}),(0,t.jsxs)("div",{className:"space-y-1.5",children:[(0,t.jsx)(d.J,{htmlFor:"edit-ua",children:"Edit it, or paste one from your own logs"}
22),(0,t.jsx)(c.T,{id:"edit-ua",value:W,spellCheck:!1,placeholder:"Leave empty to check the string built above. Paste a suspicious string here to find out which token gives it away.",onChange:e=>H(e.target.value),className:"min-h-[76px] font-mono text-xs"}),W.trim()&&(0,t.jsx)(o.$,{variant:"ghost",size:"sm",onClick:()=>H(""),children:"Back to the built string"})]})]}),(0,t.jsxs)("div",{className:"space-y-2",children:[(0,t.jsx)("div",{className:"text-sm font-medium",children:"Send it"}),(0,t.jsx)("div",{className:"flex flex-wrap gap-1.5",children:ev.map(e=>(0,t.jsx)(o.$,{variant:e.id===B?"default":"outline",size:"sm",onClick:()=>D(e.id),children:e.title},e.id))}),ej&&(0,t.jsxs)("div",{className:"space-y-2 rounded-md border p-3",children:[(0,t.jsxs)("div",{className:"flex items-center justify-between gap-2",children:[(0,t.jsx)("span",{className:"text-sm font-medium",children:ej.title}),(0,t.jsx)(n.i,{value:ej.code,copiedLabel:"Copied!",describe:ej.title})]}),(0,t.jsx)("pre",{className:"overflow-x-auto rounded bg-muted p-3 text-xs leading-relaxed",children:(0,t.jsx)("code",{children:ej.code})}),(0,t.jsx)("p",{className:"text-xs text-muted-foreground",children:ej.caveat})]})]}),(0,t.jsx)(m.ToolActions,{getParams:eO,title:"Random User Agent Generator",queryIsImpersonal:"the browser, platform, version, device, processor, Windows version, Android version and device model you picked - all of them describe a browser, not you"}),(0,t.jsxs)("div",{className:"space-y-3 rounded-lg border p-3",children:[(0,t.jsx)("div",{className:"text-sm font-medium",children:"Build a rotation pool or a device matrix"}),(0,t.jsxs)("div",{className:"grid gap-3 sm:grid-cols-2",children:[(0,t.jsxs)("div",{className:"space-y-1.5",children:[(0,t.jsx)("span",{className:"text-sm font-medium",children:"Browsers"}),(0,t.jsx)("div",{className:"flex flex-wrap gap-x-3 gap-y-1",children:f.map(e=>(0,t.jsxs)("label",{className:"flex items-center gap-1.5 text-sm",children:[(0,t.jsx)("input",{type:"checkbox",checked:Z.includes(e.id),onChange:()=>eP(Z,e.id,ee)}),e.name]},e.id))})]}),(0,t.jsxs)("div",{className:"space-y-1.5",children:[(0,t.jsx)("span",{className:"text-sm font-medium",children:"Platforms"}),(0,t.jsx)("div",{className:"flex flex-wrap gap-x-3 gap-y-1",children:g.map(e=>(0,t.jsxs)("label",{className:"flex items-center gap-1.5 text-sm",children:[(0,t.jsx)("input",{type:"checkbox",checked:er.includes(e.id),onChange:()=>eP(er,e.id,es)}),e.name]},e.id))})]})]}),(0,t.jsxs)("div",{className:"flex flex-wrap items-end gap-3",children:[(0,t.jsxs)("div",{className:"w-28 space-y-1.5",children:[(0,t.jsx)(d.J,{htmlFor:"count",children:"How many"}),(0,t.jsx)(l.p,{id:"count",value:et,inputMode:"numeric",onChange:e=>ea(e.target.value.replace(/[^\d]/g,"").slice(0,6))})]}),(0,t.jsxs)("label",{className:"flex items-center gap-2 pb-2 text-sm",children:[(0,t.jsx)("input",{type:"checkbox",checked:eo,onChange:e=>en(e.target.checked)}),"No duplicates"]}),(0,t.jsx)(o.$,{className:"mb-0.5",onClick:function(){let r=Number(et);el(function(e,r,s,t,a,o){let n=Math.max(0,Math.trunc(s)),i=function(e,r,s,t){let a=[];for(let o of e)for(let e of r)w(o,e)&&null===T({...s,browser:o,platform:e},t)&&("android"===e?(a.push({...s,browser:o,platform:e,tablet:!1}),a.push({...s,browser:o,platform:e,tablet:!0})):a.push({...s,browser:o,platform:e,tablet:!1}));return a}(e,r,a,o);if(0===i.length){let r=e.map(e=>({b:e,why:T({...a,browser:e,platform:x(e).platforms[0]},o)})).filter(e=>null!==e.why);return{rows:[],requested:n,skipped:n,reason:r.length===e.length&&r.length>0?`Nothing was produced. ${r[0].why}`:"No browser and platform pair in that selection can exist, so nothing was produced."}}let l=Math.min(n,1e3),d=n>1e3,c=t&&l>i.length;c&&(l=i.length);let m=n-l,h="";c&&d?h=`Capped at 1000, and only ${i.length} unique clients exist for these filters, so ${m} of the ${n} you asked for were NOT produced. Widen the browser or platform selection.`:c?h=`Only ${i.length} unique clients exist for these filters, so ${m} of the ${n} you asked for were NOT produced. Widen the browser or platform selection.`:d&&(h=`Capped at 1000. The ${m} rows you asked for beyond that were NOT produced, run it again for another batch.`);let p=[];for(let e=0;e<l;e++){let r=i[e%i.length];if(!r)continue;let s={...r,greaseSeed:a.greaseSeed+e},t=L(s,o),n=t[0];n&&p.push({ua:n.value,headers:t,label:`${x(s.browser).name} on ${g.find(e=>e.id===s.platform)?.name}${"android"===s.platform?s.tablet?" tablet":" phone":""}`})}return{rows:p,requested:n,skipped:n-p.length,reason:h}}(Z,er,Number.isFinite(r)?r:0,eo,{...e,greaseSeed:e.greaseSeed},s))},children:"Generate"})]}),ei&&(0,t.jsxs)("div",{className:"space-y-2",children:[(0,t.jsxs)("p",{className:"text-sm",children:["Wrote ",(0,t.jsx)("span",{className:"font-medium tabular-nums",children:ei.rows.length})," of"," ",(0,t.jsx)("span",{className:"tabular-nums",children:ei.requested})," requested.",ei.reason?` ${ei.reason}`:""]}),ei.rows.length>0&&(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)("div",{className:"max-h-56 overflow-auto rounded-md border",children:(0,t.jsx)("table",{className:"w-full text-xs",children:(0,t.jsx)("tbody",{children:ei.rows.map((e,r)=>(0,t.jsxs)("tr",{className:(0,h.cn)(r%2==1&&"bg-muted/50"),children:[(0,t.jsx)("th",{scope:"row",className:"whitespace-nowrap px-3 py-1.5 text-left font-medium",children:e.label}),(0,t.jsx)("td",{className:"break-all px-3 py-1.5 font-mono",children:e.ua})]},`${e.label}-${r}`))})})}),(0,t.jsxs)("div",{className:"flex flex-wrap gap-2",children:[(0,t.jsx)(o.$,{variant:"outline",size:"sm",onClick:()=>I("user-agents.txt",[`# generated ${Y}`,`# ${ei.rows.length} of ${ei.requested} requested`,...ei.rows.map(e=>e.ua)].join("\n"),"text/plain"),children:"Download TXT"}),(0,t.jsx)(o.$,{variant:"outline",size:"sm",onClick:()=>I("user-agents.json",JSON.stringify({generated:Y,versionTable:b,rowsWritten:ei.rows.length,rowsRequested:ei.requested,clients:ei.rows.map(e=>({client:e.label,headers:Object.fromEntries(e.headers.map(e=>[e.name,e.value]))}))},null,2),"application/json"),children:"Download JSON"}),(0,t.jsx)(o.$,{variant:"outline",size:"sm",onClick:()=>I("user-agents.csv",function(e,r){let s=[...new Set(e.rows.flatMap(e=>e.headers.map(e=>e.name)))];return[`# generated ${r}`,["client",...s].map(e=>(0,u.r)(e)).join(","),...e.rows.map(e=>[e.label,...s.map(r=>e.headers.find(e=>e.name===r)?.value??"")].map(e=>(0,u.r)(e)).join(","))].join("\n")}(ei,Y),"text/csv"),children:"Download CSV"}),(0,t.jsx)(n.i,{value:()=>ei.rows.map(e=>e.ua).join("\n"),label:"Copy all strings",copiedLabel:"Copied!",describe:"every generated string",disabled:0===ei.rows.length})]}),(0,t.jsxs)("p",{className:"text-xs text-muted-foreground",children:["The JSON and CSV carry each row with its matching hint headers, not just the string, because a pool of bare strings is the half-measure that gets a crawler blocked anyway. Cap is ",1e3," rows per run."]})]})]})]}),(0,t.jsxs)("div",{className:"space-y-2",children:[(0,t.jsx)("div",{className:"text-sm font-medium",children:"Crawler strings"}),(0,t.jsx)("div",{className:"overflow-hidden rounded-md border",children:(0,t.jsx)("table",{className:"w-full text-xs",children:(0,t.jsx)("tbody",{children:z.map((e,r)=>{var s;let a=(s=M(),e.template.replace("{C}",s));return(0,t.jsxs)("tr",{className:(0,h.cn)(r%2==1&&"bg-muted/50"),children:[(0,t.jsxs)("th",{scope:"row",className:"whitespace-nowrap px-3 py-2 text-left align-top font-medium",children:[e.name,(0,t.jsx)("span",{className:"block font-normal text-muted-foreground",children:e.docs})]}),(0,t.jsx)("td",{className:"break-all px-3 py-2 align-top font-mono",children:a}),(0,t.jsx)("td",{className:"px-3 py-2 align-top",children:(0,t.jsx)(n.i,{value:a,copiedLabel:"Copied!",describe:`the ${e.name}
22 string`})})]},e.name)})})})}),(0,t.jsx)("p",{className:"text-xs text-muted-foreground",children:"These follow the format each operator publishes at the address next to the name, and the Chrome number inside the Google and Bing strings tracks stable Chrome, independent of the version box above. Operators change these, so treat their own page as the authority. Sending a crawler string does not make you that crawler either, since sites verify the real ones by reverse DNS."})]}),(0,t.jsx)("p",{className:"text-xs text-muted-foreground",children:"Everything here runs in your browser. No string, header or pool you build is sent anywhere, and the page makes no network calls once it has loaded."})]})}}}]);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.