UNPKG

@jussimirvfx/meta-pixel-tracking

Version:

Sistema completo de tracking do Meta Pixel (Pixel + CAPI) com proteção anti-adblock para landing pages

1,477 lines (1,476 loc) 67.8 kB
var __defProp = Object.defineProperty; var __defProps = Object.defineProperties; var __getOwnPropDescs = Object.getOwnPropertyDescriptors; var __getOwnPropSymbols = Object.getOwnPropertySymbols; var __hasOwnProp = Object.prototype.hasOwnProperty; var __propIsEnum = Object.prototype.propertyIsEnumerable; var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __spreadValues = (a, b) => { for (var prop in b || (b = {})) if (__hasOwnProp.call(b, prop)) __defNormalProp(a, prop, b[prop]); if (__getOwnPropSymbols) for (var prop of __getOwnPropSymbols(b)) { if (__propIsEnum.call(b, prop)) __defNormalProp(a, prop, b[prop]); } return a; }; var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b)); var __objRest = (source, exclude) => { var target = {}; for (var prop in source) if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0) target[prop] = source[prop]; if (source != null && __getOwnPropSymbols) for (var prop of __getOwnPropSymbols(source)) { if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop)) target[prop] = source[prop]; } return target; }; var __publicField = (obj, key, value) => { __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value); return value; }; var __async = (__this, __arguments, generator) => { return new Promise((resolve, reject) => { var fulfilled = (value) => { try { step(generator.next(value)); } catch (e) { reject(e); } }; var rejected = (value) => { try { step(generator.throw(value)); } catch (e) { reject(e); } }; var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected); step((generator = generator.apply(__this, __arguments)).next()); }); }; import { jsx, Fragment } from "react/jsx-runtime"; import { useState, useCallback, useEffect, useRef } from "react"; let isConfigured = false; function detectVercelAndEnableDebug() { if (typeof window === "undefined") return false; const url = window.location.href; const isVercel = url.includes("vercel.app") || url.includes("vercel.com"); if (isVercel) { console.log("[META PIXEL] 🚀 Detectado ambiente Vercel, ativando debug automático"); return true; } return false; } let META_PIXEL_CONFIG = { PIXEL_ID: "", ACCESS_TOKEN: "", TEST_EVENT_CODE: "", DEDUPLICATION: { MAX_AGE_HOURS: 24 }, UNIVERSAL_PARAMETERS: [ "event_time", "event_source_url", "page_title", "page_path", "browser_language", "screen_width", "screen_height", "viewport_width", "viewport_height", "timezone", "referrer" ], STANDARD_EVENTS: [ "PageView", "Lead", "LeadQualificado" ], VERBOSE: false }; function isMetaPixelConfigured() { return isConfigured && !!META_PIXEL_CONFIG.PIXEL_ID && !!META_PIXEL_CONFIG.ACCESS_TOKEN; } function validateConfiguration() { if (!META_PIXEL_CONFIG.PIXEL_ID) { throw new Error("PIXEL_ID é obrigatório. Configure usando configureMetaPixel()"); } if (!META_PIXEL_CONFIG.ACCESS_TOKEN) { throw new Error("ACCESS_TOKEN é obrigatório. Configure usando configureMetaPixel()"); } } function configureMetaPixel(config) { META_PIXEL_CONFIG = __spreadValues(__spreadValues({}, META_PIXEL_CONFIG), config); isConfigured = true; const isVercel = detectVercelAndEnableDebug(); if (isVercel || typeof window !== "undefined" && false) { META_PIXEL_CONFIG.VERBOSE = true; console.log("[META PIXEL] 🔍 Debug ativado automaticamente"); } if (!config.PIXEL_ID) { console.error("⚠️ PIXEL_ID não fornecido na configuração"); } if (!config.ACCESS_TOKEN) { console.error("⚠️ ACCESS_TOKEN não fornecido na configuração"); } if (META_PIXEL_CONFIG.VERBOSE) { console.log("[META PIXEL CONFIGURADO]", { PIXEL_ID: META_PIXEL_CONFIG.PIXEL_ID ? "Configurado" : "Não configurado", ACCESS_TOKEN: META_PIXEL_CONFIG.ACCESS_TOKEN ? "Configurado" : "Não configurado", TEST_EVENT_CODE: META_PIXEL_CONFIG.TEST_EVENT_CODE || "Não configurado", VERBOSE: META_PIXEL_CONFIG.VERBOSE, ENVIRONMENT: isVercel ? "Vercel" : "production" }); } if (typeof window !== "undefined") { window._metaPixelDebug = { getConfig: () => META_PIXEL_CONFIG, isConfigured: () => isMetaPixelConfigured(), validate: validateConfiguration }; } } if (typeof window !== "undefined" && false) { Promise.resolve().then(() => { if (!isMetaPixelConfigured()) { console.warn("[META PIXEL NÃO CONFIGURADO] Package não configurado. Use configureMetaPixel() antes de usar o hook."); } }); window._metaPixelDebug = { getConfig: () => META_PIXEL_CONFIG, isConfigured: () => isMetaPixelConfigured(), validate: validateConfiguration }; } var LogCategory = /* @__PURE__ */ ((LogCategory2) => { LogCategory2["INIT"] = "INIT"; LogCategory2["META_PIXEL"] = "META_PIXEL"; LogCategory2["CONVERSION_API"] = "CONVERSION_API"; LogCategory2["PAGE_VIEW"] = "PAGE_VIEW"; LogCategory2["SCROLL"] = "SCROLL"; LogCategory2["LEAD"] = "LEAD"; LogCategory2["QUALIFIED_LEAD"] = "QUALIFIED_LEAD"; LogCategory2["VIDEO"] = "VIDEO"; LogCategory2["ERROR"] = "ERROR"; LogCategory2["DEBUG"] = "DEBUG"; return LogCategory2; })(LogCategory || {}); var LogLevel = /* @__PURE__ */ ((LogLevel2) => { LogLevel2[LogLevel2["DEBUG"] = 0] = "DEBUG"; LogLevel2[LogLevel2["INFO"] = 1] = "INFO"; LogLevel2[LogLevel2["WARN"] = 2] = "WARN"; LogLevel2[LogLevel2["ERROR"] = 3] = "ERROR"; return LogLevel2; })(LogLevel || {}); class Logger { constructor() { __publicField(this, "logs", []); __publicField(this, "maxLogs", 1e3); } // Função para detectar se deve mostrar logs shouldShowLogs() { var _a, _b, _c, _d, _e; if (typeof window === "undefined") return false; try { if ((_c = (_b = (_a = window._metaPixelDebug) == null ? void 0 : _a.getConfig) == null ? void 0 : _b.call(_a)) == null ? void 0 : _c.VERBOSE) { return true; } } catch (error) { } const isDev = ( // Vite development typeof import.meta !== "undefined" && ((_d = { "BASE_URL": "/", "MODE": "production", "DEV": false, "PROD": true, "SSR": false }) == null ? void 0 : _d.MODE) === "development" || // Vite preview typeof import.meta !== "undefined" && ((_e = { "BASE_URL": "/", "MODE": "production", "DEV": false, "PROD": true, "SSR": false }) == null ? void 0 : _e.MODE) === "preview" || // Node.js development process.env.NODE_ENV === "development" || // Verificar se há debug ativo window.location.hostname === "localhost" || window.location.hostname === "127.0.0.1" || // Verificar se há parâmetro de debug na URL window.location.search.includes("debug=true") || // Verificar se há localStorage com debug ativo localStorage.getItem("meta-pixel-debug") === "true" || // Verificar se há console aberto (método simples) window.outerHeight - window.innerHeight > 200 ); return isDev; } addLog(level, category, message, data) { const entry = { timestamp: Date.now(), level, category, message, data }; this.logs.push(entry); if (this.logs.length > this.maxLogs) { this.logs = this.logs.slice(-this.maxLogs); } if (this.shouldShowLogs()) { const prefix = `[META PIXEL - ${category}]`; const timestamp = (/* @__PURE__ */ new Date()).toLocaleTimeString(); switch (level) { case 0: console.debug(`${prefix} ${timestamp} - ${message}`, data || ""); break; case 1: console.info(`${prefix} ${timestamp} - ${message}`, data || ""); break; case 2: console.warn(`${prefix} ${timestamp} - ${message}`, data || ""); break; case 3: console.error(`${prefix} ${timestamp} - ${message}`, data || ""); break; } } if (typeof window !== "undefined") { if (!window._metaPixelLogs) { window._metaPixelLogs = { getLogs: () => this.logs, getLogsByCategory: (category2) => this.logs.filter((log) => log.category === category2), clear: () => { this.logs = []; }, enable: () => { localStorage.setItem("meta-pixel-debug", "true"); }, disable: () => { localStorage.removeItem("meta-pixel-debug"); }, isEnabled: () => this.shouldShowLogs() }; } } } debug(category, message, data) { this.addLog(0, category, message, data); } info(category, message, data) { this.addLog(1, category, message, data); } warn(category, message, data) { this.addLog(2, category, message, data); } error(category, message, data) { this.addLog(3, category, message, data); } // Métodos específicos para eventos principais pageView(eventId, params) { var _a, _b, _c, _d, _e, _f; this.info("PAGE_VIEW", "PageView enviado", { eventId, pageTitle: params.page_title, pagePath: params.page_path, hasUserData: !!params.user_data, userData: { hasEmail: !!((_a = params.user_data) == null ? void 0 : _a.em), hasPhone: !!((_b = params.user_data) == null ? void 0 : _b.ph), hasName: !!(((_c = params.user_data) == null ? void 0 : _c.fn) || ((_d = params.user_data) == null ? void 0 : _d.ln)), hasFbc: !!((_e = params.user_data) == null ? void 0 : _e.fbc), hasFbp: !!((_f = params.user_data) == null ? void 0 : _f.fbp) } }); } scroll(depth, eventId, params) { this.info("SCROLL", `Scroll atingiu ${depth}%`, { eventId, depth, scrollPercentage: params.scroll_percentage, scrollY: params.scroll_y, pageTitle: params.page_title, pagePath: params.page_path }); } lead(eventId, params, userData) { this.info("LEAD", "Lead enviado", { eventId, value: params.value, currency: params.currency, contentName: params.content_name, hasUserData: true, userData: { hasEmail: !!(userData == null ? void 0 : userData.em), hasPhone: !!(userData == null ? void 0 : userData.ph), hasName: !!((userData == null ? void 0 : userData.fn) || (userData == null ? void 0 : userData.ln)), hasFbc: !!(userData == null ? void 0 : userData.fbc), hasFbp: !!(userData == null ? void 0 : userData.fbp) }, processedUserData: { hasEmailHash: !!(userData == null ? void 0 : userData.em), hasPhoneHash: !!(userData == null ? void 0 : userData.ph), hasNameHash: !!((userData == null ? void 0 : userData.fn) || (userData == null ? void 0 : userData.ln)) } }); } leadQualificado(eventId, params, userData) { this.info("QUALIFIED_LEAD", "LeadQualificado enviado", { eventId, value: params.value, currency: params.currency, contentName: params.content_name, leadScore: params.lead_score, qualificationStatus: params.qualification_status, hasUserData: true, userData: { hasEmail: !!(userData == null ? void 0 : userData.em), hasPhone: !!(userData == null ? void 0 : userData.ph), hasName: !!((userData == null ? void 0 : userData.fn) || (userData == null ? void 0 : userData.ln)), hasFbc: !!(userData == null ? void 0 : userData.fbc), hasFbp: !!(userData == null ? void 0 : userData.fbp) } }); } pixelEvent(eventName, eventId, method, success) { this.info("META_PIXEL", `Evento enviado via Pixel: ${eventName}`, { eventId, method, success }); } conversionApiEvent(eventName, eventId, success, responseTime) { this.info("CONVERSION_API", `Evento enviado via API: ${eventName}`, { eventId, success, responseTime: responseTime ? `${Math.round(responseTime)}ms` : void 0 }); } getLogs() { return [...this.logs]; } getLogsByCategory(category) { return this.logs.filter((log) => log.category === category); } clear() { this.logs = []; } } const logger = new Logger(); let isInitialized = false; const STANDARD_EVENTS = [ "PageView", "Lead", "LeadQualificado" ]; function createFacebookPixelProxy() { if (typeof window === "undefined") return; const fbPixelCode = ` !function(f,b,e,v,n,t,s) {if(f.fbq)return;n=f.fbq=function(){n.callMethod? n.callMethod.apply(n,arguments):n.queue.push(arguments)}; if(!f._fbq)f._fbq=n;n.push=n;n.loaded=!0;n.version='2.0'; n.queue=[];}(window,document,'script',''); // Carregar o script real do Facebook de forma assíncrona (function() { var script = document.createElement('script'); script.async = true; script.src = 'https://connect.facebook.net/en_US/fbevents.js'; script.onerror = function() { // Fallback: tentar outros CDNs var fallbackScript = document.createElement('script'); fallbackScript.async = true; fallbackScript.src = 'https://cdn.fbsbx.com/en_US/fbevents.js'; document.head.appendChild(fallbackScript); }; document.head.appendChild(script); })(); `; const blob = new Blob([fbPixelCode], { type: "application/javascript" }); const scriptUrl = URL.createObjectURL(blob); const script = document.createElement("script"); script.async = true; script.src = scriptUrl; script.onload = () => { logger.info(LogCategory.INIT, "Script do Facebook carregado via proxy anti-adblock"); window._fbPixelScriptLoaded = true; URL.revokeObjectURL(scriptUrl); }; script.onerror = () => { logger.warn(LogCategory.INIT, "Proxy falhou, tentando método direto"); loadFacebookPixelScriptDirect(); }; document.head.appendChild(script); } function loadFacebookPixelScriptDirect() { if (typeof window === "undefined") return; const script = document.createElement("script"); script.async = true; script.src = "https://connect.facebook.net/en_US/fbevents.js"; script.onload = () => { logger.info(LogCategory.INIT, "Script do Facebook carregado diretamente"); window._fbPixelScriptLoaded = true; }; script.onerror = (error) => { logger.error(LogCategory.INIT, "Erro ao carregar script do Facebook", { error }); loadFacebookPixelAlternativeCDN(); }; document.head.appendChild(script); } function loadFacebookPixelAlternativeCDN() { if (typeof window === "undefined") return; const script = document.createElement("script"); script.async = true; script.src = "https://cdn.fbsbx.com/en_US/fbevents.js"; script.onload = () => { logger.info(LogCategory.INIT, "Script do Facebook carregado via CDN alternativo"); window._fbPixelScriptLoaded = true; }; script.onerror = (error) => { logger.error(LogCategory.INIT, "Todos os métodos de carregamento falharam", { error }); }; document.head.appendChild(script); } function initFacebookPixelOffline() { if (typeof window === "undefined") return; if (!window.fbq) { window.fbq = function(...args) { if (!window._fbq_calls) window._fbq_calls = []; window._fbq_calls.push(args); if (args.length >= 2) { const [command, eventName] = args; logger.info(LogCategory.META_PIXEL, `Evento ${eventName} armazenado (script bloqueado)`, { command, args: args.slice(2) }); } }; if (!window._fbq) window._fbq = window.fbq; window.fbq.push = window.fbq; window.fbq.loaded = true; window.fbq.version = "2.0-offline"; window.fbq.queue = []; logger.warn(LogCategory.INIT, "Facebook Pixel inicializado em modo offline (script bloqueado)"); } } function initFacebookPixel() { if (typeof window === "undefined") return; if (isInitialized || window._fbPixelInitialized) { logger.debug(LogCategory.INIT, "Facebook Pixel já inicializado, pulando..."); isInitialized = true; return; } isInitialized = true; window._fbPixelInitialized = true; logger.info(LogCategory.INIT, "Iniciando Facebook Pixel com proteção anti-adblock..."); if (!window._fbPixelScriptLoaded) { createFacebookPixelProxy(); setTimeout(() => { if (!window.fbq || typeof window.fbq !== "function") { logger.warn(LogCategory.INIT, "Script detectado como bloqueado, inicializando modo offline"); initFacebookPixelOffline(); } }, 3e3); } if (!window.fbq) { window.fbq = function(...args) { if (args.length === 0) { logger.warn(LogCategory.META_PIXEL, "Tentativa de chamar fbq() sem argumentos"); return; } if (window.fbq.callMethod) { window.fbq.callMethod.apply(window.fbq, args); } else { window.fbq.queue.push(args); } }; if (!window._fbq) window._fbq = window.fbq; window.fbq.push = window.fbq; window.fbq.loaded = true; window.fbq.version = "2.0"; window.fbq.queue = []; } const pixelId = META_PIXEL_CONFIG.PIXEL_ID; window.fbq("init", pixelId); logger.info(LogCategory.INIT, `Facebook Pixel inicializado ${pixelId} com proteção anti-adblock`); if (!window.trackFBEvent) { window.trackFBEvent = (event, params) => { if (window.fbq) { const _a = params || {}, { event_id } = _a, otherParams = __objRest(_a, ["event_id"]); const options = event_id ? { eventID: event_id } : {}; if (STANDARD_EVENTS.includes(event)) { window.fbq("track", event, otherParams, options); } else { window.fbq("trackCustom", event, otherParams, options); } return true; } return false; }; logger.info(LogCategory.INIT, "Função global de rastreamento registrada"); } } function loadFacebookPixelScript() { if (typeof window === "undefined") return; if (window._fbPixelScriptLoaded) { logger.debug(LogCategory.INIT, "Script do Facebook já carregado"); return; } logger.info(LogCategory.INIT, "Carregando script do Facebook com proteção anti-adblock"); createFacebookPixelProxy(); } function isPixelBlocked() { if (typeof window === "undefined") return false; if (!window.fbq) return true; return window.fbq.version === "2.0-offline"; } function getPixelBlockingStats() { return { isBlocked: isPixelBlocked(), method: window._fbPixelScriptLoaded ? "script_loaded" : "script_blocked", fallbackActive: !window._fbPixelScriptLoaded && !!window.fbq }; } var commonjsGlobal = typeof globalThis !== "undefined" ? globalThis : typeof window !== "undefined" ? window : typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : {}; function getDefaultExportFromCjs(x) { return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, "default") ? x["default"] : x; } function getAugmentedNamespace(n) { if (n.__esModule) return n; var f = n.default; if (typeof f == "function") { var a = function a2() { if (this instanceof a2) { return Reflect.construct(f, arguments, this.constructor); } return f.apply(this, arguments); }; a.prototype = f.prototype; } else a = {}; Object.defineProperty(a, "__esModule", { value: true }); Object.keys(n).forEach(function(k) { var d = Object.getOwnPropertyDescriptor(n, k); Object.defineProperty(a, k, d.get ? d : { enumerable: true, get: function() { return n[k]; } }); }); return a; } var sha256 = { exports: {} }; function commonjsRequire(path) { throw new Error('Could not dynamically require "' + path + '". Please configure the dynamicRequireTargets or/and ignoreDynamicRequires option of @rollup/plugin-commonjs appropriately for this require call to work.'); } var core = { exports: {} }; const __viteBrowserExternal = {}; const __viteBrowserExternal$1 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: __viteBrowserExternal }, Symbol.toStringTag, { value: "Module" })); const require$$0 = /* @__PURE__ */ getAugmentedNamespace(__viteBrowserExternal$1); var hasRequiredCore; function requireCore() { if (hasRequiredCore) return core.exports; hasRequiredCore = 1; (function(module, exports) { (function(root, factory) { { module.exports = factory(); } })(commonjsGlobal, function() { var CryptoJS = CryptoJS || function(Math2, undefined$1) { var crypto; if (typeof window !== "undefined" && window.crypto) { crypto = window.crypto; } if (typeof self !== "undefined" && self.crypto) { crypto = self.crypto; } if (typeof globalThis !== "undefined" && globalThis.crypto) { crypto = globalThis.crypto; } if (!crypto && typeof window !== "undefined" && window.msCrypto) { crypto = window.msCrypto; } if (!crypto && typeof commonjsGlobal !== "undefined" && commonjsGlobal.crypto) { crypto = commonjsGlobal.crypto; } if (!crypto && typeof commonjsRequire === "function") { try { crypto = require$$0; } catch (err) { } } var cryptoSecureRandomInt = function() { if (crypto) { if (typeof crypto.getRandomValues === "function") { try { return crypto.getRandomValues(new Uint32Array(1))[0]; } catch (err) { } } if (typeof crypto.randomBytes === "function") { try { return crypto.randomBytes(4).readInt32LE(); } catch (err) { } } } throw new Error("Native crypto module could not be used to get secure random number."); }; var create = Object.create || function() { function F() { } return function(obj) { var subtype; F.prototype = obj; subtype = new F(); F.prototype = null; return subtype; }; }(); var C = {}; var C_lib = C.lib = {}; var Base = C_lib.Base = function() { return { /** * Creates a new object that inherits from this object. * * @param {Object} overrides Properties to copy into the new object. * * @return {Object} The new object. * * @static * * @example * * var MyType = CryptoJS.lib.Base.extend({ * field: 'value', * * method: function () { * } * }); */ extend: function(overrides) { var subtype = create(this); if (overrides) { subtype.mixIn(overrides); } if (!subtype.hasOwnProperty("init") || this.init === subtype.init) { subtype.init = function() { subtype.$super.init.apply(this, arguments); }; } subtype.init.prototype = subtype; subtype.$super = this; return subtype; }, /** * Extends this object and runs the init method. * Arguments to create() will be passed to init(). * * @return {Object} The new object. * * @static * * @example * * var instance = MyType.create(); */ create: function() { var instance = this.extend(); instance.init.apply(instance, arguments); return instance; }, /** * Initializes a newly created object. * Override this method to add some logic when your objects are created. * * @example * * var MyType = CryptoJS.lib.Base.extend({ * init: function () { * // ... * } * }); */ init: function() { }, /** * Copies properties into this object. * * @param {Object} properties The properties to mix in. * * @example * * MyType.mixIn({ * field: 'value' * }); */ mixIn: function(properties) { for (var propertyName in properties) { if (properties.hasOwnProperty(propertyName)) { this[propertyName] = properties[propertyName]; } } if (properties.hasOwnProperty("toString")) { this.toString = properties.toString; } }, /** * Creates a copy of this object. * * @return {Object} The clone. * * @example * * var clone = instance.clone(); */ clone: function() { return this.init.prototype.extend(this); } }; }(); var WordArray = C_lib.WordArray = Base.extend({ /** * Initializes a newly created word array. * * @param {Array} words (Optional) An array of 32-bit words. * @param {number} sigBytes (Optional) The number of significant bytes in the words. * * @example * * var wordArray = CryptoJS.lib.WordArray.create(); * var wordArray = CryptoJS.lib.WordArray.create([0x00010203, 0x04050607]); * var wordArray = CryptoJS.lib.WordArray.create([0x00010203, 0x04050607], 6); */ init: function(words, sigBytes) { words = this.words = words || []; if (sigBytes != undefined$1) { this.sigBytes = sigBytes; } else { this.sigBytes = words.length * 4; } }, /** * Converts this word array to a string. * * @param {Encoder} encoder (Optional) The encoding strategy to use. Default: CryptoJS.enc.Hex * * @return {string} The stringified word array. * * @example * * var string = wordArray + ''; * var string = wordArray.toString(); * var string = wordArray.toString(CryptoJS.enc.Utf8); */ toString: function(encoder) { return (encoder || Hex).stringify(this); }, /** * Concatenates a word array to this word array. * * @param {WordArray} wordArray The word array to append. * * @return {WordArray} This word array. * * @example * * wordArray1.concat(wordArray2); */ concat: function(wordArray) { var thisWords = this.words; var thatWords = wordArray.words; var thisSigBytes = this.sigBytes; var thatSigBytes = wordArray.sigBytes; this.clamp(); if (thisSigBytes % 4) { for (var i = 0; i < thatSigBytes; i++) { var thatByte = thatWords[i >>> 2] >>> 24 - i % 4 * 8 & 255; thisWords[thisSigBytes + i >>> 2] |= thatByte << 24 - (thisSigBytes + i) % 4 * 8; } } else { for (var j = 0; j < thatSigBytes; j += 4) { thisWords[thisSigBytes + j >>> 2] = thatWords[j >>> 2]; } } this.sigBytes += thatSigBytes; return this; }, /** * Removes insignificant bits. * * @example * * wordArray.clamp(); */ clamp: function() { var words = this.words; var sigBytes = this.sigBytes; words[sigBytes >>> 2] &= 4294967295 << 32 - sigBytes % 4 * 8; words.length = Math2.ceil(sigBytes / 4); }, /** * Creates a copy of this word array. * * @return {WordArray} The clone. * * @example * * var clone = wordArray.clone(); */ clone: function() { var clone = Base.clone.call(this); clone.words = this.words.slice(0); return clone; }, /** * Creates a word array filled with random bytes. * * @param {number} nBytes The number of random bytes to generate. * * @return {WordArray} The random word array. * * @static * * @example * * var wordArray = CryptoJS.lib.WordArray.random(16); */ random: function(nBytes) { var words = []; for (var i = 0; i < nBytes; i += 4) { words.push(cryptoSecureRandomInt()); } return new WordArray.init(words, nBytes); } }); var C_enc = C.enc = {}; var Hex = C_enc.Hex = { /** * Converts a word array to a hex string. * * @param {WordArray} wordArray The word array. * * @return {string} The hex string. * * @static * * @example * * var hexString = CryptoJS.enc.Hex.stringify(wordArray); */ stringify: function(wordArray) { var words = wordArray.words; var sigBytes = wordArray.sigBytes; var hexChars = []; for (var i = 0; i < sigBytes; i++) { var bite = words[i >>> 2] >>> 24 - i % 4 * 8 & 255; hexChars.push((bite >>> 4).toString(16)); hexChars.push((bite & 15).toString(16)); } return hexChars.join(""); }, /** * Converts a hex string to a word array. * * @param {string} hexStr The hex string. * * @return {WordArray} The word array. * * @static * * @example * * var wordArray = CryptoJS.enc.Hex.parse(hexString); */ parse: function(hexStr) { var hexStrLength = hexStr.length; var words = []; for (var i = 0; i < hexStrLength; i += 2) { words[i >>> 3] |= parseInt(hexStr.substr(i, 2), 16) << 24 - i % 8 * 4; } return new WordArray.init(words, hexStrLength / 2); } }; var Latin1 = C_enc.Latin1 = { /** * Converts a word array to a Latin1 string. * * @param {WordArray} wordArray The word array. * * @return {string} The Latin1 string. * * @static * * @example * * var latin1String = CryptoJS.enc.Latin1.stringify(wordArray); */ stringify: function(wordArray) { var words = wordArray.words; var sigBytes = wordArray.sigBytes; var latin1Chars = []; for (var i = 0; i < sigBytes; i++) { var bite = words[i >>> 2] >>> 24 - i % 4 * 8 & 255; latin1Chars.push(String.fromCharCode(bite)); } return latin1Chars.join(""); }, /** * Converts a Latin1 string to a word array. * * @param {string} latin1Str The Latin1 string. * * @return {WordArray} The word array. * * @static * * @example * * var wordArray = CryptoJS.enc.Latin1.parse(latin1String); */ parse: function(latin1Str) { var latin1StrLength = latin1Str.length; var words = []; for (var i = 0; i < latin1StrLength; i++) { words[i >>> 2] |= (latin1Str.charCodeAt(i) & 255) << 24 - i % 4 * 8; } return new WordArray.init(words, latin1StrLength); } }; var Utf8 = C_enc.Utf8 = { /** * Converts a word array to a UTF-8 string. * * @param {WordArray} wordArray The word array. * * @return {string} The UTF-8 string. * * @static * * @example * * var utf8String = CryptoJS.enc.Utf8.stringify(wordArray); */ stringify: function(wordArray) { try { return decodeURIComponent(escape(Latin1.stringify(wordArray))); } catch (e) { throw new Error("Malformed UTF-8 data"); } }, /** * Converts a UTF-8 string to a word array. * * @param {string} utf8Str The UTF-8 string. * * @return {WordArray} The word array. * * @static * * @example * * var wordArray = CryptoJS.enc.Utf8.parse(utf8String); */ parse: function(utf8Str) { return Latin1.parse(unescape(encodeURIComponent(utf8Str))); } }; var BufferedBlockAlgorithm = C_lib.BufferedBlockAlgorithm = Base.extend({ /** * Resets this block algorithm's data buffer to its initial state. * * @example * * bufferedBlockAlgorithm.reset(); */ reset: function() { this._data = new WordArray.init(); this._nDataBytes = 0; }, /** * Adds new data to this block algorithm's buffer. * * @param {WordArray|string} data The data to append. Strings are converted to a WordArray using UTF-8. * * @example * * bufferedBlockAlgorithm._append('data'); * bufferedBlockAlgorithm._append(wordArray); */ _append: function(data) { if (typeof data == "string") { data = Utf8.parse(data); } this._data.concat(data); this._nDataBytes += data.sigBytes; }, /** * Processes available data blocks. * * This method invokes _doProcessBlock(offset), which must be implemented by a concrete subtype. * * @param {boolean} doFlush Whether all blocks and partial blocks should be processed. * * @return {WordArray} The processed data. * * @example * * var processedData = bufferedBlockAlgorithm._process(); * var processedData = bufferedBlockAlgorithm._process(!!'flush'); */ _process: function(doFlush) { var processedWords; var data = this._data; var dataWords = data.words; var dataSigBytes = data.sigBytes; var blockSize = this.blockSize; var blockSizeBytes = blockSize * 4; var nBlocksReady = dataSigBytes / blockSizeBytes; if (doFlush) { nBlocksReady = Math2.ceil(nBlocksReady); } else { nBlocksReady = Math2.max((nBlocksReady | 0) - this._minBufferSize, 0); } var nWordsReady = nBlocksReady * blockSize; var nBytesReady = Math2.min(nWordsReady * 4, dataSigBytes); if (nWordsReady) { for (var offset = 0; offset < nWordsReady; offset += blockSize) { this._doProcessBlock(dataWords, offset); } processedWords = dataWords.splice(0, nWordsReady); data.sigBytes -= nBytesReady; } return new WordArray.init(processedWords, nBytesReady); }, /** * Creates a copy of this object. * * @return {Object} The clone. * * @example * * var clone = bufferedBlockAlgorithm.clone(); */ clone: function() { var clone = Base.clone.call(this); clone._data = this._data.clone(); return clone; }, _minBufferSize: 0 }); C_lib.Hasher = BufferedBlockAlgorithm.extend({ /** * Configuration options. */ cfg: Base.extend(), /** * Initializes a newly created hasher. * * @param {Object} cfg (Optional) The configuration options to use for this hash computation. * * @example * * var hasher = CryptoJS.algo.SHA256.create(); */ init: function(cfg) { this.cfg = this.cfg.extend(cfg); this.reset(); }, /** * Resets this hasher to its initial state. * * @example * * hasher.reset(); */ reset: function() { BufferedBlockAlgorithm.reset.call(this); this._doReset(); }, /** * Updates this hasher with a message. * * @param {WordArray|string} messageUpdate The message to append. * * @return {Hasher} This hasher. * * @example * * hasher.update('message'); * hasher.update(wordArray); */ update: function(messageUpdate) { this._append(messageUpdate); this._process(); return this; }, /** * Finalizes the hash computation. * Note that the finalize operation is effectively a destructive, read-once operation. * * @param {WordArray|string} messageUpdate (Optional) A final message update. * * @return {WordArray} The hash. * * @example * * var hash = hasher.finalize(); * var hash = hasher.finalize('message'); * var hash = hasher.finalize(wordArray); */ finalize: function(messageUpdate) { if (messageUpdate) { this._append(messageUpdate); } var hash = this._doFinalize(); return hash; }, blockSize: 512 / 32, /** * Creates a shortcut function to a hasher's object interface. * * @param {Hasher} hasher The hasher to create a helper for. * * @return {Function} The shortcut function. * * @static * * @example * * var SHA256 = CryptoJS.lib.Hasher._createHelper(CryptoJS.algo.SHA256); */ _createHelper: function(hasher) { return function(message, cfg) { return new hasher.init(cfg).finalize(message); }; }, /** * Creates a shortcut function to the HMAC's object interface. * * @param {Hasher} hasher The hasher to use in this HMAC helper. * * @return {Function} The shortcut function. * * @static * * @example * * var HmacSHA256 = CryptoJS.lib.Hasher._createHmacHelper(CryptoJS.algo.SHA256); */ _createHmacHelper: function(hasher) { return function(message, key) { return new C_algo.HMAC.init(hasher, key).finalize(message); }; } }); var C_algo = C.algo = {}; return C; }(Math); return CryptoJS; }); })(core); return core.exports; } (function(module, exports) { (function(root, factory) { { module.exports = factory(requireCore()); } })(commonjsGlobal, function(CryptoJS) { (function(Math2) { var C = CryptoJS; var C_lib = C.lib; var WordArray = C_lib.WordArray; var Hasher = C_lib.Hasher; var C_algo = C.algo; var H = []; var K = []; (function() { function isPrime(n2) { var sqrtN = Math2.sqrt(n2); for (var factor = 2; factor <= sqrtN; factor++) { if (!(n2 % factor)) { return false; } } return true; } function getFractionalBits(n2) { return (n2 - (n2 | 0)) * 4294967296 | 0; } var n = 2; var nPrime = 0; while (nPrime < 64) { if (isPrime(n)) { if (nPrime < 8) { H[nPrime] = getFractionalBits(Math2.pow(n, 1 / 2)); } K[nPrime] = getFractionalBits(Math2.pow(n, 1 / 3)); nPrime++; } n++; } })(); var W = []; var SHA2562 = C_algo.SHA256 = Hasher.extend({ _doReset: function() { this._hash = new WordArray.init(H.slice(0)); }, _doProcessBlock: function(M, offset) { var H2 = this._hash.words; var a = H2[0]; var b = H2[1]; var c = H2[2]; var d = H2[3]; var e = H2[4]; var f = H2[5]; var g = H2[6]; var h = H2[7]; for (var i = 0; i < 64; i++) { if (i < 16) { W[i] = M[offset + i] | 0; } else { var gamma0x = W[i - 15]; var gamma0 = (gamma0x << 25 | gamma0x >>> 7) ^ (gamma0x << 14 | gamma0x >>> 18) ^ gamma0x >>> 3; var gamma1x = W[i - 2]; var gamma1 = (gamma1x << 15 | gamma1x >>> 17) ^ (gamma1x << 13 | gamma1x >>> 19) ^ gamma1x >>> 10; W[i] = gamma0 + W[i - 7] + gamma1 + W[i - 16]; } var ch = e & f ^ ~e & g; var maj = a & b ^ a & c ^ b & c; var sigma0 = (a << 30 | a >>> 2) ^ (a << 19 | a >>> 13) ^ (a << 10 | a >>> 22); var sigma1 = (e << 26 | e >>> 6) ^ (e << 21 | e >>> 11) ^ (e << 7 | e >>> 25); var t1 = h + sigma1 + ch + K[i] + W[i]; var t2 = sigma0 + maj; h = g; g = f; f = e; e = d + t1 | 0; d = c; c = b; b = a; a = t1 + t2 | 0; } H2[0] = H2[0] + a | 0; H2[1] = H2[1] + b | 0; H2[2] = H2[2] + c | 0; H2[3] = H2[3] + d | 0; H2[4] = H2[4] + e | 0; H2[5] = H2[5] + f | 0; H2[6] = H2[6] + g | 0; H2[7] = H2[7] + h | 0; }, _doFinalize: function() { var data = this._data; var dataWords = data.words; var nBitsTotal = this._nDataBytes * 8; var nBitsLeft = data.sigBytes * 8; dataWords[nBitsLeft >>> 5] |= 128 << 24 - nBitsLeft % 32; dataWords[(nBitsLeft + 64 >>> 9 << 4) + 14] = Math2.floor(nBitsTotal / 4294967296); dataWords[(nBitsLeft + 64 >>> 9 << 4) + 15] = nBitsTotal; data.sigBytes = dataWords.length * 4; this._process(); return this._hash; }, clone: function() { var clone = Hasher.clone.call(this); clone._hash = this._hash.clone(); return clone; } }); C.SHA256 = Hasher._createHelper(SHA2562); C.HmacSHA256 = Hasher._createHmacHelper(SHA2562); })(Math); return CryptoJS.SHA256; }); })(sha256); var sha256Exports = sha256.exports; const SHA256 = /* @__PURE__ */ getDefaultExportFromCjs(sha256Exports); function hashValue(value) { if (!value) return ""; return SHA256(value).toString(); } function hashEmail(email) { if (!email) return ""; const normalized = email.trim().toLowerCase(); return hashValue(normalized); } function hashPhone(phone, countryCode = "55") { if (!phone) return ""; let normalized = phone.replace(/\D/g, ""); if (!normalized.startsWith(countryCode) && normalized.length <= 11) { normalized = countryCode + normalized; } return hashValue(normalized); } function hashName(name) { if (!name) return ""; const normalized = name.trim().toLowerCase().normalize("NFD").replace(/[\u0300-\u036f]/g, ""); return hashValue(normalized); } function hashFirstLastName(fullName) { if (!fullName) return {}; const parts = fullName.trim().split(/\s+/); const result = {}; if (parts.length > 0) { result.fn = hashName(parts[0]); } if (parts.length > 1) { result.ln = hashName(parts[parts.length - 1]); } return result; } function getCookie(name) { var _a; if (typeof document === "undefined") return null; const value = `; ${document.cookie}`; const parts = value.split(`; ${name}=`); if (parts.length === 2) { return ((_a = parts.pop()) == null ? void 0 : _a.split(";").shift()) || null; } return null; } function getFbp() { return getCookie("_fbp"); } function getFbc() { return getCookie("_fbc"); } function generateEventId(prefix = "evt") { const timestamp = Date.now(); const random = Math.random().toString(36).substring(2, 15); return `${prefix}_${timestamp}_${random}`; } const STORAGE_KEY = "_meta_events_sent"; function prepareUserData(userData) { const prepared = { client_user_agent: navigator.userAgent, client_ip_address: "SERÁ_PREENCHIDO_PELO_BACKEND", // Placeholder para IP // ✅ SEMPRE incluir cookies do Facebook para melhor advanced matching fbp: getFbp(), fbc: getFbc() }; if (!userData) return prepared; if (userData.email) { prepared.em = [hashEmail(userData.email)]; } if (userData.phone || userData.telefone) { prepared.ph = [hashPhone(userData.phone || userData.telefone)]; } if (userData.name || userData.nome) { const fullName = userData.name || userData.nome; const { fn, ln } = hashFirstLastName(fullName); if (fn) prepared.fn = [fn]; if (ln) prepared.ln = [ln]; } if (userData.city || userData.cidade) { const normalizedCity = (userData.city || userData.cidade).trim().toLowerCase(); prepared.ct = [hashValue(normalizedCity)]; } if (userData.state || userData.estado) { const normalizedState = (userData.state || userData.estado).trim().toLowerCase(); prepared.st = [hashValue(normalizedState)]; } if (userData.zip || userData.cep) { const normalizedZip = (userData.zip || userData.cep).replace(/\D/g, ""); prepared.zp = [hashValue(normalizedZip)]; } if (userData.country || userData.pais) { const normalizedCountry = (userData.country || userData.pais).trim().toLowerCase(); prepared.country = [hashValue(normalizedCountry)]; } if (userData.external_id) { prepared.external_id = [String(userData.external_id)]; } return prepared; } function addUniversalParameters(params) { if (typeof window === "undefined") return params; return __spreadProps(__spreadValues({}, params), { event_time: Math.floor(Date.now() / 1e3), event_source_url: window.location.href, page_title: document.title || "", page_path: window.location.pathname, page_url: window.location.href, browser_language: navigator.language || "", screen_width: window.screen.width, screen_height: window.screen.height, viewport_width: window.innerWidth, viewport_height: window.innerHeight, referrer: document.referrer || void 0 }); } function isEventAlreadySent(eventName, eventId) { if (typeof window === "undefined") return false; try { const stored = localStorage.getItem(STORAGE_KEY); if (!stored) return false; const events = JSON.parse(stored); const key = `${eventName}_${eventId}`; if (events[key]) { const now = Date.now(); const maxAge = 24 * 60 * 60 * 1e3; if (now - events[key] < maxAge) { logger.info(LogCategory.META_PIXEL, `Evento duplicado ignorado: ${eventName}`, { eventId }); return true; } } return false; } catch (error) { logger.error(LogCategory.META_PIXEL, "Erro ao verificar duplicação", { error }); return false; } } function markEventAsSent(eventName, eventId) { if (typeof window === "undefined") return; try { const stored = localStorage.getItem(STORAGE_KEY) || "{}"; const events = JSON.parse(stored); events[`${eventName}_${eventId}`] = Date.now(); const now = Date.now(); const maxAge = 24 * 60 * 60 * 1e3; Object.keys(events).forEach((key) => { if (now - events[key] > maxAge) { delete events[key]; } }); localStorage.setItem(STORAGE_KEY, JSON.stringify(events)); } catch (error) { logger.error(LogCategory.META_PIXEL, "Erro ao marcar evento como enviado", { error }); } } function sendPixelEvent(event) { return __async(this, null, function* () { if (typeof window === "undefined" || !window.fbq) return false; try { const { event_name, event_id, custom_data } = event; const params = __spreadValues({}, custom_data); delete params.user_data; const options = event_id ? { eventID: event_id } : {}; const isStandardEvent = ["PageView", "Lead", "Purchase", "CompleteRegistration", "Contact"].includes(event_name); if (i