@letsrunit/playwright 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +44 -0
- package/dist/index.d.ts +106 -0
- package/dist/index.js +3006 -0
- package/dist/index.js.map +1 -0
- package/package.json +67 -0
- package/src/browser.ts +20 -0
- package/src/field/calendar.ts +300 -0
- package/src/field/date-group.ts +253 -0
- package/src/field/date-text-input.ts +270 -0
- package/src/field/index.ts +57 -0
- package/src/field/native-checkbox.ts +21 -0
- package/src/field/native-date.ts +62 -0
- package/src/field/native-input.ts +17 -0
- package/src/field/native-select.ts +75 -0
- package/src/field/otp.ts +22 -0
- package/src/field/radio-group.ts +27 -0
- package/src/field/slider.ts +132 -0
- package/src/field/types.ts +16 -0
- package/src/format-html.ts +17 -0
- package/src/index.ts +12 -0
- package/src/locator.ts +102 -0
- package/src/page-info.ts +33 -0
- package/src/screenshot.ts +84 -0
- package/src/scroll.ts +10 -0
- package/src/scrub-html.ts +333 -0
- package/src/selector/date-selector.ts +272 -0
- package/src/selector/field-selector.ts +121 -0
- package/src/selector/index.ts +2 -0
- package/src/snapshot.ts +55 -0
- package/src/suppress-interferences.ts +288 -0
- package/src/translations/af.ts +41 -0
- package/src/translations/ar.ts +7 -0
- package/src/translations/az.ts +40 -0
- package/src/translations/bg.ts +7 -0
- package/src/translations/bn.ts +40 -0
- package/src/translations/bs.ts +7 -0
- package/src/translations/ca.ts +41 -0
- package/src/translations/cs.ts +7 -0
- package/src/translations/da.ts +44 -0
- package/src/translations/de.ts +47 -0
- package/src/translations/el.ts +40 -0
- package/src/translations/en.ts +7 -0
- package/src/translations/es.ts +7 -0
- package/src/translations/et.ts +7 -0
- package/src/translations/eu.ts +7 -0
- package/src/translations/fa.ts +7 -0
- package/src/translations/fi.ts +39 -0
- package/src/translations/fr.ts +42 -0
- package/src/translations/ga.ts +40 -0
- package/src/translations/he.ts +45 -0
- package/src/translations/hi.ts +39 -0
- package/src/translations/hr.ts +7 -0
- package/src/translations/hu.ts +7 -0
- package/src/translations/hy.ts +7 -0
- package/src/translations/id.ts +7 -0
- package/src/translations/index.ts +68 -0
- package/src/translations/is.ts +7 -0
- package/src/translations/it.ts +7 -0
- package/src/translations/ja.ts +7 -0
- package/src/translations/ka.ts +36 -0
- package/src/translations/ko.ts +7 -0
- package/src/translations/lt.ts +7 -0
- package/src/translations/lv.ts +43 -0
- package/src/translations/nl.ts +43 -0
- package/src/translations/no.ts +46 -0
- package/src/translations/pl.ts +39 -0
- package/src/translations/pt.ts +41 -0
- package/src/translations/ro.ts +40 -0
- package/src/translations/ru.ts +7 -0
- package/src/translations/sk.ts +7 -0
- package/src/translations/sl.ts +7 -0
- package/src/translations/sv.ts +44 -0
- package/src/translations/sw.ts +7 -0
- package/src/translations/ta.ts +7 -0
- package/src/translations/th.ts +39 -0
- package/src/translations/tl.ts +7 -0
- package/src/translations/tr.ts +41 -0
- package/src/translations/uk.ts +7 -0
- package/src/translations/ur.ts +43 -0
- package/src/translations/vi.ts +7 -0
- package/src/translations/zh.ts +7 -0
- package/src/types.ts +37 -0
- package/src/unified-html-diff.ts +22 -0
- package/src/utils/date.ts +40 -0
- package/src/utils/pick-field-element.ts +48 -0
- package/src/utils/type-check.ts +7 -0
- package/src/wait.ts +170 -0
|
@@ -0,0 +1,288 @@
|
|
|
1
|
+
import { sleep } from '@letsrunit/utils';
|
|
2
|
+
import type { Page } from '@playwright/test';
|
|
3
|
+
import { getTranslations } from './translations';
|
|
4
|
+
|
|
5
|
+
type Options = {
|
|
6
|
+
timeoutMs?: number; // max sweep time
|
|
7
|
+
preferReject?: boolean; // click "Reject"/"Decline" where possible
|
|
8
|
+
lang?: string; // Interface language, used for accept/reject/close button texts
|
|
9
|
+
pollIntervalMs?: number; // how often we probe when nothing happened
|
|
10
|
+
settleAfterActionMs?: number; // give the DOM time to settle after a click
|
|
11
|
+
quietPeriodMs?: number; // stop if nothing happened for this long
|
|
12
|
+
minSweepMs?: number; // always sweep at least this long (to catch late banners)
|
|
13
|
+
maxActions?: number; // safety: don't click forever on re-spawning modals
|
|
14
|
+
verbose?: boolean;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
interface TrRegExps {
|
|
18
|
+
accept: RegExp;
|
|
19
|
+
reject: RegExp;
|
|
20
|
+
close: RegExp;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const knownCMPSelectors: Array<{ name: string; accept: string[]; reject: string[] }> = [
|
|
24
|
+
{ name: 'OneTrust', accept: ['#onetrust-accept-btn-handler'], reject: ['#onetrust-reject-all-handler'] },
|
|
25
|
+
{
|
|
26
|
+
name: 'Cookiebot',
|
|
27
|
+
accept: ['#CybotCookiebotDialogBodyLevelButtonLevelOptinAllowAll'],
|
|
28
|
+
reject: ['#CybotCookiebotDialogBodyLevelButtonDecline'],
|
|
29
|
+
},
|
|
30
|
+
{ name: 'Didomi', accept: ['button.didomi-accept-all'], reject: ['button.didomi-reject-all'] },
|
|
31
|
+
{
|
|
32
|
+
name: 'Quantcast',
|
|
33
|
+
accept: ['button[qc-cmp2-action="accept_all"]'],
|
|
34
|
+
reject: ['button[qc-cmp2-action="reject_all"]'],
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
name: 'TrustArc',
|
|
38
|
+
accept: ['#truste-consent-button'],
|
|
39
|
+
reject: ['#truste-reject-button', '#truste-consent-required'],
|
|
40
|
+
},
|
|
41
|
+
{ name: 'Iubenda', accept: ['button.iubenda-cs-accept-btn'], reject: ['button.iubenda-cs-reject-btn'] },
|
|
42
|
+
{
|
|
43
|
+
name: 'CookieYes',
|
|
44
|
+
accept: ['#wt-cli-accept-all-btn', '#cookie_action_close_header'],
|
|
45
|
+
reject: ['#wt-cli-reject-btn'],
|
|
46
|
+
},
|
|
47
|
+
{ name: 'Osano', accept: ['.osano-cm-accept-all'], reject: ['.osano-cm-reject-all'] },
|
|
48
|
+
{ name: 'Klaro', accept: ['.cm-btn-accept'], reject: ['.cm-btn-decline'] },
|
|
49
|
+
];
|
|
50
|
+
|
|
51
|
+
function escapeRegex(text: string): string {
|
|
52
|
+
return text.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function normalizePhrase(p: string): string {
|
|
56
|
+
// collapse whitespace to \s+ to match various spacing and NBSPs
|
|
57
|
+
return escapeRegex(p.trim()).replace(/\s+/g, '\\s+');
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function buildRegexFromTranslations(phrases: string[], opts?: { anchorWhole?: boolean; flags?: string }): RegExp {
|
|
61
|
+
const unique = Array.from(new Set(phrases.map(normalizePhrase))).filter((s) => s.length > 0);
|
|
62
|
+
const body = unique.length ? unique.join('|') : '';
|
|
63
|
+
const source = opts?.anchorWhole ? `^(?:${body})$` : `(?:${body})`;
|
|
64
|
+
return new RegExp(source, opts?.flags ?? 'i');
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
async function tryClick(page: Page, selectors: string[], _label: string) {
|
|
68
|
+
for (const s of selectors) {
|
|
69
|
+
const el = page.locator(s).first();
|
|
70
|
+
if (await el.count().catch(() => 0)) {
|
|
71
|
+
try {
|
|
72
|
+
await el.scrollIntoViewIfNeeded({ timeout: 250 });
|
|
73
|
+
await el.click({ timeout: 500 });
|
|
74
|
+
return true;
|
|
75
|
+
} catch {}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
return false;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
async function closeNativeJsAlerts(page: Page) {
|
|
82
|
+
page.on('dialog', (d) => d.accept().catch(() => {}));
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// 1) Known cookie CMPs (quick wins)
|
|
86
|
+
async function sweepKnownCMPs(page: Page, preferReject: boolean): Promise<boolean> {
|
|
87
|
+
for (const cmp of knownCMPSelectors) {
|
|
88
|
+
if (preferReject && (await tryClick(page, cmp.reject, `${cmp.name} reject`))) return true;
|
|
89
|
+
if (await tryClick(page, cmp.accept, `${cmp.name} accept`)) return true;
|
|
90
|
+
if (!preferReject && (await tryClick(page, cmp.reject, `${cmp.name} reject`))) return true;
|
|
91
|
+
}
|
|
92
|
+
return false;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// 2) Role/text-based generic approach (works surprisingly often)
|
|
96
|
+
async function clickByRoleAndText(page: Page, preferReject: boolean, regex: TrRegExps): Promise<boolean> {
|
|
97
|
+
// Dialogs
|
|
98
|
+
const dialogs = page.getByRole('dialog');
|
|
99
|
+
if (await dialogs.count().catch(() => 0)) {
|
|
100
|
+
const target = preferReject
|
|
101
|
+
? dialogs.getByRole('button', { name: regex.reject }).first()
|
|
102
|
+
: dialogs.getByRole('button', { name: regex.accept }).first();
|
|
103
|
+
|
|
104
|
+
if (await target.count().catch(() => 0)) {
|
|
105
|
+
try {
|
|
106
|
+
await target.click({ timeout: 700 });
|
|
107
|
+
return true;
|
|
108
|
+
} catch {}
|
|
109
|
+
}
|
|
110
|
+
// fallback: any accept/reject in dialog
|
|
111
|
+
const any =
|
|
112
|
+
(await dialogs.getByRole('button', { name: regex.accept }).first().count()) ||
|
|
113
|
+
(await dialogs.getByRole('button', { name: regex.reject }).first().count());
|
|
114
|
+
if (any) {
|
|
115
|
+
try {
|
|
116
|
+
const btn = dialogs.getByRole('button', { name: regex.accept }).first();
|
|
117
|
+
await ((await btn.count()) ? btn : dialogs.getByRole('button', { name: regex.reject }).first()).click({
|
|
118
|
+
timeout: 700,
|
|
119
|
+
});
|
|
120
|
+
return true;
|
|
121
|
+
} catch {}
|
|
122
|
+
}
|
|
123
|
+
// close-icon
|
|
124
|
+
const close = dialogs.getByRole('button', { name: regex.close }).first();
|
|
125
|
+
if (await close.count().catch(() => 0)) {
|
|
126
|
+
try {
|
|
127
|
+
await close.click({ timeout: 700 });
|
|
128
|
+
return true;
|
|
129
|
+
} catch {}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// Random buttons (no dialog role)
|
|
134
|
+
const generic = page.getByRole('button', { name: preferReject ? regex.reject : regex.accept }).first();
|
|
135
|
+
if (await generic.count().catch(() => 0)) {
|
|
136
|
+
try {
|
|
137
|
+
await generic.click({ timeout: 700 });
|
|
138
|
+
return true;
|
|
139
|
+
} catch {}
|
|
140
|
+
}
|
|
141
|
+
return false;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// 3) Heuristic for “promo/newsletter” modals (email field + close button)
|
|
145
|
+
async function sweepNewsletter(page: Page, regex: TrRegExps): Promise<boolean> {
|
|
146
|
+
const modalLike = page.locator('*:visible').filter({
|
|
147
|
+
has: page.locator('input[type="email"],input[placeholder*="email" i]'),
|
|
148
|
+
});
|
|
149
|
+
if (await modalLike.count().catch(() => 0)) {
|
|
150
|
+
const close = modalLike.getByRole('button', { name: regex.close }).first();
|
|
151
|
+
if (await close.count().catch(() => 0)) {
|
|
152
|
+
try {
|
|
153
|
+
await close.click({ timeout: 700 });
|
|
154
|
+
return true;
|
|
155
|
+
} catch {}
|
|
156
|
+
}
|
|
157
|
+
// click outside the modal (overlay)
|
|
158
|
+
const overlay = page.locator('div[role="presentation"], .modal-backdrop, .overlay, .ReactModal__Overlay');
|
|
159
|
+
if (await overlay.count().catch(() => 0)) {
|
|
160
|
+
try {
|
|
161
|
+
await overlay.first().click({ timeout: 500, position: { x: 5, y: 5 } });
|
|
162
|
+
return true;
|
|
163
|
+
} catch {}
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
return false;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
// 4) Full-screen overlay heuristic (fixed + large + high z-index)
|
|
170
|
+
async function sweepOverlays(page: Page, regex: TrRegExps): Promise<boolean> {
|
|
171
|
+
const acceptRxSource = regex.accept.source; // serialize for page.evaluate closure safety
|
|
172
|
+
const acceptRxFlags = regex.accept.flags;
|
|
173
|
+
|
|
174
|
+
return await page
|
|
175
|
+
.evaluate(
|
|
176
|
+
([source, flags]) => {
|
|
177
|
+
const acceptRx = new RegExp(source, flags);
|
|
178
|
+
const isBig = (el: Element) => {
|
|
179
|
+
const r = (el as HTMLElement).getBoundingClientRect?.();
|
|
180
|
+
return r && r.width > window.innerWidth * 0.6 && r.height > window.innerHeight * 0.4;
|
|
181
|
+
};
|
|
182
|
+
const candidates = Array.from(document.querySelectorAll<HTMLElement>('body *'))
|
|
183
|
+
.filter((el) => {
|
|
184
|
+
const s = getComputedStyle(el);
|
|
185
|
+
if (!s) return false;
|
|
186
|
+
const fixed = s.position === 'fixed' || s.position === 'sticky';
|
|
187
|
+
const z = parseInt(s.zIndex || '0', 10);
|
|
188
|
+
return fixed && z >= 1000 && isBig(el) && (el as HTMLElement).offsetParent !== null;
|
|
189
|
+
})
|
|
190
|
+
.slice(0, 5);
|
|
191
|
+
|
|
192
|
+
for (const el of candidates) {
|
|
193
|
+
// try a close button inside
|
|
194
|
+
const btn = el.querySelector<HTMLElement>(
|
|
195
|
+
'[aria-label*="close" i], button[aria-label*="close" i], button:has(svg), .close, [data-close], .btn-close',
|
|
196
|
+
);
|
|
197
|
+
|
|
198
|
+
if (btn) {
|
|
199
|
+
btn.click();
|
|
200
|
+
return true;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
// otherwise: click a visible “accept/agree/ok”
|
|
204
|
+
const clickByText = (rx: RegExp) => {
|
|
205
|
+
const walker = document.createTreeWalker(el, NodeFilter.SHOW_ELEMENT);
|
|
206
|
+
let n: Node | null;
|
|
207
|
+
while ((n = walker.nextNode())) {
|
|
208
|
+
const e = n as HTMLElement;
|
|
209
|
+
if (!e) continue;
|
|
210
|
+
if (!(e as HTMLElement).offsetParent) continue;
|
|
211
|
+
const text = (e as HTMLElement).innerText?.trim();
|
|
212
|
+
|
|
213
|
+
if (text && rx.test(text)) {
|
|
214
|
+
(e as HTMLElement).click();
|
|
215
|
+
return true;
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
return false;
|
|
219
|
+
};
|
|
220
|
+
if (clickByText(acceptRx)) return true;
|
|
221
|
+
}
|
|
222
|
+
return false;
|
|
223
|
+
},
|
|
224
|
+
[acceptRxSource, acceptRxFlags],
|
|
225
|
+
)
|
|
226
|
+
.catch(() => false);
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
export async function suppressInterferences(page: Page, opts: Options = {}) {
|
|
230
|
+
const timeoutMs = opts.timeoutMs ?? 4000;
|
|
231
|
+
const preferReject = opts.preferReject ?? false;
|
|
232
|
+
|
|
233
|
+
const pollIntervalMs = opts.pollIntervalMs ?? 120;
|
|
234
|
+
const settleAfterActionMs = opts.settleAfterActionMs ?? 500;
|
|
235
|
+
const quietPeriodMs = opts.quietPeriodMs ?? 800;
|
|
236
|
+
const minSweepMs = opts.minSweepMs ?? 500;
|
|
237
|
+
const maxActions = opts.maxActions ?? 6;
|
|
238
|
+
|
|
239
|
+
// Build regexes from translations so callers can provide i18n
|
|
240
|
+
const { accept, reject, close } = getTranslations(opts.lang ?? 'en');
|
|
241
|
+
const regex = {
|
|
242
|
+
accept: buildRegexFromTranslations(accept, { anchorWhole: true }),
|
|
243
|
+
reject: buildRegexFromTranslations(reject, { anchorWhole: true }),
|
|
244
|
+
close: buildRegexFromTranslations(close, { anchorWhole: false }),
|
|
245
|
+
};
|
|
246
|
+
|
|
247
|
+
await closeNativeJsAlerts(page);
|
|
248
|
+
|
|
249
|
+
let actions = 0;
|
|
250
|
+
const startedAt = Date.now();
|
|
251
|
+
let lastActivityAt = startedAt;
|
|
252
|
+
|
|
253
|
+
while (Date.now() < lastActivityAt + timeoutMs) {
|
|
254
|
+
// Try sweepers (short-circuit on first success)
|
|
255
|
+
const did =
|
|
256
|
+
(await sweepKnownCMPs(page, preferReject)) ||
|
|
257
|
+
(await clickByRoleAndText(page, preferReject, regex)) ||
|
|
258
|
+
(await sweepNewsletter(page, regex)) ||
|
|
259
|
+
(await sweepOverlays(page, regex));
|
|
260
|
+
|
|
261
|
+
if (did) {
|
|
262
|
+
actions += 1;
|
|
263
|
+
lastActivityAt = Date.now();
|
|
264
|
+
|
|
265
|
+
// Optional: bail if we are hitting a loop of re-spawning popups
|
|
266
|
+
if (actions >= maxActions) {
|
|
267
|
+
if (opts.verbose) console.log(`[suppressInterferences] Max actions ${maxActions} reached, stopping.`);
|
|
268
|
+
break;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
// Let the DOM settle; some UIs spawn a second layer after the first click
|
|
272
|
+
await sleep(settleAfterActionMs);
|
|
273
|
+
continue;
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
// Nothing clicked this iteration — if we've been quiet long enough (and passed a minimum sweep window), stop early
|
|
277
|
+
const quietFor = Date.now() - lastActivityAt;
|
|
278
|
+
const ranFor = Date.now() - startedAt;
|
|
279
|
+
|
|
280
|
+
if (quietFor >= quietPeriodMs && ranFor >= minSweepMs) {
|
|
281
|
+
if (opts.verbose) console.log(`[suppressInterferences] Quiet for ${quietFor}ms, stopping early.`);
|
|
282
|
+
break;
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
// Brief pause before probing again
|
|
286
|
+
await sleep(pollIntervalMs);
|
|
287
|
+
}
|
|
288
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
const translations = {
|
|
2
|
+
accept: [
|
|
3
|
+
"Aanvaar",
|
|
4
|
+
"Aanvaar alles",
|
|
5
|
+
"Stem saam",
|
|
6
|
+
"Laat toe",
|
|
7
|
+
"Laat alles toe",
|
|
8
|
+
"OK",
|
|
9
|
+
"Reg so",
|
|
10
|
+
"Ek verstaan",
|
|
11
|
+
"Gaan voort",
|
|
12
|
+
"Stoor en aanvaar",
|
|
13
|
+
"Bevestig"
|
|
14
|
+
],
|
|
15
|
+
reject: [
|
|
16
|
+
"Verwerp",
|
|
17
|
+
"Verwerp alles",
|
|
18
|
+
"Weier",
|
|
19
|
+
"Moenie toelaat nie",
|
|
20
|
+
"Slegs noodsaaklik",
|
|
21
|
+
"Net noodsaaklike koekies",
|
|
22
|
+
"Gaan voort sonder koekies",
|
|
23
|
+
"Nee dankie",
|
|
24
|
+
"Moenie aanvaar nie",
|
|
25
|
+
"Weier alles"
|
|
26
|
+
],
|
|
27
|
+
close: [
|
|
28
|
+
"Sluit",
|
|
29
|
+
"Kanselleer",
|
|
30
|
+
"Maak toe",
|
|
31
|
+
"Verwyder",
|
|
32
|
+
"Nie nou nie",
|
|
33
|
+
"Nee dankie",
|
|
34
|
+
"Later",
|
|
35
|
+
"×",
|
|
36
|
+
"Slaan oor",
|
|
37
|
+
"Maak venster toe"
|
|
38
|
+
]
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
export default translations;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
const translations = {
|
|
2
|
+
accept: ["موافق", "أوافق", "قبول", "قبول الكل", "الموافقة على الكل", "السماح", "حسنًا", "تم", "تمام", "متابعة", "تابع", "حفظ والموافقة", "حفظ والقبول"],
|
|
3
|
+
reject: ["رفض", "رفض الكل", "عدم الموافقة", "عدم السماح", "الضرورية فقط", "الأساسية فقط", "المتابعة بدون ملفات تعريف الارتباط", "الاستمرار بدون ملفات تعريف الارتباط", "لا شكرًا", "لا، شكرًا"],
|
|
4
|
+
close: ["إغلاق", "إلغاء", "تجاهل", "ليس الآن", "لا شكرًا", "لاحقًا", "×", "إخفاء", "تخطي"]
|
|
5
|
+
};
|
|
6
|
+
|
|
7
|
+
export default translations;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
const translations = {
|
|
2
|
+
accept: [
|
|
3
|
+
"Qəbul et",
|
|
4
|
+
"Hamısını qəbul et",
|
|
5
|
+
"Razıyam",
|
|
6
|
+
"Təsdiq et",
|
|
7
|
+
"İcazə ver",
|
|
8
|
+
"Hamısına icazə ver",
|
|
9
|
+
"OK",
|
|
10
|
+
"Oldu",
|
|
11
|
+
"Başa düşdüm",
|
|
12
|
+
"Anladım",
|
|
13
|
+
"Davam et",
|
|
14
|
+
"Saxla və qəbul et"
|
|
15
|
+
],
|
|
16
|
+
reject: [
|
|
17
|
+
"Rədd et",
|
|
18
|
+
"Hamısını rədd et",
|
|
19
|
+
"İmtina et",
|
|
20
|
+
"İcazə vermə",
|
|
21
|
+
"Yalnız zəruri kukilər",
|
|
22
|
+
"Yalnız zəruri",
|
|
23
|
+
"Kukilərsiz davam et",
|
|
24
|
+
"Heç birinə icazə vermə",
|
|
25
|
+
"Qəbul etmirəm",
|
|
26
|
+
"Yox, sağ olun"
|
|
27
|
+
],
|
|
28
|
+
close: [
|
|
29
|
+
"Bağla",
|
|
30
|
+
"Ləğv et",
|
|
31
|
+
"Geri",
|
|
32
|
+
"Keç",
|
|
33
|
+
"İndi yox",
|
|
34
|
+
"Sonra",
|
|
35
|
+
"Yox, sağ olun",
|
|
36
|
+
"×"
|
|
37
|
+
]
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
export default translations;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
const translations = {
|
|
2
|
+
accept: ["Приеми", "Приеми всички", "Съгласявам се", "Съгласен съм", "Разреши", "Разреши всички", "ОК", "Добре", "Разбрах", "Продължи", "Запази и приеми", "Да, приемам"],
|
|
3
|
+
reject: ["Откажи", "Откажи всички", "Отказвам", "Отхвърли", "Само необходимите", "Само задължителните", "Само основните", "Продължи без бисквитки", "Не, благодаря", "Забрани", "Забрани всички", "Не позволявам"],
|
|
4
|
+
close: ["Затвори", "Отказ", "Отмени", "Скрий", "Не сега", "По-късно", "Не, благодаря", "Готово", "×"]
|
|
5
|
+
};
|
|
6
|
+
|
|
7
|
+
export default translations;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
const translations = {
|
|
2
|
+
accept: [
|
|
3
|
+
"স্বীকার করুন",
|
|
4
|
+
"সব স্বীকার করুন",
|
|
5
|
+
"সম্মতি দিচ্ছি",
|
|
6
|
+
"সম্মত",
|
|
7
|
+
"অনুমতি দিন",
|
|
8
|
+
"সব অনুমতি দিন",
|
|
9
|
+
"ঠিক আছে",
|
|
10
|
+
"বোঝা গেল",
|
|
11
|
+
"চালিয়ে যান",
|
|
12
|
+
"সংরক্ষণ করে স্বীকার",
|
|
13
|
+
"সেভ করে চালিয়ে যান",
|
|
14
|
+
"আমি রাজি"
|
|
15
|
+
],
|
|
16
|
+
reject: [
|
|
17
|
+
"প্রত্যাখ্যান করুন",
|
|
18
|
+
"সব প্রত্যাখ্যান করুন",
|
|
19
|
+
"নামঞ্জুর",
|
|
20
|
+
"অনুমতি দেব না",
|
|
21
|
+
"শুধু প্রয়োজনীয়",
|
|
22
|
+
"শুধুমাত্র দরকারি",
|
|
23
|
+
"কুকি ছাড়াই চালিয়ে যান",
|
|
24
|
+
"না, ধন্যবাদ",
|
|
25
|
+
"না",
|
|
26
|
+
"সম্মতি দিচ্ছি না"
|
|
27
|
+
],
|
|
28
|
+
close: [
|
|
29
|
+
"বন্ধ করুন",
|
|
30
|
+
"বাতিল",
|
|
31
|
+
"ক্যান্সেল",
|
|
32
|
+
"এখন নয়",
|
|
33
|
+
"পরে",
|
|
34
|
+
"না, ধন্যবাদ",
|
|
35
|
+
"দেখেছি",
|
|
36
|
+
"×"
|
|
37
|
+
]
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
export default translations;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
const translations = {
|
|
2
|
+
accept: ["Prihvati", "Prihvati sve", "Slažem se", "Dozvoli", "Dozvoli sve", "U redu", "OK", "Razumijem", "Nastavi", "Sačuvaj i prihvati", "Potvrdi", "Prihvati i nastavi"],
|
|
3
|
+
reject: ["Odbij", "Odbij sve", "Ne prihvatam", "Ne dozvoli", "Samo neophodni", "Samo obavezni", "Nastavi bez kolačića", "Ne, hvala", "Onemogući sve"],
|
|
4
|
+
close: ["Zatvori", "Otkaži", "Odustani", "Odbaci", "Ne sada", "Ne, hvala", "Kasnije", "×"]
|
|
5
|
+
};
|
|
6
|
+
|
|
7
|
+
export default translations;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
const translations = {
|
|
2
|
+
accept: [
|
|
3
|
+
"Acceptar",
|
|
4
|
+
"Acceptar-ho tot",
|
|
5
|
+
"D'acord",
|
|
6
|
+
"Permetre",
|
|
7
|
+
"Permetre-ho tot",
|
|
8
|
+
"OK",
|
|
9
|
+
"Entesos",
|
|
10
|
+
"Ho entenc",
|
|
11
|
+
"Continuar",
|
|
12
|
+
"Desa i accepta",
|
|
13
|
+
"Sí, accepto"
|
|
14
|
+
],
|
|
15
|
+
reject: [
|
|
16
|
+
"Rebutjar",
|
|
17
|
+
"Rebutjar-ho tot",
|
|
18
|
+
"Denegar",
|
|
19
|
+
"No permetre",
|
|
20
|
+
"Només les necessàries",
|
|
21
|
+
"Només essencials",
|
|
22
|
+
"Continuar sense galetes",
|
|
23
|
+
"No, gràcies",
|
|
24
|
+
"Desactivar totes",
|
|
25
|
+
"Continuar sense acceptar"
|
|
26
|
+
],
|
|
27
|
+
close: [
|
|
28
|
+
"Tancar",
|
|
29
|
+
"Cancel·lar",
|
|
30
|
+
"Descartar",
|
|
31
|
+
"Ara no",
|
|
32
|
+
"No, gràcies",
|
|
33
|
+
"Més tard",
|
|
34
|
+
"×",
|
|
35
|
+
"Tanca la finestra",
|
|
36
|
+
"Ometre",
|
|
37
|
+
"Fer-ho més tard"
|
|
38
|
+
]
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
export default translations;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
const translations = {
|
|
2
|
+
accept: ["Přijmout", "Přijmout vše", "Souhlasím", "Povolit", "Povolit vše", "OK", "Rozumím", "Pokračovat", "Uložit a přijmout", "Potvrdit"],
|
|
3
|
+
reject: ["Odmítnout", "Odmítnout vše", "Nesouhlasím", "Nepovolovat", "Pouze nezbytné", "Jen nezbytné", "Pouze nutné cookies", "Pouze základní", "Pokračovat bez cookies", "Ne, díky"],
|
|
4
|
+
close: ["Zavřít", "Zrušit", "Skrýt", "Ne teď", "Později", "Ne, díky", "×"]
|
|
5
|
+
};
|
|
6
|
+
|
|
7
|
+
export default translations;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
const translations = {
|
|
2
|
+
accept: [
|
|
3
|
+
"accepter",
|
|
4
|
+
"accepter alle",
|
|
5
|
+
"accepter alle cookies",
|
|
6
|
+
"godkend",
|
|
7
|
+
"tillad",
|
|
8
|
+
"tillad alle",
|
|
9
|
+
"ok",
|
|
10
|
+
"okay",
|
|
11
|
+
"forstået",
|
|
12
|
+
"fortsæt",
|
|
13
|
+
"gå videre",
|
|
14
|
+
"gem og accepter",
|
|
15
|
+
"gem indstillinger",
|
|
16
|
+
"accepter valg"
|
|
17
|
+
],
|
|
18
|
+
reject: [
|
|
19
|
+
"afvis",
|
|
20
|
+
"afvis alle",
|
|
21
|
+
"afvis alle cookies",
|
|
22
|
+
"afslå",
|
|
23
|
+
"tillad ikke",
|
|
24
|
+
"kun nødvendige",
|
|
25
|
+
"kun nødvendige cookies",
|
|
26
|
+
"kun påkrævede",
|
|
27
|
+
"fortsæt uden cookies",
|
|
28
|
+
"nej tak",
|
|
29
|
+
"begræns til nødvendige"
|
|
30
|
+
],
|
|
31
|
+
close: [
|
|
32
|
+
"luk",
|
|
33
|
+
"annuller",
|
|
34
|
+
"skjul",
|
|
35
|
+
"ikke nu",
|
|
36
|
+
"nej tak",
|
|
37
|
+
"senere",
|
|
38
|
+
"×",
|
|
39
|
+
"måske senere",
|
|
40
|
+
"luk besked"
|
|
41
|
+
]
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
export default translations;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
const translations = {
|
|
2
|
+
accept: [
|
|
3
|
+
"Akzeptieren",
|
|
4
|
+
"Alle akzeptieren",
|
|
5
|
+
"Zustimmen",
|
|
6
|
+
"Ich stimme zu",
|
|
7
|
+
"Erlauben",
|
|
8
|
+
"Alle erlauben",
|
|
9
|
+
"Zulassen",
|
|
10
|
+
"Alles zulassen",
|
|
11
|
+
"OK",
|
|
12
|
+
"Okay",
|
|
13
|
+
"Verstanden",
|
|
14
|
+
"Weiter",
|
|
15
|
+
"Speichern & akzeptieren",
|
|
16
|
+
"Speichern und fortfahren",
|
|
17
|
+
"Alles klar"
|
|
18
|
+
],
|
|
19
|
+
reject: [
|
|
20
|
+
"Ablehnen",
|
|
21
|
+
"Alle ablehnen",
|
|
22
|
+
"Nicht erlauben",
|
|
23
|
+
"Nicht zustimmen",
|
|
24
|
+
"Nur notwendige",
|
|
25
|
+
"Nur notwendige Cookies",
|
|
26
|
+
"Nur essenzielle",
|
|
27
|
+
"Nur erforderliche",
|
|
28
|
+
"Ohne Cookies fortfahren",
|
|
29
|
+
"Nein danke",
|
|
30
|
+
"Zugriff verweigern",
|
|
31
|
+
"Ablehnen und schließen"
|
|
32
|
+
],
|
|
33
|
+
close: [
|
|
34
|
+
"Schließen",
|
|
35
|
+
"Abbrechen",
|
|
36
|
+
"Ausblenden",
|
|
37
|
+
"Jetzt nicht",
|
|
38
|
+
"Nein danke",
|
|
39
|
+
"Später",
|
|
40
|
+
"×",
|
|
41
|
+
"Fenster schließen",
|
|
42
|
+
"Verwerfen",
|
|
43
|
+
"Zurück"
|
|
44
|
+
]
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
export default translations;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
const translations = {
|
|
2
|
+
accept: [
|
|
3
|
+
"Αποδοχή",
|
|
4
|
+
"Αποδοχή όλων",
|
|
5
|
+
"Συμφωνώ",
|
|
6
|
+
"Εντάξει",
|
|
7
|
+
"ΟΚ",
|
|
8
|
+
"Το κατάλαβα",
|
|
9
|
+
"Συνέχεια",
|
|
10
|
+
"Επιτρέπω",
|
|
11
|
+
"Επιτρέπω όλα",
|
|
12
|
+
"Αποθήκευση και αποδοχή",
|
|
13
|
+
"Προχώρησε"
|
|
14
|
+
],
|
|
15
|
+
reject: [
|
|
16
|
+
"Απόρριψη",
|
|
17
|
+
"Απόρριψη όλων",
|
|
18
|
+
"Άρνηση",
|
|
19
|
+
"Μη αποδοχή",
|
|
20
|
+
"Μόνο τα απαραίτητα",
|
|
21
|
+
"Μόνο τα αναγκαία",
|
|
22
|
+
"Συνέχεια χωρίς cookies",
|
|
23
|
+
"Χωρίς cookies",
|
|
24
|
+
"Όχι, ευχαριστώ"
|
|
25
|
+
],
|
|
26
|
+
close: [
|
|
27
|
+
"Κλείσιμο",
|
|
28
|
+
"Κλείσε",
|
|
29
|
+
"Άκυρο",
|
|
30
|
+
"Ακύρωση",
|
|
31
|
+
"Παράβλεψη",
|
|
32
|
+
"Όχι τώρα",
|
|
33
|
+
"Αργότερα",
|
|
34
|
+
"Επιστροφή",
|
|
35
|
+
"×",
|
|
36
|
+
"Χ"
|
|
37
|
+
]
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
export default translations;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
const translations = {
|
|
2
|
+
accept: ["accept", "accept all", "agree", "allow", "allow all", "ok", "okay", "got it", "continue", "save & accept"],
|
|
3
|
+
reject: ["reject", "reject all", "decline", "deny", "only necessary", "necessary only", "only essential", "essential only", "continue without cookies", "no thanks"],
|
|
4
|
+
close: ["close", "cancel", "dismiss", "not now", "no thanks", "later", "×"]
|
|
5
|
+
};
|
|
6
|
+
|
|
7
|
+
export default translations;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
const translations = {
|
|
2
|
+
accept: ["Aceptar", "Aceptar todo", "Estoy de acuerdo", "Permitir", "Permitir todo", "OK", "De acuerdo", "Entendido", "Continuar", "Guardar y aceptar", "Sí, acepto"],
|
|
3
|
+
reject: ["Rechazar", "Rechazar todo", "Denegar", "No permitir", "Solo las necesarias", "Solo lo esencial", "Continuar sin cookies", "No, gracias", "Seguir sin aceptar", "No aceptar"],
|
|
4
|
+
close: ["Cerrar", "Cancelar", "Descartar", "Ahora no", "No, gracias", "Más tarde", "×", "Omitir", "Ignorar", "Volver"]
|
|
5
|
+
};
|
|
6
|
+
|
|
7
|
+
export default translations;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
const translations = {
|
|
2
|
+
accept: ["Nõustun", "Olen nõus", "Luba kõik", "Luba", "OK", "Olgu", "Sain aru", "Jätka", "Salvesta ja nõustu", "Kinnita"],
|
|
3
|
+
reject: ["Keeldu", "Keeldu kõigist küpsistest", "Ära luba", "Ainult vajalikud", "Vaid hädavajalikud", "Jätka ilma küpsisteta", "Ei, aitäh", "Ära salvesta"],
|
|
4
|
+
close: ["Sulge", "Tühista", "Loobu", "Mitte praegu", "Ei, aitäh", "Hiljem", "Pane kinni", "×"]
|
|
5
|
+
};
|
|
6
|
+
|
|
7
|
+
export default translations;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
const translations = {
|
|
2
|
+
accept: ["Onartu", "Guztiak onartu", "Ados", "Baimendu", "Guztiak baimendu", "Ulertuta", "Jarraitu", "Onartzen dut", "Gorde eta onartu", "OK"],
|
|
3
|
+
reject: ["Ez onartu", "Guztiak ukatu", "Ukatu", "Ez baimendu", "Ezeztatu", "Beharrezkoak bakarrik", "Funtsezkoak bakarrik", "Cookie-rik gabe jarraitu", "Onartu gabe jarraitu", "Ez, eskerrik asko"],
|
|
4
|
+
close: ["Itxi", "Ezeztatu", "Baztertu", "Orain ez", "Ez, eskerrik asko", "Geroago", "Utzi", "×"]
|
|
5
|
+
};
|
|
6
|
+
|
|
7
|
+
export default translations;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
const translations = {
|
|
2
|
+
accept: ["پذیرفتن", "پذیرفتن همه", "قبول میکنم", "موافقم", "اجازه میدهم", "باشه", "تأیید", "ادامه", "ذخیره و پذیرش", "تأیید و ادامه"],
|
|
3
|
+
reject: ["رد کردن", "رد همه", "عدم پذیرش", "اجازه نمیدهم", "فقط ضروریها", "فقط موارد لازم", "ادامه بدون کوکی", "بدون کوکی ادامه بده", "نه، ممنون", "نمیخواهم", "نپذیرفتن"],
|
|
4
|
+
close: ["بستن", "لغو", "انصراف", "الان نه", "فعلاً نه", "بعداً", "×", "بازگشت", "خروج"]
|
|
5
|
+
};
|
|
6
|
+
|
|
7
|
+
export default translations;
|