@react-lgpd-consent/core 0.5.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/CHANGELOG.md +4 -0
- package/LICENSE +21 -0
- package/README.md +80 -0
- package/dist/index.cjs +2623 -0
- package/dist/index.d.cts +3845 -0
- package/dist/index.d.ts +3845 -0
- package/dist/index.js +2542 -0
- package/package.json +77 -0
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,2623 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var React4 = require('react');
|
|
4
|
+
var Cookies = require('js-cookie');
|
|
5
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
6
|
+
|
|
7
|
+
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
8
|
+
|
|
9
|
+
function _interopNamespace(e) {
|
|
10
|
+
if (e && e.__esModule) return e;
|
|
11
|
+
var n = Object.create(null);
|
|
12
|
+
if (e) {
|
|
13
|
+
Object.keys(e).forEach(function (k) {
|
|
14
|
+
if (k !== 'default') {
|
|
15
|
+
var d = Object.getOwnPropertyDescriptor(e, k);
|
|
16
|
+
Object.defineProperty(n, k, d.get ? d : {
|
|
17
|
+
enumerable: true,
|
|
18
|
+
get: function () { return e[k]; }
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
n.default = e;
|
|
24
|
+
return Object.freeze(n);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
var React4__namespace = /*#__PURE__*/_interopNamespace(React4);
|
|
28
|
+
var Cookies__default = /*#__PURE__*/_interopDefault(Cookies);
|
|
29
|
+
|
|
30
|
+
// @react-lgpd-consent/core - Tree-shakeable ESM build
|
|
31
|
+
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
32
|
+
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
33
|
+
}) : x)(function(x) {
|
|
34
|
+
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
35
|
+
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
// src/utils/categoryUtils.ts
|
|
39
|
+
function createProjectPreferences(config, defaultValue = false) {
|
|
40
|
+
const preferences = {
|
|
41
|
+
necessary: true
|
|
42
|
+
// Sempre presente e true (essencial)
|
|
43
|
+
};
|
|
44
|
+
const enabledCategories = config?.enabledCategories || [];
|
|
45
|
+
enabledCategories.forEach((category) => {
|
|
46
|
+
if (category !== "necessary") {
|
|
47
|
+
preferences[category] = defaultValue;
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
const customCategories = config?.customCategories || [];
|
|
51
|
+
customCategories.forEach((cat) => {
|
|
52
|
+
if (cat.id && cat.id !== "necessary") {
|
|
53
|
+
preferences[cat.id] = defaultValue;
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
return preferences;
|
|
57
|
+
}
|
|
58
|
+
function validateProjectPreferences(preferences, config) {
|
|
59
|
+
const validPreferences = {
|
|
60
|
+
necessary: true
|
|
61
|
+
// Sempre válida
|
|
62
|
+
};
|
|
63
|
+
const enabledCategories = config?.enabledCategories || [];
|
|
64
|
+
enabledCategories.forEach((category) => {
|
|
65
|
+
if (category !== "necessary" && preferences[category] !== void 0) {
|
|
66
|
+
validPreferences[category] = preferences[category];
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
const customCategories = config?.customCategories || [];
|
|
70
|
+
customCategories.forEach((cat) => {
|
|
71
|
+
const id = cat.id;
|
|
72
|
+
if (id && id !== "necessary" && preferences[id] !== void 0) {
|
|
73
|
+
validPreferences[id] = preferences[id];
|
|
74
|
+
}
|
|
75
|
+
});
|
|
76
|
+
return validPreferences;
|
|
77
|
+
}
|
|
78
|
+
function getAllProjectCategories(config) {
|
|
79
|
+
const allCategories = [
|
|
80
|
+
{
|
|
81
|
+
id: "necessary",
|
|
82
|
+
name: "Necess\xE1rios",
|
|
83
|
+
description: "Cookies essenciais para funcionamento b\xE1sico do site",
|
|
84
|
+
essential: true
|
|
85
|
+
}
|
|
86
|
+
];
|
|
87
|
+
const enabledCategories = config?.enabledCategories || [];
|
|
88
|
+
enabledCategories.forEach((category) => {
|
|
89
|
+
if (category !== "necessary") {
|
|
90
|
+
allCategories.push(getDefaultCategoryDefinition(category));
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
const customCategories = config?.customCategories || [];
|
|
94
|
+
customCategories.forEach((cat) => {
|
|
95
|
+
if (cat.id && cat.id !== "necessary") {
|
|
96
|
+
allCategories.push({ ...cat, essential: !!cat.essential });
|
|
97
|
+
}
|
|
98
|
+
});
|
|
99
|
+
return allCategories;
|
|
100
|
+
}
|
|
101
|
+
function getDefaultCategoryDefinition(category) {
|
|
102
|
+
const definitions = {
|
|
103
|
+
necessary: {
|
|
104
|
+
id: "necessary",
|
|
105
|
+
name: "Necess\xE1rios",
|
|
106
|
+
description: "Cookies essenciais para funcionamento b\xE1sico do site",
|
|
107
|
+
essential: true
|
|
108
|
+
},
|
|
109
|
+
analytics: {
|
|
110
|
+
id: "analytics",
|
|
111
|
+
name: "An\xE1lise e Estat\xEDsticas",
|
|
112
|
+
description: "Cookies para an\xE1lise de uso e estat\xEDsticas do site",
|
|
113
|
+
essential: false
|
|
114
|
+
},
|
|
115
|
+
functional: {
|
|
116
|
+
id: "functional",
|
|
117
|
+
name: "Funcionalidades",
|
|
118
|
+
description: "Cookies para funcionalidades extras como prefer\xEAncias e idioma",
|
|
119
|
+
essential: false
|
|
120
|
+
},
|
|
121
|
+
marketing: {
|
|
122
|
+
id: "marketing",
|
|
123
|
+
name: "Marketing e Publicidade",
|
|
124
|
+
description: "Cookies para publicidade direcionada e marketing",
|
|
125
|
+
essential: false
|
|
126
|
+
},
|
|
127
|
+
social: {
|
|
128
|
+
id: "social",
|
|
129
|
+
name: "Redes Sociais",
|
|
130
|
+
description: "Cookies para integra\xE7\xE3o com redes sociais e compartilhamento",
|
|
131
|
+
essential: false
|
|
132
|
+
},
|
|
133
|
+
personalization: {
|
|
134
|
+
id: "personalization",
|
|
135
|
+
name: "Personaliza\xE7\xE3o",
|
|
136
|
+
description: "Cookies para personaliza\xE7\xE3o de conte\xFAdo e experi\xEAncia",
|
|
137
|
+
essential: false
|
|
138
|
+
}
|
|
139
|
+
};
|
|
140
|
+
return definitions[category];
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
// src/utils/logger.ts
|
|
144
|
+
var LogLevel = /* @__PURE__ */ ((LogLevel2) => {
|
|
145
|
+
LogLevel2[LogLevel2["ERROR"] = 0] = "ERROR";
|
|
146
|
+
LogLevel2[LogLevel2["WARN"] = 1] = "WARN";
|
|
147
|
+
LogLevel2[LogLevel2["INFO"] = 2] = "INFO";
|
|
148
|
+
LogLevel2[LogLevel2["DEBUG"] = 3] = "DEBUG";
|
|
149
|
+
return LogLevel2;
|
|
150
|
+
})(LogLevel || {});
|
|
151
|
+
var _ConsentLogger = class _ConsentLogger {
|
|
152
|
+
constructor() {
|
|
153
|
+
this.enabled = _ConsentLogger.IS_DEVELOPMENT;
|
|
154
|
+
this.level = 2 /* INFO */;
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Habilita ou desabilita o sistema de logging.
|
|
158
|
+
* @param {boolean} enabled Se `true`, os logs serão exibidos; caso contrário, serão suprimidos.
|
|
159
|
+
*/
|
|
160
|
+
setEnabled(enabled) {
|
|
161
|
+
this.enabled = enabled;
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Define o nível mínimo de severidade para os logs.
|
|
165
|
+
* Mensagens com severidade menor que o nível definido não serão exibidas.
|
|
166
|
+
* @param {LogLevel} level O nível mínimo de severidade (ex: `LogLevel.DEBUG` para ver todos os logs).
|
|
167
|
+
*/
|
|
168
|
+
setLevel(level) {
|
|
169
|
+
this.level = level;
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Registra uma mensagem de erro.
|
|
173
|
+
* @param {...unknown[]} args Argumentos a serem logados.
|
|
174
|
+
*/
|
|
175
|
+
error(...args) {
|
|
176
|
+
if (this.enabled && this.level >= 0 /* ERROR */) {
|
|
177
|
+
console.error(_ConsentLogger.LOG_PREFIX, "[ERROR]", ...args);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Registra uma mensagem de aviso.
|
|
182
|
+
* Suprimido em produção por padrão (apenas se logging estiver explicitamente habilitado).
|
|
183
|
+
* @param {...unknown[]} args Argumentos a serem logados.
|
|
184
|
+
*/
|
|
185
|
+
warn(...args) {
|
|
186
|
+
if (this.enabled && this.level >= 1 /* WARN */ && !_ConsentLogger.IS_PRODUCTION) {
|
|
187
|
+
console.warn(_ConsentLogger.LOG_PREFIX, "[WARN]", ...args);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* Registra uma mensagem informativa.
|
|
192
|
+
* Suprimido em produção por padrão.
|
|
193
|
+
* @param {...unknown[]} args Argumentos a serem logados.
|
|
194
|
+
*/
|
|
195
|
+
info(...args) {
|
|
196
|
+
if (this.enabled && this.level >= 2 /* INFO */ && !_ConsentLogger.IS_PRODUCTION) {
|
|
197
|
+
console.info(_ConsentLogger.LOG_PREFIX, "[INFO]", ...args);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* Registra uma mensagem de depuração.
|
|
202
|
+
* Sempre suprimido em produção.
|
|
203
|
+
* @param {...unknown[]} args Argumentos a serem logados.
|
|
204
|
+
*/
|
|
205
|
+
debug(...args) {
|
|
206
|
+
if (this.enabled && this.level >= 3 /* DEBUG */ && !_ConsentLogger.IS_PRODUCTION) {
|
|
207
|
+
console.debug(_ConsentLogger.LOG_PREFIX, "[DEBUG]", ...args);
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
/**
|
|
211
|
+
* Inicia um grupo de logs no console.
|
|
212
|
+
* Suprimido em produção.
|
|
213
|
+
* @param {...unknown[]} args Argumentos para o título do grupo.
|
|
214
|
+
*/
|
|
215
|
+
group(...args) {
|
|
216
|
+
if (this.enabled && this.level >= 3 /* DEBUG */ && !_ConsentLogger.IS_PRODUCTION) {
|
|
217
|
+
console.group(_ConsentLogger.LOG_PREFIX, ...args);
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* Finaliza o grupo de logs mais recente no console.
|
|
222
|
+
* Suprimido em produção.
|
|
223
|
+
*/
|
|
224
|
+
groupEnd() {
|
|
225
|
+
if (this.enabled && this.level >= 3 /* DEBUG */ && !_ConsentLogger.IS_PRODUCTION) {
|
|
226
|
+
console.groupEnd();
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
/**
|
|
230
|
+
* Exibe dados tabulares no console.
|
|
231
|
+
* Suprimido em produção.
|
|
232
|
+
* @param {unknown} tabularData Dados a serem exibidos na tabela.
|
|
233
|
+
* @param {string[]} [properties] Propriedades opcionais para exibir.
|
|
234
|
+
*/
|
|
235
|
+
table(tabularData, properties) {
|
|
236
|
+
if (this.enabled && this.level >= 3 /* DEBUG */ && !_ConsentLogger.IS_PRODUCTION) {
|
|
237
|
+
console.table(tabularData, properties);
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
/**
|
|
241
|
+
* Registra informações sobre a compatibilidade do tema Material-UI.
|
|
242
|
+
* @param {unknown} themeInfo Objeto potencialmente parcial do tema (inspeção segura).
|
|
243
|
+
*/
|
|
244
|
+
themeCompatibility(themeInfo) {
|
|
245
|
+
const isRecord = (v) => typeof v === "object" && v !== null;
|
|
246
|
+
const theme = isRecord(themeInfo) ? themeInfo : void 0;
|
|
247
|
+
const palette = theme && isRecord(theme["palette"]) ? theme["palette"] : void 0;
|
|
248
|
+
const primary = palette && isRecord(palette["primary"]);
|
|
249
|
+
const transitions = theme && isRecord(theme["transitions"]) ? theme["transitions"] : void 0;
|
|
250
|
+
const duration = transitions && isRecord(transitions["duration"]);
|
|
251
|
+
this.debug("Theme compatibility check:", {
|
|
252
|
+
hasTheme: !!theme,
|
|
253
|
+
hasPalette: !!palette,
|
|
254
|
+
hasPrimary: !!primary,
|
|
255
|
+
hasTransitions: !!transitions,
|
|
256
|
+
hasDuration: !!duration
|
|
257
|
+
});
|
|
258
|
+
}
|
|
259
|
+
/**
|
|
260
|
+
* Registra mudanças no estado de consentimento.
|
|
261
|
+
* @param {string} action Ação que causou a mudança de estado.
|
|
262
|
+
* @param {{ consented?: boolean; isModalOpen?: boolean; preferences?: Record<string, unknown> }} state Estado atual.
|
|
263
|
+
*/
|
|
264
|
+
consentState(action, state) {
|
|
265
|
+
this.debug(`Consent state change [${action}]:`, {
|
|
266
|
+
consented: state.consented,
|
|
267
|
+
isModalOpen: state.isModalOpen,
|
|
268
|
+
preferencesCount: Object.keys(state.preferences || {}).length
|
|
269
|
+
});
|
|
270
|
+
}
|
|
271
|
+
/**
|
|
272
|
+
* Registra operações de cookie (leitura, escrita, remoção).
|
|
273
|
+
* @param {'read' | 'write' | 'delete'} operation Tipo de operação.
|
|
274
|
+
* @param {string} cookieName Nome do cookie.
|
|
275
|
+
* @param {unknown} [data] Dados associados, se aplicável.
|
|
276
|
+
*/
|
|
277
|
+
cookieOperation(operation, cookieName, data) {
|
|
278
|
+
this.debug(`Cookie ${operation}:`, {
|
|
279
|
+
name: cookieName,
|
|
280
|
+
hasData: !!data,
|
|
281
|
+
dataSize: data ? JSON.stringify(data).length : 0
|
|
282
|
+
});
|
|
283
|
+
}
|
|
284
|
+
/**
|
|
285
|
+
* Registra a renderização de um componente.
|
|
286
|
+
* @param {string} componentName Nome do componente.
|
|
287
|
+
* @param {Record<string, unknown>} [props] Propriedades do componente.
|
|
288
|
+
*/
|
|
289
|
+
componentRender(componentName, props) {
|
|
290
|
+
this.debug(`Component render [${componentName}]:`, {
|
|
291
|
+
hasProps: !!props,
|
|
292
|
+
propsKeys: props ? Object.keys(props) : []
|
|
293
|
+
});
|
|
294
|
+
}
|
|
295
|
+
/**
|
|
296
|
+
* Registra o status de carregamento de scripts de integração.
|
|
297
|
+
* @param {string} scriptName O nome do script.
|
|
298
|
+
* @param {'load' | 'remove'} action A ação realizada (carregar ou remover).
|
|
299
|
+
* @param {boolean} success Se a operação foi bem-sucedida.
|
|
300
|
+
*/
|
|
301
|
+
scriptIntegration(scriptName, action, success) {
|
|
302
|
+
this.info(`Script ${action} [${scriptName}]:`, success ? "SUCCESS" : "FAILED");
|
|
303
|
+
}
|
|
304
|
+
/**
|
|
305
|
+
* Registra chamadas à API interna da biblioteca.
|
|
306
|
+
* @param {string} method Nome do método da API chamado.
|
|
307
|
+
* @param {unknown} [params] Parâmetros passados para o método.
|
|
308
|
+
*/
|
|
309
|
+
apiUsage(method, params) {
|
|
310
|
+
this.debug(`API call [${method}]:`, params);
|
|
311
|
+
}
|
|
312
|
+
};
|
|
313
|
+
_ConsentLogger.IS_DEVELOPMENT = typeof globalThis !== "undefined" && globalThis.process?.env?.NODE_ENV === "development";
|
|
314
|
+
_ConsentLogger.IS_PRODUCTION = typeof globalThis !== "undefined" && globalThis.process?.env?.NODE_ENV === "production";
|
|
315
|
+
_ConsentLogger.LOG_PREFIX = "[react-lgpd-consent]";
|
|
316
|
+
var ConsentLogger = _ConsentLogger;
|
|
317
|
+
var logger = new ConsentLogger();
|
|
318
|
+
function setDebugLogging(enabled, level = 2 /* INFO */) {
|
|
319
|
+
logger.setEnabled(enabled);
|
|
320
|
+
logger.setLevel(level);
|
|
321
|
+
logger.info(`Debug logging ${enabled ? "enabled" : "disabled"} with level ${LogLevel[level]}`);
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
// src/utils/cookieUtils.ts
|
|
325
|
+
var DEFAULT_COOKIE_OPTS = {
|
|
326
|
+
name: "cookieConsent",
|
|
327
|
+
maxAgeDays: 365,
|
|
328
|
+
sameSite: "Lax",
|
|
329
|
+
secure: typeof window !== "undefined" ? window.location.protocol === "https:" : false,
|
|
330
|
+
path: "/"
|
|
331
|
+
};
|
|
332
|
+
var COOKIE_SCHEMA_VERSION = "1.0";
|
|
333
|
+
function readConsentCookie(name = DEFAULT_COOKIE_OPTS.name) {
|
|
334
|
+
logger.debug("Reading consent cookie", { name });
|
|
335
|
+
if (typeof document === "undefined") {
|
|
336
|
+
logger.debug("Cookie read skipped: server-side environment");
|
|
337
|
+
return null;
|
|
338
|
+
}
|
|
339
|
+
const raw = Cookies__default.default.get(name);
|
|
340
|
+
if (!raw) {
|
|
341
|
+
logger.debug("No consent cookie found");
|
|
342
|
+
return null;
|
|
343
|
+
}
|
|
344
|
+
try {
|
|
345
|
+
const data = JSON.parse(raw);
|
|
346
|
+
logger.cookieOperation("read", name, data);
|
|
347
|
+
if (!data.version) {
|
|
348
|
+
logger.debug("Migrating legacy cookie format");
|
|
349
|
+
return migrateLegacyCookie(data);
|
|
350
|
+
}
|
|
351
|
+
if (data.version !== COOKIE_SCHEMA_VERSION) {
|
|
352
|
+
logger.warn(`Cookie version mismatch: ${data.version} != ${COOKIE_SCHEMA_VERSION}`);
|
|
353
|
+
return null;
|
|
354
|
+
}
|
|
355
|
+
return data;
|
|
356
|
+
} catch (error) {
|
|
357
|
+
logger.error("Error parsing consent cookie", error);
|
|
358
|
+
return null;
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
function migrateLegacyCookie(legacyData) {
|
|
362
|
+
try {
|
|
363
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
364
|
+
return {
|
|
365
|
+
version: COOKIE_SCHEMA_VERSION,
|
|
366
|
+
consented: Boolean(legacyData.consented) || false,
|
|
367
|
+
preferences: legacyData.preferences && typeof legacyData.preferences === "object" ? legacyData.preferences : { necessary: true },
|
|
368
|
+
consentDate: now,
|
|
369
|
+
lastUpdate: now,
|
|
370
|
+
source: "banner",
|
|
371
|
+
isModalOpen: false
|
|
372
|
+
};
|
|
373
|
+
} catch {
|
|
374
|
+
return null;
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
function writeConsentCookie(state, config, opts, source = "banner") {
|
|
378
|
+
if (typeof document === "undefined") {
|
|
379
|
+
logger.debug("Cookie write skipped: server-side environment");
|
|
380
|
+
return;
|
|
381
|
+
}
|
|
382
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
383
|
+
const o = { ...DEFAULT_COOKIE_OPTS, ...opts };
|
|
384
|
+
const cookieData = {
|
|
385
|
+
version: COOKIE_SCHEMA_VERSION,
|
|
386
|
+
consented: state.consented,
|
|
387
|
+
preferences: state.preferences,
|
|
388
|
+
consentDate: state.consentDate || now,
|
|
389
|
+
lastUpdate: now,
|
|
390
|
+
source,
|
|
391
|
+
projectConfig: config
|
|
392
|
+
};
|
|
393
|
+
logger.cookieOperation("write", o.name, cookieData);
|
|
394
|
+
Cookies__default.default.set(o.name, JSON.stringify(cookieData), {
|
|
395
|
+
expires: o.maxAgeDays,
|
|
396
|
+
sameSite: o.sameSite,
|
|
397
|
+
secure: o.secure,
|
|
398
|
+
path: o.path
|
|
399
|
+
});
|
|
400
|
+
logger.info("Consent cookie saved", {
|
|
401
|
+
consented: cookieData.consented,
|
|
402
|
+
source: cookieData.source,
|
|
403
|
+
preferencesCount: Object.keys(cookieData.preferences).length
|
|
404
|
+
});
|
|
405
|
+
}
|
|
406
|
+
function removeConsentCookie(opts) {
|
|
407
|
+
if (typeof document === "undefined") {
|
|
408
|
+
logger.debug("Cookie removal skipped: server-side environment");
|
|
409
|
+
return;
|
|
410
|
+
}
|
|
411
|
+
const o = { ...DEFAULT_COOKIE_OPTS, ...opts };
|
|
412
|
+
logger.cookieOperation("delete", o.name);
|
|
413
|
+
Cookies__default.default.remove(o.name, { path: o.path });
|
|
414
|
+
logger.info("Consent cookie removed");
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
// src/utils/dataLayerEvents.ts
|
|
418
|
+
var LIBRARY_VERSION = "0.5.0";
|
|
419
|
+
function ensureDataLayer() {
|
|
420
|
+
if (typeof window === "undefined") return;
|
|
421
|
+
if (!window.dataLayer) {
|
|
422
|
+
window.dataLayer = [];
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
function pushConsentInitializedEvent(categories) {
|
|
426
|
+
if (typeof window === "undefined") return;
|
|
427
|
+
ensureDataLayer();
|
|
428
|
+
const event = {
|
|
429
|
+
event: "consent_initialized",
|
|
430
|
+
consent_version: LIBRARY_VERSION,
|
|
431
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
432
|
+
categories
|
|
433
|
+
};
|
|
434
|
+
window.dataLayer?.push(event);
|
|
435
|
+
}
|
|
436
|
+
function pushConsentUpdatedEvent(categories, origin, previousCategories) {
|
|
437
|
+
if (typeof window === "undefined") return;
|
|
438
|
+
ensureDataLayer();
|
|
439
|
+
const changedCategories = previousCategories ? Object.keys(categories).filter((key) => categories[key] !== previousCategories[key]) : [];
|
|
440
|
+
const event = {
|
|
441
|
+
event: "consent_updated",
|
|
442
|
+
consent_version: LIBRARY_VERSION,
|
|
443
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
444
|
+
origin,
|
|
445
|
+
categories,
|
|
446
|
+
changed_categories: changedCategories
|
|
447
|
+
};
|
|
448
|
+
window.dataLayer?.push(event);
|
|
449
|
+
}
|
|
450
|
+
function useDataLayerEvents() {
|
|
451
|
+
return {
|
|
452
|
+
pushInitialized: pushConsentInitializedEvent,
|
|
453
|
+
pushUpdated: pushConsentUpdatedEvent
|
|
454
|
+
};
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
// src/hooks/useConsent.ts
|
|
458
|
+
function useConsent() {
|
|
459
|
+
const state = useConsentStateInternal();
|
|
460
|
+
const actions = useConsentActionsInternal();
|
|
461
|
+
return {
|
|
462
|
+
consented: state.consented,
|
|
463
|
+
preferences: state.preferences,
|
|
464
|
+
isModalOpen: state.isModalOpen,
|
|
465
|
+
acceptAll: actions.acceptAll,
|
|
466
|
+
rejectAll: actions.rejectAll,
|
|
467
|
+
setPreference: actions.setPreference,
|
|
468
|
+
setPreferences: actions.setPreferences,
|
|
469
|
+
openPreferences: actions.openPreferences,
|
|
470
|
+
closePreferences: actions.closePreferences,
|
|
471
|
+
resetConsent: actions.resetConsent
|
|
472
|
+
};
|
|
473
|
+
}
|
|
474
|
+
function useConsentTexts() {
|
|
475
|
+
return useConsentTextsInternal();
|
|
476
|
+
}
|
|
477
|
+
function useConsentHydration() {
|
|
478
|
+
return useConsentHydrationInternal();
|
|
479
|
+
}
|
|
480
|
+
var globalOpenPreferences = null;
|
|
481
|
+
function _registerGlobalOpenPreferences(openPreferences) {
|
|
482
|
+
globalOpenPreferences = openPreferences;
|
|
483
|
+
}
|
|
484
|
+
function _unregisterGlobalOpenPreferences() {
|
|
485
|
+
globalOpenPreferences = null;
|
|
486
|
+
}
|
|
487
|
+
function useOpenPreferencesModal() {
|
|
488
|
+
const actions = useConsentActionsInternal();
|
|
489
|
+
if (!actions) {
|
|
490
|
+
throw new Error(
|
|
491
|
+
"[LGPD-CONSENT] useOpenPreferencesModal deve ser usado dentro do ConsentProvider. Envolva seu componente com <ConsentProvider>."
|
|
492
|
+
);
|
|
493
|
+
}
|
|
494
|
+
return actions.openPreferences;
|
|
495
|
+
}
|
|
496
|
+
function openPreferencesModal() {
|
|
497
|
+
if (globalOpenPreferences) {
|
|
498
|
+
globalOpenPreferences();
|
|
499
|
+
} else {
|
|
500
|
+
logger.warn(
|
|
501
|
+
"openPreferencesModal called but no ConsentProvider is mounted. Make sure ConsentProvider is rendered before calling this function."
|
|
502
|
+
);
|
|
503
|
+
}
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
// src/utils/cookieRegistry.ts
|
|
507
|
+
var COOKIE_PATTERNS_BY_CATEGORY = {
|
|
508
|
+
necessary: ["cookieConsent"],
|
|
509
|
+
analytics: ["_ga", "_ga_*", "_gid", "_gcl_au", "_hj*", "mp_*", "_clck", "_clsk"],
|
|
510
|
+
functional: ["intercom-*", "__zlcmid", "_zendesk_shared_session", "_userway_*"],
|
|
511
|
+
marketing: ["_fbp", "fr"],
|
|
512
|
+
social: [],
|
|
513
|
+
personalization: []
|
|
514
|
+
};
|
|
515
|
+
var COOKIE_INFO_BY_INTEGRATION = {
|
|
516
|
+
"google-analytics": [
|
|
517
|
+
{
|
|
518
|
+
name: "_ga",
|
|
519
|
+
purpose: "Identifica\xE7\xE3o \xFAnica de visitantes para an\xE1lise de tr\xE1fego",
|
|
520
|
+
duration: "2 anos",
|
|
521
|
+
provider: "Google Analytics"
|
|
522
|
+
},
|
|
523
|
+
{
|
|
524
|
+
name: "_ga_*",
|
|
525
|
+
purpose: "Rastreamento de sess\xF5es e eventos espec\xEDficos do stream GA4",
|
|
526
|
+
duration: "2 anos",
|
|
527
|
+
provider: "Google Analytics"
|
|
528
|
+
},
|
|
529
|
+
{
|
|
530
|
+
name: "_gid",
|
|
531
|
+
purpose: "Distin\xE7\xE3o de visitantes \xFAnicos em per\xEDodo de 24h",
|
|
532
|
+
duration: "24 horas",
|
|
533
|
+
provider: "Google Analytics"
|
|
534
|
+
}
|
|
535
|
+
],
|
|
536
|
+
"google-tag-manager": [
|
|
537
|
+
{
|
|
538
|
+
name: "_gcl_au",
|
|
539
|
+
purpose: "Rastreamento de convers\xF5es de an\xFAncios",
|
|
540
|
+
duration: "90 dias",
|
|
541
|
+
provider: "Google"
|
|
542
|
+
}
|
|
543
|
+
],
|
|
544
|
+
hotjar: [
|
|
545
|
+
{
|
|
546
|
+
name: "_hjSession_*",
|
|
547
|
+
purpose: "Rastreamento de sess\xE3o",
|
|
548
|
+
duration: "30 minutos",
|
|
549
|
+
provider: "Hotjar"
|
|
550
|
+
},
|
|
551
|
+
{
|
|
552
|
+
name: "_hjSessionUser_*",
|
|
553
|
+
purpose: "Persist\xEAncia de usu\xE1rio entre sess\xF5es",
|
|
554
|
+
duration: "365 dias",
|
|
555
|
+
provider: "Hotjar"
|
|
556
|
+
},
|
|
557
|
+
{
|
|
558
|
+
name: "_hjFirstSeen",
|
|
559
|
+
purpose: "Detec\xE7\xE3o da primeira visita do usu\xE1rio",
|
|
560
|
+
duration: "Sess\xE3o",
|
|
561
|
+
provider: "Hotjar"
|
|
562
|
+
}
|
|
563
|
+
],
|
|
564
|
+
mixpanel: [
|
|
565
|
+
{
|
|
566
|
+
name: "mp_*",
|
|
567
|
+
purpose: "Rastreamento de eventos e propriedades do usu\xE1rio para analytics",
|
|
568
|
+
duration: "1 ano",
|
|
569
|
+
provider: "Mixpanel"
|
|
570
|
+
}
|
|
571
|
+
],
|
|
572
|
+
clarity: [
|
|
573
|
+
{
|
|
574
|
+
name: "_clck",
|
|
575
|
+
purpose: "Identificador de usu\xE1rio",
|
|
576
|
+
duration: "365 dias",
|
|
577
|
+
provider: "Microsoft"
|
|
578
|
+
},
|
|
579
|
+
{ name: "_clsk", purpose: "Rastreamento de sess\xE3o", duration: "1 dia", provider: "Microsoft" }
|
|
580
|
+
],
|
|
581
|
+
intercom: [
|
|
582
|
+
{
|
|
583
|
+
name: "intercom-id-*",
|
|
584
|
+
purpose: "Identificador do usu\xE1rio",
|
|
585
|
+
duration: "9 meses",
|
|
586
|
+
provider: "Intercom"
|
|
587
|
+
},
|
|
588
|
+
{
|
|
589
|
+
name: "intercom-session-*",
|
|
590
|
+
purpose: "Gerenciamento de sess\xE3o",
|
|
591
|
+
duration: "1 semana",
|
|
592
|
+
provider: "Intercom"
|
|
593
|
+
}
|
|
594
|
+
],
|
|
595
|
+
"zendesk-chat": [
|
|
596
|
+
{
|
|
597
|
+
name: "__zlcmid",
|
|
598
|
+
purpose: "Identificador de sess\xE3o de chat",
|
|
599
|
+
duration: "1 ano",
|
|
600
|
+
provider: "Zendesk"
|
|
601
|
+
},
|
|
602
|
+
{
|
|
603
|
+
name: "_zendesk_shared_session",
|
|
604
|
+
purpose: "Gerenciamento de sess\xE3o",
|
|
605
|
+
duration: "Sess\xE3o",
|
|
606
|
+
provider: "Zendesk"
|
|
607
|
+
}
|
|
608
|
+
],
|
|
609
|
+
userway: [
|
|
610
|
+
{
|
|
611
|
+
name: "_userway_*",
|
|
612
|
+
purpose: "Prefer\xEAncias de acessibilidade",
|
|
613
|
+
duration: "1 ano",
|
|
614
|
+
provider: "UserWay"
|
|
615
|
+
}
|
|
616
|
+
],
|
|
617
|
+
"facebook-pixel": [
|
|
618
|
+
{ name: "_fbp", purpose: "Rastreamento de an\xFAncios", duration: "90 dias", provider: "Meta" },
|
|
619
|
+
{ name: "fr", purpose: "Direcionamento de an\xFAncios", duration: "90 dias", provider: "Meta" }
|
|
620
|
+
]
|
|
621
|
+
};
|
|
622
|
+
var INTEGRATION_DEFAULT_CATEGORY = {
|
|
623
|
+
"google-analytics": "analytics",
|
|
624
|
+
"google-tag-manager": "analytics",
|
|
625
|
+
hotjar: "analytics",
|
|
626
|
+
mixpanel: "analytics",
|
|
627
|
+
clarity: "analytics",
|
|
628
|
+
intercom: "functional",
|
|
629
|
+
"zendesk-chat": "functional",
|
|
630
|
+
userway: "functional",
|
|
631
|
+
"facebook-pixel": "marketing"
|
|
632
|
+
};
|
|
633
|
+
var COOKIE_CATALOG_OVERRIDES = {};
|
|
634
|
+
var COOKIE_CATEGORY_OVERRIDES = {};
|
|
635
|
+
function setCookieCatalogOverrides(overrides) {
|
|
636
|
+
COOKIE_CATALOG_OVERRIDES = {
|
|
637
|
+
byCategory: { ...COOKIE_CATALOG_OVERRIDES.byCategory || {}, ...overrides.byCategory || {} },
|
|
638
|
+
byIntegration: {
|
|
639
|
+
...COOKIE_CATALOG_OVERRIDES.byIntegration || {},
|
|
640
|
+
...overrides.byIntegration || {}
|
|
641
|
+
}
|
|
642
|
+
};
|
|
643
|
+
}
|
|
644
|
+
function setCookieCategoryOverrides(map) {
|
|
645
|
+
COOKIE_CATEGORY_OVERRIDES = { ...COOKIE_CATEGORY_OVERRIDES, ...map };
|
|
646
|
+
}
|
|
647
|
+
function matchPattern(name, pattern) {
|
|
648
|
+
if (pattern.endsWith("*")) return name.startsWith(pattern.slice(0, -1));
|
|
649
|
+
return name === pattern;
|
|
650
|
+
}
|
|
651
|
+
function getCookiesInfoForCategory(categoryId, usedIntegrations) {
|
|
652
|
+
const result = [];
|
|
653
|
+
usedIntegrations.forEach((id) => {
|
|
654
|
+
const defaultCat = INTEGRATION_DEFAULT_CATEGORY[id];
|
|
655
|
+
const defaults = COOKIE_INFO_BY_INTEGRATION[id] || [];
|
|
656
|
+
const list = COOKIE_CATALOG_OVERRIDES.byIntegration?.[id] || defaults;
|
|
657
|
+
list.forEach((desc) => {
|
|
658
|
+
const overrideCat = Object.entries(COOKIE_CATEGORY_OVERRIDES).find(
|
|
659
|
+
([pattern]) => matchPattern(desc.name, pattern)
|
|
660
|
+
)?.[1];
|
|
661
|
+
const finalCat = overrideCat ?? defaultCat;
|
|
662
|
+
if (finalCat === categoryId && !result.find((d) => d.name === desc.name)) result.push(desc);
|
|
663
|
+
});
|
|
664
|
+
});
|
|
665
|
+
const catOverride = COOKIE_CATALOG_OVERRIDES.byCategory?.[categoryId];
|
|
666
|
+
if (catOverride) {
|
|
667
|
+
catOverride.forEach((d) => {
|
|
668
|
+
const idx = result.findIndex((x) => x.name === d.name);
|
|
669
|
+
if (idx >= 0) result[idx] = d;
|
|
670
|
+
else result.push(d);
|
|
671
|
+
});
|
|
672
|
+
}
|
|
673
|
+
if (categoryId === "necessary") {
|
|
674
|
+
if (!result.find((d) => d.name === "cookieConsent")) {
|
|
675
|
+
result.push({
|
|
676
|
+
name: "cookieConsent",
|
|
677
|
+
purpose: "Armazena suas prefer\xEAncias de consentimento",
|
|
678
|
+
duration: "365 dias",
|
|
679
|
+
provider: "Este site"
|
|
680
|
+
});
|
|
681
|
+
}
|
|
682
|
+
}
|
|
683
|
+
return result;
|
|
684
|
+
}
|
|
685
|
+
|
|
686
|
+
// src/utils/developerGuidance.ts
|
|
687
|
+
var DEFAULT_PROJECT_CATEGORIES = {
|
|
688
|
+
enabledCategories: ["analytics"]
|
|
689
|
+
};
|
|
690
|
+
function calculateComplianceScore(guidance) {
|
|
691
|
+
let score = 0;
|
|
692
|
+
const maxScore = 100;
|
|
693
|
+
if (!guidance.usingDefaults) score += 30;
|
|
694
|
+
const totalCategories = guidance.activeCategoriesInfo.length;
|
|
695
|
+
const toggleableCategories = guidance.activeCategoriesInfo.filter((c) => c.uiRequired).length;
|
|
696
|
+
if (totalCategories > 1) score += 20;
|
|
697
|
+
if (toggleableCategories >= 2 && toggleableCategories <= 4) score += 25;
|
|
698
|
+
const criticalWarnings = guidance.messages.filter((m) => m.severity === "error").length;
|
|
699
|
+
const warnings = guidance.messages.filter((m) => m.severity === "warning").length;
|
|
700
|
+
if (criticalWarnings === 0) score += 15;
|
|
701
|
+
if (warnings === 0) score += 10;
|
|
702
|
+
return Math.min(score, maxScore);
|
|
703
|
+
}
|
|
704
|
+
function analyzeDeveloperConfiguration(config) {
|
|
705
|
+
const guidance = {
|
|
706
|
+
warnings: [],
|
|
707
|
+
suggestions: [],
|
|
708
|
+
messages: [],
|
|
709
|
+
activeCategoriesInfo: [],
|
|
710
|
+
usingDefaults: !config,
|
|
711
|
+
complianceScore: 0
|
|
712
|
+
};
|
|
713
|
+
const addMessage = (severity, message, category, actionable = true) => {
|
|
714
|
+
const guidanceMessage = { severity, message, category, actionable };
|
|
715
|
+
guidance.messages.push(guidanceMessage);
|
|
716
|
+
if (severity === "warning" || severity === "error") {
|
|
717
|
+
guidance.warnings.push(message);
|
|
718
|
+
} else {
|
|
719
|
+
guidance.suggestions.push(message);
|
|
720
|
+
}
|
|
721
|
+
};
|
|
722
|
+
const finalConfig = config || DEFAULT_PROJECT_CATEGORIES;
|
|
723
|
+
if (!config) {
|
|
724
|
+
addMessage(
|
|
725
|
+
"warning",
|
|
726
|
+
'LGPD-CONSENT: Nenhuma configura\xE7\xE3o de categorias especificada. Usando padr\xE3o: necessary + analytics. Para produ\xE7\xE3o, especifique explicitamente as categorias via prop "categories".',
|
|
727
|
+
"configuration"
|
|
728
|
+
);
|
|
729
|
+
}
|
|
730
|
+
guidance.activeCategoriesInfo.push({
|
|
731
|
+
id: "necessary",
|
|
732
|
+
name: "Cookies Necess\xE1rios",
|
|
733
|
+
description: "Essenciais para funcionamento b\xE1sico do site",
|
|
734
|
+
essential: true,
|
|
735
|
+
uiRequired: false,
|
|
736
|
+
cookies: COOKIE_PATTERNS_BY_CATEGORY["necessary"]
|
|
737
|
+
});
|
|
738
|
+
const enabled = finalConfig.enabledCategories || [];
|
|
739
|
+
const NAMES = {
|
|
740
|
+
analytics: { name: "Cookies Anal\xEDticos", description: "Medem uso e performance do site" },
|
|
741
|
+
functional: {
|
|
742
|
+
name: "Cookies Funcionais",
|
|
743
|
+
description: "Melhoram experi\xEAncia e funcionalidades"
|
|
744
|
+
},
|
|
745
|
+
marketing: { name: "Cookies de Marketing", description: "Publicidade direcionada e campanhas" },
|
|
746
|
+
social: { name: "Cookies de Redes Sociais", description: "Integra\xE7\xE3o com plataformas sociais" },
|
|
747
|
+
personalization: { name: "Cookies de Personaliza\xE7\xE3o", description: "Adapta\xE7\xE3o de conte\xFAdo" }
|
|
748
|
+
};
|
|
749
|
+
enabled.forEach((id) => {
|
|
750
|
+
const info = NAMES[id];
|
|
751
|
+
if (info) {
|
|
752
|
+
guidance.activeCategoriesInfo.push({
|
|
753
|
+
id,
|
|
754
|
+
name: info.name,
|
|
755
|
+
description: info.description,
|
|
756
|
+
essential: false,
|
|
757
|
+
uiRequired: true,
|
|
758
|
+
cookies: COOKIE_PATTERNS_BY_CATEGORY[id]
|
|
759
|
+
});
|
|
760
|
+
}
|
|
761
|
+
});
|
|
762
|
+
const custom = finalConfig.customCategories || [];
|
|
763
|
+
custom.forEach((cat) => {
|
|
764
|
+
if (!cat?.id || cat.id === "necessary") return;
|
|
765
|
+
guidance.activeCategoriesInfo.push({
|
|
766
|
+
id: cat.id,
|
|
767
|
+
name: cat.name,
|
|
768
|
+
description: cat.description,
|
|
769
|
+
essential: !!cat.essential,
|
|
770
|
+
uiRequired: !cat.essential,
|
|
771
|
+
cookies: cat.cookies
|
|
772
|
+
});
|
|
773
|
+
});
|
|
774
|
+
try {
|
|
775
|
+
const gt = globalThis;
|
|
776
|
+
const implied = (gt.__LGPD_REQUIRED_CATEGORIES__ || []).filter(Boolean);
|
|
777
|
+
implied.forEach((id) => {
|
|
778
|
+
if (!guidance.activeCategoriesInfo.find((c) => c.id === id)) {
|
|
779
|
+
const info = NAMES[id];
|
|
780
|
+
if (info) {
|
|
781
|
+
guidance.activeCategoriesInfo.push({
|
|
782
|
+
id,
|
|
783
|
+
name: info.name,
|
|
784
|
+
description: info.description,
|
|
785
|
+
essential: false,
|
|
786
|
+
uiRequired: true,
|
|
787
|
+
cookies: COOKIE_PATTERNS_BY_CATEGORY[id]
|
|
788
|
+
});
|
|
789
|
+
if (!enabled.includes(id)) {
|
|
790
|
+
addMessage(
|
|
791
|
+
"info",
|
|
792
|
+
`Integra\xE7\xF5es detectadas requerem a categoria '${id}'. Adicione-a em categories.enabledCategories.`,
|
|
793
|
+
"integration"
|
|
794
|
+
);
|
|
795
|
+
}
|
|
796
|
+
}
|
|
797
|
+
}
|
|
798
|
+
});
|
|
799
|
+
} catch {
|
|
800
|
+
}
|
|
801
|
+
try {
|
|
802
|
+
const gt2 = globalThis;
|
|
803
|
+
const used = gt2.__LGPD_USED_INTEGRATIONS__ || [];
|
|
804
|
+
guidance.activeCategoriesInfo = guidance.activeCategoriesInfo.map((c) => {
|
|
805
|
+
const info = getCookiesInfoForCategory(c.id, used);
|
|
806
|
+
const names = Array.from(/* @__PURE__ */ new Set([...c.cookies || [], ...info.map((d) => d.name)]));
|
|
807
|
+
return { ...c, cookies: names };
|
|
808
|
+
});
|
|
809
|
+
} catch {
|
|
810
|
+
}
|
|
811
|
+
const totalToggleable = guidance.activeCategoriesInfo.filter((c) => c.uiRequired).length;
|
|
812
|
+
if (totalToggleable === 0) {
|
|
813
|
+
addMessage(
|
|
814
|
+
"info",
|
|
815
|
+
'Apenas cookies necess\xE1rios est\xE3o configurados. Para compliance LGPD, considere adicionar categorias como "analytics" ou "functional" conforme uso real.',
|
|
816
|
+
"compliance"
|
|
817
|
+
);
|
|
818
|
+
}
|
|
819
|
+
if (totalToggleable > 5) {
|
|
820
|
+
addMessage(
|
|
821
|
+
"warning",
|
|
822
|
+
`${totalToggleable} categorias opcionais detectadas. UI com muitas op\xE7\xF5es pode prejudicar a experi\xEAncia. Considere agrupar categorias similares.`,
|
|
823
|
+
"usability"
|
|
824
|
+
);
|
|
825
|
+
}
|
|
826
|
+
guidance.complianceScore = calculateComplianceScore(guidance);
|
|
827
|
+
return guidance;
|
|
828
|
+
}
|
|
829
|
+
var GUIDANCE_CACHE = /* @__PURE__ */ new Set();
|
|
830
|
+
var SESSION_LOGGED = {
|
|
831
|
+
intro: false,
|
|
832
|
+
bestPractices: false
|
|
833
|
+
};
|
|
834
|
+
function getComplianceScoreColor(score) {
|
|
835
|
+
if (score >= 80) return "#4caf50";
|
|
836
|
+
if (score >= 60) return "#ff9800";
|
|
837
|
+
return "#f44336";
|
|
838
|
+
}
|
|
839
|
+
function logComplianceScore(prefix, score) {
|
|
840
|
+
const color = getComplianceScoreColor(score);
|
|
841
|
+
console.log(
|
|
842
|
+
`%c${prefix} Score de Conformidade LGPD: ${score}/100`,
|
|
843
|
+
`color: ${color}; font-weight: bold; font-size: 14px;`
|
|
844
|
+
);
|
|
845
|
+
}
|
|
846
|
+
function logMessagesByType(prefix, messages, type, config) {
|
|
847
|
+
const filteredMessages = messages.filter((m) => m.severity === type);
|
|
848
|
+
if (filteredMessages.length === 0) return false;
|
|
849
|
+
const typeConfig = {
|
|
850
|
+
error: {
|
|
851
|
+
show: config.showWarnings,
|
|
852
|
+
title: "Erros Cr\xEDticos",
|
|
853
|
+
color: "#d32f2f",
|
|
854
|
+
method: console.error
|
|
855
|
+
},
|
|
856
|
+
warning: {
|
|
857
|
+
show: config.showWarnings,
|
|
858
|
+
title: "Avisos de Configura\xE7\xE3o",
|
|
859
|
+
color: "#f57c00",
|
|
860
|
+
method: console.warn
|
|
861
|
+
},
|
|
862
|
+
info: {
|
|
863
|
+
show: config.showSuggestions,
|
|
864
|
+
title: "Sugest\xF5es",
|
|
865
|
+
color: "#2196f3",
|
|
866
|
+
method: console.info
|
|
867
|
+
}
|
|
868
|
+
};
|
|
869
|
+
const typeSettings = typeConfig[type];
|
|
870
|
+
if (!typeSettings.show) return false;
|
|
871
|
+
console.group(
|
|
872
|
+
`%c${prefix} ${typeSettings.title}`,
|
|
873
|
+
`color: ${typeSettings.color}; font-weight: bold;`
|
|
874
|
+
);
|
|
875
|
+
filteredMessages.forEach(
|
|
876
|
+
(msg) => typeSettings.method(
|
|
877
|
+
`%c${prefix}%c ${msg.message}`,
|
|
878
|
+
`color: ${typeSettings.color};`,
|
|
879
|
+
"color: #333;"
|
|
880
|
+
)
|
|
881
|
+
);
|
|
882
|
+
console.groupEnd();
|
|
883
|
+
return true;
|
|
884
|
+
}
|
|
885
|
+
function getGuidanceHash(guidance) {
|
|
886
|
+
const sortedWarnings = [...guidance.warnings].sort((a, b) => a.localeCompare(b));
|
|
887
|
+
const sortedSuggestions = [...guidance.suggestions].sort(
|
|
888
|
+
(a, b) => a.localeCompare(b)
|
|
889
|
+
);
|
|
890
|
+
const sortedCategories = guidance.activeCategoriesInfo.map((c) => c.id).sort((a, b) => a.localeCompare(b));
|
|
891
|
+
return JSON.stringify({
|
|
892
|
+
warnings: sortedWarnings,
|
|
893
|
+
suggestions: sortedSuggestions,
|
|
894
|
+
categories: sortedCategories,
|
|
895
|
+
usingDefaults: guidance.usingDefaults
|
|
896
|
+
});
|
|
897
|
+
}
|
|
898
|
+
function logIntroOnce() {
|
|
899
|
+
if (SESSION_LOGGED.intro) return;
|
|
900
|
+
SESSION_LOGGED.intro = true;
|
|
901
|
+
console.log(
|
|
902
|
+
`%c\u{1F36A} LGPD-CONSENT %c- Sistema de Consentimento Ativo`,
|
|
903
|
+
"background: #4caf50; color: white; padding: 4px 8px; border-radius: 4px; font-weight: bold;",
|
|
904
|
+
"color: #2e7d32; font-weight: 500;"
|
|
905
|
+
);
|
|
906
|
+
}
|
|
907
|
+
function logServerSideIfAvailable(guidance) {
|
|
908
|
+
try {
|
|
909
|
+
const gt = globalThis;
|
|
910
|
+
if (gt.process?.stdout?.write) {
|
|
911
|
+
const prefix = "\x1B[36m[LGPD-CONSENT]\x1B[0m";
|
|
912
|
+
const warnings = guidance.warnings.length;
|
|
913
|
+
const suggestions = guidance.suggestions.length;
|
|
914
|
+
const stdout = gt.process.stdout;
|
|
915
|
+
if (warnings > 0 || suggestions > 0) {
|
|
916
|
+
stdout.write(`${prefix} \u{1F527} Config: ${warnings} avisos, ${suggestions} sugest\xF5es
|
|
917
|
+
`);
|
|
918
|
+
if (warnings > 0) {
|
|
919
|
+
guidance.warnings.forEach((w) => {
|
|
920
|
+
stdout.write(`${prefix} \x1B[33m\u26A0\uFE0F ${w}\x1B[0m
|
|
921
|
+
`);
|
|
922
|
+
});
|
|
923
|
+
}
|
|
924
|
+
if (suggestions > 0) {
|
|
925
|
+
guidance.suggestions.forEach((s) => {
|
|
926
|
+
stdout.write(`${prefix} \x1B[36m\u{1F4A1} ${s}\x1B[0m
|
|
927
|
+
`);
|
|
928
|
+
});
|
|
929
|
+
}
|
|
930
|
+
}
|
|
931
|
+
}
|
|
932
|
+
} catch {
|
|
933
|
+
}
|
|
934
|
+
}
|
|
935
|
+
function logDeveloperGuidance(guidance, disableGuidanceProp, config) {
|
|
936
|
+
const gt = globalThis;
|
|
937
|
+
const nodeEnv = typeof gt.process !== "undefined" ? gt.process?.env?.NODE_ENV : void 0;
|
|
938
|
+
const isProd = nodeEnv === "production" || gt.__LGPD_PRODUCTION__ === true;
|
|
939
|
+
if (isProd || disableGuidanceProp) return;
|
|
940
|
+
const guidanceHash = getGuidanceHash(guidance);
|
|
941
|
+
if (GUIDANCE_CACHE.has(guidanceHash)) return;
|
|
942
|
+
GUIDANCE_CACHE.add(guidanceHash);
|
|
943
|
+
logServerSideIfAvailable(guidance);
|
|
944
|
+
const guidanceConfig = {
|
|
945
|
+
showWarnings: true,
|
|
946
|
+
showSuggestions: true,
|
|
947
|
+
showCategoriesTable: true,
|
|
948
|
+
showBestPractices: true,
|
|
949
|
+
showComplianceScore: true,
|
|
950
|
+
minimumSeverity: "info",
|
|
951
|
+
...config
|
|
952
|
+
};
|
|
953
|
+
if (guidanceConfig.messageProcessor) {
|
|
954
|
+
guidanceConfig.messageProcessor(guidance.messages);
|
|
955
|
+
return;
|
|
956
|
+
}
|
|
957
|
+
logIntroOnce();
|
|
958
|
+
const PREFIX = "\u{1F36A}";
|
|
959
|
+
let hasImportantInfo = false;
|
|
960
|
+
const filteredMessages = guidance.messages.filter((msg) => {
|
|
961
|
+
const severityLevels = { info: 0, warning: 1, error: 2 };
|
|
962
|
+
const minLevel = severityLevels[guidanceConfig.minimumSeverity || "info"];
|
|
963
|
+
const msgLevel = severityLevels[msg.severity];
|
|
964
|
+
return msgLevel >= minLevel;
|
|
965
|
+
});
|
|
966
|
+
hasImportantInfo = logMessagesByType(PREFIX, filteredMessages, "error", guidanceConfig) || hasImportantInfo;
|
|
967
|
+
hasImportantInfo = logMessagesByType(PREFIX, filteredMessages, "warning", guidanceConfig) || hasImportantInfo;
|
|
968
|
+
if (hasImportantInfo || guidance.usingDefaults) {
|
|
969
|
+
hasImportantInfo = logMessagesByType(PREFIX, filteredMessages, "info", guidanceConfig) || hasImportantInfo;
|
|
970
|
+
}
|
|
971
|
+
if (guidanceConfig.showComplianceScore && guidance.complianceScore !== void 0) {
|
|
972
|
+
logComplianceScore(PREFIX, guidance.complianceScore);
|
|
973
|
+
}
|
|
974
|
+
if (guidanceConfig.showCategoriesTable && (hasImportantInfo || guidance.usingDefaults)) {
|
|
975
|
+
const rows = guidance.activeCategoriesInfo.map((cat) => ({
|
|
976
|
+
"\u{1F4CA} Categoria": cat.id,
|
|
977
|
+
"\u{1F3F7}\uFE0F Nome": cat.name,
|
|
978
|
+
"\u{1F39B}\uFE0F UI": cat.uiRequired ? "\u2705" : "\u{1F512}",
|
|
979
|
+
"\u{1F36A} Cookies": (cat.cookies || []).slice(0, 3).join(", ") + (cat.cookies && cat.cookies.length > 3 ? ` (+${cat.cookies.length - 3})` : "")
|
|
980
|
+
}));
|
|
981
|
+
if (typeof console.table === "function") {
|
|
982
|
+
console.group(`%c${PREFIX} Configura\xE7\xE3o Ativa`, "color: #4caf50; font-weight: bold;");
|
|
983
|
+
console.table(rows);
|
|
984
|
+
console.groupEnd();
|
|
985
|
+
}
|
|
986
|
+
}
|
|
987
|
+
if (!SESSION_LOGGED.bestPractices && hasImportantInfo) {
|
|
988
|
+
SESSION_LOGGED.bestPractices = true;
|
|
989
|
+
console.group(`%c${PREFIX} LGPD - Boas Pr\xE1ticas`, "color: #9c27b0; font-weight: bold;");
|
|
990
|
+
console.info(
|
|
991
|
+
`%c${PREFIX}%c Necessary: sempre ativo \u2022 Demais: opt-out por padr\xE3o`,
|
|
992
|
+
"color: #9c27b0;",
|
|
993
|
+
"color: #7b1fa2;"
|
|
994
|
+
);
|
|
995
|
+
console.info(
|
|
996
|
+
`%c${PREFIX}%c Documente pol\xEDticas claras por categoria`,
|
|
997
|
+
"color: #9c27b0;",
|
|
998
|
+
"color: #7b1fa2;"
|
|
999
|
+
);
|
|
1000
|
+
console.info(
|
|
1001
|
+
`%c${PREFIX}%c Registre consentimento com data/hora/origem`,
|
|
1002
|
+
"color: #9c27b0;",
|
|
1003
|
+
"color: #7b1fa2;"
|
|
1004
|
+
);
|
|
1005
|
+
console.groupEnd();
|
|
1006
|
+
}
|
|
1007
|
+
}
|
|
1008
|
+
function useDeveloperGuidance(config, disableGuidanceProp, guidanceConfig) {
|
|
1009
|
+
const guidance = React4__namespace.default.useMemo(() => analyzeDeveloperConfiguration(config), [config]);
|
|
1010
|
+
React4__namespace.default.useEffect(() => {
|
|
1011
|
+
if (!disableGuidanceProp) logDeveloperGuidance(guidance, disableGuidanceProp, guidanceConfig);
|
|
1012
|
+
}, [guidance, disableGuidanceProp, guidanceConfig]);
|
|
1013
|
+
return guidance;
|
|
1014
|
+
}
|
|
1015
|
+
var GUIDANCE_PRESETS = {
|
|
1016
|
+
/** Configuração completa para desenvolvimento */
|
|
1017
|
+
development: {
|
|
1018
|
+
showWarnings: true,
|
|
1019
|
+
showSuggestions: true,
|
|
1020
|
+
showCategoriesTable: true,
|
|
1021
|
+
showBestPractices: true,
|
|
1022
|
+
showComplianceScore: true,
|
|
1023
|
+
minimumSeverity: "info"
|
|
1024
|
+
},
|
|
1025
|
+
/** Configuração silenciosa para produção */
|
|
1026
|
+
production: {
|
|
1027
|
+
showWarnings: false,
|
|
1028
|
+
showSuggestions: false,
|
|
1029
|
+
showCategoriesTable: false,
|
|
1030
|
+
showBestPractices: false,
|
|
1031
|
+
showComplianceScore: false,
|
|
1032
|
+
minimumSeverity: "error"
|
|
1033
|
+
},
|
|
1034
|
+
/** Apenas erros críticos */
|
|
1035
|
+
minimal: {
|
|
1036
|
+
showWarnings: true,
|
|
1037
|
+
showSuggestions: false,
|
|
1038
|
+
showCategoriesTable: false,
|
|
1039
|
+
showBestPractices: false,
|
|
1040
|
+
showComplianceScore: false,
|
|
1041
|
+
minimumSeverity: "error"
|
|
1042
|
+
},
|
|
1043
|
+
/** Focado em conformidade LGPD */
|
|
1044
|
+
compliance: {
|
|
1045
|
+
showWarnings: true,
|
|
1046
|
+
showSuggestions: true,
|
|
1047
|
+
showCategoriesTable: true,
|
|
1048
|
+
showBestPractices: true,
|
|
1049
|
+
showComplianceScore: true,
|
|
1050
|
+
minimumSeverity: "warning"
|
|
1051
|
+
}
|
|
1052
|
+
};
|
|
1053
|
+
|
|
1054
|
+
// src/utils/validation.ts
|
|
1055
|
+
var isDev = () => typeof process !== "undefined" && process.env.NODE_ENV !== "production";
|
|
1056
|
+
function validateConsentProviderProps(props) {
|
|
1057
|
+
const warnings = [];
|
|
1058
|
+
const errors = [];
|
|
1059
|
+
const sanitized = {};
|
|
1060
|
+
if (!isDev()) {
|
|
1061
|
+
if (props.categories) {
|
|
1062
|
+
const enabled = Array.from(/* @__PURE__ */ new Set([...props.categories.enabledCategories ?? []]));
|
|
1063
|
+
const sanitizedEnabled = enabled.filter((c) => c !== "necessary");
|
|
1064
|
+
sanitized.categories = {
|
|
1065
|
+
enabledCategories: sanitizedEnabled,
|
|
1066
|
+
customCategories: props.categories.customCategories
|
|
1067
|
+
};
|
|
1068
|
+
}
|
|
1069
|
+
return { sanitized, warnings, errors };
|
|
1070
|
+
}
|
|
1071
|
+
let z;
|
|
1072
|
+
try {
|
|
1073
|
+
z = __require("zod");
|
|
1074
|
+
} catch {
|
|
1075
|
+
z = void 0;
|
|
1076
|
+
}
|
|
1077
|
+
const issues = [];
|
|
1078
|
+
if (z) {
|
|
1079
|
+
const CustomCategorySchema = z.object({
|
|
1080
|
+
id: z.string().min(1, "customCategories[].id deve ser uma string n\xE3o vazia"),
|
|
1081
|
+
name: z.string().min(1, "customCategories[].name deve ser uma string n\xE3o vazia"),
|
|
1082
|
+
description: z.string().min(1, "customCategories[].description deve ser uma string n\xE3o vazia"),
|
|
1083
|
+
essential: z.boolean().optional(),
|
|
1084
|
+
cookies: z.array(z.string().min(1)).optional()
|
|
1085
|
+
});
|
|
1086
|
+
const ProjectCategoriesConfigSchema = z.object({
|
|
1087
|
+
enabledCategories: z.array(z.string().min(1)).optional(),
|
|
1088
|
+
customCategories: z.array(CustomCategorySchema).optional()
|
|
1089
|
+
}).strict();
|
|
1090
|
+
const res = ProjectCategoriesConfigSchema.safeParse(props.categories);
|
|
1091
|
+
if (!res.success) {
|
|
1092
|
+
res.error.issues.forEach(
|
|
1093
|
+
(issue) => issues.push({ path: `categories.${issue.path.join(".")}`, message: issue.message })
|
|
1094
|
+
);
|
|
1095
|
+
}
|
|
1096
|
+
}
|
|
1097
|
+
if (!props.categories) {
|
|
1098
|
+
warnings.push(
|
|
1099
|
+
"Prop 'categories' n\xE3o fornecida. A lib aplicar\xE1 um padr\xE3o seguro, mas recomenda-se definir 'categories.enabledCategories' explicitamente para clareza e auditoria."
|
|
1100
|
+
);
|
|
1101
|
+
} else {
|
|
1102
|
+
const cat = props.categories;
|
|
1103
|
+
const enabled = Array.from(/* @__PURE__ */ new Set([...cat.enabledCategories ?? []]));
|
|
1104
|
+
if (enabled.includes("necessary")) {
|
|
1105
|
+
warnings.push("'necessary' \xE9 sempre inclu\xEDda automaticamente \u2014 remova de enabledCategories.");
|
|
1106
|
+
}
|
|
1107
|
+
const sanitizedEnabled = enabled.filter((c) => c !== "necessary");
|
|
1108
|
+
const invalidEnabled = sanitizedEnabled.filter((c) => typeof c !== "string" || c.trim() === "");
|
|
1109
|
+
if (invalidEnabled.length > 0) {
|
|
1110
|
+
warnings.push(
|
|
1111
|
+
`enabledCategories cont\xE9m valores inv\xE1lidos: ${invalidEnabled.map((v) => String(v)).join(", ")} \u2014 remova ou corrija os IDs de categoria`
|
|
1112
|
+
);
|
|
1113
|
+
}
|
|
1114
|
+
const custom = cat.customCategories ?? [];
|
|
1115
|
+
if (z) {
|
|
1116
|
+
const CustomCategorySchema = z.object({
|
|
1117
|
+
id: z.string().min(1),
|
|
1118
|
+
name: z.string().min(1),
|
|
1119
|
+
description: z.string().min(1),
|
|
1120
|
+
essential: z.boolean().optional(),
|
|
1121
|
+
cookies: z.array(z.string().min(1)).optional()
|
|
1122
|
+
});
|
|
1123
|
+
const customParse = z.array(CustomCategorySchema).safeParse(custom);
|
|
1124
|
+
if (!customParse.success) {
|
|
1125
|
+
customParse.error.issues.forEach(
|
|
1126
|
+
(issue) => issues.push({ path: `customCategories.${issue.path.join(".")}`, message: issue.message })
|
|
1127
|
+
);
|
|
1128
|
+
}
|
|
1129
|
+
}
|
|
1130
|
+
const ids = /* @__PURE__ */ new Set();
|
|
1131
|
+
const dupes = [];
|
|
1132
|
+
["necessary", ...sanitizedEnabled].forEach((id) => {
|
|
1133
|
+
if (ids.has(id)) dupes.push(id);
|
|
1134
|
+
ids.add(id);
|
|
1135
|
+
});
|
|
1136
|
+
custom.forEach((c) => {
|
|
1137
|
+
if (ids.has(c.id)) dupes.push(c.id);
|
|
1138
|
+
ids.add(c.id);
|
|
1139
|
+
});
|
|
1140
|
+
if (dupes.length > 0) {
|
|
1141
|
+
warnings.push(
|
|
1142
|
+
`IDs de categoria duplicados detectados: ${Array.from(new Set(dupes)).join(
|
|
1143
|
+
", "
|
|
1144
|
+
)} \u2014 verifique 'enabledCategories' e 'customCategories'.`
|
|
1145
|
+
);
|
|
1146
|
+
}
|
|
1147
|
+
sanitized.categories = {
|
|
1148
|
+
enabledCategories: sanitizedEnabled,
|
|
1149
|
+
customCategories: custom
|
|
1150
|
+
};
|
|
1151
|
+
}
|
|
1152
|
+
if (warnings.length > 0) {
|
|
1153
|
+
logger.warn("Valida\xE7\xE3o do ConsentProvider:", ...warnings);
|
|
1154
|
+
}
|
|
1155
|
+
if (errors.length > 0 || issues.length > 0) {
|
|
1156
|
+
issues.forEach((i) => errors.push(`Prop inv\xE1lida: ${i.path} \u2014 ${i.message}`));
|
|
1157
|
+
logger.error("Erros de configura\xE7\xE3o do ConsentProvider:", ...errors);
|
|
1158
|
+
}
|
|
1159
|
+
return { sanitized, warnings, errors };
|
|
1160
|
+
}
|
|
1161
|
+
|
|
1162
|
+
// src/utils/cookieDiscovery.ts
|
|
1163
|
+
function discoverRuntimeCookies() {
|
|
1164
|
+
if (typeof document === "undefined" || !document.cookie) return [];
|
|
1165
|
+
const names = Array.from(
|
|
1166
|
+
new Set(
|
|
1167
|
+
document.cookie.split(";").map((s) => s.trim()).filter(Boolean).map((s) => s.split("=")[0])
|
|
1168
|
+
)
|
|
1169
|
+
);
|
|
1170
|
+
const list = names.map((name) => ({ name }));
|
|
1171
|
+
try {
|
|
1172
|
+
;
|
|
1173
|
+
globalThis.__LGPD_DISCOVERED_COOKIES__ = list;
|
|
1174
|
+
} catch {
|
|
1175
|
+
}
|
|
1176
|
+
return list;
|
|
1177
|
+
}
|
|
1178
|
+
function detectConsentCookieName() {
|
|
1179
|
+
if (typeof document === "undefined" || !document.cookie) return null;
|
|
1180
|
+
try {
|
|
1181
|
+
const pairs = document.cookie.split(";").map((s) => s.trim()).filter(Boolean);
|
|
1182
|
+
for (const p of pairs) {
|
|
1183
|
+
const [name, ...rest] = p.split("=");
|
|
1184
|
+
const raw = rest.join("=");
|
|
1185
|
+
if (!raw) continue;
|
|
1186
|
+
let val = raw;
|
|
1187
|
+
try {
|
|
1188
|
+
val = decodeURIComponent(raw);
|
|
1189
|
+
} catch {
|
|
1190
|
+
}
|
|
1191
|
+
if (val.startsWith("{")) {
|
|
1192
|
+
try {
|
|
1193
|
+
const obj = JSON.parse(val);
|
|
1194
|
+
if (obj && typeof obj === "object" && "preferences" in obj && "version" in obj) {
|
|
1195
|
+
return name;
|
|
1196
|
+
}
|
|
1197
|
+
} catch {
|
|
1198
|
+
}
|
|
1199
|
+
}
|
|
1200
|
+
}
|
|
1201
|
+
} catch {
|
|
1202
|
+
}
|
|
1203
|
+
return null;
|
|
1204
|
+
}
|
|
1205
|
+
function categorizeDiscoveredCookies(discovered, registerOverrides = false) {
|
|
1206
|
+
const list = discovered || globalThis.__LGPD_DISCOVERED_COOKIES__ || [];
|
|
1207
|
+
const out = {};
|
|
1208
|
+
function matchPattern2(name, pattern) {
|
|
1209
|
+
if (pattern.endsWith("*")) return name.startsWith(pattern.slice(0, -1));
|
|
1210
|
+
return name === pattern;
|
|
1211
|
+
}
|
|
1212
|
+
list.filter((d) => d.name && d.name !== "cookieConsent").forEach((d) => {
|
|
1213
|
+
let assigned = null;
|
|
1214
|
+
Object.keys(COOKIE_PATTERNS_BY_CATEGORY).forEach((cat2) => {
|
|
1215
|
+
if (assigned) return;
|
|
1216
|
+
const patterns = COOKIE_PATTERNS_BY_CATEGORY[cat2] || [];
|
|
1217
|
+
if (patterns.some((p) => matchPattern2(d.name, p))) assigned = cat2;
|
|
1218
|
+
});
|
|
1219
|
+
const cat = assigned || "analytics";
|
|
1220
|
+
out[cat] = out[cat] || [];
|
|
1221
|
+
if (!out[cat].find((x) => x.name === d.name)) out[cat].push(d);
|
|
1222
|
+
});
|
|
1223
|
+
if (registerOverrides) {
|
|
1224
|
+
const byCategory = {};
|
|
1225
|
+
Object.entries(out).forEach(([cat, cookies]) => {
|
|
1226
|
+
byCategory[cat] = cookies;
|
|
1227
|
+
});
|
|
1228
|
+
setCookieCatalogOverrides({ byCategory });
|
|
1229
|
+
}
|
|
1230
|
+
return out;
|
|
1231
|
+
}
|
|
1232
|
+
var CategoriesContext = React4__namespace.createContext(null);
|
|
1233
|
+
function CategoriesProvider({
|
|
1234
|
+
children,
|
|
1235
|
+
config,
|
|
1236
|
+
disableDeveloperGuidance,
|
|
1237
|
+
disableDiscoveryLog
|
|
1238
|
+
}) {
|
|
1239
|
+
const [impliedVersion, setImpliedVersion] = React4__namespace.useState(0);
|
|
1240
|
+
React4__namespace.useEffect(() => {
|
|
1241
|
+
const handler = () => setImpliedVersion((v) => v + 1);
|
|
1242
|
+
if (typeof window !== "undefined" && typeof window.addEventListener === "function") {
|
|
1243
|
+
window.addEventListener("lgpd:requiredCategories", handler);
|
|
1244
|
+
return () => window.removeEventListener("lgpd:requiredCategories", handler);
|
|
1245
|
+
}
|
|
1246
|
+
return () => {
|
|
1247
|
+
};
|
|
1248
|
+
}, []);
|
|
1249
|
+
const contextValue = React4__namespace.useMemo(() => {
|
|
1250
|
+
const finalConfig = config || DEFAULT_PROJECT_CATEGORIES;
|
|
1251
|
+
const guidance = analyzeDeveloperConfiguration(config);
|
|
1252
|
+
const toggleableCategories = guidance.activeCategoriesInfo.filter((cat) => cat.uiRequired);
|
|
1253
|
+
return {
|
|
1254
|
+
config: finalConfig,
|
|
1255
|
+
guidance,
|
|
1256
|
+
toggleableCategories,
|
|
1257
|
+
allCategories: guidance.activeCategoriesInfo
|
|
1258
|
+
};
|
|
1259
|
+
}, [config, impliedVersion]);
|
|
1260
|
+
React4__namespace.useEffect(() => {
|
|
1261
|
+
logDeveloperGuidance(contextValue.guidance, disableDeveloperGuidance);
|
|
1262
|
+
}, [contextValue.guidance, disableDeveloperGuidance]);
|
|
1263
|
+
React4__namespace.useEffect(() => {
|
|
1264
|
+
try {
|
|
1265
|
+
const gt = globalThis;
|
|
1266
|
+
const env = typeof gt.process !== "undefined" ? gt.process?.env?.NODE_ENV : void 0;
|
|
1267
|
+
const isDev2 = env === "development";
|
|
1268
|
+
if (!isDev2 || gt.__LGPD_DISCOVERY_LOGGED__ === true || disableDiscoveryLog) return;
|
|
1269
|
+
const discovered = discoverRuntimeCookies();
|
|
1270
|
+
const consentName = detectConsentCookieName() || DEFAULT_COOKIE_OPTS.name;
|
|
1271
|
+
const PREFIX = "[\u{1F36A} LGPD-CONSENT]";
|
|
1272
|
+
if (typeof console !== "undefined") {
|
|
1273
|
+
try {
|
|
1274
|
+
console.group(`${PREFIX} \u{1F50E} Descoberta de cookies (experimental)`);
|
|
1275
|
+
const names = Array.from(
|
|
1276
|
+
new Set([consentName, ...discovered.map((d) => d.name)].filter(Boolean))
|
|
1277
|
+
);
|
|
1278
|
+
const rows = names.map((n) => ({ Cookie: n }));
|
|
1279
|
+
if (typeof console.table === "function") console.table(rows);
|
|
1280
|
+
else console.log(rows);
|
|
1281
|
+
console.info(
|
|
1282
|
+
`${PREFIX} \u2139\uFE0F Estes nomes s\xE3o detectados em tempo de execu\xE7\xE3o. Ajuste ou categorize via APIs de override se necess\xE1rio.`
|
|
1283
|
+
);
|
|
1284
|
+
console.groupEnd();
|
|
1285
|
+
} catch {
|
|
1286
|
+
}
|
|
1287
|
+
}
|
|
1288
|
+
gt.__LGPD_DISCOVERY_LOGGED__ = true;
|
|
1289
|
+
} catch {
|
|
1290
|
+
}
|
|
1291
|
+
}, [disableDiscoveryLog]);
|
|
1292
|
+
return /* @__PURE__ */ jsxRuntime.jsx(CategoriesContext.Provider, { value: contextValue, children });
|
|
1293
|
+
}
|
|
1294
|
+
function useCategories() {
|
|
1295
|
+
const context = React4__namespace.useContext(CategoriesContext);
|
|
1296
|
+
if (!context) {
|
|
1297
|
+
throw new Error(
|
|
1298
|
+
"useCategories deve ser usado dentro de CategoriesProvider. Certifique-se de que o ConsentProvider est\xE1 envolvendo seu componente."
|
|
1299
|
+
);
|
|
1300
|
+
}
|
|
1301
|
+
return context;
|
|
1302
|
+
}
|
|
1303
|
+
function useCategoryStatus(categoryId) {
|
|
1304
|
+
const { allCategories } = useCategories();
|
|
1305
|
+
const category = allCategories.find((cat) => cat.id === categoryId);
|
|
1306
|
+
return {
|
|
1307
|
+
isActive: !!category,
|
|
1308
|
+
isEssential: category?.essential || false,
|
|
1309
|
+
needsToggle: category?.uiRequired || false,
|
|
1310
|
+
name: category?.name,
|
|
1311
|
+
description: category?.description
|
|
1312
|
+
};
|
|
1313
|
+
}
|
|
1314
|
+
var DesignContext = React4__namespace.createContext(void 0);
|
|
1315
|
+
function DesignProvider({
|
|
1316
|
+
tokens,
|
|
1317
|
+
children
|
|
1318
|
+
}) {
|
|
1319
|
+
return /* @__PURE__ */ jsxRuntime.jsx(DesignContext.Provider, { value: tokens, children });
|
|
1320
|
+
}
|
|
1321
|
+
function useDesignTokens() {
|
|
1322
|
+
return React4__namespace.useContext(DesignContext);
|
|
1323
|
+
}
|
|
1324
|
+
function createFullConsentState(consented, preferences, source, projectConfig, isModalOpen = false, existingState) {
|
|
1325
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
1326
|
+
return {
|
|
1327
|
+
version: "1.0",
|
|
1328
|
+
consented,
|
|
1329
|
+
preferences,
|
|
1330
|
+
consentDate: existingState?.consentDate || now,
|
|
1331
|
+
lastUpdate: now,
|
|
1332
|
+
source,
|
|
1333
|
+
projectConfig,
|
|
1334
|
+
isModalOpen
|
|
1335
|
+
};
|
|
1336
|
+
}
|
|
1337
|
+
var DEFAULT_TEXTS = {
|
|
1338
|
+
// Textos básicos
|
|
1339
|
+
bannerMessage: "Utilizamos cookies para melhorar sua experi\xEAncia.",
|
|
1340
|
+
acceptAll: "Aceitar todos",
|
|
1341
|
+
declineAll: "Recusar",
|
|
1342
|
+
preferences: "Prefer\xEAncias",
|
|
1343
|
+
policyLink: "Saiba mais",
|
|
1344
|
+
modalTitle: "Prefer\xEAncias de Cookies",
|
|
1345
|
+
modalIntro: "Ajuste as categorias de cookies. Cookies necess\xE1rios s\xE3o sempre utilizados para funcionalidades b\xE1sicas.",
|
|
1346
|
+
save: "Salvar prefer\xEAncias",
|
|
1347
|
+
necessaryAlwaysOn: "Cookies necess\xE1rios (sempre ativos)",
|
|
1348
|
+
// Textos adicionais para UI customizada
|
|
1349
|
+
preferencesButton: "Configurar Cookies",
|
|
1350
|
+
preferencesTitle: "Gerenciar Prefer\xEAncias de Cookies",
|
|
1351
|
+
preferencesDescription: "Escolha quais tipos de cookies voc\xEA permite que sejam utilizados.",
|
|
1352
|
+
close: "Fechar",
|
|
1353
|
+
accept: "Aceitar",
|
|
1354
|
+
reject: "Rejeitar",
|
|
1355
|
+
// Textos ANPD expandidos (opcionais)
|
|
1356
|
+
brandingPoweredBy: "fornecido por",
|
|
1357
|
+
controllerInfo: void 0,
|
|
1358
|
+
// Exibido se definido
|
|
1359
|
+
dataTypes: void 0,
|
|
1360
|
+
// Exibido se definido
|
|
1361
|
+
thirdPartySharing: void 0,
|
|
1362
|
+
// Exibido se definido
|
|
1363
|
+
userRights: void 0,
|
|
1364
|
+
// Exibido se definido
|
|
1365
|
+
contactInfo: void 0,
|
|
1366
|
+
// Exibido se definido
|
|
1367
|
+
retentionPeriod: void 0,
|
|
1368
|
+
// Exibido se definido
|
|
1369
|
+
lawfulBasis: void 0,
|
|
1370
|
+
// Exibido se definido
|
|
1371
|
+
transferCountries: void 0
|
|
1372
|
+
// Exibido se definido
|
|
1373
|
+
};
|
|
1374
|
+
function reducer(state, action) {
|
|
1375
|
+
logger.consentState(action.type, state);
|
|
1376
|
+
switch (action.type) {
|
|
1377
|
+
case "ACCEPT_ALL": {
|
|
1378
|
+
const prefs = createProjectPreferences(action.config, true);
|
|
1379
|
+
const newState = createFullConsentState(true, prefs, "banner", action.config, false, state);
|
|
1380
|
+
logger.info("User accepted all cookies", {
|
|
1381
|
+
preferences: newState.preferences
|
|
1382
|
+
});
|
|
1383
|
+
return newState;
|
|
1384
|
+
}
|
|
1385
|
+
case "REJECT_ALL": {
|
|
1386
|
+
const prefs = createProjectPreferences(action.config, false);
|
|
1387
|
+
const newState = createFullConsentState(true, prefs, "banner", action.config, false, state);
|
|
1388
|
+
logger.info("User rejected all cookies", {
|
|
1389
|
+
preferences: newState.preferences
|
|
1390
|
+
});
|
|
1391
|
+
return newState;
|
|
1392
|
+
}
|
|
1393
|
+
case "SET_CATEGORY":
|
|
1394
|
+
logger.debug("Category preference changed", {
|
|
1395
|
+
category: action.category,
|
|
1396
|
+
value: action.value
|
|
1397
|
+
});
|
|
1398
|
+
return {
|
|
1399
|
+
...state,
|
|
1400
|
+
preferences: {
|
|
1401
|
+
...state.preferences,
|
|
1402
|
+
[action.category]: action.value
|
|
1403
|
+
},
|
|
1404
|
+
lastUpdate: (/* @__PURE__ */ new Date()).toISOString()
|
|
1405
|
+
};
|
|
1406
|
+
case "SET_PREFERENCES":
|
|
1407
|
+
logger.info("Preferences saved", { preferences: action.preferences });
|
|
1408
|
+
return createFullConsentState(true, action.preferences, "modal", action.config, false, state);
|
|
1409
|
+
case "OPEN_MODAL":
|
|
1410
|
+
return { ...state, isModalOpen: true };
|
|
1411
|
+
case "CLOSE_MODAL":
|
|
1412
|
+
return createFullConsentState(true, state.preferences, "modal", action.config, false, state);
|
|
1413
|
+
case "RESET": {
|
|
1414
|
+
return createFullConsentState(
|
|
1415
|
+
false,
|
|
1416
|
+
createProjectPreferences(action.config),
|
|
1417
|
+
"programmatic",
|
|
1418
|
+
action.config,
|
|
1419
|
+
false
|
|
1420
|
+
);
|
|
1421
|
+
}
|
|
1422
|
+
case "HYDRATE": {
|
|
1423
|
+
const validatedPreferences = validateProjectPreferences(
|
|
1424
|
+
action.state.preferences,
|
|
1425
|
+
action.config
|
|
1426
|
+
);
|
|
1427
|
+
return {
|
|
1428
|
+
...action.state,
|
|
1429
|
+
preferences: validatedPreferences,
|
|
1430
|
+
isModalOpen: false
|
|
1431
|
+
};
|
|
1432
|
+
}
|
|
1433
|
+
default:
|
|
1434
|
+
return state;
|
|
1435
|
+
}
|
|
1436
|
+
}
|
|
1437
|
+
var StateCtx = React4__namespace.createContext(null);
|
|
1438
|
+
var ActionsCtx = React4__namespace.createContext(null);
|
|
1439
|
+
var TextsCtx = React4__namespace.createContext(DEFAULT_TEXTS);
|
|
1440
|
+
var HydrationCtx = React4__namespace.createContext(false);
|
|
1441
|
+
function ConsentProvider({
|
|
1442
|
+
initialState,
|
|
1443
|
+
categories,
|
|
1444
|
+
texts: textsProp,
|
|
1445
|
+
designTokens,
|
|
1446
|
+
PreferencesModalComponent,
|
|
1447
|
+
preferencesModalProps = {},
|
|
1448
|
+
CookieBannerComponent,
|
|
1449
|
+
cookieBannerProps = {},
|
|
1450
|
+
FloatingPreferencesButtonComponent,
|
|
1451
|
+
floatingPreferencesButtonProps = {},
|
|
1452
|
+
disableFloatingPreferencesButton = false,
|
|
1453
|
+
blocking = false,
|
|
1454
|
+
blockingStrategy = "auto",
|
|
1455
|
+
hideBranding: _hideBranding = false,
|
|
1456
|
+
onConsentGiven,
|
|
1457
|
+
onPreferencesSaved,
|
|
1458
|
+
cookie: cookieOpts,
|
|
1459
|
+
disableDeveloperGuidance,
|
|
1460
|
+
guidanceConfig,
|
|
1461
|
+
children,
|
|
1462
|
+
disableDiscoveryLog
|
|
1463
|
+
}) {
|
|
1464
|
+
const texts = React4__namespace.useMemo(() => ({ ...DEFAULT_TEXTS, ...textsProp ?? {} }), [textsProp]);
|
|
1465
|
+
const cookie = React4__namespace.useMemo(
|
|
1466
|
+
() => ({ ...DEFAULT_COOKIE_OPTS, ...cookieOpts ?? {} }),
|
|
1467
|
+
[cookieOpts]
|
|
1468
|
+
);
|
|
1469
|
+
const finalCategoriesConfig = React4__namespace.useMemo(() => {
|
|
1470
|
+
const isProd = typeof process !== "undefined" && process.env?.NODE_ENV === "production";
|
|
1471
|
+
if (!categories) return DEFAULT_PROJECT_CATEGORIES;
|
|
1472
|
+
if (isProd) return categories;
|
|
1473
|
+
const { sanitized } = validateConsentProviderProps({ categories });
|
|
1474
|
+
return sanitized.categories ?? categories;
|
|
1475
|
+
}, [categories]);
|
|
1476
|
+
React4__namespace.useEffect(() => {
|
|
1477
|
+
const isProd = typeof process !== "undefined" && process.env?.NODE_ENV === "production";
|
|
1478
|
+
if (!isProd && !categories) {
|
|
1479
|
+
logger.warn(
|
|
1480
|
+
"Prop 'categories' n\xE3o fornecida. A lib aplicar\xE1 um padr\xE3o seguro, mas recomenda-se definir 'categories.enabledCategories' explicitamente para clareza e auditoria."
|
|
1481
|
+
);
|
|
1482
|
+
}
|
|
1483
|
+
}, [categories]);
|
|
1484
|
+
const didWarnAboutMissingUI = React4__namespace.useRef(false);
|
|
1485
|
+
useDeveloperGuidance(finalCategoriesConfig, disableDeveloperGuidance, guidanceConfig);
|
|
1486
|
+
React4__namespace.useEffect(() => {
|
|
1487
|
+
const isProd = typeof process !== "undefined" && process.env?.NODE_ENV === "production";
|
|
1488
|
+
if (!isProd && PreferencesModalComponent) {
|
|
1489
|
+
console.info(
|
|
1490
|
+
"[LGPD-CONSENT] Dica: seu PreferencesModal \xE9 customizado. Garanta exibir os detalhes dos cookies por categoria (nome, finalidade, dura\xE7\xE3o) usando as APIs setCookieCatalogOverrides / setCookieCategoryOverrides e getCookiesInfoForCategory. Consulte QUICKSTART e INTEGRACOES.md."
|
|
1491
|
+
);
|
|
1492
|
+
}
|
|
1493
|
+
}, [PreferencesModalComponent]);
|
|
1494
|
+
const boot = React4__namespace.useMemo(() => {
|
|
1495
|
+
if (initialState) return { ...initialState, isModalOpen: false };
|
|
1496
|
+
return createFullConsentState(
|
|
1497
|
+
false,
|
|
1498
|
+
createProjectPreferences(finalCategoriesConfig),
|
|
1499
|
+
"banner",
|
|
1500
|
+
finalCategoriesConfig,
|
|
1501
|
+
false
|
|
1502
|
+
);
|
|
1503
|
+
}, [initialState, finalCategoriesConfig]);
|
|
1504
|
+
const [state, dispatch] = React4__namespace.useReducer(reducer, boot);
|
|
1505
|
+
const [isHydrated, setIsHydrated] = React4__namespace.useState(false);
|
|
1506
|
+
const previousPreferencesRef = React4__namespace.useRef(state.preferences);
|
|
1507
|
+
React4__namespace.useEffect(() => {
|
|
1508
|
+
if (!initialState) {
|
|
1509
|
+
const saved = readConsentCookie(cookie.name);
|
|
1510
|
+
if (saved?.consented) {
|
|
1511
|
+
dispatch({
|
|
1512
|
+
type: "HYDRATE",
|
|
1513
|
+
state: saved,
|
|
1514
|
+
config: finalCategoriesConfig
|
|
1515
|
+
});
|
|
1516
|
+
}
|
|
1517
|
+
}
|
|
1518
|
+
setIsHydrated(true);
|
|
1519
|
+
}, [cookie.name, initialState, finalCategoriesConfig]);
|
|
1520
|
+
React4__namespace.useEffect(() => {
|
|
1521
|
+
if (isHydrated) {
|
|
1522
|
+
pushConsentInitializedEvent(state.preferences);
|
|
1523
|
+
logger.info("DataLayer: consent_initialized event dispatched", {
|
|
1524
|
+
preferences: state.preferences
|
|
1525
|
+
});
|
|
1526
|
+
}
|
|
1527
|
+
}, [isHydrated]);
|
|
1528
|
+
React4__namespace.useEffect(() => {
|
|
1529
|
+
if (state.consented) writeConsentCookie(state, finalCategoriesConfig, cookie);
|
|
1530
|
+
}, [state, cookie, finalCategoriesConfig]);
|
|
1531
|
+
const prevConsented = React4__namespace.useRef(state.consented);
|
|
1532
|
+
React4__namespace.useEffect(() => {
|
|
1533
|
+
if (!prevConsented.current && state.consented && onConsentGiven) {
|
|
1534
|
+
setTimeout(() => onConsentGiven(state), 150);
|
|
1535
|
+
}
|
|
1536
|
+
prevConsented.current = state.consented;
|
|
1537
|
+
}, [state, onConsentGiven]);
|
|
1538
|
+
React4__namespace.useEffect(() => {
|
|
1539
|
+
if (!isHydrated) return;
|
|
1540
|
+
const hasChanged = Object.keys(state.preferences).some(
|
|
1541
|
+
(key) => state.preferences[key] !== previousPreferencesRef.current[key]
|
|
1542
|
+
);
|
|
1543
|
+
if (hasChanged) {
|
|
1544
|
+
const origin = state.source === "programmatic" ? "reset" : state.source;
|
|
1545
|
+
pushConsentUpdatedEvent(state.preferences, origin, previousPreferencesRef.current);
|
|
1546
|
+
logger.info("DataLayer: consent_updated event dispatched", {
|
|
1547
|
+
origin,
|
|
1548
|
+
preferences: state.preferences,
|
|
1549
|
+
consented: state.consented
|
|
1550
|
+
});
|
|
1551
|
+
previousPreferencesRef.current = state.preferences;
|
|
1552
|
+
}
|
|
1553
|
+
}, [state.preferences, state.consented, state.source, isHydrated]);
|
|
1554
|
+
const api = React4__namespace.useMemo(() => {
|
|
1555
|
+
const acceptAll = () => dispatch({ type: "ACCEPT_ALL", config: finalCategoriesConfig });
|
|
1556
|
+
const rejectAll = () => dispatch({ type: "REJECT_ALL", config: finalCategoriesConfig });
|
|
1557
|
+
const setPreference = (category, value) => dispatch({ type: "SET_CATEGORY", category, value });
|
|
1558
|
+
const setPreferences = (preferences) => {
|
|
1559
|
+
dispatch({
|
|
1560
|
+
type: "SET_PREFERENCES",
|
|
1561
|
+
preferences,
|
|
1562
|
+
config: finalCategoriesConfig
|
|
1563
|
+
});
|
|
1564
|
+
if (onPreferencesSaved) {
|
|
1565
|
+
setTimeout(() => onPreferencesSaved(preferences), 150);
|
|
1566
|
+
}
|
|
1567
|
+
};
|
|
1568
|
+
const openPreferences = () => dispatch({ type: "OPEN_MODAL" });
|
|
1569
|
+
const closePreferences = () => dispatch({ type: "CLOSE_MODAL", config: finalCategoriesConfig });
|
|
1570
|
+
const resetConsent = () => {
|
|
1571
|
+
removeConsentCookie(cookie);
|
|
1572
|
+
dispatch({ type: "RESET", config: finalCategoriesConfig });
|
|
1573
|
+
};
|
|
1574
|
+
return {
|
|
1575
|
+
consented: !!state.consented,
|
|
1576
|
+
preferences: state.preferences,
|
|
1577
|
+
isModalOpen: state.isModalOpen,
|
|
1578
|
+
acceptAll,
|
|
1579
|
+
rejectAll,
|
|
1580
|
+
setPreference,
|
|
1581
|
+
setPreferences,
|
|
1582
|
+
openPreferences,
|
|
1583
|
+
closePreferences,
|
|
1584
|
+
resetConsent
|
|
1585
|
+
};
|
|
1586
|
+
}, [state, cookie, finalCategoriesConfig, onPreferencesSaved]);
|
|
1587
|
+
React4__namespace.useEffect(() => {
|
|
1588
|
+
_registerGlobalOpenPreferences(api.openPreferences);
|
|
1589
|
+
return () => _unregisterGlobalOpenPreferences();
|
|
1590
|
+
}, [api.openPreferences]);
|
|
1591
|
+
const providerBackdropColor = React4__namespace.useMemo(() => {
|
|
1592
|
+
const backdrop = designTokens?.layout?.backdrop;
|
|
1593
|
+
if (backdrop === false) return "transparent";
|
|
1594
|
+
if (typeof backdrop === "string") return backdrop;
|
|
1595
|
+
return "rgba(0, 0, 0, 0.4)";
|
|
1596
|
+
}, [designTokens]);
|
|
1597
|
+
const content = /* @__PURE__ */ jsxRuntime.jsx(StateCtx.Provider, { value: state, children: /* @__PURE__ */ jsxRuntime.jsx(ActionsCtx.Provider, { value: api, children: /* @__PURE__ */ jsxRuntime.jsx(TextsCtx.Provider, { value: texts, children: /* @__PURE__ */ jsxRuntime.jsx(HydrationCtx.Provider, { value: isHydrated, children: /* @__PURE__ */ jsxRuntime.jsx(DesignProvider, { tokens: designTokens, children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1598
|
+
CategoriesProvider,
|
|
1599
|
+
{
|
|
1600
|
+
config: finalCategoriesConfig,
|
|
1601
|
+
disableDeveloperGuidance,
|
|
1602
|
+
disableDiscoveryLog,
|
|
1603
|
+
children: [
|
|
1604
|
+
children,
|
|
1605
|
+
PreferencesModalComponent ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
1606
|
+
PreferencesModalComponent,
|
|
1607
|
+
{
|
|
1608
|
+
preferences: api.preferences,
|
|
1609
|
+
setPreferences: api.setPreferences,
|
|
1610
|
+
closePreferences: api.closePreferences,
|
|
1611
|
+
isModalOpen: api.isModalOpen,
|
|
1612
|
+
texts,
|
|
1613
|
+
...preferencesModalProps
|
|
1614
|
+
}
|
|
1615
|
+
) : (
|
|
1616
|
+
// Aviso de desenvolvimento: usuário pode estar esquecendo de fornecer componentes UI
|
|
1617
|
+
process.env.NODE_ENV === "development" && typeof window !== "undefined" && !didWarnAboutMissingUI.current && !CookieBannerComponent && !FloatingPreferencesButtonComponent && (() => {
|
|
1618
|
+
didWarnAboutMissingUI.current = true;
|
|
1619
|
+
console.warn(
|
|
1620
|
+
"%c[@react-lgpd-consent/core] Aviso: Nenhum componente UI fornecido",
|
|
1621
|
+
"color: #ff9800; font-weight: bold; font-size: 14px",
|
|
1622
|
+
`
|
|
1623
|
+
|
|
1624
|
+
\u26A0\uFE0F O ConsentProvider do core \xE9 HEADLESS (sem interface visual).
|
|
1625
|
+
Usu\xE1rios n\xE3o ver\xE3o banner de consentimento nem conseguir\xE3o gerenciar prefer\xEAncias.
|
|
1626
|
+
|
|
1627
|
+
\u{1F4E6} Componentes UI ausentes:
|
|
1628
|
+
\u2022 CookieBanner - Banner de consentimento inicial
|
|
1629
|
+
\u2022 PreferencesModal - Modal de gerenciamento de prefer\xEAncias
|
|
1630
|
+
\u2022 FloatingPreferencesButton - Bot\xE3o para reabrir prefer\xEAncias
|
|
1631
|
+
|
|
1632
|
+
\u2705 Solu\xE7\xF5es:
|
|
1633
|
+
|
|
1634
|
+
1\uFE0F\u20E3 Usar pacote MUI (RECOMENDADO - componentes prontos):
|
|
1635
|
+
import { ConsentProvider } from '@react-lgpd-consent/mui'
|
|
1636
|
+
// Modal, banner e bot\xE3o injetados automaticamente!
|
|
1637
|
+
|
|
1638
|
+
2\uFE0F\u20E3 Fornecer seus pr\xF3prios componentes:
|
|
1639
|
+
<ConsentProvider
|
|
1640
|
+
CookieBannerComponent={YourBanner}
|
|
1641
|
+
PreferencesModalComponent={YourModal}
|
|
1642
|
+
FloatingPreferencesButtonComponent={YourButton}
|
|
1643
|
+
/>
|
|
1644
|
+
|
|
1645
|
+
3\uFE0F\u20E3 Usar headless (sem UI - intencional):
|
|
1646
|
+
// Use hooks como useConsent() para criar UI customizada
|
|
1647
|
+
// Ignore este aviso se for intencional
|
|
1648
|
+
|
|
1649
|
+
\u{1F4DA} Docs: https://github.com/lucianoedipo/react-lgpd-consent#usage
|
|
1650
|
+
`
|
|
1651
|
+
);
|
|
1652
|
+
return null;
|
|
1653
|
+
})()
|
|
1654
|
+
),
|
|
1655
|
+
blocking && isHydrated && !state.consented && blockingStrategy === "provider" && /* @__PURE__ */ jsxRuntime.jsx(
|
|
1656
|
+
"div",
|
|
1657
|
+
{
|
|
1658
|
+
style: {
|
|
1659
|
+
position: "fixed",
|
|
1660
|
+
top: 0,
|
|
1661
|
+
left: 0,
|
|
1662
|
+
right: 0,
|
|
1663
|
+
bottom: 0,
|
|
1664
|
+
backgroundColor: providerBackdropColor,
|
|
1665
|
+
zIndex: 1299
|
|
1666
|
+
},
|
|
1667
|
+
"data-testid": "lgpd-provider-overlay",
|
|
1668
|
+
"aria-hidden": true
|
|
1669
|
+
}
|
|
1670
|
+
),
|
|
1671
|
+
!state.consented && isHydrated && CookieBannerComponent && /* @__PURE__ */ jsxRuntime.jsx(
|
|
1672
|
+
CookieBannerComponent,
|
|
1673
|
+
{
|
|
1674
|
+
consented: api.consented,
|
|
1675
|
+
acceptAll: api.acceptAll,
|
|
1676
|
+
rejectAll: api.rejectAll,
|
|
1677
|
+
openPreferences: api.openPreferences,
|
|
1678
|
+
texts,
|
|
1679
|
+
blocking,
|
|
1680
|
+
...cookieBannerProps
|
|
1681
|
+
}
|
|
1682
|
+
),
|
|
1683
|
+
state.consented && !disableFloatingPreferencesButton && FloatingPreferencesButtonComponent && /* @__PURE__ */ jsxRuntime.jsx(
|
|
1684
|
+
FloatingPreferencesButtonComponent,
|
|
1685
|
+
{
|
|
1686
|
+
openPreferences: api.openPreferences,
|
|
1687
|
+
consented: api.consented,
|
|
1688
|
+
...floatingPreferencesButtonProps
|
|
1689
|
+
}
|
|
1690
|
+
)
|
|
1691
|
+
]
|
|
1692
|
+
}
|
|
1693
|
+
) }) }) }) }) });
|
|
1694
|
+
return content;
|
|
1695
|
+
}
|
|
1696
|
+
function useConsentStateInternal() {
|
|
1697
|
+
const ctx = React4__namespace.useContext(StateCtx);
|
|
1698
|
+
if (!ctx) throw new Error("useConsentState must be used within ConsentProvider");
|
|
1699
|
+
return ctx;
|
|
1700
|
+
}
|
|
1701
|
+
function useConsentActionsInternal() {
|
|
1702
|
+
const ctx = React4__namespace.useContext(ActionsCtx);
|
|
1703
|
+
if (!ctx) throw new Error("useConsentActions must be used within ConsentProvider");
|
|
1704
|
+
return ctx;
|
|
1705
|
+
}
|
|
1706
|
+
function useConsentTextsInternal() {
|
|
1707
|
+
const ctx = React4__namespace.useContext(TextsCtx);
|
|
1708
|
+
return ctx;
|
|
1709
|
+
}
|
|
1710
|
+
function useConsentHydrationInternal() {
|
|
1711
|
+
return React4__namespace.useContext(HydrationCtx);
|
|
1712
|
+
}
|
|
1713
|
+
var defaultTexts = DEFAULT_TEXTS;
|
|
1714
|
+
function ConsentGate(props) {
|
|
1715
|
+
const { preferences } = useConsent();
|
|
1716
|
+
if (!preferences[props.category]) return null;
|
|
1717
|
+
return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: props.children });
|
|
1718
|
+
}
|
|
1719
|
+
|
|
1720
|
+
// src/utils/scriptLoader.ts
|
|
1721
|
+
function loadScript(id, src, category = null, attrs = {}) {
|
|
1722
|
+
if (typeof document === "undefined") return Promise.resolve();
|
|
1723
|
+
if (document.getElementById(id)) return Promise.resolve();
|
|
1724
|
+
return new Promise((resolve, reject) => {
|
|
1725
|
+
const checkConsent = () => {
|
|
1726
|
+
const consentCookie = document.cookie.split("; ").find((row) => row.startsWith("cookieConsent="))?.split("=")[1];
|
|
1727
|
+
if (!consentCookie) {
|
|
1728
|
+
setTimeout(checkConsent, 100);
|
|
1729
|
+
return;
|
|
1730
|
+
}
|
|
1731
|
+
try {
|
|
1732
|
+
const consent = JSON.parse(decodeURIComponent(consentCookie));
|
|
1733
|
+
if (!consent.consented || consent.isModalOpen) {
|
|
1734
|
+
setTimeout(checkConsent, 100);
|
|
1735
|
+
return;
|
|
1736
|
+
}
|
|
1737
|
+
if (category && !consent.preferences[category]) {
|
|
1738
|
+
reject(new Error(`Consent not given for ${category} scripts`));
|
|
1739
|
+
return;
|
|
1740
|
+
}
|
|
1741
|
+
const s = document.createElement("script");
|
|
1742
|
+
s.id = id;
|
|
1743
|
+
s.src = src;
|
|
1744
|
+
s.async = true;
|
|
1745
|
+
for (const [k, v] of Object.entries(attrs)) s.setAttribute(k, v);
|
|
1746
|
+
s.onload = () => resolve();
|
|
1747
|
+
s.onerror = () => reject(new Error(`Failed to load script: ${src}`));
|
|
1748
|
+
document.body.appendChild(s);
|
|
1749
|
+
} catch {
|
|
1750
|
+
setTimeout(checkConsent, 100);
|
|
1751
|
+
}
|
|
1752
|
+
};
|
|
1753
|
+
checkConsent();
|
|
1754
|
+
});
|
|
1755
|
+
}
|
|
1756
|
+
|
|
1757
|
+
// src/utils/autoConfigureCategories.ts
|
|
1758
|
+
var FORBIDDEN_NECESSARY_SCRIPTS = /* @__PURE__ */ new Set([
|
|
1759
|
+
// Analytics & Performance
|
|
1760
|
+
"google-analytics",
|
|
1761
|
+
"google-tag-manager",
|
|
1762
|
+
"hotjar",
|
|
1763
|
+
"mixpanel",
|
|
1764
|
+
"clarity",
|
|
1765
|
+
"amplitude",
|
|
1766
|
+
"segment",
|
|
1767
|
+
// Marketing & Advertising
|
|
1768
|
+
"facebook-pixel",
|
|
1769
|
+
"twitter-pixel",
|
|
1770
|
+
"linkedin-insight",
|
|
1771
|
+
"pinterest-tag",
|
|
1772
|
+
"snapchat-pixel",
|
|
1773
|
+
"tiktok-pixel",
|
|
1774
|
+
"reddit-pixel",
|
|
1775
|
+
// Communication & Support
|
|
1776
|
+
"intercom",
|
|
1777
|
+
"zendesk-chat",
|
|
1778
|
+
"drift",
|
|
1779
|
+
"crisp",
|
|
1780
|
+
"freshchat",
|
|
1781
|
+
// A/B Testing & Optimization
|
|
1782
|
+
"optimizely",
|
|
1783
|
+
"vwo",
|
|
1784
|
+
"google-optimize",
|
|
1785
|
+
"unbounce",
|
|
1786
|
+
// Social & Content
|
|
1787
|
+
"youtube-embed",
|
|
1788
|
+
"vimeo-embed",
|
|
1789
|
+
"twitter-widget",
|
|
1790
|
+
"facebook-widget",
|
|
1791
|
+
"instagram-widget",
|
|
1792
|
+
// Accessibility (exceto scripts críticos)
|
|
1793
|
+
"userway"
|
|
1794
|
+
]);
|
|
1795
|
+
function analyzeIntegrationCategories(integrations) {
|
|
1796
|
+
const categoryMap = {};
|
|
1797
|
+
integrations.forEach((integration) => {
|
|
1798
|
+
const category = integration.category;
|
|
1799
|
+
if (!categoryMap[category]) {
|
|
1800
|
+
categoryMap[category] = [];
|
|
1801
|
+
}
|
|
1802
|
+
categoryMap[category].push(integration.id);
|
|
1803
|
+
});
|
|
1804
|
+
return categoryMap;
|
|
1805
|
+
}
|
|
1806
|
+
function autoConfigureCategories(originalConfig, integrations, options = {}) {
|
|
1807
|
+
const { warningOnly = false, silent = false } = options;
|
|
1808
|
+
const config = originalConfig || { enabledCategories: ["analytics"] };
|
|
1809
|
+
const categoryIntegrations = analyzeIntegrationCategories(integrations);
|
|
1810
|
+
const requiredCategories = Object.keys(categoryIntegrations);
|
|
1811
|
+
const currentCategories = new Set(config.enabledCategories || []);
|
|
1812
|
+
const missingCategories = requiredCategories.filter((cat) => !currentCategories.has(cat));
|
|
1813
|
+
let adjustedConfig = { ...config };
|
|
1814
|
+
let autoEnabledCategories = [];
|
|
1815
|
+
if (missingCategories.length > 0) {
|
|
1816
|
+
if (warningOnly) {
|
|
1817
|
+
if (!silent) {
|
|
1818
|
+
logMissingCategoriesWarning(missingCategories, categoryIntegrations);
|
|
1819
|
+
}
|
|
1820
|
+
} else {
|
|
1821
|
+
autoEnabledCategories = [...missingCategories];
|
|
1822
|
+
adjustedConfig = {
|
|
1823
|
+
...config,
|
|
1824
|
+
enabledCategories: [...currentCategories, ...missingCategories]
|
|
1825
|
+
};
|
|
1826
|
+
if (!silent) {
|
|
1827
|
+
logAutoEnabledCategories(autoEnabledCategories, categoryIntegrations);
|
|
1828
|
+
}
|
|
1829
|
+
}
|
|
1830
|
+
}
|
|
1831
|
+
return {
|
|
1832
|
+
originalConfig: config,
|
|
1833
|
+
adjustedConfig,
|
|
1834
|
+
autoEnabledCategories,
|
|
1835
|
+
missingCategories,
|
|
1836
|
+
wasAdjusted: autoEnabledCategories.length > 0,
|
|
1837
|
+
categoryIntegrations
|
|
1838
|
+
};
|
|
1839
|
+
}
|
|
1840
|
+
function logMissingCategoriesWarning(missingCategories, categoryIntegrations) {
|
|
1841
|
+
const isDev2 = process.env.NODE_ENV !== "production";
|
|
1842
|
+
if (!isDev2) return;
|
|
1843
|
+
const PREFIX = "[\u{1F36A} LGPD-CONSENT AUTO-CONFIG]";
|
|
1844
|
+
console.group(`${PREFIX} \u26A0\uFE0F Categorias Requeridas N\xE3o Habilitadas`);
|
|
1845
|
+
missingCategories.forEach((category) => {
|
|
1846
|
+
const integrations = categoryIntegrations[category] || [];
|
|
1847
|
+
console.warn(
|
|
1848
|
+
`${PREFIX} Categoria '${category}' requerida por integra\xE7\xF5es: ${integrations.join(", ")}`
|
|
1849
|
+
);
|
|
1850
|
+
});
|
|
1851
|
+
const categoriesCode = missingCategories.map((c) => `'${c}'`).join(", ");
|
|
1852
|
+
console.warn(
|
|
1853
|
+
`${PREFIX} Para corrigir, adicione estas categorias ao ConsentProvider:`,
|
|
1854
|
+
`categories={{ enabledCategories: [...existingCategories, ${categoriesCode}] }}`
|
|
1855
|
+
);
|
|
1856
|
+
console.groupEnd();
|
|
1857
|
+
}
|
|
1858
|
+
function logAutoEnabledCategories(autoEnabledCategories, categoryIntegrations) {
|
|
1859
|
+
const isDev2 = process.env.NODE_ENV !== "production";
|
|
1860
|
+
if (!isDev2) return;
|
|
1861
|
+
const PREFIX = "[\u{1F36A} LGPD-CONSENT AUTO-CONFIG]";
|
|
1862
|
+
console.group(`${PREFIX} \u2705 Categorias Auto-Habilitadas`);
|
|
1863
|
+
autoEnabledCategories.forEach((category) => {
|
|
1864
|
+
const integrations = categoryIntegrations[category] || [];
|
|
1865
|
+
console.info(
|
|
1866
|
+
`${PREFIX} Categoria '${category}' auto-habilitada para integra\xE7\xF5es: ${integrations.join(", ")}`
|
|
1867
|
+
);
|
|
1868
|
+
});
|
|
1869
|
+
console.info(`${PREFIX} \u{1F4A1} Essas categorias foram automaticamente adicionadas \xE0 configura\xE7\xE3o.`);
|
|
1870
|
+
console.info(`${PREFIX} \u{1F527} Para controle manual, especifique explicitamente no ConsentProvider.`);
|
|
1871
|
+
console.groupEnd();
|
|
1872
|
+
}
|
|
1873
|
+
function validateIntegrationCategories(integrations, enabledCategories) {
|
|
1874
|
+
const requiredCategories = integrations.map((i) => i.category);
|
|
1875
|
+
const enabledSet = new Set(enabledCategories);
|
|
1876
|
+
return requiredCategories.every((category) => enabledSet.has(category));
|
|
1877
|
+
}
|
|
1878
|
+
function extractCategoriesFromIntegrations(integrations) {
|
|
1879
|
+
const categories = /* @__PURE__ */ new Set();
|
|
1880
|
+
integrations.forEach((integration) => {
|
|
1881
|
+
categories.add(integration.category);
|
|
1882
|
+
});
|
|
1883
|
+
return Array.from(categories);
|
|
1884
|
+
}
|
|
1885
|
+
function validateNecessaryClassification(integrations, enabledCategories) {
|
|
1886
|
+
const warnings = [];
|
|
1887
|
+
const hasNecessaryCategory = enabledCategories.includes("necessary");
|
|
1888
|
+
if (!hasNecessaryCategory) {
|
|
1889
|
+
return warnings;
|
|
1890
|
+
}
|
|
1891
|
+
const problematicIntegrations = integrations.filter(
|
|
1892
|
+
(integration) => integration.category === "necessary" && FORBIDDEN_NECESSARY_SCRIPTS.has(integration.id)
|
|
1893
|
+
);
|
|
1894
|
+
if (problematicIntegrations.length > 0) {
|
|
1895
|
+
warnings.push(
|
|
1896
|
+
`\u26A0\uFE0F ATEN\xC7\xC3O GDPR/LGPD: As seguintes integra\xE7\xF5es NUNCA devem ser classificadas como 'necessary':`
|
|
1897
|
+
);
|
|
1898
|
+
problematicIntegrations.forEach((integration) => {
|
|
1899
|
+
warnings.push(
|
|
1900
|
+
` \u2022 '${integration.id}' (categoria: ${integration.category}) - Requer consentimento expl\xEDcito`
|
|
1901
|
+
);
|
|
1902
|
+
});
|
|
1903
|
+
warnings.push(
|
|
1904
|
+
`\u{1F4A1} Scripts 'necessary' executam SEM consentimento e podem resultar em multas.`,
|
|
1905
|
+
`\u{1F4DA} Apenas scripts de seguran\xE7a, autentica\xE7\xE3o ou core do site se qualificam.`,
|
|
1906
|
+
`\u{1F527} Mova estes scripts para categorias apropriadas (analytics, marketing, etc.)`
|
|
1907
|
+
);
|
|
1908
|
+
}
|
|
1909
|
+
return warnings;
|
|
1910
|
+
}
|
|
1911
|
+
|
|
1912
|
+
// src/utils/ConsentScriptLoader.tsx
|
|
1913
|
+
function ConsentScriptLoader({
|
|
1914
|
+
integrations,
|
|
1915
|
+
reloadOnChange = false
|
|
1916
|
+
}) {
|
|
1917
|
+
const { preferences, consented } = useConsent();
|
|
1918
|
+
const categories = useCategories();
|
|
1919
|
+
const loadedScripts = React4__namespace.useRef(/* @__PURE__ */ new Set());
|
|
1920
|
+
React4__namespace.useEffect(() => {
|
|
1921
|
+
try {
|
|
1922
|
+
const ids = (integrations || []).map((i) => i.id);
|
|
1923
|
+
const gt = globalThis;
|
|
1924
|
+
const current = Array.isArray(gt.__LGPD_USED_INTEGRATIONS__) ? gt.__LGPD_USED_INTEGRATIONS__ : [];
|
|
1925
|
+
const merged = Array.from(/* @__PURE__ */ new Set([...current, ...ids]));
|
|
1926
|
+
gt.__LGPD_USED_INTEGRATIONS__ = merged;
|
|
1927
|
+
try {
|
|
1928
|
+
const gmap = globalThis;
|
|
1929
|
+
const map = gmap.__LGPD_INTEGRATIONS_MAP__ || {};
|
|
1930
|
+
(integrations || []).forEach((i) => {
|
|
1931
|
+
map[i.id] = i.category;
|
|
1932
|
+
});
|
|
1933
|
+
gmap.__LGPD_INTEGRATIONS_MAP__ = map;
|
|
1934
|
+
} catch {
|
|
1935
|
+
}
|
|
1936
|
+
} catch {
|
|
1937
|
+
}
|
|
1938
|
+
}, [integrations]);
|
|
1939
|
+
React4__namespace.useEffect(() => {
|
|
1940
|
+
try {
|
|
1941
|
+
const required = Array.from(new Set((integrations || []).map((i) => i.category))).filter(
|
|
1942
|
+
Boolean
|
|
1943
|
+
);
|
|
1944
|
+
const gt = globalThis;
|
|
1945
|
+
const current = Array.isArray(gt.__LGPD_REQUIRED_CATEGORIES__) ? gt.__LGPD_REQUIRED_CATEGORIES__ : [];
|
|
1946
|
+
const merged = Array.from(/* @__PURE__ */ new Set([...current, ...required]));
|
|
1947
|
+
gt.__LGPD_REQUIRED_CATEGORIES__ = merged;
|
|
1948
|
+
if (typeof window !== "undefined" && typeof window.dispatchEvent === "function") {
|
|
1949
|
+
window.dispatchEvent(new CustomEvent("lgpd:requiredCategories"));
|
|
1950
|
+
}
|
|
1951
|
+
} catch {
|
|
1952
|
+
}
|
|
1953
|
+
}, [integrations]);
|
|
1954
|
+
React4__namespace.useEffect(() => {
|
|
1955
|
+
const isDev2 = process.env.NODE_ENV !== "production";
|
|
1956
|
+
if (!isDev2 || integrations.length === 0) return;
|
|
1957
|
+
const enabledCategories = categories.allCategories.map((cat) => cat.id);
|
|
1958
|
+
const isValid = validateIntegrationCategories(integrations, enabledCategories);
|
|
1959
|
+
if (!isValid) {
|
|
1960
|
+
autoConfigureCategories({ enabledCategories }, integrations, {
|
|
1961
|
+
warningOnly: true,
|
|
1962
|
+
silent: false
|
|
1963
|
+
});
|
|
1964
|
+
}
|
|
1965
|
+
const necessaryWarnings = validateNecessaryClassification(integrations, enabledCategories);
|
|
1966
|
+
if (necessaryWarnings.length > 0) {
|
|
1967
|
+
console.group("\u{1F6A8} [LGPD-CONSENT] VALIDA\xC7\xC3O DE COMPLIANCE");
|
|
1968
|
+
necessaryWarnings.forEach((warning) => {
|
|
1969
|
+
if (warning.startsWith("\u26A0\uFE0F")) {
|
|
1970
|
+
console.error(warning);
|
|
1971
|
+
} else if (warning.startsWith("\u{1F4A1}") || warning.startsWith("\u{1F4DA}") || warning.startsWith("\u{1F527}")) {
|
|
1972
|
+
console.warn(warning);
|
|
1973
|
+
} else {
|
|
1974
|
+
console.log(warning);
|
|
1975
|
+
}
|
|
1976
|
+
});
|
|
1977
|
+
console.groupEnd();
|
|
1978
|
+
}
|
|
1979
|
+
}, [integrations, categories]);
|
|
1980
|
+
React4__namespace.useEffect(() => {
|
|
1981
|
+
if (!consented) return;
|
|
1982
|
+
integrations.forEach(async (integration) => {
|
|
1983
|
+
const shouldLoad = preferences[integration.category];
|
|
1984
|
+
const alreadyLoaded = loadedScripts.current.has(integration.id);
|
|
1985
|
+
if (shouldLoad && (!alreadyLoaded || reloadOnChange)) {
|
|
1986
|
+
try {
|
|
1987
|
+
await loadScript(integration.id, integration.src, integration.category, integration.attrs);
|
|
1988
|
+
if (integration.init) {
|
|
1989
|
+
integration.init();
|
|
1990
|
+
}
|
|
1991
|
+
loadedScripts.current.add(integration.id);
|
|
1992
|
+
} catch (error) {
|
|
1993
|
+
logger.error(`\u274C Failed to load script: ${integration.id}`, error);
|
|
1994
|
+
}
|
|
1995
|
+
}
|
|
1996
|
+
});
|
|
1997
|
+
}, [preferences, consented, integrations, reloadOnChange]);
|
|
1998
|
+
return null;
|
|
1999
|
+
}
|
|
2000
|
+
function useConsentScriptLoader() {
|
|
2001
|
+
const { preferences, consented } = useConsent();
|
|
2002
|
+
return React4__namespace.useCallback(
|
|
2003
|
+
async (integration) => {
|
|
2004
|
+
if (!consented) {
|
|
2005
|
+
logger.warn(`\u26A0\uFE0F Cannot load script ${integration.id}: No consent given`);
|
|
2006
|
+
return false;
|
|
2007
|
+
}
|
|
2008
|
+
const shouldLoad = preferences[integration.category];
|
|
2009
|
+
if (!shouldLoad) {
|
|
2010
|
+
logger.warn(
|
|
2011
|
+
`\u26A0\uFE0F Cannot load script ${integration.id}: Category '${integration.category}' not consented`
|
|
2012
|
+
);
|
|
2013
|
+
return false;
|
|
2014
|
+
}
|
|
2015
|
+
try {
|
|
2016
|
+
await loadScript(integration.id, integration.src, integration.category, integration.attrs);
|
|
2017
|
+
if (integration.init) {
|
|
2018
|
+
integration.init();
|
|
2019
|
+
}
|
|
2020
|
+
return true;
|
|
2021
|
+
} catch (error) {
|
|
2022
|
+
logger.error(`\u274C Failed to load script: ${integration.id}`, error);
|
|
2023
|
+
return false;
|
|
2024
|
+
}
|
|
2025
|
+
},
|
|
2026
|
+
[preferences, consented]
|
|
2027
|
+
);
|
|
2028
|
+
}
|
|
2029
|
+
|
|
2030
|
+
// src/utils/scriptIntegrations.ts
|
|
2031
|
+
function createGoogleAnalyticsIntegration(config) {
|
|
2032
|
+
const src = config.scriptUrl ?? `https://www.googletagmanager.com/gtag/js?id=${config.measurementId}`;
|
|
2033
|
+
return {
|
|
2034
|
+
id: "google-analytics",
|
|
2035
|
+
category: "analytics",
|
|
2036
|
+
src,
|
|
2037
|
+
cookies: ["_ga", "_ga_*", "_gid"],
|
|
2038
|
+
cookiesInfo: [
|
|
2039
|
+
{
|
|
2040
|
+
name: "_ga",
|
|
2041
|
+
purpose: "Identifica\xE7\xE3o \xFAnica de visitantes para an\xE1lise de tr\xE1fego",
|
|
2042
|
+
duration: "2 anos",
|
|
2043
|
+
provider: "Google Analytics"
|
|
2044
|
+
},
|
|
2045
|
+
{
|
|
2046
|
+
name: "_ga_*",
|
|
2047
|
+
purpose: "Rastreamento de sess\xF5es e eventos espec\xEDficos do stream GA4",
|
|
2048
|
+
duration: "2 anos",
|
|
2049
|
+
provider: "Google Analytics"
|
|
2050
|
+
},
|
|
2051
|
+
{
|
|
2052
|
+
name: "_gid",
|
|
2053
|
+
purpose: "Distin\xE7\xE3o de visitantes \xFAnicos em per\xEDodo de 24h",
|
|
2054
|
+
duration: "24 horas",
|
|
2055
|
+
provider: "Google Analytics"
|
|
2056
|
+
}
|
|
2057
|
+
],
|
|
2058
|
+
init: () => {
|
|
2059
|
+
if (typeof window !== "undefined") {
|
|
2060
|
+
const w = window;
|
|
2061
|
+
w.dataLayer = w.dataLayer ?? [];
|
|
2062
|
+
const gtag = (...args) => {
|
|
2063
|
+
w.dataLayer.push(...args);
|
|
2064
|
+
};
|
|
2065
|
+
w.gtag = gtag;
|
|
2066
|
+
gtag("js", /* @__PURE__ */ new Date());
|
|
2067
|
+
gtag("config", config.measurementId, config.config ?? {});
|
|
2068
|
+
}
|
|
2069
|
+
},
|
|
2070
|
+
attrs: { async: "true" }
|
|
2071
|
+
};
|
|
2072
|
+
}
|
|
2073
|
+
function createGoogleTagManagerIntegration(config) {
|
|
2074
|
+
const src = config.scriptUrl ?? `https://www.googletagmanager.com/gtm.js?id=${config.containerId}`;
|
|
2075
|
+
return {
|
|
2076
|
+
id: "google-tag-manager",
|
|
2077
|
+
category: "analytics",
|
|
2078
|
+
src,
|
|
2079
|
+
cookies: ["_gcl_au"],
|
|
2080
|
+
init: () => {
|
|
2081
|
+
if (typeof window !== "undefined") {
|
|
2082
|
+
const dataLayerName = config.dataLayerName || "dataLayer";
|
|
2083
|
+
const w = window;
|
|
2084
|
+
const layer = w[dataLayerName] ?? [];
|
|
2085
|
+
w[dataLayerName] = layer;
|
|
2086
|
+
layer.push({ "gtm.start": (/* @__PURE__ */ new Date()).getTime(), event: "gtm.js" });
|
|
2087
|
+
}
|
|
2088
|
+
}
|
|
2089
|
+
};
|
|
2090
|
+
}
|
|
2091
|
+
function createUserWayIntegration(config) {
|
|
2092
|
+
const src = config.scriptUrl ?? "https://cdn.userway.org/widget.js";
|
|
2093
|
+
return {
|
|
2094
|
+
id: "userway",
|
|
2095
|
+
category: "functional",
|
|
2096
|
+
src,
|
|
2097
|
+
cookies: ["_userway_*"],
|
|
2098
|
+
init: () => {
|
|
2099
|
+
if (typeof window !== "undefined") {
|
|
2100
|
+
const w = window;
|
|
2101
|
+
w.UserWayWidgetApp = w.UserWayWidgetApp || {};
|
|
2102
|
+
w.UserWayWidgetApp.accountId = config.accountId;
|
|
2103
|
+
}
|
|
2104
|
+
},
|
|
2105
|
+
attrs: { "data-account": config.accountId }
|
|
2106
|
+
};
|
|
2107
|
+
}
|
|
2108
|
+
var COMMON_INTEGRATIONS = {
|
|
2109
|
+
googleAnalytics: createGoogleAnalyticsIntegration,
|
|
2110
|
+
googleTagManager: createGoogleTagManagerIntegration,
|
|
2111
|
+
userway: createUserWayIntegration
|
|
2112
|
+
};
|
|
2113
|
+
function createFacebookPixelIntegration(config) {
|
|
2114
|
+
const src = config.scriptUrl ?? "https://connect.facebook.net/en_US/fbevents.js";
|
|
2115
|
+
return {
|
|
2116
|
+
id: "facebook-pixel",
|
|
2117
|
+
category: "marketing",
|
|
2118
|
+
src,
|
|
2119
|
+
cookies: ["_fbp", "fr"],
|
|
2120
|
+
init: () => {
|
|
2121
|
+
if (typeof window !== "undefined") {
|
|
2122
|
+
const w = window;
|
|
2123
|
+
if (!w.fbq) {
|
|
2124
|
+
const fbq = (...args) => {
|
|
2125
|
+
if (w.fbq && typeof w.fbq.callMethod === "function") {
|
|
2126
|
+
w.fbq.callMethod(...args);
|
|
2127
|
+
} else {
|
|
2128
|
+
fbq.queue = fbq.queue || [];
|
|
2129
|
+
fbq.queue.push(args);
|
|
2130
|
+
}
|
|
2131
|
+
};
|
|
2132
|
+
fbq.loaded = true;
|
|
2133
|
+
w.fbq = fbq;
|
|
2134
|
+
}
|
|
2135
|
+
w.fbq("init", config.pixelId, config.advancedMatching ?? {});
|
|
2136
|
+
if (config.autoTrack !== false) w.fbq("track", "PageView");
|
|
2137
|
+
}
|
|
2138
|
+
}
|
|
2139
|
+
};
|
|
2140
|
+
}
|
|
2141
|
+
function createHotjarIntegration(config) {
|
|
2142
|
+
const v = config.version ?? 6;
|
|
2143
|
+
const src = config.scriptUrl ?? `https://static.hotjar.com/c/hotjar-${config.siteId}.js?sv=${v}`;
|
|
2144
|
+
return {
|
|
2145
|
+
id: "hotjar",
|
|
2146
|
+
category: "analytics",
|
|
2147
|
+
src,
|
|
2148
|
+
cookies: [
|
|
2149
|
+
"_hjSession_*",
|
|
2150
|
+
"_hjSessionUser_*",
|
|
2151
|
+
"_hjFirstSeen",
|
|
2152
|
+
"_hjIncludedInSessionSample",
|
|
2153
|
+
"_hjAbsoluteSessionInProgress"
|
|
2154
|
+
],
|
|
2155
|
+
cookiesInfo: [
|
|
2156
|
+
{
|
|
2157
|
+
name: "_hjSession_*",
|
|
2158
|
+
purpose: "Identifica\xE7\xE3o \xFAnica da sess\xE3o de grava\xE7\xE3o e heatmaps",
|
|
2159
|
+
duration: "30 minutos",
|
|
2160
|
+
provider: "Hotjar"
|
|
2161
|
+
},
|
|
2162
|
+
{
|
|
2163
|
+
name: "_hjSessionUser_*",
|
|
2164
|
+
purpose: "Identifica\xE7\xE3o persistente do usu\xE1rio entre sess\xF5es",
|
|
2165
|
+
duration: "365 dias",
|
|
2166
|
+
provider: "Hotjar"
|
|
2167
|
+
},
|
|
2168
|
+
{
|
|
2169
|
+
name: "_hjFirstSeen",
|
|
2170
|
+
purpose: "Detec\xE7\xE3o de primeira visita do usu\xE1rio ao site",
|
|
2171
|
+
duration: "Sess\xE3o",
|
|
2172
|
+
provider: "Hotjar"
|
|
2173
|
+
},
|
|
2174
|
+
{
|
|
2175
|
+
name: "_hjIncludedInSessionSample",
|
|
2176
|
+
purpose: "Indica se a sess\xE3o est\xE1 inclu\xEDda na amostra de grava\xE7\xE3o",
|
|
2177
|
+
duration: "30 minutos",
|
|
2178
|
+
provider: "Hotjar"
|
|
2179
|
+
},
|
|
2180
|
+
{
|
|
2181
|
+
name: "_hjAbsoluteSessionInProgress",
|
|
2182
|
+
purpose: "Detecta se uma sess\xE3o absoluta est\xE1 em progresso",
|
|
2183
|
+
duration: "30 minutos",
|
|
2184
|
+
provider: "Hotjar"
|
|
2185
|
+
}
|
|
2186
|
+
],
|
|
2187
|
+
init: () => {
|
|
2188
|
+
if (typeof window !== "undefined") {
|
|
2189
|
+
const w = window;
|
|
2190
|
+
w._hjSettings = { hjid: config.siteId, hjsv: v };
|
|
2191
|
+
if (!w.hj) {
|
|
2192
|
+
const hj = (...args) => {
|
|
2193
|
+
hj.q = hj.q || [];
|
|
2194
|
+
hj.q.push(args);
|
|
2195
|
+
};
|
|
2196
|
+
w.hj = hj;
|
|
2197
|
+
}
|
|
2198
|
+
if (config.debug && typeof console !== "undefined" && typeof console.info === "function") {
|
|
2199
|
+
console.info("[Hotjar] initialized with siteId", config.siteId);
|
|
2200
|
+
}
|
|
2201
|
+
}
|
|
2202
|
+
}
|
|
2203
|
+
};
|
|
2204
|
+
}
|
|
2205
|
+
function createMixpanelIntegration(config) {
|
|
2206
|
+
const src = config.scriptUrl ?? "https://cdn.mxpnl.com/libs/mixpanel-2-latest.min.js";
|
|
2207
|
+
return {
|
|
2208
|
+
id: "mixpanel",
|
|
2209
|
+
category: "analytics",
|
|
2210
|
+
src,
|
|
2211
|
+
cookies: ["mp_*"],
|
|
2212
|
+
cookiesInfo: [
|
|
2213
|
+
{
|
|
2214
|
+
name: "mp_*",
|
|
2215
|
+
purpose: "Rastreamento de eventos e propriedades do usu\xE1rio para analytics",
|
|
2216
|
+
duration: "1 ano",
|
|
2217
|
+
provider: "Mixpanel"
|
|
2218
|
+
}
|
|
2219
|
+
],
|
|
2220
|
+
init: () => {
|
|
2221
|
+
if (typeof window !== "undefined") {
|
|
2222
|
+
const w = window;
|
|
2223
|
+
w.mixpanel = w.mixpanel || { init: () => void 0 };
|
|
2224
|
+
if (w.mixpanel && typeof w.mixpanel.init === "function") {
|
|
2225
|
+
try {
|
|
2226
|
+
w.mixpanel.init(config.token, config.config ?? {}, config.api_host);
|
|
2227
|
+
} catch (error) {
|
|
2228
|
+
if (typeof console !== "undefined" && typeof console.warn === "function") {
|
|
2229
|
+
console.warn("[Mixpanel] Failed to initialize:", error);
|
|
2230
|
+
}
|
|
2231
|
+
}
|
|
2232
|
+
}
|
|
2233
|
+
}
|
|
2234
|
+
}
|
|
2235
|
+
};
|
|
2236
|
+
}
|
|
2237
|
+
function createClarityIntegration(config) {
|
|
2238
|
+
const src = config.scriptUrl ?? `https://www.clarity.ms/tag/${config.projectId}`;
|
|
2239
|
+
return {
|
|
2240
|
+
id: "clarity",
|
|
2241
|
+
category: "analytics",
|
|
2242
|
+
src,
|
|
2243
|
+
cookies: ["_clck", "_clsk", "CLID", "ANONCHK", "MR", "MUID", "SM"],
|
|
2244
|
+
init: () => {
|
|
2245
|
+
if (typeof window !== "undefined" && typeof config.upload !== "undefined") {
|
|
2246
|
+
const w = window;
|
|
2247
|
+
if (typeof w.clarity === "function") {
|
|
2248
|
+
try {
|
|
2249
|
+
w.clarity("set", "upload", config.upload);
|
|
2250
|
+
} catch (error) {
|
|
2251
|
+
if (typeof console !== "undefined" && typeof console.warn === "function") {
|
|
2252
|
+
console.warn("[Clarity] Failed to configure upload setting:", error);
|
|
2253
|
+
}
|
|
2254
|
+
}
|
|
2255
|
+
}
|
|
2256
|
+
}
|
|
2257
|
+
}
|
|
2258
|
+
};
|
|
2259
|
+
}
|
|
2260
|
+
function createIntercomIntegration(config) {
|
|
2261
|
+
const src = config.scriptUrl ?? `https://widget.intercom.io/widget/${config.app_id}`;
|
|
2262
|
+
return {
|
|
2263
|
+
id: "intercom",
|
|
2264
|
+
category: "functional",
|
|
2265
|
+
src,
|
|
2266
|
+
cookies: ["intercom-id-*", "intercom-session-*"],
|
|
2267
|
+
init: () => {
|
|
2268
|
+
if (typeof window !== "undefined") {
|
|
2269
|
+
const w = window;
|
|
2270
|
+
if (typeof w.Intercom === "function") {
|
|
2271
|
+
try {
|
|
2272
|
+
w.Intercom("boot", { app_id: config.app_id });
|
|
2273
|
+
} catch (error) {
|
|
2274
|
+
if (typeof console !== "undefined" && typeof console.warn === "function") {
|
|
2275
|
+
console.warn("[Intercom] Failed to boot:", error);
|
|
2276
|
+
}
|
|
2277
|
+
}
|
|
2278
|
+
}
|
|
2279
|
+
}
|
|
2280
|
+
}
|
|
2281
|
+
};
|
|
2282
|
+
}
|
|
2283
|
+
function createZendeskChatIntegration(config) {
|
|
2284
|
+
const src = config.scriptUrl ?? `https://static.zdassets.com/ekr/snippet.js?key=${config.key}`;
|
|
2285
|
+
return {
|
|
2286
|
+
id: "zendesk-chat",
|
|
2287
|
+
category: "functional",
|
|
2288
|
+
src,
|
|
2289
|
+
cookies: ["__zlcmid", "_zendesk_shared_session"],
|
|
2290
|
+
init: () => {
|
|
2291
|
+
if (typeof window !== "undefined") {
|
|
2292
|
+
const w = window;
|
|
2293
|
+
if (typeof w.zE === "function") {
|
|
2294
|
+
try {
|
|
2295
|
+
w.zE("webWidget", "identify", { key: config.key });
|
|
2296
|
+
} catch (error) {
|
|
2297
|
+
if (typeof console !== "undefined" && typeof console.warn === "function") {
|
|
2298
|
+
console.warn("[Zendesk] Failed to identify:", error);
|
|
2299
|
+
}
|
|
2300
|
+
}
|
|
2301
|
+
}
|
|
2302
|
+
}
|
|
2303
|
+
}
|
|
2304
|
+
};
|
|
2305
|
+
}
|
|
2306
|
+
function createECommerceIntegrations(cfg) {
|
|
2307
|
+
const list = [];
|
|
2308
|
+
if (cfg.googleAnalytics) list.push(createGoogleAnalyticsIntegration(cfg.googleAnalytics));
|
|
2309
|
+
if (cfg.facebookPixel) list.push(createFacebookPixelIntegration(cfg.facebookPixel));
|
|
2310
|
+
if (cfg.hotjar) list.push(createHotjarIntegration(cfg.hotjar));
|
|
2311
|
+
if (cfg.userway) list.push(createUserWayIntegration(cfg.userway));
|
|
2312
|
+
return list;
|
|
2313
|
+
}
|
|
2314
|
+
function createSaaSIntegrations(cfg) {
|
|
2315
|
+
const list = [];
|
|
2316
|
+
if (cfg.googleAnalytics) list.push(createGoogleAnalyticsIntegration(cfg.googleAnalytics));
|
|
2317
|
+
if (cfg.mixpanel) list.push(createMixpanelIntegration(cfg.mixpanel));
|
|
2318
|
+
if (cfg.intercom) list.push(createIntercomIntegration(cfg.intercom));
|
|
2319
|
+
if (cfg.hotjar) list.push(createHotjarIntegration(cfg.hotjar));
|
|
2320
|
+
return list;
|
|
2321
|
+
}
|
|
2322
|
+
function createCorporateIntegrations(cfg) {
|
|
2323
|
+
const list = [];
|
|
2324
|
+
if (cfg.googleAnalytics) list.push(createGoogleAnalyticsIntegration(cfg.googleAnalytics));
|
|
2325
|
+
if (cfg.clarity) list.push(createClarityIntegration(cfg.clarity));
|
|
2326
|
+
if (cfg.zendesk) list.push(createZendeskChatIntegration(cfg.zendesk));
|
|
2327
|
+
if (cfg.userway) list.push(createUserWayIntegration(cfg.userway));
|
|
2328
|
+
return list;
|
|
2329
|
+
}
|
|
2330
|
+
var INTEGRATION_TEMPLATES = {
|
|
2331
|
+
ecommerce: {
|
|
2332
|
+
essential: ["google-analytics", "facebook-pixel"],
|
|
2333
|
+
optional: ["hotjar", "userway"],
|
|
2334
|
+
categories: ["analytics", "marketing", "functional"]
|
|
2335
|
+
},
|
|
2336
|
+
saas: {
|
|
2337
|
+
essential: ["google-analytics", "mixpanel"],
|
|
2338
|
+
optional: ["intercom", "hotjar"],
|
|
2339
|
+
categories: ["analytics", "functional"]
|
|
2340
|
+
},
|
|
2341
|
+
corporate: {
|
|
2342
|
+
essential: ["google-analytics"],
|
|
2343
|
+
optional: ["userway", "zendesk-chat", "clarity"],
|
|
2344
|
+
categories: ["analytics", "functional"]
|
|
2345
|
+
}
|
|
2346
|
+
};
|
|
2347
|
+
function suggestCategoryForScript(name) {
|
|
2348
|
+
const n = name.toLowerCase();
|
|
2349
|
+
if (n.includes("facebook") || n.includes("pixel") || n.includes("ads")) return ["marketing"];
|
|
2350
|
+
if (n.includes("hotjar") || n.includes("mixpanel") || n.includes("clarity")) return ["analytics"];
|
|
2351
|
+
if (n.includes("intercom") || n.includes("zendesk") || n.includes("chat")) return ["functional"];
|
|
2352
|
+
return ["analytics"];
|
|
2353
|
+
}
|
|
2354
|
+
|
|
2355
|
+
// src/types/advancedTexts.ts
|
|
2356
|
+
var EXPANDED_DEFAULT_TEXTS = {
|
|
2357
|
+
// Textos adicionais
|
|
2358
|
+
confirm: "Confirmar",
|
|
2359
|
+
cancel: "Cancelar",
|
|
2360
|
+
loading: "Carregando...",
|
|
2361
|
+
// Feedback
|
|
2362
|
+
feedback: {
|
|
2363
|
+
saveSuccess: "Prefer\xEAncias salvas com sucesso!",
|
|
2364
|
+
saveError: "Erro ao salvar prefer\xEAncias. Tente novamente.",
|
|
2365
|
+
consentUpdated: "Consentimento atualizado.",
|
|
2366
|
+
cookiesRejected: "Cookies opcionais rejeitados.",
|
|
2367
|
+
settingsReset: "Configura\xE7\xF5es resetadas."
|
|
2368
|
+
},
|
|
2369
|
+
// Acessibilidade
|
|
2370
|
+
accessibility: {
|
|
2371
|
+
bannerLabel: "Banner de consentimento de cookies",
|
|
2372
|
+
modalLabel: "Modal de prefer\xEAncias de cookies",
|
|
2373
|
+
keyboardNavigation: "Use Tab para navegar, Enter para selecionar",
|
|
2374
|
+
toggleState: {
|
|
2375
|
+
enabled: "Habilitado",
|
|
2376
|
+
disabled: "Desabilitado"
|
|
2377
|
+
},
|
|
2378
|
+
liveRegion: "Regi\xE3o de an\xFAncios din\xE2micos"
|
|
2379
|
+
},
|
|
2380
|
+
// Categorias
|
|
2381
|
+
categories: {
|
|
2382
|
+
necessary: {
|
|
2383
|
+
name: "Cookies Necess\xE1rios",
|
|
2384
|
+
description: "Essenciais para o funcionamento b\xE1sico do site",
|
|
2385
|
+
examples: "Sess\xE3o, seguran\xE7a, prefer\xEAncias de idioma"
|
|
2386
|
+
},
|
|
2387
|
+
analytics: {
|
|
2388
|
+
name: "Cookies de Analytics",
|
|
2389
|
+
description: "Ajudam a entender como os visitantes usam o site",
|
|
2390
|
+
examples: "Google Analytics, contadores de p\xE1gina"
|
|
2391
|
+
},
|
|
2392
|
+
marketing: {
|
|
2393
|
+
name: "Cookies de Marketing",
|
|
2394
|
+
description: "Usados para personalizar an\xFAncios e ofertas",
|
|
2395
|
+
examples: "Facebook Pixel, Google Ads, remarketing"
|
|
2396
|
+
},
|
|
2397
|
+
functional: {
|
|
2398
|
+
name: "Cookies Funcionais",
|
|
2399
|
+
description: "Melhoram a funcionalidade e personaliza\xE7\xE3o",
|
|
2400
|
+
examples: "Chat, mapas, v\xEDdeos embarcados"
|
|
2401
|
+
},
|
|
2402
|
+
performance: {
|
|
2403
|
+
name: "Cookies de Performance",
|
|
2404
|
+
description: "Coletam informa\xE7\xF5es sobre velocidade e estabilidade",
|
|
2405
|
+
examples: "Monitoramento de erro, otimiza\xE7\xE3o de velocidade"
|
|
2406
|
+
}
|
|
2407
|
+
},
|
|
2408
|
+
// Contextos específicos
|
|
2409
|
+
contexts: {
|
|
2410
|
+
ecommerce: {
|
|
2411
|
+
cartAbandonment: "Lembramos dos produtos no seu carrinho",
|
|
2412
|
+
personalizedOffers: "Ofertas personalizadas baseadas no seu hist\xF3rico",
|
|
2413
|
+
paymentSecurity: "Seguran\xE7a adicional no processo de pagamento",
|
|
2414
|
+
productRecommendations: "Sugest\xF5es de produtos relevantes"
|
|
2415
|
+
},
|
|
2416
|
+
saas: {
|
|
2417
|
+
userAnalytics: "An\xE1lise de uso para melhorar funcionalidades",
|
|
2418
|
+
performanceMonitoring: "Monitoramento de performance da aplica\xE7\xE3o",
|
|
2419
|
+
featureUsage: "Estat\xEDsticas de uso de recursos",
|
|
2420
|
+
customerSupport: "Suporte ao cliente mais eficiente"
|
|
2421
|
+
},
|
|
2422
|
+
government: {
|
|
2423
|
+
citizenServices: "Melhoria dos servi\xE7os ao cidad\xE3o",
|
|
2424
|
+
dataProtection: "Prote\xE7\xE3o rigorosa dos dados pessoais",
|
|
2425
|
+
transparency: "Transpar\xEAncia no uso de dados",
|
|
2426
|
+
accessibility: "Recursos de acessibilidade digital"
|
|
2427
|
+
},
|
|
2428
|
+
education: {
|
|
2429
|
+
studentProgress: "Acompanhamento do progresso educacional",
|
|
2430
|
+
learningAnalytics: "Analytics para melhorar o aprendizado",
|
|
2431
|
+
accessibility: "Recursos educacionais acess\xEDveis",
|
|
2432
|
+
parentalConsent: "Consentimento parental quando necess\xE1rio"
|
|
2433
|
+
}
|
|
2434
|
+
},
|
|
2435
|
+
// Variações de tom
|
|
2436
|
+
variants: {
|
|
2437
|
+
formal: {
|
|
2438
|
+
bannerMessage: "Este s\xEDtio eletr\xF4nico utiliza cookies para otimizar a experi\xEAncia de navega\xE7\xE3o.",
|
|
2439
|
+
acceptAll: "Concordar com todos os cookies",
|
|
2440
|
+
declineAll: "Recusar cookies opcionais",
|
|
2441
|
+
modalTitle: "Configura\xE7\xE3o de Cookies"
|
|
2442
|
+
},
|
|
2443
|
+
casual: {
|
|
2444
|
+
bannerMessage: "\u{1F36A} Ei! Usamos cookies para tornar sua experi\xEAncia ainda melhor!",
|
|
2445
|
+
acceptAll: "Aceitar tudo",
|
|
2446
|
+
declineAll: "S\xF3 o essencial",
|
|
2447
|
+
modalTitle: "Seus Cookies"
|
|
2448
|
+
},
|
|
2449
|
+
concise: {
|
|
2450
|
+
bannerMessage: "Usamos cookies. Voc\xEA aceita?",
|
|
2451
|
+
acceptAll: "Sim",
|
|
2452
|
+
declineAll: "N\xE3o",
|
|
2453
|
+
modalTitle: "Cookies"
|
|
2454
|
+
},
|
|
2455
|
+
detailed: {
|
|
2456
|
+
bannerMessage: "Utilizamos cookies e tecnologias similares para melhorar sua experi\xEAncia de navega\xE7\xE3o, personalizar conte\xFAdo, analisar tr\xE1fego e oferecer funcionalidades de redes sociais.",
|
|
2457
|
+
acceptAll: "Aceitar todos os cookies e tecnologias",
|
|
2458
|
+
declineAll: "Recusar todos os cookies opcionais",
|
|
2459
|
+
modalTitle: "Centro de Prefer\xEAncias de Privacidade"
|
|
2460
|
+
}
|
|
2461
|
+
},
|
|
2462
|
+
// Internacionalização simplificada (apenas textos básicos)
|
|
2463
|
+
i18n: {
|
|
2464
|
+
en: {
|
|
2465
|
+
bannerMessage: "We use cookies to enhance your experience.",
|
|
2466
|
+
acceptAll: "Accept All",
|
|
2467
|
+
declineAll: "Decline",
|
|
2468
|
+
preferences: "Preferences",
|
|
2469
|
+
modalTitle: "Cookie Preferences",
|
|
2470
|
+
modalIntro: "Customize your cookie preferences below.",
|
|
2471
|
+
save: "Save Preferences",
|
|
2472
|
+
necessaryAlwaysOn: "Necessary cookies (always active)"
|
|
2473
|
+
},
|
|
2474
|
+
es: {
|
|
2475
|
+
bannerMessage: "Utilizamos cookies para mejorar su experiencia.",
|
|
2476
|
+
acceptAll: "Aceptar Todo",
|
|
2477
|
+
declineAll: "Rechazar",
|
|
2478
|
+
preferences: "Preferencias",
|
|
2479
|
+
modalTitle: "Preferencias de Cookies",
|
|
2480
|
+
modalIntro: "Personalice sus preferencias de cookies a continuaci\xF3n.",
|
|
2481
|
+
save: "Guardar Preferencias",
|
|
2482
|
+
necessaryAlwaysOn: "Cookies necess\xE1rias (sempre ativas)"
|
|
2483
|
+
},
|
|
2484
|
+
fr: {
|
|
2485
|
+
bannerMessage: "Nous utilisons des cookies pour am\xE9liorer votre exp\xE9rience.",
|
|
2486
|
+
acceptAll: "Tout Accepter",
|
|
2487
|
+
declineAll: "Refuser",
|
|
2488
|
+
preferences: "Pr\xE9f\xE9rences",
|
|
2489
|
+
modalTitle: "Pr\xE9f\xE9rences des Cookies",
|
|
2490
|
+
modalIntro: "Personnalisez vos pr\xE9f\xE9rences de cookies ci-dessous.",
|
|
2491
|
+
save: "Enregistrer les Pr\xE9f\xE9rences",
|
|
2492
|
+
necessaryAlwaysOn: "Cookies n\xE9cessaires (toujours actifs)"
|
|
2493
|
+
}
|
|
2494
|
+
},
|
|
2495
|
+
// Textos técnicos
|
|
2496
|
+
technical: {
|
|
2497
|
+
sessionCookies: "Cookies de sess\xE3o s\xE3o tempor\xE1rios e expiram quando voc\xEA fecha o navegador.",
|
|
2498
|
+
persistentCookies: "Cookies persistentes permanecem no seu dispositivo at\xE9 expirarem ou serem removidos.",
|
|
2499
|
+
thirdPartyCookies: "Cookies de terceiros s\xE3o definidos por dom\xEDnios diferentes do site que voc\xEA est\xE1 visitando.",
|
|
2500
|
+
browserSettings: "Voc\xEA pode gerenciar cookies nas configura\xE7\xF5es do seu navegador.",
|
|
2501
|
+
disablingImpact: "Desabilitar cookies pode afetar a funcionalidade do site."
|
|
2502
|
+
},
|
|
2503
|
+
// Cookie details
|
|
2504
|
+
cookieDetails: {
|
|
2505
|
+
tableHeaders: {
|
|
2506
|
+
name: "Nome",
|
|
2507
|
+
purpose: "Finalidade",
|
|
2508
|
+
duration: "Dura\xE7\xE3o",
|
|
2509
|
+
provider: "Fornecedor",
|
|
2510
|
+
type: "Tipo"
|
|
2511
|
+
},
|
|
2512
|
+
noCookies: "Nenhum cookie encontrado para esta categoria.",
|
|
2513
|
+
toggleDetails: {
|
|
2514
|
+
expand: "Ver detalhes",
|
|
2515
|
+
collapse: "Ocultar detalhes"
|
|
2516
|
+
}
|
|
2517
|
+
}
|
|
2518
|
+
};
|
|
2519
|
+
function resolveTexts(texts, options = {}) {
|
|
2520
|
+
const { language = "pt", variant } = options;
|
|
2521
|
+
let resolved = { ...texts };
|
|
2522
|
+
if (variant && texts.variants?.[variant]) {
|
|
2523
|
+
resolved = { ...resolved, ...texts.variants[variant] };
|
|
2524
|
+
}
|
|
2525
|
+
if (language !== "pt" && texts.i18n?.[language]) {
|
|
2526
|
+
resolved = { ...resolved, ...texts.i18n[language] };
|
|
2527
|
+
}
|
|
2528
|
+
return resolved;
|
|
2529
|
+
}
|
|
2530
|
+
var TEXT_TEMPLATES = {
|
|
2531
|
+
ecommerce: {
|
|
2532
|
+
...EXPANDED_DEFAULT_TEXTS,
|
|
2533
|
+
bannerMessage: "Utilizamos cookies para personalizar ofertas e melhorar sua experi\xEAncia de compra.",
|
|
2534
|
+
acceptAll: "Aceitar e continuar",
|
|
2535
|
+
variants: {
|
|
2536
|
+
casual: {
|
|
2537
|
+
bannerMessage: "\u{1F6D2} Usamos cookies para encontrar as melhores ofertas para voc\xEA!",
|
|
2538
|
+
acceptAll: "Quero ofertas personalizadas!"
|
|
2539
|
+
}
|
|
2540
|
+
}
|
|
2541
|
+
},
|
|
2542
|
+
saas: {
|
|
2543
|
+
...EXPANDED_DEFAULT_TEXTS,
|
|
2544
|
+
bannerMessage: "Utilizamos cookies para otimizar o desempenho da aplica\xE7\xE3o e sua experi\xEAncia.",
|
|
2545
|
+
acceptAll: "Aceitar e otimizar",
|
|
2546
|
+
variants: {
|
|
2547
|
+
formal: {
|
|
2548
|
+
bannerMessage: "Esta aplica\xE7\xE3o utiliza cookies para an\xE1lise de performance e melhoria cont\xEDnua da experi\xEAncia do usu\xE1rio.",
|
|
2549
|
+
acceptAll: "Autorizar coleta de dados de uso"
|
|
2550
|
+
}
|
|
2551
|
+
}
|
|
2552
|
+
},
|
|
2553
|
+
government: {
|
|
2554
|
+
...EXPANDED_DEFAULT_TEXTS,
|
|
2555
|
+
bannerMessage: "Este portal utiliza cookies em conformidade com a LGPD para melhorar os servi\xE7os p\xFAblicos.",
|
|
2556
|
+
acceptAll: "Aceitar em conformidade",
|
|
2557
|
+
variants: {
|
|
2558
|
+
formal: {
|
|
2559
|
+
bannerMessage: "Este s\xEDtio eletr\xF4nico do governo utiliza cookies estritamente necess\xE1rios e opcionais, em conformidade com a Lei Geral de Prote\xE7\xE3o de Dados.",
|
|
2560
|
+
acceptAll: "Concordar com o uso de cookies"
|
|
2561
|
+
}
|
|
2562
|
+
}
|
|
2563
|
+
}
|
|
2564
|
+
};
|
|
2565
|
+
|
|
2566
|
+
exports.COMMON_INTEGRATIONS = COMMON_INTEGRATIONS;
|
|
2567
|
+
exports.ConsentGate = ConsentGate;
|
|
2568
|
+
exports.ConsentProvider = ConsentProvider;
|
|
2569
|
+
exports.ConsentScriptLoader = ConsentScriptLoader;
|
|
2570
|
+
exports.DEFAULT_PROJECT_CATEGORIES = DEFAULT_PROJECT_CATEGORIES;
|
|
2571
|
+
exports.DesignProvider = DesignProvider;
|
|
2572
|
+
exports.EXPANDED_DEFAULT_TEXTS = EXPANDED_DEFAULT_TEXTS;
|
|
2573
|
+
exports.GUIDANCE_PRESETS = GUIDANCE_PRESETS;
|
|
2574
|
+
exports.INTEGRATION_TEMPLATES = INTEGRATION_TEMPLATES;
|
|
2575
|
+
exports.LogLevel = LogLevel;
|
|
2576
|
+
exports.TEXT_TEMPLATES = TEXT_TEMPLATES;
|
|
2577
|
+
exports.analyzeDeveloperConfiguration = analyzeDeveloperConfiguration;
|
|
2578
|
+
exports.analyzeIntegrationCategories = analyzeIntegrationCategories;
|
|
2579
|
+
exports.autoConfigureCategories = autoConfigureCategories;
|
|
2580
|
+
exports.categorizeDiscoveredCookies = categorizeDiscoveredCookies;
|
|
2581
|
+
exports.createClarityIntegration = createClarityIntegration;
|
|
2582
|
+
exports.createCorporateIntegrations = createCorporateIntegrations;
|
|
2583
|
+
exports.createECommerceIntegrations = createECommerceIntegrations;
|
|
2584
|
+
exports.createFacebookPixelIntegration = createFacebookPixelIntegration;
|
|
2585
|
+
exports.createGoogleAnalyticsIntegration = createGoogleAnalyticsIntegration;
|
|
2586
|
+
exports.createGoogleTagManagerIntegration = createGoogleTagManagerIntegration;
|
|
2587
|
+
exports.createHotjarIntegration = createHotjarIntegration;
|
|
2588
|
+
exports.createIntercomIntegration = createIntercomIntegration;
|
|
2589
|
+
exports.createMixpanelIntegration = createMixpanelIntegration;
|
|
2590
|
+
exports.createProjectPreferences = createProjectPreferences;
|
|
2591
|
+
exports.createSaaSIntegrations = createSaaSIntegrations;
|
|
2592
|
+
exports.createUserWayIntegration = createUserWayIntegration;
|
|
2593
|
+
exports.createZendeskChatIntegration = createZendeskChatIntegration;
|
|
2594
|
+
exports.defaultTexts = defaultTexts;
|
|
2595
|
+
exports.detectConsentCookieName = detectConsentCookieName;
|
|
2596
|
+
exports.discoverRuntimeCookies = discoverRuntimeCookies;
|
|
2597
|
+
exports.extractCategoriesFromIntegrations = extractCategoriesFromIntegrations;
|
|
2598
|
+
exports.getAllProjectCategories = getAllProjectCategories;
|
|
2599
|
+
exports.getCookiesInfoForCategory = getCookiesInfoForCategory;
|
|
2600
|
+
exports.loadScript = loadScript;
|
|
2601
|
+
exports.logDeveloperGuidance = logDeveloperGuidance;
|
|
2602
|
+
exports.logger = logger;
|
|
2603
|
+
exports.openPreferencesModal = openPreferencesModal;
|
|
2604
|
+
exports.pushConsentInitializedEvent = pushConsentInitializedEvent;
|
|
2605
|
+
exports.pushConsentUpdatedEvent = pushConsentUpdatedEvent;
|
|
2606
|
+
exports.resolveTexts = resolveTexts;
|
|
2607
|
+
exports.setCookieCatalogOverrides = setCookieCatalogOverrides;
|
|
2608
|
+
exports.setCookieCategoryOverrides = setCookieCategoryOverrides;
|
|
2609
|
+
exports.setDebugLogging = setDebugLogging;
|
|
2610
|
+
exports.suggestCategoryForScript = suggestCategoryForScript;
|
|
2611
|
+
exports.useCategories = useCategories;
|
|
2612
|
+
exports.useCategoryStatus = useCategoryStatus;
|
|
2613
|
+
exports.useConsent = useConsent;
|
|
2614
|
+
exports.useConsentHydration = useConsentHydration;
|
|
2615
|
+
exports.useConsentScriptLoader = useConsentScriptLoader;
|
|
2616
|
+
exports.useConsentTexts = useConsentTexts;
|
|
2617
|
+
exports.useDataLayerEvents = useDataLayerEvents;
|
|
2618
|
+
exports.useDesignTokens = useDesignTokens;
|
|
2619
|
+
exports.useDeveloperGuidance = useDeveloperGuidance;
|
|
2620
|
+
exports.useOpenPreferencesModal = useOpenPreferencesModal;
|
|
2621
|
+
exports.validateIntegrationCategories = validateIntegrationCategories;
|
|
2622
|
+
exports.validateNecessaryClassification = validateNecessaryClassification;
|
|
2623
|
+
exports.validateProjectPreferences = validateProjectPreferences;
|