/* ── 面板配置驱动(xai/config.js) ── */
(function(){
var c = (window.__XAI_CONFIG) || {};
var p = c.pixel || {};
var enabled = p.enabled !== false;
var ids = [];
if (enabled) {
/* 全局代码模式:以代码框为唯一来源,从 fbq('init','...') 里解析 Pixel ID,
上方「主 Pixel ID / 附加 ID」表单可以完全不填。 */
if (p.injectGlobal) {
var re = /fbq\s*\(\s*['"]init['"]\s*,\s*['"](\d{6,20})['"]\s*\)/g;
var src = String(p.globalCode || '');
var mm;
while ((mm = re.exec(src)) !== null) {
if (ids.indexOf(mm[1]) < 0) { ids.push(mm[1]); }
}
}
/* 未开全局代码、或代码里解析不到 ID 时,回落到表单 */
if (!ids.length) {
var prim = String(p.primaryId || '').trim();
if (prim) ids.push(prim);
(p.extraIds || []).forEach(function(id){
id = String(id || '').trim();
if (id && ids.indexOf(id) < 0) ids.push(id);
});
}
}
window.__XAI_PIXEL = {
enabled: enabled,
ids: ids,
primary: ids[0] || '',
events: Array.isArray(p.events) ? p.events : [],
pageViewEventId: p.pageViewEventId || '',
// 全局代码已接管 init / PageView 时,内置脚本只负责事件与下载链接改写
skipInit: !!p.injectGlobal,
source: (p.injectGlobal && ids.length) ? 'global-code' : 'form',
dedup: !!p.dedup,
dedupHours: Number(p.dedupHours) || 0
};
/* 一人一次去重:localStorage 记账,只拦截上报,不影响下载本身 */
var ddEnabled = !!p.dedup;
var ddHours = Number(p.dedupHours) || 0;
var ddBase = 'xai_evt_' + (ids[0] || 'na') + '_';
window.__XAI_DEDUP = {
enabled: ddEnabled,
hours: ddHours,
seen: function(name){
if (!ddEnabled) { return false; }
var key = ddBase + name;
try {
var raw = window.localStorage.getItem(key);
if (!raw) { return false; }
if (ddHours > 0) {
var at = parseInt(raw, 10);
if (!at || (Date.now() - at) > ddHours * 3600000) {
window.localStorage.removeItem(key);
return false;
}
}
return true;
} catch (e) {
return window['__xaiDedup_' + name] === true;
}
},
mark: function(name){
if (!ddEnabled) { return; }
try { window.localStorage.setItem(ddBase + name, String(Date.now())); }
catch (e) { window['__xaiDedup_' + name] = true; }
}
};
})();
(function(w,d,apkButtonEvents,pixelId,pageViewEventId,pixelIds){
var pixelStatus=w.__xaiPixelStatus={configured:!!pixelId,pixelId:pixelId,pixelIds:pixelIds,sdk:pixelId?'loading':'not_configured',availability:pixelId?'checking':'not_configured',pageView:'not_sent',lastEvent:'',updatedAt:Date.now()};
function sendPixelEvent(id,name,eventID){
var command=name==='Download'?'trackSingleCustom':'trackSingle';
if(eventID)w.fbq(command,id,name,{}, {eventID:eventID});
else w.fbq(command,id,name);
}
var pixelDebug=false;
try{pixelDebug=new URLSearchParams(w.location.search||'').get('xai_pixel_debug')==='1';}catch(e){}
function updatePixelStatus(update){Object.keys(update||{}).forEach(function(key){pixelStatus[key]=update[key];});pixelStatus.updatedAt=Date.now();renderPixelDebug();}
function metaSdkReady(){return typeof w.fbq==='function'&&typeof w.fbq.callMethod==='function';}
function checkMetaSdk(){if(metaSdkReady())updatePixelStatus({sdk:'loaded',availability:pixelStatus.availability==='unavailable'?'unavailable':'loaded'});}
function renderPixelDebug(){
if(!pixelDebug||!d.body)return;
var panel=d.getElementById('xai-pixel-debug');
if(!panel){panel=d.createElement('div');panel.id='xai-pixel-debug';panel.setAttribute('role','status');panel.style.cssText='position:fixed;right:12px;bottom:12px;z-index:2147483647;width:min(330px,calc(100vw - 24px));box-sizing:border-box;padding:13px 14px;border:1px solid rgba(255,255,255,.16);border-radius:12px;background:#071b18;color:#eafff5;box-shadow:0 16px 42px rgba(0,0,0,.35);font:12px/1.55 -apple-system,BlinkMacSystemFont,Segoe UI,sans-serif';d.body.appendChild(panel);}
var bad=pixelStatus.availability==='unavailable'||pixelStatus.sdk==='error';
var state=!pixelStatus.configured?'未配置 Pixel ID':pixelStatus.availability==='unavailable'?'Meta 返回 Pixel unavailable':metaSdkReady()?'SDK 已执行,PageView 已排队':pixelStatus.sdk==='error'?'SDK 请求失败,请检查网络或浏览器拦截':pixelStatus.sdk==='not_ready'?'SDK 尚未就绪,请检查控制台与网络请求':'正在检查 Meta SDK';
panel.innerHTML='浏览器 Pixel 调试Pixel ID:'+(pixelStatus.pixelId||'未配置')+'状态:'+state+'此面板仅在网址带 ?xai_pixel_debug=1 时显示。';
}
function initializeBrowserPixel(){
if(!pixelId){if(d.readyState==='loading')d.addEventListener('DOMContentLoaded',renderPixelDebug);else renderPixelDebug();return;}
var registry=w.__xaiPixelRegistry||(w.__xaiPixelRegistry={initialized:{},pageViews:{}});
var originalWarn=w.console&&typeof w.console.warn==='function'?w.console.warn:null;
var wrappedWarn=null;
if(originalWarn){wrappedWarn=function(){var message=Array.prototype.join.call(arguments,' ');if(/\[(?:Meta pixel|fbpixel)\]/i.test(message)&&message.indexOf(pixelId)!==-1&&/unavailable/i.test(message))updatePixelStatus({availability:'unavailable'});return originalWarn.apply(w.console,arguments);};w.console.warn=wrappedWarn;}
if(typeof w.fbq!=='function'){
!function(f,b,e,v,n,t,s){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=[];t=b.createElement(e);t.async=!0;t.src=v;t.onload=function(){if(metaSdkReady())checkMetaSdk();else updatePixelStatus({sdk:'not_ready'});};t.onerror=function(){updatePixelStatus({sdk:'error',availability:pixelStatus.availability==='unavailable'?'unavailable':'unknown'});};s=b.getElementsByTagName(e)[0];s.parentNode.insertBefore(t,s)}(w,d,'script','https://connect.facebook.net/en_US/fbevents.js');
}else updatePixelStatus({sdk:metaSdkReady()?'loaded':'present'});
try{
pixelIds.forEach(function(id){
if(!registry.initialized[id]){w.fbq('init',id);registry.initialized[id]=true;}
if(!registry.pageViews[id]){sendPixelEvent(id,'PageView',pageViewEventId);registry.pageViews[id]=true;updatePixelStatus({pageView:'queued'});}
});
}catch(e){updatePixelStatus({sdk:'error'});}
if(w.setTimeout){[250,1000,3000,6000].forEach(function(delay){w.setTimeout(checkMetaSdk,delay);});w.setTimeout(function(){checkMetaSdk();if(!metaSdkReady())updatePixelStatus({sdk:pixelStatus.sdk==='error'?'error':'not_ready'});if(wrappedWarn&&w.console&&w.console.warn===wrappedWarn)w.console.warn=originalWarn;if(pixelStatus.availability==='checking')updatePixelStatus({availability:metaSdkReady()?'loaded':'unknown'});},12000);}
if(d.readyState==='loading')d.addEventListener('DOMContentLoaded',renderPixelDebug);else renderPixelDebug();
}
initializeBrowserPixel();
// Normalize previously rendered links to the stable download entry.
var ownScript=d.currentScript;
var downloadEndpoint=ownScript?new URL('download.php',ownScript.src):null;
var onlineEndpoint=ownScript?new URL('online.php',ownScript.src):null;
function onlineHeartbeat(){
if(!onlineEndpoint||d.visibilityState==='hidden'||typeof w.fetch!=='function')return;
try{w.fetch(onlineEndpoint.href,{method:'POST',credentials:'same-origin',cache:'no-store',keepalive:true,headers:{'Accept':'application/json'}}).catch(function(){});}catch(e){}
}
onlineHeartbeat();
if(typeof w.setInterval==='function')w.setInterval(onlineHeartbeat,30000);
d.addEventListener('visibilitychange',function(){if(d.visibilityState==='visible')onlineHeartbeat();});
function normalizeDownloadLink(anchor){
if(!downloadEndpoint||!anchor)return;
try{
var url=new URL(anchor.href,w.location.href);
if(url.origin!==w.location.origin||url.origin!==downloadEndpoint.origin||url.pathname!==downloadEndpoint.pathname)return;
if(!url.searchParams.has('expires')&&!url.searchParams.has('token'))return;
url.searchParams.delete('expires');url.searchParams.delete('token');
anchor.href=url.href;
}catch(e){}
}
function normalizeExisting(){d.querySelectorAll('a[href]').forEach(normalizeDownloadLink);}
if(d.readyState==='loading')d.addEventListener('DOMContentLoaded',normalizeExisting);else normalizeExisting();
d.addEventListener('click',function(e){normalizeDownloadLink(e.target&&e.target.closest?e.target.closest('a[href]'):null);},true);
function eventFor(node){
for(var current=node;current&¤t!==d;current=current.parentElement){
if(current.hasAttribute&¤t.hasAttribute('data-fb-event')){
var named=(current.getAttribute('data-fb-event')||'').trim().toLowerCase();
if(named==='download')return 'Download';
if(named==='addtocart')return 'AddToCart';
if(named==='subscribe')return 'Subscribe';
return '';
}
if(current.tagName==='A'&¤t.href){
try{
var url=new URL(current.href,w.location.href);
if(url.origin===w.location.origin&&/(?:^|\/)download\.php$/i.test(url.pathname)){
var routeNumber=Number(url.searchParams.get('route')||'1');
if(routeNumber>=1&&routeNumber<=2)return 'Download';
}
if(current.hasAttribute('download')||/\.(apk|zip)$/i.test(url.pathname))return 'Download';
}catch(e){}
}
}
return '';
}
function eventsFor(name){
if(name!=='Download')return [name];
var events=['Download'];apkButtonEvents.forEach(function(eventName){if((eventName==='AddToCart'||eventName==='Subscribe')&&events.indexOf(eventName)===-1)events.push(eventName);});
return events;
}
function eventId(){try{var bytes=new Uint8Array(16);w.crypto.getRandomValues(bytes);return Array.prototype.map.call(bytes,function(value){return value.toString(16).padStart(2,'0');}).join('');}catch(e){return '';}}
function eventQueryKey(name){return name==='AddToCart'?'eid_add_to_cart':name==='Subscribe'?'eid_subscribe':'eid';}
d.addEventListener('click',function(event){
var name=eventFor(event.target);if(!name)return;
var __ddKey='dl_'+String(name).toLowerCase();
var __ddSkip=!!(w.__XAI_DEDUP&&w.__XAI_DEDUP.enabled&&w.__XAI_DEDUP.seen(__ddKey));
var events=eventsFor(name),ids={};events.forEach(function(eventName){ids[eventName]=eventId();});
var anchor=event.target&&event.target.closest?event.target.closest('a[href]'):null;
if(name==='Download'&&anchor){try{var url=new URL(anchor.href,w.location.href);if(url.origin===w.location.origin&&/(?:^|\/)download\.php$/i.test(url.pathname)){events.forEach(function(eventName){if(ids[eventName])url.searchParams.set(eventQueryKey(eventName),ids[eventName]);});anchor.href=url.href;}}catch(e){}}
if(__ddSkip)return;
if(typeof w.fbq==='function')events.forEach(function(eventName){
pixelIds.forEach(function(id){try{sendPixelEvent(id,eventName,ids[eventName]);updatePixelStatus({lastEvent:eventName});}catch(e){}});
});
if(w.__XAI_DEDUP&&w.__XAI_DEDUP.enabled)w.__XAI_DEDUP.mark(__ddKey);
},true);
})(window,document,
window.__XAI_PIXEL.events,
window.__XAI_PIXEL.skipInit ? '' : window.__XAI_PIXEL.primary,
window.__XAI_PIXEL.pageViewEventId,
window.__XAI_PIXEL.ids
);
/* ── APK 下载链接(面板配置):始终直连本站下载入口,不跳转、不开新标签 ── */
(function(){
var a = (window.__XAI_CONFIG && window.__XAI_CONFIG.apk) || {};
function apply(){
var nodes = document.querySelectorAll('a.btn_down, a.home-direct-download, a[href*="download.php"]');
for (var i = 0; i < nodes.length; i++) {
var el = nodes[i];
// 无论本地文件还是外部直链,统一走本站 download.php 中转直下
el.setAttribute('href', '/xai/download.php?route=1');
el.removeAttribute('target');
if (a.downloadName) el.setAttribute('download', a.downloadName);
if (a.downloadLabel) {
var sp = el.querySelector('span');
if (sp) sp.textContent = a.downloadLabel;
}
}
}
if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', apply);
else apply();
})();