user-agents 2.0.0-alpha.687 → 2.0.0-alpha.689
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.md +43 -3
- package/dist/index.cjs +3 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +8 -3
- package/dist/index.d.ts +6 -3
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/user-agents.json +73802 -72875
- package/package.json +21 -18
- package/src/update-data.ts +11 -3
- package/src/user-agent.ts +57 -30
package/README.md
CHANGED
|
@@ -194,6 +194,30 @@ const userAgent = new UserAgent([
|
|
|
194
194
|
This example also shows that you can specify both multiple and nested properties on object filters.
|
|
195
195
|
|
|
196
196
|
|
|
197
|
+
### Filtering for Modern Browsers
|
|
198
|
+
|
|
199
|
+
If you want to restrict the generated user agents to only modern browsers, you can combine User-Agents with the [browserslist](https://www.npmjs.com/package/browserslist) and [browserslist-useragent](https://www.npmjs.com/package/browserslist-useragent) packages.
|
|
200
|
+
The `browserslist` package lets you define what "modern" means using flexible queries like `"last 2 versions and not dead"`, and `browserslist-useragent` handles matching user agent strings against those queries.
|
|
201
|
+
|
|
202
|
+
```javascript
|
|
203
|
+
import browserslist from 'browserslist';
|
|
204
|
+
import { matchesUA } from 'browserslist-useragent';
|
|
205
|
+
import UserAgent from 'user-agents';
|
|
206
|
+
|
|
207
|
+
const browsers = browserslist('last 2 versions and not dead');
|
|
208
|
+
|
|
209
|
+
function isModernBrowser(data) {
|
|
210
|
+
return matchesUA(data.userAgent, { browsers, allowHigherVersions: true });
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
const userAgent = new UserAgent(isModernBrowser);
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
The `allowHigherVersions` option ensures that browser versions newer than those in the browserslist database are still accepted.
|
|
217
|
+
Keep in mind that the User-Agents data is already updated daily from real-world traffic, so the generated user agents are naturally skewed toward modern browsers even without explicit filtering.
|
|
218
|
+
You can find the full list of supported browserslist queries in the [browserslist documentation](https://github.com/browserslist/browserslist#full-list).
|
|
219
|
+
|
|
220
|
+
|
|
197
221
|
## API
|
|
198
222
|
|
|
199
223
|
### class: UserAgent([filters])
|
|
@@ -272,14 +296,30 @@ Note that each property of `data` is also accessible directly on `userAgent`.
|
|
|
272
296
|
For example, `userAgent.appName` is equivalent to `userAgent.data.appName`.
|
|
273
297
|
|
|
274
298
|
|
|
299
|
+
## Data
|
|
300
|
+
|
|
301
|
+
The dataset is built from a snapshot of the last 24 hours of real-world browser traffic, and a new version of the package is published daily with a fully refreshed dataset.
|
|
302
|
+
This means that the data is not accumulated over time; older browser versions are naturally phased out as they disappear from the traffic, and each release reflects a current view of the browser landscape.
|
|
303
|
+
|
|
304
|
+
User agents are not selected with uniform probability.
|
|
305
|
+
Each profile in the dataset is weighted according to its real-world usage frequency, so commonly seen browsers like Chrome on Windows will appear far more often than niche configurations.
|
|
306
|
+
The result is a random distribution that closely mirrors actual web traffic.
|
|
307
|
+
|
|
308
|
+
|
|
275
309
|
## Versioning
|
|
276
310
|
|
|
277
311
|
The project follows [the Semantic Versioning guidelines](https://semver.org/).
|
|
278
312
|
The automated deployments will always correspond to patch versions, and minor versions should not introduce breaking changes.
|
|
279
|
-
It's likely that the structure of user agent data will change in the future, and this will correspond to a new major version.
|
|
280
313
|
|
|
281
|
-
|
|
282
|
-
|
|
314
|
+
The current `latest` release on npm is v1, which is built with JavaScript and Webpack and outputs a UMD bundle.
|
|
315
|
+
The upcoming v2 release is available under the `next` tag (`npm install user-agents@next`) and includes several improvements:
|
|
316
|
+
|
|
317
|
+
- Rewritten in TypeScript with exported type definitions for `UserAgentData` and `Filter`.
|
|
318
|
+
- Built with tsup, producing native ESM and CJS entry points instead of a UMD bundle.
|
|
319
|
+
- Removed the `Function` class inheritance, which resolves Content Security Policy errors in browser extensions and other restricted environments.
|
|
320
|
+
|
|
321
|
+
The v1 line is deprecated and will stop receiving daily data updates once v2 is promoted to `latest`.
|
|
322
|
+
Both versions receive the same daily data and share an identical API surface, so upgrading should be straightforward.
|
|
283
323
|
|
|
284
324
|
|
|
285
325
|
## Acknowledgements
|
package/dist/index.cjs
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } }var
|
|
1
|
+
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } }var _useragentsjson = require('./user-agents.json'); var _useragentsjson2 = _interopRequireDefault(_useragentsjson);var o=_useragentsjson2.default,p=r=>{let n=r.reduce((e,[s])=>e+s,0),a=0;return r.map(([e,s])=>(a+=e/n,[a,s]))},y=o.map(({weight:r},n)=>[r,n]),b=p(y),l=(r,n=a=>a)=>{let a;return typeof r=="function"?a=[r]:r instanceof RegExp?a=[e=>typeof e=="object"&&e&&"userAgent"in e&&e.userAgent?r.test(e.userAgent):r.test(e)]:r instanceof Array?a=r.map(e=>l(e)):typeof r=="object"?a=Object.entries(r).map(([e,s])=>l(s,t=>t[e])):a=[e=>typeof e=="object"&&e&&"userAgent"in e&&e.userAgent?r===e.userAgent:r===e],e=>{try{let s=n(e);return a.every(t=>t(s))}catch (e2){return!1}}},A=r=>{if(!r)return b;let n=l(r),a=[];return o.forEach((e,s)=>{n(e)&&a.push([e.weight,s])}),p(a)},g=(r,n)=>{Object.defineProperty(r,"cumulativeWeightIndexPairs",{configurable:!0,enumerable:!1,writable:!1,value:n})},d=new WeakSet,m,h,u=class r{constructor(n){this[m]=()=>this.data.userAgent;this.toString=()=>this.data.userAgent;this.random=()=>{let n=new r;return g(n,this.cumulativeWeightIndexPairs),n.randomize(),n};this.top=n=>{let a=this.cumulativeWeightIndexPairs,e=a.map(([t,i],c)=>({weight:c>0?t-a[c-1][0]:t,index:i}));e.sort((t,i)=>i.weight-t.weight);let s=n!=null?Math.min(n,e.length):e.length;return e.slice(0,s).map(({index:t})=>structuredClone(o[t]))};this.randomize=()=>{let n=Math.random(),[,a]=_nullishCoalesce(this.cumulativeWeightIndexPairs.find(([e])=>e>n), () => ([]));if(a==null)throw new Error("Error finding a random user agent.");this.data=structuredClone(o[a])};if(g(this,A(n)),this.cumulativeWeightIndexPairs.length===0)throw new Error("No user agents matched your filters.");this.randomize();let a=()=>{},e=new Proxy(a,{apply:()=>this.random(),get:(s,t)=>{if(this.data&&typeof t=="string"&&Object.prototype.hasOwnProperty.call(this.data,t)&&Object.prototype.propertyIsEnumerable.call(this.data,t)){let i=this.data[t];if(i!==void 0)return i}return Reflect.get(this,t)},set:(s,t,i)=>Reflect.set(this,t,i),defineProperty:(s,t,i)=>Reflect.defineProperty(this,t,i),getOwnPropertyDescriptor:(s,t)=>Reflect.getOwnPropertyDescriptor(this,t),has:(s,t)=>Reflect.has(this,t),deleteProperty:(s,t)=>Reflect.deleteProperty(this,t),ownKeys:()=>Reflect.ownKeys(this),getPrototypeOf:()=>r.prototype});return d.add(e),e}static[(h=Symbol.hasInstance,m=Symbol.toPrimitive,h)](n){return n instanceof Object&&d.has(n)}static{this.random=n=>{try{return new r(n)}catch (e3){return null}}}};var U=u;exports.default = U;
|
|
2
2
|
|
|
3
|
-
module.exports = exports.default
|
|
3
|
+
module.exports = exports.default;
|
|
4
|
+
//# sourceMappingURL=index.cjs.map
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/user-agent.ts","../src/index.ts"],"names":["cloneDeep","untypedUserAgents","userAgents","makeCumulativeWeightIndexPairs","weightIndexPairs","totalWeight","sum","weight","index","defaultWeightIndexPairs","defaultCumulativeWeightIndexPairs","constructFilter","filters","accessor","parentObject","childFilters","value","childFilter","key","valueFilter","constructCumulativeWeightIndexPairsFromFilters","filter","rawUserAgent","setCumulativeWeightIndexPairs","userAgent","cumulativeWeightIndexPairs","_a","UserAgent","_UserAgent","randomNumber","cumulativeWeight","target","property","receiver","src_default"],"mappings":"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","sourcesContent":["import cloneDeep from 'lodash.clonedeep';\n\nimport untypedUserAgents from './user-agents.json' assert { type: 'json' };\n\nconst userAgents: UserAgentData[] = untypedUserAgents as UserAgentData[];\n\ntype NestedValueOf<T> = T extends object ? T[keyof T] | NestedValueOf<T[keyof T]> : T;\n\nexport type Filter<T extends UserAgentData | NestedValueOf<UserAgentData> = UserAgentData> =\n | ((parentObject: T) => boolean)\n | RegExp\n | Array<Filter<T>>\n | { [key: string]: Filter<T> }\n | string;\n\nexport interface UserAgentData {\n appName: 'Netscape';\n connection: {\n downlink: number;\n effectiveType: '3g' | '4g';\n rtt: number;\n downlinkMax?: number | null;\n type?: 'cellular' | 'wifi';\n };\n language?: string | null;\n oscpu?: string | null;\n platform:\n | 'iPad'\n | 'iPhone'\n | 'Linux aarch64'\n | 'Linux armv81'\n | 'Linux armv8l'\n | 'Linux x86_64'\n | 'MacIntel'\n | 'Win32';\n pluginsLength: number;\n screenHeight: number;\n screenWidth: number;\n userAgent: string;\n vendor: 'Apple Computer, Inc.' | 'Google Inc.' | '';\n weight: number;\n}\n\ndeclare module './user-agent' {\n export interface UserAgent extends Readonly<UserAgentData> {\n readonly cumulativeWeightIndexPairs: Array<[number, number]>;\n readonly data: UserAgentData;\n (): UserAgent;\n }\n}\n\n// Normalizes the total weight to 1 and constructs a cumulative distribution.\nconst makeCumulativeWeightIndexPairs = (\n weightIndexPairs: Array<[number, number]>,\n): Array<[number, number]> => {\n const totalWeight = weightIndexPairs.reduce((sum, [weight]) => sum + weight, 0);\n let sum = 0;\n return weightIndexPairs.map(([weight, index]) => {\n sum += weight / totalWeight;\n return [sum, index];\n });\n};\n\n// Precompute these so that we can quickly generate unfiltered user agents.\nconst defaultWeightIndexPairs: Array<[number, number]> = userAgents.map(({ weight }, index) => [\n weight,\n index,\n]);\nconst defaultCumulativeWeightIndexPairs = makeCumulativeWeightIndexPairs(defaultWeightIndexPairs);\n\n// Turn the various filter formats into a single filter function that acts on raw user agents.\nconst constructFilter = <T extends UserAgentData | NestedValueOf<UserAgentData>>(\n filters: Filter<T>,\n accessor: (parentObject: T) => T | NestedValueOf<T> = (parentObject: T): T => parentObject,\n): ((profile: T) => boolean) => {\n // WARNING: This type and a lot of the types in here are wrong, but I can't get TypeScript to\n // resolve things correctly so this will have to do for now.\n let childFilters: Array<(parentObject: T) => boolean>;\n if (typeof filters === 'function') {\n childFilters = [filters];\n } else if (filters instanceof RegExp) {\n childFilters = [\n (value: T | NestedValueOf<T>) =>\n typeof value === 'object' && value && 'userAgent' in value && value.userAgent\n ? filters.test(value.userAgent)\n : filters.test(value as string),\n ];\n } else if (filters instanceof Array) {\n childFilters = filters.map((childFilter) => constructFilter(childFilter));\n } else if (typeof filters === 'object') {\n childFilters = Object.entries(filters).map(([key, valueFilter]) =>\n constructFilter(\n valueFilter as Filter<T>,\n (parentObject: T): T | NestedValueOf<T> =>\n (parentObject as unknown as { [key: string]: NestedValueOf<T> })[key] as NestedValueOf<T>,\n ),\n );\n } else {\n childFilters = [\n (value: T | NestedValueOf<T>) =>\n typeof value === 'object' && value && 'userAgent' in value && value.userAgent\n ? filters === value.userAgent\n : filters === value,\n ];\n }\n\n return (parentObject: T) => {\n try {\n const value = accessor(parentObject);\n return childFilters.every((childFilter) => childFilter(value as T));\n } catch (error) {\n // This happens when a user-agent lacks a nested property.\n return false;\n }\n };\n};\n\n// Construct normalized cumulative weight index pairs given the filters.\nconst constructCumulativeWeightIndexPairsFromFilters = (\n filters?: Filter<UserAgentData>,\n): Array<[number, number]> => {\n if (!filters) {\n return defaultCumulativeWeightIndexPairs;\n }\n\n const filter = constructFilter(filters);\n\n const weightIndexPairs: Array<[number, number]> = [];\n userAgents.forEach((rawUserAgent, index) => {\n if (filter(rawUserAgent)) {\n weightIndexPairs.push([rawUserAgent.weight, index]);\n }\n });\n return makeCumulativeWeightIndexPairs(weightIndexPairs);\n};\n\nconst setCumulativeWeightIndexPairs = (\n userAgent: UserAgent,\n cumulativeWeightIndexPairs: Array<[number, number]>,\n) => {\n Object.defineProperty(userAgent, 'cumulativeWeightIndexPairs', {\n configurable: true,\n enumerable: false,\n writable: false,\n value: cumulativeWeightIndexPairs,\n });\n};\n\nexport class UserAgent extends Function {\n constructor(filters?: Filter) {\n super();\n setCumulativeWeightIndexPairs(this, constructCumulativeWeightIndexPairsFromFilters(filters));\n if (this.cumulativeWeightIndexPairs.length === 0) {\n throw new Error('No user agents matched your filters.');\n }\n\n this.randomize();\n\n // eslint-disable-next-line no-constructor-return\n return new Proxy(this, {\n apply: () => this.random(),\n get: (target, property, receiver) => {\n const dataCandidate =\n target.data &&\n typeof property === 'string' &&\n Object.prototype.hasOwnProperty.call(target.data, property) &&\n Object.prototype.propertyIsEnumerable.call(target.data, property);\n if (dataCandidate) {\n const value = target.data[property as keyof UserAgentData];\n if (value !== undefined) {\n return value;\n }\n }\n\n return Reflect.get(target, property, receiver);\n },\n });\n }\n\n static random = (filters: Filter) => {\n try {\n return new UserAgent(filters);\n } catch (error) {\n return null;\n }\n };\n\n //\n // Standard Object Methods\n //\n\n [Symbol.toPrimitive] = (): string => this.data.userAgent;\n\n toString = (): string => this.data.userAgent;\n\n random = (): UserAgent => {\n const userAgent = new UserAgent();\n setCumulativeWeightIndexPairs(userAgent, this.cumulativeWeightIndexPairs);\n userAgent.randomize();\n return userAgent;\n };\n\n randomize = (): void => {\n // Find a random raw random user agent.\n const randomNumber = Math.random();\n const [, index] =\n this.cumulativeWeightIndexPairs.find(\n ([cumulativeWeight]) => cumulativeWeight > randomNumber,\n ) ?? [];\n if (index == null) {\n throw new Error('Error finding a random user agent.');\n }\n const rawUserAgent = userAgents[index];\n\n (this as { data: UserAgentData }).data = cloneDeep(rawUserAgent);\n };\n}\n","import { Filter, UserAgent, UserAgentData } from './user-agent';\n\nexport default UserAgent;\nexport type { Filter, UserAgentData };\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/user-agent.ts","../src/index.ts"],"names":["userAgents","untypedUserAgents","makeCumulativeWeightIndexPairs","weightIndexPairs","totalWeight","sum","weight","index","defaultWeightIndexPairs","defaultCumulativeWeightIndexPairs","constructFilter","filters","accessor","parentObject","childFilters","value","childFilter","key","valueFilter","constructCumulativeWeightIndexPairsFromFilters","filter","rawUserAgent","setCumulativeWeightIndexPairs","userAgent","cumulativeWeightIndexPairs","userAgentInstances","_a","_b","UserAgent","_UserAgent","count","pairs","entries","cumWeight","i","a","b","n","randomNumber","cumulativeWeight","target","proxy","_target","property","descriptor","instance","index_default"],"mappings":"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","file":"/home/circleci/user-agents/dist/index.cjs","sourcesContent":["import untypedUserAgents from './user-agents.json' with { type: 'json' };\n\nconst userAgents: UserAgentData[] = untypedUserAgents as UserAgentData[];\n\ntype NestedValueOf<T> = T extends object ? T[keyof T] | NestedValueOf<T[keyof T]> : T;\n\nexport type Filter<T extends UserAgentData | NestedValueOf<UserAgentData> = UserAgentData> =\n | ((parentObject: T) => boolean)\n | RegExp\n | Array<Filter<T>>\n | { [key: string]: Filter<T> }\n | string;\n\nexport interface UserAgentData {\n appName: 'Netscape';\n connection: {\n downlink: number;\n effectiveType: '3g' | '4g';\n rtt: number;\n downlinkMax?: number | null;\n type?: 'cellular' | 'wifi';\n };\n language?: string | null;\n oscpu?: string | null;\n platform:\n | 'iPad'\n | 'iPhone'\n | 'Linux aarch64'\n | 'Linux armv81'\n | 'Linux armv8l'\n | 'Linux x86_64'\n | 'MacIntel'\n | 'Win32';\n pluginsLength: number;\n screenHeight: number;\n screenWidth: number;\n userAgent: string;\n vendor: 'Apple Computer, Inc.' | 'Google Inc.' | '';\n weight: number;\n}\n\ndeclare module './user-agent' {\n export interface UserAgent extends Readonly<UserAgentData> {\n readonly cumulativeWeightIndexPairs: Array<[number, number]>;\n readonly data: UserAgentData;\n (): UserAgent;\n }\n}\n\n// Normalizes the total weight to 1 and constructs a cumulative distribution.\nconst makeCumulativeWeightIndexPairs = (\n weightIndexPairs: Array<[number, number]>,\n): Array<[number, number]> => {\n const totalWeight = weightIndexPairs.reduce((sum, [weight]) => sum + weight, 0);\n let sum = 0;\n return weightIndexPairs.map(([weight, index]) => {\n sum += weight / totalWeight;\n return [sum, index];\n });\n};\n\n// Precompute these so that we can quickly generate unfiltered user agents.\nconst defaultWeightIndexPairs: Array<[number, number]> = userAgents.map(({ weight }, index) => [\n weight,\n index,\n]);\nconst defaultCumulativeWeightIndexPairs = makeCumulativeWeightIndexPairs(defaultWeightIndexPairs);\n\n// Turn the various filter formats into a single filter function that acts on raw user agents.\nconst constructFilter = <T extends UserAgentData | NestedValueOf<UserAgentData>>(\n filters: Filter<T>,\n accessor: (parentObject: T) => T | NestedValueOf<T> = (parentObject: T): T => parentObject,\n): ((profile: T) => boolean) => {\n // WARNING: This type and a lot of the types in here are wrong, but I can't get TypeScript to\n // resolve things correctly so this will have to do for now.\n let childFilters: Array<(parentObject: T) => boolean>;\n if (typeof filters === 'function') {\n childFilters = [filters];\n } else if (filters instanceof RegExp) {\n childFilters = [\n (value: T | NestedValueOf<T>) =>\n typeof value === 'object' && value && 'userAgent' in value && value.userAgent\n ? filters.test(value.userAgent)\n : filters.test(value as string),\n ];\n } else if (filters instanceof Array) {\n childFilters = filters.map((childFilter) => constructFilter(childFilter));\n } else if (typeof filters === 'object') {\n childFilters = Object.entries(filters).map(([key, valueFilter]) =>\n constructFilter(\n valueFilter as Filter<T>,\n (parentObject: T): T | NestedValueOf<T> =>\n (parentObject as unknown as { [key: string]: NestedValueOf<T> })[key] as NestedValueOf<T>,\n ),\n );\n } else {\n childFilters = [\n (value: T | NestedValueOf<T>) =>\n typeof value === 'object' && value && 'userAgent' in value && value.userAgent\n ? filters === value.userAgent\n : filters === value,\n ];\n }\n\n return (parentObject: T) => {\n try {\n const value = accessor(parentObject);\n return childFilters.every((childFilter) => childFilter(value as T));\n } catch {\n // This happens when a user-agent lacks a nested property.\n return false;\n }\n };\n};\n\n// Construct normalized cumulative weight index pairs given the filters.\nconst constructCumulativeWeightIndexPairsFromFilters = (\n filters?: Filter<UserAgentData>,\n): Array<[number, number]> => {\n if (!filters) {\n return defaultCumulativeWeightIndexPairs;\n }\n\n const filter = constructFilter(filters);\n\n const weightIndexPairs: Array<[number, number]> = [];\n userAgents.forEach((rawUserAgent, index) => {\n if (filter(rawUserAgent)) {\n weightIndexPairs.push([rawUserAgent.weight, index]);\n }\n });\n return makeCumulativeWeightIndexPairs(weightIndexPairs);\n};\n\nconst setCumulativeWeightIndexPairs = (\n userAgent: UserAgent,\n cumulativeWeightIndexPairs: Array<[number, number]>,\n) => {\n Object.defineProperty(userAgent, 'cumulativeWeightIndexPairs', {\n configurable: true,\n enumerable: false,\n writable: false,\n value: cumulativeWeightIndexPairs,\n });\n};\n\n// WeakSet tracking all UserAgent instances for `instanceof` support through proxies.\nconst userAgentInstances = new WeakSet<object>();\n\nexport class UserAgent {\n static [Symbol.hasInstance](instance: unknown): boolean {\n return instance instanceof Object && userAgentInstances.has(instance as object);\n }\n\n static random = (filters: Filter) => {\n try {\n return new UserAgent(filters);\n } catch {\n return null;\n }\n };\n\n readonly data!: UserAgentData;\n\n constructor(filters?: Filter) {\n setCumulativeWeightIndexPairs(this, constructCumulativeWeightIndexPairsFromFilters(filters));\n if (this.cumulativeWeightIndexPairs.length === 0) {\n throw new Error('No user agents matched your filters.');\n }\n\n this.randomize();\n\n // Use a plain function as the proxy target so the `apply` trap works without\n // extending `Function`, which requires `eval` and violates CSP in browser extensions.\n // All property access is forwarded to the real UserAgent instance via the traps.\n const target = () => {};\n const proxy = new Proxy(target as unknown as this, {\n apply: () => this.random(),\n get: (_target, property) => {\n if (\n this.data &&\n typeof property === 'string' &&\n Object.prototype.hasOwnProperty.call(this.data, property) &&\n Object.prototype.propertyIsEnumerable.call(this.data, property)\n ) {\n const value = this.data[property as keyof UserAgentData];\n if (value !== undefined) {\n return value;\n }\n }\n\n return Reflect.get(this, property);\n },\n set: (_target, property, value) => Reflect.set(this, property, value),\n defineProperty: (_target, property, descriptor) =>\n Reflect.defineProperty(this, property, descriptor),\n getOwnPropertyDescriptor: (_target, property) =>\n Reflect.getOwnPropertyDescriptor(this, property),\n has: (_target, property) => Reflect.has(this, property),\n deleteProperty: (_target, property) => Reflect.deleteProperty(this, property),\n ownKeys: () => Reflect.ownKeys(this),\n getPrototypeOf: () => UserAgent.prototype,\n });\n userAgentInstances.add(proxy);\n return proxy;\n }\n\n [Symbol.toPrimitive] = (): string => this.data.userAgent;\n\n toString = (): string => this.data.userAgent;\n\n random = (): UserAgent => {\n const userAgent = new UserAgent();\n setCumulativeWeightIndexPairs(userAgent, this.cumulativeWeightIndexPairs);\n userAgent.randomize();\n return userAgent;\n };\n\n top = (count?: number): UserAgentData[] => {\n // Recover individual weights from the cumulative distribution and sort by descending weight.\n const pairs = this.cumulativeWeightIndexPairs;\n const entries = pairs.map(([cumWeight, index], i) => ({\n weight: i > 0 ? cumWeight - pairs[i - 1][0] : cumWeight,\n index,\n }));\n entries.sort((a, b) => b.weight - a.weight);\n const n = count != null ? Math.min(count, entries.length) : entries.length;\n return entries.slice(0, n).map(({ index }) => structuredClone(userAgents[index]));\n };\n\n randomize = (): void => {\n // Find a random raw random user agent.\n const randomNumber = Math.random();\n const [, index] =\n this.cumulativeWeightIndexPairs.find(\n ([cumulativeWeight]) => cumulativeWeight > randomNumber,\n ) ?? [];\n if (index == null) {\n throw new Error('Error finding a random user agent.');\n }\n\n (this as { data: UserAgentData }).data = structuredClone(userAgents[index]);\n };\n}\n","import { Filter, UserAgent, UserAgentData } from './user-agent';\n\nexport default UserAgent;\nexport type { Filter, UserAgentData };\n"]}
|
package/dist/index.d.cts
CHANGED
|
@@ -28,13 +28,18 @@ declare module './user-agent' {
|
|
|
28
28
|
(): UserAgent;
|
|
29
29
|
}
|
|
30
30
|
}
|
|
31
|
-
declare class UserAgent
|
|
32
|
-
|
|
31
|
+
declare class UserAgent {
|
|
32
|
+
static [Symbol.hasInstance](instance: unknown): boolean;
|
|
33
33
|
static random: (filters: Filter) => UserAgent | null;
|
|
34
|
+
readonly data: UserAgentData;
|
|
35
|
+
constructor(filters?: Filter);
|
|
34
36
|
[Symbol.toPrimitive]: () => string;
|
|
35
37
|
toString: () => string;
|
|
36
38
|
random: () => UserAgent;
|
|
39
|
+
top: (count?: number) => UserAgentData[];
|
|
37
40
|
randomize: () => void;
|
|
38
41
|
}
|
|
39
42
|
|
|
40
|
-
|
|
43
|
+
// @ts-ignore
|
|
44
|
+
export = UserAgent;
|
|
45
|
+
export type { Filter, UserAgentData };
|
package/dist/index.d.ts
CHANGED
|
@@ -28,13 +28,16 @@ declare module './user-agent' {
|
|
|
28
28
|
(): UserAgent;
|
|
29
29
|
}
|
|
30
30
|
}
|
|
31
|
-
declare class UserAgent
|
|
32
|
-
|
|
31
|
+
declare class UserAgent {
|
|
32
|
+
static [Symbol.hasInstance](instance: unknown): boolean;
|
|
33
33
|
static random: (filters: Filter) => UserAgent | null;
|
|
34
|
+
readonly data: UserAgentData;
|
|
35
|
+
constructor(filters?: Filter);
|
|
34
36
|
[Symbol.toPrimitive]: () => string;
|
|
35
37
|
toString: () => string;
|
|
36
38
|
random: () => UserAgent;
|
|
39
|
+
top: (count?: number) => UserAgentData[];
|
|
37
40
|
randomize: () => void;
|
|
38
41
|
}
|
|
39
42
|
|
|
40
|
-
export { Filter, UserAgentData, UserAgent as default };
|
|
43
|
+
export { type Filter, type UserAgentData, UserAgent as default };
|
package/dist/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import
|
|
1
|
+
import f from"./user-agents.json"with{type:"json"};var o=f,p=r=>{let n=r.reduce((e,[s])=>e+s,0),a=0;return r.map(([e,s])=>(a+=e/n,[a,s]))},y=o.map(({weight:r},n)=>[r,n]),b=p(y),l=(r,n=a=>a)=>{let a;return typeof r=="function"?a=[r]:r instanceof RegExp?a=[e=>typeof e=="object"&&e&&"userAgent"in e&&e.userAgent?r.test(e.userAgent):r.test(e)]:r instanceof Array?a=r.map(e=>l(e)):typeof r=="object"?a=Object.entries(r).map(([e,s])=>l(s,t=>t[e])):a=[e=>typeof e=="object"&&e&&"userAgent"in e&&e.userAgent?r===e.userAgent:r===e],e=>{try{let s=n(e);return a.every(t=>t(s))}catch{return!1}}},A=r=>{if(!r)return b;let n=l(r),a=[];return o.forEach((e,s)=>{n(e)&&a.push([e.weight,s])}),p(a)},g=(r,n)=>{Object.defineProperty(r,"cumulativeWeightIndexPairs",{configurable:!0,enumerable:!1,writable:!1,value:n})},d=new WeakSet,m,h,u=class r{constructor(n){this[m]=()=>this.data.userAgent;this.toString=()=>this.data.userAgent;this.random=()=>{let n=new r;return g(n,this.cumulativeWeightIndexPairs),n.randomize(),n};this.top=n=>{let a=this.cumulativeWeightIndexPairs,e=a.map(([t,i],c)=>({weight:c>0?t-a[c-1][0]:t,index:i}));e.sort((t,i)=>i.weight-t.weight);let s=n!=null?Math.min(n,e.length):e.length;return e.slice(0,s).map(({index:t})=>structuredClone(o[t]))};this.randomize=()=>{let n=Math.random(),[,a]=this.cumulativeWeightIndexPairs.find(([e])=>e>n)??[];if(a==null)throw new Error("Error finding a random user agent.");this.data=structuredClone(o[a])};if(g(this,A(n)),this.cumulativeWeightIndexPairs.length===0)throw new Error("No user agents matched your filters.");this.randomize();let a=()=>{},e=new Proxy(a,{apply:()=>this.random(),get:(s,t)=>{if(this.data&&typeof t=="string"&&Object.prototype.hasOwnProperty.call(this.data,t)&&Object.prototype.propertyIsEnumerable.call(this.data,t)){let i=this.data[t];if(i!==void 0)return i}return Reflect.get(this,t)},set:(s,t,i)=>Reflect.set(this,t,i),defineProperty:(s,t,i)=>Reflect.defineProperty(this,t,i),getOwnPropertyDescriptor:(s,t)=>Reflect.getOwnPropertyDescriptor(this,t),has:(s,t)=>Reflect.has(this,t),deleteProperty:(s,t)=>Reflect.deleteProperty(this,t),ownKeys:()=>Reflect.ownKeys(this),getPrototypeOf:()=>r.prototype});return d.add(e),e}static[(h=Symbol.hasInstance,m=Symbol.toPrimitive,h)](n){return n instanceof Object&&d.has(n)}static{this.random=n=>{try{return new r(n)}catch{return null}}}};var U=u;export{U as default};
|
|
2
2
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/user-agent.ts","../src/index.ts"],"sourcesContent":["import cloneDeep from 'lodash.clonedeep';\n\nimport untypedUserAgents from './user-agents.json' assert { type: 'json' };\n\nconst userAgents: UserAgentData[] = untypedUserAgents as UserAgentData[];\n\ntype NestedValueOf<T> = T extends object ? T[keyof T] | NestedValueOf<T[keyof T]> : T;\n\nexport type Filter<T extends UserAgentData | NestedValueOf<UserAgentData> = UserAgentData> =\n | ((parentObject: T) => boolean)\n | RegExp\n | Array<Filter<T>>\n | { [key: string]: Filter<T> }\n | string;\n\nexport interface UserAgentData {\n appName: 'Netscape';\n connection: {\n downlink: number;\n effectiveType: '3g' | '4g';\n rtt: number;\n downlinkMax?: number | null;\n type?: 'cellular' | 'wifi';\n };\n language?: string | null;\n oscpu?: string | null;\n platform:\n | 'iPad'\n | 'iPhone'\n | 'Linux aarch64'\n | 'Linux armv81'\n | 'Linux armv8l'\n | 'Linux x86_64'\n | 'MacIntel'\n | 'Win32';\n pluginsLength: number;\n screenHeight: number;\n screenWidth: number;\n userAgent: string;\n vendor: 'Apple Computer, Inc.' | 'Google Inc.' | '';\n weight: number;\n}\n\ndeclare module './user-agent' {\n export interface UserAgent extends Readonly<UserAgentData> {\n readonly cumulativeWeightIndexPairs: Array<[number, number]>;\n readonly data: UserAgentData;\n (): UserAgent;\n }\n}\n\n// Normalizes the total weight to 1 and constructs a cumulative distribution.\nconst makeCumulativeWeightIndexPairs = (\n weightIndexPairs: Array<[number, number]>,\n): Array<[number, number]> => {\n const totalWeight = weightIndexPairs.reduce((sum, [weight]) => sum + weight, 0);\n let sum = 0;\n return weightIndexPairs.map(([weight, index]) => {\n sum += weight / totalWeight;\n return [sum, index];\n });\n};\n\n// Precompute these so that we can quickly generate unfiltered user agents.\nconst defaultWeightIndexPairs: Array<[number, number]> = userAgents.map(({ weight }, index) => [\n weight,\n index,\n]);\nconst defaultCumulativeWeightIndexPairs = makeCumulativeWeightIndexPairs(defaultWeightIndexPairs);\n\n// Turn the various filter formats into a single filter function that acts on raw user agents.\nconst constructFilter = <T extends UserAgentData | NestedValueOf<UserAgentData>>(\n filters: Filter<T>,\n accessor: (parentObject: T) => T | NestedValueOf<T> = (parentObject: T): T => parentObject,\n): ((profile: T) => boolean) => {\n // WARNING: This type and a lot of the types in here are wrong, but I can't get TypeScript to\n // resolve things correctly so this will have to do for now.\n let childFilters: Array<(parentObject: T) => boolean>;\n if (typeof filters === 'function') {\n childFilters = [filters];\n } else if (filters instanceof RegExp) {\n childFilters = [\n (value: T | NestedValueOf<T>) =>\n typeof value === 'object' && value && 'userAgent' in value && value.userAgent\n ? filters.test(value.userAgent)\n : filters.test(value as string),\n ];\n } else if (filters instanceof Array) {\n childFilters = filters.map((childFilter) => constructFilter(childFilter));\n } else if (typeof filters === 'object') {\n childFilters = Object.entries(filters).map(([key, valueFilter]) =>\n constructFilter(\n valueFilter as Filter<T>,\n (parentObject: T): T | NestedValueOf<T> =>\n (parentObject as unknown as { [key: string]: NestedValueOf<T> })[key] as NestedValueOf<T>,\n ),\n );\n } else {\n childFilters = [\n (value: T | NestedValueOf<T>) =>\n typeof value === 'object' && value && 'userAgent' in value && value.userAgent\n ? filters === value.userAgent\n : filters === value,\n ];\n }\n\n return (parentObject: T) => {\n try {\n const value = accessor(parentObject);\n return childFilters.every((childFilter) => childFilter(value as T));\n } catch (error) {\n // This happens when a user-agent lacks a nested property.\n return false;\n }\n };\n};\n\n// Construct normalized cumulative weight index pairs given the filters.\nconst constructCumulativeWeightIndexPairsFromFilters = (\n filters?: Filter<UserAgentData>,\n): Array<[number, number]> => {\n if (!filters) {\n return defaultCumulativeWeightIndexPairs;\n }\n\n const filter = constructFilter(filters);\n\n const weightIndexPairs: Array<[number, number]> = [];\n userAgents.forEach((rawUserAgent, index) => {\n if (filter(rawUserAgent)) {\n weightIndexPairs.push([rawUserAgent.weight, index]);\n }\n });\n return makeCumulativeWeightIndexPairs(weightIndexPairs);\n};\n\nconst setCumulativeWeightIndexPairs = (\n userAgent: UserAgent,\n cumulativeWeightIndexPairs: Array<[number, number]>,\n) => {\n Object.defineProperty(userAgent, 'cumulativeWeightIndexPairs', {\n configurable: true,\n enumerable: false,\n writable: false,\n value: cumulativeWeightIndexPairs,\n });\n};\n\nexport class UserAgent extends Function {\n constructor(filters?: Filter) {\n super();\n setCumulativeWeightIndexPairs(this, constructCumulativeWeightIndexPairsFromFilters(filters));\n if (this.cumulativeWeightIndexPairs.length === 0) {\n throw new Error('No user agents matched your filters.');\n }\n\n this.randomize();\n\n // eslint-disable-next-line no-constructor-return\n return new Proxy(this, {\n apply: () => this.random(),\n get: (target, property, receiver) => {\n const dataCandidate =\n target.data &&\n typeof property === 'string' &&\n Object.prototype.hasOwnProperty.call(target.data, property) &&\n Object.prototype.propertyIsEnumerable.call(target.data, property);\n if (dataCandidate) {\n const value = target.data[property as keyof UserAgentData];\n if (value !== undefined) {\n return value;\n }\n }\n\n return Reflect.get(target, property, receiver);\n },\n });\n }\n\n static random = (filters: Filter) => {\n try {\n return new UserAgent(filters);\n } catch (error) {\n return null;\n }\n };\n\n //\n // Standard Object Methods\n //\n\n [Symbol.toPrimitive] = (): string => this.data.userAgent;\n\n toString = (): string => this.data.userAgent;\n\n random = (): UserAgent => {\n const userAgent = new UserAgent();\n setCumulativeWeightIndexPairs(userAgent, this.cumulativeWeightIndexPairs);\n userAgent.randomize();\n return userAgent;\n };\n\n randomize = (): void => {\n // Find a random raw random user agent.\n const randomNumber = Math.random();\n const [, index] =\n this.cumulativeWeightIndexPairs.find(\n ([cumulativeWeight]) => cumulativeWeight > randomNumber,\n ) ?? [];\n if (index == null) {\n throw new Error('Error finding a random user agent.');\n }\n const rawUserAgent = userAgents[index];\n\n (this as { data: UserAgentData }).data = cloneDeep(rawUserAgent);\n };\n}\n","import { Filter, UserAgent, UserAgentData } from './user-agent';\n\nexport default UserAgent;\nexport type { Filter, UserAgentData };\n"],"mappings":"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","names":["cloneDeep","untypedUserAgents","userAgents","makeCumulativeWeightIndexPairs","weightIndexPairs","totalWeight","sum","weight","index","defaultWeightIndexPairs","defaultCumulativeWeightIndexPairs","constructFilter","filters","accessor","parentObject","childFilters","value","childFilter","key","valueFilter","constructCumulativeWeightIndexPairsFromFilters","filter","rawUserAgent","setCumulativeWeightIndexPairs","userAgent","cumulativeWeightIndexPairs","_a","UserAgent","_UserAgent","randomNumber","cumulativeWeight","target","property","receiver","src_default","UserAgent"]}
|
|
1
|
+
{"version":3,"sources":["../src/user-agent.ts","../src/index.ts"],"sourcesContent":["import untypedUserAgents from './user-agents.json' with { type: 'json' };\n\nconst userAgents: UserAgentData[] = untypedUserAgents as UserAgentData[];\n\ntype NestedValueOf<T> = T extends object ? T[keyof T] | NestedValueOf<T[keyof T]> : T;\n\nexport type Filter<T extends UserAgentData | NestedValueOf<UserAgentData> = UserAgentData> =\n | ((parentObject: T) => boolean)\n | RegExp\n | Array<Filter<T>>\n | { [key: string]: Filter<T> }\n | string;\n\nexport interface UserAgentData {\n appName: 'Netscape';\n connection: {\n downlink: number;\n effectiveType: '3g' | '4g';\n rtt: number;\n downlinkMax?: number | null;\n type?: 'cellular' | 'wifi';\n };\n language?: string | null;\n oscpu?: string | null;\n platform:\n | 'iPad'\n | 'iPhone'\n | 'Linux aarch64'\n | 'Linux armv81'\n | 'Linux armv8l'\n | 'Linux x86_64'\n | 'MacIntel'\n | 'Win32';\n pluginsLength: number;\n screenHeight: number;\n screenWidth: number;\n userAgent: string;\n vendor: 'Apple Computer, Inc.' | 'Google Inc.' | '';\n weight: number;\n}\n\ndeclare module './user-agent' {\n export interface UserAgent extends Readonly<UserAgentData> {\n readonly cumulativeWeightIndexPairs: Array<[number, number]>;\n readonly data: UserAgentData;\n (): UserAgent;\n }\n}\n\n// Normalizes the total weight to 1 and constructs a cumulative distribution.\nconst makeCumulativeWeightIndexPairs = (\n weightIndexPairs: Array<[number, number]>,\n): Array<[number, number]> => {\n const totalWeight = weightIndexPairs.reduce((sum, [weight]) => sum + weight, 0);\n let sum = 0;\n return weightIndexPairs.map(([weight, index]) => {\n sum += weight / totalWeight;\n return [sum, index];\n });\n};\n\n// Precompute these so that we can quickly generate unfiltered user agents.\nconst defaultWeightIndexPairs: Array<[number, number]> = userAgents.map(({ weight }, index) => [\n weight,\n index,\n]);\nconst defaultCumulativeWeightIndexPairs = makeCumulativeWeightIndexPairs(defaultWeightIndexPairs);\n\n// Turn the various filter formats into a single filter function that acts on raw user agents.\nconst constructFilter = <T extends UserAgentData | NestedValueOf<UserAgentData>>(\n filters: Filter<T>,\n accessor: (parentObject: T) => T | NestedValueOf<T> = (parentObject: T): T => parentObject,\n): ((profile: T) => boolean) => {\n // WARNING: This type and a lot of the types in here are wrong, but I can't get TypeScript to\n // resolve things correctly so this will have to do for now.\n let childFilters: Array<(parentObject: T) => boolean>;\n if (typeof filters === 'function') {\n childFilters = [filters];\n } else if (filters instanceof RegExp) {\n childFilters = [\n (value: T | NestedValueOf<T>) =>\n typeof value === 'object' && value && 'userAgent' in value && value.userAgent\n ? filters.test(value.userAgent)\n : filters.test(value as string),\n ];\n } else if (filters instanceof Array) {\n childFilters = filters.map((childFilter) => constructFilter(childFilter));\n } else if (typeof filters === 'object') {\n childFilters = Object.entries(filters).map(([key, valueFilter]) =>\n constructFilter(\n valueFilter as Filter<T>,\n (parentObject: T): T | NestedValueOf<T> =>\n (parentObject as unknown as { [key: string]: NestedValueOf<T> })[key] as NestedValueOf<T>,\n ),\n );\n } else {\n childFilters = [\n (value: T | NestedValueOf<T>) =>\n typeof value === 'object' && value && 'userAgent' in value && value.userAgent\n ? filters === value.userAgent\n : filters === value,\n ];\n }\n\n return (parentObject: T) => {\n try {\n const value = accessor(parentObject);\n return childFilters.every((childFilter) => childFilter(value as T));\n } catch {\n // This happens when a user-agent lacks a nested property.\n return false;\n }\n };\n};\n\n// Construct normalized cumulative weight index pairs given the filters.\nconst constructCumulativeWeightIndexPairsFromFilters = (\n filters?: Filter<UserAgentData>,\n): Array<[number, number]> => {\n if (!filters) {\n return defaultCumulativeWeightIndexPairs;\n }\n\n const filter = constructFilter(filters);\n\n const weightIndexPairs: Array<[number, number]> = [];\n userAgents.forEach((rawUserAgent, index) => {\n if (filter(rawUserAgent)) {\n weightIndexPairs.push([rawUserAgent.weight, index]);\n }\n });\n return makeCumulativeWeightIndexPairs(weightIndexPairs);\n};\n\nconst setCumulativeWeightIndexPairs = (\n userAgent: UserAgent,\n cumulativeWeightIndexPairs: Array<[number, number]>,\n) => {\n Object.defineProperty(userAgent, 'cumulativeWeightIndexPairs', {\n configurable: true,\n enumerable: false,\n writable: false,\n value: cumulativeWeightIndexPairs,\n });\n};\n\n// WeakSet tracking all UserAgent instances for `instanceof` support through proxies.\nconst userAgentInstances = new WeakSet<object>();\n\nexport class UserAgent {\n static [Symbol.hasInstance](instance: unknown): boolean {\n return instance instanceof Object && userAgentInstances.has(instance as object);\n }\n\n static random = (filters: Filter) => {\n try {\n return new UserAgent(filters);\n } catch {\n return null;\n }\n };\n\n readonly data!: UserAgentData;\n\n constructor(filters?: Filter) {\n setCumulativeWeightIndexPairs(this, constructCumulativeWeightIndexPairsFromFilters(filters));\n if (this.cumulativeWeightIndexPairs.length === 0) {\n throw new Error('No user agents matched your filters.');\n }\n\n this.randomize();\n\n // Use a plain function as the proxy target so the `apply` trap works without\n // extending `Function`, which requires `eval` and violates CSP in browser extensions.\n // All property access is forwarded to the real UserAgent instance via the traps.\n const target = () => {};\n const proxy = new Proxy(target as unknown as this, {\n apply: () => this.random(),\n get: (_target, property) => {\n if (\n this.data &&\n typeof property === 'string' &&\n Object.prototype.hasOwnProperty.call(this.data, property) &&\n Object.prototype.propertyIsEnumerable.call(this.data, property)\n ) {\n const value = this.data[property as keyof UserAgentData];\n if (value !== undefined) {\n return value;\n }\n }\n\n return Reflect.get(this, property);\n },\n set: (_target, property, value) => Reflect.set(this, property, value),\n defineProperty: (_target, property, descriptor) =>\n Reflect.defineProperty(this, property, descriptor),\n getOwnPropertyDescriptor: (_target, property) =>\n Reflect.getOwnPropertyDescriptor(this, property),\n has: (_target, property) => Reflect.has(this, property),\n deleteProperty: (_target, property) => Reflect.deleteProperty(this, property),\n ownKeys: () => Reflect.ownKeys(this),\n getPrototypeOf: () => UserAgent.prototype,\n });\n userAgentInstances.add(proxy);\n return proxy;\n }\n\n [Symbol.toPrimitive] = (): string => this.data.userAgent;\n\n toString = (): string => this.data.userAgent;\n\n random = (): UserAgent => {\n const userAgent = new UserAgent();\n setCumulativeWeightIndexPairs(userAgent, this.cumulativeWeightIndexPairs);\n userAgent.randomize();\n return userAgent;\n };\n\n top = (count?: number): UserAgentData[] => {\n // Recover individual weights from the cumulative distribution and sort by descending weight.\n const pairs = this.cumulativeWeightIndexPairs;\n const entries = pairs.map(([cumWeight, index], i) => ({\n weight: i > 0 ? cumWeight - pairs[i - 1][0] : cumWeight,\n index,\n }));\n entries.sort((a, b) => b.weight - a.weight);\n const n = count != null ? Math.min(count, entries.length) : entries.length;\n return entries.slice(0, n).map(({ index }) => structuredClone(userAgents[index]));\n };\n\n randomize = (): void => {\n // Find a random raw random user agent.\n const randomNumber = Math.random();\n const [, index] =\n this.cumulativeWeightIndexPairs.find(\n ([cumulativeWeight]) => cumulativeWeight > randomNumber,\n ) ?? [];\n if (index == null) {\n throw new Error('Error finding a random user agent.');\n }\n\n (this as { data: UserAgentData }).data = structuredClone(userAgents[index]);\n };\n}\n","import { Filter, UserAgent, UserAgentData } from './user-agent';\n\nexport default UserAgent;\nexport type { Filter, UserAgentData };\n"],"mappings":"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","names":["untypedUserAgents","userAgents","makeCumulativeWeightIndexPairs","weightIndexPairs","totalWeight","sum","weight","index","defaultWeightIndexPairs","defaultCumulativeWeightIndexPairs","constructFilter","filters","accessor","parentObject","childFilters","value","childFilter","key","valueFilter","constructCumulativeWeightIndexPairsFromFilters","filter","rawUserAgent","setCumulativeWeightIndexPairs","userAgent","cumulativeWeightIndexPairs","userAgentInstances","_a","_b","UserAgent","_UserAgent","count","pairs","entries","cumWeight","i","a","b","n","randomNumber","cumulativeWeight","target","proxy","_target","property","descriptor","instance","index_default","UserAgent"]}
|