@blakfy/cookie 2.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/ARCHITECTURE.md +186 -0
- package/CHANGELOG.md +107 -0
- package/COMPLIANCE.md +191 -0
- package/LICENSE +21 -0
- package/MIGRATION.md +156 -0
- package/README.md +480 -0
- package/TCF-CERTIFICATION.md +106 -0
- package/dist/cookie-defaults.js +76 -0
- package/dist/cookie-defaults.js.LEGAL.txt +0 -0
- package/dist/cookie-defaults.min.js +10 -0
- package/dist/cookie-defaults.min.js.LEGAL.txt +0 -0
- package/dist/cookie.js +3998 -0
- package/dist/cookie.js.LEGAL.txt +0 -0
- package/dist/cookie.js.map +7 -0
- package/dist/cookie.min.js +10 -0
- package/dist/cookie.min.js.LEGAL.txt +0 -0
- package/package.json +60 -0
package/README.md
ADDED
|
@@ -0,0 +1,480 @@
|
|
|
1
|
+
# Blakfy Cookie Widget
|
|
2
|
+
|
|
3
|
+
>     
|
|
4
|
+
>
|
|
5
|
+
> Tek script ile **KVKK + GDPR + CCPA + Google CMv2 + Microsoft UET + Yandex Metrica + IAB TCF v2.2** uyumlu cookie consent (çerez onayı) widget. **23 dil**, **18 hazır preset** (üçüncü parti araç entegrasyonu), **3 renk teması**, **3-tab tercihler modalı** (Kategoriler / Hizmetler / Hakkında), **tag-gating** (script engelleme/serbest bırakma) dahil.
|
|
6
|
+
|
|
7
|
+
**Versiyon:** 2.1.0 • **Lisans:** MIT • **CDN:** `cdn.jsdelivr.net/gh/tariktunc/blakfy-cookie@v2` • **npm:** `@blakfy/cookie-next@2`
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## Quick Start (3 adım)
|
|
12
|
+
|
|
13
|
+
### 1. Bootstrap (head içine, ilk script olarak)
|
|
14
|
+
|
|
15
|
+
`<head>` bloğuna **en üst sıraya** koy. GTM/GA4/Pixel'den **önce** yüklenmeli — onların default `denied` durumunda başlamasını sağlar (Google Consent Mode v2 + Microsoft UET).
|
|
16
|
+
|
|
17
|
+
```html
|
|
18
|
+
<!-- Bootstrap: Tüm consent sinyallerini 'denied' olarak başlatır -->
|
|
19
|
+
<script src="https://cdn.jsdelivr.net/gh/tariktunc/blakfy-cookie@v2/dist/cookie-defaults.min.js"></script>
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
### 2. Site içerik script'lerin (GTM/GA4/Pixel/Clarity vb.)
|
|
23
|
+
|
|
24
|
+
Bunlar olduğu gibi kalır. Bootstrap zaten consent default'larını `denied` olarak set etti, dolayısıyla bu tag'ler kullanıcı onay verene kadar cookie yazmaz.
|
|
25
|
+
|
|
26
|
+
```html
|
|
27
|
+
<!-- Örnek: Google Tag Manager (değişiklik gerektirmez) -->
|
|
28
|
+
<script>
|
|
29
|
+
(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
|
|
30
|
+
new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
|
|
31
|
+
j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
|
|
32
|
+
'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
|
|
33
|
+
})(window,document,'script','dataLayer','GTM-XXXXXX');
|
|
34
|
+
</script>
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
### 3. Widget (body sonu, `</body>`'den önce)
|
|
38
|
+
|
|
39
|
+
```html
|
|
40
|
+
<script
|
|
41
|
+
src="https://cdn.jsdelivr.net/gh/tariktunc/blakfy-cookie@v2/dist/cookie.min.js"
|
|
42
|
+
data-blakfy-locale="auto"
|
|
43
|
+
data-blakfy-policy-url="/cerez-politikasi"
|
|
44
|
+
data-blakfy-version="1.0"
|
|
45
|
+
data-blakfy-presets="ga4,gtm,facebook,clarity"
|
|
46
|
+
data-blakfy-ccpa="auto"
|
|
47
|
+
data-blakfy-tcf="false"
|
|
48
|
+
data-blakfy-position="bottom-right"
|
|
49
|
+
data-blakfy-theme="auto"
|
|
50
|
+
data-blakfy-accent="#3E5C3A"></script>
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
**Bittiğinde:** Sayfa yüklendiğinde sağ alt köşede consent banner ve "Powered by Blakfy Studio" badge belirir. Kullanıcı bir karar verene kadar GTM/GA4/Facebook Pixel/Clarity tag'leri çalışmaz; karar verildiğinde otomatik aktif olur.
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
## Senaryolar
|
|
58
|
+
|
|
59
|
+
### Vanilla HTML / WordPress / Shopify
|
|
60
|
+
|
|
61
|
+
Yukarıdaki 3 adımı `<head>` ve `</body>` öncesine yapıştır. Çalışır. Tam çalışan örnek için: [`examples/vanilla-html.html`](./examples/vanilla-html.html).
|
|
62
|
+
|
|
63
|
+
WordPress için PHP snippet: [`examples/wordpress-snippet.php`](./examples/wordpress-snippet.php).
|
|
64
|
+
|
|
65
|
+
Shopify için: theme `theme.liquid` dosyasının `<head>` ve `</body>` öncesi noktalarına aynı 3 adım eklenir. Ek bir paket gerekmez.
|
|
66
|
+
|
|
67
|
+
### Next.js 14+ (önerilen — App Router)
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
npm install @blakfy/cookie-next@2
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
`app/layout.tsx`:
|
|
74
|
+
|
|
75
|
+
```tsx
|
|
76
|
+
import { BlakfyCookieProvider, ConsentModeDefault } from "@blakfy/cookie-next";
|
|
77
|
+
|
|
78
|
+
export default function RootLayout({ children }: { children: React.ReactNode }) {
|
|
79
|
+
return (
|
|
80
|
+
<html lang="tr">
|
|
81
|
+
<head>
|
|
82
|
+
{/* Bootstrap: GCM/UET/Yandex default denied */}
|
|
83
|
+
<ConsentModeDefault />
|
|
84
|
+
</head>
|
|
85
|
+
<body>
|
|
86
|
+
<BlakfyCookieProvider
|
|
87
|
+
locale="auto"
|
|
88
|
+
policyUrl="/cerez-politikasi"
|
|
89
|
+
policyVersion="1.0"
|
|
90
|
+
presets="ga4,gtm,facebook,clarity"
|
|
91
|
+
ccpa="auto"
|
|
92
|
+
tcf={false}
|
|
93
|
+
position="bottom-right"
|
|
94
|
+
theme="auto"
|
|
95
|
+
accent="#3E5C3A"
|
|
96
|
+
>
|
|
97
|
+
{children}
|
|
98
|
+
</BlakfyCookieProvider>
|
|
99
|
+
</body>
|
|
100
|
+
</html>
|
|
101
|
+
);
|
|
102
|
+
}
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
Tam Next.js örneği: [`examples/nextjs/`](./examples/nextjs/).
|
|
106
|
+
Paket README'si: [`packages/cookie-next/README.md`](./packages/cookie-next/README.md).
|
|
107
|
+
|
|
108
|
+
### GTM ile birlikte
|
|
109
|
+
|
|
110
|
+
GTM, default `denied` ile başlar (bootstrap sayesinde). Trigger'larında "Consent State" şartı eklemen yeterli — Tag → "Consent settings" → "Require additional consent for tag firing" → ilgili kategoriler (örn. `analytics_storage` veya `ad_storage`). Kullanıcı kabul edince `gtag('consent','update', ...)` otomatik çağrılır ve tag'ler kendiliğinden tetiklenir.
|
|
111
|
+
|
|
112
|
+
```js
|
|
113
|
+
// Doğrulama (DevTools console)
|
|
114
|
+
window.dataLayer.find(e => e[0] === 'consent');
|
|
115
|
+
// → ["consent", "default", { ad_storage: "denied", ... }]
|
|
116
|
+
window.BlakfyCookie.acceptAll();
|
|
117
|
+
// → ["consent", "update", { ad_storage: "granted", ... }]
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
### Bing Ads (Microsoft UET) ile
|
|
121
|
+
|
|
122
|
+
UET tag'ini olduğu gibi koy — bootstrap `window.uetq.push('consent','default',{ad_storage:'denied'})` çağrısını otomatik yapar. Kullanıcı `marketing` onayı verince UET'e `update` push edilir. Microsoft Clarity de aynı sinyali okur.
|
|
123
|
+
|
|
124
|
+
```html
|
|
125
|
+
<!-- UET tag — değişiklik gerektirmez -->
|
|
126
|
+
<script>
|
|
127
|
+
(function(w,d,t,r,u){var f,n,i;w[u]=w[u]||[],f=function(){var o={ti:"XXXXXXX"};
|
|
128
|
+
o.q=w[u],w[u]=new UET(o),w[u].push("pageLoad")},n=d.createElement(t),n.src=r,
|
|
129
|
+
n.async=1,n.onload=n.onreadystatechange=function(){var s=this.readyState;
|
|
130
|
+
s&&s!=="loaded"&&s!=="complete"||(f(),n.onload=n.onreadystatechange=null)},
|
|
131
|
+
i=d.getElementsByTagName(t)[0],i.parentNode.insertBefore(n,i);
|
|
132
|
+
})(window,document,"script","//bat.bing.com/bat.js","uetq");
|
|
133
|
+
</script>
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
### Yandex Metrica ile
|
|
137
|
+
|
|
138
|
+
Yandex'in standart consent API'si yoktur, tag-gating kullanılır. Metrica embed kodunu `type="text/plain"` ile sar:
|
|
139
|
+
|
|
140
|
+
```html
|
|
141
|
+
<script type="text/plain" data-blakfy-category="analytics">
|
|
142
|
+
(function(m,e,t,r,i,k,a){m[i]=m[i]||function(){(m[i].a=m[i].a||[]).push(arguments)};
|
|
143
|
+
m[i].l=1*new Date();k=e.createElement(t),a=e.getElementsByTagName(t)[0],
|
|
144
|
+
k.async=1,k.src=r,a.parentNode.insertBefore(k,a)})
|
|
145
|
+
(window,document,"script","https://mc.yandex.ru/metrica/tag.js","ym");
|
|
146
|
+
ym(XXXXXXXX, "init", { clickmap:true, trackLinks:true, accurateTrackBitrate:true });
|
|
147
|
+
</script>
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
**Webvisor (session replay)** için ayrı `recording` kategori onayı gerekir (KVKK/GDPR yorumu). Otomatik temizlenen cookie'ler: `_ym_*`, `yandexuid`, `yabs-frequency`.
|
|
151
|
+
|
|
152
|
+
---
|
|
153
|
+
|
|
154
|
+
## Tercihler Modalı (3 Sekme)
|
|
155
|
+
|
|
156
|
+
"Tercihler" veya `window.BlakfyCookie.open()` çağrıldığında açılan modal 3 sekmeden oluşur:
|
|
157
|
+
|
|
158
|
+
| Sekme | İçerik |
|
|
159
|
+
|---|---|
|
|
160
|
+
| **Kategoriler** | Zorunlu / Analitik / Pazarlama / Fonksiyonel toggle switch'leri. "Seçimleri Kaydet" ve "Tümünü Kabul Et" butonları. |
|
|
161
|
+
| **Hizmetler** | Aktif preset'lere göre accordion kartlar. Her kart: açıklama, veri işleyici, adres, amaçlar, teknolojiler, toplanan veriler, hukuki dayanak, saklama süresi, aktarım ülkeleri, gizlilik politikası linki. GDPR Madde 13/14 + KVKK Madde 10 zorunlu bilgi ifşası. |
|
|
162
|
+
| **Hakkında** | CMP kimliği (Blakfy Studio), platform açıklaması (GDPR / KVKK / CCPA), sürüm numarası. |
|
|
163
|
+
|
|
164
|
+
> **Yasal dayanak:** Hizmetler sekmesindeki bilgiler GDPR Madde 13/14 (bilgi yükümlülüğü) ve KVKK Madde 10 (aydınlatma yükümlülüğü) gerekliliklerini karşılar. Presets kullanmadan da her site kendi hizmet bilgilerini `SERVICE_METADATA` yapısına ekleyebilir.
|
|
165
|
+
|
|
166
|
+
---
|
|
167
|
+
|
|
168
|
+
## Renk Temaları
|
|
169
|
+
|
|
170
|
+
3 hazır tema, `data-blakfy-theme` ile seçilir:
|
|
171
|
+
|
|
172
|
+
| Tema | Açıklama | Attribute değeri |
|
|
173
|
+
|---|---|---|
|
|
174
|
+
| **Beyaz** (varsayılan) | Beyaz arka plan, koyu metin | `light` veya atlanabilir |
|
|
175
|
+
| **Açık gri** | `#f0f0f0` arka plan, koyu metin | `gray` |
|
|
176
|
+
| **Siyah** | `#1a1a1a` arka plan, açık metin | `dark` |
|
|
177
|
+
| **Otomatik** | Sistem `prefers-color-scheme` ayarını okur | `auto` |
|
|
178
|
+
|
|
179
|
+
```html
|
|
180
|
+
<!-- Açık gri tema -->
|
|
181
|
+
<script src="...cookie.min.js" data-blakfy-theme="gray" ...></script>
|
|
182
|
+
|
|
183
|
+
<!-- Siyah tema -->
|
|
184
|
+
<script src="...cookie.min.js" data-blakfy-theme="dark" ...></script>
|
|
185
|
+
|
|
186
|
+
<!-- Sistem temasını takip et -->
|
|
187
|
+
<script src="...cookie.min.js" data-blakfy-theme="auto" ...></script>
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
Tüm temalarda `--blakfy-accent` CSS değişkeni geçerliliğini korur — buton ve aktif sekme rengi `data-blakfy-accent` ile özelleştirilebilir.
|
|
191
|
+
|
|
192
|
+
---
|
|
193
|
+
|
|
194
|
+
## Configuration Reference
|
|
195
|
+
|
|
196
|
+
Tüm `<script>` tag'i üzerine konabilen `data-blakfy-*` attribute'ları:
|
|
197
|
+
|
|
198
|
+
| Attribute | Default | Tip | Açıklama |
|
|
199
|
+
|---|---|---|---|
|
|
200
|
+
| `data-blakfy-locale` | `auto` | BCP47 ya da `auto` | Dil. `auto` → tarayıcıdan tespit. 23 desteklenen dil aşağıda. |
|
|
201
|
+
| `data-blakfy-main-lang` | `null` | BCP47 | Sitenin **birincil dili** (audit log için). Boşsa locale ile aynı. |
|
|
202
|
+
| `data-blakfy-policy-url` | `/cerez-politikasi` | URL | "Çerez Politikası" linki için hedef. |
|
|
203
|
+
| `data-blakfy-version` | `1.0` | string | **Politika versiyonu**. Bunu artırırsan tüm kullanıcılar tekrar onay vermek zorunda (re-consent). |
|
|
204
|
+
| `data-blakfy-audit-endpoint` | `null` | URL | Consent kararı bu endpoint'e POST edilir (KVKK Md.12 / GDPR Art.7(1) kanıt). |
|
|
205
|
+
| `data-blakfy-position` | `bottom-right` | enum | `bottom-right` \| `bottom-left` \| `bottom` \| `top` \| `center` |
|
|
206
|
+
| `data-blakfy-theme` | `auto` | enum | **`light`** (beyaz) \| **`gray`** (açık gri) \| **`dark`** (siyah) \| `auto` (`prefers-color-scheme`) |
|
|
207
|
+
| `data-blakfy-accent` | `#3E5C3A` | hex | Buton ve vurgu rengi. |
|
|
208
|
+
| `data-blakfy-presets` | `null` | virgül listesi | Etkinleştirilecek preset key'leri. Örn: `ga4,gtm,facebook,clarity`. Aşağıda 18 preset listesi. |
|
|
209
|
+
| `data-blakfy-tcf` | `false` | bool | IAB TCF v2.2 modülünü aç (`__tcfapi` global). |
|
|
210
|
+
| `data-blakfy-cmp-id` | `0` | int | TCF CMP ID. `0` = preview/test mode. Sertifikasyon sonrası gerçek ID. |
|
|
211
|
+
| `data-blakfy-ccpa` | `auto` | enum | `auto` (jurisdiction tespiti), `true` (her zaman aç), `false` (kapat) |
|
|
212
|
+
| `data-blakfy-gpc` | `respect` | enum | `respect` (tarayıcı GPC'si auto-deny say) \| `ignore` |
|
|
213
|
+
| `data-blakfy-dnt` | `respect` | enum | `respect` (UI'da uyar) \| `auto-deny` (auto-reject) |
|
|
214
|
+
| `data-blakfy-status-url` | jsDelivr `@2/status.json` | URL | Status bar mesajları için kaynak. |
|
|
215
|
+
| `data-blakfy-status` | `true` | bool | `false` ise status bar render edilmez. |
|
|
216
|
+
|
|
217
|
+
**Desteklenen 23 dil:** `tr`, `en`, `ar`, `fa`, `ur`, `fr`, `ru`, `de`, `he`, `uk`, `es`, `it`, `pt`, `nl`, `pl`, `sv`, `cs`, `zh`, `zh-TW`, `ja`, `ko`, `id`, `hi` (RTL: `ar`, `fa`, `ur`, `he`).
|
|
218
|
+
|
|
219
|
+
---
|
|
220
|
+
|
|
221
|
+
## API Reference
|
|
222
|
+
|
|
223
|
+
`window.BlakfyCookie` global olarak erişilebilir. Tüm v1 metodları korunmuştur, v2'de yeni metodlar eklendi.
|
|
224
|
+
|
|
225
|
+
| Metod | Sürüm | İmza | Açıklama |
|
|
226
|
+
|---|---|---|---|
|
|
227
|
+
| `version` | v1 | `string` | Kütüphane sürümü, örn. `"2.1.0"`. |
|
|
228
|
+
| `open()` | v1 | `() => void` | Tercihler modalını aç. |
|
|
229
|
+
| `acceptAll()` | v1 | `() => void` | Tüm kategorileri kabul et. |
|
|
230
|
+
| `rejectAll()` | v1 | `() => void` | Tüm kategorileri reddet (essential dışında). |
|
|
231
|
+
| `getConsent(cat)` | v1 | `(c: ConsentCategory) => boolean` | Kategori onaylı mı. `essential` her zaman `true`. |
|
|
232
|
+
| `getState()` | v1 | `() => BlakfyConsentState \| null` | Tam consent state objesi. |
|
|
233
|
+
| `onChange(fn)` | v1 | `(fn: (state) => void) => void` | State değişince çağrılır. |
|
|
234
|
+
| `setLocale(loc)` | v1 | `(loc: BlakfyLocale) => void` | Dili değiştir (UI re-render). |
|
|
235
|
+
| `getMainLang()` | v1 | `() => BlakfyLocale` | Audit log için ayarlanan birincil dil. |
|
|
236
|
+
| `onConsent(cat, fn)` | **v2** | `(c, fn: (granted: boolean) => void) => void` | Kategori-bazlı listener. Mevcut state ile **anında** çağrılır, sonra her değişimde tekrar. |
|
|
237
|
+
| `registerCleanup(opts)` | **v2** | `(opts: { category, cookies?, storage? }) => void` | Onay geri çekildiğinde silinecek cookie'leri/localStorage anahtarlarını kaydet. |
|
|
238
|
+
| `unblock(cat)` | **v2** | `(c: ConsentCategory) => void` | Kategori için tag-gating'i manuel aç. |
|
|
239
|
+
| `scan()` | **v2** | `() => ConsentCategory[]` | DOM'u tekrar tara (SPA navigasyonu sonrası). |
|
|
240
|
+
| `usePreset(name)` | **v2** | `(name: string) => Preset \| null` | Hazır preset'i runtime'da uygula. |
|
|
241
|
+
| `tcf.getTCString()` | **v2** | `() => string` | IAB TCF v2.2 TC string. |
|
|
242
|
+
| `ccpa.optOut()` | **v2** | `() => void` | CCPA "Do Not Sell" opt-out. |
|
|
243
|
+
| `ccpa.isOptedOut()` | **v2** | `() => boolean` | CCPA opt-out durumu. |
|
|
244
|
+
| `getJurisdiction()` | **v2** | `() => "GDPR" \| "CCPA" \| "LGPD" \| "default"` | Tespit edilen yetki alanı. |
|
|
245
|
+
| `window.__tcfapi(...)` | **v2** | IAB standart | `getTCData`, `addEventListener`, `removeEventListener` (TCF v2.2 spec). |
|
|
246
|
+
|
|
247
|
+
**ConsentCategory:** `"essential"` | `"analytics"` | `"marketing"` | `"functional"` | `"recording"`
|
|
248
|
+
|
|
249
|
+
**BlakfyConsentState alanları:** `id` (uuid), `essential` (true), `analytics`, `marketing`, `functional`, `recording`, `timestamp` (ISO), `version` (policy), `locale`, `mainLang`, `jurisdiction`, `tcString`, `uspString`.
|
|
250
|
+
|
|
251
|
+
---
|
|
252
|
+
|
|
253
|
+
## Tag-Gating
|
|
254
|
+
|
|
255
|
+
Üçüncü parti tag'lerini kullanıcı onay vermeden çalıştırma. 4 yöntem.
|
|
256
|
+
|
|
257
|
+
### Harici script
|
|
258
|
+
|
|
259
|
+
```html
|
|
260
|
+
<!-- type="text/plain" → tarayıcı çalıştırmaz -->
|
|
261
|
+
<script type="text/plain"
|
|
262
|
+
data-blakfy-category="marketing"
|
|
263
|
+
data-blakfy-src="https://connect.facebook.net/en_US/fbevents.js"
|
|
264
|
+
async></script>
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
Onay verildiğinde widget script'in `type` attribute'unu `text/javascript`'e çevirir, `data-blakfy-src` → `src` taşır ve DOM'a yeniden ekler.
|
|
268
|
+
|
|
269
|
+
### Inline script
|
|
270
|
+
|
|
271
|
+
```html
|
|
272
|
+
<script type="text/plain" data-blakfy-category="analytics">
|
|
273
|
+
console.log("Analytics tag fired");
|
|
274
|
+
fbq('init', 'PIXEL_ID');
|
|
275
|
+
</script>
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
### Iframe (YouTube, Vimeo, harita, vb.)
|
|
279
|
+
|
|
280
|
+
```html
|
|
281
|
+
<iframe data-blakfy-src="https://www.youtube.com/embed/VIDEO_ID"
|
|
282
|
+
data-blakfy-category="marketing"
|
|
283
|
+
data-blakfy-placeholder="auto"
|
|
284
|
+
width="560" height="315"
|
|
285
|
+
title="YouTube video"
|
|
286
|
+
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope"
|
|
287
|
+
allowfullscreen></iframe>
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
`data-blakfy-placeholder="auto"` → otomatik "Çerez onayı bekleniyor" placeholder UI'ı gösterilir.
|
|
291
|
+
|
|
292
|
+
### React/Next.js declarative gating
|
|
293
|
+
|
|
294
|
+
```tsx
|
|
295
|
+
"use client";
|
|
296
|
+
import { useGating } from "@blakfy/cookie-next";
|
|
297
|
+
|
|
298
|
+
export function YouTubeEmbed({ id }: { id: string }) {
|
|
299
|
+
const allowed = useGating("marketing");
|
|
300
|
+
if (!allowed) {
|
|
301
|
+
return (
|
|
302
|
+
<div className="aspect-video rounded bg-zinc-100 flex items-center justify-center">
|
|
303
|
+
Onay bekleniyor — bu içeriği görmek için pazarlama çerezlerini kabul edin.
|
|
304
|
+
</div>
|
|
305
|
+
);
|
|
306
|
+
}
|
|
307
|
+
return (
|
|
308
|
+
<iframe
|
|
309
|
+
src={`https://www.youtube.com/embed/${id}`}
|
|
310
|
+
className="w-full aspect-video"
|
|
311
|
+
title="YouTube"
|
|
312
|
+
allow="accelerometer; clipboard-write; encrypted-media; gyroscope"
|
|
313
|
+
allowFullScreen
|
|
314
|
+
/>
|
|
315
|
+
);
|
|
316
|
+
}
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
---
|
|
320
|
+
|
|
321
|
+
## 18 Hazır Preset
|
|
322
|
+
|
|
323
|
+
`data-blakfy-presets="ga4,gtm,facebook,clarity"` gibi virgüllü liste ile aktive edilir. Preset; cookie'leri ve localStorage anahtarlarını otomatik **registerCleanup**'a kaydeder, böylece kullanıcı onayı geri çekince bunlar otomatik silinir.
|
|
324
|
+
|
|
325
|
+
| Key | Araç | Kategori | Örnek Cookie / Storage |
|
|
326
|
+
|---|---|---|---|
|
|
327
|
+
| `ga4` | Google Analytics 4 | analytics | `_ga`, `_ga_*`, `_gid`, `_gat` |
|
|
328
|
+
| `gtm` | Google Tag Manager | analytics | `_dc_gtm_*` |
|
|
329
|
+
| `maps` | Google Maps | functional | `NID`, `SID`, `HSID` |
|
|
330
|
+
| `recaptcha` | Google reCAPTCHA | functional | `_GRECAPTCHA` |
|
|
331
|
+
| `facebook` | Facebook Pixel | marketing | `_fbp`, `_fbc`, `fr` |
|
|
332
|
+
| `youtube` | YouTube embed | marketing | `VISITOR_INFO1_LIVE`, `YSC`, `PREF` |
|
|
333
|
+
| `vimeo` | Vimeo embed | marketing | `vuid`, `_ga` |
|
|
334
|
+
| `hotjar` | Hotjar | analytics | `_hjSession*`, `_hjid` |
|
|
335
|
+
| `clarity` | Microsoft Clarity | analytics | `_clck`, `_clsk`, `MUID` |
|
|
336
|
+
| `linkedin` | LinkedIn Insight | marketing | `li_sugr`, `bcookie`, `lidc`, `UserMatchHistory` |
|
|
337
|
+
| `yandex` | Yandex Metrica | analytics + recording | `_ym_*`, `yandexuid`, `yabs-frequency` |
|
|
338
|
+
| `bing` | Bing Ads (UET) | marketing | `MUID`, `_uetsid`, `_uetvid` |
|
|
339
|
+
| `tiktok` | TikTok Pixel | marketing | `tt_*`, `_ttp` |
|
|
340
|
+
| `pinterest` | Pinterest Tag | marketing | `_pinterest_*`, `_pin_unauth` |
|
|
341
|
+
| `tawkto` | Tawk.to chat | functional | `__tawkUUID`, `Tawk_*` |
|
|
342
|
+
| `intercom` | Intercom | functional | `intercom-*` |
|
|
343
|
+
| `hubspot` | HubSpot | marketing | `__hssc`, `__hssrc`, `__hstc`, `hubspotutk` |
|
|
344
|
+
| `mailchimp` | Mailchimp | marketing | `_mcid`, `mc_*` |
|
|
345
|
+
|
|
346
|
+
**Manuel ekleme** (preset'sız):
|
|
347
|
+
|
|
348
|
+
```js
|
|
349
|
+
window.BlakfyCookie.registerCleanup({
|
|
350
|
+
category: "marketing",
|
|
351
|
+
cookies: ["my_custom_pixel", /^_track_/],
|
|
352
|
+
storage: ["myAppMarketingCache"]
|
|
353
|
+
});
|
|
354
|
+
```
|
|
355
|
+
|
|
356
|
+
---
|
|
357
|
+
|
|
358
|
+
## Compliance
|
|
359
|
+
|
|
360
|
+
| Yasa / Standart | Yetki Alanı | Modül | Ne yapar |
|
|
361
|
+
|---|---|---|---|
|
|
362
|
+
| **GDPR** | AB | `core/` + `ui/` | Eşit prominence kabul/red butonu, pre-tick yok, granular kategori onayı. |
|
|
363
|
+
| **ePrivacy Directive** | AB | `core/consent-store` | Onay öncesi cookie yazılmaz. |
|
|
364
|
+
| **KVKK** | Türkiye | `core/audit.js` | Md.12 ispat yükümlülüğü için audit log POST. |
|
|
365
|
+
| **CCPA / CPRA** | Kaliforniya | `compliance/ccpa.js` | "Do Not Sell" linki, USP string `1YYY`, GPC saygısı. |
|
|
366
|
+
| **LGPD** | Brezilya | `i18n/pt.js` + `geo/` | Portekizce UI, jurisdiction tespiti (v2.1'de tam destek). |
|
|
367
|
+
| **Google Consent Mode v2** | Google ekosistemi | `compliance/google-cmv2.js` | `gtag('consent','update', {...})` 7 sinyal. |
|
|
368
|
+
| **Microsoft UET** | Bing Ads + Clarity | `compliance/microsoft-uet.js` | `uetq.push('consent','update', {ad_storage})` |
|
|
369
|
+
| **Yandex Metrica** | Yandex ekosistemi | `compliance/yandex-metrica.js` | Tag-gating + Webvisor ayrı `recording` kategori. |
|
|
370
|
+
| **IAB TCF v2.2** | AB AdTech (AdSense) | `compliance/tcf-v2.js` | `__tcfapi`, TC string, GVL fetch. |
|
|
371
|
+
| **GPC** | Tarayıcı standardı | `compliance/gpc.js` | `navigator.globalPrivacyControl` → marketing/analytics auto-deny. |
|
|
372
|
+
| **DNT** | Tarayıcı standardı | `compliance/dnt.js` | `navigator.doNotTrack === "1"` → UI uyarı veya auto-deny. |
|
|
373
|
+
|
|
374
|
+
### TCF v2.2 (AdSense / Ad Manager kullanıcıları için)
|
|
375
|
+
|
|
376
|
+
`data-blakfy-tcf="true" data-blakfy-cmp-id="0"` ile preview mode'da çalışır. Production için IAB Europe sertifikasyonu gerekir (~2-3 ay, yıllık ~€2.000 ücret). Süreç ve audit gereksinimleri: [`TCF-CERTIFICATION.md`](./TCF-CERTIFICATION.md).
|
|
377
|
+
|
|
378
|
+
```js
|
|
379
|
+
// TC string okuma
|
|
380
|
+
window.BlakfyCookie.tcf.getTCString();
|
|
381
|
+
// IAB standart API
|
|
382
|
+
window.__tcfapi("getTCData", 2, (data, success) => console.log(data));
|
|
383
|
+
```
|
|
384
|
+
|
|
385
|
+
### CCPA / CPRA (ABD trafiği)
|
|
386
|
+
|
|
387
|
+
`data-blakfy-ccpa="auto"` → `geo/jurisdiction.js` Kaliforniya tespit ederse:
|
|
388
|
+
|
|
389
|
+
- Banner'daki "Reddet" → **"Do Not Sell or Share My Personal Information"**
|
|
390
|
+
- Footer'a kalıcı `<a class="blakfy-ccpa-link">` (yasal zorunluluk)
|
|
391
|
+
- USP string `1YYY` (versiyon, opt-out, sale, third-party) `__uspapi` üzerinden expose edilir
|
|
392
|
+
- `Sec-GPC: 1` header otomatik opt-out sayılır
|
|
393
|
+
|
|
394
|
+
### GPC / DNT default davranışı
|
|
395
|
+
|
|
396
|
+
- **GPC** (`navigator.globalPrivacyControl === true`): Kullanıcı açık onay vermediyse `marketing` ve `analytics` otomatik **denied**. CCPA jurisdiction'da yasal opt-out.
|
|
397
|
+
- **DNT** (`navigator.doNotTrack === "1"`): Default'ta sadece banner'da uyarı yazısı. `data-blakfy-dnt="auto-deny"` ile auto-reject yapılabilir. (DNT zayıf bir standart; GPC tercih edilir.)
|
|
398
|
+
|
|
399
|
+
---
|
|
400
|
+
|
|
401
|
+
## Troubleshooting
|
|
402
|
+
|
|
403
|
+
### Widget hiç görünmüyor
|
|
404
|
+
|
|
405
|
+
1. Console'da hata var mı? Network sekmesinde `cookie.min.js` 200 dönüyor mu?
|
|
406
|
+
2. Script tag'i `</body>`'den önce mi? `<head>` içine konursa DOM hazır olmadan render denenir.
|
|
407
|
+
3. Daha önce kabul/red verildiyse banner görünmez (kalıcı). Modal'ı tetiklemek için: `window.BlakfyCookie.open()` veya footer'a "Çerez Tercihleri" linki koy.
|
|
408
|
+
|
|
409
|
+
### Banner her sayfada / her seferinde tekrar açılıyor
|
|
410
|
+
|
|
411
|
+
`data-blakfy-version` (politika versiyonu) değişti mi? Bu değer her cookie'de saklanır; uyuşmuyorsa re-consent tetiklenir. **Dikkat:** Kütüphane sürümü `cookie.min.js` patch güncellemeleri kullanıcıyı **etkilemez** (v2 düzeltmesi). v1'de bu bir bug'dı.
|
|
412
|
+
|
|
413
|
+
### GTM / GA4 tetiklenmiyor
|
|
414
|
+
|
|
415
|
+
- **Bootstrap script GTM'den önce mi yükleniyor?** `cookie-defaults.min.js` `<head>`'in **ilk** script'i olmalı. Aksi halde GTM `consent default` çağrısını kaçırır.
|
|
416
|
+
- Tag → "Consent settings" → "Require additional consent for tag firing" doğru kategorilere ayarlı mı?
|
|
417
|
+
- Kullanıcı kabul etti mi: `window.BlakfyCookie.getState()` ile kontrol et.
|
|
418
|
+
|
|
419
|
+
### Yandex Metrica çalışıyor ama Webvisor (session replay) çalışmıyor
|
|
420
|
+
|
|
421
|
+
Webvisor `marketing` değil, **`recording`** kategorisi gerektirir. Modal'da bu seçeneğe ayrı onay vermelisin. KVKK/GDPR yorumu: session replay biyometriye yakın özel veri olduğu için ek granular onay zorunlu.
|
|
422
|
+
|
|
423
|
+
### TCF preview mode'da takıldım
|
|
424
|
+
|
|
425
|
+
`data-blakfy-cmp-id="0"` preview mode'dur. AdSense/Ad Manager production için IAB Europe sertifikasyonu sonrası atanan gerçek CMP ID girilmeli. Detay: [`TCF-CERTIFICATION.md`](./TCF-CERTIFICATION.md).
|
|
426
|
+
|
|
427
|
+
### "Powered by Blakfy Studio" badge'i nasıl gizlerim?
|
|
428
|
+
|
|
429
|
+
**Gizlenemez.** 3 katmanlı anti-tampering korumalı (CSS `!important`, MutationObserver re-injection, kod-baked HTML). Lisans şartının parçasıdır. Marka koruması.
|
|
430
|
+
|
|
431
|
+
### Next.js'te FOUC (içerik atlaması) görüyorum
|
|
432
|
+
|
|
433
|
+
`@blakfy/cookie-next@2`'ye yükselt. v1'de FOUC vardı; v2'de `next/script` `beforeInteractive` strateji kullanılıyor.
|
|
434
|
+
|
|
435
|
+
### `acceptAll()` sonrası 3rd-party tag'ler hala engelli
|
|
436
|
+
|
|
437
|
+
`window.BlakfyCookie.scan()` çağır — SPA navigasyonu veya dinamik DOM ekleme sonrası gating observer'ı tekrar tetikler.
|
|
438
|
+
|
|
439
|
+
---
|
|
440
|
+
|
|
441
|
+
## Migration v1 → v2
|
|
442
|
+
|
|
443
|
+
**Kısa cevap:** Değişiklik gerekmez. v1 kullanıcıları `@1` etiketinde kalır, çalışmaya devam eder. v2'ye opt-in yapmak için **CDN URL'sindeki `@1` → `@2`** ve dosya adı `cookie.js` → `dist/cookie.min.js` güncellemesi yeterli — tüm v1 attribute'ları korunur, kullanıcı consent cookie'si geriye uyumlu okunur.
|
|
444
|
+
|
|
445
|
+
Detay: [`MIGRATION.md`](./MIGRATION.md).
|
|
446
|
+
|
|
447
|
+
---
|
|
448
|
+
|
|
449
|
+
## Footer "Çerez Tercihleri" linki
|
|
450
|
+
|
|
451
|
+
```html
|
|
452
|
+
<a href="#" onclick="event.preventDefault(); window.BlakfyCookie.open();">
|
|
453
|
+
Çerez Tercihleri
|
|
454
|
+
</a>
|
|
455
|
+
```
|
|
456
|
+
|
|
457
|
+
Veya React:
|
|
458
|
+
|
|
459
|
+
```tsx
|
|
460
|
+
<button onClick={() => window.BlakfyCookie?.open()}>Çerez Tercihleri</button>
|
|
461
|
+
```
|
|
462
|
+
|
|
463
|
+
---
|
|
464
|
+
|
|
465
|
+
## Diğer Kaynaklar
|
|
466
|
+
|
|
467
|
+
- [`ARCHITECTURE.md`](./ARCHITECTURE.md) — modül yapısı, veri akışı, boyut bütçesi
|
|
468
|
+
- [`COMPLIANCE.md`](./COMPLIANCE.md) — her yasa için detaylı uyumluluk mappingleri
|
|
469
|
+
- [`CHANGELOG.md`](./CHANGELOG.md) — sürüm notları
|
|
470
|
+
- [`MIGRATION.md`](./MIGRATION.md) — v1 → v2 geçiş
|
|
471
|
+
- [`TCF-CERTIFICATION.md`](./TCF-CERTIFICATION.md) — IAB Europe başvuru süreci
|
|
472
|
+
- [`packages/cookie-next/README.md`](./packages/cookie-next/README.md) — npm paketi rehberi
|
|
473
|
+
|
|
474
|
+
---
|
|
475
|
+
|
|
476
|
+
## License
|
|
477
|
+
|
|
478
|
+
MIT © Blakfy Studio. "Powered by Blakfy Studio" branding badge anti-tampering korumalı ve kaldırılamaz.
|
|
479
|
+
|
|
480
|
+
Issues: https://github.com/tariktunc/blakfy-cookie/issues
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
# IAB TCF v2.2 Sertifikasyon Süreci
|
|
2
|
+
|
|
3
|
+
> Bu doküman v2.0.0 release sonrası başlatılacak süreçtir. Kod hazır, ama IAB Europe'tan resmi CMP ID alınmadan widget "preview mode"da çalışır.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Neden Sertifikasyon Lazım?
|
|
8
|
+
|
|
9
|
+
Eğer site sahibi:
|
|
10
|
+
- Google AdSense
|
|
11
|
+
- Google Ad Manager (DV360, Google Ads — re-marketing dahil)
|
|
12
|
+
- Major SSP'ler (Magnite, Index Exchange, Xandr...)
|
|
13
|
+
|
|
14
|
+
kullanıyorsa, **Mart 2024'ten beri** TCF v2.2 sertifikalı bir CMP zorunlu. Sertifikasız widget "non-compliant" sayılır ve Google reklam servisi durdurabilir.
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
## Süreç (5 Adım)
|
|
19
|
+
|
|
20
|
+
### 1. Başvuru
|
|
21
|
+
- URL: https://iabeurope.eu/cmp-list/
|
|
22
|
+
- Form: CMP adı, URL, teknik temas kişisi, audit dokümanları
|
|
23
|
+
- Süre: 1 hafta cevap
|
|
24
|
+
|
|
25
|
+
### 2. Teknik Audit
|
|
26
|
+
IAB Europe denetçisi şunları kontrol eder:
|
|
27
|
+
- `__tcfapi` global fonksiyonun varlığı ve doğru komut yüzeyi (✅ kodda var)
|
|
28
|
+
- TC string formatı (Base64URL, doğru segment yapısı) (✅)
|
|
29
|
+
- Vendor List senkronizasyonu (GVL fetch) (✅)
|
|
30
|
+
- UI'da vendor toggle erişilebilirliği (✅ src/ui/modal.js)
|
|
31
|
+
- DSAR (Data Subject Access Request) akışı dokümante edildi mi
|
|
32
|
+
- Consent withdrawal her zaman mümkün mü (✅ widget her zaman erişilebilir)
|
|
33
|
+
|
|
34
|
+
### 3. Ücret
|
|
35
|
+
- **Annual fee**: ~€2.000 (CMP boyutuna göre değişir)
|
|
36
|
+
- Faturalama: Yıllık peşin
|
|
37
|
+
|
|
38
|
+
### 4. CMP ID Atama
|
|
39
|
+
- Audit geçince IAB Europe bir **numeric CMP ID** atar (örn. `123`)
|
|
40
|
+
- Bu ID widget'a yazılır:
|
|
41
|
+
```html
|
|
42
|
+
<script src="..." data-blakfy-cmp-id="123"></script>
|
|
43
|
+
```
|
|
44
|
+
- ID `0` = preview/test mode (audit öncesi)
|
|
45
|
+
|
|
46
|
+
### 5. Yıllık Yenileme
|
|
47
|
+
- Her yıl re-audit (kod değişikliği varsa)
|
|
48
|
+
- Yenileme ücreti aynı
|
|
49
|
+
|
|
50
|
+
---
|
|
51
|
+
|
|
52
|
+
## Geliştirici Tarafında Yapılacaklar (kullanıcıya talimat)
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
# Sertifikasyon onayı geldiğinde
|
|
56
|
+
1. CMP ID'yi al (örn. 123)
|
|
57
|
+
2. Site script tag'ine ekle:
|
|
58
|
+
data-blakfy-cmp-id="123"
|
|
59
|
+
3. Yeniden deploy.
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
Kütüphane güncellemesi gerekmez — `data-blakfy-cmp-id="0"` (preview) ile `data-blakfy-cmp-id="123"` (prod) arasındaki tek fark TC string'in `cmpId` field'ı.
|
|
63
|
+
|
|
64
|
+
---
|
|
65
|
+
|
|
66
|
+
## Preview Mode Davranışı (CMP ID 0)
|
|
67
|
+
|
|
68
|
+
- `__tcfapi` çalışır
|
|
69
|
+
- TC string üretilir ama `cmpId=0`
|
|
70
|
+
- Test ortamlarında ve sertifikasyon beklenirken kullanılır
|
|
71
|
+
- Production AdSense kullanımı için **uygun değildir** — Google reddeder
|
|
72
|
+
|
|
73
|
+
---
|
|
74
|
+
|
|
75
|
+
## Vendor List
|
|
76
|
+
|
|
77
|
+
- Kaynak: `https://vendor-list.consensu.org/v3/vendor-list.json`
|
|
78
|
+
- Boyut: ~500 KB JSON, 1500+ vendor
|
|
79
|
+
- Strateji: Lazy fetch + 24 saat cache
|
|
80
|
+
- UI'da arama/filtreleme: src/ui/modal.js içinde (vendor toggle paneli)
|
|
81
|
+
|
|
82
|
+
---
|
|
83
|
+
|
|
84
|
+
## DSAR (Data Subject Access Request) Akışı
|
|
85
|
+
|
|
86
|
+
GDPR Art. 15 + 17 gereği kullanıcı:
|
|
87
|
+
- Verilerine **erişim** isteyebilir → site sahibi audit log'tan döndürür
|
|
88
|
+
- **Silme** isteyebilir → audit log + cookie temizlenir
|
|
89
|
+
- **Onay geri çekme** isteyebilir → widget her zaman açık (`BlakfyCookie.open()`)
|
|
90
|
+
|
|
91
|
+
Site sahibinin yapması gereken:
|
|
92
|
+
- `data-blakfy-audit-endpoint` ile DSAR taleplerini sorgulayabileceği bir endpoint kurmak
|
|
93
|
+
- Privacy policy sayfasında DSAR talimatları yazmak (örnek README'de)
|
|
94
|
+
|
|
95
|
+
---
|
|
96
|
+
|
|
97
|
+
## Maliyet Özeti
|
|
98
|
+
|
|
99
|
+
| Kalem | Yıllık |
|
|
100
|
+
|---|---|
|
|
101
|
+
| IAB Europe sertifikasyon ücreti | ~€2.000 |
|
|
102
|
+
| Audit hazırlık (developer saati) | bir kerelik, dahil |
|
|
103
|
+
| GVL CDN serving (Cloudflare) | ücretsiz (consensu.org host eder) |
|
|
104
|
+
| **TOPLAM** | **~€2.000/yıl** |
|
|
105
|
+
|
|
106
|
+
Eğer site AdSense/Ad Manager kullanmıyorsa **sertifikasyona gerek yok**, kod yine de hazır kalır.
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* Blakfy Cookie Widget v2.1.0
|
|
3
|
+
* https://github.com/tariktunc/blakfy-cookie
|
|
4
|
+
* MIT License | (c) Blakfy Studio
|
|
5
|
+
*
|
|
6
|
+
* KVKK + GDPR + CCPA + Google CMv2 + Microsoft UET + Yandex + TCF v2.2 + GPC + DNT
|
|
7
|
+
* 23 languages | 18 presets | Tag-gating | Powered by Blakfy Studio
|
|
8
|
+
*/
|
|
9
|
+
(() => {
|
|
10
|
+
// src/compliance/google-cmv2.js
|
|
11
|
+
var defaultsInstalled = false;
|
|
12
|
+
var installDefaults = () => {
|
|
13
|
+
if (typeof window === "undefined") return;
|
|
14
|
+
if (defaultsInstalled) return;
|
|
15
|
+
defaultsInstalled = true;
|
|
16
|
+
window.dataLayer = window.dataLayer || [];
|
|
17
|
+
if (typeof window.gtag !== "function") {
|
|
18
|
+
window.gtag = function() {
|
|
19
|
+
window.dataLayer.push(arguments);
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
window.gtag("consent", "default", {
|
|
23
|
+
ad_storage: "denied",
|
|
24
|
+
ad_user_data: "denied",
|
|
25
|
+
ad_personalization: "denied",
|
|
26
|
+
analytics_storage: "denied",
|
|
27
|
+
functionality_storage: "denied",
|
|
28
|
+
personalization_storage: "denied",
|
|
29
|
+
security_storage: "granted",
|
|
30
|
+
wait_for_update: 500
|
|
31
|
+
});
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
// src/compliance/microsoft-uet.js
|
|
35
|
+
var defaultsInstalled2 = false;
|
|
36
|
+
var installDefaults2 = () => {
|
|
37
|
+
if (typeof window === "undefined") return;
|
|
38
|
+
if (defaultsInstalled2) return;
|
|
39
|
+
defaultsInstalled2 = true;
|
|
40
|
+
window.uetq = window.uetq || [];
|
|
41
|
+
window.uetq.push("consent", "default", { ad_storage: "denied" });
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
// src/compliance/yandex-metrica.js
|
|
45
|
+
var defaultsInstalled3 = false;
|
|
46
|
+
var installDefaults3 = () => {
|
|
47
|
+
if (typeof window === "undefined") return;
|
|
48
|
+
if (defaultsInstalled3) return;
|
|
49
|
+
defaultsInstalled3 = true;
|
|
50
|
+
if (typeof window.ym !== "function") {
|
|
51
|
+
window.ym = function() {
|
|
52
|
+
};
|
|
53
|
+
window.ym.__blakfyStub = true;
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
// src/cookie-defaults.js
|
|
58
|
+
(function() {
|
|
59
|
+
if (typeof window === "undefined") return;
|
|
60
|
+
if (window.__blakfyConsentDefaultsLoaded) return;
|
|
61
|
+
window.__blakfyConsentDefaultsLoaded = true;
|
|
62
|
+
try {
|
|
63
|
+
installDefaults();
|
|
64
|
+
} catch (e) {
|
|
65
|
+
}
|
|
66
|
+
try {
|
|
67
|
+
installDefaults2();
|
|
68
|
+
} catch (e) {
|
|
69
|
+
}
|
|
70
|
+
try {
|
|
71
|
+
installDefaults3();
|
|
72
|
+
} catch (e) {
|
|
73
|
+
}
|
|
74
|
+
})();
|
|
75
|
+
})();
|
|
76
|
+
/*! For license information please see cookie-defaults.js.LEGAL.txt */
|
|
File without changes
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* Blakfy Cookie Widget v2.1.0
|
|
3
|
+
* https://github.com/tariktunc/blakfy-cookie
|
|
4
|
+
* MIT License | (c) Blakfy Studio
|
|
5
|
+
*
|
|
6
|
+
* KVKK + GDPR + CCPA + Google CMv2 + Microsoft UET + Yandex + TCF v2.2 + GPC + DNT
|
|
7
|
+
* 23 languages | 18 presets | Tag-gating | Powered by Blakfy Studio
|
|
8
|
+
*/
|
|
9
|
+
(()=>{var n=!1,e=()=>{typeof window!="undefined"&&(n||(n=!0,window.dataLayer=window.dataLayer||[],typeof window.gtag!="function"&&(window.gtag=function(){window.dataLayer.push(arguments)}),window.gtag("consent","default",{ad_storage:"denied",ad_user_data:"denied",ad_personalization:"denied",analytics_storage:"denied",functionality_storage:"denied",personalization_storage:"denied",security_storage:"granted",wait_for_update:500})))};var a=!1,o=()=>{typeof window!="undefined"&&(a||(a=!0,window.uetq=window.uetq||[],window.uetq.push("consent","default",{ad_storage:"denied"})))};var i=!1,d=()=>{typeof window!="undefined"&&(i||(i=!0,typeof window.ym!="function"&&(window.ym=function(){},window.ym.__blakfyStub=!0)))};(function(){if(typeof window!="undefined"&&!window.__blakfyConsentDefaultsLoaded){window.__blakfyConsentDefaultsLoaded=!0;try{e()}catch(t){}try{o()}catch(t){}try{d()}catch(t){}}})();})();
|
|
10
|
+
/*! For license information please see cookie-defaults.min.js.LEGAL.txt */
|
|
File without changes
|