@ginger-ai/ginger-js 0.0.1
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 +88 -0
- package/dist/ginger.cjs.js +2 -0
- package/dist/ginger.cjs.js.map +1 -0
- package/dist/ginger.esm.d.ts +294 -0
- package/dist/ginger.esm.js +2 -0
- package/dist/ginger.esm.js.map +1 -0
- package/dist/ginger.umd.js +2 -0
- package/dist/ginger.umd.js.map +1 -0
- package/dist/types/behaviour/index.d.ts +49 -0
- package/dist/types/behaviour/index.d.ts.map +1 -0
- package/dist/types/client/index.d.ts +35 -0
- package/dist/types/client/index.d.ts.map +1 -0
- package/dist/types/core/constants.d.ts +5 -0
- package/dist/types/core/constants.d.ts.map +1 -0
- package/dist/types/core/dto/bot-detector.dto.d.ts +30 -0
- package/dist/types/core/dto/bot-detector.dto.d.ts.map +1 -0
- package/dist/types/core/dto/device-detector.dto.d.ts +54 -0
- package/dist/types/core/dto/device-detector.dto.d.ts.map +1 -0
- package/dist/types/core/dto/fingerprint.dto.d.ts +29 -0
- package/dist/types/core/dto/fingerprint.dto.d.ts.map +1 -0
- package/dist/types/core/dto/ginger.dto.d.ts +73 -0
- package/dist/types/core/dto/ginger.dto.d.ts.map +1 -0
- package/dist/types/core/dto/incognito-detector.dto.d.ts +4 -0
- package/dist/types/core/dto/incognito-detector.dto.d.ts.map +1 -0
- package/dist/types/core/dto/index.d.ts +10 -0
- package/dist/types/core/dto/index.d.ts.map +1 -0
- package/dist/types/core/dto/metrics.dto.d.ts +19 -0
- package/dist/types/core/dto/metrics.dto.d.ts.map +1 -0
- package/dist/types/core/dto/os-detector.dto.d.ts +6 -0
- package/dist/types/core/dto/os-detector.dto.d.ts.map +1 -0
- package/dist/types/core/dto/tor-detector.dto.d.ts +5 -0
- package/dist/types/core/dto/tor-detector.dto.d.ts.map +1 -0
- package/dist/types/core/helpers.d.ts +8 -0
- package/dist/types/core/helpers.d.ts.map +1 -0
- package/dist/types/core/http/httpClient.d.ts +28 -0
- package/dist/types/core/http/httpClient.d.ts.map +1 -0
- package/dist/types/core/http/request.d.ts +4 -0
- package/dist/types/core/http/request.d.ts.map +1 -0
- package/dist/types/core/index.d.ts +6 -0
- package/dist/types/core/index.d.ts.map +1 -0
- package/dist/types/core/util/error.d.ts +25 -0
- package/dist/types/core/util/error.d.ts.map +1 -0
- package/dist/types/core/util/generate-requestid.d.ts +2 -0
- package/dist/types/core/util/generate-requestid.d.ts.map +1 -0
- package/dist/types/device/components/audio/audio.d.ts +2 -0
- package/dist/types/device/components/audio/audio.d.ts.map +1 -0
- package/dist/types/device/components/canvas/canvas.d.ts +3 -0
- package/dist/types/device/components/canvas/canvas.d.ts.map +1 -0
- package/dist/types/device/components/extra/extra.d.ts +19 -0
- package/dist/types/device/components/extra/extra.d.ts.map +1 -0
- package/dist/types/device/components/fonts/fonts.d.ts +3 -0
- package/dist/types/device/components/fonts/fonts.d.ts.map +1 -0
- package/dist/types/device/components/hardware/hardware.d.ts +2 -0
- package/dist/types/device/components/hardware/hardware.d.ts.map +1 -0
- package/dist/types/device/components/index.d.ts +15 -0
- package/dist/types/device/components/index.d.ts.map +1 -0
- package/dist/types/device/components/locales/locales.d.ts +2 -0
- package/dist/types/device/components/locales/locales.d.ts.map +1 -0
- package/dist/types/device/components/math/math.d.ts +2 -0
- package/dist/types/device/components/math/math.d.ts.map +1 -0
- package/dist/types/device/components/permissions/permissions.d.ts +3 -0
- package/dist/types/device/components/permissions/permissions.d.ts.map +1 -0
- package/dist/types/device/components/plugins/plugins.d.ts +3 -0
- package/dist/types/device/components/plugins/plugins.d.ts.map +1 -0
- package/dist/types/device/components/screen/screen.d.ts +2 -0
- package/dist/types/device/components/screen/screen.d.ts.map +1 -0
- package/dist/types/device/components/screen/screenResolution.d.ts +16 -0
- package/dist/types/device/components/screen/screenResolution.d.ts.map +1 -0
- package/dist/types/device/components/system/browser.d.ts +22 -0
- package/dist/types/device/components/system/browser.d.ts.map +1 -0
- package/dist/types/device/components/system/emoji.d.ts +2 -0
- package/dist/types/device/components/system/emoji.d.ts.map +1 -0
- package/dist/types/device/components/system/system.d.ts +2 -0
- package/dist/types/device/components/system/system.d.ts.map +1 -0
- package/dist/types/device/components/webgl/imageHash.d.ts +3 -0
- package/dist/types/device/components/webgl/imageHash.d.ts.map +1 -0
- package/dist/types/device/components/webgl/webgl.d.ts +54 -0
- package/dist/types/device/components/webgl/webgl.d.ts.map +1 -0
- package/dist/types/device/factory.d.ts +26 -0
- package/dist/types/device/factory.d.ts.map +1 -0
- package/dist/types/device/index.d.ts +61 -0
- package/dist/types/device/index.d.ts.map +1 -0
- package/dist/types/device/modules/bot.d.ts +9 -0
- package/dist/types/device/modules/bot.d.ts.map +1 -0
- package/dist/types/device/modules/browserDetails.d.ts +6 -0
- package/dist/types/device/modules/browserDetails.d.ts.map +1 -0
- package/dist/types/device/modules/device/analyze-data.d.ts +7 -0
- package/dist/types/device/modules/device/analyze-data.d.ts.map +1 -0
- package/dist/types/device/modules/device/gather-data.d.ts +6 -0
- package/dist/types/device/modules/device/gather-data.d.ts.map +1 -0
- package/dist/types/device/modules/device/helpers.d.ts +9 -0
- package/dist/types/device/modules/device/helpers.d.ts.map +1 -0
- package/dist/types/device/modules/device/index.d.ts +3 -0
- package/dist/types/device/modules/device/index.d.ts.map +1 -0
- package/dist/types/device/modules/fp.d.ts +14 -0
- package/dist/types/device/modules/fp.d.ts.map +1 -0
- package/dist/types/device/modules/incognito.d.ts +7 -0
- package/dist/types/device/modules/incognito.d.ts.map +1 -0
- package/dist/types/device/modules/options.d.ts +12 -0
- package/dist/types/device/modules/options.d.ts.map +1 -0
- package/dist/types/device/modules/os.d.ts +3 -0
- package/dist/types/device/modules/os.d.ts.map +1 -0
- package/dist/types/device/modules/tor.d.ts +4 -0
- package/dist/types/device/modules/tor.d.ts.map +1 -0
- package/dist/types/device/utils/async.d.ts +33 -0
- package/dist/types/device/utils/async.d.ts.map +1 -0
- package/dist/types/device/utils/browser_.d.ts +103 -0
- package/dist/types/device/utils/browser_.d.ts.map +1 -0
- package/dist/types/device/utils/commonPixels.d.ts +2 -0
- package/dist/types/device/utils/commonPixels.d.ts.map +1 -0
- package/dist/types/device/utils/data.d.ts +33 -0
- package/dist/types/device/utils/data.d.ts.map +1 -0
- package/dist/types/device/utils/dom.d.ts +26 -0
- package/dist/types/device/utils/dom.d.ts.map +1 -0
- package/dist/types/device/utils/ephemeralIFrame.d.ts +5 -0
- package/dist/types/device/utils/ephemeralIFrame.d.ts.map +1 -0
- package/dist/types/device/utils/getMostFrequent.d.ts +6 -0
- package/dist/types/device/utils/getMostFrequent.d.ts.map +1 -0
- package/dist/types/device/utils/hash.d.ts +6 -0
- package/dist/types/device/utils/hash.d.ts.map +1 -0
- package/dist/types/device/utils/misc.d.ts +7 -0
- package/dist/types/device/utils/misc.d.ts.map +1 -0
- package/dist/types/device/utils/raceAll.d.ts +9 -0
- package/dist/types/device/utils/raceAll.d.ts.map +1 -0
- package/dist/types/index.d.ts +4 -0
- package/dist/types/index.d.ts.map +1 -0
- package/package.json +52 -0
- package/src/behaviour/index.ts +279 -0
- package/src/client/index.ts +132 -0
- package/src/core/constants.ts +4 -0
- package/src/core/dto/bot-detector.dto.ts +32 -0
- package/src/core/dto/device-detector.dto.ts +67 -0
- package/src/core/dto/fingerprint.dto.ts +38 -0
- package/src/core/dto/ginger.dto.ts +89 -0
- package/src/core/dto/incognito-detector.dto.ts +2 -0
- package/src/core/dto/index.ts +18 -0
- package/src/core/dto/metrics.dto.ts +20 -0
- package/src/core/dto/os-detector.dto.ts +5 -0
- package/src/core/dto/tor-detector.dto.ts +4 -0
- package/src/core/helpers.ts +33 -0
- package/src/core/http/httpClient.ts +52 -0
- package/src/core/http/request.ts +32 -0
- package/src/core/index.ts +5 -0
- package/src/core/util/error.ts +40 -0
- package/src/core/util/generate-requestid.ts +63 -0
- package/src/device/components/audio/audio.ts +58 -0
- package/src/device/components/canvas/canvas.ts +88 -0
- package/src/device/components/extra/extra.ts +581 -0
- package/src/device/components/fonts/fonts.ts +143 -0
- package/src/device/components/hardware/hardware.ts +66 -0
- package/src/device/components/index.ts +14 -0
- package/src/device/components/locales/locales.ts +21 -0
- package/src/device/components/math/math.ts +39 -0
- package/src/device/components/permissions/permissions.ts +60 -0
- package/src/device/components/plugins/plugins.ts +22 -0
- package/src/device/components/screen/screen.ts +13 -0
- package/src/device/components/screen/screenResolution.ts +45 -0
- package/src/device/components/system/browser.ts +838 -0
- package/src/device/components/system/emoji.ts +134 -0
- package/src/device/components/system/system.ts +76 -0
- package/src/device/components/webgl/imageHash.ts +144 -0
- package/src/device/components/webgl/webgl.ts +302 -0
- package/src/device/factory.ts +54 -0
- package/src/device/index.ts +60 -0
- package/src/device/modules/bot.ts +25 -0
- package/src/device/modules/browserDetails.ts +11 -0
- package/src/device/modules/device/analyze-data.ts +150 -0
- package/src/device/modules/device/gather-data.ts +92 -0
- package/src/device/modules/device/helpers.ts +123 -0
- package/src/device/modules/device/index.ts +64 -0
- package/src/device/modules/fp.ts +138 -0
- package/src/device/modules/incognito.ts +253 -0
- package/src/device/modules/options.ts +17 -0
- package/src/device/modules/os.ts +15 -0
- package/src/device/modules/tor.ts +41 -0
- package/src/device/utils/async.ts +106 -0
- package/src/device/utils/browser_.ts +347 -0
- package/src/device/utils/commonPixels.ts +38 -0
- package/src/device/utils/data.ts +161 -0
- package/src/device/utils/dom.ts +148 -0
- package/src/device/utils/ephemeralIFrame.ts +35 -0
- package/src/device/utils/getMostFrequent.ts +39 -0
- package/src/device/utils/hash.ts +202 -0
- package/src/device/utils/misc.ts +18 -0
- package/src/device/utils/raceAll.ts +19 -0
- package/src/index.ts +3 -0
|
@@ -0,0 +1,581 @@
|
|
|
1
|
+
import { includeComponent } from "../../factory";
|
|
2
|
+
|
|
3
|
+
import { selectorToElement } from "../../utils/dom";
|
|
4
|
+
import { countTruthy } from "../../utils/data";
|
|
5
|
+
import { wait } from "../../utils/async";
|
|
6
|
+
import { isAndroid, isWebKit } from "../../utils/browser_";
|
|
7
|
+
import { detectBrowser } from "../system/browser";
|
|
8
|
+
|
|
9
|
+
// Floating-point calculations (Math.sin(), Math.log()) produce slightly different results across CPUs due to:
|
|
10
|
+
// Extremely hard to spoof without emulating a different CPU.
|
|
11
|
+
// function getCPUFingerprint(): any {
|
|
12
|
+
// return {
|
|
13
|
+
// sin1: Math.sin(1),
|
|
14
|
+
// log10: Math.log(10),
|
|
15
|
+
// tanh05: Math.tanh(0.5),
|
|
16
|
+
// };
|
|
17
|
+
// }
|
|
18
|
+
|
|
19
|
+
const enum SpecialFingerprint {
|
|
20
|
+
/** The browser doesn't support AudioContext or baseLatency */
|
|
21
|
+
NotSupported = -1,
|
|
22
|
+
/** Entropy source is disabled because of console warnings */
|
|
23
|
+
Disabled = -2,
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function getAudioContextBaseLatency(): any {
|
|
27
|
+
// The signal emits warning in Chrome and Firefox, therefore it is enabled on Safari where it doesn't produce warning
|
|
28
|
+
// and on Android where it's less visible
|
|
29
|
+
const isAllowedPlatform = isAndroid() || isWebKit();
|
|
30
|
+
if (!isAllowedPlatform) {
|
|
31
|
+
return SpecialFingerprint.Disabled;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
if (!window.AudioContext) {
|
|
35
|
+
return SpecialFingerprint.NotSupported;
|
|
36
|
+
}
|
|
37
|
+
return new AudioContext().baseLatency ?? SpecialFingerprint.NotSupported;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/CSS/@media/color-gamut
|
|
42
|
+
*/
|
|
43
|
+
function getColorGamut(): any {
|
|
44
|
+
// rec2020 includes p3 and p3 includes srgb
|
|
45
|
+
for (const gamut of ["rec2020", "p3", "srgb"] as const) {
|
|
46
|
+
if (matchMedia(`(color-gamut: ${gamut})`).matches) {
|
|
47
|
+
return gamut;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
return undefined;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function areColorsForced(): any {
|
|
54
|
+
if (doesMatch("active")) {
|
|
55
|
+
return true;
|
|
56
|
+
}
|
|
57
|
+
if (doesMatch("none")) {
|
|
58
|
+
return false;
|
|
59
|
+
}
|
|
60
|
+
return undefined;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function doesMatch(value: string) {
|
|
64
|
+
return matchMedia(`(forced-colors: ${value})`).matches;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const maxValueToCheck = 100;
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* If the display is monochrome (e.g. black&white), the value will be ≥0 and will mean the number of bits per pixel.
|
|
71
|
+
* If the display is not monochrome, the returned value will be 0.
|
|
72
|
+
* If the browser doesn't support this feature, the returned value will be undefined.
|
|
73
|
+
*
|
|
74
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/CSS/@media/monochrome
|
|
75
|
+
*/
|
|
76
|
+
function getMonochromeDepth(): any {
|
|
77
|
+
if (!matchMedia("(min-monochrome: 0)").matches) {
|
|
78
|
+
// The media feature isn't supported by the browser
|
|
79
|
+
return undefined;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// A variation of binary search algorithm can be used here.
|
|
83
|
+
// But since expected values are very small (≤10), there is no sense in adding the complexity.
|
|
84
|
+
for (let i = 0; i <= maxValueToCheck; ++i) {
|
|
85
|
+
if (matchMedia(`(max-monochrome: ${i})`).matches) {
|
|
86
|
+
return i;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
throw new Error("Too high value");
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
function getOsCpu(): any {
|
|
94
|
+
return (navigator as any).oscpu;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Checks for browser-specific (not engine specific) global variables to tell browsers with the same engine apart.
|
|
99
|
+
* Only somewhat popular browsers are considered.
|
|
100
|
+
*/
|
|
101
|
+
export function getVendorFlavors(): any {
|
|
102
|
+
const flavors: string[] = [];
|
|
103
|
+
|
|
104
|
+
for (const key of [
|
|
105
|
+
// Blink and some browsers on iOS
|
|
106
|
+
"chrome",
|
|
107
|
+
|
|
108
|
+
// Safari on macOS
|
|
109
|
+
"safari",
|
|
110
|
+
|
|
111
|
+
// Chrome on iOS (checked in 85 on 13 and 87 on 14)
|
|
112
|
+
"__crWeb",
|
|
113
|
+
"__gCrWeb",
|
|
114
|
+
|
|
115
|
+
// Yandex Browser on iOS, macOS and Android (checked in 21.2 on iOS 14, macOS and Android)
|
|
116
|
+
"yandex",
|
|
117
|
+
|
|
118
|
+
// Yandex Browser on iOS (checked in 21.2 on 14)
|
|
119
|
+
"__yb",
|
|
120
|
+
"__ybro",
|
|
121
|
+
|
|
122
|
+
// Firefox on iOS (checked in 32 on 14)
|
|
123
|
+
"__firefox__",
|
|
124
|
+
|
|
125
|
+
// Edge on iOS (checked in 46 on 14)
|
|
126
|
+
"__edgeTrackingPreventionStatistics",
|
|
127
|
+
"webkit",
|
|
128
|
+
|
|
129
|
+
// Opera Touch on iOS (checked in 2.6 on 14)
|
|
130
|
+
"oprt",
|
|
131
|
+
|
|
132
|
+
// Samsung Internet on Android (checked in 11.1)
|
|
133
|
+
"samsungAr",
|
|
134
|
+
|
|
135
|
+
// UC Browser on Android (checked in 12.10 and 13.0)
|
|
136
|
+
"ucweb",
|
|
137
|
+
"UCShellJava",
|
|
138
|
+
|
|
139
|
+
// Puffin on Android (checked in 9.0)
|
|
140
|
+
"puffinDevice",
|
|
141
|
+
|
|
142
|
+
// UC on iOS and Opera on Android have no specific global variables
|
|
143
|
+
// Edge for Android isn't checked
|
|
144
|
+
]) {
|
|
145
|
+
const value = (window as unknown as Record<string, unknown>)[key];
|
|
146
|
+
if (value && typeof value === "object") {
|
|
147
|
+
flavors.push(key);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
const sortedVendorFlavors = flavors.sort();
|
|
152
|
+
|
|
153
|
+
// If no vendor flavor is detected, default to use the browser name
|
|
154
|
+
if (sortedVendorFlavors.length > 0) {
|
|
155
|
+
return sortedVendorFlavors;
|
|
156
|
+
} else {
|
|
157
|
+
const { name: browsername } = detectBrowser();
|
|
158
|
+
return [browsername];
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
type Filters = Record<string, string[]>;
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* Only single element selector are supported (no operators like space, +, >, etc).
|
|
166
|
+
* `embed` and `position: fixed;` will be considered as blocked anyway because it always has no offsetParent.
|
|
167
|
+
* Avoid `iframe` and anything with `[src=]` because they produce excess HTTP requests.
|
|
168
|
+
*
|
|
169
|
+
* The "inappropriate" selectors are obfuscated. See https://github.com/fingerprintjs/fingerprintjs/issues/734.
|
|
170
|
+
* A function is used instead of a plain object to help tree-shaking.
|
|
171
|
+
*
|
|
172
|
+
* The function code is generated automatically. See docs/content_blockers.md to learn how to make the list.
|
|
173
|
+
*/
|
|
174
|
+
export function getFilters(): Filters {
|
|
175
|
+
const fromB64 = atob; // Just for better minification
|
|
176
|
+
|
|
177
|
+
return {
|
|
178
|
+
abpIndo: [
|
|
179
|
+
"#Iklan-Melayang",
|
|
180
|
+
"#Kolom-Iklan-728",
|
|
181
|
+
"#SidebarIklan-wrapper",
|
|
182
|
+
'[title="ALIENBOLA" i]',
|
|
183
|
+
fromB64("I0JveC1CYW5uZXItYWRz"),
|
|
184
|
+
],
|
|
185
|
+
abpvn: [
|
|
186
|
+
".quangcao",
|
|
187
|
+
"#mobileCatfish",
|
|
188
|
+
fromB64("LmNsb3NlLWFkcw=="),
|
|
189
|
+
'[id^="bn_bottom_fixed_"]',
|
|
190
|
+
"#pmadv",
|
|
191
|
+
],
|
|
192
|
+
adBlockFinland: [
|
|
193
|
+
".mainostila",
|
|
194
|
+
fromB64("LnNwb25zb3JpdA=="),
|
|
195
|
+
".ylamainos",
|
|
196
|
+
fromB64("YVtocmVmKj0iL2NsaWNrdGhyZ2guYXNwPyJd"),
|
|
197
|
+
fromB64("YVtocmVmXj0iaHR0cHM6Ly9hcHAucmVhZHBlYWsuY29tL2FkcyJd"),
|
|
198
|
+
],
|
|
199
|
+
adBlockPersian: [
|
|
200
|
+
"#navbar_notice_50",
|
|
201
|
+
".kadr",
|
|
202
|
+
'TABLE[width="140px"]',
|
|
203
|
+
"#divAgahi",
|
|
204
|
+
fromB64("YVtocmVmXj0iaHR0cDovL2cxLnYuZndtcm0ubmV0L2FkLyJd"),
|
|
205
|
+
],
|
|
206
|
+
adBlockWarningRemoval: [
|
|
207
|
+
"#adblock-honeypot",
|
|
208
|
+
".adblocker-root",
|
|
209
|
+
".wp_adblock_detect",
|
|
210
|
+
fromB64("LmhlYWRlci1ibG9ja2VkLWFk"),
|
|
211
|
+
fromB64("I2FkX2Jsb2NrZXI="),
|
|
212
|
+
],
|
|
213
|
+
adGuardAnnoyances: [
|
|
214
|
+
".hs-sosyal",
|
|
215
|
+
"#cookieconsentdiv",
|
|
216
|
+
'div[class^="app_gdpr"]',
|
|
217
|
+
".as-oil",
|
|
218
|
+
'[data-cypress="soft-push-notification-modal"]',
|
|
219
|
+
],
|
|
220
|
+
adGuardBase: [
|
|
221
|
+
".BetterJsPopOverlay",
|
|
222
|
+
fromB64("I2FkXzMwMFgyNTA="),
|
|
223
|
+
fromB64("I2Jhbm5lcmZsb2F0MjI="),
|
|
224
|
+
fromB64("I2NhbXBhaWduLWJhbm5lcg=="),
|
|
225
|
+
fromB64("I0FkLUNvbnRlbnQ="),
|
|
226
|
+
],
|
|
227
|
+
adGuardChinese: [
|
|
228
|
+
fromB64("LlppX2FkX2FfSA=="),
|
|
229
|
+
fromB64("YVtocmVmKj0iLmh0aGJldDM0LmNvbSJd"),
|
|
230
|
+
"#widget-quan",
|
|
231
|
+
fromB64("YVtocmVmKj0iLzg0OTkyMDIwLnh5eiJd"),
|
|
232
|
+
fromB64("YVtocmVmKj0iLjE5NTZobC5jb20vIl0="),
|
|
233
|
+
],
|
|
234
|
+
adGuardFrench: [
|
|
235
|
+
"#pavePub",
|
|
236
|
+
fromB64("LmFkLWRlc2t0b3AtcmVjdGFuZ2xl"),
|
|
237
|
+
".mobile_adhesion",
|
|
238
|
+
".widgetadv",
|
|
239
|
+
fromB64("LmFkc19iYW4="),
|
|
240
|
+
],
|
|
241
|
+
adGuardGerman: ['aside[data-portal-id="leaderboard"]'],
|
|
242
|
+
adGuardJapanese: [
|
|
243
|
+
"#kauli_yad_1",
|
|
244
|
+
fromB64("YVtocmVmXj0iaHR0cDovL2FkMi50cmFmZmljZ2F0ZS5uZXQvIl0="),
|
|
245
|
+
fromB64("Ll9wb3BJbl9pbmZpbml0ZV9hZA=="),
|
|
246
|
+
fromB64("LmFkZ29vZ2xl"),
|
|
247
|
+
fromB64("Ll9faXNib29zdFJldHVybkFk"),
|
|
248
|
+
],
|
|
249
|
+
adGuardMobile: [
|
|
250
|
+
fromB64("YW1wLWF1dG8tYWRz"),
|
|
251
|
+
fromB64("LmFtcF9hZA=="),
|
|
252
|
+
'amp-embed[type="24smi"]',
|
|
253
|
+
"#mgid_iframe1",
|
|
254
|
+
fromB64("I2FkX2ludmlld19hcmVh"),
|
|
255
|
+
],
|
|
256
|
+
adGuardRussian: [
|
|
257
|
+
fromB64("YVtocmVmXj0iaHR0cHM6Ly9hZC5sZXRtZWFkcy5jb20vIl0="),
|
|
258
|
+
fromB64("LnJlY2xhbWE="),
|
|
259
|
+
'div[id^="smi2adblock"]',
|
|
260
|
+
fromB64("ZGl2W2lkXj0iQWRGb3hfYmFubmVyXyJd"),
|
|
261
|
+
"#psyduckpockeball",
|
|
262
|
+
],
|
|
263
|
+
adGuardSocial: [
|
|
264
|
+
fromB64("YVtocmVmXj0iLy93d3cuc3R1bWJsZXVwb24uY29tL3N1Ym1pdD91cmw9Il0="),
|
|
265
|
+
fromB64("YVtocmVmXj0iLy90ZWxlZ3JhbS5tZS9zaGFyZS91cmw/Il0="),
|
|
266
|
+
".etsy-tweet",
|
|
267
|
+
"#inlineShare",
|
|
268
|
+
".popup-social",
|
|
269
|
+
],
|
|
270
|
+
adGuardSpanishPortuguese: [
|
|
271
|
+
"#barraPublicidade",
|
|
272
|
+
"#Publicidade",
|
|
273
|
+
"#publiEspecial",
|
|
274
|
+
"#queTooltip",
|
|
275
|
+
".cnt-publi",
|
|
276
|
+
],
|
|
277
|
+
adGuardTrackingProtection: [
|
|
278
|
+
"#qoo-counter",
|
|
279
|
+
fromB64("YVtocmVmXj0iaHR0cDovL2NsaWNrLmhvdGxvZy5ydS8iXQ=="),
|
|
280
|
+
fromB64("YVtocmVmXj0iaHR0cDovL2hpdGNvdW50ZXIucnUvdG9wL3N0YXQucGhwIl0="),
|
|
281
|
+
fromB64("YVtocmVmXj0iaHR0cDovL3RvcC5tYWlsLnJ1L2p1bXAiXQ=="),
|
|
282
|
+
"#top100counter",
|
|
283
|
+
],
|
|
284
|
+
adGuardTurkish: [
|
|
285
|
+
"#backkapat",
|
|
286
|
+
fromB64("I3Jla2xhbWk="),
|
|
287
|
+
fromB64("YVtocmVmXj0iaHR0cDovL2Fkc2Vydi5vbnRlay5jb20udHIvIl0="),
|
|
288
|
+
fromB64("YVtocmVmXj0iaHR0cDovL2l6bGVuemkuY29tL2NhbXBhaWduLyJd"),
|
|
289
|
+
fromB64("YVtocmVmXj0iaHR0cDovL3d3dy5pbnN0YWxsYWRzLm5ldC8iXQ=="),
|
|
290
|
+
],
|
|
291
|
+
bulgarian: [
|
|
292
|
+
fromB64("dGQjZnJlZW5ldF90YWJsZV9hZHM="),
|
|
293
|
+
"#ea_intext_div",
|
|
294
|
+
".lapni-pop-over",
|
|
295
|
+
"#xenium_hot_offers",
|
|
296
|
+
],
|
|
297
|
+
easyList: [
|
|
298
|
+
".yb-floorad",
|
|
299
|
+
fromB64("LndpZGdldF9wb19hZHNfd2lkZ2V0"),
|
|
300
|
+
fromB64("LnRyYWZmaWNqdW5reS1hZA=="),
|
|
301
|
+
".textad_headline",
|
|
302
|
+
fromB64("LnNwb25zb3JlZC10ZXh0LWxpbmtz"),
|
|
303
|
+
],
|
|
304
|
+
easyListChina: [
|
|
305
|
+
fromB64("LmFwcGd1aWRlLXdyYXBbb25jbGljayo9ImJjZWJvcy5jb20iXQ=="),
|
|
306
|
+
fromB64("LmZyb250cGFnZUFkdk0="),
|
|
307
|
+
"#taotaole",
|
|
308
|
+
"#aafoot.top_box",
|
|
309
|
+
".cfa_popup",
|
|
310
|
+
],
|
|
311
|
+
easyListCookie: [
|
|
312
|
+
".ezmob-footer",
|
|
313
|
+
".cc-CookieWarning",
|
|
314
|
+
"[data-cookie-number]",
|
|
315
|
+
fromB64("LmF3LWNvb2tpZS1iYW5uZXI="),
|
|
316
|
+
".sygnal24-gdpr-modal-wrap",
|
|
317
|
+
],
|
|
318
|
+
easyListCzechSlovak: [
|
|
319
|
+
"#onlajny-stickers",
|
|
320
|
+
fromB64("I3Jla2xhbW5pLWJveA=="),
|
|
321
|
+
fromB64("LnJla2xhbWEtbWVnYWJvYXJk"),
|
|
322
|
+
".sklik",
|
|
323
|
+
fromB64("W2lkXj0ic2tsaWtSZWtsYW1hIl0="),
|
|
324
|
+
],
|
|
325
|
+
easyListDutch: [
|
|
326
|
+
fromB64("I2FkdmVydGVudGll"),
|
|
327
|
+
fromB64("I3ZpcEFkbWFya3RCYW5uZXJCbG9jaw=="),
|
|
328
|
+
".adstekst",
|
|
329
|
+
fromB64("YVtocmVmXj0iaHR0cHM6Ly94bHR1YmUubmwvY2xpY2svIl0="),
|
|
330
|
+
"#semilo-lrectangle",
|
|
331
|
+
],
|
|
332
|
+
easyListGermany: [
|
|
333
|
+
"#SSpotIMPopSlider",
|
|
334
|
+
fromB64("LnNwb25zb3JsaW5rZ3J1ZW4="),
|
|
335
|
+
fromB64("I3dlcmJ1bmdza3k="),
|
|
336
|
+
fromB64("I3Jla2xhbWUtcmVjaHRzLW1pdHRl"),
|
|
337
|
+
fromB64("YVtocmVmXj0iaHR0cHM6Ly9iZDc0Mi5jb20vIl0="),
|
|
338
|
+
],
|
|
339
|
+
easyListItaly: [
|
|
340
|
+
fromB64("LmJveF9hZHZfYW5udW5jaQ=="),
|
|
341
|
+
".sb-box-pubbliredazionale",
|
|
342
|
+
fromB64("YVtocmVmXj0iaHR0cDovL2FmZmlsaWF6aW9uaWFkcy5zbmFpLml0LyJd"),
|
|
343
|
+
fromB64("YVtocmVmXj0iaHR0cHM6Ly9hZHNlcnZlci5odG1sLml0LyJd"),
|
|
344
|
+
fromB64("YVtocmVmXj0iaHR0cHM6Ly9hZmZpbGlhemlvbmlhZHMuc25haS5pdC8iXQ=="),
|
|
345
|
+
],
|
|
346
|
+
easyListLithuania: [
|
|
347
|
+
fromB64("LnJla2xhbW9zX3RhcnBhcw=="),
|
|
348
|
+
fromB64("LnJla2xhbW9zX251b3JvZG9z"),
|
|
349
|
+
fromB64("aW1nW2FsdD0iUmVrbGFtaW5pcyBza3lkZWxpcyJd"),
|
|
350
|
+
fromB64("aW1nW2FsdD0iRGVkaWt1b3RpLmx0IHNlcnZlcmlhaSJd"),
|
|
351
|
+
fromB64("aW1nW2FsdD0iSG9zdGluZ2FzIFNlcnZlcmlhaS5sdCJd"),
|
|
352
|
+
],
|
|
353
|
+
estonian: [fromB64("QVtocmVmKj0iaHR0cDovL3BheTRyZXN1bHRzMjQuZXUiXQ==")],
|
|
354
|
+
fanboyAnnoyances: [
|
|
355
|
+
"#ac-lre-player",
|
|
356
|
+
".navigate-to-top",
|
|
357
|
+
"#subscribe_popup",
|
|
358
|
+
".newsletter_holder",
|
|
359
|
+
"#back-top",
|
|
360
|
+
],
|
|
361
|
+
fanboyAntiFacebook: [".util-bar-module-firefly-visible"],
|
|
362
|
+
fanboyEnhancedTrackers: [
|
|
363
|
+
".open.pushModal",
|
|
364
|
+
"#issuem-leaky-paywall-articles-zero-remaining-nag",
|
|
365
|
+
"#sovrn_container",
|
|
366
|
+
'div[class$="-hide"][zoompage-fontsize][style="display: block;"]',
|
|
367
|
+
".BlockNag__Card",
|
|
368
|
+
],
|
|
369
|
+
fanboySocial: [
|
|
370
|
+
"#FollowUs",
|
|
371
|
+
"#meteored_share",
|
|
372
|
+
"#social_follow",
|
|
373
|
+
".article-sharer",
|
|
374
|
+
".community__social-desc",
|
|
375
|
+
],
|
|
376
|
+
frellwitSwedish: [
|
|
377
|
+
fromB64("YVtocmVmKj0iY2FzaW5vcHJvLnNlIl1bdGFyZ2V0PSJfYmxhbmsiXQ=="),
|
|
378
|
+
fromB64("YVtocmVmKj0iZG9rdG9yLXNlLm9uZWxpbmsubWUiXQ=="),
|
|
379
|
+
"article.category-samarbete",
|
|
380
|
+
fromB64("ZGl2LmhvbGlkQWRz"),
|
|
381
|
+
"ul.adsmodern",
|
|
382
|
+
],
|
|
383
|
+
greekAdBlock: [
|
|
384
|
+
fromB64("QVtocmVmKj0iYWRtYW4ub3RlbmV0LmdyL2NsaWNrPyJd"),
|
|
385
|
+
fromB64("QVtocmVmKj0iaHR0cDovL2F4aWFiYW5uZXJzLmV4b2R1cy5nci8iXQ=="),
|
|
386
|
+
fromB64(
|
|
387
|
+
"QVtocmVmKj0iaHR0cDovL2ludGVyYWN0aXZlLmZvcnRobmV0LmdyL2NsaWNrPyJd"
|
|
388
|
+
),
|
|
389
|
+
"DIV.agores300",
|
|
390
|
+
"TABLE.advright",
|
|
391
|
+
],
|
|
392
|
+
hungarian: [
|
|
393
|
+
"#cemp_doboz",
|
|
394
|
+
".optimonk-iframe-container",
|
|
395
|
+
fromB64("LmFkX19tYWlu"),
|
|
396
|
+
fromB64("W2NsYXNzKj0iR29vZ2xlQWRzIl0="),
|
|
397
|
+
"#hirdetesek_box",
|
|
398
|
+
],
|
|
399
|
+
iDontCareAboutCookies: [
|
|
400
|
+
'.alert-info[data-block-track*="CookieNotice"]',
|
|
401
|
+
".ModuleTemplateCookieIndicator",
|
|
402
|
+
".o--cookies--container",
|
|
403
|
+
"#cookies-policy-sticky",
|
|
404
|
+
"#stickyCookieBar",
|
|
405
|
+
],
|
|
406
|
+
icelandicAbp: [
|
|
407
|
+
fromB64(
|
|
408
|
+
"QVtocmVmXj0iL2ZyYW1ld29yay9yZXNvdXJjZXMvZm9ybXMvYWRzLmFzcHgiXQ=="
|
|
409
|
+
),
|
|
410
|
+
],
|
|
411
|
+
latvian: [
|
|
412
|
+
fromB64(
|
|
413
|
+
"YVtocmVmPSJodHRwOi8vd3d3LnNhbGlkemluaS5sdi8iXVtzdHlsZT0iZGlzcGxheTogYmxvY2s7IHdpZHRoOiAxMjBweDsgaGVpZ2h0O" +
|
|
414
|
+
"iA0MHB4OyBvdmVyZmxvdzogaGlkZGVuOyBwb3NpdGlvbjogcmVsYXRpdmU7Il0="
|
|
415
|
+
),
|
|
416
|
+
fromB64(
|
|
417
|
+
"YVtocmVmPSJodHRwOi8vd3d3LnNhbGlkemluaS5sdi8iXVtzdHlsZT0iZGlzcGxheTogYmxvY2s7IHdpZHRoOiA4OHB4OyBoZWlnaHQ6I" +
|
|
418
|
+
"DMxcHg7IG92ZXJmbG93OiBoaWRkZW47IHBvc2l0aW9uOiByZWxhdGl2ZTsiXQ=="
|
|
419
|
+
),
|
|
420
|
+
],
|
|
421
|
+
listKr: [
|
|
422
|
+
fromB64("YVtocmVmKj0iLy9hZC5wbGFuYnBsdXMuY28ua3IvIl0="),
|
|
423
|
+
fromB64("I2xpdmVyZUFkV3JhcHBlcg=="),
|
|
424
|
+
fromB64("YVtocmVmKj0iLy9hZHYuaW1hZHJlcC5jby5rci8iXQ=="),
|
|
425
|
+
fromB64("aW5zLmZhc3R2aWV3LWFk"),
|
|
426
|
+
".revenue_unit_item.dable",
|
|
427
|
+
],
|
|
428
|
+
listeAr: [
|
|
429
|
+
fromB64("LmdlbWluaUxCMUFk"),
|
|
430
|
+
".right-and-left-sponsers",
|
|
431
|
+
fromB64("YVtocmVmKj0iLmFmbGFtLmluZm8iXQ=="),
|
|
432
|
+
fromB64("YVtocmVmKj0iYm9vcmFxLm9yZyJd"),
|
|
433
|
+
fromB64("YVtocmVmKj0iZHViaXp6bGUuY29tL2FyLz91dG1fc291cmNlPSJd"),
|
|
434
|
+
],
|
|
435
|
+
listeFr: [
|
|
436
|
+
fromB64("YVtocmVmXj0iaHR0cDovL3Byb21vLnZhZG9yLmNvbS8iXQ=="),
|
|
437
|
+
fromB64("I2FkY29udGFpbmVyX3JlY2hlcmNoZQ=="),
|
|
438
|
+
fromB64("YVtocmVmKj0id2Vib3JhbWEuZnIvZmNnaS1iaW4vIl0="),
|
|
439
|
+
".site-pub-interstitiel",
|
|
440
|
+
'div[id^="crt-"][data-criteo-id]',
|
|
441
|
+
],
|
|
442
|
+
officialPolish: [
|
|
443
|
+
"#ceneo-placeholder-ceneo-12",
|
|
444
|
+
fromB64("W2hyZWZePSJodHRwczovL2FmZi5zZW5kaHViLnBsLyJd"),
|
|
445
|
+
fromB64(
|
|
446
|
+
"YVtocmVmXj0iaHR0cDovL2Fkdm1hbmFnZXIudGVjaGZ1bi5wbC9yZWRpcmVjdC8iXQ=="
|
|
447
|
+
),
|
|
448
|
+
fromB64("YVtocmVmXj0iaHR0cDovL3d3dy50cml6ZXIucGwvP3V0bV9zb3VyY2UiXQ=="),
|
|
449
|
+
fromB64("ZGl2I3NrYXBpZWNfYWQ="),
|
|
450
|
+
],
|
|
451
|
+
ro: [
|
|
452
|
+
fromB64("YVtocmVmXj0iLy9hZmZ0cmsuYWx0ZXgucm8vQ291bnRlci9DbGljayJd"),
|
|
453
|
+
fromB64(
|
|
454
|
+
"YVtocmVmXj0iaHR0cHM6Ly9ibGFja2ZyaWRheXNhbGVzLnJvL3Ryay9zaG9wLyJd"
|
|
455
|
+
),
|
|
456
|
+
fromB64(
|
|
457
|
+
"YVtocmVmXj0iaHR0cHM6Ly9ldmVudC4ycGVyZm9ybWFudC5jb20vZXZlbnRzL2NsaWNrIl0="
|
|
458
|
+
),
|
|
459
|
+
fromB64("YVtocmVmXj0iaHR0cHM6Ly9sLnByb2ZpdHNoYXJlLnJvLyJd"),
|
|
460
|
+
'a[href^="/url/"]',
|
|
461
|
+
],
|
|
462
|
+
ruAd: [
|
|
463
|
+
fromB64("YVtocmVmKj0iLy9mZWJyYXJlLnJ1LyJd"),
|
|
464
|
+
fromB64("YVtocmVmKj0iLy91dGltZy5ydS8iXQ=="),
|
|
465
|
+
fromB64("YVtocmVmKj0iOi8vY2hpa2lkaWtpLnJ1Il0="),
|
|
466
|
+
"#pgeldiz",
|
|
467
|
+
".yandex-rtb-block",
|
|
468
|
+
],
|
|
469
|
+
thaiAds: [
|
|
470
|
+
"a[href*=macau-uta-popup]",
|
|
471
|
+
fromB64("I2Fkcy1nb29nbGUtbWlkZGxlX3JlY3RhbmdsZS1ncm91cA=="),
|
|
472
|
+
fromB64("LmFkczMwMHM="),
|
|
473
|
+
".bumq",
|
|
474
|
+
".img-kosana",
|
|
475
|
+
],
|
|
476
|
+
webAnnoyancesUltralist: [
|
|
477
|
+
"#mod-social-share-2",
|
|
478
|
+
"#social-tools",
|
|
479
|
+
fromB64("LmN0cGwtZnVsbGJhbm5lcg=="),
|
|
480
|
+
".zergnet-recommend",
|
|
481
|
+
".yt.btn-link.btn-md.btn",
|
|
482
|
+
],
|
|
483
|
+
};
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
/**
|
|
487
|
+
* The order of the returned array means nothing (it's always sorted alphabetically).
|
|
488
|
+
*
|
|
489
|
+
* Notice that the source is slightly unstable.
|
|
490
|
+
* Safari provides a 2-taps way to disable all content blockers on a page temporarily.
|
|
491
|
+
* Also content blockers can be disabled permanently for a domain, but it requires 4 taps.
|
|
492
|
+
* So empty array shouldn't be treated as "no blockers", it should be treated as "no signal".
|
|
493
|
+
* If you are a website owner, don't make your visitors want to disable content blockers.
|
|
494
|
+
*/
|
|
495
|
+
async function getDomBlockers(): Promise<any> {
|
|
496
|
+
if (!isApplicable()) {
|
|
497
|
+
return undefined;
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
const filters = getFilters();
|
|
501
|
+
const filterNames = Object.keys(filters) as Array<keyof typeof filters>;
|
|
502
|
+
const allSelectors = ([] as string[]).concat(
|
|
503
|
+
...filterNames.map((filterName) => filters[filterName])
|
|
504
|
+
);
|
|
505
|
+
const blockedSelectors = await getBlockedSelectors(allSelectors);
|
|
506
|
+
|
|
507
|
+
const activeBlockers = filterNames.filter((filterName) => {
|
|
508
|
+
const selectors = filters[filterName];
|
|
509
|
+
const blockedCount = countTruthy(
|
|
510
|
+
selectors.map((selector) => blockedSelectors[selector])
|
|
511
|
+
);
|
|
512
|
+
return blockedCount > selectors.length * 0.6;
|
|
513
|
+
});
|
|
514
|
+
activeBlockers.sort();
|
|
515
|
+
|
|
516
|
+
return activeBlockers;
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
function isApplicable(): boolean {
|
|
520
|
+
// Safari (desktop and mobile) and all Android browsers keep content blockers in both regular and private mode
|
|
521
|
+
return isWebKit() || isAndroid();
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
async function getBlockedSelectors<T extends string>(
|
|
525
|
+
selectors: readonly T[]
|
|
526
|
+
): Promise<{ [K in T]?: true }> {
|
|
527
|
+
const d = document;
|
|
528
|
+
const root = d.createElement("div");
|
|
529
|
+
const elements = new Array<HTMLElement>(selectors.length);
|
|
530
|
+
const blockedSelectors: { [K in T]?: true } = {}; // Set() isn't used just in case somebody need older browser support
|
|
531
|
+
|
|
532
|
+
forceShow(root);
|
|
533
|
+
|
|
534
|
+
// First create all elements that can be blocked. If the DOM steps below are done in a single cycle,
|
|
535
|
+
// browser will alternate tree modification and layout reading, that is very slow.
|
|
536
|
+
for (let i = 0; i < selectors.length; ++i) {
|
|
537
|
+
const element = selectorToElement(selectors[i]);
|
|
538
|
+
if (element.tagName === "DIALOG") {
|
|
539
|
+
(element as HTMLDialogElement).show();
|
|
540
|
+
}
|
|
541
|
+
const holder = d.createElement("div"); // Protects from unwanted effects of `+` and `~` selectors of filters
|
|
542
|
+
forceShow(holder);
|
|
543
|
+
holder.appendChild(element);
|
|
544
|
+
root.appendChild(holder);
|
|
545
|
+
elements[i] = element;
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
// document.body can be null while the page is loading
|
|
549
|
+
while (!d.body) {
|
|
550
|
+
await wait(50);
|
|
551
|
+
}
|
|
552
|
+
d.body.appendChild(root);
|
|
553
|
+
|
|
554
|
+
try {
|
|
555
|
+
// Then check which of the elements are blocked
|
|
556
|
+
for (let i = 0; i < selectors.length; ++i) {
|
|
557
|
+
if (!elements[i].offsetParent) {
|
|
558
|
+
blockedSelectors[selectors[i]] = true;
|
|
559
|
+
}
|
|
560
|
+
}
|
|
561
|
+
} finally {
|
|
562
|
+
// Then remove the elements
|
|
563
|
+
root.parentNode?.removeChild(root);
|
|
564
|
+
}
|
|
565
|
+
|
|
566
|
+
return blockedSelectors;
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
function forceShow(element: HTMLElement) {
|
|
570
|
+
element.style.setProperty("visibility", "hidden", "important");
|
|
571
|
+
element.style.setProperty("display", "block", "important");
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
includeComponent("domBlockers", getDomBlockers);
|
|
575
|
+
includeComponent("vendorFlavour", getVendorFlavors);
|
|
576
|
+
includeComponent("monochrome", getMonochromeDepth);
|
|
577
|
+
includeComponent("forcedColors", areColorsForced);
|
|
578
|
+
includeComponent("colorGamut", getColorGamut);
|
|
579
|
+
includeComponent("osCpu", getOsCpu);
|
|
580
|
+
includeComponent("audioLatency", getAudioContextBaseLatency);
|
|
581
|
+
|