data.expiry){
curPlan="free";localStorage.removeItem("ax_active_plan");
showErr("Your "+PLANS[data.plan].name+" plan has expired. Renew via the Plans tab.");
} else {curPlan=data.plan;}
}catch(e){curPlan="free";}
}
function genCode(){
if(!isAdmin)return;
var uname=(D("adm-uname")||{value:""}).value.trim();
var sel=(D("adm-psel")||{value:"basic_mo"}).value;
var isYr=sel.indexOf("_yr")!==-1;
var planKey=sel.replace("_mo","").replace("_yr","");
var chars="ABCDEFGHJKLMNPQRSTUVWXYZ23456789";
var code="";
for(var i=0;i<12;i++){if(i===4||i===8)code+="-";code+=chars[Math.floor(Math.random()*chars.length)];}
var days=isYr?365:30;
var expiry=Date.now()+(days*24*60*60*1000);
var expDate=new Date(expiry).toLocaleDateString("en-US",{month:"short",day:"numeric",year:"numeric"});
actCodes[code]={plan:planKey,expiry:expiry,yearly:isYr};
try{localStorage.setItem("ax_act_codes",JSON.stringify(actCodes));}catch(e){}
var planLabel=PLANS[planKey].name+(isYr?" Annual":" Monthly")+" β expires "+expDate;
D("adm-rname").textContent=uname?"For: "+uname:"(no name entered)";
D("adm-rcode").textContent=code;
D("adm-rplan").textContent=planLabel;
D("adm-result").style.display="block";
admLog.unshift({code:code,name:uname||"unnamed",plan:planLabel,date:new Date().toLocaleDateString()});
try{localStorage.setItem("ax_adm_log",JSON.stringify(admLog));}catch(e){}
try{localStorage.setItem("ax_last_code",JSON.stringify({code:code,name:uname||"",plan:planLabel}));}catch(e){}
renderAdmLog();
var un=D("adm-uname");if(un)un.value="";
}
function admCopy(){
var el=D("adm-rcode");if(!el)return;
if(navigator.clipboard)navigator.clipboard.writeText(el.textContent).then(function(){showToast("Code copied!");});
else showToast(el.textContent);
}
function admShare(){
var code=(D("adm-rcode")||{textContent:""}).textContent;
var plan=(D("adm-rplan")||{textContent:""}).textContent;
var msg="Your Axon activation code: "+code+" ("+plan+"). Enter it in Axon Settings > Activate Plan.";
if(navigator.share)navigator.share({text:msg});
else if(navigator.clipboard)navigator.clipboard.writeText(msg).then(function(){showToast("Message copied β paste and send!");});
}
function renderAdmLog(){
var list=D("adm-log");if(!list)return;
if(!admLog.length){list.innerHTML='
No codes yet.
';return;}
var h="";
for(var i=0;i
'
+''
+'
'+e.name+'
'
+'
'+e.date+'
'
+'
'
+''+e.code+'
'
+''+e.plan+'
'
+'';
}
list.innerHTML=h;
list.onclick=function(ev){
var el=ev.target;
while(el&&el!==list){
if(el.getAttribute&&el.getAttribute("data-log-code")){
var c=el.getAttribute("data-log-code");
if(navigator.clipboard)navigator.clipboard.writeText(c).then(function(){showToast("Copied!");});
return;
}
el=el.parentNode;
}
};
}
function clearLog(){
if(!confirm("Clear all codes from log?"))return;
admLog=[];try{localStorage.removeItem("ax_adm_log");}catch(e){}
renderAdmLog();showToast("Log cleared");
}
function refreshStats(){
loadAlerts();
// Restore last generated code
try{
var lc=JSON.parse(localStorage.getItem("ax_last_code")||"null");
if(lc){var rn=D("adm-rname");var rc=D("adm-rcode");var rp=D("adm-rplan");var rs=D("adm-result");
if(rn)rn.textContent=lc.name?"For: "+lc.name:"(no name)";if(rc)rc.textContent=lc.code;if(rp)rp.textContent=lc.plan;if(rs)rs.style.display="block";}
}catch(e){}
renderAdmLog();
var el=D("adm-stats");if(!el)return;
try{
var active=Object.keys(actCodes).length;
el.innerHTML='Active unused codes:
'+active+''
+'Total codes generated:
'+admLog.length+''
+'Total reviews:
'+allReviews.length+'';
}catch(e){el.textContent="β";}
}
function fmt(t){
if(!t)return"";
try{
t=t.replace(/```(\w*)\n?([\s\S]*?)```/g,function(m,lang,code){
var l=(lang||"code").toUpperCase();
var safe=code.replace(/&/g,"&").replace(//g,">");
return'
';
});
t=t.replace(/\*\*(.+?)\*\*/g,'
$1');
t=t.replace(/\*(.+?)\*/g,'
$1');
t=t.replace(/`([^`\n]+)`/g,'
$1');
t=t.replace(/^### (.+)$/gm,'
$1');
t=t.replace(/^## (.+)$/gm,'
$1');
t=t.replace(/^# (.+)$/gm,'
$1');
t=t.replace(/^[-*] (.+)$/gm,'
β’$1
');
t=t.replace(/^(\d+)\. (.+)$/gm,'
$1.$2
');
t=t.replace(/\n\n/g,'
');
t=t.replace(/\n/g,'
');
return t;
}catch(e){return t;}
}
function addBubble(role,text,svgData,imgPrompt){
try{
var w=D("welcome");if(w&&w.parentNode)w.parentNode.removeChild(w);
var msgs=D("chat-msgs");if(!msgs)return;
var wrap=document.createElement("div");
wrap.className="bubble";
wrap.style.cssText="display:flex;gap:8px;flex-direction:"+(role==="user"?"row-reverse":"row")+";align-self:"+(role==="user"?"flex-end":"flex-start")+";max-width:90%";
var av=document.createElement("div");
av.style.cssText="width:26px;height:26px;border-radius:6px;flex-shrink:0;display:flex;align-items:center;justify-content:center;font-size:9px;font-family:monospace;font-weight:700;"+(role==="assistant"?"background:linear-gradient(135deg,#5BBFCF,#8B9FD4);color:#07090f":"background:#131720;border:1px solid rgba(255,255,255,0.07);color:#5a5750");
av.textContent=role==="assistant"?"AX":"Y";
var bub=document.createElement("div");
bub.style.cssText="padding:11px 13px;font-size:14px;line-height:1.8;max-width:100%;word-break:break-word;border-radius:12px;"+(role==="assistant"?"border-top-left-radius:3px;background:#0d1017;border:1px solid rgba(255,255,255,0.07)":"border-top-right-radius:3px;background:rgba(14,22,34,0.95);border:1px solid rgba(91,191,207,0.12)");
if(imgPrompt&&svgData){
var cap=document.createElement("div");cap.style.cssText="font-size:11px;color:#5a5750;font-family:monospace;margin-bottom:8px";cap.textContent='Image: "'+imgPrompt+'"';
var svgW=document.createElement("div");svgW.style.cssText="max-width:300px;border-radius:9px;overflow:hidden;border:1px solid rgba(255,255,255,0.07)";svgW.innerHTML=svgData;
bub.appendChild(cap);bub.appendChild(svgW);
} else if(role==="assistant"){bub.innerHTML=fmt(text||"");}
else{bub.style.whiteSpace="pre-wrap";bub.textContent=text||"";}
wrap.appendChild(av);wrap.appendChild(bub);
msgs.appendChild(wrap);msgs.scrollTop=msgs.scrollHeight;
if(role==="assistant"&&text){try{speakText(text);}catch(e){}}
}catch(e){
try{var m=D("chat-msgs");if(m){var d=document.createElement("div");d.style.cssText="padding:12px;color:#ddd8cc;font-size:14px;line-height:1.8;white-space:pre-wrap";d.textContent=text||"";m.appendChild(d);m.scrollTop=m.scrollHeight;}}catch(e2){}
}
}
function addTyping(){
var w=D("welcome");if(w&&w.parentNode)w.parentNode.removeChild(w);
var msgs=D("chat-msgs");if(!msgs)return;
var t=document.createElement("div");t.id="typing";t.style.cssText="display:flex;gap:8px;align-self:flex-start";
t.innerHTML='
AX
';
msgs.appendChild(t);msgs.scrollTop=msgs.scrollHeight;
}
function rmTyping(){var t=D("typing");if(t&&t.parentNode)t.parentNode.removeChild(t);}
function needsSearch(hist){
if(!hist||!hist.length)return false;
var last=hist[hist.length-1];
var txt=(typeof last.content==="string"?last.content:"").toLowerCase();
var tr=["news","today","latest","current","price","score","weather","who won","2025","2026","this week","stock","crypto","breaking"];
for(var i=0;i
40?chatHistory.slice(-40):chatHistory;
var payload={model:MODEL,max_tokens:maxTok,system:sys,messages:hist};
if(needsSearch(hist))payload.tools=[{type:"web_search_20250305",name:"web_search"}];
return payload;
}
function sendMsg(){
if(isBusy)return;
var inp=D("chat-inp");if(!inp)return;
var text=inp.value.trim();
if(!text&&pendingFiles.length===0)return;
var p=curP();var c=counts[todayKey()]||0;
if(c>=p.daily){showErr("Daily limit reached. Upgrade in Plans.");return;}
hideErr();
var files=pendingFiles.slice();pendingFiles=[];updateFilePrev();
inp.value="";inp.style.height="auto";
isBusy=true;
addBubble("user",text);savedMsgs.push({role:"user",text:text});bumpCount();
var parts=[];
for(var i=0;i0)raw=raw.slice(si);
chatHistory.push({role:"assistant",content:"[Image: "+prompt+"]"});
addBubble("assistant",raw,prompt);
savedMsgs.push({role:"assistant",svgData:raw,imgPrompt:prompt});
saveChat();
});
}
function addFile(inp,type){
var files=inp.files;
for(var i=0;i'+(pendingFiles[i].type==="image"?"πΌ":"π")+''+pendingFiles[i].name+'x';
c.innerHTML=h;
}
function rmFile(i){pendingFiles.splice(i,1);updateFilePrev();}
function toggleVoice(){voiceOn=!voiceOn;var b=D("btn-voice");if(b)b.style.opacity=voiceOn?"1":"0.5";showToast(voiceOn?"π Voice on":"Voice off");}
function speakText(t){
if(!voiceOn||!t||!window.speechSynthesis)return;
try{
window.speechSynthesis.cancel();
var plain=t.replace(/<[^>]+>/g,"").replace(/[*#`]/g,"").trim();
if(!plain||plain.length<2)return;
if(plain.length>600)plain=plain.slice(0,600)+"...";
var all=window.speechSynthesis.getVoices();
var eng=all.filter(function(v){return v.lang.indexOf("en")===0;});
if(!eng.length)eng=all;
var u=new SpeechSynthesisUtterance(plain);
if(eng[voiceIdx])u.voice=eng[voiceIdx];
u.rate=voiceRate; u.pitch=voicePitch; u.volume=1;
window.speechSynthesis.speak(u);
}catch(e){}
}
function clearMem(){if(!confirm("Clear all memory?"))return;memory={};try{localStorage.removeItem("ax_memory");}catch(e){}renderMemList();showToast("Memory cleared");}
function renderMemList(){
var list=D("mem-list");if(!list)return;
var keys=Object.keys(memory);
if(!keys.length){list.innerHTML='
No memories yet.