jumpy-lion 0.1.6-beta.26 → 0.1.6-beta.28

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.
@@ -67,6 +67,42 @@ export interface FingerprintConfigJson {
67
67
  * in generateFingerprintConfig(); 0/undefined = "fall through to driver".
68
68
  */
69
69
  maxTextureSize?: number;
70
+ /**
71
+ * GL_MAX_VIEWPORT_DIMS override (returned as [w, w]). Mac M1 / modern
72
+ * discrete = 16384; Intel HD = 16384 too on modern; older Intel = 8192.
73
+ */
74
+ maxViewportDim?: number;
75
+ /**
76
+ * Per-platform GL extension allowlist returned by gl.getSupportedExtensions().
77
+ * When empty/undefined, the C++ emulation provider falls back to a
78
+ * Mac-realistic 9-token default. Populating this with the family-specific
79
+ * extension set closes the SwiftShader-vs-spoofed-GPU gap (CreepJS hashes
80
+ * the extensions list).
81
+ */
82
+ extensions?: string[];
83
+ /**
84
+ * GPU family hint consumed by the C++ EmulatedConfig in M2+ to select
85
+ * per-family Tier-2 rendering quirks (glsl_probe_classifier.cc) and
86
+ * per-family Tier-1 baseline tables (baseline_data.cc). Today (M1) it
87
+ * gets written but the C++ side ignores it until M2 lands the parser.
88
+ */
89
+ familyHint?: 'apple_metal' | 'linux_mesa_amd' | 'linux_mesa_nvidia' | 'linux_mesa_intel' | 'windows_d3d_nvidia' | 'windows_d3d_amd' | 'windows_d3d_intel';
90
+ /** GL_MAX_DRAW_BUFFERS override. Mac M1 = 8; Intel HD 4000-series = 4. */
91
+ maxDrawBuffers?: number;
92
+ /** GL_MAX_SAMPLES override. Mac M1 = 4; modern discrete NVIDIA/AMD = 8 or 16; SwiftShader = 4. */
93
+ maxSamples?: number;
94
+ /** GL_MAX_3D_TEXTURE_SIZE override. Mac M1 / modern discrete = 16384; Intel HD = 2048. */
95
+ max3dTextureSize?: number;
96
+ /** GL_MAX_ARRAY_TEXTURE_LAYERS override. Mac M1 = 2048; Intel HD = 512. */
97
+ maxArrayTextureLayers?: number;
98
+ /** GL_SUBPIXEL_BITS override. Mac Metal = 4; D3D11 = 4; some Mesa = 8. */
99
+ subpixelBits?: number;
100
+ /** GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS override. Mac M1 = 64; varies. */
101
+ maxTransformFeedbackInterleavedComponents?: number;
102
+ /** GL_ALIASED_LINE_WIDTH_RANGE [min, max]. Mac M1 = [1,1]; NVIDIA D3D = [1, 7.375]; Mesa = [1, 16]. */
103
+ aliasedLineWidthRange?: [number, number];
104
+ /** GL_ALIASED_POINT_SIZE_RANGE [min, max]. Mac M1 = [1, 511]; varies. */
105
+ aliasedPointSizeRange?: [number, number];
70
106
  };
71
107
  screen: {
72
108
  width: number;
@@ -117,6 +153,28 @@ export interface FingerprintConfigJson {
117
153
  audio?: {
118
154
  sampleRate: number;
119
155
  };
156
+ /**
157
+ * Canvas / fonts platform hints (M6). Consumed by the C++ FingerprintConfig
158
+ * parser to drive:
159
+ * - the Cromite fonts allowlist consumer (font enumeration via
160
+ * `document.fonts`, measureText, FontFaceSet) when `fonts` is set
161
+ * - Skia text rendering mode (canvas2D + page text rasterisation)
162
+ * when `textRenderingMode` is set
163
+ * Both fields are optional — the C++ parser derives a sensible per-family
164
+ * default from `webgl.familyHint` when they're absent so the operator
165
+ * doesn't have to repeat the platform allowlist for every session.
166
+ */
167
+ canvas?: {
168
+ /** Font family names to advertise. Defaults to a per-family list. */
169
+ fonts?: string[];
170
+ /**
171
+ * Skia text rendering mode hint. Recognised values:
172
+ * "subpixel_aa_no_hinting" — Mac CoreText
173
+ * "lcd_subpixel_full_hinting" — Windows DirectWrite / ClearType
174
+ * "rgb_subpixel_slight_hinting" — Linux FreeType + fontconfig
175
+ */
176
+ textRenderingMode?: 'subpixel_aa_no_hinting' | 'lcd_subpixel_full_hinting' | 'rgb_subpixel_slight_hinting';
177
+ };
120
178
  /**
121
179
  * Spoofed coordinates for navigator.geolocation.getCurrentPosition() /
122
180
  * watchPosition(). The C++ patch replaces the position struct AFTER the
@@ -145,6 +203,48 @@ export interface FingerprintConfigJson {
145
203
  speed?: number;
146
204
  };
147
205
  }
206
+ type GpuFamilyHint = 'apple_metal' | 'linux_mesa_amd' | 'linux_mesa_nvidia' | 'linux_mesa_intel' | 'windows_d3d_nvidia' | 'windows_d3d_amd' | 'windows_d3d_intel';
207
+ interface WebglFamilyProfile {
208
+ maxTextureSize: number;
209
+ maxViewportDim: number;
210
+ maxDrawBuffers: number;
211
+ maxSamples: number;
212
+ max3dTextureSize: number;
213
+ maxArrayTextureLayers: number;
214
+ subpixelBits: number;
215
+ maxTransformFeedbackInterleavedComponents: number;
216
+ aliasedLineWidthRange: [number, number];
217
+ aliasedPointSizeRange: [number, number];
218
+ /**
219
+ * Per-family extension allowlist. The list IS the value gl.getSupportedExtensions()
220
+ * returns. Includes WEBGL_debug_renderer_info gated by Chromium itself, plus
221
+ * the GL_OES_packed_depth_stencil token the C++ factory requires for context
222
+ * creation (will also be force-injected by EmulatedGLES2Interface ctor if missing).
223
+ */
224
+ extensions: string[];
225
+ }
226
+ /**
227
+ * Classify the renderer string emitted by fingerprint-generator into one of the
228
+ * seven GPU families known to the C++ EmulatedConfig. Returns undefined when
229
+ * the renderer doesn't match a known family (e.g. SwiftShader / llvmpipe ANGLE
230
+ * fallback) — the caller should not write a familyHint in that case so the
231
+ * binary falls through to its current Mac-realistic defaults.
232
+ *
233
+ * The match order matters: more specific patterns (D3D11 vs OpenGL ES) must
234
+ * come before broader ones (vendor-only) so e.g. "ANGLE (NVIDIA, ... Direct3D11"
235
+ * is classified as windows_d3d_nvidia rather than linux_mesa_nvidia.
236
+ */
237
+ export declare function classifyWebglRenderer(renderer: string): GpuFamilyHint | undefined;
238
+ /**
239
+ * Resolve the WebglFamilyProfile to use for a given renderer string. Falls
240
+ * back to the apple_metal profile (the current binary's hardcoded default)
241
+ * when the renderer is unrecognised, so the JSON config stays consistent
242
+ * with whatever the C++ EmulatedConfig defaults to before M2 lands.
243
+ */
244
+ export declare function deriveWebglFamilyProfile(renderer: string): {
245
+ family: GpuFamilyHint | undefined;
246
+ profile: WebglFamilyProfile;
247
+ };
148
248
  /**
149
249
  * Generate a FingerprintConfig JSON object from fingerprint-generator output.
150
250
  *
@@ -165,4 +265,5 @@ export declare function writeTempFingerprintConfig(config: FingerprintConfigJson
165
265
  * Delete the temp config file after the browser has exited.
166
266
  */
167
267
  export declare function cleanupTempFingerprintConfig(filePath: string): Promise<void>;
268
+ export {};
168
269
  //# sourceMappingURL=anti-detect-config.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"anti-detect-config.d.ts","sourceRoot":"","sources":["../../src/browser-process/anti-detect-config.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"anti-detect-config.d.ts","sourceRoot":"","sources":["../../src/browser-process/anti-detect-config.ts"],"names":[],"mappings":"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"}
@@ -57,6 +57,390 @@ function deriveNetwork(seed) {
57
57
  function deriveAudioSampleRate(platform) {
58
58
  return platform.startsWith('Mac') ? 44100 : 48000;
59
59
  }
60
+ const PLATFORM_GPU_TABLE = {
61
+ // Apple Silicon (M1/M2/M3/M4) via ANGLE Metal backend. Verified against
62
+ // 2026-05 harvest on real M3 Pro running Chromium 147.
63
+ apple_metal: {
64
+ maxTextureSize: 16384,
65
+ maxViewportDim: 16384,
66
+ maxDrawBuffers: 8,
67
+ maxSamples: 4,
68
+ max3dTextureSize: 16384,
69
+ maxArrayTextureLayers: 2048,
70
+ subpixelBits: 4,
71
+ maxTransformFeedbackInterleavedComponents: 64,
72
+ aliasedLineWidthRange: [1, 1],
73
+ aliasedPointSizeRange: [1, 511],
74
+ extensions: [
75
+ 'GL_OES_packed_depth_stencil',
76
+ 'GL_OES_texture_float',
77
+ 'GL_OES_texture_float_linear',
78
+ 'GL_OES_texture_half_float',
79
+ 'GL_OES_texture_half_float_linear',
80
+ 'GL_OES_element_index_uint',
81
+ 'GL_OES_vertex_array_object',
82
+ 'GL_OES_standard_derivatives',
83
+ 'GL_OES_fbo_render_mipmap',
84
+ 'GL_EXT_blend_minmax',
85
+ 'GL_EXT_color_buffer_half_float',
86
+ 'GL_EXT_disjoint_timer_query',
87
+ 'GL_EXT_float_blend',
88
+ 'GL_EXT_frag_depth',
89
+ 'GL_EXT_shader_texture_lod',
90
+ 'GL_EXT_sRGB',
91
+ 'GL_EXT_texture_filter_anisotropic',
92
+ 'GL_KHR_parallel_shader_compile',
93
+ 'GL_WEBGL_compressed_texture_astc',
94
+ 'GL_WEBGL_compressed_texture_etc',
95
+ 'GL_WEBGL_compressed_texture_etc1',
96
+ 'GL_WEBGL_color_buffer_float',
97
+ 'GL_WEBGL_debug_renderer_info',
98
+ 'GL_WEBGL_debug_shaders',
99
+ 'GL_WEBGL_depth_texture',
100
+ 'GL_WEBGL_draw_buffers',
101
+ 'GL_WEBGL_lose_context',
102
+ 'GL_WEBGL_multi_draw',
103
+ ],
104
+ },
105
+ // Linux + Mesa AMD radeonsi (radeon Vega/RDNA on a recent kernel + Mesa).
106
+ // Calibration: ANGLE OpenGL backend reports the underlying GLES strings.
107
+ linux_mesa_amd: {
108
+ maxTextureSize: 16384,
109
+ maxViewportDim: 16384,
110
+ maxDrawBuffers: 8,
111
+ maxSamples: 8,
112
+ max3dTextureSize: 16384,
113
+ maxArrayTextureLayers: 2048,
114
+ subpixelBits: 8, // Mesa typically advertises 8-bit subpixel precision
115
+ maxTransformFeedbackInterleavedComponents: 128,
116
+ aliasedLineWidthRange: [1, 16],
117
+ aliasedPointSizeRange: [1, 2047],
118
+ extensions: [
119
+ 'GL_OES_packed_depth_stencil',
120
+ 'GL_OES_texture_float',
121
+ 'GL_OES_texture_float_linear',
122
+ 'GL_OES_texture_half_float',
123
+ 'GL_OES_texture_half_float_linear',
124
+ 'GL_OES_element_index_uint',
125
+ 'GL_OES_vertex_array_object',
126
+ 'GL_OES_standard_derivatives',
127
+ 'GL_OES_fbo_render_mipmap',
128
+ 'GL_EXT_blend_minmax',
129
+ 'GL_EXT_color_buffer_float',
130
+ 'GL_EXT_color_buffer_half_float',
131
+ 'GL_EXT_disjoint_timer_query',
132
+ 'GL_EXT_float_blend',
133
+ 'GL_EXT_frag_depth',
134
+ 'GL_EXT_shader_texture_lod',
135
+ 'GL_EXT_sRGB',
136
+ 'GL_EXT_texture_compression_bptc',
137
+ 'GL_EXT_texture_compression_rgtc',
138
+ 'GL_EXT_texture_filter_anisotropic',
139
+ 'GL_KHR_parallel_shader_compile',
140
+ 'GL_WEBGL_color_buffer_float',
141
+ 'GL_WEBGL_compressed_texture_s3tc',
142
+ 'GL_WEBGL_compressed_texture_s3tc_srgb',
143
+ 'GL_WEBGL_debug_renderer_info',
144
+ 'GL_WEBGL_debug_shaders',
145
+ 'GL_WEBGL_depth_texture',
146
+ 'GL_WEBGL_draw_buffers',
147
+ 'GL_WEBGL_lose_context',
148
+ 'GL_WEBGL_multi_draw',
149
+ ],
150
+ },
151
+ // Linux + Mesa NVIDIA (open-source nouveau driver). Less common than the
152
+ // proprietary driver but a real population (Debian default w/o nonfree).
153
+ linux_mesa_nvidia: {
154
+ maxTextureSize: 16384,
155
+ maxViewportDim: 16384,
156
+ maxDrawBuffers: 8,
157
+ maxSamples: 8,
158
+ max3dTextureSize: 16384,
159
+ maxArrayTextureLayers: 2048,
160
+ subpixelBits: 8,
161
+ maxTransformFeedbackInterleavedComponents: 128,
162
+ aliasedLineWidthRange: [1, 10.4375],
163
+ aliasedPointSizeRange: [1, 63.375],
164
+ extensions: [
165
+ 'GL_OES_packed_depth_stencil',
166
+ 'GL_OES_texture_float',
167
+ 'GL_OES_texture_float_linear',
168
+ 'GL_OES_texture_half_float',
169
+ 'GL_OES_texture_half_float_linear',
170
+ 'GL_OES_element_index_uint',
171
+ 'GL_OES_vertex_array_object',
172
+ 'GL_OES_standard_derivatives',
173
+ 'GL_OES_fbo_render_mipmap',
174
+ 'GL_EXT_blend_minmax',
175
+ 'GL_EXT_color_buffer_float',
176
+ 'GL_EXT_color_buffer_half_float',
177
+ 'GL_EXT_disjoint_timer_query',
178
+ 'GL_EXT_float_blend',
179
+ 'GL_EXT_frag_depth',
180
+ 'GL_EXT_shader_texture_lod',
181
+ 'GL_EXT_sRGB',
182
+ 'GL_EXT_texture_compression_bptc',
183
+ 'GL_EXT_texture_compression_rgtc',
184
+ 'GL_EXT_texture_filter_anisotropic',
185
+ 'GL_KHR_parallel_shader_compile',
186
+ 'GL_WEBGL_color_buffer_float',
187
+ 'GL_WEBGL_compressed_texture_s3tc',
188
+ 'GL_WEBGL_compressed_texture_s3tc_srgb',
189
+ 'GL_WEBGL_debug_renderer_info',
190
+ 'GL_WEBGL_debug_shaders',
191
+ 'GL_WEBGL_depth_texture',
192
+ 'GL_WEBGL_draw_buffers',
193
+ 'GL_WEBGL_lose_context',
194
+ 'GL_WEBGL_multi_draw',
195
+ ],
196
+ },
197
+ // Linux + Mesa Intel (most common Linux laptop config — UHD/Iris/Iris Xe).
198
+ linux_mesa_intel: {
199
+ maxTextureSize: 16384,
200
+ maxViewportDim: 16384,
201
+ maxDrawBuffers: 8,
202
+ maxSamples: 8, // Intel UHD typically 8; older HD 4000 family = 4
203
+ max3dTextureSize: 2048, // Intel HD class iGPU is limited here vs discrete
204
+ maxArrayTextureLayers: 2048,
205
+ subpixelBits: 8,
206
+ maxTransformFeedbackInterleavedComponents: 128,
207
+ aliasedLineWidthRange: [1, 7.375],
208
+ aliasedPointSizeRange: [1, 255],
209
+ extensions: [
210
+ 'GL_OES_packed_depth_stencil',
211
+ 'GL_OES_texture_float',
212
+ 'GL_OES_texture_float_linear',
213
+ 'GL_OES_texture_half_float',
214
+ 'GL_OES_texture_half_float_linear',
215
+ 'GL_OES_element_index_uint',
216
+ 'GL_OES_vertex_array_object',
217
+ 'GL_OES_standard_derivatives',
218
+ 'GL_OES_fbo_render_mipmap',
219
+ 'GL_EXT_blend_minmax',
220
+ 'GL_EXT_color_buffer_float',
221
+ 'GL_EXT_color_buffer_half_float',
222
+ 'GL_EXT_disjoint_timer_query',
223
+ 'GL_EXT_float_blend',
224
+ 'GL_EXT_frag_depth',
225
+ 'GL_EXT_shader_texture_lod',
226
+ 'GL_EXT_sRGB',
227
+ 'GL_EXT_texture_compression_bptc',
228
+ 'GL_EXT_texture_compression_rgtc',
229
+ 'GL_EXT_texture_filter_anisotropic',
230
+ 'GL_KHR_parallel_shader_compile',
231
+ 'GL_WEBGL_color_buffer_float',
232
+ 'GL_WEBGL_compressed_texture_s3tc',
233
+ 'GL_WEBGL_compressed_texture_s3tc_srgb',
234
+ 'GL_WEBGL_debug_renderer_info',
235
+ 'GL_WEBGL_debug_shaders',
236
+ 'GL_WEBGL_depth_texture',
237
+ 'GL_WEBGL_draw_buffers',
238
+ 'GL_WEBGL_lose_context',
239
+ 'GL_WEBGL_multi_draw',
240
+ ],
241
+ },
242
+ // Windows + D3D11 NVIDIA — calibrated against a real GeForce RTX session.
243
+ // Notable D3D quirks: ALIASED_LINE_WIDTH_RANGE = [1, 7.375], MAX_SAMPLES = 8.
244
+ windows_d3d_nvidia: {
245
+ maxTextureSize: 16384,
246
+ maxViewportDim: 16384,
247
+ maxDrawBuffers: 8,
248
+ maxSamples: 8,
249
+ max3dTextureSize: 2048,
250
+ maxArrayTextureLayers: 2048,
251
+ subpixelBits: 4,
252
+ maxTransformFeedbackInterleavedComponents: 128,
253
+ aliasedLineWidthRange: [1, 7.375],
254
+ aliasedPointSizeRange: [1, 1023],
255
+ extensions: [
256
+ 'GL_OES_packed_depth_stencil',
257
+ 'GL_OES_texture_float',
258
+ 'GL_OES_texture_float_linear',
259
+ 'GL_OES_texture_half_float',
260
+ 'GL_OES_texture_half_float_linear',
261
+ 'GL_OES_element_index_uint',
262
+ 'GL_OES_vertex_array_object',
263
+ 'GL_OES_standard_derivatives',
264
+ 'GL_OES_fbo_render_mipmap',
265
+ 'GL_EXT_blend_minmax',
266
+ 'GL_EXT_color_buffer_float',
267
+ 'GL_EXT_color_buffer_half_float',
268
+ 'GL_EXT_disjoint_timer_query',
269
+ 'GL_EXT_float_blend',
270
+ 'GL_EXT_frag_depth',
271
+ 'GL_EXT_shader_texture_lod',
272
+ 'GL_EXT_sRGB',
273
+ 'GL_EXT_texture_compression_bptc',
274
+ 'GL_EXT_texture_compression_rgtc',
275
+ 'GL_EXT_texture_filter_anisotropic',
276
+ 'GL_KHR_parallel_shader_compile',
277
+ 'GL_WEBGL_color_buffer_float',
278
+ 'GL_WEBGL_compressed_texture_s3tc',
279
+ 'GL_WEBGL_compressed_texture_s3tc_srgb',
280
+ 'GL_WEBGL_debug_renderer_info',
281
+ 'GL_WEBGL_debug_shaders',
282
+ 'GL_WEBGL_depth_texture',
283
+ 'GL_WEBGL_draw_buffers',
284
+ 'GL_WEBGL_lose_context',
285
+ 'GL_WEBGL_multi_draw',
286
+ ],
287
+ },
288
+ // Windows + D3D11 AMD Radeon — calibrated against a real Radeon RX session.
289
+ windows_d3d_amd: {
290
+ maxTextureSize: 16384,
291
+ maxViewportDim: 16384,
292
+ maxDrawBuffers: 8,
293
+ maxSamples: 8,
294
+ max3dTextureSize: 2048,
295
+ maxArrayTextureLayers: 2048,
296
+ subpixelBits: 4,
297
+ maxTransformFeedbackInterleavedComponents: 128,
298
+ aliasedLineWidthRange: [1, 7.375],
299
+ aliasedPointSizeRange: [1, 1023],
300
+ extensions: [
301
+ 'GL_OES_packed_depth_stencil',
302
+ 'GL_OES_texture_float',
303
+ 'GL_OES_texture_float_linear',
304
+ 'GL_OES_texture_half_float',
305
+ 'GL_OES_texture_half_float_linear',
306
+ 'GL_OES_element_index_uint',
307
+ 'GL_OES_vertex_array_object',
308
+ 'GL_OES_standard_derivatives',
309
+ 'GL_OES_fbo_render_mipmap',
310
+ 'GL_EXT_blend_minmax',
311
+ 'GL_EXT_color_buffer_float',
312
+ 'GL_EXT_color_buffer_half_float',
313
+ 'GL_EXT_disjoint_timer_query',
314
+ 'GL_EXT_float_blend',
315
+ 'GL_EXT_frag_depth',
316
+ 'GL_EXT_shader_texture_lod',
317
+ 'GL_EXT_sRGB',
318
+ 'GL_EXT_texture_compression_bptc',
319
+ 'GL_EXT_texture_compression_rgtc',
320
+ 'GL_EXT_texture_filter_anisotropic',
321
+ 'GL_KHR_parallel_shader_compile',
322
+ 'GL_WEBGL_color_buffer_float',
323
+ 'GL_WEBGL_compressed_texture_s3tc',
324
+ 'GL_WEBGL_compressed_texture_s3tc_srgb',
325
+ 'GL_WEBGL_debug_renderer_info',
326
+ 'GL_WEBGL_debug_shaders',
327
+ 'GL_WEBGL_depth_texture',
328
+ 'GL_WEBGL_draw_buffers',
329
+ 'GL_WEBGL_lose_context',
330
+ 'GL_WEBGL_multi_draw',
331
+ ],
332
+ },
333
+ // Windows + D3D11 Intel — UHD 620/630/770 + Iris Xe. Notably lower
334
+ // max3dTextureSize on older HD class. Iris Xe in practice matches modern
335
+ // limits; we use the conservative iGPU values here.
336
+ windows_d3d_intel: {
337
+ maxTextureSize: 16384,
338
+ maxViewportDim: 16384,
339
+ maxDrawBuffers: 8,
340
+ maxSamples: 8,
341
+ max3dTextureSize: 2048,
342
+ maxArrayTextureLayers: 2048,
343
+ subpixelBits: 4,
344
+ maxTransformFeedbackInterleavedComponents: 64,
345
+ aliasedLineWidthRange: [1, 7.375],
346
+ aliasedPointSizeRange: [1, 255],
347
+ extensions: [
348
+ 'GL_OES_packed_depth_stencil',
349
+ 'GL_OES_texture_float',
350
+ 'GL_OES_texture_float_linear',
351
+ 'GL_OES_texture_half_float',
352
+ 'GL_OES_texture_half_float_linear',
353
+ 'GL_OES_element_index_uint',
354
+ 'GL_OES_vertex_array_object',
355
+ 'GL_OES_standard_derivatives',
356
+ 'GL_OES_fbo_render_mipmap',
357
+ 'GL_EXT_blend_minmax',
358
+ 'GL_EXT_color_buffer_float',
359
+ 'GL_EXT_color_buffer_half_float',
360
+ 'GL_EXT_disjoint_timer_query',
361
+ 'GL_EXT_float_blend',
362
+ 'GL_EXT_frag_depth',
363
+ 'GL_EXT_shader_texture_lod',
364
+ 'GL_EXT_sRGB',
365
+ 'GL_EXT_texture_compression_bptc',
366
+ 'GL_EXT_texture_compression_rgtc',
367
+ 'GL_EXT_texture_filter_anisotropic',
368
+ 'GL_KHR_parallel_shader_compile',
369
+ 'GL_WEBGL_color_buffer_float',
370
+ 'GL_WEBGL_compressed_texture_s3tc',
371
+ 'GL_WEBGL_compressed_texture_s3tc_srgb',
372
+ 'GL_WEBGL_debug_renderer_info',
373
+ 'GL_WEBGL_debug_shaders',
374
+ 'GL_WEBGL_depth_texture',
375
+ 'GL_WEBGL_draw_buffers',
376
+ 'GL_WEBGL_lose_context',
377
+ 'GL_WEBGL_multi_draw',
378
+ ],
379
+ },
380
+ };
381
+ /**
382
+ * Classify the renderer string emitted by fingerprint-generator into one of the
383
+ * seven GPU families known to the C++ EmulatedConfig. Returns undefined when
384
+ * the renderer doesn't match a known family (e.g. SwiftShader / llvmpipe ANGLE
385
+ * fallback) — the caller should not write a familyHint in that case so the
386
+ * binary falls through to its current Mac-realistic defaults.
387
+ *
388
+ * The match order matters: more specific patterns (D3D11 vs OpenGL ES) must
389
+ * come before broader ones (vendor-only) so e.g. "ANGLE (NVIDIA, ... Direct3D11"
390
+ * is classified as windows_d3d_nvidia rather than linux_mesa_nvidia.
391
+ */
392
+ export function classifyWebglRenderer(renderer) {
393
+ const r = renderer.toLowerCase();
394
+ // Windows + D3D11 backend — distinctive substring "direct3d11" or " d3d11"
395
+ // (ANGLE renderer strings on Windows always contain Direct3D11).
396
+ if (r.includes('direct3d11') || r.includes('d3d11')) {
397
+ if (r.includes('nvidia'))
398
+ return 'windows_d3d_nvidia';
399
+ if (r.includes('amd') || r.includes('radeon') || r.includes('ati '))
400
+ return 'windows_d3d_amd';
401
+ if (r.includes('intel'))
402
+ return 'windows_d3d_intel';
403
+ // Unknown vendor on D3D11 — fall through to default
404
+ return undefined;
405
+ }
406
+ // Apple Metal — "ANGLE Metal Renderer:" or "Apple M[0-9]"
407
+ if (r.includes('apple metal') || r.includes('angle metal') || /apple m[0-9]/i.test(r) || r.includes('apple silicon')) {
408
+ return 'apple_metal';
409
+ }
410
+ // Linux + Mesa — distinctive substrings: "mesa ", "(radeonsi", "(nouveau"
411
+ // or "OpenGL ES" or "OpenGL 4." outside of an Apple/D3D context.
412
+ if (r.includes('mesa') || r.includes('radeonsi') || r.includes('nouveau') || r.includes('llvmpipe')) {
413
+ if (r.includes('nvidia') || r.includes('nouveau'))
414
+ return 'linux_mesa_nvidia';
415
+ if (r.includes('amd') || r.includes('radeon') || r.includes('radeonsi') || r.includes('ati '))
416
+ return 'linux_mesa_amd';
417
+ if (r.includes('intel'))
418
+ return 'linux_mesa_intel';
419
+ return undefined;
420
+ }
421
+ // Bare "OpenGL ES" with a vendor — common Mesa shape that doesn't include
422
+ // the word "mesa" in the renderer string (e.g. "ANGLE (NVIDIA, ..., OpenGL ES 3.2)").
423
+ if (r.includes('opengl es') || r.includes(', opengl 4.')) {
424
+ if (r.includes('nvidia'))
425
+ return 'linux_mesa_nvidia';
426
+ if (r.includes('amd') || r.includes('radeon'))
427
+ return 'linux_mesa_amd';
428
+ if (r.includes('intel'))
429
+ return 'linux_mesa_intel';
430
+ }
431
+ return undefined;
432
+ }
433
+ /**
434
+ * Resolve the WebglFamilyProfile to use for a given renderer string. Falls
435
+ * back to the apple_metal profile (the current binary's hardcoded default)
436
+ * when the renderer is unrecognised, so the JSON config stays consistent
437
+ * with whatever the C++ EmulatedConfig defaults to before M2 lands.
438
+ */
439
+ export function deriveWebglFamilyProfile(renderer) {
440
+ const family = classifyWebglRenderer(renderer);
441
+ const profile = family ? PLATFORM_GPU_TABLE[family] : PLATFORM_GPU_TABLE.apple_metal;
442
+ return { family, profile };
443
+ }
60
444
  // ─── Generation ───────────────────────────────────────────────────────────────
61
445
  /**
62
446
  * Generate a FingerprintConfig JSON object from fingerprint-generator output.
@@ -130,7 +514,15 @@ export function generateFingerprintConfig(fingerprint, sessionId, resolvedLocale
130
514
  // 8192; real Apple Silicon (Metal), modern NVIDIA / AMD discrete GPUs, and
131
515
  // most Intel iGPUs return 16384. Pair the spoofed renderer with its real
132
516
  // texture-size cap; mismatch is an instant CreepJS catch.
517
+ //
518
+ // M1 — also classify the renderer into a GPU family (apple_metal,
519
+ // linux_mesa_*, windows_d3d_*) so we can populate the rest of the
520
+ // platform-divergent WebGL pnames (max_draw_buffers, aliased_*_range, ...)
521
+ // from the per-family PLATFORM_GPU_TABLE. The C++ binary ignores the new
522
+ // keys until M2 lands the parser additions; once it does, the JSON shape
523
+ // is already correct.
133
524
  const rendererLower = webglRenderer.toLowerCase();
525
+ const { family: webglFamily, profile: webglFamilyProfile } = deriveWebglFamilyProfile(webglRenderer);
134
526
  const webglMaxTextureSize = (() => {
135
527
  if (/apple|metal|m[123]\b|intel.*iris.*xe|nvidia geforce rtx 40|nvidia geforce rtx 30|nvidia geforce rtx 20|amd radeon (rx [56789]|pro)/i.test(rendererLower)) {
136
528
  return 16384;
@@ -141,7 +533,7 @@ export function generateFingerprintConfig(fingerprint, sessionId, resolvedLocale
141
533
  if (/swiftshader|llvmpipe|mesa offscreen/i.test(rendererLower)) {
142
534
  return 8192; // honest SwiftShader claim
143
535
  }
144
- return 16384; // safe default for any unspoofed-renderer-string profile
536
+ return webglFamilyProfile.maxTextureSize; // family-table default
145
537
  })();
146
538
  // Screen
147
539
  const screen = fp.screen;
@@ -263,6 +655,17 @@ export function generateFingerprintConfig(fingerprint, sessionId, resolvedLocale
263
655
  vendor: webglVendor,
264
656
  renderer: webglRenderer,
265
657
  maxTextureSize: webglMaxTextureSize,
658
+ maxViewportDim: webglFamilyProfile.maxViewportDim,
659
+ extensions: webglFamilyProfile.extensions,
660
+ ...(webglFamily && { familyHint: webglFamily }),
661
+ maxDrawBuffers: webglFamilyProfile.maxDrawBuffers,
662
+ maxSamples: webglFamilyProfile.maxSamples,
663
+ max3dTextureSize: webglFamilyProfile.max3dTextureSize,
664
+ maxArrayTextureLayers: webglFamilyProfile.maxArrayTextureLayers,
665
+ subpixelBits: webglFamilyProfile.subpixelBits,
666
+ maxTransformFeedbackInterleavedComponents: webglFamilyProfile.maxTransformFeedbackInterleavedComponents,
667
+ aliasedLineWidthRange: webglFamilyProfile.aliasedLineWidthRange,
668
+ aliasedPointSizeRange: webglFamilyProfile.aliasedPointSizeRange,
266
669
  },
267
670
  screen: {
268
671
  width: screen?.width ?? 1920,
@@ -302,6 +705,32 @@ export function generateFingerprintConfig(fingerprint, sessionId, resolvedLocale
302
705
  // AudioContext.sampleRate hint matched to platform. Consumed by the C++
303
706
  // base_audio_context.h getter when the binding-layer override lands.
304
707
  config.audio = { sampleRate: deriveAudioSampleRate(platform) };
708
+ // M6: canvas text rendering mode. Derived from the WebGL family hint so
709
+ // the canvas2D text rasterisation matches the OS we claim. The C++
710
+ // FingerprintConfig parser ALSO derives the same default when canvas is
711
+ // omitted entirely, so this is belt-and-suspenders — but writing it from
712
+ // here means the JSON config is self-describing and a reader can see
713
+ // exactly which mode + font allowlist the session ships with.
714
+ if (webglFamily) {
715
+ const textRenderingMode = (() => {
716
+ switch (webglFamily) {
717
+ case 'apple_metal': return 'subpixel_aa_no_hinting';
718
+ case 'windows_d3d_nvidia':
719
+ case 'windows_d3d_amd':
720
+ case 'windows_d3d_intel':
721
+ return 'lcd_subpixel_full_hinting';
722
+ case 'linux_mesa_amd':
723
+ case 'linux_mesa_nvidia':
724
+ case 'linux_mesa_intel':
725
+ return 'rgb_subpixel_slight_hinting';
726
+ default:
727
+ return undefined;
728
+ }
729
+ })();
730
+ if (textRenderingMode) {
731
+ config.canvas = { textRenderingMode };
732
+ }
733
+ }
305
734
  return config;
306
735
  }
307
736
  /**